Source code for pyNastran.bdf.cards.properties.bush

"""
All bush properties are defined in this file.  This includes:

 *   PBUSH
 *   PBUSH1D
 *   PBUSH2D (not implemented)
 *   PBUSHT

All bush properties are BushingProperty and Property objects.

"""
from __future__ import (nested_scopes, generators, division, absolute_import,
                        print_function, unicode_literals)

from pyNastran.utils.numpy_utils import integer_types
from pyNastran.bdf.cards.base_card import Property
from pyNastran.bdf.bdf_interface.assign_type import (
    integer, integer_or_blank, double, double_or_blank, string,
    string_or_blank, blank, fields)
from pyNastran.bdf.field_writer_8 import print_card_8
from pyNastran.bdf.field_writer_16 import print_card_16

[docs]class BushingProperty(Property): type = 'BushingProperty' def __init__(self): Property.__init__(self)
[docs] def cross_reference(self, model): pass
[docs] def uncross_reference(self): """Removes cross-reference links""" pass
[docs]class PBUSH(BushingProperty): """ Generalized Spring-and-Damper Property Defines the nominal property values for a generalized spring-and-damper structural element. +-------+-----+------+-----+-----+-----+-----+-----+----+ | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | +=======+=====+======+=====+=====+=====+=====+=====+====+ | PBUSH | PID | K | K1 | K2 | K3 | K4 | K5 | K6 | +-------+-----+------+-----+-----+-----+-----+-----+----+ | | B | B1 | B2 | B3 | B4 | B5 | B6 | | +-------+-----+------+-----+-----+-----+-----+-----+----+ | | GE | GE1 | GE2 | GE3 | GE4 | GE5 | GE6 | | +-------+-----+------+-----+-----+-----+-----+-----+----+ | | RCV | SA | ST | EA | ET | | | | +-------+-----+------+-----+-----+-----+-----+-----+----+ | | M | MASS | | | | | | | +-------+-----+------+-----+-----+-----+-----+-----+----+ """ type = 'PBUSH' _field_map = { 1: 'pid', } pname_map = { -2 : 'K1', -3 : 'K2', -4 : 'K3', -5 : 'K4', -6 : 'K5', -7 : 'K6', -8 : 'B1', -9 : 'B2', -10 : 'B3', -11 : 'B4', -12 : 'B5', -13 : 'B6', -14 : 'GE1', -15 : 'GE2', -16 : 'GE3', -17 : 'GE4', -18 : 'GE5', -19 : 'GE6', -20 : 'SA', -21 : 'ST', -22 : 'EA', -23 : 'ET', }
[docs] def update_by_pname_fid(self, name, value): if name == 'B1': self.Bi[0] = value elif name == 'B2': self.Bi[1] = value elif name == 'B3': self.Bi[2] = value elif name == 'B4': self.Bi[3] = value elif name == 'B5': self.Bi[4] = value elif name == 'B6': self.Bi[5] = value elif name == 'K1': self.Ki[0] = value elif name == 'K2': self.Ki[1] = value elif name == 'K3': self.Ki[2] = value elif name == 'K4': self.Ki[3] = value elif name == 'K5': self.Ki[4] = value elif name == 'K6': self.Ki[5] = value elif name == 'GE1': self.GEi[0] = value elif name == 'GE2': self.GEi[1] = value elif name == 'GE3': self.GEi[2] = value elif name == 'GE4': self.GEi[3] = value elif name == 'GE5': self.GEi[4] = value elif name == 'GE6': self.GEi[5] = value #elif name == 'M': #self.mass elif isinstance(name, int) and name in self.pname_map: name2 = self.pname_map[name] self.update_by_pname_fid(name2, value) else: raise NotImplementedError('property_type=%r has not implemented %r in pname_map' % ( self.type, name))
#pname_fid_map = { #4 : 'A', 'A' : 'A', #5 : 'i1', 'I1' : 'i1', #6 : 'i2', 'I2' : 'i2', #7 : 'i12', 'I12' : 'i12', #5 : 'j', 'J' : 'j', #} def __init__(self, pid, k, b, ge, rcv=None, mass=None, comment=''): """ Creates a PBUSH card, which defines a property for a CBUSH Parameters ---------- pid : int property id k : List[float] Nominal stiffness values in directions 1 through 6. len(k) = 6 b : List[float] Nominal damping coefficients in direction 1 through 6 in units of force per unit velocity len(b) = 6 ge : List[float] Nominal structural damping constant in directions 1 through 6. len(ge) = 6 rcv : List[float]; default=None -> (None, None, None, None) [sa, st, ea, et] = rcv length(mass_fields) = 4 mass : float; default=None lumped mass of the CBUSH This is an MSC only parameter. comment : str; default='' a comment for the card """ BushingProperty.__init__(self) if comment: self.comment = comment #: Property ID self.pid = pid self.vars = [] # K parameter self.Ki = k if k: nk = len(k) if nk < 6: k.extend([0.] * (6 - nk)) self.vars.append('K') # B parameter self.Bi = b if b: nb = len(b) if nb < 6: b.extend([0.] * (6 - nb)) self.vars.append('B') # GE parameter self.GEi = ge if ge: nge = len(ge) if nge < 6: ge.extend([0.] * (6 - nge)) self.vars.append('GE') # RCV parameters if rcv is None: sa, st, ea, et = None, None, None, None else: sa, st, ea, et = rcv if sa is not None or st is not None or ea is not None or et is not None: self.vars.append('RCV') self.sa = sa self.st = st self.ea = ea self.et = et # M parameter (MSC only; in 2016, not in 2005) self.mass = mass if mass: self.vars.append('M')
[docs] @classmethod def _init_from_empty(cls): pid = 1 k = [1.] b = [1.] ge = [1.] return PBUSH(pid, k, b, ge, rcv=None, mass=None, comment='')
[docs] def validate(self): assert isinstance(self.Ki, list), 'PBUSH: pid=%i type(Ki)=%s Ki=%s' % (self.pid, type(self.Ki), self.Ki) assert isinstance(self.Bi, list), 'PBUSH: pid=%i type(Bi)=%s Bi=%s' % (self.pid, type(self.Bi), self.Bi) assert isinstance(self.GEi, list), 'PBUSH: pid=%i type(GEi)=%s GEi=%s' % (self.pid, type(self.GEi), self.GEi)
[docs] @classmethod def add_card(cls, card, comment=''): """ Adds a PBUSH card from ``BDF.add_card(...)`` Parameters ---------- card : BDFCard() a BDFCard object comment : str; default='' a comment for the card """ k_fields = [] b_fields = [] ge_fields = [] rcv_fields = [None, None, None, None] mass = None pid = integer(card, 1, 'pid') nfields = card.nfields istart = 2 while istart < nfields: pname = string(card, istart, 'pname') if pname == 'K': # Flag indicating that the next 1 to 6 fields are stiffness values in # the element coordinate system. #self.k = string(card, istart, 'k') #: Nominal stiffness values in directions 1 through 6. #: See Remarks 2 and 3. (Real; Default = 0.0) k_fields = cls._read_var(card, 'Ki', istart + 1, istart + 7) elif pname == 'B': # Flag indicating that the next 1 to 6 fields are force-per-velocity # damping. #self.b = string(card, istart, 'b') #: Force per unit velocity (Real) #: Nominal damping coefficients in direction 1 through 6 in units of #: force per unit velocity. See Remarks 2, 3, and 9. (Real; Default=0.) b_fields = cls._read_var(card, 'Bi', istart + 1, istart + 7) elif pname == 'GE': # Flag indicating that the next fields, 1 through 6 are structural # damping constants. See Remark 7. (Character) #self.ge = string(card, istart, 'ge') #: Nominal structural damping constant in directions 1 through 6. See #: Remarks 2. and 3. (Real; Default = 0.0) ge_fields = cls._read_var(card, 'GEi', istart + 1, istart + 7) elif pname == 'RCV': rcv_fields = cls._read_rcv(card, istart) elif pname == 'M': # Lumped mass of the cbush; default=0.0 mass = double_or_blank(card, istart + 1, 'mass', 0.) else: raise RuntimeError('unsupported PBUSH type; pname=%r' % pname) #break # old version... istart += 8 return PBUSH(pid, k_fields, b_fields, ge_fields, rcv_fields, mass, comment=comment)
[docs] @classmethod def _read_var(cls, card, var_prefix, istart, iend): Ki = fields(double_or_blank, card, var_prefix, istart, iend) return Ki
@classmethod def add_op2_data(cls, data, comment=''): """ Adds a PBUSH card from the OP2 Parameters ---------- data : List[varies] a list of fields defined in OP2 format comment : str; default='' a comment for the card """ (pid, k1, k2, k3, k4, k5, k6, b1, b2, b3, b4, b5, b6, g1, g2, g3, g4, g5, g6, sa, st, ea, et) = data k_fields = [k1, k2, k3, k4, k5, k6] b_fields = [b1, b2, b3, b4, b5, b6] ge_fields = [g1, g2, g3, g4, g5, g6] rcv_fields = [sa, st, ea, et] mass = 0. return PBUSH(pid, k_fields, b_fields, ge_fields, rcv_fields, mass, comment=comment) def _verify(self, xref): pid = self.Pid() assert isinstance(pid, integer_types), 'pid=%r' % pid
[docs] @classmethod def _read_rcv(cls, card, istart): # Flag indicating that the next 1 to 4 fields are stress or strain # coefficients. (Character) #self.rcv = string(card, istart, 'rcv') sa = double_or_blank(card, istart + 1, 'sa', 1.) st = double_or_blank(card, istart + 2, 'st', 1.) ea = double_or_blank(card, istart + 3, 'ea', 1.) et = double_or_blank(card, istart + 4, 'et', 1.) return [sa, st, ea, et]
[docs] def raw_fields(self): list_fields = ['PBUSH', self.pid] for var in self.vars: if var == 'K': list_fields += ['K'] + self.Ki elif var == 'B': list_fields += ['B'] + self.Bi elif var == 'GE': list_fields += ['GE'] + self.GEi elif var == 'RCV': list_fields += ['RCV', self.sa, self.st, self.ea, self.et] elif var == 'M': list_fields += ['M', self.mass] else: raise RuntimeError('not supported PBUSH field...') nspaces = 8 - (len(list_fields) - 1) % 8 if nspaces == 8: list_fields += [None] elif nspaces < 8: list_fields += [None] * (nspaces + 1) return list_fields
[docs] def repr_fields(self): return self.raw_fields()
[docs] def write_card(self, size=8, is_double=False): card = self.repr_fields() if size == 8: return self.comment + print_card_8(card) return self.comment + print_card_16(card)
[docs]class PBUSH1D(BushingProperty): """ +---------+--------+-------+--------+--------+-------+-------+-------+ | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | +=========+========+=======+========+========+=======+=======+=======+ | PBUSH1D | PID | K | C | M | | SA | SE | +---------+--------+-------+--------+--------+-------+-------+-------+ | | SHOCKA | TYPE | CVT | CVC | EXPVT | EXPVC | IDTS | +---------+--------+-------+--------+--------+-------+-------+-------+ | | IDETS | IDECS | IDETSD | IDECSD | | | | +---------+--------+-------+--------+--------+-------+-------+-------+ | | SPRING | TYPE | IDT | IDC | IDTDU | IDCDU | | +---------+--------+-------+--------+--------+-------+-------+-------+ | | DAMPER | TYPE | IDT | IDC | IDTDV | IDCDV | | +---------+--------+-------+--------+--------+-------+-------+-------+ | | GENER | IDT | IDC | IDTDU | IDCDU | IDTDV | IDCDV | +---------+--------+-------+--------+--------+-------+-------+-------+ """ type = 'PBUSH1D' _properties = ['pname_fid_map'] pname_fid_map = { 'K' : 'k', 'C' : 'c', 'M' : 'm', }
[docs] @classmethod def _init_from_empty(cls): pid = 1 return PBUSH1D(pid, k=0., c=0., m=0., sa=0., se=0., optional_vars=None, comment='')
def __init__(self, pid, k=0., c=0., m=0., sa=0., se=0., optional_vars=None, comment=''): """ Creates a PBUSH1D card Parameters ---------- pid : int property id k : float stiffness c : float Viscous damping m : float mass sa : float Stress recovery coefficient [1/area]. se : float Strain recovery coefficient [1/length]. optional_vars : dict[name] : value; default=None name : str SHOCKA, SPRING, DAMPER, GENER values : List[varies] the values SHOCKA: Coefficients of the following force versus velocity/displacement relationship F(u, v) = Cv * S(u) * sign(v) * |v|^EXPV TYPE CVT CVC EXPVT EXPVC IDTS IDETS IDECS IDETSD IDECSD CVT/CVC : int Viscous damping coefficient CV for tension v > 0, force per unit velocity. EXPVT/EXPVC : int Exponent of velocity EXPV for tension v > 0 (or compression v < 0). IDTS : int Identification number of a TABLEDi entry for tension and compression if TYPE=TABLE. The TABLEDi entry defines the scale factor S, versus displacement u. IDETS/IDECS : int Identification number of a DEQATN entry for tension if TYPE=EQUAT. The DEQATN entry defines the scale factor S, versus displacement u, for tension u > 0 (or compression v < 0). IDETSD/IDECSD : int Identification number of a DEQATN entry for tension if TYPE=EQUAT. The DEQATN entry defines the defines the scale factor S, versus displacement u, for tension u > 0 (or compression v < 0). SPRING: Nonlinear elastic spring element in terms of a force versus displacement relationship TYPE IDT IDC IDTDU IDCDU DAMPER: Nonlinear viscous element in terms of a force versus velocity relationship. TYPE IDT IDC IDTDV IDCDV GENER: General nonlinear elastic spring and viscous damper element in terms of a force versus displacement and velocity relationship. For this element, the relationship can only be defined with TYPE=EQUAT (and it's implicit). IDT IDC IDTDU IDCDU IDTDV IDCDV TYPE : int the type of the result; {TABLE, EQUAT} IDT/IDC : int tension/compression table/equation IDTDU/IDCDU : int du/dt tension/compression table/eq IDTDV/IDCDV : int dv/dt tension/compression table/eq """ BushingProperty.__init__(self) if comment: self.comment = comment #: Property ID self.pid = pid self.k = k self.c = c self.m = m self.sa = sa self.se = se # SPRING parameters self.spring_type = None self.spring_idt = None self.spring_idc = None self.spring_idtdu = None self.spring_idcdu = None # DAMPER parameters self.damper_type = None self.damper_idt = None self.damper_idc = None self.damper_idtdv = None self.damper_idcdv = None # GENER parameters #self.gener_idt = None #self.gener_idc = None #self.gener_idtdu = None #self.gener_idcdu = None #self.gener_idtdv = None #self.gener_idcdv = None # SHOCK parameters self.shock_type = None self.shock_cvt = None self.shock_cvc = None self.shock_exp_vt = None self.shock_exp_vc = None self.shock_idts = None self.shock_idets = None self.shock_idecs = None self.shock_idetsd = None self.shock_idecsd = None if optional_vars: for key, values in optional_vars.items(): if key == 'SHOCKA': (shock_type, shock_cvt, shock_cvc, shock_exp_vt, shock_exp_vc, shock_idts, shock_idets, shock_idecs, shock_idetsd, shock_idecsd ) = values self.shock_type = shock_type self.shock_cvt = shock_cvt self.shock_cvc = shock_cvc self.shock_exp_vt = shock_exp_vt self.shock_exp_vc = shock_exp_vc self.shock_idts = shock_idts self.shock_idets = shock_idets self.shock_idecs = shock_idecs self.shock_idetsd = shock_idetsd self.shock_idecsd = shock_idecsd elif key == 'SPRING': (spring_type, spring_idt, spring_idc, spring_idtdu, spring_idcdu) = values self.spring_type = spring_type self.spring_idt = spring_idt self.spring_idtc = spring_idc self.spring_idc = spring_idc self.spring_idtdu = spring_idtdu self.spring_idcdu = spring_idcdu elif key == 'DAMPER': (damper_type, damper_idt, damper_idc, damper_idtdv, damper_idcdv) = values self.damper_type = damper_type self.damper_idt = damper_idt self.damper_idc = damper_idc self.damper_idtdv = damper_idtdv self.damper_idcdv = damper_idcdv elif key == 'GENER': ( gener_idt, gener_idc, gener_idtdu, gener_idcdu, gener_idtdv, gener_idcdv ) = values self.gener_idt = gener_idt self.gener_idc = gener_idc self.gener_idtdu = gener_idtdu self.gener_idcdu = gener_idcdu self.gener_idtdv = gener_idtdv self.gener_idcdv = gener_idcdv else: msg = ('PBUSH1D: pid=%s key=%r and must be ' '{SHOCKA, SPRING, DAPMER, GENER}' % self.pid) raise RuntimeError(msg) if optional_vars is None: self.vars = [] else: self.vars = list(optional_vars.keys()) self.vars.sort()
[docs] @classmethod def add_card(cls, card, comment=''): """ Adds a PBUSH1D card from ``BDF.add_card(...)`` Parameters ---------- card : BDFCard() a BDFCard object comment : str; default='' a comment for the card """ pid = integer(card, 1, 'pid') k = double_or_blank(card, 2, 'k', 0.0) c = double_or_blank(card, 3, 'c', 0.0) m = double_or_blank(card, 4, 'm', 0.0) sa = double_or_blank(card, 6, 'sa', 0.0) se = double_or_blank(card, 7, 'se', 0.0) nfields = card.nfields optional_vars = {} istart = 9 while istart < nfields: pname = string(card, istart, 'pname') if pname == 'SHOCKA': istart, out = cls._read_shock(card, istart) optional_vars['SHOCKA'] = out elif pname == 'SPRING': out = cls._read_spring(card, istart) optional_vars['SPRING'] = out elif pname == 'DAMPER': out = cls._read_damper(card, istart) optional_vars['DAMPER'] = out elif pname == 'GENER': out = cls._read_gener(card, istart) optional_vars['GENER'] = out else: break istart += 8 #self.pid = pid #self.k = k #self.c = c #self.m = m #self.sa = sa #self.se = se return PBUSH1D(pid, k=k, c=c, m=m, sa=sa, se=se, optional_vars=optional_vars, comment=comment)
#@classmethod #def add_op2_data(cls, data, comment=''): #pid = data[0] #b = data[1] #raise NotImplementedError('PBUSH1D data...') def _verify(self, xref): pid = self.Pid() assert isinstance(pid, int), 'pid=%r' % pid
[docs] @staticmethod def _read_shock(card, istart): """ F(u, v) = Cv * S(u) * sign(v) * |v|^ev """ shock_type = string_or_blank(card, istart + 1, 'shockType') shock_cvt = double(card, istart + 2, 'shockCVT') shock_cvc = double_or_blank(card, istart + 3, 'shockCVC') shock_exp_vt = double_or_blank(card, istart + 4, 'shockExpVT', 1.0) shock_exp_vc = double_or_blank(card, istart + 5, 'shockExpVC', shock_exp_vt) if shock_type == 'TABLE': shock_idts = None shock_idets = None shock_idecs = None shock_idetsd = None shock_idecsd = None # shock_idts = integer(card, istart + 6, 'shockIDTS') # shock_idets = blank(card, istart + 9, 'shockIDETS') # shock_idecs = blank(card, istart + 10, 'shockIDECS') # shock_idetsd = blank(card, istart + 11, 'shockIDETSD') # shock_idecsd = blank(card, istart + 12, 'shockIDECSD') elif shock_type == 'EQUAT': shock_idts = blank(card, istart + 6, 'shockIDTS') shock_idets = integer(card, istart + 9, 'shockIDETS') shock_idecs = integer_or_blank(card, istart + 10, 'shockIDECS', shock_idets) shock_idetsd = integer(card, istart + 11, 'shockIDETSD') shock_idecsd = integer_or_blank(card, istart + 11, 'shockIDECSD', shock_idetsd) #def DEquation(self): #if isinstance(self.dequation, int): #return self.dequation #return self.dequation.equation_id else: msg = 'Invalid shockType=%r on card\n%s' % (shock_type, card) raise RuntimeError(msg) out = ( shock_type, shock_cvt, shock_cvc, shock_exp_vt, shock_exp_vc, shock_idts, shock_idets, shock_idecs, shock_idetsd, shock_idecsd ) istart += 8 return istart, out
[docs] @staticmethod def _read_spring(card, istart): """ F(u) = Ft(u) """ spring_type = string_or_blank(card, istart + 1, 'springType') spring_idt = integer(card, istart + 2, 'springIDT') if spring_type == 'TABLE': spring_idc = blank(card, istart + 3, 'springIDC') spring_idtdu = blank(card, istart + 4, 'springIDTDU') spring_idcdu = blank(card, istart + 5, 'springIDCDU') elif spring_type == 'EQUAT': spring_idc = integer_or_blank(card, istart + 3, 'springIDC', spring_idt) spring_idtdu = integer(card, istart + 4, 'springIDTDU') spring_idcdu = integer_or_blank(card, istart + 5, 'springIDCDU', spring_idtdu) else: msg = 'Invalid springType=%r on card\n%s' % (spring_type, card) raise RuntimeError(msg) return spring_type, spring_idt, spring_idc, spring_idtdu, spring_idcdu
[docs] @staticmethod def _read_damper(card, istart): """ F(v) = Ft(u) """ damper_type = string_or_blank(card, istart + 1, 'damperType') damper_idt = integer(card, istart + 2, 'damperIDT') if damper_type == 'TABLE': damper_idc = blank(card, istart + 3, 'damperIDC') damper_idtdv = blank(card, istart + 4, 'damperIDTDV') damper_idcdv = blank(card, istart + 5, 'damperIDCDV') elif damper_type == 'EQUAT': damper_idc = integer_or_blank(card, istart + 3, 'damperIDC') damper_idtdv = integer(card, istart + 4, 'damperIDTDV') damper_idcdv = integer_or_blank(card, istart + 5, 'damperIDCDV', damper_idtdv) else: msg = 'Invalid damper_type=%r on card\n%s' % (damper_type, card) raise RuntimeError(msg) return damper_type, damper_idt, damper_idc, damper_idtdv, damper_idcdv
[docs] @staticmethod def _read_gener(card, istart): """ F(u, v) = Ft(u, v) """ gener_idt = integer(card, istart + 2, 'generIDT') gener_idc = integer_or_blank(card, istart + 3, 'generIDC', gener_idt) gener_idtdu = integer(card, istart + 4, 'generIDTDU') gener_idcdu = integer_or_blank(card, istart + 5, 'generIDCDU', gener_idtdu) gener_idtdv = integer(card, istart + 6, 'generIDTDV') gener_idcdv = integer_or_blank(card, istart + 7, 'generIDCDV', gener_idtdv) out = ( gener_idt, gener_idc, gener_idtdu, gener_idcdu, gener_idtdv, gener_idcdv ) return out
[docs] def _shock_fields(self): list_fields = ['SHOCKA', self.shock_type, self.shock_cvt, self.shock_cvc, self.shock_exp_vt, self.shock_exp_vc, self.shock_idts, None, None, self.shock_idets, self.shock_idecs, self.shock_idetsd, self.shock_idecsd] return list_fields
[docs] def _spring_fields(self): list_fields = ['SPRING', self.spring_type, self.spring_idt, self.spring_idc, self.spring_idtdu, self.spring_idcdu] return list_fields
[docs] def _damper_fields(self): list_fields = ['DAMPER', self.damper_type, self.damper_idt, self.damper_idc, self.damper_idtdv, self.damper_idcdv] return list_fields
[docs] def _gener_fields(self): list_fields = ['GENER', None, self.gener_idt, self.gener_idc, self.gener_idtdu, self.gener_idcdu, self.gener_idtdv, self.gener_idcdv] return list_fields
[docs] def raw_fields(self): list_fields = ['PBUSH1D', self.pid, self.k, self.c, self.m, None, self.sa, self.se, None] for var in self.vars: if var == 'SHOCKA': list_fields += self._shock_fields() elif var == 'SPRING': list_fields += self._spring_fields() elif var == 'DAMPER': list_fields += self._damper_fields() elif var == 'GENER': list_fields += self._gener_fields() else: msg = 'var=%s not supported PBUSH1D field...' % var raise RuntimeError(msg) nspaces = 8 - (len(list_fields) - 1) % 8 if nspaces < 8: list_fields += [None] * (nspaces) return list_fields
[docs] def repr_fields(self): return self.raw_fields()
[docs] def write_card(self, size=8, is_double=False): card = self.repr_fields() if size == 8: return self.comment + print_card_8(card) return self.comment + print_card_16(card)
[docs]class PBUSH2D(BushingProperty): type = 'PBUSH2D' def __init__(self, card=None, comment=''): BushingProperty.__init__(self, card) if comment: self.comment = comment raise NotImplementedError()
[docs] def write_card(self, size=8, is_double=False): """ Writes the card with the specified width and precision Parameters ---------- size : int (default=8) size of the field; {8, 16} is_double : bool (default=False) is this card double precision Returns ------- msg : str the string representation of the card """ card = self.repr_fields() if size == 8: return self.comment + print_card_8(card) return self.comment + print_card_16(card)
[docs]def _append_nones(list_obj, nrequired): """this function has side effects""" n_none = nrequired - len(list_obj) list_obj.extend([None] * n_none)
[docs]class PBUSHT(BushingProperty): type = 'PBUSHT'
[docs] @classmethod def _init_from_empty(cls): pid = 1 k_tables = [] b_tables = [] ge_tables = [] kn_tables = [] return PBUSHT(pid, k_tables, b_tables, ge_tables, kn_tables, comment='')
[docs] def update_by_pname_fid(self, name, value): if name == 'TGEID1': self.ge_tables[0] = value elif name == 'TGEID2': self.ge_tables[1] = value else: raise NotImplementedError('%r has not implemented update_by_pname_fid for %r' % (self.type, name))
def __init__(self, pid, k_tables, b_tables, ge_tables, kn_tables, comment=''): BushingProperty.__init__(self) if comment: self.comment = comment self.pid = pid _append_nones(k_tables, 6) _append_nones(b_tables, 6) _append_nones(ge_tables, 6) _append_nones(kn_tables, 6) self.k_tables = k_tables self.b_tables = b_tables self.ge_tables = ge_tables self.kn_tables = kn_tables
[docs] @classmethod def add_card(cls, card, comment=''): """ Adds a PBUSHT card from ``BDF.add_card(...)`` Parameters ---------- card : BDFCard() a BDFCard object comment : str; default='' a comment for the card """ k_tables = [] b_tables = [] ge_tables = [] kn_tables = [] pid = integer(card, 1, 'pid') nfields = len(card) - 1 nrows = nfields // 8 if nfields % 8 != 0: nrows += 1 for irow in range(nrows): ifield = 1 + irow * 8 param = string(card, ifield + 1, 'param_type') table = [] for j in range(6): table_value = integer_or_blank(card, ifield + j + 2, param + '%i' % (j+1)) table.append(table_value) if param == 'K': k_tables = table elif param == 'B': b_tables = table elif param == 'GE': ge_tables = table elif param == 'KN': kn_tables = table else: raise ValueError(param) return PBUSHT(pid, k_tables, b_tables, ge_tables, kn_tables, comment=comment)
[docs] def raw_fields(self): list_fields = ['PBUSHT', self.pid] if self.k_tables: list_fields += ['K'] + self.k_tables + [None] if self.b_tables: list_fields += ['B'] + self.b_tables + [None] if self.ge_tables: list_fields += ['GE'] + self.ge_tables + [None] if self.kn_tables: list_fields += ['KN'] + self.kn_tables return list_fields
[docs] def write_card(self, size=8, is_double=False): card = self.repr_fields() if size == 8: return self.comment + print_card_8(card) return self.comment + print_card_16(card)