Package windSimSuite :: Module common
[hide private]

Source Code for Module windSimSuite.common

  1  #!/usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3  # 
  4  # This file is part of MBDyn sim suite. 
  5  # Copyright (C) 2007 André ESPAZE, as part of a Master thesis supervised by 
  6  # Martin O.L.Hansen (DTU) and Nicolas Chauvat (Logilab) 
  7   
  8  # MBDyn sim suite is free software; you can redistribute it and/or modify 
  9  # it under the terms of the GNU General Public License as published by 
 10  # the Free Software Foundation; either version 2 of the License, or 
 11  # (at your option) any later version. 
 12  # 
 13  # This program is distributed in the hope that it will be useful, 
 14  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 16  # GNU General Public License for more details. 
 17  # 
 18  # You should have received a copy of the GNU General Public License 
 19  # along with this program; if not, write to the Free Software 
 20  # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
 21  # 
 22  """Common object for the Wind Sim Suite simulation. 
 23  """ 
 24  import numpy as N 
 25  from types import ListType 
 26  from mbdyn.record import Record 
 27   
 28  from mbdyn.nodes import NODE_CLASS 
 29  from mbdyn.elements import ELEM_CLASS 
 30   
31 -def get_norm(array):
32 """Return the norm of a 3x1 array""" 33 norm = N.sqrt(N.dot(array.transpose(), array)) 34 return float(norm[0][0])
35 36
37 -class List(ListType):
38 """A list containing also object names as 39 attribute. 40 """ 41
42 - def __init__(self):
43 ListType.__init__(self) 44 self.names = []
45
46 - def add(self, obj, name=None):
47 """Add an object to the list. 48 As an alternative, an oject can have an attribute C{mbdyn_objects} 49 for object based on the top of the Python module, that does 50 not exist in MBDyn.""" 51 if hasattr(obj, "mbdyn_objects"): 52 for child_obj in obj.mbdyn_objects: 53 self._add_mbdyn_object(child_obj, name) 54 else: 55 self._add_mbdyn_object(obj, name)
56
57 - def _add_mbdyn_object(self, obj, name):
58 """Add a MBDyn object to the list and keep 59 track of its name""" 60 self.append(obj) 61 if name != None: 62 self.names.append(name) 63 else: 64 self.names.append(obj.name)
65
66 - def get(self, obj_name):
67 """Return an object from its name""" 68 try: 69 return self[self.names.index(obj_name)] 70 except: 71 print self.names 72 raise
73 74
75 -class _ConversionTable:
76 """Used to convert a quantity between different units 77 """ 78
79 - def __init__(self, default_unit, convert_to_default):
80 self.unit_keys = [] 81 self.conversion_factors = [] 82 self.build_conversion_lists(default_unit, convert_to_default)
83
84 - def build_conversion_lists(self, default_unit, convert_to_default):
85 """Build the conversion list for the unit used by default""" 86 self.unit_keys.append(default_unit) 87 self.conversion_factors.append(1.) 88 for unit_key, conversion_factor in convert_to_default.items(): 89 self.unit_keys.append(unit_key) 90 self.conversion_factors.append(conversion_factor)
91
92 - def get_factor(self, unit_key):
93 """Return the factor to pass from the C{unit_key} 94 to the default unit.""" 95 return self.conversion_factors[self.unit_keys.index(unit_key)]
96
97 - def get_factor_to(self, unit_key):
98 """Return the factor to pass from the default unit 99 to the C{unit_key}""" 100 return 1./self.conversion_factors[self.unit_keys.index(unit_key)]
101
102 - def get_keys_str(self):
103 """Return all the possible keys as a string""" 104 string = "'%s' " % self.unit_keys[0] 105 for key in self.unit_keys[1:-1]: 106 string += ",'%s' " % key 107 string += "and '%s'" % self.unit_keys[-1] 108 return string
109 110
111 -class _PhysicQuantity:
112 """A physical quantity stored with a default 113 unit. The default unit is specified by the 114 derived class. The conversion from one unit 115 to another is achieved by the L{_ConversionTable}. 116 The user then stores a value to a particular unit 117 by the L{__setitem__} method. 118 He can retrieved the value to any available unit 119 by L{__getitem__}. 120 """ 121
122 - def __init__(self, conv_table, value, unit):
123 self.conv_table = conv_table 124 if value != None: 125 self[unit] = value 126 else: 127 self.value = None
128
129 - def __setitem__(self, unit_key, value):
130 if unit_key not in self.conv_table.unit_keys: 131 print "No able to set the value from the key: '%s'." % unit_key 132 print "Keys possible are %s." % self.conv_table.get_keys_str() 133 else: 134 self.value = value * self.conv_table.get_factor(unit_key)
135
136 - def __getitem__(self, unit_key):
137 return self.value * self.conv_table.get_factor_to(unit_key)
138 139
140 -class Angle(_PhysicQuantity):
141 """An angle that can be converted from radian 142 to degree. The default unit is in radian. 143 Any value can be set by specifying the unit by 144 'rad' or 'deg'. 145 """ 146
147 - def __init__(self, value=None, unit="rad"):
148 convert_to_rad = {"deg" : N.pi / 180.} 149 conv_table = _ConversionTable("rad", convert_to_rad) 150 _PhysicQuantity.__init__(self, conv_table, value, unit)
151
152 - def __repr__(self):
153 return "Angle of %s %s" % (self.value, "rad")
154 155
156 -class RotationalSpeed(_PhysicQuantity):
157 """An rotational speed that can be converted from radian per 158 second to rotation per minutes. 159 The default unit is in radian per second. 160 Any value can be set by specifying the unit by 161 'rad/s' or 'rpm'. 162 """ 163
164 - def __init__(self, value=None, unit="rad/s"):
165 convert_to_rad_s = {"rpm" : 2. * N.pi / 60.} 166 conv_table = _ConversionTable("rad/s", convert_to_rad_s) 167 _PhysicQuantity.__init__(self, conv_table, value, unit)
168
169 - def __repr__(self):
170 return "Rotational speed of %s %s" % (self.value, "rad/s")
171 172
173 -class BasicObject(Record):
174 """The base object for the L{windSimSuite} package. 175 This object inherits from the C{Record} object 176 of the mbdyn package so then attributes that need 177 to be saved can be precised. 178 """ 179
180 - def __init__(self, name):
181 Record.__init__(self) 182 self.name = name 183 self.own_para_names += ["name"]
184
185 - def set_name(self, name):
186 """Set the object name""" 187 self.name = name
188 189
190 -class ObjectWithNodesAndElems(BasicObject):
191 """An abstract object with MBDyn nodes and elements. 192 This object is supposed to help the building of custom 193 objects on the top of MBDyn ones by providing a set of methods 194 for adding them to the simulation, being able to save them in 195 files and retrieved them for post processing. 196 Need to be tested, but if it works fine, it could be merged 197 to the MBDyn module. 198 """ 199
200 - def __init__(self, name):
201 BasicObject.__init__(self, name) 202 self.node_class = NODE_CLASS 203 self.elt_class = ELEM_CLASS 204 205 self.nodes = List() 206 self.node_paras = [] 207 208 self.elts = List() 209 self.elt_paras = [] 210 211 self.refs = List() 212 213 self.own_para_names += ["name", "node_paras", "elt_paras"]
214
215 - def set_node_class(self, node_class):
216 """node_class is a dictonary of class. The first key 217 is the group of the class and the second key the class 218 type. 219 This method is used when using class from the interface, 220 with GTK and VTK widgets, instead of the classic one.""" 221 self.node_class = node_class
222
223 - def add_node(self, node):
224 """Add a node to its L{List}""" 225 self.nodes.append(node)
226
227 - def add_element(self, elt):
228 """Add an element to its L{List}""" 229 self.elts.append(elt)
230
231 - def add_on_simulation(self, simu):
232 """Add the nodes, elements and references on the 233 simulation, before writing the MBDyn input file""" 234 for node in self.nodes: 235 simu.add_node(node) 236 for elt in self.elts: 237 simu.add_element(elt) 238 for ref in self.refs: 239 simu.add_reference(ref)
240
241 - def collect_node_parameters(self):
242 """Collect the node parameters into the C{para} 243 dictionary""" 244 for node in self.nodes: 245 node.collect_parameters() 246 self.node_paras.append(node.para)
247
248 - def collect_elt_parameters(self):
249 """Collect the element parameters into the C{para} 250 dictionary""" 251 for elt in self.elts: 252 elt.collect_parameters() 253 self.elt_paras.append(elt.para)
254
255 - def collect_parameters(self):
256 """Collect the object parameters""" 257 self.collect_own_parameters() 258 self.collect_node_parameters() 259 self.collect_elt_parameters()
260
261 - def set_node_parameters(self):
262 """Create the node from the C{node_class} 263 and the C{node_paras}""" 264 for node_para in self.node_paras: 265 NodeClass = self.node_class[node_para["group_key"]]\ 266 [node_para["class_key"]] 267 node = NodeClass() 268 node.set_parameters(node_para) 269 270 try: 271 self.nodes.append(node) 272 except: 273 print self.name 274 import sys; sys.exit()
275
276 - def set_elt_parameters(self):
277 """Create the elements from the C{elts_class} 278 and the C{elts_paras}""" 279 for elt_para in self.elt_paras: 280 try: 281 ElemClass = self.elt_class[elt_para["group_key"]]\ 282 [elt_para["class_key"]] 283 except: 284 print elt_para["name"] 285 print elt_para["group_key"], elt_para["class_key"] 286 raise 287 elt = ElemClass() 288 elt.set_parameters(elt_para) 289 self.elts.append(elt)
290
291 - def set_parameters(self, para):
292 """Retrieve the object status from the C{para} 293 dictionary.""" 294 self.set_own_parameters(para) 295 self.set_node_parameters() 296 self.set_elt_parameters()
297