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 00029 from .thermal import ThermalCard 00030 from pyNastran.bdf.fieldWriter import set_blank_if_default 00031 from ..baseCard import expandThru, expandThruBy, collapseThruBy 00032 00033 class ThermalLoadDefault(ThermalCard): 00034 def __init__(self, card, data): 00035 pass 00036 00037 class ThermalLoad(ThermalCard): 00038 def __init__(self, card, data): 00039 pass 00040 00041 00042 class QBDY1(ThermalLoad): 00043 """ 00044 Defines a uniform heat flux into CHBDYj elements. 00045 """ 00046 type = 'QBDY1' 00047 def __init__(self, card=None, data=None): 00048 ThermalLoad.__init__(self, card, data) 00049 00050 if card: 00051 ## Load set identification number. (Integer > 0) 00052 self.sid = card.field(1) 00053 00054 ## Heat flux into element (FLOAT) 00055 self.qFlux = card.field(2) 00056 eids = card.fields(3) 00057 ## CHBDYj element identification numbers (Integer) 00058 self.eids = expandThru(eids) # @warning should this use expandThruBy ??? 00059 else: 00060 self.sid = data[0] 00061 self.qFlux = data[1] 00062 self.eids = data[2:] 00063 ### 00064 00065 def crossReference(self,model): 00066 self.eids = model.Elements(self.eids) 00067 00068 def Eid(self): 00069 if isinstance(self.eid,int): 00070 return self.eid 00071 return self.eid.eid 00072 00073 def nQFluxTerms(self): 00074 return len(self.qFlux) 00075 00076 def rawFields(self): 00077 fields = ['QBDY1', self.sid, self.qFlux]+list(self.eids)+[self.qFlux] 00078 return fields 00079 00080 def reprFields(self): 00081 eids = collapseThruBy(self.eids) 00082 fields = ['QBDY1', self.sid, self.qFlux]+list(eids)+[self.qFlux] 00083 #print "FIELDS = ",fields 00084 return fields 00085 00086 class QBDY2(ThermalLoad): # not tested 00087 """ 00088 Defines a uniform heat flux load for a boundary surface. 00089 """ 00090 type = 'QBDY2' 00091 def __init__(self, card=None, data=None): 00092 ThermalLoad.__init__(self, card, data) 00093 00094 if card: 00095 ## Load set identification number. (Integer > 0) 00096 self.sid = card.field(1) 00097 ## Identification number of an CHBDYj element. (Integer > 0) 00098 self.eid = card.field(2) 00099 ## Heat flux at the i-th grid point on the referenced CHBDYj element. (Real or blank) 00100 self.qFlux = self.removeTrailingNones(card.fields(3)) 00101 else: 00102 self.sid = data[0] 00103 self.eid = data[1] 00104 self.qFlux = data[2] 00105 ### 00106 00107 def crossReference(self,model): 00108 self.eid = model.Element(self.eid) 00109 00110 def Eid(self): 00111 if isinstance(self.eid,int): 00112 return self.eid 00113 return self.eid.eid 00114 00115 def nQFluxTerms(self): 00116 return len(self.qFlux) 00117 00118 def rawFields(self): 00119 fields = ['QBDY2', self.sid, self.Eid(), self.qFlux] 00120 return fields 00121 00122 def reprFields(self): 00123 return self.rawFields() 00124 00125 class QBDY3(ThermalLoad): 00126 """ 00127 Defines a uniform heat flux load for a boundary surface. 00128 """ 00129 type = 'QBDY3' 00130 def __init__(self, card=None, data=None): 00131 ThermalLoad.__init__(self, card, data) 00132 00133 if card: 00134 ## Load set identification number. (Integer > 0) 00135 self.sid = card.field(1) 00136 ## Heat flux into element 00137 self.Q0 = card.field(2) 00138 ## Control point for thermal flux load. (Integer > 0; Default = 0) 00139 self.cntrlnd = card.field(3,0) 00140 eids = card.fields(4) 00141 ## CHBDYj element identification numbers 00142 self.eids = expandThruBy(eids) 00143 else: 00144 self.sid = data[0] 00145 self.Q0 = data[1] 00146 self.cntrlnd = data[2] 00147 self.eids = list(data[3:]) 00148 ### 00149 00150 def crossReference(self,model): 00151 for i,eid in enumerate(self.eids): 00152 self.eids[i] = model.Element(eid) 00153 00154 def Eids(self): 00155 eids = [] 00156 for eid in self.eids: 00157 eids.append(self.Eid(eid)) 00158 return eids 00159 00160 def Eid(self,eid): 00161 if isinstance(eid,int): 00162 return eid 00163 return eid.eid 00164 00165 def rawFields(self): 00166 eids = self.Eids() 00167 eids.sort() 00168 fields = ['QBDY3', self.sid, self.Q0, self.cntrlnd]+eids 00169 return fields 00170 00171 def reprFields(self): 00172 cntrlnd = set_blank_if_default(self.cntrlnd,0) 00173 eids = collapseThruBy(self.Eids()) 00174 eids.sort() 00175 fields = ['QBDY3',self.sid, self.Q0, cntrlnd]+eids 00176 return fields 00177 00178 class QHBDY(ThermalLoad): 00179 """ 00180 Defines a uniform heat flux into a set of grid points. 00181 """ 00182 type = 'QHBDY' 00183 def __init__(self, card=None, data=None): 00184 ThermalLoad.__init__(self, card, data) 00185 00186 if card: 00187 ## Load set identification number. (Integer > 0) 00188 self.sid = card.field(1) 00189 00190 self.flag = card.field(2) 00191 assert self.flag in ['POINT','LINE','REV','AREA3','AREA4','AREA6','AREA8'] 00192 00193 ## Magnitude of thermal flux into face. Q0 is positive for heat into the surface. (Real) 00194 self.Q0 = card.field(3) 00195 00196 ## Area factor depends on type. (Real > 0.0 or blank) 00197 self.af = card.field(4) 00198 self.grids = card.fields(5) 00199 00200 ## Grid point identification of connected grid points. (Integer > 0 or blank) 00201 self.grids = expandThruBy(self.grids) 00202 else: 00203 self.sid = data[0] 00204 self.flag = data[1] 00205 self.Q0 = data[2] 00206 self.af = data[3] 00207 self.grids = data[4:] 00208 ### 00209 00210 #def crossReference(self,model): 00211 # pass 00212 00213 def rawFields(self): 00214 fields = ['QHBDY', self.sid, self.flag, self.Q0, self.af]+self.grids 00215 return fields 00216 00217 def reprFields(self): 00218 return self.rawFields() 00219 00220 class TEMP(ThermalLoad): 00221 """ 00222 Defines temperature at grid points for determination of thermal loading, 00223 temperature-dependent material properties, or stress recovery. 00224 """ 00225 type = 'TEMP' 00226 def __init__(self, card=None, data=None): 00227 ThermalLoad.__init__(self, card, data) 00228 00229 if card: 00230 ## Load set identification number. (Integer > 0) 00231 self.sid = card.field(1) 00232 00233 fields = card.fields(2) 00234 nFields = len(fields) 00235 assert nFields%2 == 0 00236 00237 ## dictionary of temperatures where the key is the grid ID (Gi) and the value is the temperature (Ti) 00238 self.temperatures = {} 00239 for i in xrange(0, nFields, 2): 00240 self.temperatures[fields[i]] = fields[i+1] 00241 ### 00242 else: 00243 #print "TEMP data = ",data 00244 self.sid = data[0] 00245 self.temperatures = {data[1]: data[2]} 00246 ### 00247 00248 def add(self, tempObj): 00249 assert self.sid==tempObj.sid 00250 for (gid, temp) in self.tempObj.temperatures.iteritems(): 00251 self.temperatures[gid] = temp 00252 ### 00253 00254 def crossReference(self, model): 00255 pass 00256 00257 def rawFields(self): 00258 """Writes the TEMP card""" 00259 fields = ['TEMP',self.sid] 00260 00261 nTemps = len(self.temperatures)-1 00262 for i,(gid, temp) in enumerate(sorted(self.temperatures.iteritems())): 00263 fields += [gid, temp] 00264 if i%3 == 2 and nTemps > i: # start a new TEMP card 00265 fields += [None, 'TEMP', self.lid] 00266 return fields 00267 00268 def reprFields(self): 00269 """Writes the TEMP card""" 00270 return self.rawFields() 00271 00272 # Loads 00273 #------------------------------------------------------- 00274 # Default Loads 00275 00276 class TEMPD(ThermalLoadDefault): 00277 """ 00278 Defines a temperature value for all grid points of the structural model that have not 00279 been given a temperature on a TEMP entry 00280 """ 00281 type = 'TEMPD' 00282 def __init__(self, card=None, data=None): 00283 ThermalLoadDefault.__init__(self, card, data) 00284 if card: 00285 fields = card.fields(1) 00286 nFields = len(fields) 00287 assert nFields%2 == 0 00288 00289 ## dictionary of temperatures where the key is the set ID (SIDi) and the value is the temperature (Ti) 00290 self.temperatures = {} 00291 for i in xrange(0, nFields, 2): 00292 self.temperatures[fields[i]] = fields[i+1] 00293 ### 00294 else: 00295 self.temperatures = {data[0]: data[1] } 00296 ### 00297 00298 def add(self,tempdObj): 00299 for (lid, tempd) in self.tempdObj.temperatures.iteritems(): 00300 self.temperatures[lid] = tempd 00301 ### 00302 00303 def crossReference(self, model): 00304 pass 00305 00306 def reprFields(self): 00307 """Writes the TEMPD card""" 00308 fields = ['TEMPD'] 00309 00310 nTemps = len(self.temperatures)-1 00311 #print "self.temperatures = ",self.temperatures 00312 #print "nTemps = ",nTemps 00313 for i,(gid, temp) in enumerate(sorted(self.temperatures.iteritems())): 00314 fields += [gid, temp] 00315 if i%4 == 3 and nTemps > i: # start a new TEMP card 00316 fields += ['TEMPD'] 00317 return fields