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 from __future__ import print_function 00026 #from numpy import array 00027 from numpy import angle 00028 from pyNastran.op2.op2Codes import Op2Codes 00029 00030 class baseScalarObject(Op2Codes): 00031 def __init__(self): 00032 pass 00033 00034 def name(self): 00035 return self.__class__.__name__ 00036 00037 def writeF06(self,header,pageStamp,pageNum=1,f=None,isMagPhase=False): 00038 msg = ['writeF06 is not implemented in %s\n' %(self.__class__.__name__)] 00039 return (''.join(msg),pageNum) 00040 00041 def writeF06Transient(self,header,pageStamp,pageNum=1,f=None,isMagPhase=False): 00042 msg = 'writeF06Transient is not implemented in %s\n' %(self.__class__.__name__) 00043 return (''.join(msg),pageNum) 00044 00045 def writeFloats10E(self,vals): 00046 vals2 = [] 00047 isAllZeros = True 00048 for v in vals: 00049 v2 = '%10.3E' %(v) 00050 if v2==' 0.000E+00' or v2=='-0.000E+00': 00051 v2 = ' 0.0 ' 00052 else: 00053 isAllZeros = False 00054 vals2.append(v2) 00055 return (vals2,isAllZeros) 00056 00057 def writeFloats12E(self,vals): 00058 vals2 = [] 00059 isAllZeros = True 00060 for v in vals: 00061 v2 = '%12.5E' %(v) 00062 if v2==' 0.00000E+00' or v2=='-0.00000E+00': 00063 v2 = ' 0.0 ' 00064 else: 00065 isAllZeros = False 00066 vals2.append(v2) 00067 return (vals2,isAllZeros) 00068 00069 def writeFloats13E(self,vals): 00070 vals2 = [] 00071 isAllZeros = True 00072 for v in vals: 00073 v2 = '%13.6E' %(v) 00074 if v2==' 0.000000E+00' or v2=='-0.000000E+00': 00075 v2 = ' 0.0 ' 00076 else: 00077 isAllZeros = False 00078 vals2.append(v2) 00079 return (vals2,isAllZeros) 00080 00081 def writeImagFloats13E(self,vals,isMagPhase): 00082 vals2 = [] 00083 isAllZeros = True 00084 00085 if isMagPhase: 00086 for v in vals: 00087 v2 = '%13.6E' %(abs(v)) 00088 if v2==' 0.000000E+00' or v2=='-0.000000E+00': 00089 v2 = ' 0.0 ' 00090 else: 00091 isAllZeros = False 00092 vals2.append(v2) 00093 00094 for v in vals: 00095 v3 = '%13.6E' %(angle(v,deg=True)) 00096 if v3==' 0.000000E+00' or v3=='-0.000000E+00': 00097 v3 = ' 0.0 ' 00098 else: 00099 isAllZeros = False 00100 vals2.append(v3) 00101 else: 00102 for v in vals: 00103 v2 = '%13.6E' %(v.real) 00104 if v2==' 0.000000E+00' or v2=='-0.000000E+00': 00105 v2 = ' 0.0 ' 00106 else: 00107 isAllZeros = False 00108 vals2.append(v2) 00109 00110 for v in vals: 00111 v3 = '%13.6E' %(v.imag) 00112 if v3==' 0.000000E+00' or v3=='-0.000000E+00': 00113 v3 = ' 0.0 ' 00114 else: 00115 isAllZeros = False 00116 vals2.append(v3) 00117 return (vals2,isAllZeros) 00118 00119 def writeFloats8p4F(self,vals): 00120 vals2 = [] 00121 isAllZeros = True 00122 for v in vals: 00123 v2 = '%8.4f' %(v) 00124 if v2==' 0.0000' or v2==' -0.0000': 00125 v2 = ' 0.0 ' 00126 else: 00127 isAllZeros = False 00128 vals2.append(v2) 00129 return (vals2,isAllZeros) 00130 00131 00132 class scalarObject(baseScalarObject): 00133 def __init__(self, dataCode, iSubcase): 00134 assert 'nonlinearFactor' in dataCode, dataCode 00135 baseScalarObject.__init__(self) 00136 self.iSubcase = iSubcase 00137 self.isTransient = False 00138 self.dt = None 00139 self.dataCode = dataCode 00140 self.applyDataCode() 00141 self.log.debug(self.codeInformation()) 00142 00143 def isImaginary(self): 00144 return bool(self.sortBits[1]) 00145 00146 def writeMatlabArgs(self,name,iSubcase,f): 00147 for key,value,in sorted(self.dataCode.iteritems()): 00148 if key is not 'log': 00149 if isinstance(value,str): 00150 value = "'%s'" %(value) 00151 msg = 'fem.%s(%i).%s = %s;\n' %(name,iSubcase,key,value) 00152 elif isinstance(value,list) and isinstance(value[0],str): 00153 msgTemp = "','".join(value) 00154 msg = "fem.%s(%i).%s = {'%s'};\n" %(name,iSubcase,key,msgTemp) 00155 00156 elif value is None: 00157 value = "'%s'" %(value) 00158 else: 00159 msg = 'fem.%s(%i).%s = %s;\n' %(name,iSubcase,key,value) 00160 f.write(msg) 00161 ### 00162 ### 00163 00164 def applyDataCode(self): 00165 self.log = self.dataCode['log'] 00166 for key,value in sorted(self.dataCode.iteritems()): 00167 if key is not 'log': 00168 self.__setattr__(key,value) 00169 #self.log.debug(" key=%s value=%s" %(key,value)) 00170 #print " key=%s value=%s" %(key,value) 00171 #self.log.debug("") 00172 00173 def getUnsteadyValue(self): 00174 name = self.dataCode['name'] 00175 return self.getVar(name) 00176 00177 def getVar(self,name): 00178 return getattr(self,name) 00179 00180 def setVar(self,name,value): 00181 return self.__setattr__(name,value) 00182 00183 def startDataMember(self,varName,valueName): 00184 if hasattr(self,varName): 00185 return True 00186 elif hasattr(self,valueName): 00187 self.setVar(varName,[]) 00188 return True 00189 return False 00190 00191 def appendDataMember(self,varName,valueName): 00192 """this appends a data member to a variable that may or may not exist""" 00193 #print "append..." 00194 hasList = self.startDataMember(varName,valueName) 00195 if hasList: 00196 listA = self.getVar(varName) 00197 if listA is not None: 00198 #print "has %s" %(varName) 00199 value = self.getVar(valueName) 00200 try: 00201 n = len(listA) 00202 except: 00203 print("listA = ",listA) 00204 raise 00205 listA.append(value) 00206 assert len(listA)==n+1 00207 ### 00208 ### 00209 00210 def setDataMembers(self): 00211 if 'dataNames' not in self.dataCode: 00212 msg = 'No "transient" variable was set for %s\n' %(self.tableName) 00213 raise NotImplementedError(msg+self.codeInformation()) 00214 00215 for name in self.dataCode['dataNames']: 00216 #print "name = ",name 00217 self.appendDataMember(name+'s',name) 00218 ### 00219 00220 def updateDataCode(self,dataCode): 00221 self.dataCode = dataCode 00222 self.applyDataCode() 00223 self.setDataMembers() 00224 00225 def printDataMembers(self): 00226 """ 00227 Prints out the "unique" vals of the case. 00228 Uses a provided list of dataCode['dataNames'] to set the values for 00229 each subcase. Then populates a list of self.name+'s' (by using 00230 setattr) with the current value. For example, if the variable name is 00231 'mode', we make self.modes. Then to extract the values, we build a 00232 list of of the variables that were set like this and then loop over 00233 then to print their values. 00234 00235 This way there is no dependency on one result type having ['mode'] and 00236 another result type having ['mode','eigr','eigi']. 00237 """ 00238 keyVals = [] 00239 for name in self.dataCode['dataNames']: 00240 vals = getattr(self,name+'s') 00241 keyVals.append(vals) 00242 #print "%ss = %s" %(name,vals) 00243 00244 msg = '' 00245 for name in self.dataCode['dataNames']: 00246 msg += '%-10s ' %(name) 00247 msg += '\n' 00248 00249 nModes = len(keyVals[0]) 00250 for i in xrange(nModes): 00251 for vals in keyVals: 00252 msg += '%-10g ' %(vals[i]) 00253 msg += '\n' 00254 ### 00255 return msg+'\n' 00256 00257 def recastGridType(self,gridType): 00258 """converts a gridType integer to a string""" 00259 if gridType==1: 00260 Type = 'G' # GRID 00261 elif gridType==2: 00262 Type = 'S' # SPOINT 00263 elif gridType==7: 00264 Type = 'L' # RIGID POINT (e.g. RBE3) 00265 elif gridType==0: 00266 Type = 'H' # SECTOR/HARMONIC/RING POINT 00267 else: 00268 raise RuntimeError('gridType=%s' %(gridType)) 00269 ### 00270 return Type 00271 00272 def updateDt(self,dataCode,dt): 00273 """ 00274 this method is called if the object 00275 already exits and a new time step is found 00276 """ 00277 self.dataCode = dataCode 00278 self.applyDataCode() 00279 raise RuntimeError('updateDt not implemented in the %s class' %(self.__class__.__name__)) 00280 #assert dt>=0. 00281 #print "updating dt...dt=%s" %(dt) 00282 if dt is not None: 00283 self.dt = dt 00284 self.addNewTransient() 00285 ### 00286