Source code for pyNastran.bdf.cards.bdf_sets

# pylint: disable=C0103,R0902,R0904,R0914,C0111
from __future__ import (nested_scopes, generators, division, absolute_import,
                        print_function, unicode_literals)
from six.moves import zip, range

from pyNastran.bdf.cards.baseCard import BaseCard, expand_thru, collapse_thru, collapse_thru_packs
from pyNastran.bdf.field_writer_8 import print_card_8, print_int_card_blocks
from pyNastran.bdf.bdfInterface.assign_type import (integer, integer_or_blank,
    components, components_or_blank, fields, integer_or_string, string,
    string_or_blank, integer_string_or_blank)

[docs]class Set(BaseCard): """Generic Class all SETx cards inherit from""" def __init__(self, card, data): #: Unique identification number. (Integer > 0) self.sid = None #: list of IDs in the SETx self.IDs = None
[docs] def cleanIDs(self): """eliminates duplicate IDs from self.IDs and sorts self.IDs""" self.IDs = list(set(self.IDs)) self.IDs.sort()
[docs] def SetIDs(self): """gets the IDs of the SETx""" return collapse_thru(self.IDs)
[docs] def repr_fields(self): list_fields = self.raw_fields() return list_fields
def __repr__(self): return self.comment() + print_card_8(self.repr_fields())
[docs] def write_card(self, size=8, is_double=False): card = self.repr_fields() return self.comment() + print_card_8(card)
[docs]class SetSuper(Set): """Generic Class all Superelement SETx cards inherit from.""" def __init__(self, card, data): #: Superelement identification number. Must be a primary superelement. #: (Integer >= 0) self.seid = None #: list of IDs in the SESETx self.IDs = None
[docs]class ABCQSet(Set): """ Generic Class ASET, BSET, CSET, QSET cards inherit from. Defines degrees-of-freedom in the analysis set (A-set) +------+-----+----+-----+------+-----+----+-----+----+ | ASET | ID1 | C1 | ID2 | C2 | ID3 | C3 | ID4 | C4 | +------+-----+----+-----+------+-----+----+-----+----+ | ASET | 16 | 2 | 23 | 3516 | 1 | 4 | | | +------+-----+----+-----+------+-----+----+-----+----+ """ def __init__(self, card=None, data=None, comment=''): Set.__init__(self, card, data) if comment: self._comment = comment #: Identifiers of grids points. (Integer > 0) self.IDs = [] self.components = [] nterms = len(card) // 2 for n in range(nterms): i = n * 2 + 1 ID = integer(card, i, 'ID' + str(n)) component = components(card, i + 1, 'component' + str(n)) self.IDs.append(ID) self.components.append(component)
[docs] def raw_fields(self): """gets the "raw" card without any processing as a list for printing""" list_fields = [self.type] # ASET, BSET for (ID, comp) in zip(self.IDs, self.components): list_fields += [ID, comp] return list_fields
def __repr__(self): list_fields = self.raw_fields() return self.comment() + print_card_8(list_fields)
[docs]class ASET(ABCQSet): """ Defines degrees-of-freedom in the analysis set (A-set). +------+-----+----+-----+------+-----+----+-----+----+ | ASET | ID1 | C1 | ID2 | C2 | ID3 | C3 | ID4 | C4 | +------+-----+----+-----+------+-----+----+-----+----+ | ASET | 16 | 2 | 23 | 3516 | 1 | 4 | | | +------+-----+----+-----+------+-----+----+-----+----+ """ type = 'ASET' def __init__(self, card=None, data=None, comment=''): ABCQSet.__init__(self, card, data, comment)
[docs]class BSET(ABCQSet): """ Defines analysis set (a-set) degrees-of-freedom to be fixed (b-set) during generalized dynamic reduction or component mode synthesis calculations. +------+-----+----+-----+------+-----+----+-----+----+ | BSET | ID1 | C1 | ID2 | C2 | ID3 | C3 | ID4 | C4 | +------+-----+----+-----+------+-----+----+-----+----+ | BSET | 16 | 2 | 23 | 3516 | 1 | 4 | | | +------+-----+----+-----+------+-----+----+-----+----+ """ type = 'BSET' def __init__(self, card=None, data=None, comment=''): ABCQSet.__init__(self, card, data, comment)
[docs]class CSET(ABCQSet): """ Defines analysis set (a-set) degrees-of-freedom to be fixed (b-set) during generalized dynamic reduction or component mode synthesis calculations. +------+-----+----+-----+------+-----+----+-----+----+ | CSET | ID1 | C1 | ID2 | C2 | ID3 | C3 | ID4 | C4 | +------+-----+----+-----+------+-----+----+-----+----+ | CSET | 16 | 2 | 23 | 3516 | 1 | 4 | | | +------+-----+----+-----+------+-----+----+-----+----+ """ type = 'CSET' def __init__(self, card=None, data=None, comment=''): ABCQSet.__init__(self, card, data, comment)
[docs]class QSET(ABCQSet): """ Defines generalized degrees-of-freedom (q-set) to be used for dynamic reduction or component mode synthesis. +------+-----+----+-----+------+-----+----+-----+----+ | QSET | ID1 | C1 | ID2 | C2 | ID3 | C3 | ID4 | C4 | +------+-----+----+-----+------+-----+----+-----+----+ | QSET | 16 | 2 | 23 | 3516 | 1 | 4 | | | +------+-----+----+-----+------+-----+----+-----+----+ """ type = 'QSET' def __init__(self, card=None, data=None, comment=''): ABCQSet.__init__(self, card, data, comment)
[docs]class ABQSet1(Set): """ Generic Class ASET1, BSET1, QSET1 cards inherit from. Defines degrees-of-freedom in the analysis set (a-set). +--=----+-----+-----+------+------+-----+-----+-----+-----+ | ASET1 | C | ID1 | ID2 | ID3 | ID4 | ID5 | ID6 | ID7 | +-------+-----+-----+------+------+-----+-----+-----+-----+ | | ID8 | ID9 | | | | | | | +-------+-----+-----+------+------+-----+-----+-----+-----+ | ASET1 | C | ID1 | THRU | ID2 | | | | | +-------+-----+-----+------+------+-----+-----+-----+-----+ """ def __init__(self, card=None, data=None, comment=''): Set.__init__(self, card, data) if comment: self._comment = comment #: Component number. (Integer zero or blank for scalar points or any #: unique combination of the Integers 1 through 6 for grid points with #: no embedded blanks.) self.components = components_or_blank(card, 1, 'components', 0) nfields = len(card) IDs = [] i = 1 for ifield in range(2, nfields): ID = integer_string_or_blank(card, ifield, 'ID%i' % i) if ID: i += 1 IDs.append(ID) #IDs = fields(integer_or_string, card, 'ID', i=2, j=nfields) #: Identifiers of grids points. (Integer > 0) self.IDs = expand_thru(IDs)
[docs] def raw_fields(self): """gets the "raw" card without any processing as a list for printing""" list_fields = [self.type, self.components] + collapse_thru(self.IDs) return list_fields
def __repr__(self): list_fields = self.raw_fields() return self.comment() + print_card_8(list_fields)
[docs]class ASET1(ABQSet1): """ Defines degrees-of-freedom in the analysis set (a-set) +-------+-----+-----+------+-----+-----+-----+-----+-----+ | ASET1 | C | ID1 | ID2 | ID3 | ID4 | ID5 | ID6 | ID7 | +-------+-----+-----+------+-----+-----+-----+-----+-----+ | | ID8 | ID9 | | | | | | | +-------+-----+-----+------+-----+-----+-----+-----+-----+ | ASET1 | C | ID1 | THRU | ID2 | | | | | +-------+-----+-----+------+-----+-----+-----+-----+-----+ """ type = 'ASET1' def __init__(self, card=None, data=None, comment=''): ABQSet1.__init__(self, card, data, comment)
[docs]class BSET1(ABQSet1): type = 'BSET1' def __init__(self, card=None, data=None, comment=''): ABQSet1.__init__(self, card, data, comment)
[docs]class CSET1(Set): """ Defines analysis set (a-set) degrees-of-freedom to be fixed (b-set) during generalized dynamic reduction or component mode synthesis calculations. +-------+-----+-----+------+-----+-----+-----+-----+-----+ | CSET1 | C | ID1 | ID2 | ID3 | ID4 | ID5 | ID6 | ID7 | +-------+-----+-----+------+-----+-----+-----+-----+-----+ | | ID8 | ID9 | | | | | | | +-------+-----+-----+------+-----+-----+-----+-----+-----+ | CSET1 | C | ID1 | THRU | ID2 | | | | | +-------+-----+-----+------+-----+-----+-----+-----+-----+ | CSET1 | ,, | ALL | | | | | | | +-------+-----+-----+------+-----+-----+-----+-----+-----+ """ type = 'CSET1' def __init__(self, card=None, data=None, comment=''): Set.__init__(self, card, data) if comment: self._comment = comment #: Identifiers of grids points. (Integer > 0) self.IDs = [] if string_or_blank(card, 2, 'C') == 'ALL': self.components = '123456' else: self.components = components(card, 1, 'components') IDs = fields(integer_or_string, 'ID', i=2, j=len(card)) self.IDs = expand_thru(IDs)
[docs] def raw_fields(self): """gets the "raw" card without any processing as a list for printing""" list_fields = ['CSET1', self.components] + collapse_thru(self.IDs) return list_fields
def __repr__(self): list_fields = self.raw_fields() return self.comment() + print_card_8(list_fields)
[docs]class QSET1(ABQSet1): """ Defines generalized degrees-of-freedom (q-set) to be used for dynamic reduction or component mode synthesis. """ type = 'QSET1' def __init__(self, card=None, data=None, comment=''): ABQSet1.__init__(self, card, data, comment)
[docs]class SET1(Set): """ Defines a list of structural grid points or element identification numbers. +------+--------+--------+-----+------+-----+-----+------+-----+ | SET1 | SID | ID1 | ID2 | ID3 | ID4 | ID5 | ID6 | ID7 | +------+--------+--------+-----+------+-----+-----+------+-----+ | | ID8 | -etc.- | | | | | | | +------+--------+--------+-----+------+-----+-----+------+-----+ | SET1 | 3 | 31 | 62 | 93 | 124 | 16 | 17 | 18 | +------+--------+--------+-----+------+-----+-----+------+-----+ | | 19 | | | | | | | | +------+--------+--------+-----+------+-----+-----+------+-----+ | SET1 | 6 | 29 | 32 | THRU | 50 | 61 | THRU | 70 | +------+--------+--------+-----+------+-----+-----+------+-----+ | | 17 | 57 | | | | | | | +------+--------+--------+-----+------+-----+-----+------+-----+ """ type = 'SET1' def __init__(self, card=None, data=None, comment=''): Set.__init__(self, card, data) if comment: self._comment = comment #: Unique identification number. (Integer > 0) self.sid = integer(card, 1, 'sid') self.IDs = [] IDs = [] i = 1 for ifield in range(2, len(card)): ID = integer_string_or_blank(card, ifield, 'ID%i' % i) if ID: i += 1 IDs.append(ID) #IDs = fields(integer_or_string, card, 'ID', i=2, j=len(card)) self.isSkin = False i = 0 if isinstance(IDs[0], str) and IDs[0] == 'SKIN': self.isSkin = True i += 1 #: List of structural grid point or element identification numbers. #: (Integer > 0 or 'THRU'; for the 'THRU' option, ID1 < ID2 or 'SKIN'; #: in field 3) self.IDs = expand_thru(IDs[i:]) self.cleanIDs() def __eq__(self, set1): self.cleanIDs() set1.cleanIDs() if self.IDs == set1.IDs: return True return False
[docs] def symmetric_difference(self, set1): s1 = set(self.IDs) s2 = set(set1.IDs) return s1.symmetric_difference(s2)
[docs] def add_set(self, set1): self.IDs += set1.IDs self.cleanIDs()
[docs] def IsSkin(self): return self.isSkin
[docs] def raw_fields(self): skin = [] if self.isSkin: skin = ['SKIN'] return ['SET1', self.sid] + skin + self.IDs
[docs] def write_card(self, size=8, is_double=False): skin = [] if self.isSkin: skin = ['SKIN'] #return self.comment() + print_card_8(['SET1', self.sid] + skin + self.IDs) field_packs = [] singles, doubles = collapse_thru_packs(self.IDs) if singles: field_packs.append(['SET1', self.sid] + skin + singles) if doubles: for pack in doubles: field_packs.append(['SET1', self.sid] + skin + pack) msg = [] for field_pack in field_packs: msg.append(print_card_8(field_pack)) return ''.join(msg)
[docs]class SET3(Set): """ Defines a list of grids, elements or points. +------+-----+-------+-----+-----+-----+-----+-----+-----+ | SET3 | SID | DES | ID1 | ID2 | ID3 | ID4 | ID5 | ID6 | +------+-----+-------+-----+-----+-----+-----+-----+-----+ | | ID7 | ID8 | etc | | | | | | +------+-----+-------+-----+-----+-----+-----+-----+-----+ Example +------+-----+-------+-----+----+ | SET3 | 1 | POINT | 11 | 12 | +------+-----+-------+-----+----+ """ type = 'SET3' def __init__(self, card=None, data=None, comment=''): Set.__init__(self, card, data) if comment: self._comment = comment #: Unique identification number. (Integer > 0) self.sid = integer(card, 1, 'sid') #: Set description (Character). Valid options are 'GRID', 'ELEM', #: 'POINT' and 'PROP'. self.desc = string(card, 2, 'desc') assert self.desc in ['GRID', 'POINT', 'ELEM', 'PROP'], 'desc = %r' % self.desc #: Identifiers of grids points, elements, points or properties. #: (Integer > 0) self.IDs = [] IDs = fields(integer_or_string, card, 'ID', i=3, j=len(card)) self.IDs = expand_thru(IDs) self.cleanIDs()
[docs] def symmetric_difference(self, set1): s1 = set(self.IDs) s2 = set(set1.IDs) return s1.symmetric_difference(s2)
[docs] def IsGrid(self): if self.desc == 'GRID': return True return False
[docs] def IsPoint(self): if self.desc == 'POINT': return True return False
[docs] def IsProperty(self): if self.desc == 'PROP': return True return False
[docs] def IsElement(self): if self.desc == 'ELEM': return True return False
[docs] def raw_fields(self): """Gets the "raw" card without any processing as a list for printing""" list_fields = ['SET3', self.sid, self.desc] + self.SetIDs() return list_fields
def __repr__(self): fields_blocks = [ 'SET3', [[self.sid, self.desc], False], # these are not all integers [self.SetIDs(), True], # these are all integers ] return self.comment() + print_int_card_blocks(fields_blocks)
[docs]class SESET(SetSuper): """ Defines interior grid points for a superelement. """ type = 'SESET' def __init__(self, card=None, data=None, comment=''): SetSuper.__init__(self, card, data) if comment: self._comment = comment self.seid = integer_or_blank(card, 1, 'seid', 0) #: Grid or scalar point identification number. #: (0 < Integer < 1000000; G1 < G2) self.IDs = [] IDs = fields(integer_or_string, card, 'ID', i=2, j=len(card)) self.IDs = expand_thru(IDs) self.cleanIDs()
[docs] def add_SESET_Object(self, seset): self.IDs += seset.IDs self.cleanIDs()
[docs] def raw_fields(self): return ['SESET', self.seid] + collapse_thru(self.IDs)
def __repr__(self): thruFields = collapse_thru(self.IDs) #list_fields = ['SESET', self.seid] cards = [] while 'THRU' in thruFields: iThru = thruFields.index('THRU') card = print_card_8(['SESET', self.seid] + thruFields[iThru - 1:iThru + 2]) cards.append(card) thruFields = thruFields[0:iThru - 1]+thruFields[iThru + 2:] if thruFields: card = print_card_8(['SESET', self.seid] + thruFields) cards.append(card) return ''.join(cards)
[docs]class SEBSET(Set): """ Defines boundary degrees-of-freedom to be fixed (b-set) during generalized dynamic reduction or component mode calculations. +--------+------+-----+------+-----+----+-----+----+ | SEBSET | SEID | ID1 | C1 | ID2 | C2 | ID3 | C3 | +--------+------+-----+------+-----+----+-----+----+ | SEBSET | C | ID1 | THRU | ID2 | | | | +--------+------+-----+------+-----+----+-----+----+ """ def __init__(self, card=None, data=None, comment=''): Set.__init__(self, card, data) if comment: self._comment = comment #: Identifiers of grids points. (Integer > 0) self.components = [] self.IDs = [] #fields = str(card.fields(1)) nsets = (len(card) - 1) // 2 for n in range(nsets): i = n * 2 + 1 component = components(card, i, 'component' + str(n)) ID = components(card, i + 1, 'ID' + str(n)) self.components.append(component) self.IDs.append(ID)
[docs] def raw_fields(self): """ gets the "raw" card without any processing as a list for printing """ list_fields = ['SEBSET'] for (component, ID) in zip(self.components, self.IDs): list_fields += [component, ID] return list_fields
[docs]class SEBSET1(Set): """ Defines boundary degrees-of-freedom to be fixed (b-set) during generalized dynamic reduction or component mode calculations. +---------+-----+-----+--------+-----+-----+-----+-----+-----+ | SEBSET1 | C | ID1 | ID2 | ID3 | ID4 | ID5 | ID6 | ID7 | +---------+-----+-----+--------+-----+-----+-----+-----+-----+ | | ID8 | ID9 | | | | | | | +---------+-----+-----+--------+-----+-----+-----+-----+-----+ | SEBSET1 | C | ID1 | 'THRU' | ID2 | | | | | +---------+-----+-----+--------+-----+-----+-----+-----+-----+ """ def __init__(self, card=None, data=None, comment=''): Set.__init__(self, card, data) if comment: self._comment = comment #: Identifiers of grids points. (Integer > 0) self.IDs = [] self.components = components(card, 1, 'components') IDs = fields(integer_or_string, card, 2, 'ID') self.IDs = expand_thru(IDs)
[docs] def raw_fields(self): """gets the "raw" card without any processing as a list for printing""" list_fields = ['SEBSET1', self.components] + collapse_thru(self.IDs) return list_fields
def __repr__(self): list_fields = self.raw_fields() return self.comment() + print_card_8(list_fields)
[docs]class SEQSET1(Set): """ Defines the generalized degrees-of-freedom of the superelement to be used in generalized dynamic reduction or component mode synthesis. +--------+-----+-----+--------+-----+-----+-----+-----+-----+ |SEQSET1 | C | ID1 | ID2 | ID3 | ID4 | ID5 | ID6 | ID7 | +--------+-----+-----+--------+-----+-----+-----+-----+-----+ | | ID8 | ID9 | | | | | | | +--------+-----+-----+--------+-----+-----+-----+-----+-----+ |SEQSET1 | C | ID1 | 'THRU' | ID2 | | | | | +--------+-----+-----+--------+-----+-----+-----+-----+-----+ """ def __init__(self, card=None, data=None, comment=''): Set.__init__(self, card, data) if comment: self._comment = comment #: Identifiers of grids points. (Integer > 0) self.IDs = [] self.components = components(card, 1, 'components') IDs = fields(integer_or_string, card, i=2, j=len(card)) self.IDs = expand_thru(IDs)
[docs] def raw_fields(self): """gets the "raw" card without any processing as a list for printing""" list_fields = ['SEQSET1', self.components] + collapse_thru(self.IDs) return list_fields
[docs]class SEQSEP(SetSuper): # not integrated...is this an SESET ??? """ Used with the CSUPER entry to define the correspondence of the exterior grid points between an identical or mirror-image superelement and its primary superelement. """ type = 'SEQSEP' def __init__(self, card=None, data=None, comment=''): SetSuper.__init__(self, card, data) if comment: self._comment = comment #: Identification number for secondary superelement. (Integer >= 0). self.ssid = integer(card, 1, 'ssid') #: Identification number for the primary superelement. (Integer >= 0). self.psid = integer(card, 2, 'psid') #: Exterior grid point identification numbers for the primary #: superelement. (Integer > 0) self.IDs = [] IDs = fields(integer_or_string, card, i=3, j=len(card)) self.IDs = expand_thru(IDs) self.cleanIDs()
[docs] def raw_fields(self): """gets the "raw" card without any processing as a list for printing""" list_fields = ['SEQSEP', self.ssid, self.psid] + self.SetIDs() return list_fields
[docs]class RADSET(Set): # not integrated """ Specifies which radiation cavities are to be included for radiation enclosure analysis. +--------+----------+----------+----------+----------+----------+----------+----------+ | RADSET | ICAVITY1 | ICAVITY2 | ICAVITY3 | ICAVITY4 | ICAVITY5 | ICAVITY6 | ICAVITY7 | +--------+----------+----------+----------+----------+----------+----------+----------+ | | ICAVITY8 | ICAVITY9 | -etc.- | | | | | +--------+----------+----------+----------+----------+----------+----------+----------+ """ type = 'RADSET' def __init__(self, card=None, data=None, comment=''): Set.__init__(self, card, data) if comment: self._comment = comment self.seid = integer(card, 1, 'seid') #: Grid or scalar point identification number. #: (0 < Integer < 1000000; G1 < G2) self.IDs = [] IDs = fields(integer_or_string, card, 'ID', i=2, j=len(card)) self.IDs = expand_thru(IDs) self.cleanIDs()
[docs] def addRadsetObject(self, radset): self.IDs += radset.IDs self.cleanIDs()
[docs] def raw_fields(self): """gets the "raw" card without any processing as a list for printing""" list_fields = ['RADSET', self.seid] + self.SetIDs() return list_fields