"""
defines the following card:
- PARAM
"""
# pylint: disable=C0103,R0902,R0904,R0914
import numpy as np
from pyNastran.bdf import MAX_INT
from pyNastran.bdf.cards.base_card import BaseCard
from pyNastran.bdf.bdf_interface.bdf_card import BDFCard
from pyNastran.bdf.bdf_interface.assign_type import (
integer, double, integer_or_blank, double_or_blank, string, string_or_blank,
integer_string_or_blank, integer_double_string_or_blank, blank)
from pyNastran.bdf.field_writer_8 import print_card_8
from pyNastran.bdf.field_writer_16 import print_card_16
from pyNastran.utils.numpy_utils import integer_types, float_types
from typing import Union
#float_words_1 = [
#b'K6ROT', b'WTMASS', b'SNORM', b'PATVER', b'MAXRATIO', b'EPSHT',
#b'SIGMA', b'TABS']
SMALL_FIELD_PARAMS = [
'ACOUT', 'ACOWEAK', 'ACSYM', 'ADJMETH', 'AESMAXIT', 'AESMETH', 'ADSTAT',
'MAXLINES'] #+ INT_WORDS_1 + STR_WORDS_1
# per NX 11 QRG
temperatures = ['', '-C', '-F', '-K', 'R']
systems = [
('N', 'M'), ('N', 'MM'), ('MN', 'MM'), ('CN', 'CM'), ('KGF', 'M'), ('KGF', 'MM'),
('LBF', 'FT'), ('LBF', 'IN'), ('PDL', 'FT'),
]
unit_systems = ['']
for system in systems:
force, length = system
for temperature in temperatures:
unit_system = f'{force}-{length}{temperature}'
unit_systems.append(unit_system)
del temperatures, systems, system, temperature, force, length
PARAMS = (
# A
('ACSYM', 'YES', ['YES', 'NO']),
('APDCON', 1.0),
('ADSTAT', 'YES', ['YES', 'NO']),
('AESDISC', 1e-8),
('AESMAXIT', 15),
('AESMETH', 'SELECT', ['SELECT', 'AUTO', 'DIRECT', 'RITZ', 'ITER']),
('AESRNDM', 2),
('AESTOL', 1e-8),
('AFNORM', 1.0),
('AFZERO', 1.0),
('AGGPCH', 'NO', ['YES', 'NO']),
('ALPHA1', (0., 0.)),
('ALPHA2', (0., 0.)),
('ALTRED', 'NO', ['YES', 'NO']),
('AMPCZ', 1e-6),
('ASCOUP', 'YES', ['YES', 'NO']),
('ASING', 0),
('AUNITS', 1.0),
('AUTOADJ', 'YES', ['YES', 'NO']),
('AUTOMPC', 'NO', ['YES', 'NO']),
('AUTOSEEL', 'NO', ['YES', 'NO']),
#('AUTOSPC', 'NO', ['YES', 'NO']), # varies by solution
('AUTOSPCR', 'NO', ['YES', 'NO']),
('AUTOSPRT', 'YES', ['YES', 'NO']),
# B
('BAILOUT', 0),
('BETA', (1./3., 0.)),
('BIGER', 0.),
('BIGER1', 0.),
('BIGER2', 0.),
('BOLTFACT', 1.E7),
('BSHDAMP', 'DIFF', ['SAME', 'DIFF']),
('BUCKLE', -1),
# C
('CA1', (1., 0.)),
('CA2', (1., 0.)),
('CB1', (1., 0.)),
('CB2', (1., 0.)),
('CDIF', 'YES', ['YES', 'NO']),
('CDITER', 0),
('CDPCH', 'NO', ['YES', 'NO']),
('CDPRT', 'YES', ['YES', 'NO']),
('CHECKOUT', 'NO', ['YES', 'NO']),
('CK1', (1., 0.)),
('CK2', (1., 0.)),
('CK3', (1., 0.)),
('CK41', (1., 0.)),
('CK42', (1., 0.)),
('CLOSE', 1.),
('CM1', (1., 0.)),
('CM2', (1., 0.)),
# CNSTRT
('CNTASET', 'NO', ['YES', 'NO']),
('COLPHEXA', 'NO', ['YES', 'NO']),
#('COMPMATT', 'NO', ['YES', 'NO', 'NONSMEAR']), # MSC only: 'NONSMEAR'
('CONFAC', 1E-5),
('CORROPT', 'NO', ['YES', 'NO']),
('COUPMASS', -1),
('CP1', (1., 0.)),
('CP2', (1., 0.)),
('CURV', -1),
('CURVPLOT', -1),
# D
#('DBALL', 'DBAL', ['DBAL']),
#('DBCCONV', 'XL', ['XL']),
('DBCDIAG', 0),
('DBCOVWRT', 'YES', ['YES', 'NO']),
('DBDICT', -1),
#('DBDN', 'DBAL', ['DBAL']),
('DBDRPRJ', 0),
('DBDRVER', 0),
#('DBRCV', 'DBAL', ['DBAL']),
#('DBUP', 'DBAL', ['DBAL']),
('DDRMM', 0),
('DESPCH', 0),
('DESPCH1', 6),
('DFREQ', 1E-5),
('DIGITS', 15),
('DOF123', 0, [0, 1]),
('DOPT', 0),
('DPEPS', 1E-4),
('DPREONLY', 'NO', ['YES', 'NO']),
('DSNOKD', 0.),
('DSZERO', 0.),
('DYNSPCF', 'NEW', ['NEW', 'OLD']),
# E
('ELITASPC', 'NO', ['YES', 'NO']),
('EPPRT', 1E-8),
('EPZERO', 1E-8),
('ERROR', -1),
('EST', 2),
('EXTBEMI', 0, [0, 1]),
('EXTBEMO', 0, [0, 1]),
('EXTDR', 'NO', ['YES', 'NO']), # missing values?
('EXTDROUT', 'NO', ['NO', 'MATRIXDB', 'DMIGDB', 'DMIGOP2']), # missing values?
('EXTDRUNT', 31),
('EXTOUT', 'NO', ['NO', 'MATRIXDB', 'DMIGDB', 'DMIGOP2', 'DMIGPCH']),
('EXTRCV', 0),
('EXTUNIT', 30),
# F
('F56', 'NO', ['YES', 'NO']),
('FACTOR', 10000),
('FCTC1', 1.), ('FCTC2', 1.), ('FCTC3', 1.), ('FCTC4', 1.), ('FCTC5', 1.),
('FCTM1', 1.), ('FCTM2', 1.), ('FCTM3', 1.), ('FCTM4', 1.), ('FCTM5', 1.),
('FCTZ1', 1.), ('FCTZ2', 1.), ('FCTZ3', 1.), ('FCTZ4', 1.), ('FCTZ5', 1.),
('FIXEDB', 0, [-2, -1, 0, 1]),
('FKSYMFAC', 1.),
('FLEXINCR', 'NO', ['YES', 'NO']),
('FLUIDMP', 0),
('FLUIDSE', 0),
('FOLLOWK', 'YES', ['YES', 'NO']),
('FRQDEPO', 'NO', ['YES', 'NO']),
('FRRU', 'YES', ['YES', 'NO']),
('FRUMIN', 500),
('FZERO', 1E-3),
# G
('G', 0.),
('GFL', 0.),
# ('Gi')
('GDAMPF', 'YES', ['YES', 'NO']),
('GEOMU', 40),
('GPECT', -1, [-1, 1]),
('GRDPNT', -1),
('GUSTAERO', 1, [1, -1]),
# H
('HEATSTAT', 'NO', ['YES', 'NO']),
('HFREQ', 1E30),
('HFREQFL', 1E30),
# I
#('IFP', '')
('IFTM', 0, [0, 1, 2]),
('INEMETH', 1, [0, 1]),
('INP4FMT', 32, [32, 64]),
('INREL', 0, [-2, -1, 0]),
('INRELM', 0, [0, -1]),
('IRES', -1, [1, -1]),
('ITAPE', -1),
# K
('K6ROT', 100.),
('KDAMP', 1, [-1, 1]),
('KDAMPFL', 1, [-1, 1]),
('KDIAG', -1.0),
('KGGCPCH', 0, [0, 1]),
('KGGLPCH', 0, [0, 1]),
('OUGCORD', '', ['', 'GLOBAL', 'BASIC']),
('UNITSYS', '', unit_systems),
# L
)
string_params = {}
int_params = {}
int_params_allowed = {}
float_params = {}
float2_params = {}
for param in PARAMS:
key = param[0]
value = param[1]
nparam = len(param)
if isinstance(value, str):
allowed = param[2]
string_params[key] = (value, allowed)
elif isinstance(value, int):
if nparam == 2:
int_params[key] = value
else: # 3
allowed = param[2]
int_params_allowed[key] = (value, allowed)
elif isinstance(value, float):
float_params[key] = value
else: # two values
nvalues = len(value)
assert nvalues == 2, param
if isinstance(value[0], float):
float2_params[key] = value
else:
raise RuntimeError(param)
del allowed
STR_WORDS_1 = {
'POSTEXT', 'PRTMAXIM', 'AUTOSPC', 'OGEOM', 'PRGPST',
'RESVEC', 'RESVINER', 'OGPS', 'OIBULK', 'OMACHPR',
'UNITSYS', 'F56', 'OUGCORD', 'OGEM', 'EXTSEOUT',
'AUTOSPC', 'CDIF', 'EXTDROUT', 'OGEOM', 'OMID', 'PRTMAXIM', 'PRGPST',
'POSTEXT', 'RESVEC', 'SUPAERO', 'SHLDAMP', 'ZROCMAS',
'ALTRED', 'RSCON', 'RESVINER', 'MESH', 'SKINOUT', 'VUPENTA',
'DYNSEN', 'PRTGPL', 'PRTEQXIN', 'PRTGPDT', 'PRTCSTM', 'PRTBGPDT', 'PRTGPTT',
'PRTMGG', 'PRTPG', 'FOLLOWK', 'DBCCONV', 'COMPMATT', 'ADB', 'HEATSTAT',
'AUTOSPCR', 'CHECKOUT', 'EPSILONT', 'RMS', 'RESPATH', 'AUTOMSET', 'COMPMATT',
'F56', 'METHFL', 'DMIGNRG', 'METHT', 'AEDB', 'SAVEOFP', 'DBDN', 'DBCONV',
'ASCOUP', 'DBUP', 'VUHEXA', 'FLEXINCR', 'SRCOMPS', 'VUTETRA', 'DYNSPCF',
'SRCOMPS', 'SERST', 'PGRPST', 'CDPRT', 'CFDIAGP', 'CWDIAGP', 'ENFMOTN', 'RMSINT',
'DEBUG', 'CHKOUT', 'DBALL', 'OIBULK', 'RMXTRAN', 'CDPCH', 'AUTOADJ', 'SEMAP',
'SOFTEXIT', 'SM', 'RESFLEX', 'SENSUOO', 'OGEM', 'XBYMODE', 'STRESS', 'OPTION',
'AOTOSPC', 'ARBMAS', 'ARBMSS', 'OMACHPR', 'AUTOMPC', 'BSHDAMP', 'ASCII4',
'SPCSTR', 'AUTOSPRT', 'PBRPROP', 'ELITASPC', 'SECOMB', 'CNTASET', 'WMODAL',
'RESVALT', 'PRTRESLT', 'ITFPRNT', 'AMLS', 'PRGPOST', 'SDAMPUP', 'COLPHEXA',
'ELEMITER', 'ROTSYNC', 'MECHFIX', 'CTYPE', 'SESDAMP', 'SYNCDAMP',
}
INT_WORDS_1 = {
'ACTH', 'ADMPOST', 'ALPHA', 'ALTSHAPE', 'AMGOK', 'APPEN', 'AROWS',
'ASING', 'BAILOUT', 'BAND', 'BUCKLE', 'CDITER', 'CHKMASS',
'CHKSTIF', 'CNSTRT', 'COMPARE', 'COUPMASS', 'CURV', 'CURVPLOT',
'CYCIO', 'CYCSEQ', 'DBCDIAG', 'DBCLEAN', 'DBDICT', 'DBDRNL',
'DBDRNL', 'DBDROPT', 'DBNBLKS', 'DBRNL', 'DBSORT', 'DCOMP',
'DDRMM', 'DEBUGPRT', 'DESPCH', 'DESPCH1', 'DESPCHL', 'DIA600',
'DLOAD', 'DPHFLG', 'DRMH', 'DUMMY', 'DYENDTIM', 'DYLDKND',
'DYMATS1', 'DYNAMES', 'EFWGT', 'EIGVECDS', 'EIGVECDS', 'ERROR',
'EST', 'EXTBEMI', 'EXTBEMO', 'FIXEDB', 'FLUIDMP', 'FLUIDSE',
'FLYLOAD', 'GEOMPLT', 'GEOMU', 'GPECT', 'GPFORCE', 'GPWG', 'GRDEQ',
'GRDPNT', 'GUSTAERO', 'GYROAVG', 'GYROFATL', 'I', 'I', 'IEXT',
'IFTM', 'IFTM', 'INFILE', 'INREL', 'INRLM', 'INT1', 'INT2', 'INT3',
'INT4', 'IPAD', 'IPU', 'IRES', 'ITSMAX', 'IUNIT4', 'J', 'KDAMP',
'KDAMPFL', 'KEPRT', 'KGGCPCH', 'LAMA', 'LANGLE', 'LGDIS', 'LGDISP',
'LGSTRN', 'LMODES', 'LMODESFL', 'LOADU', 'LOOPID', 'LSTRN',
'MAKEMAT', 'MARCASUM', 'MARCAUCU', 'MARCAUDM', 'MARCAUNW',
'MARCAUST', 'MARCAUTN', 'MARCAUTO', 'MARCAUTR', 'MARCCENT',
'MARCEKND', 'MARCGAUS', 'MARCNMPC', 'MARCONLY', 'MARCOPT',
'MARCPOS', 'MARCPOST', 'MARCPRN', 'MARCPTH', 'MARCRBE2', 'MARCRBE3',
'MARCREVR', 'MARCRIGD', 'MARCRUN', 'MARCSETT', 'MARCSINC',
'MARCSLHT', 'MARCSUMY', 'MARCT19', 'MARCTABL', 'MARCTNSF',
'MARCTNSF', 'MARCTOL', 'MARCVERS', 'MATFILE', 'MATNL', 'MAXIT',
'MAXITER', 'MAXLINES', 'MESHG', 'METHCMRS', 'MODACC', 'MODTRK',
'MPCX', 'MPTDUMP', 'MRALIAS', 'MRFOLOW1', 'MRFOLOW3', 'MRFOLOW4',
'MRORINTS', 'MROUTLAY', 'MRTIMING', 'NASPRT', 'NBRUPT', 'NEWSEQ',
'NEWSET', 'NLAYERS', 'NLDISP', 'NLPACK', 'NLTOL', 'NMLOOP', 'NOAP',
'NOBAND', 'NOCOMP', 'NOCOMPS', 'NODATA', 'NOELOF', 'NOELOP',
'NOFISR', 'NOGPF', 'NOINT', 'NONCUP', 'NOPRT', 'NOREAL', 'NQSET',
'NT', 'NTOL', 'NUMOUT', 'NUMOUT1', 'OCORD', 'OELMSET', 'OGRAV',
'OGRDOPT', 'OGRDSET', 'OLDSEQ', 'OMAXR', 'OMSGLVL', 'OP2FMT',
'OPCHSET', 'OPGTKG', 'OPPHIPA', 'OPTEXIT', 'ORDER', 'ORIGID',
'OSWELM', 'OSWPPT', 'OSWPTT', 'OUNIT2', 'OUNIT2M', 'P1', 'PANELMP',
'PARAM', 'PARTFAC', 'PDRMSG', 'PEDGEP', 'PH2OUT', 'PIVOT', 'PLTMSG',
'PNCHDB', 'PNCHDB', 'POSTU', 'PROUT', 'PVALDR', 'PVALINIT', 'QRES',
'R', 'RANREAL', 'RBMODES', 'RFORCE', 'RMXCRT', 'RMXTRN', 'ROTCSV',
'ROTGPF', 'RSOPT', 'RSPECTRA', 'S1', 'S1A', 'S1AG', 'S1AM', 'S1G',
'S1M', 'SCRSPEC', 'SELOCAL', 'SEMAPPRT', 'SEOP2CV', 'SEP1XOVR',
'SEQOUT', 'SESEF', 'SIGNB', 'SIZE', 'SMALL', 'SNORMPRT', 'SOLADJC',
'STRUCTMP', 'SUBID', 'SUBSKP', 'SUPER', 'TDAMP', 'TEMPMATE',
'TESTNEG', 'TESTNO', 'TORSIN', 'TSTATIC', 'UNUSED', 'USETPRT',
'USETSEL', 'VMOPT', 'XFLAG', 'XYUNIT', 'OPPHIB',
}
FLOAT_PARAMS = {
'AUNITS', 'CHIMERA', 'EPSHT', 'EPPRT', 'G', 'GFL', 'K6ROT', 'MAXRATIO',
'PATVER', 'PRPHIVZ', 'SIGMA', 'SNORM', 'TABS', 'TINY', 'W3', 'W4', 'WTMASS',
'HFREQ', 'CONFAC', 'VREF', 'CFRANDEL', 'DSNOKD', 'DFREQ', 'TESTSE', # 'TESTNEG',
'KDIAG', 'NDAMP', 'M', 'Q', 'TABST', 'TOLRSC', 'DPEPS', 'PREFDB', 'MACH',
'LFREQ', 'EPZER0', 'W4FL', 'MARCAUT0', 'DSZERO', 'BETAXX', 'STIME',
'CWRANDEL', 'MARCAUTT', 'AMORT', 'SEAU', 'TOLLRSC', 'EXTRCV', 'PRPA', 'LFREQFL',
'MARCAUTS', 'MARCFRIC', 'SOFFSET', 'LMFACT', 'PENFN', 'CLOSE', 'BIGER', 'WR3',
'HFREQFL', 'EPZERO', 'PRPJ', 'FRIC', 'LAMBDAS', 'MARCSCL', 'MARCAUTB',
'PATVERS', 'RPM', 'W3FL', 'ROTOMRF', 'MARCAUTM', 'TOL', 'MXLAGM1', 'MARCTVL',
'BETA', 'FKSYMFAC', 'BOLTFACT', 'ROTCMRF', 'LMSCAL', 'RESVRAT', 'SMALLQ',
'LAMLIM', 'MARCAUTX', 'MARCRSCL', 'BIGER1', 'DYCOWPRD', 'DYDTOUT', 'FZERO',
'BIGER2', 'DYCOWPRP', 'MTRFMAX', 'REAL1', 'REAL2', 'REAL3',
}
FLOAT2_PARAMS = {'BETA1', 'CA1', 'CA2'}
STR_WORDS_1.update(set(string_params.keys()))
INT_WORDS_1.update(set(int_params.keys()))
FLOAT_PARAMS.update(set(float_params.keys()))
FLOAT2_PARAMS.update(set(float2_params.keys()))
INT_STR_WORDS_1 = INT_WORDS_1 | STR_WORDS_1
[docs]
class PARAM(BaseCard):
type = 'PARAM'
_field_map = {1: 'key'}
def _update_field_helper(self, n: int, value) -> None:
if n - 2 >= 0:
try:
self.values[n - 2] = value
except IndexError:
msg = 'Field %r=%r is an invalid %s entry for key=%r.' % (
n, value, self.type, self.key.upper())
raise IndexError(msg)
else:
raise KeyError('Field %r=%r is an invalid %s entry.' % (n, value, self.type))
[docs]
@classmethod
def _init_from_empty(cls):
key = 'POST'
values = -1
return PARAM(key, values, comment='')
def __init__(self, key: str, values, comment: str=''):
"""
Creates a PARAM card
Parameters
----------
key : str
the name of the PARAM
values : int/float/str/list
varies depending on the type of PARAM
comment : str; default=''
a comment for the card
"""
if comment:
self.comment = comment
self.key = key
if isinstance(values, list):
pass
elif isinstance(values, (integer_types, float_types, str)):
values = [values]
self.values = values
if isinstance(self.values, tuple) or isinstance(self.values[0], (list, tuple)):
raise TypeError((key, self.values))
#assert not isinstance(values, tuple), values
#if isinstance(values, list):
#assert not isinstance(values[0], tuple), values
[docs]
@classmethod
def add_card(cls, card: BDFCard, comment: str=''):
"""
Adds a PARAM card from ``BDF.add_card(...)``
Parameters
----------
card : BDFCard()
a BDFCard object
comment : str; default=''
a comment for the card
"""
key = string(card, 1, 'key')
n = 1
value = None
if key == 'ACOUT':
value = string_or_blank(card, 2, 'value', default='PEAK')
elif key == 'ACOWEAK':
value = string_or_blank(card, 2, 'value', default='NO')
elif key == 'ADJMETH':
value = integer_or_blank(card, 2, 'value', default=0)
elif key == 'ADPCON':
value = double_or_blank(card, 2, 'value', default=1.0)
#elif key == 'ADMPOST':
#value = string_or_blank(card, 2, 'value', default=0) ## TODO: 0 is not a string
elif key == 'ADSDISC':
value = double_or_blank(card, 2, 'value', default=1e-8)
elif key == 'AESMAXIT':
value = integer_or_blank(card, 2, 'value', default=15)
elif key == 'AESMETH':
value = string_or_blank(card, 2, 'value', 'SELECT')
assert value in ['SELECT', 'AUTO', 'DIRECT', 'RITZ', 'ITER'], 'value=%s' % value
elif key == 'AESTOL':
value = double_or_blank(card, 2, 'value', default=1e-10)
elif key in ['ALPHA1FL', 'ALPHA2FL']: # check alpha1/alpha1FL
value1 = double_or_blank(card, 2, 'value1', default=0.0)
value2 = double_or_blank(card, 3, 'value2', default=0.0)
n = 2
elif key == 'COMPMATT':
#('COMPMATT', 'NO', ['YES', 'NO', 'NONSMEAR']), # MSC only: 'NONSMEAR'
value = string_or_blank(card, 2, 'value1', 'NO')
if value == 'NONS': # assume
value = 'NONSMEAR'
if value in {'SMEAR', 'SMEARED'}: # assume
value = 'YES'
assert value in {'YES', 'NO', 'NONSMEAR'}, 'value=%r' % value
elif key == 'LIMITER':
value1 = string_or_blank(card, 2, 'value', default='ROE')
value2 = blank(card, 3, 'blank', default=None)
if value1 in 'ROE-SCHEME':
value1 = 'ROE'
elif key == 'POST':
value = integer_or_blank(card, 2, 'value', default=1)
elif key == 'UNITSYS':
value = string_or_blank(card, 2, 'value', default='')
elif key == 'MDOF':
# NX - integer
# MSC - string
value = integer_string_or_blank(card, 2, 'value', default=None)
#-------------------------------------------------------------
# strings; has defaults
elif key in string_params:
default, allowed_values = string_params[key]
value = string_or_blank(card, 2, 'value', default=default)
assert value in allowed_values, f'value={value} allowed={allowed_values}'
# ints; has defaults
elif key in int_params:
default=int_params[key]
value = integer_or_blank(card, 2, 'value', default=default)
elif key in int_params_allowed:
default, allowed_values = int_params_allowed[key]
value = integer_or_blank(card, 2, 'value', default=default)
assert value in allowed_values, f'value={value} allowed={allowed_values}'
# floats; has defaults
elif key in float_params:
default=float_params[key]
value = double_or_blank(card, 2, 'value', default=default)
elif key in float2_params:
defaults = float2_params[key]
value = double_or_blank(card, 2, 'value', default=defaults[0])
value = double_or_blank(card, 2, 'value', default=defaults[1])
n = 2
# unchecked catch all
elif key in STR_WORDS_1:
value = string(card, 2, 'value')
elif key in INT_WORDS_1:
value = integer(card, 2, 'value')
elif key in FLOAT_PARAMS:
value = double(card, 2, 'value')
elif key in FLOAT2_PARAMS:
value1 = double(card, 2, 'value1')
value2 = double(card, 3, 'value2')
values = [value1, value2]
n = 2
#-------------------------------------------------------------
else:
#raise NotImplementedError(card)
n = 2
value1 = integer_double_string_or_blank(card, 2, 'value1')
value2 = integer_double_string_or_blank(card, 3, 'value2')
if value2 is None:
value = value1
n = 1
if value is None:
# n=2 or blank
if isinstance(value1, str):
assert ' ' not in value1, f'PARAM value1={value1!r}'
if isinstance(value2, str):
assert ' ' not in value2, f'PARAM value2={value2!r}'
values = [value1, value2]
else:
# n=1
if isinstance(value, str):
assert ' ' not in value, f'PARAM value={value!r}'
values = [value]
if n == 1:
assert len(card) <= 3, f'len(PARAM card)={len(card):d} card={card!r}'
else:
assert len(card) <= 4, f'len(PARAM card)={len(card):d} card={card!r}'
return PARAM(key, values, comment=comment)
[docs]
def update_values(self, value1=None, value2=None):
"""
Updates value1 and value2. Performs type checking based on the PARAM
type after setting any default value(s).
Parameters
----------
value1 : varies; default=None
the main value
value2 : varies; default=None
optional value
If you want to access the data directly, use:
>>> param = bdf.params['POST']
>>> param.values[0] = -1 # value1
>>> param.values[1] = 3 # value2
>>>
.. note:: Most PARAM cards only have one value. Some have two.
"""
if self.key == 'ACOUT':
if value1 is None:
value1 = 'PEAK'
if not isinstance(value1, str):
msg = f'key={self.key} value1={value1!r} must be a string.'
raise TypeError(msg)
elif self.key == 'ACOWEAK':
if value1 is None:
value1 = 'NO'
if not isinstance(value1, str):
msg = f'key={self.key} value1={value1!r} must be a string.'
raise TypeError(msg)
elif self.key == 'ACSYM':
if value1 is None:
value1 = 'YES'
if not isinstance(value1, str):
msg = f'key={self.key} value1={value1!r} must be a string.'
raise TypeError(msg)
elif self.key == 'ADJMETH':
if value1 is None:
value1 = 0
if not isinstance(value1, int):
msg = f'key={self.key} value1={value1!r} must be an integer.'
raise TypeError(msg)
#elif self.key == 'ADMPOST': ## TODO: 0 is not a string
#value = string_or_blank(card, 2, 'value', 0)
elif self.key == 'ADSTAT':
if value1 is None:
value1 = 'YES'
if not isinstance(value1, str):
msg = f'key={self.key} value1={value1!r} must be a string.'
raise TypeError(msg)
elif self.key in ['ALPHA1', 'ALPHA2', 'ALPHA1FL', 'ALPHA2FL']:
if value1 is None:
value1 = 0.0
if value2 is None:
value2 = 0.0
if not isinstance(value1, float):
msg = f'key={self.key} value1={value1!r} must be a float.'
raise TypeError(msg)
if isinstance(value2, float):
msg = f'key={self.key} value2={value2!r} must be a float.'
raise TypeError(msg)
elif self.key in ['CB1', 'CB2', 'CK1', 'CK2', 'CK3', 'CM1', 'CM2', 'CP1', 'CP2']:
if value1 is None:
value1 = 1.0
if value2 is None:
value2 = 0.0
if not isinstance(value1, float):
msg = f'key={self.key} value1={value1!r} must be a float.'
raise TypeError(msg)
if isinstance(value2, float):
msg = f'key={self.key} value2={value2!r} must be a float.'
raise TypeError(msg)
else:
if not isinstance(value1, (int, float, str)):
msg = f'key={self.key} value1={value1!r} must be an integer, float, or string.'
raise TypeError(msg)
self.values = [value1]
if value2 is not None:
self.values.append(value2)
[docs]
def raw_fields(self):
list_fields = ['PARAM', self.key] + self.values
return list_fields
[docs]
def repr_fields(self):
return self.raw_fields()
[docs]
def write_card(self, size: int=8, is_double: bool=False) -> str:
card = self.raw_fields()
if isinstance(self.values[0], int) and self.values[0] > MAX_INT:
return self.comment + print_card_16(['PARAM', self.key, self.values[0]])
if self.key in INT_STR_WORDS_1:
return '%sPARAM %8s%8s\n' % (
self.comment, self.key, self.values[0])
if size == 8 or self.key in SMALL_FIELD_PARAMS:
return self.comment + print_card_8(card)
return self.comment + print_card_16(card)
[docs]
class PARAM_NASA95(BaseCard):
[docs]
@classmethod
def _init_from_empty(cls):
key = 'POST'
values = -1
return PARAM_NASA95(key, values, comment='')
def __init__(self, key, values, comment=''):
"""
Creates a PARAM card
Parameters
----------
key : str
the name of the PARAM
values : int/float/str/list
varies depending on the type of PARAM
comment : str; default=''
a comment for the card
"""
if comment:
self.comment = comment
self.key = key
if isinstance(values, (int, float, str)):
values = [values]
self.values = values
[docs]
@classmethod
def add_card(cls, card, comment=''):
"""
Adds a PARAM card from ``BDF.add_card(...)``
Parameters
----------
card : BDFCard()
a BDFCard object
comment : str; default=''
a comment for the card
"""
key = string(card, 1, 'key')
if key == 'AUTOSPC':
values = [
integer_or_blank(card, 2, 'value', 0)
]
elif key == 'BETA':
values = [
double_or_blank(card, 2, 'value', 0.55)
]
elif key == 'BETAD':
values = [
integer_or_blank(card, 2, 'value', 4)
]
elif key == 'COUPMASS':
values = [
integer_or_blank(card, 2, 'value', 1)
]
# CTYPE
elif key == 'CYCIO':
values = [
integer_or_blank(card, 2, 'value', 1)
]
elif key == 'CYCSEQ':
values = [
integer_or_blank(card, 2, 'value', -1)
]
elif key == 'EPSHT':
values = [
double_or_blank(card, 2, 'value', 0.001)
]
elif key == 'ESPIO':
values = [
double_or_blank(card, 2, 'value', 1e-5)
]
elif key == 'G':
values = [
double(card, 2, 'G')
]
else:
ifield = 2
# x
#[PARAM, AUTOSPC, 2]
values = []
while ifield < len(card):
value = integer_double_string_or_blank(card, ifield, 'field_{i}')
values.append(value)
ifield += 1
return PARAM_NASA95(key, values, comment=comment)
[docs]
def raw_fields(self):
list_fields = ['PARAM', self.key] + self.values
return list_fields
[docs]
def repr_fields(self):
return self.raw_fields()
[docs]
def write_card(self, size: int=8, is_double: bool=False) -> str:
card = self.raw_fields()
if size == 8:
return self.comment + print_card_8(card)
return self.comment + print_card_16(card)
[docs]
class PARAM_MYSTRAN(BaseCard):
"""
Parameter Name DataType Function of Parameter
ARP_TOL; real; Default=1x10^-6
Tolerance to use in Lanczos eigenvalue extraction method for convergence
ART_KED
(for diff stiffness – not fully implemented)
char; field 3: ART_KED, default=N. If Y add artificial stiff to diag of KED stiff matrix
char; field 4: ART_TRAN_MASS: value for translation degrees of freedom, default 1x10^-6
char; field 5: ART_ROT_MASS: value for translation degrees of freedom, default 1x10^-6
ART_MASS
char; field 3: ART_MASS, default=N. If Y add artificial mass to diag of MGG mass matrix
real; Field 4: ART_TRAN_MASS: value for translation degrees of freedom, default 1x10^-6
real; Field 5: ART_ROT_MASS: value for translation degrees of freedom, default 1x10^-6
AUTOSPC
['PARAM', 'AUTOSPC', 'Y', '1.0E-9', None, 'Y', 'Y']
Char Field 3: AUTOSPC value, default=Y (AUTOSPC), N turns AUTOSPC off.
Real Field 4: AUTOSPC_RAT, default=1x10^-6 (see Section 3.4.1.1)
Int Field 5: AUTOSPC_NSET, default=1 (see Section 3.4.1.1)
Char Field 6: AUTOSPC_INFO, default=N. If Y then print messages about the AUTOSPC's
Char Field 7: AUTOSPC_SPCF, default=N. If Y print AUTOSPC forces of constraint
BAILOUT Int; Default=1
If > 0 quit if a singularity in decomposing a matrix is detected.
If <= 0 do not quit
CBMIN3 Real; Default=2.0
The constant CB used in tuning the shear correction factor in
Ref 3 for the TRIA3 plate element.
CBMIN4 real; default=3.6
The constant CB used in tuning the shear correction factor in
Ref 4 for the QUAD4 plate element (QUAD4TYP='MIN4'). See Ref 4
CBMIN4T real; default=3.6
The constant CB used in tuning the shear correction factor in
Ref 4 for the QUAD4 plate element (QUAD4TYP='MIN4T').
CHKGRDS
char; default=Y.
If N do not check that all grids for all elements exist
CUSERIN
char; If this parameter is present, Bulk Data entries for Craig-Bampton (CB)
reduced models will be written to the F06 file as a CUSERIN element
(including grids, coordinate systems, etc)
int; field 3: element ID, default=9999999
int; field 4: property ID, default=9999999
int; field 5: starting index for the SPOINT's to represent modes of the CB model, default=1001
int; field 6: IN4 file number that goes on the PUSERIN entry for this CUSERIN element, default=9999999
char; field 7: Set-ID for the CUSERIN element (typically the 'R', or boundary, set), default is blank field
int; field 8: Format for how to write the component numbers
(1 thru 6) for each grid of the CUSERIN element.
If 0, write them in compact form (e.g. 1356). If > 0
write them in expanded form (1 3 56), default=0
DARPACK int; default=2
how many extra modes to find above EIG_N2 on the EIGRL entry.
These few highest mode are not used due to difficulty with
getting good GP force balance.
EIGESTL int; default=5000
For eigenvalue problems by the Lanczos method, if the number of
L-set DOF's exceed EIGESTL the method for specifying the search
range will be changed from F1 to F2 to N (see EIGRL Bulk Data
entry) to avoid excessive run times (since the code to estimate
the number of eigens in the F1 to F2 range can be excessive).
EIGNORM2 char; default=N
If 'Y' then eigenvectors will be renormalized a last time by
multiplying by a set of scale factors (1 per eigenvector)
supplied in a file with the same name as the input file and
extension 'EIN' (if it exists)
ELFORCEN; char; default=GLOBAL
If and nodal forces have been requested in Case Control and:
ELFORCEN=GLOBAL, they will be output in the global coordinate system.
ELFORCEN=BASIC, they will be output in the basic coordinate systeml.
ELFORCEN=LOCAL, they will be output in the local element coordinate system.
EPSERR char; default=Y.
If N, do not calculate the NASTRAN like 'epsilon error estimate'
EPSIL Real
There are 3 EPSIL(i) values each of which requires a separate
PAPAM EPSIL Bulk Data entry with the index (i) in field 3 and
EPSIL(i) value in field 4. These are small numbers used in
MYSTRAN for the purposes indicated below:
1) EPSIL(1) (default=1x10^-15) is used in MYSTRAN such that, in
any real number comparisons, any real number whose
absolute magnitude is less than EPSIL(1) is
considered to be zero. If no PARAM EPSIL 1 entry is
in the data file then this value is reset (from the
default) in LINK1 to a value based on machine
precision calculated using LAPACK BLAS function
DLAMCH. If the user has a PARAM EPSIL 1 entry, this
value will be used for EPSIL(1) instead of the
LAPACK machine precision.
2) Currently not used
3) EPSIL(3) is used in the Inv erse Power method of eigenvalue
extraction to test convergence of an eigenvalue. The
default value (% change) is 1x10^-5 %
4) EPSIL(4) is used to calculate the maximum warp for quadrilateral
plate elements, above which a warning message will be
written. This maximum warp is EPSIL(2) times the
average length of the quadrilateral's two diagonals.
The default for EPSIL(2) is 1.x10^-1.
5) EPSIL(5) (default 1.x10^-6) is used in BAR and ROD margin of
safety calculations. If a stress magnitude is less
than EPSIL(5) a 1.x10^10 margin of safety will
printed out for that stress (in other words, an
infinite margin of safety)
6) EPSIL(6) (default 1.x10^-15) is used in BAR margin of safety calculations
EQCHECK
int; field 3: default=0 (basic origin) or reference grid to use
in calculating the rigid body displacement matrix
for the equilibrium check
int; field 4: If nonzero, do equilibrium check on the G-set
int; field 5: If nonzero, do equilibrium check on the N-set
int; field 6: If nonzero, do equilibrium check on the F-set
int; field 7: If nonzero, do equilibrium check on the A-set
int; field 8: If nonzero, do equilibrium check on the L-set
real; field 9: EQCHK_TINY, default=1x10^-5. I Do not print grid forces smaller than this
char; field 10: default=N. If Y, normalize the grid forces on diagonal stiffness
The value in fields 4-8 can be:
1: print loads due to rigid body displacements
2: print strain energy due to rigid body displacements
3: print both
GRDPNT Int default=-1.
If not -1 then the value is interpreted as a grid number
If GRDPNT != 0, calculate total mass properties of the model
relative to the basic coordinate system origin or relative
to the specified grid.
GRIDSEQ
char; field 3: GRIDSEQ value (default=BANDIT). Other values are
GRID and INPUT. BANDIT is automatic grid sequencing.
GRID is sequencing in grid ID numerical order.
INPUT is sequencing in the grid input order.
char; field 4: SEQQUIT, default=N. If Y, then quit in the sequence
processor if BANDIT did not run correctly.
char; field 5: SEQPRT, default=N. If Y, print SEQGP card images
generated by BANDIT to the F06 output file
HEXAXIS; Char
'SIDE12', use side 1-2 as the local elem x axis.
'SPLITD' (default), use angle that splits the 2 diags to define the elem x axis
IORQ1M; Int; default=2
Gaussian integration order for membrane direct stress terms for
the QUAD4, QUAD4K quadrilateral elements
IORQ1S; Int; default=1
Gaussian integration order for membrane shear stress terms for all quad elements
IORQ1B; Int; default=2
Gaussian integration order for bending stress terms for the QUAD4K element
IORQ2B; Int; default=2
Gaussian integration order for bending stress terms for the QUAD4 element
IORQ2T; Int; default=3
Gaussian integration order for transverse shear stress terms for the QUAD4 element
ITMAX; Int; default=5
Max number of iterations in refining the solution when parameter UREFINE=Y
KLLRAT; Char; default=Y
to tell whether to calc ratio of max/min KLL diagonal terms
KOORAT; Char; default=Y
to tell whether to calc ratio of max/min KOO diagonal terms
LANCMETH; Char
Procedure to use for Lanczos eigenvalue extraction (ARPACK or TRLan)
MATSPARS; Char
If=Y (default), use sparse matrix routines for add/multiply in all matrix operations.
If N, use full matrix add/multiply (not recommended)
MAXRATIO; Real; Default=1X10^7
Max value of matrix diagonal to factor diagonal before messages
are written and BAILOUT tested for aborting run
MEFMCORD; Int; default=0
The coordinate system in which to calculate modal mass and participation factors
MEFMLOC; Char
Reference location for calculating modal effective mass in Craig-Bampton (SOL 31) analyses.
This only affects the rotational modal effective masses.
Field 3 can be GRDPNT, GRID or CG:
If field 3=GRDPNT (default): ref point is the same as the one for PARAM GRDPNT
If field 3=CG: use the model center of gravity as the reference point
If field 3=GRID: use the grid point number in field 4 as the reference point
Field 4: MEFMGRID (grid to use when field 3 is GRID)
MEMAFAC; Int; default=0.9
Factor to multiply the size request of memory to be allocated when
looping to find an allowable amount of memory to allocate. Used
when the initial request for memory (in subrs ESP or EMP) cannot
be met and we know that the request is conservative.
MIN4TRED; Char; default=STC
Defines the method for how the 5th node of the MIN4T element is
reduced out (to get a 4 node quad element). STC (default) is static
condensation. B%$ (not implemented as of Version 3.0) uses a method
developed by the element author (see Users Reference manual)
MKLFACij; Char; default=INDEF
Matrix type for use in decomposing matrices in various subroutines
in MYSTRAN when PARAM SOLLIB is IntMKL'
MKLFAC21 is for use in subr REDUCE_KAA_TO_KFF
MKLFAC31 is for use in subr LINK3
MKLFAC41 is for use in subr EIG_INV_PWR
MKLFAC42 is for use in subr EIG_LANCZOS_ARPACK
MKLFAC61 is for use in subr CALC_KRRcb
MKLFAC62 is for use in subr SOLVE_DLR
MKLFAC63 is for use in subr SOLVE_PHIZL1
MKLMATST; Char; default=NONSYM
Matrix structure to use when PARAM SOLLIB=IntMKL.
Values can be NONSYM or SYM
MKLSTATS; char; default=N
If Y write stats on matrix decomposition when PARAM SOLLIB=IntMKL
MPFOUT; char
(1) '6' (default) indicates to output modal participation
factors (MPF) relative to the 6 DOF's at grid MEFMGRID (see PARAM MEFMLOC)
(2) 'R' indicates to output MPF's for all of the R-set DOF's individually
MXALLOCA; int; default=10
Max number of attempts to allow when trying to allocate memory in subroutine ALLOCATE_STF_ARRAYS
MXITERI; int; default=50
Max number of iterations to use in the Inverse Power eigenvalue extraction method
MXITERL; int; default=50
Max number of iterations to use in the Lanczos eigenvalue extraction method
OTMSKIP; int
Number of lines to skip between segments of OTM text file descriptors
PBARLDEC; int; default=5
Number of decimal digits when writing PBAR equivalents for PBARL entry real data
PBARLSHR; char; default=Y
Include K1, K2 for PBAR equiv to PBARL BAR properties
PCHSPC1
char; Field 3: PCHSPC1 value (default=N, do not punch SPC1 card
images for constraints generated by the AUTOSPC
feature, use Y to punch these)
int; Field 4: SPC1SID value (default=9999999, the set ID to put
on the SPC1 card images)
char; Field 5: SPC1QUIT value (default=N, do not stop after SPC's
are punched, or Y to stop processing)
PCMPTSTM
Real; Factor to multiply composite ply thickness for effective shear thickness
PCOMPEQ; int; default=0
Indicator to write equiv PSHELL, MAT2 to F06 for PCOMP's.
If > 0, write the equivalent PSHELL amd MAT2 Bulk Data entries
for the PCOMP. If > 1 also write the data in a format with a
greater number of digits of accuracy.
POST; int
If=-1 then write FEMAP neutral file for post processing of MYSTRAN outputs
PRTBASIC; int
If=1 print grid coordinates in the basic coordinate system
PRTCGLTM; int
If=1 print CB matrix for C.G. LTM loads
PRTCONN; int
If=1, print table of elements connected to each grid
PRTCORD; int
If PRTCORD=1 print coordinate system transformation data
PRTDISP; int
PRTDISP(I), I=1-4 go in fields 3-6 of the PARAM PRTDISP entry
that prints displacement matrices for G, N, F, and/or A-sets:
V1=PRTDISP(1)=1 print UG
V2=PRTDISP(2)=1 or 3 print UN, 2 or 3 print UM
V3=PRTDISP(3)=1 or 3 print UF, 2 or 3 print US
V4=PRTDISP(4)=1 or 3 print UA, 2 or 3 print UO
V5=PRTDISP(5)=1 or 3 print UL, 2 or 3 print UR
PRTDLR; int
If=1, the DLR matrix will be printed
PRTDOF; int
If PRTDOF=1 or 3 print TDOF table, in grid point ID numerical
order, which gives a list of the degree of freedom numbers for
each displacement set (size is number of degrees of freedom x number
of displacement sets).
If PRTDOF=2 or 3 print TDOF table, in degree of freedom numerical
order, which gives a list of the degree of freedom numbers for each
displacement set (size is number of degrees of freedom x number
of displacement sets)
PRTFOR; int
PRTFOR(I), I=1-4 go in fields 3-6 of the PARAM PRTFOR entry that
prints sparse force matrices for G, N, F, and/or A-sets:
V1=PRTFOR(1)=1 print sparse PG
V2=PRTFOR(2)=1 or 3 print sparse PN, 2 or 3 print PM
V3=PRTFOR(3)=1 or 3 print sparse PF, 2 or 3 print PS
V4=PRTFOR(4)=1 or 3 print sparse PA, 2 or 3 print PO
V5=PRTFOR(5)=1 or 3 print sparse PL, 2 or 3 print PR
PRTGMN; int
If PRTGMN=1, print GMN matrix
PRTGOA; int
If PRTGOA=1, print GOA matrix
PRTHMN; int
If=1 print HMN constraint matrix
PRTIFLTM; int
If=1 print CB matrix for Interface Forces LTM
PRTKXX; int
If=1 print CB matrix KXX
PRTMASSD; int
Same as PRTMASS, except only print diagonal terms
PRTMASS; int
PRTMASS(I), I=1-4 go in fields 3-6 of the PARAM PRTMASS entry that
prints sparse mass matrices for G, N, F, and/or A-sets:
V1=PRTMASS(1)=1 print sparse MGG
V2=PRTMASS(2)=1 or 3 print sparse MNN, 2 or 3 print MNM, MMM
V3=PRTMASS(3)=1 or 3 print sparse MFF, 2 or 3 print MFS, MSS
V4=PRTMASS(4)=1 or 3 print sparse MAA, 2 or 3 print MAO, MOO
V5=PRTMASS(5)=1 or 3 print sparse MLL, 2 or 3 print MLR, MRR
PRTMXX; int
If=1 print CB matrix MXX
PRTOU4; int
If > 0 write all OU4 (OUTPUT4) matrices to F06 file
PRTPHIXA; int
If=1 print CB matrix PHIXA
PRTPHIZL; int
If=1 print CB matrix PHIZL
PRTPSET; int
If > 0 print the OUTPUT4 matrix partitioning vector sets
PRTQSYS; int
If=1 print matrix QSYS
PRTRMG; int
If PRTRMG=1 or 3, print constraint matrix RMG
If PRTRMG=2 or 3, print partitions RMN and RMM of constraint matrix RMG
PRTSCP; int;If PRTSCP=1 print data generated in the subcase processor
PRTSTIFD; int
Same as PRTSTIFF, except only print diagonal terms
PRTSTIFF; int; Defaults=0 for PRTSTIFF(I), I=1-4 which go in
fields 3-6 of the PARAM PRTSTIFF entry that prints sparse
stiffness matrices for G, N, F, and/or A-sets:
V1=PRTSTIFF(1)=1 print sparse KGG
V2=PRTSTIFF(2)=1 or 3 print sparse KNN, 2 or 3 print KNM, KMM
V3=PRTSTIFF(3)=1 or 3 print sparse KFF, 2 or 3 print KFS, KSS
V4=PRTSTIFF(4)=1 or 3 print sparse KAA, 2 or 3 print KAO, KOO
V5=PRTSTIFF(5)=1 or 3 print sparse KLL, 2 or 3 print KLR, KRR
PRTTSET; int
If PRTSET=1 print TSET table which gives the character name of
the displacement sets that each degree of freedom belongs to
(size is number of grids x 6)
PRTUO0; int
If=1 print UO0
PRTUSET; int
If > 0 print the user defined set (U1 or U2) definitions
PRTYS; int
If=1 print matrix YS
Q4SURFIT; int; default=6
Polynomial order for the surface fit of QUAD4 stress/strain when
stresses are requested for other than corner locations
QUAD4TYP; char
'MIN4T' ! Which element to use in MYSTRAN as the QUAD4 element
'MIN4T (default)': Use Tessler's MIN4T element made up of 4 MIN3 triangles
'MIN4 ': Use Tessler's MIN4 element
QUADAXIS; char; default='SIDE12'
This determines how the quad element local x axis is defined.
'SIDE12' means that the axis between grids 1 and 2 of the quad define the local x axis.
'SPLITD' means that the axis is defined as the direction that splits the angle between the quad diagonals
RCONDK; char
If RCONDK=Y, then LAPACK calculates the condition number of the A-set stiffness matrix.
This is required if LAPACK error bounds on the A-set displacement solution are desired.
This can require significant solution time.
RELINK3; char
'Y' or 'N' to specify whether to rerun LINK3 and also LINK5 in a restart
SETLKTK
int; Field 3: SETLKTK value. default=0. Method to estimate number of
nonzeros in G-set stiffness matrix so array can be allocated.
(1) If SETLKTK=0, estimate LTERM_KGG based on full element stiffness
matrices unconnected (most conservative but not time consuming).
(2) If SETLKTK=1, estimate LTERM_KGG based on KGG bandwidth.
(3) If SETLKTK=2, estimate LTERM_KGG based on KGG density of nonzero terms
(4) If SETLKTK=3, estimate LTERM_KGG based on actual element stiffness matrices unconnected.
(5) f SETLKTK=4, estimate LTERM_KGG on value input by user in
field 5 of the PARAM SETLKT entry (PARAM USR_LTERM_KGG).
char; field 4: ESP0_PAUSE value (default=N, do not pause after subr
ESP0 to let user input LTERM_KGG, or pause if=Y
int; field 5: User input value of LTERM_KGG
SETLKTM
Same as SETLKTK but for the G-set mass matrix. Only the values
for SETLKTM=1, 3, 4 are available
SHRFXFAC; real; default=1x10^6
Factor used to adjust transverse shear stiffness when user has
indicated zero shear flexibility for shell elements. The shear
stiffness will be reset from infinite (zero flexibility) to
SHRFXFAC times the average of the bending stiffnesses in the 2 planes
SKIPMKGG; char; default=N
'Y', 'N' indicator to say whether to skip calculation of MGG,
KGG in which case MGG, KGG will be read from previously generated,
and saved, files (LINK1L for KGG, LINK1R for MGG)
SOLLIB; char; default=IntMKL
Denotes which library to use for matrix decomposition and equation solution. Options are:
IntMKL: Intel Math Kernel Library (matrices stored in sparse form)
LAPACK (matrices stored in band form)
YaleSMP: (matrices stored in sparse form) – not fully implemented in MYSTRAN
SORT_MAX; int; default=5
Max number of times to run algorithm when sorting arrays before fatal message.
SPARSTOR; char; default=SYM
If SYM, symmetric matrices are stored with only the terms on and above the diagonal.
If NONSYM all terms are stored. SYM requires less disk storage but NONSYM can save
significant time in sparse matrix partitioning and multiply operations.
STR_CID; int; default=-1.
Indicator for the coordinate system to use ID for elem stress, strain and emgineering force output:
-1 is local element coordinate system (default)
0 is basic coordinate system
j (any other integer) is a defined coordinate system for output
SUPINFO; char; default=Y
Indicator of whether some information messages should be suppressed in the F06 output file.
N indicates to suppress
Y indicates to not suppress messages in the file.
SUPWARN; char; default=Y
Indicator of whether warning messages should be suppressed in the F06 output file.
N indicates to suppress, Y indicates to not suppress messages in the file.
THRESHK; real; default=0.1
User defined value for the threshold in deciding whether to
equilibrate the A-set stiffness matrix in LAPACK subroutine
DLAQSB. Default value 0.1, LAPACK suggests
TINY; Real
Do not print matrix values whose absolute value is less than this parameter value
TRLLOHI; int
For TRLan eigen extraction (default=-1) - which end of spectrum to compute:
< 0, the smallest eigenvalues
= 0, whichever converges first
> 0, the largest eigenvalues
TRLMXLAN; int
For TRLan eigen extraction (default=7) - Max num Lanczos basis vectors to be used
(If user enters a Bulk Data PARAM TRLMXLAN then internal parameter
USER_TRLMXLAN is set to 'Y')
TRLMXMV; int
For TRLan eigen extraction (default=-2000) - Max number of
matrix-vector multiplications allowed
TRLREST; int
For TRLan eigen extraction (default=1) - Index of restarting schemes
TRLTOL; real
For TRLan eigen extraction (default=1.4901D-8) - Eigenpair is
declared converged if its residual norm is < tol*||OP||
TRLVERB; int
For TRLan eigen extraction (default=0) - Level of output data written by TRLan
TSTM_DEF; real; default=5/6 = 0.833333
Value for TS/TM on PSHELL Bulk data entry when that field on the
PSHELL is blank
USETSTR; char
Requests output of the internal sequence order for displacement
sets (e.g. G-set, etc). See section 3.6 for a discussion of
displacement sets. In addition to the sets in section 3.7, the
user displacement sets U1 and U2 (see Bulk Data entry USET and
USET1) can also have the internal sort order output to the F06
file. As an example, to obtain a row oriented tabular output
of the internal sort order for the R-set, include the Bulk data entry:
PARAM, USETSTR, R
USR_JCT; int
User supplied value for JCT - used in shell sort subroutines.
If USR_JCT=0, internal values for JCT will be used in the shell sort.
WINAMEM; real; default=2.0 GB
Max memory Windows allows for any array. If it is exceeded, a
message is printed out and execution is aborted. This is used to
avoid a failure which aborts MYSTRAN catastrophically (due to a
system fault).
WTMASS; real; default=1.0
Multiplier for mass matrix after the model total mass is output
in the Grid Point Weight Generator (GPWG). This allows user to
input mass terms as weight to get model mass properties in weight
units and then to convert back to mass units after the GPWG has
run. For example, if the model units are lb-sec2/inch for mass
and inches for length and the input data file has lb for 'mass'
(read weight), then 1/386, or 0.002591 would be the value for
WTMASS needed to convert the 'mass' matrix from weight units to
mass units.
Note
----
Default values of parameters are:
N for Char
0 for Int
0.0 for real
"""
type = 'PARAM'
_field_map = {1: 'key'}
def _update_field_helper(self, n, value):
if n - 2 >= 0:
try:
self.values[n - 2] = value
except IndexError:
msg = 'Field %r=%r is an invalid %s entry for key=%r.' % (
n, value, self.type, self.key.upper())
raise IndexError(msg)
else:
raise KeyError('Field %r=%r is an invalid %s entry.' % (n, value, self.type))
[docs]
@classmethod
def _init_from_empty(cls):
key = 'POST'
values = -1
return PARAM(key, values, comment='')
def __init__(self, key, values, comment=''):
"""
Creates a PARAM card
Parameters
----------
key : str
the name of the PARAM
values : int/float/str/list
varies depending on the type of PARAM
comment : str; default=''
a comment for the card
"""
if comment:
self.comment = comment
self.key = key
if isinstance(values, (int, float, str)):
values = [values]
self.values = values
[docs]
@classmethod
def add_card(cls, card, comment=''):
"""
Adds a PARAM card from ``BDF.add_card(...)``
Parameters
----------
card : BDFCard()
a BDFCard object
comment : str; default=''
a comment for the card
"""
key = string(card, 1, 'key')
if key == 'ARP_TOL':
values = [
double_or_blank(card, 2, 'value', 1e-6)
]
elif key == 'AUTOSPC':
# ['PARAM', 'AUTOSPC', 'Y', '1.0E-9', None, 'Y', 'Y']
# enabled, tol, nset, info, print_
enabled = string_or_blank(card, 2, 'ENABLED', 'Y')
tol = double_or_blank(card, 3, 'TOL', 1e-6)
nset = integer_or_blank(card, 4, 'NSET', 1)
info = string_or_blank(card, 5, 'INFO', 'N')
print_ = string_or_blank(card, 6, 'PRINT', 'N')
assert enabled in {'Y', 'N'}, enabled
assert info in {'Y', 'N'}, info
assert print_ in {'Y', 'N'}, print_
values = [
enabled, tol, nset, info, print_
]
elif key == 'ART_MASS':
# ['PARAM', 'ART_MASS', 'Y', '0.', '1.E-6']
values = [
string_or_blank(card, 2, 'is_mass', 'N'),
double_or_blank(card, 3, 'trans_mass', 1e-6),
double_or_blank(card, 4, 'rot_mass', 1e-6),
]
elif key == 'EIGNORM2':
#['PARAM', 'EIGNORM2', 'Y']
values = [string_or_blank(card, 2, 'enabled', 'N')]
elif key == 'EQCHECK':
#['PARAM', 'EQCHECK', '0', '3', '3', None, None, None, '-1.E10']
values = [
integer_or_blank(card, 2, 'refgrid', 0),
integer_or_blank(card, 3, 'g-set', 0),
integer_or_blank(card, 4, 'n-set', 0),
integer_or_blank(card, 5, 'f-set', 0),
integer_or_blank(card, 6, 'a-set', 0),
integer_or_blank(card, 7, 'l-set', 0),
double_or_blank(card, 8, 'grid_forces_tol', 1e-5),
string_or_blank(card, 9, 'norm_forces', 'N'),
]
elif key == 'GRDPNT':
#['PARAM', 'GRDPNT', '0']
values = [
integer_or_blank(card, 2, 'GRDPNT', -1),
]
elif key == 'MEFMLOC':
# ['PARAM', 'MEFMLOC', 'CG']
values = [string_or_blank(card, 2, 'enabled', 'GRDPNT')]
assert values[0] in ['GRDPNT', 'CG', 'GRID'], values
elif key == 'POST':
#['PARAM', 'POST', '-1']
values = [
integer_or_blank(card, 2, 'POST', -1),
]
elif key == 'RCONDK':
#['PARAM', 'RCONDK', 'Y']
values = [
string_or_blank(card, 2, 'RCONDK', 'N'),
]
elif key == 'SOLLIB':
# ['PARAM', 'SOLLIB', 'LAPACK']
values = [
string_or_blank(card, 2, 'library', 'INTELMKL'),
]
#SOLLIB; char; default=IntMKL
#Denotes which library to use for matrix decomposition and equation solution. Options are:
#IntMKL: Intel Math Kernel Library (matrices stored in sparse form)
#LAPACK (matrices stored in band form)
#YaleSMP: (matrices stored in sparse form) – not fully implemented in MYSTRAN
assert values[0] in ['INTMKL', 'LAPACK', 'YALESMP', 'BANDED', 'SPARSE'], values
elif key == 'SPARSTOR':
values = [
string_or_blank(card, 2, 'storage', 'SYM'),
]
assert values[0] in {'SYM', 'NONSYM'}, values
elif key == 'WTMASS':
#['PARAM', 'WTMASS', '.002591']
values = [
double_or_blank(card, 2, 'WTMASS', 1.0),
]
# basic print flags
elif key == 'PRTBASIC':
#['PARAM', 'PRTBASIC', '1']
values = [
integer_or_blank(card, 2, 'PRTBASIC', 0),
]
assert values[0] in [0, 1], values
elif key == 'PRTCGLTM':
#['PARAM', 'PRTCGLTM', '1']
values = [
integer_or_blank(card, 2, 'PRTCGLTM', 0),
]
assert values[0] in [0, 1], values
elif key == 'PRTDLR':
#['PARAM', 'PRTDLR', '1']
values = [
integer_or_blank(card, 2, 'PRTDLR', 0),
]
assert values[0] in [0, 1], values
elif key == 'PRTGMN':
#['PARAM', 'PRTGMN', '1']
values = [
integer_or_blank(card, 2, 'PRTGMN', 0),
]
assert values[0] in [0, 1], values
elif key == 'PRTGOA':
#['PARAM', 'PRTGOA', '1']
values = [
integer_or_blank(card, 2, 'PRTGMN', 0),
]
assert values[0] in [0, 1], values
elif key == 'PRTSCP':
#['PARAM', 'PRTSCP', '1']
values = [
integer_or_blank(card, 2, 'PRTSCP', 0),
]
assert values[0] in [0, 1], values
elif key == 'PRTTSET':
#['PARAM', 'PRTTSET', '1']
values = [
integer_or_blank(card, 2, 'PRTTSET', 0),
]
assert values[0] in [0, 1], values
elif key == 'PRTHMN':
#['PARAM', 'PRTHMN', '1']
values = [
integer_or_blank(card, 2, 'PRTHMN', 0),
]
assert values[0] in [0, 1], values
elif key == 'PRTIFLTM':
#['PARAM', 'PRTIFLTM', '1']
values = [
integer_or_blank(card, 2, 'PRTIFLTM', 0),
]
assert values[0] in [0, 1], values
elif key == 'PRTKXX':
#['PARAM', 'PRTKXX', '1']
values = [
integer_or_blank(card, 2, 'PRTKXX', 0),
]
assert values[0] in [0, 1], values
elif key == 'PRTMXX':
#['PARAM', 'PRTMXX', '1']
values = [
integer_or_blank(card, 2, 'PRTMXX', 0),
]
assert values[0] in [0, 1], values
elif key == 'PRTPHIXA':
#['PARAM', 'PRTPHIXA', '1']
values = [
integer_or_blank(card, 2, 'PRTPHIXA', 0),
]
assert values[0] in [0, 1], values
elif key == 'PRTPHIZL':
#['PARAM', 'PRTPHIZL', '1']
values = [
integer_or_blank(card, 2, 'PRTPHIZL', 0),
]
assert values[0] in [0, 1], values
elif key == 'PRTQSYS':
#['PARAM', 'PRTQSYS', '1']
values = [
integer_or_blank(card, 2, 'PRTQSYS', 0),
]
assert values[0] in [0, 1], values
elif key == 'PRTUO0':
#['PARAM', 'PRTUO0', '1']
values = [
integer_or_blank(card, 2, 'PRTUO0', 0),
]
assert values[0] in [0, 1], values
elif key == 'PRTYS':
#['PARAM', 'PRTYS', '1']
values = [
integer_or_blank(card, 2, 'PRTUO0', 0),
]
assert values[0] in [0, 1], values
# ----------------------------------
# not basic print flags
elif key == 'PRTCORD':
#['PARAM', 'PRTCORD', '2']
values = [
integer_or_blank(card, 2, 'PRTCORD', 0),
]
assert values[0] in [0, 1, 2], values # TODO: why is 2 allowed?
elif key == 'PRTDOF':
#['PARAM', 'PRTDOF', '1']
values = [
integer_or_blank(card, 2, 'PRTDOF', 0),
]
assert values[0] in [0, 1, 2, 3], values
elif key == 'PRTRMG':
#['PARAM', 'PRTRMG', '3']
values = [
integer_or_blank(card, 2, 'PRTRMG', 0),
]
assert values[0] in [0, 1, 2, 3], values
elif key == 'PRTSTIFF':
# ['PARAM', 'PRTSTIFF', '1', '3', '3', '3', '3']
values = [
integer(card, 2, 'PRTSTIFF-2'),
integer(card, 3, 'PRTSTIFF-3'),
integer(card, 4, 'PRTSTIFF-4'),
integer(card, 5, 'PRTSTIFF-5'),
integer(card, 6, 'PRTSTIFF-6'),
]
for i, value in enumerate(values):
assert value in [1, 3], f'i={i} values={values}'
elif key == 'PRTSTIFD':
# ['PARAM', 'PRTSTIFD', '1', '3', '3', '3', '3']
values = [
integer(card, 2, 'PRTSTIFD-2'),
integer(card, 3, 'PRTSTIFD-3'),
integer(card, 4, 'PRTSTIFD-4'),
integer(card, 5, 'PRTSTIFD-5'),
integer(card, 6, 'PRTSTIFD-6'),
]
for i, value in enumerate(values):
assert value in [1, 3], f'i={i} values={values}'
elif key == 'PRTFOR':
# ['PARAM', 'PRTFOR', '1', '3', '3', '3', '3']
values = [
integer(card, 2, 'PRTFOR-2'),
integer(card, 3, 'PRTFOR-3'),
integer(card, 4, 'PRTFOR-4'),
integer(card, 5, 'PRTFOR-5'),
integer(card, 6, 'PRTFOR-6'),
]
for i, value in enumerate(values):
assert value in [1, 3], f'i={i} values={values}'
elif key == 'PRTMASS':
# ['PARAM', 'PRTMASS', '1', '3', '3', '3', '3']
values = [
integer(card, 2, 'PRTMASS-2'),
integer(card, 3, 'PRTMASS-3'),
integer(card, 4, 'PRTMASS-4'),
integer(card, 5, 'PRTMASS-5'),
integer(card, 6, 'PRTMASS-6'),
]
for i, value in enumerate(values):
assert value in [1, 3], f'i={i} values={values}'
elif key == 'MXITERI':
values = [integer_or_blank(card, 2, 'MAXITERI-2', default=50),]
elif key == 'LANCMETH':
values = [string(card, 2, 'LANCMETH-2'),]
assert values[0] in {'ARPACK'}, values
#ARPACK or TRLan
elif key == 'GRIDSEQ':
values = [string_or_blank(card, 2, 'GRIDSEQ-2', default='BANDIT'),]
assert values[0] in {'BANDIT', 'GRID', 'INPUT'}, values
elif key == 'SORT_MAX':
values = [integer_or_blank(card, 2, 'SORT_MAX-2', default=5),]
else:
raise NotImplementedError(card)
return PARAM_MYSTRAN(key, values, comment=comment)
[docs]
def raw_fields(self):
list_fields = ['PARAM', self.key] + self.values
return list_fields
[docs]
def repr_fields(self):
return self.raw_fields()
[docs]
def write_card(self, size: int=8, is_double: bool=False) -> str:
card = self.raw_fields()
if size == 8:
return self.comment + print_card_8(card)
return self.comment + print_card_16(card)
MDLPRM_INT_KEYS_1 = {
'BRTOBM', 'BUSHRT', 'DCFLTEXP', 'GEV1417', 'GNLSTN',
'HDF5', 'H5GM34', 'H5INFO', 'H5MDL', 'H5MTX', 'H5NORDOF', 'H5XHH',
'IGNSHBDN', 'INTOUT', 'LMT2MPC', 'MLTSPLIN', 'MPCF129', 'NLDIFF',
'NONUPIV', 'NSGRDS4', 'PRDIDPVT', 'PRDITRFN', # 'PIVTHRSH',
'PRDMTYPE', 'PRDOOC', 'PRDWMTCH', 'QR6ROT', 'QRSHEAR',
'RDBOTH', 'RELAXF', 'REUPSE', 'RMRBE3RT', 'RSTIGNDP', 'SHRTOQ4',
'STREQCNT', 'TWBRBML',
# undefined in MSC
'RBEDOF', 'NLDIAG', 'ITRFMT', 'NLSPCD', 'MRCONV', 'LA3FLG', 'TIMADJ',
}
MDLPRM_INT_KEYS_1_DEFAULT = {
# ...more
'GNLSTN': 0,
'HDF5': -1,
'H5GM34': -1,
'H5MDL': 1,
'H5MTX': 1,
'H5NORDOF': 0,
'IGNSHBDN': 0,
'INTOUT': 0,
'LMT2MPC': 0,
'MLTSPLIN': 0,
'MPCF129': 0,
'NSGRDS4': 0,
'PRDIDPVT': 1,
'PRDITRFN': 0,
'QR6ROT': 0,
'QRSHEAR': 0,
'RDBOTH': 0,
'RELAXF': 0,
'RSTIGNDP': 0,
'SHRTOQ4': 0,
'TWBRBML': 0,
}
MDLPRM_STR_KEYS_1_DEFAULT = {
'PRTELAS': 'NO',
'PRTFAST': 'NO',
'PRTSEAM': 'NO',
'PRTWELD': 'NO',
'SHEARP': 'GARVEY',
}
MDLPRM_FLOAT_KEYS_1_DEFAULT = {
'SPBLNDX': 1.0,
}
MDLPRM_STR_KEYS_1 = {'COMPN1', 'SHEARP', 'OFFDEF',
'PRTELAS', 'PRTFAST', 'PRTMASS', 'PRTSEAM', 'PRTWELD'}
MDLPRM_FLOAT_KEYS_1 = {
'DBCTOLE', 'DELELAS', 'DELFAST', 'DELMASS', 'DELSEAM', 'DELWELD',
'PEXTS4', 'PIVTHRSH', 'SPBLNDX', 'PEXTS4', }
MDLPRM_KEYS = MDLPRM_INT_KEYS_1 | MDLPRM_STR_KEYS_1
[docs]
class MDLPRM(BaseCard):
"""MSC Nastran card"""
type = 'MDLPRM'
_field_map = {1: 'key'}
[docs]
@classmethod
def _init_from_empty(cls):
key = 'POST'
values = -1
return MDLPRM(key, values, comment='')
def __init__(self, mdlprm_dict: dict[str, Union[int, float]], comment=''):
"""
Creates a MDLPRM card
Parameters
----------
mdlprm_dict : dict[name, value]
name : str
the name of the MDLPRM
value: int/float
varies depending on the type of MDLPRM
comment : str; default=''
a comment for the card
"""
if comment:
self.comment = comment
self.mdlprm_dict = mdlprm_dict
assert isinstance(mdlprm_dict, dict), mdlprm_dict
for key, value in sorted(mdlprm_dict.items()):
if key in MDLPRM_INT_KEYS_1:
assert isinstance(value, integer_types), f'MDLPRM key={key!r} value={value!r} must be an integer'
elif key in MDLPRM_STR_KEYS_1:
assert isinstance(value, str), f'MDLPRM key={key!r} value={value!r} must be an integer'
elif key in MDLPRM_FLOAT_KEYS_1:
assert isinstance(value, float_types), f'MDLPRM key={key!r} value={value!r} must be an float'
else:
raise RuntimeError(f'MDLPRM key={key!r} value={value!r} is not supported')
assert len(mdlprm_dict) > 0, mdlprm_dict
[docs]
@classmethod
def add_card(cls, card: BDFCard, comment=''):
"""
Adds a MDLPRM card from ``BDF.add_card(...)``
Parameters
----------
card : BDFCard()
a BDFCard object
comment : str; default=''
a comment for the card
"""
mdlprm_dict = {}
ifield = 1
while ifield < len(card):
key = string_or_blank(card, ifield, 'key')
if key is None:
value = blank(card, ifield+1, 'blank_value')
ifield += 2
continue
elif key in MDLPRM_INT_KEYS_1:
default = MDLPRM_INT_KEYS_1_DEFAULT.get(key, None)
value = integer_or_blank(card, ifield+1, 'value', default=default)
assert isinstance(value, integer_types), f'MDLPRM key={key!r} value={value!r} must be an integer; card={card}'
elif key in MDLPRM_STR_KEYS_1:
default = MDLPRM_STR_KEYS_1_DEFAULT.get(key, None)
value = string_or_blank(card, ifield+1, key, default=default)
assert isinstance(value, str), f'MDLPRM key={key!r} value={value!r} must be a string; card={card}'
elif key in MDLPRM_FLOAT_KEYS_1:
default = MDLPRM_FLOAT_KEYS_1_DEFAULT.get(key, None)
value = double_or_blank(card, ifield+1, key, default=default)
assert isinstance(value, float_types), f'MDLPRM key={key!r} value={value!r} must be an float; card={card}'
else:
raise RuntimeError(f'MDLPRM key={key!r} is not supported; value={card.field(ifield+1)}')
mdlprm_dict[key] = value
ifield += 2
obj = MDLPRM(mdlprm_dict, comment=comment)
return obj
#@classmethod
[docs]
def export_to_hdf5(self, h5_file, model, desvar_ids):
"""exports the elements in a vectorized way"""
#comments = []
encoding = model.get_encoding()
keys = []
flags = []
value_ints = []
value_floats = []
value_strs = []
for key, value in sorted(self.mdlprm_dict.items()):
value_int = 0
value_float = np.nan
value_str = b''
if isinstance(value, integer_types):
value_int = value
flag = 1
elif isinstance(value, float_types):
value_float = value
flag = 2
elif isinstance(value, str):
value_str = value.encode(encoding)
flag = 3
else:
raise NotImplementedError((key, value))
keys.append(key.encode(encoding))
flags.append(flag)
value_ints.append(value_int)
value_floats.append(value_float)
value_strs.append(value_str)
h5_file.create_dataset('keys', data=keys)
h5_file.create_dataset('ifs_flag', data=flags)
h5_file.create_dataset('value_ints', data=value_ints)
h5_file.create_dataset('value_floats', data=value_floats)
h5_file.create_dataset('value_strs', data=value_strs)
[docs]
def load_hdf5_file(self, hdf5_file, encoding) -> None:
from pyNastran.utils.dict_to_h5py import _cast
keys = list(hdf5_file.keys())
assert len(keys) == 5, keys
ifs_flag = _cast(hdf5_file['ifs_flag'])
keys = _cast(hdf5_file['keys'])
value_ints = _cast(hdf5_file['value_ints'])
value_floats = _cast(hdf5_file['value_floats'])
value_strs = _cast(hdf5_file['value_strs'])
for key, flag, xint, xfloat, xstr in zip(keys, ifs_flag, value_ints, value_floats, value_strs):
key_str = key.decode(encoding)
if flag == 1:
value = xint
elif flag == 2:
value = xfloat
elif flag == 3:
value = xstr.decode(encoding)
assert isinstance(value, str), value
else: # pragma: no cover
raise RuntimeError((key_str, flag, xint, xfloat, xstr))
#print(key_str, value)
self.mdlprm_dict[key_str] = value
#print(str(self))
return
[docs]
def raw_fields(self):
list_fields = ['MDLPRM']
for key, value in self.mdlprm_dict.items():
list_fields += [key, value]
assert len(list_fields) > 1, self.mdlprm_dict
return list_fields
[docs]
def repr_fields(self):
return self.raw_fields()
[docs]
def write_card(self, size: int=8, is_double: bool=False) -> str:
card = self.raw_fields()
if size == 8:
return self.comment + print_card_8(card)
return self.comment + print_card_16(card)