pyNastran  0.5.0
pyNastran BDF Reader/Writer, OP2 Parser, and GUI
rigid.py
Go to the documentation of this file.
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()
 All Classes Namespaces Files Functions Variables