pyNastran  0.5.0
pyNastran BDF Reader/Writer, OP2 Parser, and GUI
methods.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 
00026 from __future__ import division, print_function
00027 #import sys
00028 from itertools import izip
00029 
00030 from pyNastran.bdf.fieldWriter import set_blank_if_default
00031 from pyNastran.bdf.cards.baseCard import BaseCard
00032 
00033 class Method(BaseCard):
00034     """
00035     Generic class for all methods.
00036     Part of self.methods
00037     """
00038     def __init__(self, card=None, data=None):
00039         pass
00040 
00041 class EIGB(Method):
00042     """
00043     Defines data needed to perform buckling analysis
00044     """
00045     type = 'EIGB'
00046     def __init__(self, card=None, data=None):
00047         Method.__init__(self, card, data)
00048         if card:
00049             ## Set identification number. (Unique Integer > 0)
00050             self.sid = card.field(1)
00051             ## Method of eigenvalue extraction. (Character: 'INV' for inverse
00052             ## power method or 'SINV' for enhanced inverse power method.)
00053             self.method = card.field(2)
00054             assert self.method in ['INV', 'SINV'], 'method must be INV or SINV.  method=|%s|' %(self.method)
00055             ## Eigenvalue range of interest. (Real, L1 < L2)
00056             self.L1   = card.field(3)
00057             self.L2   = card.field(4)
00058             assert self.L1 < self.L2, 'L1=%s L2=%s; L1<L2 is requried' %(self.L1, self.L2)
00059             ## Estimate of number of roots in positive range not used for
00060             ## METHOD = 'SINV'. (Integer > 0)
00061             self.nep  = card.field(5, 0)
00062             ## Desired number of positive and negative roots.
00063             ## (Integer>0; Default = 3*NEP)
00064             self.ndp  = card.field(6, 3*self.nep)
00065             self.ndn  = card.field(7, 3*self.nep)
00066             ## Method for normalizing eigenvectors.
00067             ## ('MAX' or 'POINT';Default='MAX')
00068             self.norm = card.field(9, 'MAX')
00069             self.G    = card.field(10)
00070             self.C    = card.field(11)
00071         else:
00072             raise NotImplementedError('EIGB')
00073         ###
00074         #print self.rawFields()
00075         #print self.reprFields()
00076         #print self
00077 
00078     def crossReference(self, model):
00079         pass
00080 
00081     def rawFields(self):
00082         fields = ['EIGB', self.sid, self.method, self.L1, self.L2, self.nep, self.ndp, self.ndn, None,
00083                           self.norm, self.G, self.C]
00084         return fields
00085 
00086     def reprFields(self):
00087         #method = set_blank_if_default(self.method,'INV')
00088         nep = set_blank_if_default(self.nep, 0)
00089         ndp = set_blank_if_default(self.ndp, 3*self.nep)
00090         ndn = set_blank_if_default(self.ndn, 3*self.nep)
00091         #print "nep = ",self.nep,ndn
00092         norm = set_blank_if_default(self.norm, 'MAX')
00093         fields = ['EIGB', self.sid, self.method, self.L1, self.L2, nep, ndp, ndn, None,
00094                          norm, self.G, self.C]
00095         return fields
00096 
00097 class EIGC(Method): ## not done
00098     """
00099     Defines data needed to perform complex eigenvalue analysis
00100     """
00101     type = 'EIGC'
00102     def __init__(self, card=None, data=None):
00103         Method.__init__(self, card, data)
00104         if card:
00105             ## Set identification number. (Unique Integer > 0)
00106             self.sid = card.field(1)
00107             ## Method of complex eigenvalue extraction
00108             self.method = card.field(2)
00109             assert self.method in ['INV', 'HESS', 'CLAN'], 'method=%s is not INV, HESS, CLAN' %(self.method)
00110             ## Method for normalizing eigenvectors
00111             self.norm   = card.field(3)
00112 
00113             ## Grid or scalar point identification number. Required only if
00114             ## NORM='POINT'. (Integer>0)
00115             self.G = card.field(4)
00116             ## Component number. Required only if NORM='POINT' and G is a
00117             ## geometric grid point. (1<Integer<6)
00118             self.C = card.field(5)
00119             ## Convergence criterion. (Real > 0.0. Default values are: 10-4 for
00120             ## METHOD = "INV", 10-15 for METHOD = "HESS", E is machine
00121             ## dependent for METHOD = "CLAN".)
00122             self.E = card.field(6)
00123             self.ndo = card.field(7)
00124             
00125             # ALPHAAJ OMEGAAJ ALPHABJ OMEGABJ LJ NEJ NDJ
00126             fields = card.fields(9)
00127             self.alphaAjs = []
00128             self.omegaAjs = []
00129             nFields = len(fields)
00130             nRows = nFields//8
00131             if nFields%7 > 0:
00132                 nRows += 1
00133             
00134             if self.method=='CLAN':
00135                 self.loadCLAN(nRows, card)
00136             elif self.method in ['HESS', 'INV']: # HESS, INV
00137                 self.loadHESS_INV(nRows, card)
00138             else:
00139                 msg = 'invalid EIGC method...method=|%r|' %(self.method)
00140                 raise RuntimeError(msg)
00141             ###
00142             #assert card.nFields()<8,'card = %s' %(card.fields(0))
00143         else:
00144             raise NotImplementedError('EIGC')
00145         ###
00146 
00147     def loadCLAN(self, nRows, card):
00148         self.mblkszs = []
00149         self.iblkszs = []
00150         self.ksteps  = []
00151         self.NJIs    = []
00152         for iRow in xrange(nRows):
00153             #NDJ_default = None
00154 
00155             self.alphaAjs.append(card.field(9+8*iRow  , 0.0))
00156             self.omegaAjs.append(card.field(9+8*iRow+1, 0.0))
00157             self.mblkszs.append( card.field(9+8*iRow+2, 7))
00158 
00159             #self.alphaAjs.append(card.field(9+8*iRow  ,'ALPHA%s'%(iRow)))
00160             #self.omegaAjs.append(card.field(9+8*iRow+1,'OMEGA%s'%(iRow)))
00161             #self.mblkszs.append( card.field(9+8*iRow+2,'MBLOCK%s'%(iRow)))
00162 
00163             self.iblkszs.append( card.field(9+8*iRow+3, 2))
00164             self.ksteps.append(  card.field(9+8*iRow+4, 5))
00165             self.NJIs.append(    card.field(9+8*iRow+6))
00166         ###
00167 
00168     def loadHESS_INV(self, nRows, card):
00169         self.alphaBjs = []
00170         self.omegaBjs = []
00171         self.LJs  = []
00172         self.NEJs = []
00173         self.NDJs = []
00174 
00175         alphaOmega_default = None
00176         LJ_default = None
00177         if self.method=='INV':
00178             alphaOmega_default = 0.0
00179             LJ_default = 1.0
00180 
00181         for iRow in xrange(nRows):
00182             NEj = card.field(9+7*iRow+5)
00183             NDJ_default = None
00184             if self.method=='INV':
00185                 NDJ_default = 3*NEj
00186 
00187             self.alphaAjs.append(card.field(9+8*iRow  , alphaOmega_default))
00188             self.omegaAjs.append(card.field(9+8*iRow+1, alphaOmega_default))
00189             self.alphaBjs.append(card.field(9+8*iRow+2, alphaOmega_default))
00190             self.omegaBjs.append(card.field(9+8*iRow+3, alphaOmega_default))
00191             self.LJs.append(     card.field(9+8*iRow+4, LJ_default))
00192             self.NEJs.append(    card.field(9+8*iRow+5))
00193             self.NDJs.append(    card.field(9+8*iRow+6, NDJ_default))
00194         ###
00195 
00196     def crossReference(self, model):
00197         pass
00198 
00199     def rawMethod(self):
00200         fields = []
00201         if self.method in ['HESS', 'INV']:
00202             for (alphaA, omegaA, alphaB, omegaB, Lj, NEj, NDj) in izip(
00203                  self.alphaAjs, self.omegaAjs, self.alphaBjs, self.omegaBjs,
00204                  self.LJs, self.NEJs, self.NDJs):
00205                 alphaA = set_blank_if_default(alphaA, 0.0)
00206                 omegaA = set_blank_if_default(omegaA, 0.0)
00207                 alphaB = set_blank_if_default(alphaB, 0.0)
00208                 omegaB = set_blank_if_default(omegaB, 0.0)
00209                 fields += [alphaA, omegaA, alphaB, omegaB, Lj, NEj, NDj, None]
00210             ###
00211         elif self.method=='CLAN':
00212             for (alphaA, omegaA, mblksz, iblksz, kstep, Nj) in izip(
00213                  self.alphaAjs, self.omegaAjs, self.mblkszs, self.iblkszs,
00214                  self.ksteps, self.NJIs):
00215                 alphaA = set_blank_if_default(alphaA, 0.0)
00216                 omegaA = set_blank_if_default(omegaA, 0.0)
00217                 mblksz = set_blank_if_default(mblksz, 7)
00218                 iblksz = set_blank_if_default(iblksz, 2)
00219                 kstep  = set_blank_if_default(kstep, 5)
00220                 
00221                 fields += [alphaA, omegaA, mblksz, iblksz, kstep, None, Nj, None]
00222         else:
00223             msg = 'invalid EIGC method...method=|%r|' %(self.method)
00224             raise RuntimeError(msg)
00225         return fields
00226 
00227     def reprMethod(self):
00228         return self.rawMethod()
00229 
00230     def rawFields(self):
00231         fields = ['EIGC', self.sid, self.method, self.norm, self.G, self.C, self.E, self.ndo, None]
00232         fields += self.rawMethod()
00233         return fields
00234 
00235     def reprFields(self):
00236         if self.E is None:
00237             E = None
00238         else:
00239             E = str(self.E)
00240         fields = ['EIGC', self.sid, self.method, self.norm, self.G, self.C, E, self.ndo, None]
00241         fields += self.reprMethod()
00242         return fields
00243 
00244 class EIGR(Method):
00245     """
00246     Defines data needed to perform real eigenvalue analysis
00247     """
00248     type = 'EIGR'
00249     def __init__(self, card=None, data=None):
00250         Method.__init__(self, card, data)
00251         if card:
00252             ## Set identification number. (Unique Integer > 0)
00253             self.sid = card.field(1)
00254             ## Method of eigenvalue extraction. (Character: 'INV' for inverse power
00255             ## method or 'SINV' for enhanced inverse power method.)
00256             self.method = card.field(2, 'LAN')
00257             ## Frequency range of interest
00258             self.f1   = card.field(3)
00259             self.f2   = card.field(4)
00260             ## Estimate of number of roots in range (Required for
00261             ## METHOD = 'INV'). Not used by 'SINV' method.
00262             self.ne  = card.field(5)
00263             ## Desired number of roots (default=600 for SINV 3*ne for INV)
00264             self.nd  = card.field(6)
00265             ## Method for normalizing eigenvectors. ('MAX' or 'POINT';Default='MAX')
00266             self.norm = card.field(9, 'MASS')
00267             assert self.norm in ['POINT', 'MASS', 'MAX']
00268             ## Grid or scalar point identification number. Required only if NORM='POINT'. (Integer>0)
00269             self.G    = card.field(10)
00270             ## Component number. Required only if NORM='POINT' and G is a geometric grid point. (1<Integer<6)
00271             self.C    = card.field(11)
00272         else:
00273             raise NotImplementedError('EIGR')
00274         ###
00275 
00276     def crossReference(self,model):
00277         pass
00278 
00279     def rawFields(self):
00280         fields = ['EIGR',self.sid, self.method, self.f1, self.f2, self.ne, self.nd, None, None,
00281                          self.norm, self.G, self.C]
00282         return fields
00283 
00284     def reprFields(self):
00285         method = set_blank_if_default(self.method, 'LAN')
00286         norm = set_blank_if_default(self.norm, 'MASS')
00287         fields = ['EIGR',self.sid, method, self.f1, self.f2, self.ne, self.nd, None, None,
00288                          norm, self.G, self.C]
00289         return fields
00290 
00291 class EIGP(Method):
00292     """
00293     Defines poles that are used in complex eigenvalue extraction by the Determinant method.
00294     """
00295     type = 'EIGP'
00296     def __init__(self, card=None, data=None):
00297         Method.__init__(self, card, data)
00298         if card:
00299             ## Set identification number. (Unique Integer > 0)
00300             self.sid = card.field(1)
00301             
00302             ## Coordinates of point in complex plane. (Real)
00303             self.alpha1 = card.field(2)
00304             ## Coordinates of point in complex plane. (Real)
00305             self.omega1 = card.field(3)
00306             ## Multiplicity of complex root at pole defined by point at ALPHAi
00307             ## and OMEGAi
00308             self.m1 = card.field(4)
00309             
00310             ## Coordinates of point in complex plane. (Real)
00311             self.alpha2 = card.field(5)
00312             ## Coordinates of point in complex plane. (Real)
00313             self.omega2 = card.field(6)
00314             ## Multiplicity of complex root at pole defined by point at ALPHAi
00315             ## and OMEGAi
00316             self.m2 = card.field(7)
00317         else:
00318             raise NotImplementedError('EIGP')
00319         ###
00320 
00321     def crossReference(self, model):
00322         pass
00323 
00324     def rawFields(self):
00325         fields = ['EIGP', self.alpha1, self.omega1, self.m1, self.alpha2, self.omega2, self.m2]
00326         return fields
00327 
00328     def reprFields(self):
00329         return self.rawFields()
00330 
00331 class EIGRL(Method):
00332     """
00333     Defines data needed to perform real eigenvalue (vibration or buckling)
00334     analysis with the Lanczos method
00335     """
00336     type = 'EIGRL'
00337     def __init__(self, card=None, data=None, sol=None):
00338         Method.__init__(self, card, data)
00339         if card:
00340             ## Set identification number. (Unique Integer > 0)
00341             self.sid    = card.field(1)
00342             ## For vibration analysis: frequency range of interest. For buckling
00343             ## analysis: eigenvalue range of interest. See Remark 4.
00344             ## (Real or blank, -5 10e16 <= V1 < V2 <= 5.10e16)
00345             self.v1     = card.field(2)
00346             self.v2     = card.field(3)
00347             ## Number of roots desired
00348             self.nd     = card.field(4)
00349             ## Diagnostic level. (0 < Integer < 4; Default = 0)
00350             self.msglvl = card.field(5, 0)
00351             ## Number of vectors in block or set. Default is machine dependent
00352             self.maxset = card.field(6)
00353             ## Estimate of the first flexible mode natural frequency
00354             ## (Real or blank)
00355             self.shfscl = card.field(7)
00356             ## Method for normalizing eigenvectors (Character: 'MASS' or 'MAX')
00357             self.norm   = card.field(8)
00358             
00359             optionValues = card.fields(9)
00360             self.options = []
00361             self.values  = []
00362             #print "optionValues = ",optionValues
00363             for optionValue in optionValues:
00364                 #print "optionValue = ",optionValue
00365                 (option,value) = optionValue.split('=')
00366                 self.options.append(option)
00367                 self.values.append(value)
00368 
00369             ## Method for normalizing eigenvectors
00370             if sol in [103, 115, 146]: # normal modes,cyclic normal modes, flutter
00371                 self.norm = card.field(8, 'MASS')
00372             elif sol in [105, 110, 111, 116]: # buckling, modal complex eigenvalues,modal frequency response,cyclic buckling
00373                 self.norm = card.field(8, 'MAX')
00374             else:
00375                 self.norm = card.field(8)
00376             #assert self.norm in ['MASS', 'MAX'],'norm=%s sol=%s' %(self.norm,sol)
00377             #assert card.nFields()<9,'card = %s' %(card.fields(0))
00378         else:
00379             raise NotImplementedError('EIGRL')
00380         ###
00381 
00382     def crossReference(self,model):
00383         pass
00384 
00385     def rawFields(self):
00386         fields = ['EIGRL',self.sid,self.v1,self.v2,self.nd,self.msglvl,self.maxset,self.shfscl,self.norm]
00387         for (option, value) in izip(self.options, self.values):
00388             fields += [option+'='+str(value)]
00389         return fields
00390 
00391     def reprFields(self):
00392         msglvl = set_blank_if_default(self.msglvl, 0)
00393         fields = ['EIGRL',self.sid,self.v1,self.v2,self.nd,msglvl,self.maxset,self.shfscl,self.norm]
00394         for (option, value) in izip(self.options, self.values):
00395             fields += [option+'='+str(value)]
00396         return fields
 All Classes Namespaces Files Functions Variables