Source code for pyNastran.bdf.cards.elements.rigid

# pylint: disable=C0103,R0902,R0904,R0914,C0111
"""
All rigid elements are defined in this file.  This includes:

 * RBAR
 * RBAR1
 * RBE1
 * RBE2
 * RBE3

All rigid elements are RigidElement and Element objects.
"""
from __future__ import (nested_scopes, generators, division, absolute_import,
                        print_function, unicode_literals)
from six import string_types
from six.moves import zip, range
import sys
from itertools import count

from pyNastran.bdf.field_writer_8 import set_blank_if_default, print_card_8
from pyNastran.bdf.cards.baseCard import Element
from pyNastran.bdf.bdfInterface.assign_type import (integer,
    integer_or_double, integer_double_or_blank, integer_or_blank,
    double_or_blank, integer_double_or_string, components, components_or_blank,
    blank, fields, string, interpret_value)
from pyNastran.bdf.field_writer_16 import print_card_16
from pyNastran.bdf.cards.utils import build_table_lines


[docs]class RigidElement(Element):
[docs] def cross_reference(self, model): pass
[docs]class RBAR(RigidElement): type = 'RBAR' def __init__(self, card=None, data=None, comment=''): """ +------+-----+----+----+--------+-----+-----+-----+-------+ | RBAR | EID | GA | GB | CNA | CNB | CMA | CMB | ALPHA | +------+-----+----+----+--------+-----+-----+-----+-------+ | RBAR | 5 | 1 | 2 | 123456 | | | | 6.5-6 | +------+-----+----+----+--------+-----+-----+-----+-------+ """ RigidElement.__init__(self, card, data) if comment: self._comment = comment if card: self.eid = integer(card, 1, 'eid') self.ga = integer(card, 2, 'ga') self.gb = integer(card, 3, 'gb') self.cna = components_or_blank(card, 4, 'cna') self.cnb = components_or_blank(card, 5, 'cnb') self.cma = components_or_blank(card, 6, 'cma') self.cmb = components_or_blank(card, 7, 'cmb') self.alpha = double_or_blank(card, 8, 'alpha', 0.0) assert len(card) <= 9, 'len(RBAR card) = %i' % len(card) else: self.eid = data[0] self.ga = data[1] self.gb = data[2] self.cna = data[3] self.cnb = data[4] self.cma = data[5] self.cmb = data[6] self.alpha = data[7] # def convert_to_MPC(self, mpcID): # """ # -Ai*ui + Aj*uj = 0 # where ui are the base DOFs (max=6) # mpc sid g1 c1 a1 g2 c2 a2 # rbe2 eid gn cm g1 g2 g3 g4 # """ # raise NotImplementedError() # #i = 0 # nCM = len(self.cm) # Ai = nCM * len(self.Gmi) / len(self.gn) # where nGN=1 # # card = ['MPC', mpcID] # for cm in self.cm: # the minus sign is applied to the base node # card += [self.gn, cm, -Ai] # # for gm in self.Gmi: # for cm in self.cm: # card += [gm, cm, Ai] # return card #def write_code_aster(self): #msg = '' #msg += "BLOCAGE=AFFE_CHAR_MECA( # RBAR\n" #msg += " MODELE=MODELE,\n" # rigid element #msg += " \n" #return msg
[docs] def raw_fields(self): list_fields = ['RBAR', self.eid, self.ga, self.gb, self.cna, self.cnb, self.cma, self.cmb, self.alpha] return list_fields
[docs] def repr_fields(self): alpha = set_blank_if_default(self.alpha, 0.0) list_fields = ['RBAR', self.eid, self.ga, self.gb, self.cna, self.cnb, self.cma, self.cmb, alpha] 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)
[docs]class RBAR1(RigidElement): type = 'RBAR1' def __init__(self, card=None, data=None, comment=''): """ +-------+-----+----+----+-----+-------+ | RBAR1 | EID | GA | GB | CB | ALPHA | +-------+-----+----+----+-----+-------+ | RBAR1 | 5 | 1 | 2 | 123 | 6.5-6 | +-------+-----+----+----+-----+-------+ """ RigidElement.__init__(self, card, data) if comment: self._comment = comment if card: self.eid = integer(card, 1, 'eid') self.ga = integer(card, 2, 'ga') self.gb = integer(card, 3, 'gb') self.cb = components_or_blank(card, 4, 'cb') self.alpha = double_or_blank(card, 5, 'alpha', 0.0) assert len(card) <= 6, 'len(RBAR1 card) = %i' % len(card) else: self.eid = data[0] self.ga = data[1] self.gb = data[2] self.cb = data[3] self.alpha = data[4]
[docs] def raw_fields(self): list_fields = ['RBAR1', self.eid, self.ga, self.gb, self.cb, self.alpha] return list_fields
[docs] def repr_fields(self): alpha = set_blank_if_default(self.alpha, 0.0) list_fields = ['RBAR1', self.eid, self.ga, self.gb, self.cb, alpha] 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)
[docs]class RBE1(RigidElement): # maybe not done, needs testing type = 'RBE1' def __init__(self, card=None, data=None, comment=''): RigidElement.__init__(self, card, data) if comment: self._comment = comment self.eid = integer(card, 1, 'eid') self.Gni = [] self.Cni = [] #fields = [interpret_value(field) for field in card[2:] ] iUm = card.index('UM') if iUm > 0: assert string(card, iUm, 'UM') == 'UM' #assert isinstance(card[-1], str), 'card[-1]=%r type=%s' %(card[-1], type(card[-1])) alpha_last = integer_double_or_string(card, -1, 'alpha_last') if isinstance(alpha_last, float): self.alpha = alpha_last card.pop() # remove the last field so len(card) will not include alpha else: self.alpha = 0. # loop till UM, no field9,field10 #print("iUm = %s" % iUm) n = 1 i = 0 offset = 2 while offset + i < iUm - 1: #print('field(%s) = %s' % (offset + i, card.field(offset + i))) gni = integer_or_blank(card, offset + i, 'gn%i' % n) cni = components_or_blank(card, offset + i + 1, 'cn%i' % n) if gni: #print("gni=%s cni=%s" % (gni ,cni)) self.Gni.append(gni) self.Cni.append(cni) n += 1 else: assert cni is None i += 2 #print('Gni =', self.Gni) #print('Cni =', self.Cni) self.Gmi = [] self.Cmi = [] # loop till alpha, no field9,field10 n = 1 offset = iUm + 1 i = 0 while offset + i < len(card): # dont grab alpha gmi = integer_or_blank(card, offset + i, 'gm%i' % n) cmi = components_or_blank(card, offset + i + 1, 'cm%i' % n) if gmi: #print("gmi=%s cmi=%s" % (gmi ,cmi)) self.Gmi.append(gmi) self.Cmi.append(cmi) n += 1 else: assert cmi is None i += 2 #print('Gmi =', self.Gmi) #print('Cmi =', self.Cmi) #print(self) #sys.exit()
[docs] def raw_fields(self): list_fields = [self.type, self.eid] for (i, gn, cn) in zip(count(), self.Gni, self.Cni): #print('i=%r gn=%r cn=%r' % (i, gn, cn)) list_fields += [gn, cn] if i > 0 and i % 3 == 0: #print('adding blank') list_fields += [None] nSpaces = 8 - (len(list_fields) - 1) % 8 # puts UM/ALPHA onto next line if nSpaces < 8: list_fields += [None] * nSpaces # overly complicated loop to print the UM section list_fields += ['UM'] j = 1 for (i, gm, cm) in zip(count(), self.Gmi, self.Cmi): #print "j=%s gmi=%s cmi=%s" %(j,gm,cm) list_fields += [gm, cm] if i > 0 and j % 3 == 0: list_fields += [None, None] #print "---" j -= 3 j += 1 if self.alpha > 0.: # handles default alpha value nSpaces = 8 - (len(list_fields) - 1) % 8 # puts ALPHA onto next line if nSpaces == 1: list_fields += [None, None] list_fields += [self.alpha] 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 RBE2(RigidElement): type = 'RBE2' _field_map = {1: 'eid', 2:'gn', 3:'cm'}
[docs] def _update_field_helper(self, n, value): """ Updates complicated parameters on the GRID card :param self: the GRID object pointer :param n: the field number to update :type n: int :param value: the value for the appropriate field :type field: varies """ if n > 3 and n <= 3 + len(self.Gmi): self.Gmi[n-4] = value elif n == 4 + len(self.Gmi): self.alpha = value else: raise KeyError('Field %r is an invalid %s entry.' % (n, self.type)) return value
def __init__(self, card=None, data=None, comment=''): """ +-------+-----+-----+-----+------+-------+-----+-----+-----+ | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | +-------+-----+-----+-----+------+-------+-----+-----+-----+ | RBE2 | EID | GN | CM | GM1 | GM2 | GM3 | GM4 | GM5 | +-------+-----+-----+-----+------+-------+-----+-----+-----+ | | GM6 | GM7 | GM8 | etc. | ALPHA | | | | +-------+-----+-----+-----+------+-------+-----+-----+-----+ """ RigidElement.__init__(self, card, data) if comment: self._comment = comment if card: #: Element identification number self.eid = integer(card, 1, 'eid') #: Identification number of grid point to which all six independent #: degrees-of-freedom for the element are assigned. (Integer > 0) self.gn = integer(card, 2, 'gn') #: Component numbers of the dependent degrees-of-freedom in the #: global coordinate system at grid points GMi. (Integers 1 through #: 6 with no embedded blanks.) self.cm = components_or_blank(card, 3, 'cm') alpha = integer_or_double(card, len(card) - 1, 'alpha') if isinstance(alpha, float): #: Grid point identification numbers at which dependent #: degrees-of-freedom are assigned. (Integer > 0) self.alpha = alpha # the last field is not part of Gmi n = 1 else: # the last field is part of Gmi n = 0 self.alpha = 0.0 j = 4 self.Gmi = [] for i in range(len(card)-4-n): gmi = integer(card, j + i, 'Gm%i' % (i + 1)) #print('gm%i = %s' % (i + 1, gmi)) self.Gmi.append(gmi) else: self.eid = data[0] self.gn = data[1] self.cm = data[2] self.Gmi = data[3] self.alpha = data[4] print("eid=%s gn=%s cm=%s Gmi=%s alpha=%s" % (self.eid, self.gn, self.cm, self.Gmi, self.alpha)) #raise NotImplementedError('RBE2 data...') assert self.gn is not None, 'gn=%s' % self.gn assert self.cm is not None, 'cm=%s' % self.cm self.gn = str(self.gn) self.cm = str(self.cm)
[docs] def convert_to_MPC(self, mpc_id): """ .. math:: -A_i u_i + A_j u_j = 0 where :math:`u_i` are the base DOFs (max=6) +------+------+----+----+-----+----+----+----+ | MPC | sid | g1 | c1 | a1 | g2 | c2 | a2 | +------+------+----+----+-----+----+----+----+ | RBE2 | eid | gn | cm | g1 | g2 | g3 | g4 | +------+------+----+----+-----+----+----+----+ """ nCM = len(self.cm) Ai = nCM * len(self.Gmi) / len(self.gn) # where nGN=1 card = ['MPC', mpc_id] for cm in self.cm: # the minus sign is applied to the base node card += [self.gn, cm, -Ai] for gm in self.Gmi: for cm in self.cm: card += [gm, cm, Ai] return card
[docs] def convert_to_RBE3(self): raise NotImplementedError() eid = self.eid ref_node = self.gn dof = self.cm wf = 1.0 sDof = 123 # this is probably wrong... boundary_nodes = self.Gmi # this is to get the farthest nodes for the UM card boundary_nodes.sort() rbe3_nodes = boundary_nodes rbe3 = ['RBE3', eid, ref_node, dof, wf, sDof] + rbe3_nodes return rbe3
[docs] def write_code_aster(self): """ Converts to a LIAISON SOLIDE for dofs 123456. For other dof combinations, general MPC equations are written """ msg = '' msg += "BLOCAGE=AFFE_CHAR_MECA( # RBE2 ID=%s\n" % (self.eid) msg += " MODELE=MODELE,\n" # rigid element if self.cm == 123456: msg += " LIASON_SOLIDE=(\n" msg += " _F(NOEUD=\n" msg += " " for nid in self.Gmi: msg += "'N%i'," % (nid) msg = msg[:-1] msg += '\n' else: msg += " _F(NOEUD= # doesnt handle coordinate systems\n" msg += " " for nid in self.Gmi: msg += "'N%i'," % (nid) msg = msg[:-1] msg += '\n' #msg += " \n" #msg += " \n" #msg += " \n" #msg += " \n" #msg += " \n" return msg
[docs] def raw_fields(self): list_fields = ['RBE2', self.eid, self.gn, self.cm] + self.Gmi + [self.alpha] return list_fields
[docs] def repr_fields(self): alpha = set_blank_if_default(self.alpha, 0.) list_fields = ['RBE2', self.eid, self.gn, self.cm] + self.Gmi + [alpha] return list_fields
[docs] def write_card(self, size=8, is_double=False): card = self.repr_fields() return self.comment() + print_card_8(card)
[docs]class RBE3(RigidElement): """ .. todo:: not done, needs testing badly """ type = 'RBE3' def __init__(self, card=None, data=None, comment=''): """ eid refgrid refc WtCG_groups = [wt,ci,Gij] Gmi Cmi alpha """ RigidElement.__init__(self, card, data) if comment: self._comment = comment self.eid = integer(card, 1, 'eid') blank(card, 2, 'blank') self.refgrid = integer(card, 3, 'refgrid') self.refc = components_or_blank(card, 4, 'refc') #iUM = fields.index('UM') fields = [field.upper() if isinstance(field, string_types) else field for field in card[5:]] iOffset = 5 iWtMax = len(fields) + iOffset try: iAlpha = fields.index('ALPHA') + iOffset iWtMax = iAlpha # the index to start parsing UM iUmStop = iAlpha # the index to stop parsing UM except ValueError: iAlpha = None iUmStop = iWtMax #print("iAlpha = %s" % iAlpha) try: iUm = fields.index('UM') + iOffset iWtMax = iUm except ValueError: iUm = None #print("iAlpha=%s iUm=%s" % (iAlpha, iUm)) #print("iAlpha=%s iWtMax=%s" % (iAlpha, iWtMax)) #print("iUM = ", iUM) self.WtCG_groups = [] i = iOffset n = 1 while i < iWtMax: Gij = [] wtname = 'wt' + str(n) wt = double_or_blank(card, i, wtname) if wt is not None: cname = 'c'+str(n) ci = components_or_blank(card, i + 1, cname) #print("%s=%s %s=%s" % (wtname, wt, cname, ci)) i += 2 gij = 0 j = 0 while isinstance(gij, int) and i < iWtMax: j += 1 gij_name = 'g%s,%s' % (n, j) gij = integer_double_or_blank(card, i, gij_name) if isinstance(gij, float): break #print("%s = %s" % (gij_name, gij)) if gij is not None: Gij.append(gij) i += 1 wtCG_group = [wt, ci, Gij] self.WtCG_groups.append(wtCG_group) #print('----finished a group=%r----' % wtCG_group) else: i += 1 self.Gmi = [] self.Cmi = [] #print("") if iUm: #print('UM = %s' % card.field(iUm)) # UM i = iUm + 1 n = 1 #print("i=%s iUmStop=%s" % (i, iUmStop)) for j in range(i, iUmStop, 2): gm_name = 'gm' + str(n) cm_name = 'cm' + str(n) gmi = integer_or_blank(card, j, gm_name) if gmi is not None: cmi = components(card, j + 1, cm_name) #print "gmi=%s cmi=%s" % (gmi, cmi) self.Gmi.append(gmi) self.Cmi.append(cmi) if iAlpha: self.alpha = double_or_blank(card, iAlpha + 1, 'alpha') else: #: thermal expansion coefficient self.alpha = 0.0 #print(self) # def convertToMPC(self, mpcID): # """ # -Ai*ui + Aj*uj = 0 # where ui are the base DOFs (max=6) # mpc sid g1 c1 a1 g2 c2 a2 # rbe2 eid gn cm g1 g2 g3 g4 # """ # raise NotImplementedError('this is the code for an RBE2...not RBE3') # #i = 0 # nCM = len(self.cm) # Ai = nCM * len(self.Gmi) / len(self.gn) # where nGN=1 # # card = ['MPC', mpcID] # for cm in self.cm: # the minus sign is applied to the base node # card += [self.gn, cm, -Ai] # # for gm in self.Gmi: # for cm in self.cm: # card += [gm, cm, Ai] # return card
[docs] def raw_fields(self): list_fields = ['RBE3', self.eid, None, self.refgrid, self.refc] for (wt, ci, Gij) in self.WtCG_groups: #print('wt=%s ci=%s Gij=%s' % (wt, ci, Gij)) list_fields += [wt, ci] + Gij nSpaces = 8 - (len(list_fields) - 1) % 8 # puts UM onto next line if nSpaces < 8: list_fields += [None] * nSpaces if self.Gmi and 0: fields2 = ['UM'] for (gmi, cmi) in zip(self.Gmi, self.Cmi): fields2 += [gmi, cmi] ## .. todo:: what's going on here with the arguments??? list_fields += build_table_lines(fields2, i=1, j=1) if self.Gmi: list_fields += ['UM'] if self.Gmi: #print("Gmi = %s" % self.Gmi) #print("Cmi = %s" % self.Cmi) for (gmi, cmi) in zip(self.Gmi, self.Cmi): list_fields += [gmi, cmi] nSpaces = 8 - (len(list_fields) - 1) % 8 # puts ALPHA onto next line if nSpaces < 8: list_fields += [None] * nSpaces if self.alpha > 0.: # handles the default value list_fields += ['ALPHA', self.alpha] 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() return self.comment() + print_card_8(card)