pyNastran
0.5.0
pyNastran BDF Reader/Writer, OP2 Parser, and GUI
|
00001 ## GNU Lesser General Public License 00002 ## 00003 ## Program pyNastran - a python interface to NASTRAN files 00004 ## Copyright (C) 2011-2012 Steven Doyle, Al Danial 00005 ## 00006 ## Authors and copyright holders of pyNastran 00007 ## Steven Doyle <mesheb82@gmail.com> 00008 ## Al Danial <al.danial@gmail.com> 00009 ## 00010 ## This file is part of pyNastran. 00011 ## 00012 ## pyNastran is free software: you can redistribute it and/or modify 00013 ## it under the terms of the GNU Lesser General Public License as published by 00014 ## the Free Software Foundation, either version 3 of the License, or 00015 ## (at your option) any later version. 00016 ## 00017 ## pyNastran is distributed in the hope that it will be useful, 00018 ## but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 ## GNU General Public License for more details. 00021 ## 00022 ## You should have received a copy of the GNU Lesser General Public License 00023 ## along with pyNastran. If not, see <http://www.gnu.org/licenses/>. 00024 ## 00025 # pylint: disable=C0103,R0902,R0904,R0914 00026 00027 from __future__ import division, print_function 00028 #import sys 00029 from itertools import izip, count 00030 00031 from pyNastran.bdf.fieldWriter import set_blank_if_default 00032 from pyNastran.bdf.cards.baseCard import Element 00033 00034 class RigidElement(Element): 00035 #def __repr__(self): 00036 #fields = [self.type, self.eid] 00037 #return self.printCard(fields) 00038 def crossReference(self, model): 00039 pass 00040 00041 class RBAR(RigidElement): 00042 type = 'RBAR' 00043 def __init__(self, card=None, data=None): 00044 """ 00045 RBAR EID GA GB CNA CNB CMA CMB ALPHA 00046 RBAR 5 1 2 123456 6.5-6 00047 """ 00048 RigidElement.__init__(self, card, data) 00049 if card: 00050 self.eid = card.field(1) 00051 self.ga = card.field(2) 00052 self.gb = card.field(3) 00053 self.cna = card.field(4) 00054 self.cnb = card.field(5) 00055 self.cma = card.field(6) 00056 self.cmb = card.field(7) 00057 self.alpha = card.field(8, 0.0) 00058 else: 00059 self.eid = data[0] 00060 self.ga = data[1] 00061 self.gb = data[2] 00062 self.cna = data[3] 00063 self.cnb = data[4] 00064 self.cma = data[5] 00065 self.cmb = data[6] 00066 self.alpha = data[7] 00067 ### 00068 00069 def convertToMPC(self, mpcID): 00070 """ 00071 -Ai*ui + Aj*uj = 0 00072 where ui are the base DOFs (max=6) 00073 mpc sid g1 c1 a1 g2 c2 a2 00074 rbe2 eid gn cm g1 g2 g3 g4 00075 """ 00076 raise NotImplementedError() 00077 #i = 0 00078 nCM = len(self.cm) 00079 Ai = nCM*len(self.Gmi)/len(self.gn) # where nGN=1 00080 00081 card = ['MPC', mpcID] 00082 for cm in self.cm: # the minus sign is applied to the base node 00083 card += [self.gn, cm, -Ai] 00084 00085 for gm in self.Gmi: 00086 for cm in self.cm: 00087 card += [gm, cm, Ai] 00088 return card 00089 00090 #def writeCodeAster(self): 00091 #msg = '' 00092 #msg += "BLOCAGE=AFFE_CHAR_MECA( # RBAR\n" 00093 #msg += " MODELE=MODELE,\n" # rigid element 00094 #msg += " \n" 00095 #return msg 00096 00097 def rawFields(self): 00098 fields = ['RBAR', self.eid, self.ga, self.gb, self.cna, self.cnb, self.cma, self.cmb, self.alpha] 00099 return fields 00100 00101 def reprFields(self): 00102 alpha = set_blank_if_default(self.alpha, 0.0) 00103 fields = ['RBAR', self.eid, self.ga,self.gb, self.cna, self.cnb, self.cma, self.cmb, alpha] 00104 return fields 00105 00106 class RBAR1(RigidElement): 00107 type = 'RBAR1' 00108 def __init__(self, card=None, data=None): 00109 """ 00110 RBAR1 EID GA GB CB ALPHA 00111 RBAR1 5 1 2 123 6.5-6 00112 """ 00113 RigidElement.__init__(self, card, data) 00114 if card: 00115 self.eid = card.field(1) 00116 self.ga = card.field(2) 00117 self.gb = card.field(3) 00118 self.cb = card.field(4) 00119 self.alpha = card.field(5) 00120 else: 00121 self.eid = data[0] 00122 self.ga = data[1] 00123 self.gb = data[2] 00124 self.cb = data[3] 00125 self.alpha = data[4] 00126 ### 00127 00128 def rawFields(self): 00129 fields = ['RBAR1', self.eid, self.ga, self.gb, self.cb, self.alpha] 00130 return fields 00131 00132 def reprFields(self): 00133 alpha = set_blank_if_default(self.alpha, 0.0) 00134 fields = ['RBAR1', self.eid, self.ga, self.gb, self.cb, alpha] 00135 return fields 00136 00137 class RBE1(RigidElement): # maybe not done, needs testing 00138 type = 'RBE1' 00139 def __init__(self, card=None, data=None): 00140 RigidElement.__init__(self, card, data) 00141 self.eid = card.field(1) 00142 self.Gni = [] 00143 self.Cni = [] 00144 00145 fields = card.fields(2) 00146 iUm = fields.index('UM')+2 00147 if isinstance(fields[-1],float): 00148 self.alpha = fields.pop() # the last field is not part of fields 00149 nFields = card.nFields()-1 00150 else: 00151 nFields = card.nFields() 00152 self.alpha = 0. 00153 00154 # loop till UM, no field9,field10 00155 i=2 00156 #print "iUm = %s" %(iUm) 00157 while i<iUm: 00158 gni = card.field(i) 00159 #if gni: 00160 cni = card.field(i+1) 00161 self.Gni.append(gni) 00162 self.Cni.append(cni) 00163 #print "gni=%s cni=%s" %(gni,cni) 00164 if i%6==0: 00165 i+=2 00166 i+=2 00167 ### 00168 00169 self.Gmi = [] 00170 self.Cmi = [] 00171 #print "" 00172 #print "i=%s iUm=%s card.field(iUm)=%s" %(i,iUm,card.field(iUm)) 00173 # loop till alpha, no field9,field10 00174 while i < nFields: # dont grab alpha 00175 gmi = card.field(i) 00176 cmi = card.field(i+1) 00177 if gmi: 00178 #print "gmi=%s cmi=%s" %(gmi,cmi) 00179 self.Gmi.append(gmi) 00180 self.Cmi.append(cmi) 00181 #else: 00182 #print "---" 00183 #if i%8==0: 00184 # i+=2 00185 i+=2 00186 ### 00187 #print self 00188 00189 def rawFields(self): 00190 fields = [self.type, self.eid] 00191 00192 if 0: 00193 fields2 = [self.eid] 00194 for (i, gn, cn) in izip(count(), self.Gni, self.Cni): 00195 fields+=[gn,cn] 00196 fields += self.buildTableLines(fields2, i=1, j=1) 00197 00198 for (i, gn, cn) in izip(count(), self.Gni, self.Cni): 00199 fields+=[gn, cn] 00200 if i%6==0: 00201 fields += [None] 00202 ### 00203 ### 00204 nSpaces = 8-(len(fields)-1)%8 # puts ALPHA onto next line 00205 if nSpaces<8: 00206 fields += [None]*nSpaces 00207 00208 if 0: 00209 fields2 = ['UM'] 00210 for (i, gm, cm) in izip(count(), self.Gmi, self.Cmi): 00211 #print "j=%s gmi=%s cmi=%s" %(j,gm,cm) 00212 fields2 += [gm, cm] 00213 fields += self.buildTableLines(fields2, i=1, j=1) 00214 fields = self.wipeFields(fields) 00215 00216 ## overly complicated loop to print the UM section 00217 fields += ['UM'] 00218 j=1 00219 for (i, gm, cm) in izip(count(), self.Gmi, self.Cmi): 00220 #print "j=%s gmi=%s cmi=%s" %(j,gm,cm) 00221 fields+=[gm, cm] 00222 if i>0 and j%3==0: 00223 fields += [None,None] 00224 #print "---" 00225 j-=3 00226 j+=1 00227 ### 00228 ### 00229 nSpaces = 8-(len(fields)-1)%8 # puts ALPHA onto next line 00230 if nSpaces==1: 00231 fields += [None, None] 00232 if self.alpha>0.: # handles default alpha value 00233 fields += [self.alpha] 00234 return fields 00235 00236 def reprFields(self): 00237 return self.rawFields() 00238 00239 class RBE2(RigidElement): 00240 type = 'RBE2' 00241 def __init__(self, card=None, data=None): 00242 """ 00243 RBE2 EID GN CM GM1 GM2 GM3 GM4 GM5 00244 GM6 GM7 GM8 -etc.- ALPHA 00245 """ 00246 RigidElement.__init__(self, card, data) 00247 if card: 00248 ## Element identification number 00249 self.eid = card.field(1) 00250 ## Identification number of grid point to which all six independent 00251 ## degrees-of-freedom for the element are assigned. (Integer > 0) 00252 self.gn = card.field(2) 00253 ## Component numbers of the dependent degrees-of-freedom in the 00254 ## global coordinate system at grid points GMi. (Integers 1 through 00255 ## 6 with no embedded blanks.) 00256 self.cm = card.field(3) # 123456 constraint or other 00257 ## Grid point identification numbers at which dependent 00258 ## degrees-of-freedom are assigned. (Integer > 0) 00259 self.Gmi = card.fields(4) # get the rest of the fields 00260 if len(self.Gmi)>0 and isinstance(self.Gmi[-1], float): 00261 ## Thermal expansion coefficient. See Remark 11. 00262 ## (Real > 0.0 or blank) 00263 self.alpha = self.Gmi.pop() # the last field is not part of Gmi 00264 else: 00265 self.alpha = 0.0 00266 ### 00267 else: 00268 self.eid = data[0] 00269 self.gn = data[1] 00270 self.cm = data[2] 00271 self.Gmi = data[3] 00272 self.alpha = data[4] 00273 print("eid=%s gn=%s cm=%s Gmi=%s alpha=%s" 00274 %(self.eid, self.gn, self.cm, self.Gmi, self.alpha)) 00275 raise NotImplementedError('RBE2 data...') 00276 ### 00277 assert self.gn != None 00278 assert self.cm != None 00279 self.gn = str(self.gn) 00280 self.cm = str(self.cm) 00281 00282 def convertToMPC(self,mpcID): 00283 """ 00284 -Ai*ui + Aj*uj = 0 00285 where ui are the base DOFs (max=6) 00286 mpc sid g1 c1 a1 g2 c2 a2 00287 rbe2 eid gn cm g1 g2 g3 g4 00288 """ 00289 #i = 0 00290 nCM = len(self.cm) 00291 Ai = nCM*len(self.Gmi)/len(self.gn) # where nGN=1 00292 00293 card = ['MPC',mpcID] 00294 for cm in self.cm: # the minus sign is applied to the base node 00295 card += [self.gn, cm, -Ai] 00296 00297 for gm in self.Gmi: 00298 for cm in self.cm: 00299 card += [gm, cm, Ai] 00300 return card 00301 00302 def writeCodeAster(self): 00303 """ 00304 Converts to a LIAISON SOLIDE for dofs 123456. 00305 For other dof combinations, general MPC equations are written 00306 """ 00307 msg = '' 00308 msg += "BLOCAGE=AFFE_CHAR_MECA( # RBE2 ID=%s\n" %(self.eid) 00309 msg += " MODELE=MODELE,\n" # rigid element 00310 if self.cm==123456: 00311 msg += " LIASON_SOLIDE=(\n" 00312 msg += " _F(NOEUD=\n" 00313 msg += " " 00314 for nid in self.Gmi: 00315 msg += "'N%i'," %(nid) 00316 msg = msg[:-1] 00317 msg += '\n' 00318 else: 00319 msg += " _F(NOEUD= # doesnt handle coordinate systems\n" 00320 msg += " " 00321 for nid in self.Gmi: 00322 msg += "'N%i'," %(nid) 00323 msg = msg[:-1] 00324 msg += '\n' 00325 00326 #msg += " \n" 00327 #msg += " \n" 00328 #msg += " \n" 00329 #msg += " \n" 00330 #msg += " \n" 00331 return msg 00332 00333 def rawFields(self): 00334 fields = ['RBE2', self.eid, self.gn, self.cm]+self.Gmi+[self.alpha] 00335 return fields 00336 00337 def reprFields(self): 00338 alpha = set_blank_if_default(self.alpha, 0.) 00339 fields = ['RBE2', self.eid, self.gn, self.cm]+self.Gmi+[alpha] 00340 return fields 00341 00342 class RBE3(RigidElement): # not done, needs testing badly 00343 type = 'RBE3' 00344 def __init__(self, card=None, data=None): 00345 """ 00346 eid 00347 refgrid 00348 refc 00349 WtCG_groups = [wt,ci,Gij] 00350 Gmi 00351 Cmi 00352 alpha 00353 """ 00354 RigidElement.__init__(self, card, data) 00355 self.eid = card.field(1) 00356 self.refgrid = card.field(3) 00357 self.refc = card.field(4) 00358 #fields = card.fields(5) 00359 #iUM = fields.index('UM') 00360 00361 fields = card.fields(5) 00362 #print "fields = ",fields 00363 iOffset = 5 00364 iWtMax = len(fields)+iOffset 00365 try: 00366 iAlpha = fields.index('ALPHA')+iOffset 00367 iWtMax = iAlpha # the index to start parsing UM 00368 iUmStop = iAlpha # the index to stop parsing UM 00369 except ValueError: 00370 iAlpha = None 00371 iUmStop = iWtMax 00372 #print "iAlpha = ",iAlpha 00373 try: 00374 iUm = fields.index('UM')+iOffset 00375 iWtMax = iUm 00376 except ValueError: 00377 iUm = None 00378 #print "iAlpha=%s iUm=%s" %(iAlpha,iUm) 00379 #print "iAlpha=%s iWtMax=%s" %(iAlpha,iWtMax) 00380 00381 #print "iUM = ",iUM 00382 self.WtCG_groups = [] 00383 00384 i=iOffset 00385 while i<iWtMax: 00386 Gij = [] 00387 wt = card.field(i) 00388 if wt is not None: 00389 ci = card.field(i+1) 00390 #print "wt=%s ci=%s" %(wt,ci) 00391 i+=2 00392 gij = 0 00393 while isinstance(gij, int) and i<iWtMax: 00394 gij = card.field(i) 00395 if gij is not None: 00396 Gij.append(gij) 00397 i+=1 00398 ### 00399 self.WtCG_groups.append([wt,ci,Gij]) 00400 else: 00401 i+=1 00402 ### 00403 ### 00404 00405 self.Gmi = [] 00406 self.Cmi = [] 00407 #print "" 00408 if iUm: 00409 i = iUm+1 00410 #print "i=%s iUmStop=%s" %(i,iUmStop) 00411 for j in xrange(i, iUmStop, 2): 00412 gmi = card.field(j) 00413 if gmi is not None: 00414 cmi = card.field(j+1) 00415 #print "gmi=%s cmi=%s" %(gmi,cmi) 00416 self.Gmi.append(gmi) 00417 self.Cmi.append(cmi) 00418 ### 00419 ### 00420 ### 00421 if iAlpha: 00422 self.alpha = card.field(iAlpha+1) 00423 else: 00424 ## thermal expansion coefficient 00425 self.alpha = 0.0 00426 ### 00427 #print self 00428 00429 def convertToMPC(self, mpcID): 00430 """ 00431 -Ai*ui + Aj*uj = 0 00432 where ui are the base DOFs (max=6) 00433 mpc sid g1 c1 a1 g2 c2 a2 00434 rbe2 eid gn cm g1 g2 g3 g4 00435 """ 00436 raise NotImplementedError('this is the code for an RBE2...not RBE3') 00437 #i = 0 00438 nCM = len(self.cm) 00439 Ai = nCM*len(self.Gmi)/len(self.gn) # where nGN=1 00440 00441 card = ['MPC', mpcID] 00442 for cm in self.cm: # the minus sign is applied to the base node 00443 card += [self.gn, cm, -Ai] 00444 00445 for gm in self.Gmi: 00446 for cm in self.cm: 00447 card += [gm, cm, Ai] 00448 return card 00449 00450 def rawFields(self): 00451 fields = ['RBE3', self.eid, None, self.refgrid, self.refc] 00452 for (wt,ci,Gij) in self.WtCG_groups: 00453 #print 'wt=%s ci=%s Gij=%s' %(wt,ci,Gij) 00454 fields+=[wt, ci]+Gij 00455 nSpaces = 8-(len(fields)-1)%8 # puts UM onto next line 00456 #print "nSpaces = ",nSpaces 00457 if nSpaces<8: 00458 fields += [None]*nSpaces 00459 00460 if self.Gmi and 0: 00461 fields2 = ['UM'] 00462 for (gmi,cmi) in izip(self.Gmi, self.Cmi): 00463 fields2 += [gmi, cmi] 00464 ### 00465 fields += self.buildTableLines(fields2, i=1, j=1) 00466 00467 if self.Gmi: 00468 fields += ['UM'] 00469 if self.Gmi: 00470 #print "Gmi = ",self.Gmi 00471 #print "Cmi = ",self.Cmi 00472 for (gmi,cmi) in izip(self.Gmi, self.Cmi): 00473 fields+=[gmi, cmi] 00474 ### 00475 ### 00476 nSpaces = 8-(len(fields)-1)%8 # puts ALPHA onto next line 00477 if nSpaces<8: 00478 fields += [None]*nSpaces 00479 #print "nSpaces = ",nSpaces 00480 if self.alpha>0.: # handles the default value 00481 fields += ['ALPHA', self.alpha] 00482 return fields 00483 00484 def reprFields(self): 00485 return self.rawFields()