1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """The definition of all the MBDyn groups. The top class
23 of that module is L{ItemGroup}, an abstract class that will
24 be the base of a list of nodes, L{NodeGroup}, or a list of elements,
25 L{ElementGroup}. The motivation is to access any object inside
26 a group by a list syntax once the parsing of the MBDyn input file
27 done. As the simplest example::
28
29 >>> wm = WraptMBDyn("input_file")
30 >>> wm.init()
31 >>> node = wm.nodes.structurals[0]
32
33 C{node} is a reference to the first structural node written in the input file.
34 Another example::
35
36 >>> for node in wm.nodes.structurals:
37 print node.label
38
39 1001
40 1002
41 1003
42 >>> node = wm.nodes.structurals.get_from_label(1002)
43
44 The groups can be iterated as list. Moreover by knowing the MBDyn label
45 used in the input file, any reference to the C++ instance can be got
46 as a Python object.
47
48 The work of the group is also to answer to the
49 C{convert} method called by L{Groups}, and thus get down from the
50 MBDyn polymorphism.
51
52 Note also L{GROUP_TABLE}, a dictionary gathering the group descriptions
53 for nodes and elements in a table (or list of tuples).
54 Inside a table,
55 the first field is the MBDyn name of the group (used as an
56 enumeration in the C++ code). The second is the attribute name
57 that will be set in the L{Groups} class. The third and last field
58 is the class reference of the group, so then L{WraptMBDyn} will be
59 able to create the group class during its
60 L{init<mbdyn.bindings.main.WraptMBDyn.init>} method.
61 """
62 from types import ListType
63
64 import mbdyn.bindings.swigModule as swigModule
65 from mbdyn.bindings.nodes import NODE_CLASS
66 from mbdyn.bindings.elements import ELEM_CLASS
67
68 from mbdyn.bindings.forces import FORCE_CLASS
69 from mbdyn.bindings.joints import JOINT_CLASS
70
71 CLASS = {}
72 CLASS["ELEM"] = ELEM_CLASS
73 CLASS["NODE"] = NODE_CLASS
74
75
76
77
78 CLASS["ELEM"]["FORCE"] = FORCE_CLASS
79 CLASS["ELEM"]["JOINT"] = JOINT_CLASS
80
81
83 """An element or node group used by MBDyn. It will contains for sure
84 the pointers to the C++ C{Elem} or C{Node} instances that comes from the
85 MBDyn C{DataManager}. Those instances are however a very low
86 interest for the scripting language interface, the user can just
87 get the MBDyn label from it, see <mbdyn.bindings.basic_objects>.
88
89 To get down of the MBDyn polymorphism, the SWIG module (or C{swigModule}
90 in Python) provides a conversion function, that corresponds to
91 a dynamic cast in C++. At that step the function exists because
92 provided by L{Groups}, the groups manager.
93 """
94
95 - def __init__(self, item_key, mbdyn_key, idx, nb_items):
96 ListType.__init__(self)
97 self.item_key = item_key
98 self.mbdyn_key = mbdyn_key
99 self.key = self.mbdyn_key.lower()
100 self.idx = idx
101 self.attr_name = GROUP[item_key]["ATTRIBUTES"][idx]
102 self.number = nb_items
103 self.label_list = []
104
106 """Add an item to the list and keep track of its label"""
107 self.append(item)
108 self.label_list.append(item.label)
109
111 """Return an item from its label"""
112 try:
113 return self[self.label_list.index(label)]
114 except ValueError:
115 mess = "The %s with label '%s' does not " + \
116 "seem to be present in MBDyn"
117 print mess % (self.key, str(label))
118
120 """Convert the pointers to the Elem class of MBDyn
121 to the class of the group. Getting down of the MBDyn
122 polymorphism and in the same time add a layer between
123 the c_inst.
124 For example, the pointer Elem, pointing to an Elem
125 instance is converted to the pointer Force, pointing
126 to a Force instance by a dynamic cast"""
127 ItemClass = CLASS[self.item_key][self.mbdyn_key]["general"]
128 for item in self.clean_and_copy():
129 c_inst = convert_to_group_class(item.c_inst)
130 new_item = ItemClass(c_inst)
131 self.append(new_item)
132
134 """Clean the list, defined by self, and return
135 a copy of it
136 """
137 self_copy = []
138 for item in self:
139 self_copy.append(item)
140 for item in self_copy:
141 self.remove(item)
142 return self_copy
143
144 - def convert(self, convert_to_group_class):
145 """Will execute a common conversion. However this method
146 is supposed to be overridden by every specific group."""
147 self.common_conversion(convert_to_group_class)
148
149
151 """The top class for all the node group"""
152
153 - def __init__(self, mbdyn_key, idx, nb_elts):
154 ItemGroup.__init__(self, "NODE", mbdyn_key, idx, nb_elts)
155 self.convert_method_name = "convert_to_" + self.key + "_node"
156
157
159 """The "ABSTRACT" node group"""
160 pass
161
162
164 """The "STRUCTURAL" node group"""
165 pass
166
167
169 """The "ELECTRIC" node group"""
170 pass
171
172
174 """The "PARAMETER" node group"""
175 pass
176
177
179 """The "HYDRAULIC" node group"""
180 pass
181
182
184 """The top class for the element group"""
185
186 - def __init__(self, mbdyn_key, idx, nb_elts):
187 ItemGroup.__init__(self, "ELEM", mbdyn_key, idx, nb_elts)
188 self.convert_method_name = "convert_to_" + self.key
189
190
192 """The "ROTOR" element group"""
193 pass
194
195
197 """The "AUTOMATICSTRUCTURAL" element group"""
198 pass
199
200
202 """The "GRAVITY" element group"""
203 pass
204
205
207 """The "BODY" element group"""
208 pass
209
210
212 """The "JOINT" element group"""
213
214 - def convert(self, convert_to_group_class):
218
220 """Return a new joint instance"""
221 JointClass = CLASS["ELEM"]["JOINT"][elt.class_key]
222 c_inst = getattr(swigModule, "convert_to_" + elt.class_key)(elt.c_inst)
223 return JointClass(c_inst)
224
226 """Test on the SWIG module if there is a function
227 to convert the current general reference to a more specific joint"""
228 conversion = "convert_to_" + elt.class_key
229 try:
230 getattr(swigModule, conversion)
231 return True
232 except AttributeError:
233 return False
234
236 """Try to get the lowest part of the
237 MBDyn polymorphism, when
238 differents types exist inside the same group.
239 Example: DriveHingeJoint from Joint"""
240 for elt in self.clean_and_copy():
241 if self._has_specific_type(elt):
242 new_elt = self._get_new_type(elt)
243 self.append(new_elt)
244 else:
245 self.append(elt)
246
247
248 -class Beams(ElementGroup):
249 """The "BEAM" element group"""
250 pass
251
252
254 """The "PLATE" element group"""
255 pass
256
257
259 """The "FORCE" element group"""
260
261 - def convert(self, convert_to_group_class):
265
267 """Return the new force instance"""
268 force_type = elt.c_inst.get_force_type()
269 ForceClass = CLASS["ELEM"]["FORCE"][force_type]
270 c_inst = getattr(swigModule, "convert_to_" + force_type)(elt.c_inst)
271 return ForceClass(c_inst)
272
274 """Test if there is a conversion function on the SWIG module
275 for converting the reference to a more specific one"""
276 force_type = elt.c_inst.get_force_type()
277 conversion = "convert_to_" + force_type
278 try:
279 getattr(swigModule, conversion)
280 return True
281 except AttributeError:
282 return False
283
285 """Try to get the lowest part of the
286 MBDyn polymorphism, when
287 differents types exist inside the same group.
288 Example: conservative and follower forces for this force group
289 """
290 for elt in self.clean_and_copy():
291 if self._has_specific_type(elt):
292 new_elt = self._get_new_type(elt)
293 self.append(new_elt)
294 else:
295 self.append(elt)
296
297
299 """The "ELECTRICBULK" element group"""
300 pass
301
302
304 """The "ELECTRICS" element group"""
305 pass
306
307
309 """The "HYDRAULICS" element group"""
310 pass
311
312
313 -class Bulks(ElementGroup):
314 """The "BULKS" element group"""
315 pass
316
317
319 """The "LOADABLE" element group"""
320 pass
321
322
324 """The "DRIVEN" element group"""
325 pass
326
327
329 """The "EXTERNAL" element group"""
330 pass
331
332
334 """The "AIRPROPERTIES" element group"""
335 pass
336
337
339 """The "AEROMODAL" element group"""
340 pass
341
342
344 """The "AERODYNAMIC" element group"""
345 pass
346
347
349 """The "GENEL" element group"""
350 pass
351
352
354 """The "SOCKETSTREAM_OUTPUT" element group"""
355 pass
356
357
358 GROUP_TABLE = {}
359
360 GROUP_TABLE["NODE"] = [
361 ("ABSTRACT", "abstracts", Abstracts),
362 ("STRUCTURAL", "structurals", Structurals),
363 ("ELECTRIC", "electrics", NodeElectrics),
364 ("PARAMETER", "parameters", Parameters),
365 ("HYDRAULIC", "hydraulics", NodeHydraulics)
366 ]
367
368
369
370
371
372 GROUP_TABLE["ELEM"] = [
373 ("ROTOR", "rotors", Rotors),
374 ("AUTOMATICSTRUCTURAL", "automatic_structurals", AutomaticStructurals),
375 ("GRAVITY", "gravities", Gravities),
376 ("BODY", "bodies", Bodies),
377 ("JOINT", "joints", Joints),
378 ("BEAM", "beams", Beams),
379 ("PLATE", "plates", Plates),
380 ("FORCE", "forces", Forces),
381 ("ELECTRICBULK", "electric_bulks", ElectricBulks),
382 ("ELECTRIC", "electrics", Electrics),
383 ("HYDRAULIC", "hydraulics", Hydraulics),
384 ("BULK", "bulks", Bulks),
385 ("LOADABLE", "loadables", Loadables),
386 ("DRIVEN", "drivens", Drivens),
387 ("EXTERNAL", "externals", Externals),
388 ("AIRPROPERTIES", "air_properties", AirProperties),
389 ("AEROMODAL", "aeromodals", Aeromodals),
390 ("AERODYNAMIC", "aerodynamics", Aerodynamics),
391 ("GENEL", "genels", Genels),
392 ("SOCKETSTREAM_OUTPUT", "socketstream_outputs", SocketStreamOutputs)
393 ]
394
395 GROUP = {}
396
397 for item_type in ["NODE", "ELEM"]:
398 GROUP[item_type] = {}
399 GROUP[item_type]["KEYS"] = []
400 GROUP[item_type]["ATTRIBUTES"] = []
401 GROUP[item_type]["CLASS"] = []
402 for key, attr, class_name in GROUP_TABLE[item_type]:
403 GROUP[item_type]["KEYS"].append(key)
404 GROUP[item_type]["ATTRIBUTES"].append(attr)
405 GROUP[item_type]["CLASS"].append(class_name)
406