Package mbdyn :: Module preprocessing
[hide private]

Source Code for Module mbdyn.preprocessing

  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 simulation work concerning the MBDyn pre-processing 
 23  and the writing of input files. This module defined also  
 24  the MultistepIntegrator.""" 
 25  import os 
 26   
 27  from mbdyn.common import Block, BasicObject 
 28  from mbdyn.groups import Nodes, Elements, ReferenceList 
 29  from mbdyn.control_data import ControlData 
 30   
 31   
32 -class LineArgument:
33 """An argument only displayed on one line for the integrator 34 """ 35
36 - def __init__(self, mbdyn_name, args):
37 self.name = mbdyn_name 38 # A tuple is converted to a list, as well as a single value 39 self.values = args 40 if type(args)==tuple: 41 self.args = list(args) 42 elif type(args)==list: 43 self.args = args 44 else: 45 self.args = [args]
46
47 - def to_string(self):
48 """Convert the line argument to string for the MBDyn input file""" 49 values = ", ".join([str(arg) for arg in self.args]) 50 return "%s: %s;" % (self.name, values)
51 52
53 -class ArgumentMethod:
54 """The method associated to an argument for the integrator 55 """ 56
57 - def __init__(self, obj, argument_name):
58 self.obj = obj 59 self.argument_name = argument_name
60
61 - def __call__(self, *value):
62 self.obj.add_argument(self.argument_name, value)
63 64
65 -def get_method_name(mbdyn_name):
66 """Return the method name for the argument method""" 67 return "set_" + mbdyn_name.replace(" ", "_")
68 69
70 -class MultistepIntegrator:
71 """The MBDyn multistep integrator. 72 """ 73
74 - def __init__(self, **kargs):
75 self.name = "multistep" 76 self.block = Block() 77 self.line_args = [] 78 self.line_arg_names = [] 79 self.mbdyn_attributes = ["method", "non linear solver", "tolerance", 80 "initial time", "final time", "time step", 81 "min time step", "max time step", 82 "max iterations", 83 "derivatives max iterations", 84 "derivatives tolerance", 85 "derivatives coefficient"] 86 self._build_methods() 87 self.set_property(**kargs)
88
89 - def set_property(self, **kargs):
90 """Set the properties on the integrator""" 91 for arg_name, values in kargs.items(): 92 method_name = get_method_name(arg_name) 93 self.__dict__[method_name](values)
94
95 - def add_argument(self, arg_name, value):
96 """Add an argument chosen by the user to the integrator""" 97 self.line_arg_names.append(arg_name) 98 self.line_args.append(LineArgument(arg_name, value))
99
100 - def _build_methods(self):
101 """Build all the possible options defined in 'mbdyn_attributes'.""" 102 for mbdyn_attribute in self.mbdyn_attributes: 103 method_name = get_method_name(mbdyn_attribute) 104 method = ArgumentMethod(self, mbdyn_attribute) 105 setattr(self, method_name, method)
106
107 - def __getitem__(self, arg_name):
108 """Return the values of an argument entered by the user""" 109 indice = self.line_arg_names.index(arg_name) 110 values = self.line_args[indice].values 111 if len(values) == 1: 112 return values[0] 113 else: 114 return values
115
116 - def write_into(self, file_to_write):
117 """Write the integrator block into the MBDyn input file""" 118 self.block.set_file(file_to_write) 119 self.block.set_name("data") 120 self.block.begin("data") 121 self.block.write_line(LineArgument("integrator", self.name).to_string()) 122 self.block.end() 123 self.block.write_line("") 124 self.block.set_name(self.name) 125 self.block.begin() 126 for line_arg in self.line_args: 127 self.block.write_line(line_arg.to_string()) 128 self.block.end()
129 130
131 -class SimulationBase(BasicObject):
132 """The base of the Simulation. This class will mainly handle 133 the writing of the MBDyn input file, as well as cleaning the 134 directory used for the simulation. This class is always 135 abstract, a help for defining the Simulation one. 136 """
137 - def __init__(self, name, title, keep, overwrite):
138 BasicObject.__init__(self, name) 139 140 self.title = title 141 words = self.name.split() 142 capitalized_words = [word.capitalize() for word in words[1:]] 143 self.os_name = words[0].lower() + "".join(capitalized_words) 144 145 self.nodes = Nodes() 146 self.elts = Elements() 147 self.refs = ReferenceList() 148 self.control_data = ControlData() 149 150 # A default integrator, may need to be removed because confusing? 151 self.integrator = MultistepIntegrator(initial_time = 0., 152 final_time = 2., 153 time_step = 1e-3, 154 max_iterations = 10, 155 tolerance = 1e-6) 156 157 self.create_dir = None 158 self.clean = None 159 self._overwrite = overwrite 160 self.keep_mbdyn_files(keep) 161 162 self.file_name = None 163 self.dir = None 164 165 self.has_aero_data = False 166 self.has_written = False 167 self.offset = 0
168
169 - def set_node_numerotation_offset(self, offset):
170 """An offset only use for writing the MBDyn input file and avoiding 171 integer conflict in the automatic node numbering.""" 172 self.offset = int(offset)
173
174 - def keep_mbdyn_files(self, keep):
175 """If True, will keep the MBDyn files""" 176 if keep: 177 self.create_dir = self.create_dir_simu 178 self.clean = self.clean_dir_simu 179 else: 180 self.create_dir = self.create_dir_tmp 181 self.clean = self.clean_dir_tmp
182
183 - def create_dir_tmp(self):
184 """Create the temporary directory for storing MBDyn files""" 185 import tempfile 186 self.dir = tempfile.mkdtemp(suffix="_mbdyn", dir=os.getcwd())
187
188 - def create_dir_simu(self):
189 """Create the directory where to keep the MBDyn files""" 190 if os.path.exists(self.os_name): 191 if not self._overwrite: 192 mess = "'%s' already exists" % self.os_name 193 mess += ", mbdyn will not write into it." + os.linesep 194 mess += "It is needed to delete " 195 mess += "or rename it for starting the simulation" 196 print mess 197 import sys 198 sys.exit() 199 else: 200 os.mkdir(self.os_name) 201 self.dir = self.os_name
202
203 - def clean_dir_simu(self, name_pattern=None):
204 """Will not clear the directory but indicates where are the files""" 205 print "All mbdyn's files are in the directory: '%s'." % self.dir
206
207 - def clean_dir_tmp(self, name_pattern=None):
208 """Clean the temporary directory with MBDyn files on the simulation 209 is finished.""" 210 if name_pattern == None: 211 name_pattern = self.os_name 212 files_ext = [".frc", ".ine", ".log", ".out", ".mov", ".jnt"] 213 files_to_remove = [self.os_name] 214 for ext in files_ext: 215 files_to_remove.append(name_pattern + ext) 216 for file_name in files_to_remove: 217 file_path = os.path.join(self.dir, file_name) 218 if os.path.exists(file_path): 219 try: 220 os.remove(file_path) 221 except WindowsError: 222 print "Impossible to remove the file" \ 223 " '%s' because of Bill!" % file_path 224 return 225 try: 226 os.rmdir(self.dir) 227 except OSError: 228 print "Warning, '%s' directory could not be removed" % self.dir 229 raise 230 except WindowsError: 231 print "The '%s' directory could be removed because" \ 232 " of Bill!"
233
234 - def _set_labels_and_names(self):
235 """Set the labels all the MBDyn items and rename some of the items 236 if necessary.""" 237 for group in self.nodes.groups.values() + \ 238 self.elts.groups.values() + [self.refs]: 239 group.set_labels_auto() 240 group.set_names_auto()
241 # Only for the aeordynamic beam 242 #if counter.has_key("aerodynamic beam"): 243 # self.has_aero_data = True 244 # for elt in self.elts: 245 # if elt.mbdyn_type == "aerodynamic beam": 246 # self._aero_beam = elt 247
248 - def write(self):
249 """Write the MBDyn file""" 250 # Maybe to put in the writeInto 251 self._set_labels_and_names() 252 self.elts.set_node_connectivity() 253 self.create_dir() 254 self.file_name = os.path.join(self.dir, self.os_name) 255 input_file = open(self.file_name, "w") 256 input_file.write("# " + self.title + os.linesep) 257 # A dirty test, needs to be removed by modifying 258 # the MBDyn source code: the profile data can not be 259 # defined direclty in the objects but at the beginning 260 # of the input file. 261 #if self.has_aero_data: 262 # for airfoil_data in self._aero_beam.mbdyn_airfoil_data: 263 # input_file.write(airfoil_data + os.linesep) 264 input_file.write(os.linesep) 265 # End of the dirty test 266 for obj in [self.integrator, self.control_data, 267 self.refs, self.nodes, self.elts]: 268 obj.write_into(input_file) 269 input_file.write(os.linesep) 270 input_file.close()
271
272 - def add_control_data(self, argument):
273 """Add an argument to the control data block""" 274 self.control_data.add_extra_argument(argument)
275