Package mbdyn :: Module nodes
[hide private]

Source Code for Module mbdyn.nodes

  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  """The interface to the MBDyn nodes. However the only node available today is  
 23  the L{StructuralNode}, that can be static or dynamic. 
 24  """ 
 25  from mbdyn.common import BasicObject, MANAGER 
 26  from mbdyn.common import split_into_pieces_of_3 
 27  from mbdyn.general import NULL, EYE 
 28  from mbdyn.references import NONE_REF 
 29   
 30   
31 -class Node(BasicObject):
32 """An abstract class for all the nodes. The relative reference 33 frame, the type and the saving operations are performed.""" 34
35 - def __init__(self, name="Node"):
36 BasicObject.__init__(self, name) 37 self.ref = None 38 39 self.arg_names = ["label"] 40 self.saving_actions = []
41
42 - def set_relative_from(self, ref):
43 """The relative L{ReferenceFrame} to set data from. 44 """ 45 self.ref = ref 46 self.set_default()
47
48 - def set_default(self):
49 """Will be defined by the derived class""" 50 pass
51
52 - def set_type(self, node_type, com=None):
53 """The keyword that identifies the MBDyn type. 54 For a L{StructuralNode}, it will be 'static' or 'dynamic'.""" 55 MANAGER.add_argument(self, "node_type", node_type, com)
56
57 - def collect_parameters(self):
58 """Collect the node parameters""" 59 self.collect_own_parameters()
60
61 - def set_parameters(self, para):
62 """Set the parameters saved on the structural node, 63 for retrieving the object status.""" 64 self.set_own_parameters(para)
65
66 - def init_results(self):
67 """Initialize the results by creating the needed objects 68 to save the parameters of interest during the simulation.""" 69 self.common_init_results()
70 71
72 -class StructuralNode(Node):
73 """The structural node of MBDyn. The type can be 'static' or 'dynamic' as 74 defined in MBDyn. Usually a structural node is defined relative 75 to a L{ReferenceFrame}; its position, rotation matrix, velocity and 76 angular velocity are then defined. A structural node inherits from its 77 reference frame property. It is important to understand that 78 a structural node introduces degrees of freedom in the problem, that's why 79 it needs to be attached to joints for getting constraints and describing 80 a model that can be solved. 81 82 Example of use:: 83 84 import numpy as N 85 86 ref = ReferenceFrame() 87 ref.set_position(10., 0., 0.) 88 89 node1 = StructuralNode() 90 node1.set_relative_from(ref) 91 node1.set_velocity(1., 0., 0.) 92 node1.set_angular_velocity(0., 0., 1.) 93 94 angle = N.pi/4. 95 node2 = StructuralNode() 96 node2.set_relative_from(ref) 97 node2.set_type("static") 98 node2.set_position(10., 0., 0.) 99 node2.set_rotation_matrix(one=(1., 0., 0.), 100 two=(0., N.cos(angle), N.sin(angle))) 101 102 The C{node1} is at M{10 m} from the origin, with an initial velocity 103 of M{1 m/s} along M{x} and an initial angular velocity of 104 M{1 rad/s} along M{z}. 105 The C{node2} does not have any momentum but is at M{20 m} from the origin 106 and its rotation matrix is turned of M{S{pi}/4} along the M{x} axis. 107 Those nodes can then be added to the L{Simulation}. 108 """ 109
110 - def __init__(self, name="structural node"):
111 Node.__init__(self, name) 112 self.mbdyn_type = "structural" 113 # Used for loading the node 114 self.group_key = "STRUCTURAL" 115 self.class_key = "structural" 116 117 self.control_data_with_values = [ 118 ("structural nodes", "+1 # %s" % name) 119 ] 120 121 self.position = None 122 self.rotation_matrix = None 123 self.velocity = None 124 125 self.arg_names += ["node_type", "position", 126 "rotation_matrix", "velocity", 127 "angular_velocity"] 128 129 self.ref = NONE_REF 130 self.simulation = None 131 self.set_default() 132 133 self.own_para_names += ["mbdyn_type", 134 "control_data_with_values", 135 "name", 136 "group_key", "class_key"] 137 138 self.will_save("position", 139 "rotation_matrix", 140 "velocity")
141
142 - def set_default(self):
143 """The default node is dynamic, with a null position offset, 144 a identity rotation matric, a null velocity offset and a null 145 angular velocity relative to its reference frame""" 146 self.set_type("dynamic") 147 self.set_position(NULL) 148 self.set_rotation_matrix(EYE) 149 self.set_velocity(NULL) 150 self.set_angular_velocity(NULL)
151
152 - def get_mbdyn_instance(self):
153 """Get the instance created by MBDyn when parsing 154 the input file. This instance, access by 'mbdyn_inst' can then 155 be used to communicate with MBDyn.""" 156 mbdyn_list = self.simulation.wm.nodes.structurals 157 self.mbdyn_inst = mbdyn_list.get_from_label(self.label)
158
159 - def init_results(self):
160 """Create the needed objects to save the results 161 during the simulation.""" 162 actions = {} 163 for attr_to_save in self.results.names: 164 actions[attr_to_save] = getattr(self.mbdyn_inst, 165 "get_" + attr_to_save) 166 self.has_saving_actions = True 167 self.saving_actions = actions 168 self.common_init_results()
169
170 - def set_position(self, *args, **kargs):
171 """Set the position of the node (offset relative to its 172 reference frame)""" 173 MANAGER.add_vector(self, "position", args, kargs)
174
175 - def set_rotation_matrix(self, *args, **kargs):
176 """Set the orientation matrix of the node (relative to its 177 reference frame)""" 178 MANAGER.add_orientation_matrix(self, "rotation_matrix", args, kargs)
179
180 - def set_velocity(self, *args, **kargs):
181 """Set the velocity of the node (relative to its reference frame)""" 182 MANAGER.add_vector(self, "velocity", args, kargs)
183
184 - def set_angular_velocity(self, *args, **kargs):
185 """Set the angular velocity of the node (relative 186 to its reference frame)""" 187 MANAGER.add_vector(self, "angular_velocity", args, kargs)
188
189 - def append(self, values):
190 """Append a MBDyn step to the results. 191 This method is not used any more due to the bindings module.""" 192 values_list = split_into_pieces_of_3(values) 193 #zipped_list = zip(self.results.quantity3d_names, values_list) 194 zipped_list = zip(self.results, values_list) 195 for quantity3d_name, three_values in zipped_list: 196 quantity3d = getattr(self.results, quantity3d_name) 197 for key, val in zip(quantity3d.direction_labels, three_values): 198 quantity3d[key].append(val)
199 200 201 NODE_CLASS = {} 202 NODE_CLASS["STRUCTURAL"] = {} 203 204 # This one does not make sense yet, it may in case of automatic 205 # node creation from a simulation started by WraptMBDyn (the Python module 206 # is in that case not used to write the MBDyn input file) 207 # NODE_CLASS["STRUCTURAL"]["general"] = Node 208 209 NODE_CLASS["STRUCTURAL"]["structural"] = StructuralNode 210