pyNastran  0.5.0
pyNastran BDF Reader/Writer, OP2 Parser, and GUI
mass.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 from numpy import zeros,array
00029 
00030 from pyNastran.bdf.fieldWriter import set_blank_if_default
00031 from pyNastran.bdf.cards.baseCard import Element, BaseCard
00032 
00033 
00034 class PointElement(Element):
00035     def __init__(self, card=None, data=None):
00036         Element.__init__(self, card, data)
00037 
00038 class PointMassElement(PointElement):
00039     def __init__(self, card=None, data=None):
00040         self.mass = None
00041         PointElement.__init__(self, card, data)
00042 
00043     def Mass(self):
00044         return self.mass
00045 
00046 class PointMass(BaseCard):
00047     def __init__(self, card=None, data=None):
00048         self.mass = None
00049 
00050     def Mass(self):
00051         return self.mass
00052 
00053 
00054 class CMASS1(PointMass):
00055     """
00056     Defines a scalar mass element.
00057     CMASS2 EID M   G1 C1 G2 C2
00058     CMASS1 EID PID G1 C1 G2 C2
00059     """
00060     type = 'CMASS1'
00061     def __init__(self, card=None, data=None):
00062         PointMass.__init__(self, card, data)
00063         if card:
00064             self.eid = card.field(1)
00065             self.pid = card.field(2, self.eid)
00066             self.g1 = card.field(3)
00067             self.c1 = card.field(4)
00068             self.g2 = card.field(5)
00069             self.c2 = card.field(6)
00070         else:
00071             self.eid = data[0]
00072             self.pid = data[1]
00073             self.g1  = data[2]
00074             self.g2  = data[3]
00075             self.c1  = data[4]
00076             self.c2  = data[5]
00077         ###
00078 
00079     def Mass(self):
00080         return self.pid.mass
00081 
00082     def crossReference(self, model):
00083         #self.g1 = model.Node(self.g1)
00084         #self.g2 = model.Node(self.g2)
00085         self.pid = model.Property(self.pid)
00086 
00087     def Pid(self):
00088         if isinstance(self.pid, int):
00089             return self.pid
00090         return self.pid.pid
00091 
00092     def rawFields(self):
00093         fields = ['CMASS1',self.eid,self.Pid(),self.g1,self.c1,self.g2,self.c2]
00094         return fields
00095 
00096 class CMASS2(PointMassElement):
00097     """
00098     Defines a scalar mass element without reference to a property entry.
00099     CMASS2 EID M G1 C1 G2 C2
00100     """
00101     type = 'CMASS2'
00102     def __init__(self, card=None, data=None):
00103         PointMassElement.__init__(self, card, data)
00104         if card:
00105             self.eid  = card.field(1)
00106             self.mass = card.field(2, 0.)
00107             self.g1   = card.field(3)
00108             self.c1   = card.field(4)
00109             self.g2   = card.field(5)
00110             self.c2   = card.field(6)
00111         else:
00112             self.eid  = data[0]
00113             self.mass = data[1]
00114             self.g1   = data[2]
00115             self.g2   = data[3]
00116             self.c1   = data[4]
00117             self.c2   = data[5]
00118         ###
00119 
00120     def nodeIDs(self):
00121         g1 = self.G1()
00122         g2 = self.G2()
00123         nodes = []
00124         if g1:
00125             nodes.append(g1)
00126         if g2:
00127             nodes.append(g2)
00128         return nodes
00129 
00130     def Mass(self):
00131         return self.mass
00132     
00133     def Centroid(self):
00134         """
00135         Centroid is assumed to be c=(g1+g2)/2.
00136         If g2 is blank, then the centroid is the location of g1.
00137         """
00138         f=0.
00139         p1=array([0.,0.,0.])
00140         p2=array([0.,0.,0.])
00141         if self.g1 is not None:
00142             p1 = self.g1.Position()
00143             f+=1.
00144         if self.g2 is not None:
00145             p2 = self.g2.Position()
00146             f+=1.
00147 
00148         c = (p1+p2)/f
00149         return c
00150 
00151     def crossReference(self,mesh):
00152         if isinstance(self.g1,int):
00153             self.g1 = mesh.Node(self.g1)
00154         if isinstance(self.g2,int):
00155             self.g2 = mesh.Node(self.g2)
00156         ###
00157 
00158     def G1(self):
00159         if isinstance(self.g1,int):
00160             return self.g1
00161         elif self.g1 is None:
00162             return self.g1
00163         return self.g1.nid
00164 
00165     def G2(self):
00166         if isinstance(self.g2,int):
00167             return self.g2
00168         elif self.g2 is None:
00169             return self.g2
00170         return self.g2.nid
00171 
00172     def rawFields(self):
00173         fields = ['CMASS2',self.eid,self.mass,self.G1(),self.c1,self.G2(),self.c2]
00174         return fields
00175 
00176     def reprFields(self):
00177         mass = set_blank_if_default(self.mass, 0.)
00178         fields = ['CMASS2', self.eid, mass,self.G1(),self.c1,self.G2(),self.c2]
00179         #print "cmass2 fields = ",fields
00180         return fields
00181 
00182 class CMASS3(PointMassElement):
00183     """
00184     Defines a scalar mass element that is connected only to scalar points.
00185     CMASS3 EID PID S1 S2
00186     """
00187     type = 'CMASS3'
00188     def __init__(self, card=None, data=None):
00189         PointMass.__init__(self, card, data)
00190 
00191         if card:
00192             self.eid  = card.field(1)
00193             self.pid  = card.field(2,self.eid)
00194             self.s1   = card.field(3)
00195             self.s2   = card.field(4)
00196         else:
00197             self.eid = data[0]
00198             self.pid = data[1]
00199             self.s1  = data[2]
00200             self.s2  = data[3]
00201         ###
00202 
00203     def Mass(self):
00204         return self.pid.mass
00205 
00206     def isSameCard(self, elem, debug=False):
00207         if self.type!=elem.type:  return False
00208         fields1 = [self.eid,self.Pid(),self.s1,self.s2]
00209         fields2 = [elem.eid,elem.Pid(),elem.s1,elem.s2]
00210         if debug:
00211             print("fields1=%s fields2=%s" %(fields1, fields2))
00212         return self.isSameFields(fields1,fields2)
00213 
00214     def crossReference(self,mesh):
00215         """
00216         links up the propertiy ID
00217         """
00218         #self.s1 = mesh.Node(self.s1)
00219         #self.s2 = mesh.Node(self.s2)
00220         self.pid = mesh.Property(self.pid)
00221 
00222     def rawFields(self):
00223         fields = ['CMASS3',self.eid,self.Pid(),self.s1,self.s2]
00224         return fields
00225 
00226 class CMASS4(PointMassElement):
00227     """
00228     Defines a scalar mass element that is connected only to scalar points, without reference to a property entry
00229     CMASS4 EID M S1 S2
00230     """
00231     type = 'CMASS4'
00232     def __init__(self, card=None, data=None):
00233         PointMass.__init__(self, card, data)
00234         
00235         if card:
00236             self.eid  = card.field(1)
00237             self.mass = card.field(2,0.)
00238             self.s1 = card.field(3)
00239             self.s2 = card.field(4)
00240         else:
00241             self.eid  = data[0]
00242             self.mass = data[1]
00243             self.s1   = data[2]
00244             self.s2   = data[3]
00245         ###
00246 
00247     def Mass(self):
00248         return self.mass
00249 
00250     def isSameCard(self, elem, debug=False):
00251         if self.type!=elem.type:  return False
00252         fields1 = [self.eid,self.Pid(),self.s1,self.s2]
00253         fields2 = [elem.eid,elem.Pid(),elem.s1,elem.s2]
00254         if debug:
00255             print("fields1=%s fields2=%s" %(fields1, fields2))
00256         return self.isSameFields(fields1,fields2)
00257 
00258     def crossReference(self,mesh):
00259         """
00260         """
00261         #self.s1 = mesh.Node(self.s1)
00262         #self.s2 = mesh.Node(self.s2)
00263         pass
00264 
00265     def rawFields(self):
00266         fields = ['CMASS4',self.eid,self.mass,self.s1,self.s2]
00267         return fields
00268 
00269    
00270 class CONM1(PointMass):
00271     type = 'CONM1'
00272     def __init__(self, card=None, data=None):
00273         """
00274         Concentrated Mass Element Connection, General Form
00275         Defines a 6 x 6 symmetric mass matrix at a geometric grid point
00276         
00277         CONM1 EID G CID M11 M21 M22 M31 M32
00278               M33 M41 M42 M43 M44 M51 M52 M53
00279               M54 M55 M61 M62 M63 M64 M65 M66
00280 
00281         [M] = [M11 M21 M31 M41 M51 M61]
00282               [    M22 M32 M42 M52 M62]
00283               [        M33 M43 M53 M63]
00284               [            M44 M54 M64]
00285               [    Sym         M55 M65]
00286               [                    M66]
00287         """
00288         PointMass.__init__(self, card, data)
00289         m = zeros((6,6))
00290         if card:
00291             #self.nids  = [ card[1] ]
00292             #del self.nids
00293             #self.pid = None
00294             self.eid = card.field(1)
00295             self.nid = card.field(2)
00296             self.cid = card.field(3,0)
00297             
00298             m[0,0] = card.field(4, 0.)   # M11
00299             m[1,0] = card.field(5, 0.)   # M21
00300             m[1,1] = card.field(6, 0.)   # M22
00301             m[2,0] = card.field(7, 0.)   # M31
00302             m[2,1] = card.field(8, 0.)   # M32
00303             m[2,2] = card.field(9, 0.)   # M33
00304             m[3,0] = card.field(10, 0.)  # M41
00305             m[3,1] = card.field(11, 0.)  # M42
00306             m[3,2] = card.field(12, 0.)  # M43
00307             m[3,3] = card.field(13, 0.)  # M44
00308             m[4,0] = card.field(14, 0.)  # M51
00309             m[4,1] = card.field(15, 0.)  # M52
00310             m[4,2] = card.field(16, 0.)  # M53
00311             m[4,3] = card.field(17, 0.)  # M54
00312             m[4,4] = card.field(18, 0.)  # M55
00313             m[5,0] = card.field(19, 0.)  # M61
00314             m[5,1] = card.field(20, 0.)  # M62
00315             m[5,2] = card.field(21, 0.)  # M63
00316             m[5,3] = card.field(22, 0.)  # M64
00317             m[5,4] = card.field(23, 0.)  # M65
00318             m[5,5] = card.field(24, 0.)  # M66
00319         ###
00320         else:
00321             (eid,nid,cid,m1, m2a,m2b, m3a,m3b,m3c, m4a,m4b,m4c,m4d,
00322              m5a,m5b,m5c,m5d,m5e,  m6a,m6b,m6c,m6d,m6e,m6f) = data
00323             self.eid = eid
00324             self.nid = nid
00325             self.cid = cid
00326             m[0,0] = m1   # M11
00327             m[1,0] = m2a  # M21
00328             m[1,1] = m2b  # M22
00329             m[2,0] = m3a  # M31
00330             m[2,1] = m3b  # M32
00331             m[2,2] = m3c  # M33
00332             m[3,0] = m4a  # M41
00333             m[3,1] = m4b  # M42
00334             m[3,2] = m4c  # M43
00335             m[3,3] = m4d  # M44
00336             m[4,0] = m5a  # M51
00337             m[4,1] = m5b  # M52
00338             m[4,2] = m5c  # M53
00339             m[4,3] = m5d  # M54
00340             m[4,4] = m5e  # M55
00341             m[5,0] = m6a  # M61
00342             m[5,1] = m6b  # M62
00343             m[5,2] = m6c  # M63
00344             m[5,3] = m6d  # M64
00345             m[5,4] = m6e  # M65
00346             m[5,5] = m6f  # M66
00347         ###
00348         self.massMatrix = m
00349 
00350     def nodeIDs(self):
00351         return [self.Nid()]
00352 
00353     def Nid(self):
00354         if isinstance(self.nid, int):
00355             return self.nid
00356         return self.nid.nid
00357 
00358     def Cid(self):
00359         if isinstance(self.cid, int):
00360             return self.cid
00361         return self.cid.cid
00362 
00363     def crossReference(self, model):
00364         self.nid = model.Node(self.nid)
00365         self.cid = model.Coord(self.cid)
00366 
00367     def MassMatrix(self):
00368         return self.massMatrix
00369 
00370     def rawFields(self):
00371         cid  = set_blank_if_default(self.Cid(), 0)
00372         nid = self.Nid()
00373         m = self.massMatrix
00374         fields = ['CONM1',self.eid,nid,cid,m[0,0],m[1,0],m[1,1],m[2,0],m[2,1],
00375                  m[2,2],m[3,0],m[3,1],m[3,2],m[3,3],m[4,0],m[4,1],m[4,2],
00376                  m[4,3],m[4,4],m[5,0],m[5,1],m[5,2],m[5,3],m[5,4],m[5,5] ]
00377         return fields
00378 
00379     def reprFields(self):
00380         fields = self.rawFields()
00381         fields2 = fields[0:4]
00382         for field in fields[4:]:
00383             val = set_blank_if_default(field, 0.)
00384             #print "field=%s value=%s" %(field,val)
00385             fields2.append(val)
00386         #print "fields  = ",fields
00387         #print "fields2 = ",fields2
00388         return fields2
00389 
00390 class CONM2(PointMassElement): ## @todo not done
00391     """
00392     @param self the CONM2 object
00393     @param eid element ID
00394     @param nid node ID
00395     @param cid coordinate frame of the offset (-1=absolute coordinates)
00396     @param X offset vector
00397     @param I mass moment of inertia matrix about the CG
00398     """
00399     type = 'CONM2'
00400     # 'CONM2    501274  11064          132.274'
00401     def __init__(self, card=None, data=None):
00402         PointMassElement.__init__(self, card, data)
00403         if card:
00404             #self.nids  = [ card[1] ]
00405             #del self.nids
00406             #self.pid = None
00407             self.eid  = card.field(1)
00408             self.nid  = card.field(2)
00409             self.cid  = card.field(3, 0)
00410             self.mass = card.field(4, 0.)
00411             self.X    = array(card.fields(5, 8, [0., 0., 0.]))
00412             self.I    = card.fields(9, 15, [0.]*6)
00413         else:
00414             self.eid  = data[0]
00415             self.nid  = data[1]
00416             self.cid  = data[2]
00417             self.mass = data[3]
00418             self.X    = data[4:7]
00419             self.I    = data[7:]
00420         ###
00421 
00422     def Mass(self):
00423         return self.mass
00424 
00425     def Inertia(self):
00426         """
00427         Returns the 3x3 inertia matrix
00428         @warning doesnt handle offsets or coordinate systems
00429         """
00430         I = self.I
00431         A = [ [ I[0], I[1], I[3] ],
00432               [ I[1], I[2], I[4] ],
00433               [ I[3], I[4], I[5] ]]
00434         if self.Cid()==-1:
00435             return A
00436         else:
00437             # transform to global
00438             (dx, matrix) = self.cid.transformToGlobal(self.X)
00439             raise NotImplementedError()
00440             A2 = A*matrix
00441             return A2 # correct for offset using dx???
00442 
00443     def Centroid(self):
00444         if self.Cid()==0:
00445             X2  = self.nid.Position()+self.X
00446         elif self.Cid()==-1:
00447             return self.X
00448         else:
00449             dx,matrix = self.cid.transformToGlobal(self.X)
00450             #print "dx = ",dx
00451             #print "X  = ",self.nid.Position()
00452             X2  = self.nid.Position()+dx
00453         return X2
00454 
00455     def crossReference(self, model):
00456         if self.Cid()!=-1:
00457             self.cid = model.Coord(self.cid)
00458         self.nid = model.Node(self.nid)
00459 
00460     def nodeIDs(self):
00461         return [self.Nid()]
00462 
00463     def Nid(self):
00464         if isinstance(self.nid, int):
00465             return self.nid
00466         return self.nid.nid
00467 
00468     def Cid(self):
00469         if isinstance(self.cid, int):
00470             return self.cid
00471         return self.cid.cid
00472 
00473     def writeCodeAster(self):
00474         msg = ''
00475         msg += "    DISCRET=_F(\n"
00476         msg += "             'CARA='M_T_D_N'\n"
00477         msg += "              NOEUD=N%s\n" %(self.Nid())
00478         msg += "              VALE=%g),\n" %(self.mass)
00479         return msg
00480 
00481     def rawFields(self):
00482         #print "X=%r" %(self.X)
00483         #print "I=%r" %(self.I)
00484         fields = ['CONM2', self.eid, self.Nid(), self.Cid(), self.mass]+list(self.X)+[None]+list(self.I)
00485         return fields
00486 
00487     def reprFields(self):
00488         I = []
00489         for i in self.I:
00490             if i==0.:
00491                 I.append(None)
00492             else:
00493                 I.append(i)
00494             ###
00495         ###
00496         X = []
00497         for x in self.X:
00498             if x==0.:
00499                 X.append(None)
00500             else:
00501                 X.append(x)
00502             ###
00503         ###
00504 
00505         cid  = set_blank_if_default(self.Cid(), 0)
00506         mass = set_blank_if_default(self.mass, 0.)
00507         fields = ['CONM2', self.eid, self.Nid(), cid, mass]+X+[None]+I
00508         return fields
00509 
 All Classes Namespaces Files Functions Variables