pyNastran  0.5.0
pyNastran BDF Reader/Writer, OP2 Parser, and GUI
coordinateSystems.py
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables