pyNastran  0.5.0
pyNastran BDF Reader/Writer, OP2 Parser, and GUI
properties.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 
00030 from pyNastran.bdf.fieldWriter import set_blank_if_default
00031 from pyNastran.bdf.cards.baseCard import Property
00032 
00033 class PFAST(Property):
00034     type = 'PFAST'
00035     def __init__(self, card=None, data=None):
00036         Property.__init__(self, card, data)
00037         ## Property ID
00038         self.pid   = card.field(1)
00039         ## diameter of the fastener
00040         self.d     = card.field(2)
00041         ## Specifies the element stiffness coordinate system
00042         self.mcid  = card.field(3, -1)
00043         self.mflag = card.field(4, 0) # 0-absolute 1-relative
00044         ## stiffness values in directions 1-3
00045         self.kt1 = card.field(5)
00046         self.kt2 = card.field(6)
00047         self.kt3 = card.field(7)
00048         ## Rotational stiffness values in directions 1-3
00049         self.kr1 = card.field(8, 0.0)
00050         self.kr2 = card.field(9, 0.0)
00051         self.kr3 = card.field(10, 0.0)
00052         ## Lumped mass of fastener
00053         self.mass = card.field(11, 0.0)
00054         ## Structural damping
00055         self.ge   = card.field(12, 0.0)
00056 
00057     def crossReference(self, model):
00058         self.mcid = model.Coord(self.mcid)
00059     
00060     def Mcid(self):
00061         if isinstance(self.mcid, int):
00062             return self.mcid
00063         return self.mcid.cid
00064 
00065     def Mass(self):
00066         return self.mass
00067 
00068     def rawFields(self):
00069         fields = ['PFAST',self.pid,self.d,self.Mcid(),self.mflag,self.kt1,self.kt2,self.kt3,self.kr1,
00070                           self.kr2,self.kr3,self.mass,self.ge]
00071         return fields
00072 
00073     def reprFields(self):
00074         mcid = set_blank_if_default(self.mcid, -1)
00075         mflag = set_blank_if_default(self.mflag, 0)
00076         kr1 = set_blank_if_default(self.kr1, 0.0)
00077         kr2 = set_blank_if_default(self.kr2, 0.0)
00078         kr3 = set_blank_if_default(self.kr3, 0.0)
00079 
00080         mass = set_blank_if_default(self.mass, 0.0)
00081         ge = set_blank_if_default(self.ge, 0.0)
00082         fields = ['PFAST',self.pid,self.d,mcid,mflag,self.kt1,self.kt2,self.kt3,kr1,
00083                           kr2,kr3,mass,ge]
00084         return fields
00085 
00086 class PGAP(Property):
00087     type = 'PGAP'
00088     def __init__(self, card=None, data=None):
00089         """
00090         Defines the properties of the gap element (CGAP entry).
00091         """
00092         Property.__init__(self, card, data)
00093         if card:
00094             ## Property ID
00095             self.pid   = card.field(1)
00096             ## initial gap opening
00097             self.u0    = card.field(2, 0.)
00098             ## preload
00099             self.f0    = card.field(3, 0.)
00100             ## axial stiffness of closed gap
00101             self.ka    = card.field(4, 1.e8)
00102             ## axial stiffness of open gap
00103             self.kb    = card.field(5, 1e-14*self.ka)
00104             ## static friction coeff
00105             self.mu1   = card.field(7, 0.)
00106             ## transverse stiffness of closed gap
00107             self.kt    = card.field(6, self.mu1*self.ka)
00108             ## kinetic friction coeff
00109             self.mu2   = card.field(8, self.mu1)
00110             self.tmax  = card.field(9, 0.)
00111             self.mar   = card.field(10, 100.)
00112             self.trmin = card.field(11, 0.001)
00113         else:
00114             #(pid,u0,f0,ka,kb,kt,mu1,mu2,tmax,mar,trmin) = out
00115             self.pid   = data[0]
00116             self.u0    = data[1]
00117             self.f0    = data[2]
00118             self.ka    = data[3]
00119             self.kb    = data[4]
00120             self.kt    = data[5]
00121             self.mu1   = data[6]
00122             self.mu2   = data[7]
00123             self.tmax  = data[8]
00124             self.mar   = data[9]
00125             self.trmin = data[10]
00126         ###
00127 
00128     def crossReference(self, model):
00129         pass
00130 
00131     def rawFields(self):
00132         fields = ['PGAP',self.pid,self.u0,self.f0,self.ka,self.kb,self.kt,self.mu1,self.mu2,
00133                          self.tmax,self.mar,self.trmin]
00134         return fields
00135 
00136     def reprFields(self):
00137         u0    = set_blank_if_default(self.u0, 0.)
00138         f0    = set_blank_if_default(self.f0, 0.)
00139         ka    = set_blank_if_default(self.ka, 1.e8)
00140         kb    = set_blank_if_default(self.kb, 1e-14*self.ka)
00141         kt    = set_blank_if_default(self.kt, self.mu1*self.ka)
00142         mu1   = set_blank_if_default(self.mu1, 0.)
00143         mu2   = set_blank_if_default(self.mu2, self.mu1)
00144         tmax  = set_blank_if_default(self.tmax, 0.)
00145         mar   = set_blank_if_default(self.mar, 100.)
00146         trmin = set_blank_if_default(self.trmin, 0.001)
00147         
00148         fields = ['PGAP',self.pid, u0, f0, ka, kb, kt, mu1, mu2,
00149                          tmax, mar, trmin]
00150         return fields
00151 
00152 class SolidProperty(Property):
00153     type = 'SolidProperty'
00154     def __init__(self, card, data):
00155         Property.__init__(self, card, data)
00156 
00157     def Rho(self):
00158         self.mid.rho
00159 
00160 class PLSOLID(SolidProperty):
00161     """
00162     Defines a fully nonlinear (i.e., large strain and large rotation) hyperelastic solid
00163     element.
00164     PLSOLID PID MID STR
00165     PLSOLID 20 21
00166     """
00167     type = 'PLSOLID'
00168     def __init__(self, card=None, data=None):
00169         SolidProperty.__init__(self, card, data)
00170         if card:
00171             ## Property ID
00172             self.pid = card.field(1)
00173             ## Material ID
00174             self.mid = card.field(2)
00175             self.ge  = card.field(3)
00176             self.str = card.field(4, 'GRID')
00177         else:
00178             self.pid = data[0]
00179             self.mid = data[1]
00180             self.ge  = data[2]
00181             self.str = data[3]
00182         ###
00183         assert self.str in ['GRID','GAUS'],'STR=|%s| doesnt have a valid stress/strain output value set\n' %(self.str)
00184 
00185     def crossReference(self, model):
00186         self.mid = model.Material(self.mid)
00187 
00188     def rawFields(self):
00189         stressStrain = set_blank_if_default(self.str, 'GRID')
00190         fields = ['PLSOLID', self.pid, self.Mid(), stressStrain]
00191         return fields
00192 
00193 class PSOLID(SolidProperty):
00194     """
00195     PSOLID PID MID CORDM IN STRESS ISOP FCTN
00196     PSOLID   1       1       0
00197     PSOLID 2 100 6 TWO GRID REDUCED
00198     """
00199     type = 'PSOLID'
00200     def __init__(self, card=None, data=None):
00201         SolidProperty.__init__(self, card, data)
00202         if card:
00203             ## Property ID
00204             self.pid    = card.field(1)
00205             ## Material ID
00206             self.mid    = card.field(2)
00207             self.cordm  = card.field(3, 0)
00208             self.integ  = card.field(4)
00209             #validIntegration = ['THREE','TWO','FULL','BUBBLE',2,3,None,'REDUCED']
00210             self.stress = card.field(5)
00211             self.isop   = card.field(6)
00212             self.fctn   = card.field(7, 'SMECH')
00213         else:
00214             self.pid    = data[0]
00215             self.mid    = data[1]
00216             self.cordm  = data[2]
00217             self.integ  = data[3]
00218             self.stress = data[4]
00219             self.isop   = data[5]
00220             self.fctn   = data[6]
00221 
00222             if self.fctn == 'SMEC':
00223                 self.fctn = 'SMECH'
00224         ###
00225 
00226     def writeCalculix(self, elementSet=999):
00227         msg = '*SOLID SECTION,MATERIAL=M%s,ELSET=E_Mat%s\n' %(self.mid, elementSet)
00228         return msg
00229 
00230     def rawFields(self):
00231         fields = ['PSOLID',self.pid,self.Mid(),self.cordm,self.integ,self.stress,self.isop,self.fctn]
00232         return fields
00233 
00234     def reprFields(self):
00235         cordm = set_blank_if_default(self.cordm, 0)
00236         fctn  = set_blank_if_default(self.fctn, 'SMECH')
00237         fields = ['PSOLID',self.pid,self.Mid(),cordm,self.integ,self.stress,self.isop,fctn]
00238         return fields
00239 
00240 class CrackProperty(Property):
00241     def __init__(self, card, data):
00242         pass
00243 
00244     def Mid(self):
00245         if isinstance(self.mid, int):
00246             return self.mid
00247         return self.mid.mid
00248 
00249 class PRAC2D(CrackProperty):
00250     """
00251     CRAC2D Element Property
00252     Defines the properties and stress evaluation techniques to be used with the CRAC2D
00253     structural element.
00254     """
00255     type = 'PRAC2D'
00256     def __init__(self, card=None, data=None):
00257         CrackProperty.__init__(self, card, data)
00258         if card:
00259             ## Property ID
00260             self.pid   = card.field(1)
00261             ## Material ID
00262             self.mid   = card.field(2)
00263             self.thick = card.field(3)
00264             ## Plane strain or plane stress option. Use 0 for plane strain; 1 for plane
00265             ## stress. (Integer = 0 or 1)
00266             self.iPlane = card.field(4)
00267             assert self.iPlane in [0, 1],'Invalid value for iPlane on PRAC2D, can only be 0,1 iPlane=|%s|' %(self.iPlane)
00268             ## Non-structural mass per unit area.(Real >= 0.0; Default = 0)
00269             self.nsm = card.field(5, 0.)
00270             ## Exponent used in the displacement field. See Remark 4. (Real; Default = 0.5)
00271             self.gamma = card.field(6, 0.5)
00272             ## Angle (in degrees) relative to the element x-axis along which stress
00273             ## intensity factors are to be calculated. See Remark 4. (Real; Default = 180.0)
00274             self.phi = card.field(7, 180.)
00275             
00276         else:
00277             raise NotImplementedError('not supported')
00278         ###
00279 
00280     def crossReference(self,model):
00281         self.mid = model.Material(self.mid) # MAT1, MAT2, MAT8
00282 
00283     def rawFields(self):
00284         fields = ['PRAC2D',self.pid,self.Mid(),self.thick,self.iPlane,self.nsm,self.gamma,self.phi]
00285         return fields
00286 
00287     def reprFields(self):
00288         nsm   = set_blank_if_default(self.nsm, 0.)
00289         gamma = set_blank_if_default(self.gamma, 0.5)
00290         phi   = set_blank_if_default(self.phi, 180.)
00291         fields = ['PRAC2D',self.pid,self.Mid(),self.thick,self.iPlane,nsm,gamma,phi]
00292         return fields
00293 
00294 class PRAC3D(CrackProperty):
00295     """
00296     CRAC3D Element Property
00297     Defines the properties of the CRAC3D structural element.
00298     """
00299     type = 'PRAC3D'
00300     def __init__(self, card=None, data=None):
00301         CrackProperty.__init__(self, card, data)
00302         if card:
00303             ## Property ID
00304             self.pid   = card.field(1)
00305             ## Material ID
00306             self.mid   = card.field(2)
00307             ## Exponent used in the displacement field. See Remark 4.
00308             ## (Real; Default = 0.5)
00309             self.gamma = card.field(3, 0.5)
00310             ## Angle (in degrees) relative to the element x-axis along which
00311             ## stress intensity factors are to be calculated. See Remark 4.
00312             ## (Real; Default = 180.0)
00313             self.phi = card.field(4, 180.)
00314             
00315         else:
00316             raise NotImplementedError('not supported')
00317         ###
00318 
00319     def crossReference(self, model):
00320         self.mid = model.Material(self.mid) # MAT1, MAT9
00321 
00322     def rawFields(self):
00323         fields = ['PRAC3D', self.pid, self.Mid(), self.gamma, self.phi]
00324         return fields
00325 
00326     def reprFields(self):
00327         gamma = set_blank_if_default(self.gamma, 0.5)
00328         phi   = set_blank_if_default(self.phi, 180.)
00329         fields = ['PRAC3D', self.pid, self.Mid(), gamma, phi]
00330         return fields
00331 
00332 class PCONEAX(Property): #not done
00333     type = 'PCONEAX'
00334     def __init__(self, card=None,data=None):
00335         Property.__init__(self, card, data)
00336         if card:
00337             ## Property ID
00338             self.pid   = card.field(1)
00339             ## Material ID
00340             self.mid   = card.field(2)
00341             self.group = card.field(3, 'MSCBMLO')
00342             self.Type  = card.field(4)
00343             self.dim   = [] # confusing entry...
00344         else:
00345             raise NotImplementedError('not supported')
00346         ###
00347 
00348     def crossReference(self, model):
00349         self.mid = model.Material(self.mid)
00350 
00351     def rawFields(self):
00352         fields = ['PCONEAX',self.pid, self.Mid(), self.group, self.Type]
00353         raise NotImplementedError('not supported')
00354         return fields
00355     
 All Classes Namespaces Files Functions Variables