1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """The main interface to MBDyn. This module contains
23 the C{Simulation} class that generates the input file.
24 """
25 import os
26 import copy
27
28 from mbdyn.preprocessing import SimulationBase
29 try:
30 from mbdyn.bindings.main import WraptMBDyn
31 except ImportError:
32 pass
33
35 """A list containing object with a name attribute.
36 A kind of dictionary that remenbers the order in which
37 the items have been added.
38 """
39
41 self.list = []
42 self.list_names = []
43
44 - def add(self, obj, name=None):
45 """Add an object to the list"""
46 self.list.append(obj)
47 if name != None:
48 self.list_names.append(name)
49 else:
50 self.list_names.append(obj.name)
51
53 return self.list[self.list_names.index(obj_name)]
54
55
57 """The main MBDyn simulation.
58 C{Simulation} will gather all the objects and run L{WraptMBDyn},
59 a MBDyn simulation controlled from Python.
60 """
61
62 - def __init__(self, name="mbdyn simu", title="Mbdyn used from Python",
63 keep=False, overwrite=False):
64 """'name' is only used for writing the files."""
65 SimulationBase.__init__(self, name, title, keep, overwrite)
66
67 self.time = 0.
68 self.nb_frames = 0
69
70
71
72 self.wrapt_mbdyn = None
73 self.wm = self.wrapt_mbdyn
74 self.has_wrapt_mbdyn = False
75 self.has_init = False
76 self._has_written = False
77 self.solve = self.solve_by_wrapt_mbdyn
78
79 self.call_update = True
80 self.call_save = True
81
82 self.repr_list = []
83 self.own_para_names += ["name", "title", "time", "nb_frames",
84 "repr_list"]
85 self.children_names = ["nodes", "refs"]
86 self.will_save("time")
87
89 """Set the simulation integrator"""
90 self.integrator = integrator
91
93 """Add a node, element or a reference frame to
94 the corresponding object list.
95 Store also a reference of the simulation to the item
96 object and the representation name is added for the magic
97 function __repr__.
98 """
99 item.set_simulation_ref(self)
100 getattr(self, list_name).add(item)
101 if list_name not in self.repr_list:
102 self.repr_list.append(list_name)
103
105 """Add a reference frame to the simulation"""
106 self._add_item_to_list("refs", reference)
107
112
117
119 """The user can add its own object to the simulation.
120 The idea: if the user adds its own object, then he must not add
121 the element and the node to the simulation. His object already contains
122 a list of elements and a list of nodes. By this manner, the controlData
123 can not have duplicated information, that is to say, duplicated node or
124 element. Currently in development and not in use because
125 it may be simpler to invite the user at inheriting
126 from the C{Simulation} (approach run successfully in wind-sim-suite).
127 """
128 self.control_data.add(obj)
129 for elt in obj.elements:
130 elt.set_simulation_ref(self)
131 self.elts.add(elt)
132 for node in obj.nodes:
133 node.set_simulation_ref(self)
134 self.nodes.add(node)
135 for ref in obj.references:
136 self.refs.add(ref)
137
139 """Append a MBDyn time step results to the Python objects.
140 Use when the text files are scanned"""
141 for node_line in node_lines:
142 node_data = node_line.split()
143 node_indice = int(node_data[0])
144 node_values = [float(val) for val in node_data[1:]]
145 node = self.nodes.get_node_id(node_indice)
146 if node:
147 node.append(node_values)
148
150 """Load the time step and the .mov file before
151 loading the results, used only when scanning
152 the output files"""
153 self.mov_file_name = self.file_name + ".mov"
154 self.time_step = self.integrator["time step"][0]
155
157 """Load the result from the '.mov. file of MBDyn containing
158 the kinematic degrees of freedom of the nodes"""
159 output_file = open(self.mov_file_name)
160 lines = output_file.readlines()
161 output_file.close()
162 self.nodes.init_results()
163 self.time = []
164 nodes_nb = self.nodes.get_nodes_nb()
165 outputs_nb = len(lines) / nodes_nb
166 for step_indice in range(outputs_nb):
167 self.time.append(step_indice*self.time_step)
168 output_indice = step_indice*nodes_nb
169 self.append_output(lines[output_indice : output_indice + nodes_nb])
170
172 """Set an instance of the wraptMBDyn, used
173 when the input file is not written by the Python
174 interface"""
175 self.wrapt_mbdyn = wrapt_mbdyn
176 self.wm = self.wrapt_mbdyn
177 self.has_wrapt_mbdyn = True
178
180 """The instances provided from the interface get the ones
181 created by MBDyn"""
182 for item in self.nodes.all + self.elts.all + self.refs:
183 item.get_mbdyn_instance()
184
186 """Save the mbdyn status. First the simulation is saved
187 and then all the objects. This method will be called
188 by L{WraptMBDyn} as every time step."""
189 self.time = self.wm.solver.current_time
190 self.save_results()
191 for item in self.nodes.all + self.elts.all:
192 item.save()
193
195 """The same method as L{save_mbdyn}. The default is
196 just to save mbdyn but it changes when inheritance occurs"""
197 self.save_mbdyn()
198
200 """Update all the element by calling the C{update} method
201 of each element."""
202 solver = self.wrapt_mbdyn.solver
203 self.time = solver.current_time + solver.time_step
204 for elt in self.elts.all:
205 elt.update(self)
206
208 """The same as L{update_elts}. The default update
209 for a simulation. Called by L{WraptMBDyn} as every
210 time step."""
211 self.update_elts()
212
214 """Initialization before running MBDyn.
215 The MBDyn instances are tracked from the Python objects.
216
217 If an update needs to be done on the elements, they are
218 initialized by 'do_as_init'. The WraptMBDyn update method
219 will call the simulation one.
220
221 If the values are saved from Python, the results are
222 initialized. The WraptMBDyn save method will call
223 the simulation one.
224 """
225 self.time = 0.
226 self.init_results()
227 self._get_mbdyn_instances()
228 if self.call_update:
229 for elt in self.elts.all:
230 elt.do_as_init()
231 self.wrapt_mbdyn.update = self.update
232 if self.call_save:
233 for item in self.nodes.all + self.elts.all:
234 item.init_results()
235 for ref in self.refs:
236 ref.store_mbdyn_data()
237 self.wrapt_mbdyn.save = self.save
238 self.wrapt_mbdyn.final_action = self.final_action
239
241 """Initialize the WraptMBDyn instance. This method
242 will also create a WraptMBDyn in case an input file
243 have been written."""
244 if not self.has_wrapt_mbdyn:
245 self.write()
246 self._has_written = True
247 self.set_wrapt_mbdyn(WraptMBDyn(self.os_name, self.dir))
248 self.wrapt_mbdyn.init()
249
251 """Initialize the simulation according to L{WraptMBDyn}.
252 The Python object get references to the object from
253 the bindings module, interfacing the C++
254 ones."""
255 if not self.has_init:
256 self._init_wrapt_mbdyn()
257 self.init_simulation()
258 self.has_init = True
259 else:
260 print "'init()' already called on the Simulation"
261
263 """Decide if the simulation with the input file
264 written is run with the MBDyn executable
265 of the bindings.
266 Note: does not make sense in case WraptMBDyn comes
267 from outside, no input file has been written in
268 that case."""
269 if self.has_wrapt_mbdyn:
270 print "'run_with_excutable' is inactive as " +\
271 "'set_wrapt_mbdyn' has been called."
272 else:
273 if boolean:
274 self.solve = self.solve_by_mbdyn_exec
275 else:
276 self.solve = self.solve_by_wrapt_mbdyn
277
279 """Solve the problem by WraptMBDyn. The most common
280 way to solve a simulation."""
281 if not self.has_init:
282 self.init()
283 self.wrapt_mbdyn.run_full()
284
286 """Called by WraptMBDyn when it finished the simulation.
287 This method allows to interact with WraptMBDyn (by
288 'run_until'...) without loosing the actions that should
289 be done on the simulation object at the final time"""
290 self.nb_frames = len(self.results.time)
291 if self._has_written:
292 self.clean(self.os_name + "_result")
293
295 """Run the MBDyn executable on the input file written."""
296 command = "mbdyn %s" % self.file_name
297
298 os.system(command)
299 self._set_info_for_loading()
300 self.load_results()
301 self.clean()
302
304 """Run the complete simulation"""
305 self.solve()
306
308 """Identic function has 'run_full()'"""
309 self.run_full()
310
312 """Return the representation of the simulation"""
313 string = "["
314 if len(self.repr_list) > 0:
315 for repr in self.repr_list[:-1]:
316 string += repr + ",\n"
317 string += self.repr_list[-1]
318 string += "]"
319 return string
320
322 """Collect all the parameters of the Simulation and store them
323 in the para dictionary"""
324 self.collect_own_parameters()
325 for children_name in self.children_names:
326 children = getattr(self, children_name)
327 children.collect_parameters()
328 self.para[children_name] = children.para
329
331 """Set the parameters of the simulation from the pickled
332 dictionary para"""
333 self.set_own_parameters(para)
334 for children_name in self.children_names:
335 children = getattr(self, children_name)
336 children.set_parameters(para[children_name])
337 for item in self.nodes.all + self.elts.all + self.refs:
338 item.set_simulation_ref(self)
339
340
342 """A file containing the MBDyn results as well as the Python information
343 for loading a pickled Simulation. This file acts as a container,
344 many simulations could be contained in one file.
345 """
346
347 - def __init__(self, name, mode="r", path=".", autoload=True):
348 self.name = name
349 self.mode = mode
350 self.path = path
351 self.file_name = os.path.join(path, name)
352
353 self.simulations = []
354 self.simulation_paras = []
355 self.simulation_names = []
356
357 self.file = None
358 self.CLASS = Simulation
359 self.__open()
360 if (mode=="r") and autoload:
361 self.load()
362
364 """Open the file"""
365 self.file = open(self.file_name, self.mode)
366
368 """Load the data from the file"""
369 import cPickle as pickle
370 self.simulation_paras = pickle.load(self.file)
371 self.file.close()
372 for simulation_para in self.simulation_paras:
373 simu = self.CLASS()
374 simu.set_parameters(simulation_para)
375 self.simulations.append(simu)
376 self.simulation_names.append(simu.name)
377
378 - def add(self, simu):
379 """Add a simulation to the file to save
380 (save automatically the simulation)."""
381 simu.collect_parameters()
382 para = copy.deepcopy(simu.para)
383 self.simulation_paras.append(para)
384 self.simulations.append(simu)
385 self.simulation_names.append(simu.name)
386 if not self.file.closed:
387 self.file.close()
388 self.__open()
389 self.write()
390
392 """Return a simulation from its name"""
393 return self.simulations[self.simulation_names.index(name)]
394
396 """Return the indice of a simulation. The numerotation is starting
397 at 1 and not a 0. Python users can directly access the simulation by
398 the list attribute C{simulations}."""
399 return self.simulations[indice - 1]
400
402 """Write the simulation in the file"""
403 import cPickle as pickle
404 pickle.dump(self.simulation_paras, self.file)
405
407 """Close the file"""
408 self.file.close()
409