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,W0231,R0201 00026 00027 from __future__ import division, print_function 00028 import sys 00029 from itertools import izip 00030 00031 from pyNastran.bdf.fieldWriter import set_blank_if_default 00032 from pyNastran.bdf.cards.baseCard import BaseCard 00033 00034 class Load(BaseCard): 00035 """defines the DefaultLoad class""" 00036 type = 'DefLoad' 00037 def __init__(self, card, data): 00038 self.cid = None 00039 self.nodes = None 00040 00041 def Cid(self): 00042 if isinstance(self.cid, int): 00043 return self.cid 00044 else: 00045 return self.cid.cid 00046 00047 def nodeIDs(self, nodes=None): 00048 """returns nodeIDs for repr functions""" 00049 if not nodes: 00050 nodes = self.nodes 00051 if isinstance(nodes[0], int): 00052 return [node for node in nodes] 00053 else: 00054 return [node.nid for node in nodes] 00055 00056 00057 class LoadCombination(Load): # LOAD, DLOAD 00058 def __init__(self, card, data): 00059 Load.__init__(self, card, data) 00060 00061 if card: 00062 ## load ID 00063 self.sid = card.field(1) 00064 00065 ## overall scale factor 00066 self.scale = card.field(2) 00067 00068 loads = card.fields(3) # temp list 00069 nLoadFields = len(loads) 00070 #nLoads = nLoadFields/2 00071 assert nLoadFields%2 == 0 00072 00073 ## individual scale factors (corresponds to loadIDs) 00074 self.scaleFactors = [] 00075 00076 ## individual loadIDs (corresponds to scaleFactors) 00077 self.loadIDs = [] 00078 00079 # alternating of scale factor & load set ID 00080 for i in xrange(0, nLoadFields, 2): 00081 self.scaleFactors.append(loads[i ]) 00082 self.loadIDs.append( loads[i+1]) 00083 else: 00084 self.sid = data[0] 00085 self.scale = data[1] 00086 self.scaleFactors = data[2] 00087 self.loadIDs = data[3] 00088 assert len(data) == 4, '%s data=%s' % (self.type, data) 00089 ### 00090 00091 00092 def crossReference(self, model): 00093 loadIDs2 = [] 00094 for loadID in self.loadIDs: 00095 loadID2 = model.Load(loadID) 00096 loadIDs2.append(loadID2) 00097 self.loadIDs = loadIDs2 00098 00099 def LoadID(self, lid): 00100 if isinstance(lid, int): 00101 return lid 00102 elif isinstance(lid, list): 00103 return lid[0].sid 00104 else: 00105 raise NotImplementedError(lid) 00106 00107 #def Sid(self): 00108 # try: 00109 # if isinstance(self.sid, int): 00110 # return self.sid 00111 # elif isinstance(self.sid, list): 00112 # #sys.stderr.write('type(lid[0]) = %s' %(type(self.lid[0]))) 00113 # #sys.stderr.write("the offending load...%s" %(self.lid[0])) 00114 # return self.sid[0].sid 00115 # #elif isinstance(self.lid,load) 00116 # else: 00117 # #sys.stderr.write("the offending load...%s" %(self.lid)) 00118 # return self.sid.sid 00119 # except: 00120 # msg = "error in loads.py - self.lid=\n %s\n" % (str(self.sid)) 00121 # sys.stderr.write(msg) 00122 # raise 00123 00124 #def LoadID(self, loadID): 00125 #print("load = ",loadID) 00126 #if isinstance(loadID, int): 00127 # return loadID 00128 #elif isinstance(loadID, list): 00129 # return loadID[0].LoadID() 00130 ##print("self.lid = ",load.lid) 00131 #asdf 00132 #return load.lid 00133 00134 def getLoads(self): 00135 """@note requires a cross referenced load""" 00136 loads = [] 00137 for allLoads in self.loadIDs: 00138 for load in allLoads: 00139 loads += load.getLoads() 00140 #loads += self.ID # @todo: what does this mean, was uncommented 00141 ### 00142 return loads 00143 00144 00145 class LSEQ(BaseCard): # Requires LOADSET in case control deck 00146 """ 00147 Defines a sequence of static load sets 00148 @todo how does this work... 00149 """ 00150 type = 'LSEQ' 00151 def __init__(self, card=None, data=None): 00152 if card: 00153 self.sid = card.field(1) 00154 self.exciteID = card.field(2) 00155 self.lid = card.field(3) 00156 self.tid = card.field(4) 00157 else: 00158 self.sid = data[0] 00159 self.exciteID = data[1] 00160 self.lid = data[2] 00161 self.tid = data[3] 00162 raise NotImplementedError() 00163 00164 #def nodeIDs(self, nodes=None): 00165 #"""returns nodeIDs for repr functions""" 00166 #if not nodes: 00167 # nodes = self.nodes 00168 #if isinstance(nodes[0], int): 00169 # return [node for node in nodes] 00170 #else: 00171 # return [node.nid for node in nodes] 00172 ### 00173 00174 def crossReference(self, model): 00175 self.lid = model.Load(self.lid) 00176 if self.tid: 00177 self.tid = model.Load(self.tid) 00178 00179 def LoadID(self, lid): 00180 if isinstance(lid, int): 00181 return lid 00182 elif isinstance(lid, list): 00183 return self.LoadID(lid[0]) 00184 else: 00185 return lid.sid 00186 raise RuntimeError(lid) 00187 00188 def getLoads(self): 00189 return self.lid 00190 00191 def Lid(self): 00192 if isinstance(self.lid, int): 00193 return self.lid 00194 else: 00195 return self.LoadID(self.lid) 00196 raise NotImplementedError('LSEQ '+str(self.lid)+ 00197 '\n%s' %(type(self.lid))) 00198 00199 def Tid(self): 00200 if self.tid is None: 00201 return None 00202 if isinstance(self.tid, int): 00203 return self.tid 00204 return self.tid.tid 00205 00206 def rawFields(self): 00207 fields = ['LSEQ', self.sid, self.exciteID, self.Lid(), self.Tid()] 00208 return fields 00209 00210 def reprFields(self): 00211 return self.rawFields() 00212 00213 class SLOAD(Load): 00214 """ 00215 Static Scalar Load 00216 Defines concentrated static loads on scalar or grid points. 00217 00218 @note Can be used in statics OR dynamics. 00219 00220 If Si refers to a grid point, the load is applied to component T1 of the 00221 displacement coordinate system (see the CD field on the GRID entry). 00222 """ 00223 type = 'SLOAD' 00224 def __init__(self, card=None, data=None): 00225 ## load ID 00226 self.sid = card.field(1) 00227 00228 fields = card.fields(2) 00229 n = len(fields)//2 00230 if len(fields)%2 == 1: 00231 n += 1 00232 msg = 'missing last magnitude on SLOAD card=%s' % (card.fields()) 00233 raise RuntimeError(msg) 00234 00235 self.nids = [] 00236 self.mags = [] 00237 for i in xrange(n): 00238 j = 2*i 00239 self.nids.append(fields[j ]) 00240 self.mags.append(fields[j+1]) 00241 ### 00242 00243 def crossReference(self, model): 00244 for (i, nid) in enumerate(self.nids): 00245 self.nids[i] = model.Node(nid) 00246 ### 00247 00248 def Nid(self, node): 00249 if isinstance(node, int): 00250 return node 00251 return node.nid 00252 00253 def rawFields(self): 00254 fields = ['SLOAD', self.sid] 00255 for (nid, mag) in izip(self.nids, self.mags): 00256 fields += [self.Nid(nid), mag] 00257 return fields 00258 00259 def reprFields(self): 00260 return self.rawFields() 00261 00262 #--------------------------------------------------------------------- 00263 # DLOAD loads 00264 00265 class DLOAD(LoadCombination): 00266 type = 'DLOAD' 00267 def __init__(self, card=None, data=None): 00268 LoadCombination.__init__(self, card, data) 00269 00270 #def crossReference(self, model): 00271 # for (i, sid) in enumerate(self.sids): 00272 # self.sids[i] = model.Load(sid) 00273 # ### 00274 00275 #def Sid(self, sid): 00276 # if isinstance(sid, int): 00277 # return sid 00278 # return sid.lid 00279 00280 def rawFields(self): 00281 fields = ['DLOAD', self.sid, self.scale] 00282 for (scaleFactor, loadID) in izip(self.scaleFactors, self.loadIDs): 00283 fields += [scaleFactor, self.LoadID(loadID)] 00284 return fields 00285 00286 def reprFields(self): 00287 return self.rawFields() 00288 00289 class DAREA(BaseCard): 00290 """ 00291 Defines scale (area) factors for static and dynamic loads. In dynamic 00292 analysis, DAREA is used in conjunction with ACSRCE, RLOADi and TLOADi 00293 entries. 00294 DAREA SID P1 C1 A1 P2 C2 A2 00295 DAREA 3 6 2 8.2 15 1 10.1 00296 """ 00297 type = 'DAREA' 00298 def __init__(self, card=None, nOffset=0, data=None): 00299 if card: 00300 nOffset *= 3 00301 self.sid = card.field(1) 00302 self.p = card.field(2+nOffset) 00303 self.c = card.field(3+nOffset) 00304 self.scale = card.field(4+nOffset) 00305 else: 00306 self.sid = data[0] 00307 self.p = data[1] 00308 self.c = data[2] 00309 self.scale = data[3] 00310 assert len(data)==4, 'data = %s' %(data) 00311 ### 00312 00313 def rawFields(self): 00314 fields = ['DAREA', self.sid, self.p, self.c, self.scale] 00315 return fields 00316 00317 class TabularLoad(BaseCard): 00318 def __init__(self, card, data): 00319 pass 00320 00321 class TLOAD1(TabularLoad): 00322 """ 00323 Transient Response Dynamic Excitation, Form 1 00324 Defines a time-dependent dynamic load or enforced motion of the form: 00325 \f[ {P(t)} = {A} \cdot F(t-\tau) \f] 00326 for use in transient response analysis. 00327 """ 00328 type = 'TLOAD1' 00329 def __init__(self, card=None, data=None): 00330 TabularLoad.__init__(self, card, data) 00331 ## load ID 00332 self.sid = card.field(1) 00333 00334 ## Identification number of DAREA or SPCD entry set or a thermal load 00335 ## set (in heat transfer analysis) that defines {A}. (Integer > 0) 00336 self.exciteID = card.field(2) 00337 00338 ## If it is a non-zero integer, it represents the 00339 ## identification number of DELAY Bulk Data entry that defines . If it 00340 ## is real, then it directly defines the value of that will be used for 00341 ## all degrees-of-freedom that are excited by this dynamic load entry. 00342 ## See also Remark 9. (Integer >= 0, real or blank) 00343 self.delay = card.field(3) 00344 00345 ## Defines the type of the dynamic excitation. (LOAD,DISP, VELO, ACCE) 00346 self.Type = card.field(4, 'LOAD') 00347 00348 ## Identification number of TABLEDi entry that gives F(t). (Integer > 0) 00349 self.tid = card.field(5) 00350 00351 ## Factor for initial displacements of the enforced degrees-of-freedom. 00352 ## (Real; Default = 0.0) 00353 self.us0 = card.field(6, 0.0) 00354 00355 ## Factor for initial velocities of the enforced degrees-of-freedom. 00356 ## (Real; Default = 0.0) 00357 self.vs0 = card.field(7, 0.0) 00358 if self.Type in [0, 'L', 'LO', 'LOA', 'LOAD']: 00359 self.Type = 'LOAD' 00360 elif self.Type in [1, 'D', 'DI', 'DIS', 'DISP']: 00361 self.Type = 'DISP' 00362 elif self.Type in [2, 'V', 'VE', 'VEL', 'VELO']: 00363 self.Type = 'VELO' 00364 elif self.Type in [3, 'A', 'AC', 'ACC', 'ACCE']: 00365 self.Type = 'ACCE' 00366 else: 00367 msg = 'invalid TLOAD1 type Type=|%s|' % (self.Type) 00368 raise RuntimeError(msg) 00369 00370 def getLoads(self): 00371 return [self] 00372 00373 def crossReference(self, model): 00374 if self.tid: 00375 self.tid = model.Table(self.tid) 00376 00377 def Tid(self): 00378 if self.tid == 0: 00379 return None 00380 elif isinstance(self.tid, int): 00381 return self.tid 00382 return self.tid.tid 00383 00384 def rawFields(self): 00385 fields = ['TLOAD1', self.sid, self.exciteID, self.delay, self.Type, 00386 self.Tid(), self.us0, self.vs0] 00387 return fields 00388 00389 def reprFields(self): 00390 us0 = set_blank_if_default(self.us0, 0.0) 00391 vs0 = set_blank_if_default(self.vs0, 0.0) 00392 fields = ['TLOAD1', self.sid, self.exciteID, self.delay, self.Type, 00393 self.Tid(), us0, vs0] 00394 return fields 00395 00396 class TLOAD2(TabularLoad): 00397 """ 00398 Transient Response Dynamic Excitation, Form 1 00399 Defines a time-dependent dynamic load or enforced motion of the form: 00400 \f[ {P(t)} = {A} \cdot F(t-\tau) \f] 00401 for use in transient response analysis. 00402 """ 00403 type = 'TLOAD2' 00404 def __init__(self, card=None, data=None): 00405 TabularLoad.__init__(self, card, data) 00406 ## load ID 00407 ## SID must be unique for all TLOAD1, TLOAD2, RLOAD1, RLOAD2, and ACSRCE entries. 00408 self.sid = card.field(1) 00409 00410 self.exciteID = card.field(2) 00411 self.delay = card.field(3,0) 00412 00413 ## Defines the type of the dynamic excitation. (Integer; character 00414 ## or blank; Default = 0) 00415 self.Type = card.field(4,0) 00416 00417 ## Time constant. (Real >= 0.0) 00418 if self.delay==0: 00419 self.T1 = card.field(5,0.) 00420 else: 00421 self.T1 = card.field(5) 00422 ## Time constant. (Real; T2 > T1) 00423 self.T2 = card.field(6,self.T1) 00424 ## Frequency in cycles per unit time. (Real >= 0.0; Default = 0.0) 00425 self.frequency = card.field(7,0.) 00426 ## Phase angle in degrees. (Real; Default = 0.0) 00427 self.phase = card.field(8,0.) 00428 ## Exponential coefficient. (Real; Default = 0.0) 00429 self.c = card.field(9,0.) 00430 ## Growth coefficient. (Real; Default = 0.0) 00431 self.b = card.field(10,0.) 00432 ## Factor for initial displacements of the enforced degrees-of-freedom. 00433 ## (Real; Default = 0.0) 00434 self.us0 = card.field(11,0.) 00435 ## Factor for initial velocities of the enforced degrees-of-freedom 00436 ## (Real; Default = 0.0) 00437 self.vs0 = card.field(12,0.) 00438 00439 if self.Type in [0, 'L', 'LO', 'LOA', 'LOAD']: 00440 self.Type = 'LOAD' 00441 elif self.Type in [1, 'D', 'DI', 'DIS', 'DISP']: 00442 self.Type = 'DISP' 00443 elif self.Type in [2, 'V', 'VE', 'VEL', 'VELO']: 00444 self.Type = 'VELO' 00445 elif self.Type in [3, 'A', 'AC', 'ACC', 'ACCE']: 00446 self.Type = 'ACCE' 00447 elif self.Type in [5, 6, 7, 12, 13]: 00448 pass 00449 else: 00450 msg = 'invalid TLOAD1 type Type=|%s|' % (self.Type) 00451 raise RuntimeError(msg) 00452 00453 def getLoads(self): 00454 return [self] 00455 00456 def crossReference(self, model): 00457 pass 00458 # delay 00459 # exciteID 00460 00461 def rawFields(self): 00462 fields = ['TLOAD2', self.sid, self.exciteID, self.delay, self.Type, 00463 self.T1, self.T2, self.frequency, self.phase, self.c, self.b, 00464 self.us0, self.vs0] 00465 return fields 00466 00467 def reprFields(self): 00468 #self.Type = card.field(4,0) 00469 #self.T1 = card.field(5,0.) 00470 #self.T2 = card.field(6,self.T1) 00471 frequency = set_blank_if_default(self.frequency,0.) 00472 phase = set_blank_if_default(self.phase,0.) 00473 c = set_blank_if_default(self.c,0.) 00474 b = set_blank_if_default(self.b,0.) 00475 00476 us0 = set_blank_if_default(self.us0, 0.0) 00477 vs0 = set_blank_if_default(self.vs0, 0.0) 00478 fields = ['TLOAD2', self.sid, self.exciteID, self.delay, self.Type, 00479 self.T1, self.T2,self.frequency, phase, c, b, us0, vs0] 00480 return fields 00481 00482 class RFORCE(Load): 00483 type = 'RFORCE' 00484 def __init__(self, card=None, data=None): 00485 if card: 00486 self.sid = card.field(1) 00487 self.nid = card.field(2) 00488 self.cid = card.field(3, 0) 00489 self.scale = card.field(4, 1.) 00490 self.r1 = card.field(5, 0.) 00491 self.r2 = card.field(6, 0.) 00492 self.r3 = card.field(7, 0.) 00493 self.method = card.field(8, 1) 00494 self.racc = card.field(9, 0.) 00495 self.mb = card.field(10, 0) 00496 self.idrf = card.field(11, 0) 00497 else: 00498 self.sid = data[0] 00499 print("PLOADX1 = %s" %(data)) 00500 raise NotImplementedError('PLOADX1') 00501 00502 def crossReference(self, model): 00503 #self.nid = model.Element(self.nid) 00504 #self.cid = model.Coord(self.cid) 00505 pass 00506 00507 def getLoads(self): 00508 return [self] 00509 00510 def rawFields(self): 00511 fields = ['RFORCE', self.sid, self.nid, self.cid, self.scale, 00512 self.r1, self.r2, self.r3, self.method, self.racc, 00513 self.mb, self.idrf] 00514 return fields 00515 00516 def reprFields(self): 00517 #method = set_blank_if_default(self.method,1) 00518 racc = set_blank_if_default(self.racc,0.) 00519 mb = set_blank_if_default(self.mb,0) 00520 idrf = set_blank_if_default(self.idrf,0) 00521 fields = ['RFORCE', self.sid, self.nid, self.cid, self.scale, 00522 self.r1, self.r2, self.r3, self.method, racc, 00523 mb, idrf] 00524 return fields 00525 00526 class RLOAD1(TabularLoad): 00527 """ 00528 Defines a frequency-dependent dynamic load of the form 00529 for use in frequency response problems. 00530 RLOAD1 SID EXCITEID DELAY DPHASE TC TD TYPE 00531 \f[ \large \left{ P(f) \right} = \left{A\right} [ C(f)+iD(f)] 00532 e^{ i \left{\theta - 2 \pi f \tau \right} } \f] 00533 RLOAD1 5 3 1 00534 """ 00535 type = 'RLOAD1' 00536 def __init__(self, card=None, data=None): 00537 TabularLoad.__init__(self, card, data) 00538 self.sid = card.field(1) # was sid 00539 self.exciteID = card.field(2) 00540 self.delay = card.field(3) 00541 self.dphase = card.field(4) 00542 self.tc = card.field(5, 0) 00543 self.td = card.field(6, 0) 00544 self.Type = card.field(7, 'LOAD') 00545 00546 if self.Type in [0, 'L', 'LO', 'LOA', 'LOAD']: 00547 self.Type = 'LOAD' 00548 elif self.Type in [1, 'D', 'DI', 'DIS', 'DISP']: 00549 self.Type = 'DISP' 00550 elif self.Type in [2, 'V', 'VE', 'VEL', 'VELO']: 00551 self.Type = 'VELO' 00552 elif self.Type in [3, 'A', 'AC', 'ACC', 'ACCE']: 00553 self.Type = 'ACCE' 00554 else: 00555 msg = 'invalid RLOAD1 type Type=|%s|' % (self.Type) 00556 raise RuntimeError(msg) 00557 00558 def crossReference(self, model): 00559 if self.tc: 00560 self.tc = model.Table(self.tc) 00561 if self.td: 00562 self.td = model.Table(self.td) 00563 00564 #def LoadID(self, lid): 00565 #return self.Lid() 00566 00567 def getLoads(self): 00568 return [self] 00569 00570 def Tc(self): 00571 if self.tc == 0: 00572 return None 00573 elif isinstance(self.tc, int): 00574 return self.tc 00575 return self.tc.tid 00576 00577 def Td(self): 00578 if self.td == 0: 00579 return None 00580 elif isinstance(self.td, int): 00581 return self.td 00582 return self.td.tid 00583 00584 def rawFields(self): 00585 fields = ['RLOAD1', self.sid, self.exciteID, self.delay, self.dphase, 00586 self.Tc(), self.Td(), self.Type] 00587 return fields 00588 00589 def reprFields(self): 00590 Type = set_blank_if_default(self.Type, 'LOAD') 00591 fields = ['RLOAD1', self.sid, self.exciteID, self.delay, self.dphase, 00592 self.Tc(), self.Td(), Type] 00593 return fields 00594 00595 class RLOAD2(TabularLoad): 00596 """ 00597 Defines a frequency-dependent dynamic load of the form 00598 for use in frequency response problems. 00599 00600 \f[ \large \left{ P(f) \right} = \left{A\right} * B(f) 00601 e^{ i \left{ \phi(f) + \theta - 2 \pi f \tau \right} } \f] 00602 RLOAD2 SID EXCITEID DELAY DPHASE TB TP TYPE 00603 RLOAD2 5 3 1 00604 """ 00605 type = 'RLOAD2' 00606 def __init__(self, card=None, data=None): 00607 TabularLoad.__init__(self, card, data) 00608 self.sid = card.field(1) 00609 self.exciteID = card.field(2) 00610 self.delay = card.field(3) 00611 self.dphase = card.field(4) 00612 self.tb = card.field(5, 0) 00613 self.tp = card.field(6, 0) 00614 self.Type = card.field(7, 'LOAD') 00615 00616 if self.Type in [0, 'L', 'LO', 'LOA', 'LOAD']: 00617 self.Type = 'LOAD' 00618 elif self.Type in [1, 'D', 'DI', 'DIS', 'DISP']: 00619 self.Type = 'DISP' 00620 elif self.Type in [2, 'V', 'VE', 'VEL', 'VELO']: 00621 self.Type = 'VELO' 00622 elif self.Type in [3, 'A', 'AC', 'ACC', 'ACCE']: 00623 self.Type = 'ACCE' 00624 else: 00625 msg = 'invalid RLOAD2 type Type=|%s|' % (self.Type) 00626 raise RuntimeError(msg) 00627 00628 def crossReference(self, model): 00629 if self.tb: 00630 self.tb = model.Table(self.tb) 00631 if self.tp: 00632 self.tp = model.Table(self.tp) 00633 00634 def getLoads(self): 00635 return [self] 00636 00637 #def Lid(self): 00638 #return self.lid 00639 00640 def LoadID(self): 00641 return self.sid 00642 00643 def Tb(self): 00644 if self.tb == 0: 00645 return None 00646 elif isinstance(self.tb, int): 00647 return self.tb 00648 return self.tb.tid 00649 00650 def Tp(self): 00651 if self.tp == 0: 00652 return None 00653 elif isinstance(self.tp, int): 00654 return self.tp 00655 return self.tp.tid 00656 00657 def rawFields(self): 00658 fields = ['RLOAD2', self.sid, self.exciteID, self.delay, self.dphase, 00659 self.Tb(), self.Tp(), self.Type] 00660 return fields 00661 00662 def reprFields(self): 00663 Type = set_blank_if_default(self.Type, 0.0) 00664 fields = ['RLOAD2', self.sid, self.exciteID, self.delay, self.dphase, 00665 self.Tb(), self.Tp(), Type] 00666 return fields 00667 00668 #--------------------------------------------------------------------- 00669 # RANDOM loads 00670 00671 class RandomLoad(BaseCard): 00672 def __init__(self, card, data): 00673 pass 00674 00675 class RANDPS(RandomLoad): 00676 """ 00677 Power Spectral Density Specification 00678 Defines load set power spectral density factors for use in random analysis 00679 having the frequency dependent form: 00680 \f[ S_{jk}(F) = (X+iY)G(F) \f] 00681 """ 00682 type = 'RANDPS' 00683 def __init__(self, card=None, data=None): 00684 if card: 00685 ## Random analysis set identification number. (Integer > 0) 00686 ## Defined by RANDOM in the Case Control Deck. 00687 self.sid = card.field(1) 00688 00689 ## Subcase identification number of the excited load set. 00690 ## (Integer > 0) 00691 self.j = card.field(2) 00692 00693 ## Subcase identification number of the applied load set. 00694 ## (Integer >= 0; K >= J) 00695 self.k = card.field(3) 00696 00697 ## Components of the complex number. (Real) 00698 self.x = card.field(4) 00699 self.y = card.field(5) 00700 ## Identification number of a TABRNDi entry that defines G(F). 00701 self.tid = card.field(6, 0) 00702 00703 def crossReference(self, model): 00704 if self.tid: 00705 self.tid = model.Table(self.tid) 00706 00707 def getLoads(self): 00708 return [self] 00709 00710 def Tid(self): 00711 if self.tid == 0: 00712 return None 00713 elif isinstance(self.tid, int): 00714 return self.tid 00715 return self.tid.tid 00716 00717 def rawFields(self): 00718 fields = ['RANDPS', self.sid, self.j, self.k, self.x, self.y, 00719 self.Tid()] 00720 return fields 00721 00722 def reprFields(self): 00723 return self.rawFields() 00724