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 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