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=E1101 00026 #import sys 00027 #from struct import pack 00028 from pyNastran.op2.resultObjects.op2_Objects import scalarObject 00029 00030 class TemperatureObject(scalarObject): # approachCode=1, sortCode=0, thermal=1 00031 def __init__(self, dataCode, isSort1, iSubcase,dt=None): 00032 scalarObject.__init__(self, dataCode, iSubcase) 00033 self.gridTypes = {} 00034 self.temperatures = {} 00035 00036 self.dt = dt 00037 if isSort1: 00038 if dt is not None: 00039 self.add = self.addSort1 00040 ### 00041 else: 00042 assert dt is not None 00043 self.add = self.addSort2 00044 ### 00045 00046 def addF06Data(self, data, transient): 00047 if transient is None: 00048 for line in data: 00049 (gridID,gridType) = line[0:2] 00050 temps = line[2:] 00051 for (i,temp) in enumerate(temps): 00052 nodeID = gridID+i 00053 self.gridTypes[nodeID] = gridType 00054 self.temperatures[nodeID] = temp 00055 return 00056 00057 (dtName,dt) = transient 00058 self.dataCode['name'] = dtName 00059 if dt not in self.temperatures: 00060 self.updateDt(self.dataCode,dt) 00061 self.isTransient = True 00062 00063 for line in data: 00064 (gridID,gridType) = line[0:2] 00065 temps = line[2:] 00066 for (i,temp) in enumerate(temps): 00067 nodeID = gridID+i 00068 self.gridTypes[nodeID] = gridType 00069 self.temperatures[dt][nodeID] = temp 00070 ### 00071 ### 00072 00073 def updateDt(self,dataCode,dt): 00074 self.dataCode = dataCode 00075 self.applyDataCode() 00076 if dt is not None: 00077 self.log.debug("updating %s...%s=%s iSubcase=%s" %(self.dataCode['name'],self.dataCode['name'],dt,self.iSubcase)) 00078 self.dt = dt 00079 self.addNewTransient(dt) 00080 00081 def deleteTransient(self, dt): 00082 del self.temperatures[dt] 00083 00084 def getTransients(self): 00085 k = self.temperatures.keys() 00086 k.sort() 00087 return k 00088 00089 def addNewTransient(self, dt): 00090 """initializes the transient variables""" 00091 self.temperatures[dt] = {} 00092 00093 def add(self, dt, out): 00094 (nodeID,gridType,v1,v2,v3,v4,v5,v6) = out # v2-v6 are 0 00095 assert 0<nodeID<1000000000, 'nodeID=%s' %(nodeID) 00096 #assert nodeID not in self.temperatures 00097 00098 gridType = self.recastGridType(gridType) 00099 self.gridTypes[nodeID] = gridType 00100 self.temperatures[nodeID] = v1 00101 00102 def addSort1(self,dt,out): 00103 if dt not in self.temperatures: 00104 self.addNewTransient(dt) 00105 00106 (nodeID,gridType,v1,v2,v3,v4,v5,v6) = out # v2-v6 are 0 00107 assert 0<nodeID<1000000000, 'nodeID=%s' %(nodeID) 00108 #assert nodeID not in self.temperatures[self.dt] 00109 00110 gridType = self.recastGridType(gridType) 00111 self.gridTypes[nodeID] = gridType 00112 self.temperatures[dt][nodeID] = v1 00113 00114 # def writeOp2(self,block3,deviceCode=1): 00115 # """ 00116 # creates the binary data for writing the table 00117 # @warning hasnt been tested... 00118 # """ 00119 # msg = block3 00120 # for nodeID,T in sorted(self.temperatures.iteritems()): 00121 # grid = nodeID*10+deviceCode 00122 # msg += pack('iffffff',grid,T,0,0,0,0,0) 00123 # ### 00124 # return msg 00125 # 00126 # def writeOp2Transient(self,block3,deviceCode=1): 00127 # """ 00128 # creates the binary data for writing the table 00129 # @warning hasnt been tested... 00130 # @warning dt slot needs to be fixed... 00131 # """ 00132 # msg = '' 00133 # for dt,temperatures in sorted(self.temperatures.iteritems()): 00134 # XXX = 50 ## this isnt correct... @todo update dt 00135 # msg += block3[0:XXX] + pack('i',dt) + block3[XXX+4:] 00136 # #msg += '%s = %g\n' %(self.dataCode['name'],dt) 00137 # 00138 # for nodeID,T in sorted(temperatures.iteritems()): 00139 # grid = nodeID*10+deviceCode 00140 # msg += pack('iffffff',grid,T,0,0,0,0,0) 00141 # ### 00142 # ### 00143 # return msg 00144 00145 def writeHeader(self): 00146 mainHeaders = ('nodeID','GridType') 00147 headers = ['T1','T2','T3','T4','T5','T6'] 00148 00149 msg = '%-10s %-8s ' %(mainHeaders) 00150 for header in headers: 00151 msg += '%10s ' %(header) 00152 msg += '\n' 00153 return msg 00154 00155 def __reprTransient__(self): 00156 msg = '---TRANSIENT TEMPERATURE---\n' 00157 msg += self.writeHeader() 00158 00159 for dt,temperatures in sorted(self.temperatures.iteritems()): 00160 msg += '%s = %g\n' %(self.dataCode['name'],dt) 00161 for nodeID,T in sorted(temperatures.iteritems()): 00162 gridType = self.gridTypes[nodeID] 00163 msg += '%10s %8s ' %(nodeID,gridType) 00164 00165 if abs(T)<1e-6: 00166 msg += '%10s\n' %(0) 00167 else: 00168 msg += '%10g\n' %(T) 00169 ### 00170 ### 00171 return msg 00172 00173 def writeF06(self,header,pageStamp,pageNum=1,f=None,isMagPhase=False): 00174 words = [' T E M P E R A T U R E V E C T O R\n', 00175 ' \n', 00176 ' POINT ID. TYPE ID VALUE ID+1 VALUE ID+2 VALUE ID+3 VALUE ID+4 VALUE ID+5 VALUE\n'] 00177 msg = [] 00178 if self.nonlinearFactor is not None: 00179 for dt,temperatures in sorted(self.temperatures.iteritems()): 00180 dtLine = '%14s = %12.5E\n'%(self.dataCode['name'],dt) 00181 header[2] = dtLine 00182 msg += header+words 00183 msg += self.printTempLines(temperatures) 00184 msg.append(pageStamp+str(pageNum)+'\n') 00185 if f is not None: 00186 f.write(''.join(msg)) 00187 msg = [''] 00188 pageNum += 1 00189 ### 00190 return(''.join(msg),pageNum-1) # transient 00191 00192 msg += self.printTempLines(self.temperatures) 00193 msg.append(pageStamp+str(pageNum)+'\n') 00194 if f is not None: 00195 f.write(''.join(msg)) 00196 msg = [''] 00197 return(''.join(msg),pageNum) # static 00198 00199 def printTempLines(self,temperatures): 00200 msg = [] 00201 ipack = [] 00202 oldNodeID = -1 00203 oldGridType = None 00204 for nodeID,T in sorted(temperatures.iteritems()): 00205 gridType = self.gridTypes[nodeID] 00206 00207 if oldNodeID+1 == nodeID and gridType == oldGridType: 00208 oldNodeID = nodeID 00209 ipack.append(T) 00210 else: 00211 if oldNodeID>0: 00212 msg += self.printPack(ipack) 00213 oldGridType = gridType 00214 oldNodeID = nodeID 00215 ipack = [nodeID, gridType, T] 00216 ### 00217 ### 00218 if ipack: 00219 msg += self.printPack(ipack) 00220 ### 00221 return msg 00222 00223 def printPack(self,ipack): 00224 msg = [] 00225 nID = ipack[0] 00226 gType = ipack[1] 00227 while len(ipack)>8: 00228 nID = ipack[0] 00229 packOut = ipack[:8] 00230 ipack = [nID+6,gType]+ipack[8:] 00231 msg.append(' %8i %4s %10.6E %10.6E %10.6E %10.6E %10.6E %10.6E\n' %(tuple(packOut))) 00232 00233 if ipack: 00234 fmt = ' %8i %4s '+' %10.6E'*(len(ipack)-2)+'\n' 00235 out = fmt %(tuple(ipack)) 00236 msg.append(out) 00237 return msg 00238 00239 def __repr__(self): 00240 if self.nonlinearFactor is not None: 00241 return self.__reprTransient__() 00242 00243 msg = '---TEMPERATURE---\n' 00244 msg += self.writeHeader() 00245 #print "self.dataCode=",self.dataCode 00246 for nodeID,T in sorted(self.temperatures.iteritems()): 00247 gridType = self.gridTypes[nodeID] 00248 msg += '%10s %8s ' %(nodeID,gridType) 00249 #print "nodeID=%s T=%s" %(nodeID,T) 00250 if abs(T)<1e-6: 00251 msg += '%10s\n' %(0) 00252 else: 00253 msg += '%10g\n' %(T) 00254 ### 00255 return msg 00256