pyNastran  0.5.0
pyNastran BDF Reader/Writer, OP2 Parser, and GUI
thermal.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 
00029 from pyNastran.bdf.fieldWriter import set_blank_if_default
00030 from pyNastran.bdf.cards.baseCard import BaseCard, expandThruBy, collapseThruBy
00031 
00032 class ThermalCard(BaseCard):
00033     def __init__(self, card, data):
00034         pass
00035     def crossReference(self,model):
00036         raise NotImplementedError('%s has not defined the crossReference'
00037                                   'method' %(self.type))
00038 
00039     def isSameCard(self, obj, debug=False):
00040         return False
00041 
00042 class ThermalBC(ThermalCard):
00043     def __init__(self, card, data):
00044         pass
00045 
00046 class ThermalElement(ThermalCard):
00047     pid = 0
00048     def __init__(self, card, data):
00049         pass
00050 
00051     def nodeIDs(self):
00052         return []
00053 
00054     def Pid(self):
00055         if isinstance(self.pid, int):
00056             return self.pid
00057         else:
00058             return self.pid.pid
00059         ###
00060 
00061 class ThermalProperty(ThermalCard):
00062     def __init__(self, card, data):
00063         pass
00064 
00065 #-------------------------------------------------------
00066 # Elements
00067 
00068 class CHBDYE(ThermalElement):
00069     """
00070     Defines a boundary condition surface element with reference to a heat
00071     conduction element.
00072     """
00073     type = 'CHBDYE'
00074 
00075     hexMap = {1: [4, 3, 2, 1],  # CHEXA8/CHEXA20
00076               2: [1, 2, 6, 5],
00077               3: [2, 3, 7, 6],
00078               4: [3, 4, 8, 7],
00079               5: [4, 1, 5, 8],
00080               6: [5, 6, 7, 8],
00081              }
00082 
00083     pentMap = {1: [3, 2, 1],  # CPENTA
00084                2: [1, 2, 5, 4],
00085                3: [2, 3, 6, 5],
00086                4: [3, 1, 4, 6],
00087                5: [4, 5, 6],
00088               }
00089 
00090     tetMap = {1: [1, 3, 2],  # CTETRA
00091               2: [1, 2, 4],
00092               3: [2, 3, 4],
00093               4: [3, 1, 4],
00094              }
00095 
00096     sideMaps = {'CHEXA': hexMap, 'CPENTA':pentMap, 'CTETRA':tetMap,
00097                 'CTRIA3':[1,2,3], 'CQUAD4':[1,2,3,4]}
00098 
00099     def __init__(self, card=None, data=None):
00100         ThermalElement.__init__(self, card, data)
00101         ## Surface element ID number for a side of an
00102         ## element. (0 < Integer < 100,000,000)
00103         self.eid  = card.field(1)
00104         
00105         ## A heat conduction element identification
00106         self.eid2 = card.field(2)
00107 
00108         ## A consistent element side identification number (1 < Integer < 6)
00109         self.side = card.field(3)
00110         assert 0 < self.side < 7
00111 
00112         ## A VIEW entry identification number for the front face
00113         self.iViewFront  = card.field(4, 0)
00114         ## A VIEW entry identification number for the back face
00115         self.iViewBack   = card.field(5, 0)
00116 
00117         ## RADM identification number for front face of surface element (Integer > 0)
00118         self.radMidFront = card.field(6, 0)        
00119         ## RADM identification number for back face of surface element (Integer > 0)
00120         self.radMidBack  = card.field(7, 0)
00121         
00122         self.grids = []
00123 
00124     #def crossReference(self,model):
00125     #    pass
00126     
00127     def sideToEIDs(self, eid):
00128         sideIDs = self.sideMaps[eid.type][self.side]
00129         ## [1,2,3]
00130         
00131         # id-1 is for the 0 based python index
00132         nodes = [enodes[id-1] for id in xrange(len(eid.nodes)) if id in sideIDs ]
00133         return side
00134         
00135     def rawFields(self):
00136         fields = ['CHBDYE', self.eid, self.eid2, self.side, self.iViewFront,
00137                   self.iViewBack,self.radMidFront,self.radMidBack]
00138         return fields
00139 
00140     def reprFields(self):
00141         #eids = collapseThruBy(self.eids)  ## @todo is this done
00142         fields = ['CHBDYE', self.eid, self.eid2, self.side, self.iViewFront,
00143                   self.iViewBack,self.radMidFront,self.radMidBack]
00144         return fields
00145 
00146 class CHBDYG(ThermalElement):
00147     """
00148     Defines a boundary condition surface element without reference to a
00149     property entry.
00150     """
00151     type = 'CHBDYG'
00152     def __init__(self, card=None, data=None):
00153         ThermalElement.__init__(self, card, data)
00154         
00155         if card:
00156             ## Surface element ID
00157             self.eid  = card.field(1)
00158             # no field 2
00159 
00160             ## Surface type
00161             self.Type = card.field(3)
00162             assert self.Type in ['REV','AREA3','AREA4','AREA6','AREA8']
00163 
00164             ## A VIEW entry identification number for the front face
00165             self.iViewFront  = card.field(4,0)
00166 
00167             ## A VIEW entry identification number for the back face
00168             self.iViewBack  = card.field(8,0)
00169 
00170             ## RADM identification number for front face of surface element
00171             ## (Integer > 0)
00172             self.radMidFront = card.field(6,0)
00173 
00174             ## RADM identification number for back face of surface element
00175             ## (Integer > 0)
00176             self.radMidBack = card.field(7,0)
00177             # no field 8
00178 
00179             ## Grid point IDs of grids bounding the surface (Integer > 0)
00180             self.grids = card.fields(9)
00181         else:
00182             self.eid         = data[0]
00183             self.Type        = data[1]
00184             self.iViewFront  = data[2]
00185             self.iViewBack   = data[3]
00186             self.radMidFront = data[4]
00187             self.radMidBack  = data[5]
00188             self.grids       = data[6:14]
00189         ###
00190 
00191     def crossReference(self,mesh):
00192         pass
00193         #self.pid = mesh.Phbdy(self.pid)
00194 
00195     def rawFields(self):
00196         fields = ['CHBDYG',self.eid,None,self.Type,self.iViewFront,self.iViewBack,self.radMidFront,self.radMidBack,None,
00197         ]+self.grids
00198         return fields
00199 
00200     def reprFields(self):
00201         iViewFront  = set_blank_if_default(self.iViewFront,  0)
00202         iViewBack   = set_blank_if_default(self.iViewBack,   0)
00203         radMidFront = set_blank_if_default(self.radMidFront, 0)
00204         radMidBack  = set_blank_if_default(self.radMidBack,  0)
00205 
00206         fields = ['CHBDYG',self.eid,None,self.Type,iViewFront,iViewBack,radMidFront,radMidBack,None,
00207         ]+self.grids
00208         #print "chbdyg fields = %s" %(fields)
00209         return fields
00210 
00211 class CHBDYP(ThermalElement):
00212     """
00213     Defines a boundary condition surface element with reference to a PHBDY entry
00214     """
00215     type = 'CHBDYP'
00216     def __init__(self, card=None, data=None):
00217         ThermalElement.__init__(self, card, data)
00218         if card:
00219             ## Surface element ID
00220             self.eid  = card.field(1)
00221 
00222             ## PHBDY property entry identification numbers. (Integer > 0)
00223             self.pid  = card.field(2)
00224 
00225             self.Type = card.field(3)
00226             #print "self.Type = ",self.Type
00227             #assert self.Type in ['POINT','LINE','ELCYL','FTUBE','TUBE'],'CHBDYP Type=|%s|' (self.Type)
00228 
00229             ## A VIEW entry identification number for the front face.
00230             self.iViewFront = card.field(4,0)
00231 
00232             ## A VIEW entry identification number for the back face.
00233             self.iViewBack  = card.field(5,0)
00234 
00235             ## Grid point identification numbers of grids bounding the surface. (Integer > 0)
00236             self.g1 = card.field(6)        
00237             ## Grid point identification numbers of grids bounding the surface. (Integer > 0)
00238             self.g2 = card.field(7)
00239 
00240             ## Orientation grid point. (Integer > 0; Default = 0)
00241             self.g0 = card.field(8,0)
00242 
00243             ## RADM identification number for front face of surface element. (Integer > 0)
00244             self.radMidFront = card.field(9,0)
00245 
00246             ## RADM identification number for back face of surface element. (Integer > 0)
00247             self.radMidBack = card.field(10,0)
00248 
00249             ## Grid point identification number of a midside node if it is used with the line type surface element.
00250             self.gmid = card.field(11)
00251             ## Coordinate system for defining orientation vector. (Integer > 0;Default = 0
00252             self.ce   = card.field(12,0)
00253 
00254             ## Components of the orientation vector in coordinate system CE. The origin of the orientation vector is grid point G1. (Real or blank)
00255             self.e1   = card.field(13)
00256             self.e2   = card.field(14)
00257             self.e3   = card.field(15)
00258         else:
00259             raise NotImplementedError()
00260 
00261     def crossReference(self,mesh):
00262         self.pid = mesh.Phbdy(self.pid)
00263 
00264     def rawFields(self):
00265         fields = ['CHBDYP',self.eid,self.Pid(),self.Type,self.iViewFront,self.iViewBack,self.g1,self.g2,self.g0,
00266                   self.radMidFront,self.radMidBack,self.gmid,self.ce,self.e1,self.e2,self.e3]
00267         return fields
00268 
00269     def reprFields(self):
00270         iViewFront  = set_blank_if_default(self.iViewFront,  0)
00271         iViewBack   = set_blank_if_default(self.iViewBack,   0)
00272         radMidFront = set_blank_if_default(self.radMidFront, 0)
00273         radMidBack  = set_blank_if_default(self.radMidBack,  0)
00274 
00275         g0 = set_blank_if_default(self.g0, 0)
00276         ce = set_blank_if_default(self.ce, 0)
00277 
00278         fields = ['CHBDYP',self.eid,self.Pid(),self.Type,iViewFront,iViewBack,self.g1,self.g2,g0,
00279                   radMidFront,radMidBack,self.gmid,ce,self.e1,self.e2,self.e3]
00280         return fields
00281 
00282 # Elements
00283 #-------------------------------------------------------
00284 # Properties
00285 
00286 
00287 class PCONV(ThermalProperty):
00288     """
00289     Specifies the free convection boundary condition properties of a boundary condition
00290     surface element used for heat transfer analysis.
00291     """
00292     type = 'PCONV'
00293     def __init__(self, card=None, data=None):
00294         ## Convection property identification number. (Integer > 0)
00295         self.pconid = card.field(1)
00296         ## Material property identification number. (Integer > 0)
00297         self.mid    = card.field(2)
00298         ## Type of formula used for free convection. (Integer 0, 1, 10, 11, 20, or 21)
00299         self.form   = card.field(3,0)
00300         assert self.form in [0,1,10,11,20,21]
00301 
00302         ## Free convection exponent as implemented within the context of the
00303         ## particular form that is chosen
00304         self.expf   = card.field(4,0.0)
00305         ## Formula type for various configurations of free convection
00306         self.ftype  = card.field(5,0)
00307         ## Identification number of a TABLEHT entry that specifies the twovariable
00308         ## tabular function of the free convection heat transfer coefficient
00309         self.tid    = card.field(6)
00310         #7
00311         #8
00312         ## Characteristic length
00313         self.chlen  = card.field(9)
00314         ## Grid ID of the referenced inlet point
00315         self.gidin  = card.field(10)
00316         ## Coordinate system for defining orientation vector. (Integer > 0;Default = 0
00317         self.ce     = card.field(11,0)
00318         ## Components of the orientation vector in coordinate system CE. The origin of the orientation vector is grid point G1. (Real or blank)
00319         self.e1     = card.field(12)
00320         self.e2     = card.field(13)
00321         self.e3     = card.field(14)
00322 
00323     #def crossReference(self,model):
00324     #    pass
00325 
00326     def rawFields(self):
00327         fields = ['PCONV',self.pconid,self.mid,self.form,self.expf,self.ftype,self.tid,None,None,
00328                   self.chlen,self.gidin,self.ce,self.e1,self.e2,self.e3]
00329         return fields
00330 
00331     def reprFields(self):
00332         form  = set_blank_if_default(self.form,  0)
00333         expf  = set_blank_if_default(self.expf,0.0)
00334         ftype = set_blank_if_default(self.ftype, 0)
00335         ce    = set_blank_if_default(self.ce,    0)
00336         fields = ['PCONV',self.pconid,self.mid,form,expf,ftype,self.tid,None,None,
00337                           self.chlen,self.gidin,ce,self.e1,self.e2,self.e3]
00338         return fields
00339 
00340 class PCONVM(ThermalProperty):
00341     """
00342     Specifies the free convection boundary condition properties of a boundary condition
00343     surface element used for heat transfer analysis.
00344     """
00345     type = 'PCONVM'
00346     def __init__(self, card=None, data=None):
00347         ## Convection property identification number. (Integer > 0)
00348         self.pconid = card.field(1)
00349         ## Material property identification number. (Integer > 0)
00350         self.mid    = card.field(2)
00351         ## Type of formula used for free convection. (Integer 0, 1, 10, 11, 20, or 21)
00352         self.form   = card.field(3,0)
00353         assert self.form in [0,1,10,11,20,21]
00354 
00355         ## Flag for mass flow convection. (Integer = 0 or 1; Default = 0)
00356         self.flag  = card.field(4,0)
00357         ## Constant coefficient used for forced convection
00358         self.coef  = card.field(5)
00359         ## Reynolds number convection exponent. (Real > 0.0; Default = 0.0)
00360         self.expr  = card.field(6,0.0)
00361         ## Prandtl number convection exponent for heat transfer into the working
00362         ## fluid. (Real > 0.0; Default = 0.0)
00363         self.exppi = card.field(7,0.0)
00364         ## Prandtl number convection exponent for heat transfer into the working
00365         ## fluid. (Real > 0.0; Default = 0.0)
00366         self.exppo = card.field(8,0.0)
00367 
00368     #def crossReference(self,model):
00369     #    pass
00370 
00371     def rawFields(self):
00372         fields = ['PCONVM',self.pconid,self.mid,self.form,self.flag,self.coef,self.expr,self.exppi,self.exppo]
00373         return fields
00374 
00375     def reprFields(self):
00376         form  = set_blank_if_default(self.form,   0)
00377         flag  = set_blank_if_default(self.flag,   0)
00378         expr  = set_blank_if_default(self.expr, 0.0)
00379         exppi = set_blank_if_default(self.exppi,0.0)
00380         exppo = set_blank_if_default(self.exppo,0.0)
00381         fields = ['PCONVM',self.pconid,self.mid,form,flag,self.coef,expr,exppi,exppo]
00382         return fields
00383 
00384 class PHBDY(ThermalProperty):
00385     """
00386     A property entry referenced by CHBDYP entries to give auxiliary geometric
00387     information for boundary condition surface elements
00388     """
00389     type = 'PHBDY'
00390     def __init__(self, card=None, data=None):
00391         ## Property identification number. (Unique Integer among all PHBDY entries). (Integer > 0)
00392         self.pid = card.field(1)
00393 
00394         ## Area factor of the surface used only for CHBDYP element
00395         ## TYPE = 'POINT', TYPE = 'LINE', TYPE = 'TUBE', or
00396         ## TYPE = 'ELCYL'. For TYPE = 'TUBE', AF is the constant thickness of
00397         ## the hollow tube. (Real > 0.0 or blank)
00398         self.af = card.field(2)
00399         
00400         ## Diameters associated with the surface. Used with CHBDYP element TYPE='ELCYL','TUBE','FTUBE'
00401         self.d1 = card.field(3)
00402         self.d2 = card.field(4,self.d1)
00403 
00404 
00405     #def crossReference(self,model):
00406     #    pass
00407 
00408     def rawFields(self):
00409         fields = ['PHBDY',self.pid,self.af,self.d1,self.d2]
00410         return fields
00411 
00412     def reprFields(self):
00413         d2  = set_blank_if_default(self.d2,self.d1)
00414         fields = ['PHBDY',self.pid,self.af,self.d1,d2]
00415         return fields
00416 
00417 
00418 # Properties
00419 #-------------------------------------------------------
00420 # Boundary Conditions
00421 
00422 class CONV(ThermalBC):
00423     """
00424     Specifies a free convection boundary condition for heat transfer analysis through
00425     connection to a surface element (CHBDYi entry).
00426     """
00427     type = 'CONV'
00428     def __init__(self, card=None, data=None):
00429         #ThermalBC.__init__(self, card, data)
00430         ## CHBDYG, CHBDYE, or CHBDYP surface element identification number. (Integer > 0)
00431         self.eid     = card.field(1)
00432         
00433         ## Convection property identification number of a PCONV entry
00434         self.pconID  = card.field(2)
00435         ## Point for film convection fluid property temperature
00436         self.flmnd   = card.field(3,0)
00437         ## Control point for free convection boundary condition.
00438         self.cntrlnd = card.field(4,0)
00439 
00440         TA1          = card.field(5)
00441         nFields = card.nFields()-1 # maybe off by 1...
00442         
00443         ## Ambient points used for convection 0's are allowed for TA2 and higher.
00444         self.ta = card.fields(5,card.nfields,[TA1]*nFields)
00445 
00446     def crossReference(self,model):
00447         self.eid = model.Element(self.eid)
00448         assert self.eid.type in ['CHBDYG','CHBDYE','CHBDYP']
00449 
00450     def TA(self,i=None):
00451         if i is None:
00452             return self.ta
00453         return self.ta[i]
00454 
00455     def rawFields(self):
00456         fields = ['CONV',self.eid,self.pconID,self.flmnd,self.cntrlnd]+self.ta
00457         return fields
00458 
00459     def reprFields(self):
00460         flmnd   = set_blank_if_default(self.flmnd,  0)
00461         cntrlnd = set_blank_if_default(self.cntrlnd,0)
00462         fields = ['CONV',self.eid,self.pconID,flmnd,cntrlnd]+self.ta
00463         return fields
00464 
00465 class RADM(ThermalBC):
00466     """
00467     Defines the radiation properties of a boundary element for heat transfer analysis
00468     """
00469     type = 'RADM'
00470     def __init__(self, card=None, data=None):
00471         ThermalBC.__init__(self, card, data)
00472         ## Material identification number
00473         self.radmid = card.field(1)
00474         self.absorb = card.field(2)
00475         self.emissivity = card.fields(3)
00476         assert self.radmid > 0
00477         assert 0. <= self.absorb <= 1.0
00478         for e in self.emissivity:
00479             assert 0. <= e <= 1.0
00480         
00481     #def crossReference(self,model):
00482     #    pass
00483 
00484     def reprFields(self):
00485         fields = ['RADM',self.radmid,self.absorb] + self.emissivity
00486         return fields
00487 
00488 class RADBC(ThermalBC):
00489     """
00490     Specifies an CHBDYi element face for application of radiation boundary conditions
00491     """
00492     type = 'RADBC'
00493     def __init__(self, card=None, data=None):
00494         ThermalBC.__init__(self, card, data)
00495         
00496         ## NODAMB Ambient point for radiation exchange. (Integer > 0)
00497         self.nodamb = card.field(1)
00498         ## Radiation view factor between the face and the ambient point. (Real > 0.0)
00499         self.famb   = card.field(2)
00500         ## Control point for thermal flux load. (Integer > 0; Default = 0)
00501         self.cntrlnd = card.field(3,0)
00502         
00503         eids = card.fields(4)
00504         ## CHBDYi element identification number
00505         self.eids = expandThruBy(eids)
00506         
00507     def crossReference(self,model):
00508         for i,eid in enumerate(self.eids):
00509             self.eids[i] = model.Element(eid)
00510         ###
00511 
00512     def Eids(self):
00513         eids = []
00514         for eid in self.eids:
00515             eids.append(self.Eid(eid))
00516         ###
00517         return eids
00518 
00519     def Eid(self,eid):
00520         if isinstance(eid,int):
00521             return eid
00522         return eid.eid
00523 
00524     def rawFields(self):
00525         fields = ['RADBC',self.nodamb,self.famb,self.cntrlnd]+self.Eids()
00526         return fields
00527 
00528     def reprFields(self):
00529         cntrlnd = set_blank_if_default(self.cntrlnd,0)
00530         eids   = collapseThruBy(self.Eids())
00531         fields = ['RADBC',self.nodamb,self.famb,cntrlnd]+eids
00532         return fields
00533 
00534 # Boundary Conditions
00535 #-------------------------------------------------------
00536 
 All Classes Namespaces Files Functions Variables