"""defines the BDF attributes"""
from __future__ import print_function, unicode_literals
from collections import defaultdict
from typing import List, Dict, Optional, Any
from numpy import array # type: ignore
from pyNastran.utils import object_attributes, object_methods
from pyNastran.bdf.bdf_interface.utils import deprecated
#from pyNastran.bdf.case_control_deck import CaseControlDeck
from pyNastran.bdf.cards.coordinate_systems import CORD2R
#from pyNastran.bdf.cards.constraints import ConstraintObject
from pyNastran.bdf.cards.aero.zona import ZONA
class BDFAttributes(object):
"""defines attributes of the BDF"""
def __init__(self):
"""creates the attributes for the BDF"""
self.__init_attributes()
self._is_cards_dict = False
self.is_nx = False
self.is_msc = False
self.is_zona = False
self.save_file_structure = False
self.is_superelements = False
self.set_as_msc()
self.units = [] # type: List[str]
def set_as_msc(self):
self._nastran_format = 'msc'
self.is_nx = False
self.is_msc = True
self.is_zona = False
def set_as_nx(self):
self._nastran_format = 'nx'
self.is_nx = True
self.is_msc = False
self.is_zona = False
def set_as_zona(self):
self._nastran_format = 'zona'
self.is_nx = False
self.is_msc = False
self.is_zona = True
def __properties__(self):
"""the list of @property attributes"""
return ['nastran_format', 'is_long_ids', 'sol', 'subcases',
'nnodes', 'node_ids', 'point_ids', 'npoints',
'nelements', 'element_ids', 'nproperties', 'property_ids',
'nmaterials', 'material_ids', 'ncoords', 'coord_ids',
'ncaeros', 'caero_ids', 'wtmass', 'is_bdf_vectorized', 'nid_map']
def object_attributes(self, mode='public', keys_to_skip=None, filter_properties=False):
"""
List the names of attributes of a class as strings. Returns public
attributes as default.
Parameters
----------
mode : str
defines what kind of attributes will be listed
* 'public' - names that do not begin with underscore
* 'private' - names that begin with single underscore
* 'both' - private and public
* 'all' - all attributes that are defined for the object
keys_to_skip : List[str]; default=None -> []
names to not consider to avoid deprecation warnings
filter_properties: bool: default=False
filters the @property objects
Returns
-------
attribute_names : List[str]
sorted list of the names of attributes of a given type or None
if the mode is wrong
"""
if keys_to_skip is None:
keys_to_skip = []
my_keys_to_skip = [
#'case_control_deck',
'log',
'node_ids', 'coord_ids', 'element_ids', 'property_ids',
'material_ids', 'caero_ids', 'is_long_ids',
'nnodes', 'ncoords', 'nelements', 'nproperties',
'nmaterials', 'ncaeros', 'npoints',
'point_ids', 'subcases',
'_card_parser', '_card_parser_b', '_card_parser_prepare',
'object_methods', 'object_attributes',
]
return object_attributes(self, mode=mode, keys_to_skip=keys_to_skip+my_keys_to_skip,
filter_properties=filter_properties)
def object_methods(self, mode='public', keys_to_skip=None):
# type: (str, Optional[List[str]]) -> List[str]
"""
List the names of methods of a class as strings. Returns public methods
as default.
Parameters
----------
obj : instance
the object for checking
mode : str
defines what kind of methods will be listed
* "public" - names that do not begin with underscore
* "private" - names that begin with single underscore
* "both" - private and public
* "all" - all methods that are defined for the object
keys_to_skip : List[str]; default=None -> []
names to not consider to avoid deprecation warnings
Returns
-------
method : List[str]
sorted list of the names of methods of a given type
or None if the mode is wrong
"""
if keys_to_skip is None:
keys_to_skip = []
my_keys_to_skip = [] # type: List[str]
my_keys_to_skip = [
#'case_control_deck',
'log', #'mpcObject', 'spcObject',
'node_ids', 'coord_ids', 'element_ids', 'property_ids',
'material_ids', 'caero_ids', 'is_long_ids',
'nnodes', 'ncoords', 'nelements', 'nproperties',
'nmaterials', 'ncaeros',
'point_ids', 'subcases',
'_card_parser', '_card_parser_b',
'object_methods', 'object_attributes',
]
return object_methods(self, mode=mode, keys_to_skip=keys_to_skip+my_keys_to_skip)
def deprecated(self, old_name, new_name, deprecated_version):
# type: (str, str, str) -> None
"""deprecates methods"""
return deprecated(old_name, new_name, deprecated_version, levels=[0, 1, 2])
def clear_attributes(self):
# type: () -> None
"""removes the attributes from the model"""
self.__init_attributes()
self.nodes = {}
self.loads = {} # type: Dict[int, List[Any]]
self.load_combinations = {} # type: Dict[int, List[Any]]
def reset_errors(self):
"""removes the errors from the model"""
self._ixref_errors = 0
self._stored_xref_errors = []
def __init_attributes(self):
# type: () -> None
"""
Creates storage objects for the BDF object.
This would be in the init but doing it this way allows for better
inheritance
References:
1. http://www.mscsoftware.com/support/library/conf/wuc87/p02387.pdf
"""
self.reset_errors()
self.bdf_filename = None
self.punch = None
self._encoding = None
self._is_long_ids = False # ids > 8 characters
#: ignore any ECHOON flags
self.force_echo_off = True
#: list of Nastran SYSTEM commands
self.system_command_lines = [] # type: List[str]
#: list of execive control deck lines
self.executive_control_lines = [] # type: List[str]
#: list of case control deck lines
self.case_control_lines = [] # type: List[str]
# dictionary of BDFs
self.superelement_models = {}
self.initial_superelement_models = [] # the keys before superelement mirroring
self._auto_reject = False
self._solmap_to_value = {
'NONLIN': 101, # 66 -> 101 per Reference 1
'SESTATIC': 101,
'SESTATICS': 101,
'SEMODES': 103,
'BUCKLING': 105,
'SEBUCKL': 105,
'NLSTATIC': 106,
'SEDCEIG': 107,
'SEDFREQ': 108,
'SEDTRAN': 109,
'SEMCEIG': 110,
'SEMFREQ': 111,
'SEMTRAN': 112,
'CYCSTATX': 114,
'CYCMODE': 115,
'CYCBUCKL': 116,
'CYCFREQ': 118,
'NLTRAN': 129,
'AESTAT': 144,
'FLUTTR': 145,
'SEAERO': 146,
'NLSCSH': 153,
'NLTCSH': 159,
'DBTRANS': 190,
'DESOPT': 200,
# guessing
#'CTRAN' : 115,
'CFREQ' : 118,
# solution 200 names
'STATICS': 101,
'MODES': 103,
'BUCK': 105,
'DFREQ': 108,
'MFREQ': 111,
'MTRAN': 112,
'DCEIG': 107,
'MCEIG': 110,
#'HEAT' : None,
#'STRUCTURE': None,
#'DIVERGE' : None,
'FLUTTER': 145,
'SAERO': 146,
}
self.rsolmap_to_str = {
66: 'NONLIN',
101: 'SESTSTATIC', # linear static
103: 'SEMODES', # modal
105: 'BUCKLING', # buckling
106: 'NLSTATIC', # non-linear static
107: 'SEDCEIG', # direct complex frequency response
108: 'SEDFREQ', # direct frequency response
109: 'SEDTRAN', # direct transient response
110: 'SEMCEIG', # modal complex eigenvalue
111: 'SEMFREQ', # modal frequency response
112: 'SEMTRAN', # modal transient response
114: 'CYCSTATX',
115: 'CYCMODE',
116: 'CYCBUCKL',
118: 'CYCFREQ',
129: 'NLTRAN', # nonlinear transient
144: 'AESTAT', # static aeroelastic
145: 'FLUTTR', # flutter/aeroservoelastic
146: 'SEAERO', # dynamic aeroelastic
153: 'NLSCSH', # nonlinear static thermal
159: 'NLTCSH', # nonlinear transient thermal
#187 - Dynamic Design Analysis Method
190: 'DBTRANS',
200: 'DESOPT', # optimization
}
# ------------------------ bad duplicates ----------------------------
self._iparse_errors = 0
self._nparse_errors = 0
self._stop_on_parsing_error = True
self._stop_on_duplicate_error = True
self._stored_parse_errors = [] # type: List[str]
self._duplicate_nodes = [] # type: List[str]
self._duplicate_elements = [] # type: List[str]
self._duplicate_properties = [] # type: List[str]
self._duplicate_materials = [] # type: List[str]
self._duplicate_masses = [] # type: List[str]
self._duplicate_thermal_materials = [] # type: List[str]
self._duplicate_coords = [] # type: List[str]
self.values_to_skip = {} # type: Dict[str, List[int]]
# ------------------------ structural defaults -----------------------
#: the analysis type
self._sol = None
#: used in solution 600, method
self.sol_method = None
#: the line with SOL on it, marks ???
self.sol_iline = None # type : Optional[int]
self.case_control_deck = None # type: Optional[Any]
#: store the PARAM cards
self.params = {} # type: Dict[str, Any]
# ------------------------------- nodes -------------------------------
# main structural block
#: stores POINT cards
self.points = {} # type: Dict[int, Any]
#self.grids = {}
self.spoints = {} # type: Dict[int, Any]
self.epoints = {} # type: Dict[int, Any]
#: stores GRIDSET card
self.grdset = None # type: Optional[Any]
#: stores SEQGP cards
self.seqgp = None # type: Optional[Any]
## stores RINGAX
self.ringaxs = {} # type: Dict[int, Any]
## stores GRIDB
self.gridb = {} # type: Dict[int, Any]
#: stores elements (CQUAD4, CTRIA3, CHEXA8, CTETRA4, CROD, CONROD,
#: etc.)
self.elements = {} # type: Dict[int, Any]
#: stores CBARAO, CBEAMAO
self.ao_element_flags = {} # type: Dict[int, Any]
#: stores BAROR
self.baror = None # type: Optional[Any]
#: stores BEAMOR
self.beamor = None # type: Optional[Any]
#: stores SNORM
self.normals = {} # type: Dict[int, Any]
#: stores rigid elements (RBE2, RBE3, RJOINT, etc.)
self.rigid_elements = {} # type: Dict[int, Any]
#: stores PLOTELs
self.plotels = {} # type: Optional[Any]
#: stores CONM1, CONM2, CMASS1,CMASS2, CMASS3, CMASS4, CMASS5
self.masses = {} # type: Dict[int, Any]
#: stores PMASS
self.properties_mass = {} # type: Dict[int, Any]
#: stores NSM, NSM1, NSML, NSML1
self.nsms = {} # type: Dict[int, List[Any]]
#: stores NSMADD
self.nsmadds = {} # type: Dict[int, List[Any]]
#: stores LOTS of propeties (PBAR, PBEAM, PSHELL, PCOMP, etc.)
self.properties = {} # type: Dict[int, Any]
#: stores MAT1, MAT2, MAT3, MAT8, MAT10, MAT11
self.materials = {} # type: Dict[int, Any]
#: defines the MAT4, MAT5
self.thermal_materials = {} # type: Dict[int, Any]
#: defines the MATHE, MATHP
self.hyperelastic_materials = {} # type: Dict[int, Any]
#: stores MATSx
self.MATS1 = {} # type: Dict[int, Any]
self.MATS3 = {} # type: Dict[int, Any]
self.MATS8 = {} # type: Dict[int, Any]
#: stores MATTx
self.MATT1 = {} # type: Dict[int, Any]
self.MATT2 = {} # type: Dict[int, Any]
self.MATT3 = {} # type: Dict[int, Any]
self.MATT4 = {} # type: Dict[int, Any]
self.MATT5 = {} # type: Dict[int, Any]
self.MATT8 = {} # type: Dict[int, Any]
self.MATT9 = {} # type: Dict[int, Any]
self.nxstrats = {} # type: Dict[int, Any]
#: stores the CREEP card
self.creep_materials = {} # type: Dict[int, Any]
self.tics = {} # type: Optional[Any]
# stores DLOAD entries.
self.dloads = {} # type: Dict[int, Any]
# stores ACSRCE, RLOAD1, RLOAD2, TLOAD1, TLOAD2, and ACSRCE,
# and QVECT entries.
self.dload_entries = {} # type: Dict[int, Any]
#self.gusts = {} # Case Control GUST = 100
#self.random = {} # Case Control RANDOM = 100
#: stores coordinate systems
origin = array([0., 0., 0.])
zaxis = array([0., 0., 1.])
xzplane = array([1., 0., 0.])
coord = CORD2R(cid=0, rid=0, origin=origin, zaxis=zaxis, xzplane=xzplane)
self.coords = {0 : coord} # type: Dict[int, Any]
# --------------------------- constraints ----------------------------
#: stores SUPORT1s
#self.constraints = {} # suport1, anything else???
self.suport = [] # type: List[Any]
self.suport1 = {} # type: Dict[int, Any]
self.se_suport = [] # type: List[Any]
#: stores SPC, SPC1, SPCAX, GMSPC
self.spcs = {} # type: Dict[int, List[Any]]
#: stores SPCADD
self.spcadds = {} # type: Dict[int, List[Any]]
self.spcoffs = {} # type: Dict[int, List[Any]]
self.mpcs = {} # type: Dict[int, List[Any]]
self.mpcadds = {} # type: Dict[int, List[Any]]
# --------------------------- dynamic ----------------------------
#: stores DAREA
self.dareas = {} # type: Dict[int, Any]
self.dphases = {} # type: Dict[int, Any]
self.pbusht = {} # type: Dict[int, Any]
self.pdampt = {} # type: Dict[int, Any]
self.pelast = {} # type: Dict[int, Any]
#: frequencies
self.frequencies = {} # type: Dict[int, List[Any]]
# ----------------------------------------------------------------
#: direct matrix input - DMIG
self.dmi = {} # type: Dict[str, Any]
self.dmig = {} # type: Dict[str, Any]
self.dmij = {} # type: Dict[str, Any]
self.dmiji = {} # type: Dict[str, Any]
self.dmik = {} # type: Dict[str, Any]
self.dti = {} # type: Dict[str, Any]
self._dmig_temp = defaultdict(list) # type: Dict[str, List[str]]
# ----------------------------------------------------------------
#: SETy
self.sets = {} # type: Dict[int, Any]
self.asets = [] # type: List[Any]
self.omits = [] # type: List[Any]
self.bsets = [] # type: List[Any]
self.csets = [] # type: List[Any]
self.qsets = [] # type: List[Any]
self.usets = {} # type: Dict[str, Any]
#: SExSETy
self.se_bsets = [] # type: List[Any]
self.se_csets = [] # type: List[Any]
self.se_qsets = [] # type: List[Any]
self.se_usets = {} # type: Dict[str, Any]
self.se_sets = {} # type: Dict[str, Any]
# ----------------------------------------------------------------
#: tables
# TABLES1, ...
self.tables = {} # type: Dict[int, TABLES1]
# TABLEDx
self.tables_d = {} # type: Dict[int, Union[TABLED1, TABLED2, TABLED3, TABLED4]]
# TABLEMx
self.tables_m = {} # type: Dict[int, Union[TABLEM1, TABLEM2, TABLEM3, TABLEM4]]
#: random_tables
self.random_tables = {} # type: Dict[int, Any]
#: TABDMP1
self.tables_sdamping = {} # type: Dict[int, TABDMP1]
# ----------------------------------------------------------------
#: EIGB, EIGR, EIGRL methods
self.methods = {} # type: Dict[int, Union[EIGR, EIGRL, EIGB]]
# EIGC, EIGP methods
self.cMethods = {} # type: Dict[int, Union[EIGC, EIGP]]
# ---------------------------- optimization --------------------------
# optimization
self.dconadds = {} # type: Dict[int, DCONADD]
self.dconstrs = {} # type: Dict[int, DCONSTR]
self.desvars = {} # type: Dict[int, DESVAR]
self.ddvals = {} # type: Dict[int, DDVAL]
self.dlinks = {} # type: Dict[int, DLINK]
self.dresps = {} # type: Dict[int, Union[DRESP1, DRESP2, DRESP3]]
self.dtable = None # type: Optional[DTABLE]
self.dequations = {} # type: Dict[int, DEQATN]
#: stores DVPREL1, DVPREL2...might change to DVxRel
self.dvprels = {} # type: Dict[int, Union[DVPREL1, DVPREL2]]
self.dvmrels = {} # type: Dict[int, Union[DVMREL1, DVMREL2]]
self.dvcrels = {} # type: Dict[int, Union[DVCREL1, DVCREL2]]
self.dvgrids = {} # type: Dict[int, DVGRID]
self.doptprm = None # type: Optional[DOPTPRM]
self.dscreen = {} # type: Dict[int, DSCREEN]
# ------------------------- nonlinear defaults -----------------------
#: stores NLPCI
self.nlpcis = {} # type: Dict[int, NLPCI]
#: stores NLPARM
self.nlparms = {} # type: Dict[int, NLPARM]
#: stores TSTEPs, TSTEP1s
self.tsteps = {} # type: Dict[int, Union[TSTEP, TSTEP1]]
#: stores TSTEPNL
self.tstepnls = {} # type: Dict[int, TSTEPNL]
#: stores TF
self.transfer_functions = {} # type: Dict[int, TF]
#: stores DELAY
self.delays = {} # type: Dict[int, DELAY]
#: stores ROTORD, ROTORG
self.rotors = {} # type: Dict[int, Union[ROTORD, ROTORG]]
# --------------------------- aero defaults --------------------------
# aero cards
#: stores CAEROx
self.caeros = {} # type: Dict[int, Union[CAERO1, CAERO2, CAERO3, CAERO4, CAERO5]]
#: stores PAEROx
self.paeros = {} # type: Dict[int, Union[PAERO1, PAERO2, PAERO3, PAERO4, PAERO5]]
# stores MONPNT1
self.monitor_points = [] # type: List[Union[MONPNT1, MONPNT2, MONPNT3]]
#: stores AECOMP
self.aecomps = {} # type: Dict[int, AECOMP]
#: stores AEFACT
self.aefacts = {} # type: Dict[int, AEFACT]
#: stores AELINK
self.aelinks = {} # type: Dict[int, List[AELINK]]
#: stores AELIST
self.aelists = {} # type: Dict[int, AELIST]
#: stores AEPARAM
self.aeparams = {} # type: Dict[int, AEPARAM]
#: stores AESURF
self.aesurf = {} # type: Dict[int, AESURF]
#: stores AESURFS
self.aesurfs = {} # type: Dict[int, AESURFS]
#: stores AESTAT
self.aestats = {} # type: Dict[int, AESTAT]
#: stores CSSCHD
self.csschds = {} # type: Dict[int, CSSCHD]
#: store SPLINE1,SPLINE2,SPLINE4,SPLINE5
self.splines = {} # type: Dict[int, Union[SPLINE1, SPLINE2, SPLINE3, SPLINE4, SPLINE5]]
self.zona = ZONA(self)
# axisymmetric
self.axic = None # type: Optional[AXIC]
self.axif = None # type: Optional[AXIF]
self.ringfl = {} # type: Dict[int, RINGFL]
self._is_axis_symmetric = False
# cyclic
# acoustic
# ------ SOL 144 ------
#: stores AEROS
self.aeros = None # type: Optional[AEROS]
#: stores TRIM, TRIM2
self.trims = {} # type: Dict[int, Union[TRIM, TRIM2]]
#: stores DIVERG
self.divergs = {} # type: Dict[int, DIVERG]
# ------ SOL 145 ------
#: stores AERO
self.aero = None # type: Optional[AERO]
#: stores FLFACT
self.flfacts = {} # type: Dict[int, FLFACT]
#: stores FLUTTER
self.flutters = {} # type: Dict[int, FLUTTER]
#: mkaeros
self.mkaeros = [] # type: List[Union[MKAERO1,MKAERO2]]
# ------ SOL 146 ------
#: stores GUST cards
self.gusts = {} # type: Dict[int, GUST]
# ------------------------- thermal defaults -------------------------
# BCs
#: stores thermal boundary conditions - CONV,RADBC
self.bcs = {} # type: Dict[int, Union[CONV, RADBC]]
#: stores PHBDY
self.phbdys = {} # type: Dict[int, PHBDY]
#: stores convection properties - PCONV, PCONVM ???
self.convection_properties = {} # type: Dict[int, Union[PCONV, PCONVM]]
#: stores TEMPD
self.tempds = {} # type: Dict[int, TEMPD]
#: stores VIEW
self.views = {} # type: Dict[int, VIEW]
#: stores VIEW3D
self.view3ds = {} # type: Dict[int, VIEW3D]
self.radset = None
self.radcavs = {} # type: Dict[int, RADCAV]
self.radmtx = {} # type: Dict[int, RADMTX]
# -------------------------contact cards-------------------------------
self.bcrparas = {} # type: Dict[int, BCRPARA]
self.bctadds = {} # type: Dict[int, BCTADD]
self.bctparas = {} # type: Dict[int, BCTPARA]
self.bctsets = {} # type: Dict[int, BCTSET]
self.bsurf = {} # type: Dict[int, BSURF]
self.bsurfs = {} # type: Dict[int, BSURFS]
self.bconp = {} # type: Dict[int, BCONP]
self.blseg = {} # type: Dict[int, BLSEG]
#--------------------------superelements------------------------------
self.setree = {} # type: Dict[int, SETREE]
self.senqset = {} # type: Dict[int, Union[SENQSET, SENQSET1]]
self.sebulk = {} # type: Dict[int, SEBULK]
self.sebndry = {} # type: Dict[int, SEBNDRY]
self.seloc = {} # type: Dict[int, SELOC]
self.sempln = {} # type: Dict[int, SEMPLN]
self.seconct = {} # type: Dict[int, SECONCT]
self.selabel = {} # type: Dict[int, SELABEL]
self.seexcld = {} # type: Dict[int, SEEXCLD]
self.seelt = {} # type: Dict[int, SEELT]
self.seload = {} # type: Dict[int, SELOAD]
self.csuper = {} # type: Dict[int, CSUPER]
self.csupext = {} # type: Dict[int, CSUPEXT]
# ---------------------------------------------------------------------
self._type_to_id_map = defaultdict(list) # type: Dict[int, List[Any]]
self._slot_to_type_map = {
'params' : ['PARAM'],
'nodes' : ['GRID', 'SPOINT', 'EPOINT'], # 'RINGAX',
'points' : ['POINT'],
'ringaxs' : ['RINGAX', 'POINTAX'],
'ringfl' : ['RINGFL'],
'axic' : ['AXIC'],
'axif' : ['AXIF'],
'acmodl' : ['ACMODL'],
'grdset' : ['GRDSET'],
'gridb' : ['GRIDB'],
'seqgp' : ['SEQGP'],
'ao_element_flags' : ['CBARAO'],
#'POINTAX', 'RINGAX',
# CMASS4 lies in the QRG
'masses' : ['CONM1', 'CONM2', 'CMASS1', 'CMASS2', 'CMASS3', 'CMASS4'],
'elements' : [
'CELAS1', 'CELAS2', 'CELAS3', 'CELAS4',
# 'CELAS5',
'CBUSH', 'CBUSH1D', 'CBUSH2D',
'CDAMP1', 'CDAMP2', 'CDAMP3', 'CDAMP4', 'CDAMP5',
'CFAST', 'GENEL',
'CBAR', 'CROD', 'CTUBE', 'CBEAM', 'CBEAM3', 'CONROD', 'CBEND',
'CTRIA3', 'CTRIA6', 'CTRIAR',
'CQUAD4', 'CQUAD8', 'CQUADR', 'CQUAD',
'CPLSTN3', 'CPLSTN6', 'CPLSTN4', 'CPLSTN8',
'CPLSTS3', 'CPLSTS6', 'CPLSTS4', 'CPLSTS8',
'CTRAX3', 'CTRAX6', 'CTRIAX', 'CTRIAX6',
'CQUADX', 'CQUADX4', 'CQUADX8',
'CCONEAX',
'CTETRA', 'CPYRAM', 'CPENTA', 'CHEXA', 'CIHEX1', 'CIHEX2',
'CSHEAR', 'CVISC', 'CRAC2D', 'CRAC3D',
'CGAP',
# thermal
'CHBDYE', 'CHBDYG', 'CHBDYP',
# acoustic
'CHACAB', 'CAABSF', 'CHACBR',
],
'normals' : ['SNORM'],
'nsms' : ['NSM', 'NSM1', 'NSML', 'NSML1'],
'nsmadds' : ['NSMADD'],
'rigid_elements' : ['RBAR', 'RBAR1', 'RBE1', 'RBE2', 'RBE3', 'RROD', 'RSPLINE', 'RSSCON'],
'plotels' : ['PLOTEL'],
'properties_mass' : ['PMASS'],
#'properties_acoustic' : ['PACABS'],
'properties' : [
# acoustic
'PACABS', 'PAABSF', 'PACBAR',
# 0d
'PELAS', 'PGAP', 'PFAST',
'PBUSH', 'PBUSH1D',
'PDAMP', 'PDAMP5',
# 1d
'PROD', 'PBAR', 'PBARL', 'PBEAM', 'PTUBE', 'PBEND', 'PBCOMP', 'PBRSECT', 'PBMSECT',
'PBEAML', # not fully supported
'PBEAM3',
# 2d
'PLPLANE', 'PPLANE',
'PSHELL', 'PCOMP', 'PCOMPG', 'PSHEAR',
'PSOLID', 'PLSOLID', 'PVISC', 'PRAC2D', 'PRAC3D',
'PIHEX', 'PCOMPS',
'PCONEAX',
],
'pdampt' : ['PDAMPT'],
'pelast' : ['PELAST'],
'pbusht' : ['PBUSHT'],
# materials
'materials' : ['MAT1', 'MAT2', 'MAT3', 'MAT8', 'MAT9', 'MAT10', 'MAT11',
'MAT3D', 'MATG'],
'hyperelastic_materials' : ['MATHE', 'MATHP'],
'creep_materials' : ['CREEP'],
'MATT1' : ['MATT1'],
'MATT2' : ['MATT2'],
'MATT3' : ['MATT3'],
'MATT4' : ['MATT4'], # thermal
'MATT5' : ['MATT5'], # thermal
'MATT8' : ['MATT8'],
'MATT9' : ['MATT9'],
'MATS1' : ['MATS1'],
'MATS3' : ['MATS3'],
'MATS8' : ['MATS8'],
'nxstrats' : ['NXSTRAT'],
# 'MATHE'
#'EQUIV', # testing only, should never be activated...
# thermal materials
'thermal_materials' : ['MAT4', 'MAT5'],
# spc/mpc constraints - TODO: is this correct?
'spcadds' : ['SPCADD'],
'spcs' : ['SPC', 'SPC1', 'SPCAX', 'GMSPC'],
'spcoffs' : ['SPCOFF', 'SPCOFF1'],
'mpcadds' : ['MPCADD'],
'mpcs' : ['MPC'],
'suport' : ['SUPORT'],
'suport1' : ['SUPORT1'],
'se_suport' : ['SESUP'],
'setree' : ['SETREE'],
'senqset' : ['SENQSET'],
'sebulk' : ['SEBULK'],
'sebndry' : ['SEBNDRY'],
'release' : ['RELEASE'],
'seloc' : ['SELOC'],
'sempln' : ['SEMPLN'],
'seconct' : ['SECONCT'],
'selabel' : ['SELABEL'],
'seexcld' : ['SEEXCLD'],
'seelt' : ['SEELT'],
'seload' : ['SELOAD'],
'csuper' : ['CSUPER'],
'csupext' : ['CSUPEXT'],
# loads
'load_combinations' : ['LOAD', 'LSEQ', 'CLOAD'],
'loads' : [
'FORCE', 'FORCE1', 'FORCE2',
'MOMENT', 'MOMENT1', 'MOMENT2',
'GRAV', 'ACCEL', 'ACCEL1',
'PLOAD', 'PLOAD1', 'PLOAD2', 'PLOAD4',
'RFORCE', 'RFORCE1', 'SLOAD',
'GMLOAD', 'SPCD', 'LOADCYN', 'LOADCYH', 'DEFORM',
# thermal
'TEMP', 'TEMPB3', 'QBDY1', 'QBDY2', 'QBDY3', 'QHBDY',
'QVOL',
# axisymmetric
'PLOADX1', 'FORCEAX', 'PRESAX', 'TEMPAX',
],
'cyjoin' : ['CYJOIN'],
'cyax' : ['CYAX'],
'modtrak' : ['MODTRAK'],
'dloads' : ['DLOAD'],
# stores RLOAD1, RLOAD2, TLOAD1, TLOAD2, and ACSRCE entries.
'dload_entries' : ['ACSRCE', 'TLOAD1', 'TLOAD2', 'RLOAD1', 'RLOAD2',
'QVECT', 'RANDPS', 'RANDT1'],
# aero cards
'aero' : ['AERO'],
'aeros' : ['AEROS'],
'gusts' : ['GUST', 'GUST2'],
'flutters' : ['FLUTTER'],
'flfacts' : ['FLFACT'],
'mkaeros' : ['MKAERO1', 'MKAERO2'],
'aecomps' : ['AECOMP', 'AECOMPL'],
'aefacts' : ['AEFACT'],
'aelinks' : ['AELINK'],
'aelists' : ['AELIST'],
'aeparams' : ['AEPARM'],
'aesurf' : ['AESURF'],
'aesurfs' : ['AESURFS'],
'aestats' : ['AESTAT'],
'caeros' : ['CAERO1', 'CAERO2', 'CAERO3', 'CAERO4', 'CAERO5', 'CAERO7', 'BODY7'],
'paeros' : ['PAERO1', 'PAERO2', 'PAERO3', 'PAERO4', 'PAERO5', 'SEGMESH'],
'monitor_points' : ['MONPNT1', 'MONPNT2', 'MONPNT3', 'MONDSP1'],
'splines' : ['SPLINE1', 'SPLINE2', 'SPLINE3', 'SPLINE4', 'SPLINE5', 'SPLINE6', 'SPLINE7'],
'panlsts' : ['PANLST1', 'PANLST2', 'PANLST3'],
'csschds' : ['CSSCHD',],
#'SPLINE3', 'SPLINE6', 'SPLINE7',
'trims' : ['TRIM', 'TRIM2'],
'divergs' : ['DIVERG'],
# coords
'coords' : ['CORD1R', 'CORD1C', 'CORD1S',
'CORD2R', 'CORD2C', 'CORD2S',
'GMCORD', 'ACOORD', 'CORD3G'],
# temperature cards
'tempds' : ['TEMPD'],
'phbdys' : ['PHBDY'],
'convection_properties' : ['PCONV', 'PCONVM'],
# stores thermal boundary conditions
'bcs' : ['CONV', 'CONVM', 'RADBC', 'RADM', 'TEMPBC'],
# dynamic cards
'dareas' : ['DAREA'],
'tics' : ['TIC'],
'dphases' : ['DPHASE'],
'nlparms' : ['NLPARM'],
'nlpcis' : ['NLPCI'],
'tsteps' : ['TSTEP'],
'tstepnls' : ['TSTEPNL', 'TSTEP1'],
'transfer_functions' : ['TF'],
'delays' : ['DELAY'],
'rotors' : ['ROTORG', 'ROTORD'],
'frequencies' : ['FREQ', 'FREQ1', 'FREQ2', 'FREQ3', 'FREQ4', 'FREQ5'],
# direct matrix input cards
'dmig' : ['DMIG'],
'dmij' : ['DMIJ'],
'dmiji' : ['DMIJI'],
'dmik' : ['DMIK'],
'dmi' : ['DMI'],
'dti' : ['DTI'],
# optimzation
'dequations' : ['DEQATN'],
'dtable' : ['DTABLE'],
'dconstrs' : ['DCONSTR', 'DCONADD'],
'desvars' : ['DESVAR'],
'topvar' : ['TOPVAR'],
'ddvals' : ['DDVAL'],
'dlinks' : ['DLINK'],
'dresps' : ['DRESP1', 'DRESP2', 'DRESP3'],
'dvprels' : ['DVPREL1', 'DVPREL2'],
'dvmrels' : ['DVMREL1', 'DVMREL2'],
'dvcrels' : ['DVCREL1', 'DVCREL2'],
'dvgrids' : ['DVGRID'],
'doptprm' : ['DOPTPRM'],
'dscreen' : ['DSCREEN'],
# sets
'asets' : ['ASET', 'ASET1'],
'omits' : ['OMIT', 'OMIT1'],
'bsets' : ['BSET', 'BSET1'],
'qsets' : ['QSET', 'QSET1'],
'csets' : ['CSET', 'CSET1'],
'usets' : ['USET', 'USET1'],
'sets' : ['SET1', 'SET3'],
# super-element sets
'se_bsets' : ['SEBSET', 'SEBSET1'],
'se_csets' : ['SECSET', 'SECSET1'],
'se_qsets' : ['SEQSET', 'SEQSET1'],
'se_usets' : ['SEUSET', 'SEQSET1'],
'se_sets' : ['SESET'],
'radset' : ['RADSET'],
'radcavs' : ['RADCAV', 'RADLST'],
'radmtx' : ['RADMTX'],
# SEBSEP
# parametric
'pset' : ['PSET'],
'pval' : ['PVAL'],
'gmcurv' : ['GMCURV'],
'gmsurf' : ['GMSURF'],
'feedge' : ['FEEDGE'],
'feface' : ['FEFACE'],
# tables
'tables' : [
'TABLEH1', 'TABLEHT',
'TABLES1', 'TABLEST',
],
'tables_d' : ['TABLED1', 'TABLED2', 'TABLED3', 'TABLED4', 'TABLED5'],
'tables_m' : ['TABLEM1', 'TABLEM2', 'TABLEM3', 'TABLEM4'],
'tables_sdamping' : ['TABDMP1'],
'random_tables' : ['TABRND1', 'TABRNDG'],
# initial conditions - sid (set ID)
##'TIC', (in bdf_tables.py)
# methods
'methods' : ['EIGB', 'EIGR', 'EIGRL'],
# cMethods
'cMethods' : ['EIGC', 'EIGP'],
# contact
'bctparas' : ['BCTPARA'],
'bcrparas' : ['BCRPARA'],
'bctadds' : ['BCTADD'],
'bctsets' : ['BCTSET'],
'bsurf' : ['BSURF'],
'bsurfs' : ['BSURFS'],
'bconp' : ['BCONP'],
'blseg' : ['BLSEG'],
'bfric' : ['BFRIC'],
'views' : ['VIEW'],
'view3ds' : ['VIEW3D'],
## other
#'INCLUDE', # '='
#'ENDDATA',
} # type: Dict[str, List[str]]
self._type_to_slot_map = self.get_rslot_map()
@property
def type_slot_str(self):
"""helper method for printing supported cards"""
nchars = len('Card Group')
#nchars_cards = 0
for card_group in self._slot_to_type_map:
nchars = max(nchars, len(card_group))
nline = 58
fmt = '| %%-%ss | %%-%ss |\n' % (nchars, nline)
fmt_plus = '+%%-%ss+%%-%ss+\n' % (nchars + 2, nline + 2)
dash1 = '-' * (nchars + 2)
dash2 = '-' * (nline + 2)
dash_plus = fmt_plus % (dash1, dash2)
html_msg = [
dash_plus,
fmt % ('Card Group', 'Cards'),
]
for card_group, card_types in sorted(self._slot_to_type_map.items()):
valid_cards = [card_type for card_type in card_types
if card_type in self.cards_to_read]
valid_cards.sort()
if len(valid_cards) == 0:
continue
#i = 0
sublines = []
subline = ''
while valid_cards:
card_type = valid_cards.pop(0)
# the +2 is for the comma and space
len_card_type = len(card_type) + 2
nline_new = len(subline) + len_card_type
if nline_new > nline:
sublines.append(subline.rstrip(' '))
subline = ''
subline += '%s, ' % card_type
if subline:
sublines.append(subline.rstrip(', '))
html_msg.append(dash_plus)
for isub, subline in enumerate(sublines):
if isub > 0: # adds intermediate dash lines
html_msg.append(dash_plus)
html_msg.append(fmt % (card_group, subline))
card_group = ''
html_msg.append(dash_plus)
#for card_group, card_types in sorted(self._slot_to_type_map.items()):
#html_msg.append('| %s | %s |' % (card_group, ', '.join(card_types)))
#html_msg.append(
#fmt_plus % ('-'*(nchars + 2), '-'*(nline + 2))
#)
msg = ''.join(html_msg)
return msg
@property
def nastran_format(self):
# type: () -> str
return self._nastran_format
@nastran_format.setter
def nastran_format(self, nastran_format):
# type: (str) -> None
fmt_lower = nastran_format.lower().strip()
if fmt_lower not in ['nx', 'msc', 'zona']:
raise RuntimeError(nastran_format)
self._nastran_format = fmt_lower
@property
def is_long_ids(self):
# type: () -> bool
return self._is_long_ids
#if self._nastran_format == 'nx' or self._is_long_ids:
#return True
#return False
@property
def sol(self):
# type: () -> int
"""gets the solution (e.g. 101, 103)"""
return self._sol
@sol.setter
def sol(self, sol):
# type: (int) -> int
"""sets the solution (e.g. 101, 103)"""
self._sol = sol
if len(self.executive_control_lines) == 0:
self.executive_control_lines = ['SOL %s' % sol, 'CEND']
self.sol_iline = 0
return self._sol
@property
def subcases(self):
# type: () -> Dict[int, Optional[Any]]
"""gets the subcases"""
if self.case_control_deck is None:
return {}
return self.case_control_deck.subcases
#@property
#def grids(self):
#"""might be renaming self.nodes to self.grids"""
#return self.nodes
#@property.setter
#def grids(self, grids):
#"""might be renaming self.nodes to self.grids"""
#self.nodes = grids
@property
def nnodes(self):
# type: () -> int
"""gets the number of GRIDs"""
return len(self.nodes)
@property
def node_ids(self):
"""gets the GRID ids"""
return self.nodes.keys()
@property
def point_ids(self):
"""gets the GRID, SPOINT, EPOINT ids"""
return set(self.node_ids) | set(list(self.spoints.keys())) | set(list(self.epoints.keys()))
@property
def npoints(self):
# type: () -> int
"""gets the number of GRID, SPOINT, EPOINT ids"""
return len(self.point_ids)
#--------------------
# Elements CARDS
@property
def nelements(self):
# type: () -> int
"""gets the number of element"""
return len(self.elements)
@property
def element_ids(self):
"""gets the element ids"""
return self.elements.keys()
#--------------------
# Property CARDS
@property
def nproperties(self):
# type: () -> int
"""gets the number of properties"""
return len(self.properties)
@property
def property_ids(self):
"""gets the property ids"""
return self.properties.keys()
#--------------------
# Material CARDS
@property
def nmaterials(self):
# type: () -> int
"""gets the number of materials"""
return len(self.materials)
@property
def material_ids(self):
"""gets the material ids"""
return self.materials.keys()
#--------------------
# Coords CARDS
@property
def ncoords(self):
# type: () -> int
"""gets the number of coordinate systems"""
return len(self.coords)
@property
def coord_ids(self):
"""gets the number of coordinate system ids"""
return self.coords.keys()
#--------------------
@property
def ncaeros(self):
# type: () -> int
"""gets the number of CAEROx panels"""
return len(self.caeros)
@property
def caero_ids(self):
"""gets the CAEROx ids"""
return self.caeros.keys()
@property
def wtmass(self):
"""
Gets the PARAM,WTMASS value, which defines the weight to mass
conversion factor
kg -> kg : 1.0
lb -> slug : 1/32.2
lb -> slinch : 1/(32.2*12)=1/386.4
"""
wtmass = 1.0
if 'WTMASS' in self.params:
param = self.params['WTMASS']
wtmass = param.values[0]
return wtmass
def set_param(self, key, values):
# type: (str, Union[int, float, str, List[float]]) -> None
"""sets a param card; creates it if necessary"""
if isinstance(values, (int, float, str)):
values = [values]
key = key.upper()
if key in self.params:
param = self.params[key]
param.update_values(*values)
#--------------------
# deprecations
@property
def dmis(self):
return self.dmi
@property
def dmigs(self):
return self.dmig
@property
def dmiks(self):
return self.dmik
@property
def dmijs(self):
return self.dmij
@property
def dmijis(self):
return self.dmiji
@dmis.setter
def dmis(self, dmi):
self.dmi = dmi
@dmigs.setter
def dmigs(self, dmig):
self.dmig = dmig
@dmiks.setter
def dmiks(self, dmik):
self.dmik = dmik
@dmijs.setter
def dmijs(self, dmij):
self.dmij = dmij
@dmijis.setter
def dmijis(self, dmiji):
self.dmiji = dmiji