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 from math import sqrt, degrees, radians, atan2, acos, sin, cos 00029 from itertools import izip 00030 00031 from numpy import array, cross, dot, transpose, zeros 00032 from numpy.linalg import norm 00033 00034 from pyNastran.bdf.fieldWriter import set_blank_if_default 00035 from pyNastran.bdf.cards.baseCard import BaseCard, BDFCard 00036 from pyNastran.general.general import ListPrint 00037 00038 class Coord(BaseCard): 00039 type = 'COORD' 00040 def __init__(self, card, data): 00041 """ 00042 Defines a general CORDxx object 00043 @param self the object pointer 00044 @param card a BDFCard object 00045 @param data a list analogous to the card 00046 """ 00047 ## has the coordinate system been linked yet 00048 self.isCrossReferenced = False 00049 ## have all the transformation matricies been determined 00050 self.isResolved = False 00051 self.cid = None 00052 self.e1 = None 00053 self.e2 = None 00054 self.e3 = None 00055 00056 def Cid(self): 00057 """returns the coordinate ID""" 00058 return self.cid 00059 00060 def setup(self, debug=False): 00061 """ 00062 \f[ e_{13} = e_3 - e_1 \f] 00063 \f[ e_{12} = e_2 - e_1 \f] 00064 \f[ k = \frac{e_{12}}{|e_{12}|} \f] 00065 \f[ j_{dir} = k \cross e_{13} \f] 00066 \f[ j = \frac{j_{dir}}{|j_{dir}|} \f] 00067 \f[ i = j \cross k \f] 00068 """ 00069 try: 00070 assert len(self.e1)==3, self.e1 00071 assert len(self.e2)==3, self.e2 00072 assert len(self.e3)==3, self.e3 00073 ## e_{13} 00074 e13 = self.e3-self.e1 00075 ## e_{12} 00076 e12 = self.e2-self.e1 00077 #print "e13 = %s" %(e13) 00078 #print "e12 = %s" %(e12) 00079 except TypeError: 00080 msg = '' 00081 msg += "\ntype = %s\n" %(self.type) 00082 msg += "\ncid = %s\n" %(self.Cid()) 00083 msg += "e1 = %s\n" %(self.e1) 00084 msg += "e2 = %s\n" %(self.e2) 00085 msg += "e3 = %s\n" %(self.e3) 00086 raise TypeError(msg) 00087 00088 #print self 00089 #print "e1 = ",self.e1 00090 #print "e2 = ",self.e2 00091 #print "e3 = ",self.e3 00092 00093 try: 00094 00095 ## k = (G3 cross G1) normalized 00096 self.k = self.normalize(e12) 00097 ## j = (k cross e13) normalized 00098 self.j = self.normalize(cross(self.k, e13)) 00099 except RuntimeError: 00100 print("---InvalidUnitVectorError---") 00101 print("Cp = %s" %(self.Cid())) 00102 print("e1 = %s" %(self.e1)) 00103 print("e2 = %s" %(self.e2)) 00104 print("e3 = %s" %(self.e3)) 00105 print("e13 = %s" %(e13)) 00106 print("e12 = %s" %(e12)) 00107 print("k = norm(e12)") 00108 print("k = %s\n" %(self.k)) 00109 print("j = norm(cross(k,e13))") 00110 raise 00111 try: 00112 ## i = j cross k 00113 self.i = cross(self.j, self.k) 00114 except RuntimeError: 00115 print("---InvalidUnitVectorError---") 00116 print("Cp = %s" %(self.Cid())) 00117 print("e1 = %s" %(self.e1)) 00118 print("e2 = %s" %(self.e2)) 00119 print("e3 = %s" %(self.e3)) 00120 print("e13 = %s" %(e13)) 00121 print("e12 = %s" %(e12)) 00122 print("k = norm(e12)") 00123 print("k = %s\n" %(self.k)) 00124 print("j = norm(cross(k,e13))") 00125 print("j = %s" %(self.j)) 00126 raise 00127 00128 if debug: 00129 print("Cp = %s" %(self.Cid())) 00130 print("e1 = %s" %(self.e1)) 00131 print("e2 = %s" %(self.e2)) 00132 print("e3 = %s" %(self.e3)) 00133 print('-----') 00134 print("e13 = %s" %(e13)) 00135 print("e12 = %s" %(e12)) 00136 print('-----') 00137 print("i = %s" %(self.i)) 00138 print("j = %s" %(self.j)) 00139 print("k = %s\n" %(self.k)) 00140 print('-----') 00141 00142 00143 #except TypeError: 00144 # msg = 'There is a problem handling these lines:\n' 00145 # msg += ' self.k = self.normalize(self.e3-self.e1)\n' 00146 # msg += ' self.ex0 = self.normalize(self.e2-self.e1)\n' 00147 # msg += 'e1=%s Type=%s\n' %(self.e1,type(self.e1)) 00148 # msg += 'e2=%s Type=%s\n' %(self.e2,type(self.e2)) 00149 # msg += 'e3=%s Type=%s\n' %(self.e3,type(self.e3)) 00150 # #print msg 00151 # raise CoordTypeError(msg) 00152 00153 #print "k = %s" %(self.k) 00154 #print "e13 = %s" %(e13) 00155 00156 def transformToLocal(self, p, matrix, debug=False): 00157 """ 00158 Transforms the global point p to the local coordinate system 00159 @param self 00160 the object pointer 00161 @param p 00162 the point to transform 00163 @param matrix 00164 the transformation matrix to apply - created by transformToGlobal 00165 @param debug 00166 developer debug 00167 @note 00168 uses the matrix as there is no linking from a global coordinate 00169 system to the local 00170 @note 00171 the matrix that comes in is the local to global, so we need to invert 00172 the matrix. Luckily the inverse of a tranformation matrix 00173 \f$ [\phi] \f$ is the transpose of the matrix. 00174 \f[ p_{Global} = (p_{Local}-e_1 )[\phi]+e_1 \f] 00175 \f[ [phi]^{-1} = [phi]^T \f] 00176 (pc-e1) =(pG-e1)mT 00177 (pc-e1)*m = pG-e1 00178 (pc-e1)*m+e1 = pG 00179 00180 @note 00181 be very careful of when you apply e1. It gets removed whenever 00182 rotations are applied. These equations need some TLC, but the 00183 methods are ok. 00184 """ 00185 #pGlobal = self.transformToGlobal(p, debug=False) 00186 pCoord = dot(p-self.e1, transpose(matrix)) 00187 pLocal = self.XYZtoCoord(pCoord) 00188 if debug: 00189 print("p = %s" %(p)) 00190 print("p-e1 = %s" %(p-self.e1)) 00191 print("pLocal = %s\n" %(pLocal)) 00192 print("pCoord = %s" %(pCoord)) 00193 return pLocal 00194 #return pGlobal 00195 00196 def normalize(self, v): 00197 """ 00198 Normalizes v into a unit vector 00199 @param self 00200 the object pointer 00201 @param v 00202 the vector to normalize 00203 @retval 00204 nNorm v has been normalized 00205 """ 00206 normV = norm(v) 00207 if not normV>0.: 00208 raise RuntimeError('v=%s norm(v)=%s' %(v, normV)) 00209 return v/normV 00210 00211 def T(self): 00212 """ 00213 Returns the 6x6 transformation 00214 \f[ \large [\lambda] = [B_{ij}] \f] 00215 00216 \f[ 00217 [T] = 00218 \left[ 00219 \begin{array}{cc} 00220 \lambda & 0 \\ 00221 0 & \lambda \\ 00222 \end{array} 00223 \right 00224 \f] 00225 """ 00226 (a, matrix) = self.transformToGlobal(self.e1) 00227 t = zeros((6,6)) # transformation matrix 00228 t[0:2, 0:2] = matrix 00229 t[3:5, 3:5] = matrix 00230 return t 00231 00232 def reprFields(self): 00233 return self.rawFields() 00234 00235 #def resolveCid(self): 00236 #pass 00237 00238 class RectangularCoord(object): 00239 def coordToXYZ(self, p): 00240 #print("p = %s" %(p)) 00241 #print("e1 = %s" %(self.e1)) 00242 return p+self.e1 00243 def XYZtoCoord(self, p): 00244 return p 00245 00246 class CylindricalCoord(object): 00247 """ 00248 \f[ r = \sqrt(x^2+y^2) \f] 00249 \f[ \theta = tan^-1(\frac{y}{x}) \f] 00250 \f[ z = z \f] 00251 00252 \f[ x = r cos(\theta) \f] 00253 \f[ y = r sin(\theta) \f] 00254 \f[ z = z \f] 00255 \f[ p = [x,y,z] + e_1 \f] 00256 http://en.wikipedia.org/wiki/Cylindrical_coordinate_system 00257 @note 00258 \f$ \phi \f$ and \f$ \theta \f$ are flipped per wikipedia to be 00259 consistent with nastran's documentation 00260 @see refman.pdf 00261 """ 00262 def coordToXYZ(self, p): 00263 """ 00264 @code 00265 y R 00266 | / 00267 | / 00268 | / theta 00269 *------------x 00270 @endcode 00271 00272 \f[ \large x = R \cos(\theta) \f] 00273 \f[ \large y = R \sin(\theta) \f] 00274 """ 00275 R = p[0] 00276 theta = radians(p[1]) 00277 x = R*cos(theta) 00278 y = R*sin(theta) 00279 return array([x, y, p[2]])+self.e1 00280 00281 def XYZtoCoord(self, p): 00282 (x, y, z) = p 00283 theta = degrees(atan2(y, x)) 00284 R = sqrt(x*x+y*y) 00285 return array([R, theta, z]) 00286 00287 00288 class SphericalCoord(object): 00289 """ 00290 \f[ r = \rho = \sqrt(x^2+y^2+z^2) \f] 00291 \f[ \theta = tan^-1(\frac{y}{x}) \f] 00292 \f[ \phi = cos^-1(\frac{z}{r}) \f] 00293 00294 \f[ x = r cos(\theta)sin(\phi) \f] 00295 \f[ y = r sin(\theta)sin(\phi) \f] 00296 \f[ z = r cos(\phi) \f] 00297 \f[ p = [x,y,z] + e_1 \f] 00298 http://en.wikipedia.org/wiki/Spherical_coordinate_system 00299 @note 00300 \f$ \phi \f$ and \f$ \theta \f$ are flipped per wikipedia to be 00301 consistent with nastran's documentation 00302 @see refman.pdf 00303 """ 00304 def coordToXYZ(self, p): 00305 R = p[0] 00306 theta = radians(p[1]) 00307 phi = radians(p[2]) 00308 x = R*cos(theta)*sin(phi) 00309 y = R*sin(theta)*sin(phi) 00310 z = R*cos(phi) 00311 return array([x, y, z])+self.e1 00312 00313 def XYZtoCoord(self, p): 00314 (x, y, z) = p 00315 R = sqrt(x*x+y*y+z*z) 00316 theta = degrees(atan2(y, x)) 00317 if R > 0: 00318 phi = degrees(acos(z/R)) 00319 else: 00320 phi = 0. 00321 return array([R, theta, phi]) 00322 00323 class Cord2x(Coord): 00324 def __init__(self, card, data): 00325 """ 00326 defines the CORD2x class 00327 @param self the object pointer 00328 @param card a BDFCard object 00329 @param data a list analogous to the card 00330 """ 00331 self.isResolved = False 00332 Coord.__init__(self, card, data) 00333 00334 if card: 00335 ## coordinate system ID 00336 self.cid = card.field(1) 00337 ## reference coordinate system ID 00338 self.rid = card.field(2, 0) 00339 00340 ## origin in a point relative to the rid coordinate system 00341 self.e1 = array( card.fields(3, 6, [0., 0., 0.]) ) 00342 ## z-axis in a point relative to the rid coordinate system 00343 self.e2 = array( card.fields(6, 9, [0., 0., 0.]) ) 00344 ## a point on the xz-plane relative to the rid coordinate system 00345 self.e3 = array( card.fields(9, 12, [0., 0., 0.]) ) 00346 else: 00347 self.cid = data[0] 00348 self.rid = data[1] 00349 self.e1 = array(data[2:5]) 00350 self.e2 = array(data[5:8]) 00351 self.e3 = array(data[8:11]) 00352 assert len(data) == 11, 'data = %s' %(data) 00353 ### 00354 assert len(self.e1) == 3 00355 assert len(self.e2) == 3 00356 assert len(self.e3) == 3 00357 if self.rid == 0: 00358 self.isResolved = True 00359 self.setup() 00360 00361 def resolveCid(self): 00362 """ 00363 Turns the coordinate system from being a coordinate system of 00364 type 1 depending on a type 2 to a type 1 depending on nothing. 00365 00366 More generally, takes a coordinate system that depends on multiple 00367 levels of coordinate systems and resolves them in order to resolve 00368 it's coordinate frame. So, if a coordinate system is of type 2, this 00369 will effectively set rid to 0 with a type 2. 00370 00371 This should handle any number of coordinate systems or coordinate 00372 system types assuming there is no circular references. 00373 """ 00374 #print str(self) 00375 #print self.rid 00376 #print "cid=%s rid=%s"%(self.cid, self.Rid()) 00377 if self.cid == 0 or isinstance(self.rid, int) or self.rid.isResolved: 00378 return # rid=0 so already resolved 00379 elif self.rid.isResolved == False: # rid 00380 #msg = 'there is a circular reference between Coord %s and Coord %s' %(self.cid,self.Rid() 00381 #assert self.rid.isCrossReferenced==False,msg) 00382 #print " resolving cid=%s rid=%s" %(self.cid,self.Rid()) 00383 self.rid.resolveCid() 00384 00385 ## rid coordinate system is now resolved, time to resolve the cid 00386 ## coordinate system. rid may be in a different coordinate system 00387 ## than cid 00388 self.isResolved = True 00389 self.e1,matrix = self.transformToGlobal(self.e1) 00390 00391 ## the axes are normalized, so assume they're points and 00392 ## resolve them in the XYZ system, but dont subtract e1 off 00393 ## (hence the False) 00394 self.e1,matrix = self.rid.transformToGlobal(self.e1) # origin 00395 i, matrix = self.rid.transformToGlobal(self.i, False) 00396 j, matrix = self.rid.transformToGlobal(self.j, False) 00397 k, matrix = self.rid.transformToGlobal(self.k, False) 00398 00399 ## the axes are global, so now we put them in the cid 00400 self.i = i 00401 self.j = j 00402 self.k = k 00403 00404 def crossReference(self, model): 00405 """ 00406 Links self.rid to a coordinate system. 00407 @param self the object pointer 00408 @param model the BDF object 00409 @warning 00410 Doesn't set rid to the coordinate system if it's in the global. 00411 This isn't a problem, it's meant to speed up the code in order 00412 to resolve extra coordinate systems. 00413 """ 00414 self.isCrossReferenced = True 00415 if self.rid != 0: 00416 self.rid = model.Coord(self.rid) 00417 ### 00418 00419 def transformToGlobal(self, p, resolveAltCoord=True, debug=False): 00420 """ 00421 Transforms a point from the local coordinate system to the reference 00422 coordinate frames "global" coordinate system. 00423 00424 \f[ \large [p_{global}]_{1x3} = 00425 [p_{local} -p_{origin}]_{1x3}[\Beta_{ij}]_{3x3} \f] 00426 00427 where \f$ [\Beta]_{ij} \f$ is the transformation matrix 00428 \f[ \large [\Beta]_{ij} \left[ 00429 \begin{array}{ccc} 00430 g_x \cdot i & g_x \cdot j & g_x \cdot k \\ 00431 g_y \cdot i & g_y \cdot j & g_y \cdot k \\ 00432 g_z \cdot i & g_z \cdot j & g_z \cdot k 00433 \end{array} \right] 00434 \f] 00435 00436 \f$ g \f$ is the global directional vector (e.g. \f$ g_x = [1,0,0]\f$) 00437 \f$ ijk \f$ is the ith direction in the local coordinate system 00438 @warning 00439 make sure you cross-reference before calling this 00440 @warning 00441 you probably shouldnt call this, call the Node methods Position 00442 and PositionWRT 00443 """ 00444 if debug: 00445 print("p = %s" %(p)) 00446 print("p-e1 = %s" %(p-self.e1)) 00447 00448 if not self.isResolved: 00449 self.resolveCid() 00450 if self.cid == 0: 00451 return p, array([[1., 0., 0.], 00452 [0., 1., 0.], 00453 [0., 0., 1.]]) 00454 00455 # the ijk axes arent resolved as R-theta-z, only points 00456 if resolveAltCoord: 00457 #print("p* = %s" %(p)) 00458 p = self.coordToXYZ(p) 00459 #p2 = p-self.eo 00460 00461 # Bij = Bip*j 00462 i = self.i 00463 j = self.j 00464 k = self.k 00465 if isinstance(self.rid, int): # rid=0 00466 gx = array([1., 0., 0.]) 00467 gy = array([0., 1., 0.]) 00468 gz = array([0., 0., 1.]) 00469 else: 00470 gx = self.rid.i 00471 gy = self.rid.j 00472 gz = self.rid.k 00473 ### 00474 00475 matrix = array([[dot(gx, i), dot(gy, i), dot(gz, i)], 00476 [dot(gx, j), dot(gy, j), dot(gz, j)], 00477 [dot(gx, k), dot(gy, k), dot(gz, k)]]) 00478 p2 = dot(p-self.e1, matrix) 00479 p3 = p2+self.e1 00480 00481 if debug: 00482 print("Cp = ",self.Cid()) 00483 print("gx = %s" %(gx)) 00484 print("gy = %s" %(gy)) 00485 print("gz = %s" %(gz)) 00486 print("p = %s" %(ListPrint(p))) 00487 print("matrix = \n",matrix) 00488 print("e1 = %s" %(ListPrint(self.e1))) 00489 print("p2 = %s" %(ListPrint(p2))) 00490 print('------------------------') 00491 print("p3 = %s\n" %(ListPrint(p3))) 00492 00493 #print str(self) 00494 if isinstance(self.rid, int): 00495 return (p3, matrix) 00496 else: 00497 ## @todo do i need to multiply rid.transform(p3)[1]*matrix 00498 return (self.rid.transformToGlobal(p3)[0], matrix) 00499 ### 00500 00501 def Rid(self): 00502 """Returns the reference coordinate system self.rid""" 00503 if isinstance(self.rid, int): 00504 return self.rid 00505 return self.rid.cid 00506 00507 00508 class Cord1x(Coord): 00509 rid = 0 # used only for transform to global 00510 def __init__(self, card, nCoord, data): 00511 Coord.__init__(self, card, data) 00512 00513 self.isResolved = False 00514 if nCoord is not None: 00515 assert nCoord == 0 or nCoord==1, 'nCoord=|%s|' %(nCoord) 00516 nCoord *= 4 # 0 if the 1st coord, 4 if the 2nd 00517 00518 ## the coordinate ID 00519 self.cid = card.field(1+nCoord) 00520 ## a Node at the origin 00521 self.g1 = card.field(2+nCoord) 00522 ## a Node on the z-axis 00523 self.g2 = card.field(3+nCoord) 00524 ## a Node on the xz-plane 00525 self.g3 = card.field(4+nCoord) 00526 else: 00527 self.cid = data[0] 00528 self.g1 = data[1] 00529 self.g2 = data[2] 00530 self.g3 = data[3] 00531 assert len(data) == 4, 'data = %s' %(data) 00532 ### 00533 assert self.g1 != self.g2 00534 assert self.g1 != self.g3 00535 assert self.g2 != self.g3 00536 00537 self.e1=None; self.e2=None; self.e3=None 00538 self.i=None; self.j=None; self.k=None 00539 00540 def crossReference(self, model): 00541 """ 00542 Links self.rid to a coordinate system. 00543 @param self the object pointer 00544 @param model the BDF object 00545 """ 00546 self.isCrossReferenced = True 00547 ## grid point 1 00548 self.g1 = model.Node(self.g1) 00549 ## grid point 2 00550 self.g2 = model.Node(self.g2) 00551 ## grid point 3 00552 self.g3 = model.Node(self.g3) 00553 00554 def resolveCid(self): 00555 """ 00556 finds the position of the nodes used define the coordinate system 00557 and sets the ijk vectors 00558 """ 00559 ## the origin 00560 self.e1 = self.g1.Position() 00561 ## a point on the z-axis 00562 self.e2 = self.g2.Position() 00563 ## a point on the xz-plane 00564 self.e3 = self.g3.Position() 00565 self.setup() 00566 00567 def G1(self): 00568 if isinstance(self.g1, int): 00569 return self.g1 00570 return self.g1.nid 00571 00572 def G2(self): 00573 if isinstance(self.g2, int): 00574 return self.g2 00575 return self.g2.nid 00576 00577 def G3(self): 00578 if isinstance(self.g3, int): 00579 return self.g3 00580 return self.g3.nid 00581 00582 def NodeIDs(self): 00583 """ 00584 returns [g1,g2,g3] 00585 """ 00586 grids = [self.G1(), self.G2(), self.G3()] 00587 return grids 00588 00589 class CORD3G(Coord): # not done 00590 """ 00591 Defines a general coordinate system using three rotational angles as 00592 functions of coordinate values in the reference coordinate system. 00593 The CORD3G entry is used with the MAT9 entry to orient material principal 00594 axes for 3-D composite analysis 00595 00596 CORD3G CID METHOD FORM THETAID1 THETAID2 THETAID3 CIDREF 00597 CORD3G 100 E313 EQN 110 111 112 0 00598 """ 00599 type = 'CORD3G' 00600 def __init__(self, card=[0, 0, 0, 0, 0, 0, 0], data=None): 00601 """ 00602 Intilizes the CORD3G 00603 @param self the object pointer 00604 @param card a list version of the fields 00605 """ 00606 if isinstance(card, list): 00607 assert len(card) == 8 00608 card = BDFCard(card) 00609 Coord.__init__(self, card, data) 00610 00611 self.cid = card.field(1) 00612 method = card.field(2) 00613 self.methodES = method[0] 00614 self.methodInt = int(method[1:]) 00615 assert self.methodES in ['E', 'S'] 00616 assert 0 < self.methodInt < 1000 00617 00618 self.form = card.field(3, 'EQN') 00619 self.thetas = card.field(4, 7) 00620 assert len(self.thetas) == 3, 'thetas=%s' %(self.thetas) 00621 self.cidRef = card.field(7) 00622 00623 assert self.form in ['EQN', 'TABLE'] # EQN for DEQATN, TABLE for TABLE3D 00624 00625 def crossReference(self, model): 00626 self.cidRef = model.Coord(self.cidRef) 00627 00628 def CidRef(self): 00629 if isinstance(self.cidRef, int): 00630 return self.cidRef 00631 return self.cidRef.cid 00632 00633 def transformToGlobal(self, p, debug=False): 00634 """ 00635 @warning not done, just setting up how you'd do this 00636 @note per http://en.wikipedia.org/wiki/Euler_angles 00637 "This means for example that a convention named (YXZ) is the result 00638 of performing first an intrinsic Z rotation, followed by X and 00639 Y rotations, in the moving axes (Note: the order of multiplication 00640 of matrices is the opposite of the order in which they're 00641 applied to a vector)." 00642 """ 00643 for (rotation, theta) in izip(self.rotations, self.thetas): 00644 ct = cos(radians(theta)) 00645 st = sin(radians(theta)) 00646 if rotation == 1: p = dot(self.RotationX(ct, st), p) 00647 elif rotation == 2: p = dot(self.RotationY(ct, st), p) 00648 elif rotation == 3: p = dot(self.RotationZ(ct, st), p) 00649 return p 00650 00651 def RotationX(self, ct, st): 00652 matrix = array([[ 1., 0., 0.], 00653 [ ct, 0., -st], 00654 [-st, 0., ct]]) 00655 return matrix 00656 00657 def RotationY(self, ct, st): 00658 matrix = array([[ ct, 0., st], 00659 [ 0., 1., 0.], 00660 [-st, 0., ct]]) 00661 return matrix 00662 00663 def RotationZ(self, ct, st): 00664 matrix = array([[ ct, st, 0.], 00665 [-st, ct, 0.], 00666 [ 0., 0., 1.]]) 00667 return matrix 00668 00669 def rawFields(self): 00670 method = self.methodES+str(self.methodInt) 00671 fields = ['CORD3G', self.cid, method, self.form]+self.thetas+[self.CidRef()] 00672 return fields 00673 00674 class CORD1R(Cord1x, RectangularCoord): 00675 type = 'CORD1R' 00676 """ 00677 CORD1R CIDA G1A G2A G3A CIDB G1B G2B G3B 00678 """ 00679 00680 def __init__(self, card=None, nCoord=0, data=None): 00681 """ 00682 Intilizes the CORD1R 00683 @param self 00684 the object pointer 00685 @param nCoord 00686 the coordinate location on the line (there are possibly 2 coordinates 00687 on 1 card) 00688 @param card 00689 a list version of the fields (1 CORD1R only) 00690 """ 00691 Cord1x.__init__(self, card, nCoord, data) 00692 00693 def rawFields(self): 00694 fields = ['CORD1R', self.cid]+self.NodeIDs() 00695 return fields 00696 00697 class CORD1C(Cord1x, CylindricalCoord): 00698 type = 'CORD1C' 00699 """ 00700 CORD1C CIDA G1A G2A G3A CIDB G1B G2B G3B 00701 """ 00702 def __init__(self, card=None, nCoord=0, data=None): 00703 """ 00704 Intilizes the CORD1R 00705 @param self 00706 the object pointer 00707 @param card 00708 a BDFCard object 00709 @param nCoord 00710 the coordinate location on the line (there are possibly 2 coordinates 00711 on 1 card) 00712 @param data 00713 a list version of the fields (1 CORD1R only) 00714 00715 """ 00716 Cord1x.__init__(self, card, nCoord, data) 00717 00718 def rawFields(self): 00719 fields = ['CORD1C', self.cid]+self.NodeIDs() 00720 return fields 00721 00722 class CORD1S(Cord1x, SphericalCoord): 00723 type = 'CORD1S' 00724 """ 00725 CORD1S CIDA G1A G2A G3A CIDB G1B G2B G3B 00726 """ 00727 def __init__(self, card=None, nCoord=0, data=None): 00728 """ 00729 Intilizes the CORD1S 00730 @param self 00731 the object pointer 00732 @param card 00733 a BDFCard object 00734 @param nCoord 00735 the coordinate location on the line (there are possibly 2 coordinates 00736 on 1 card) 00737 @param data 00738 a list version of the fields (1 CORD1S only) 00739 """ 00740 Cord1x.__init__(self, card, nCoord, data) 00741 00742 def rawFields(self): 00743 fields = ['CORD1S', self.cid]+self.NodeIDs() 00744 return fields 00745 00746 00747 class CORD2R(Cord2x, RectangularCoord): 00748 type = 'CORD2R' 00749 def __init__(self, card=None, data=[0,0, 0.,0.,0., 0.,0.,1., 1.,0.,0.]): 00750 """ 00751 Intilizes the CORD2R 00752 @param self 00753 the object pointer 00754 @param card 00755 a BDFCard object 00756 @param data 00757 a list version of the fields (1 CORD2R only) 00758 """ 00759 #print card 00760 Cord2x.__init__(self, card, data) 00761 00762 def rawFields(self): 00763 rid = set_blank_if_default(self.Rid(), 0) 00764 fields = ['CORD2R', self.cid, rid] +list(self.e1)+list(self.e2)+list(self.e3) 00765 return fields 00766 00767 00768 class CORD2S(Cord2x, SphericalCoord): 00769 type = 'CORD2S' 00770 def __init__(self, card=None, data=None): 00771 """ 00772 Intilizes the CORD2R 00773 @param self 00774 the object pointer 00775 @param card 00776 a BDFCard object 00777 @param data 00778 a list version of the fields (1 CORD2S only) 00779 """ 00780 Cord2x.__init__(self, card, data) 00781 00782 def rawFields(self): 00783 rid = set_blank_if_default(self.Rid(), 0) 00784 fields = ['CORD2S', self.cid, rid] +list(self.e1)+list(self.e2)+list(self.e3) 00785 return fields 00786 00787 class CORD2C(Cord2x, CylindricalCoord): 00788 type = 'CORD2C' 00789 def __init__(self, card=None, data=None): 00790 """ 00791 Intilizes the CORD2C 00792 @param self 00793 the object pointer 00794 @param card 00795 a BDFCard object 00796 @param data 00797 a list version of the fields (1 CORD2C only) 00798 """ 00799 Cord2x.__init__(self, card, data) 00800 00801 def rawFields(self): 00802 rid = set_blank_if_default(self.Rid(), 0) 00803 fields = ['CORD2C', self.cid, rid] +list(self.e1)+list(self.e2)+list(self.e3) 00804 return fields