Skip to content

Commit

Permalink
bdf_vectorized3:
Browse files Browse the repository at this point in the history
 - adding optimization: DSCREEN
 - adding random load: ACSRCE
 - adding axisymmetric: CTRAX3, CTRAX6, CTRIAX, CTRIAX6, CQUADX, CQUADX4, CQUADX8
 - adding contact BCONP, BFRIC
 - fixing self.n return (is now self.n-1)
  • Loading branch information
SteveDoyle2 committed Nov 13, 2023
1 parent 49cae1f commit 1cf6a12
Show file tree
Hide file tree
Showing 56 changed files with 3,268 additions and 801 deletions.
2 changes: 1 addition & 1 deletion pyNastran/bdf/bdf_interface/add_card.py
Original file line number Diff line number Diff line change
Expand Up @@ -7494,7 +7494,7 @@ def add_doptprm(self, params: dict[str, Union[int, float]], comment='') -> DOPTP
self._add_methods._add_doptprm_object(doptprm)
return doptprm

def add_dscreen(self, rtype: str, trs=-0.5, nstr=20, comment='') -> DSCREEN:
def add_dscreen(self, rtype: str, trs: float=-0.5, nstr: int=20, comment: str='') -> DSCREEN:
"""
Creates a DSCREEN object
Expand Down
2 changes: 1 addition & 1 deletion pyNastran/bdf/bdf_interface/add_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -1190,7 +1190,7 @@ def _add_cyjoin_object(self, cyjoin: CYJOIN) -> None:

def _add_modtrak_object(self, modtrak: MODTRAK) -> None:
"""adds an MODTRAK object"""
# only one CYAX card allowed
# only one MODTRAK card allowed
assert self.model.modtrak is None, '\nmodtrak=\n%s old=\n%s' % (modtrak, self.model.modtrak)
self.model.modtrak = modtrak

Expand Down
10 changes: 5 additions & 5 deletions pyNastran/bdf/cards/contact.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def __init__(self, friction_id: int, mu1: float, fstiff=None, comment=''):
self.mu1 = mu1

@classmethod
def add_card(cls, card, comment=''):
def add_card(cls, card: BDFCard, comment: str=''):
friction_id = integer(card, 1, 'friction_id')
fstiff = double_or_blank(card, 2, 'fstiff')
#
Expand Down Expand Up @@ -548,7 +548,7 @@ def __init__(self, contact_id, slave, master, sfac, friction_id, ptype, cid, com
self.master_ref = None

@classmethod
def add_card(cls, card, comment=''):
def add_card(cls, card: BDFCard, comment: str=''):
"""
Adds a BCONP card from ``BDF.add_card(...)``
Expand All @@ -563,10 +563,10 @@ def add_card(cls, card, comment=''):
contact_id = integer(card, 1, 'contact_id')
slave = integer(card, 2, 'slave')
master = integer(card, 3, 'master')
sfac = double_or_blank(card, 5, 'sfac', 1.0)
sfac = double_or_blank(card, 5, 'sfac', default=1.0)
friction_id = integer_or_blank(card, 6, 'fric_id')
ptype = integer_or_blank(card, 7, 'ptype', 1)
cid = integer_or_blank(card, 8, 'cid', 0)
ptype = integer_or_blank(card, 7, 'ptype', default=1)
cid = integer_or_blank(card, 8, 'cid', default=0)
return BCONP(contact_id, slave, master, sfac, friction_id, ptype, cid,
comment=comment)

Expand Down
8 changes: 4 additions & 4 deletions pyNastran/bdf/cards/dynamic.py
Original file line number Diff line number Diff line change
Expand Up @@ -1920,10 +1920,10 @@ def add_card(cls, card, comment=''):
j = irow * 8 + 9
#ifield = irow + 1
nid = integer(card, j, 'grid_%i' % (irow + 1))
component = components_or_blank(card, j + 1, 'components_%i' % (irow + 1), '0')
a0 = double_or_blank(card, j + 2, 'a0_%i' % (irow + 1), 0.)
a1 = double_or_blank(card, j + 3, 'a1_%i' % (irow + 1), 0.)
a2 = double_or_blank(card, j + 4, 'a2_%i' % (irow + 1), 0.)
component = components_or_blank(card, j + 1, 'components_%i' % (irow + 1), default='0')
a0 = double_or_blank(card, j + 2, 'a0_%i' % (irow + 1), default=0.)
a1 = double_or_blank(card, j + 3, 'a1_%i' % (irow + 1), default=0.)
a2 = double_or_blank(card, j + 4, 'a2_%i' % (irow + 1), default=0.)
nids.append(nid)
components.append(component)
a.append([a0, a1, a2])
Expand Down
21 changes: 13 additions & 8 deletions pyNastran/bdf/cards/loads/dloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from pyNastran.bdf.cards.loads.loads import DynamicLoad, LoadCombination, BaseCard
if TYPE_CHECKING: # pragma: no cover
from pyNastran.bdf.bdf import BDF
from pyNastran.bdf.bdf_interface.bdf_card import BDFCard


class ACSRCE(BaseCard):
Expand Down Expand Up @@ -55,8 +56,10 @@ def _init_from_empty(cls):
return ACSRCE(sid, excite_id, rho, b,
delay=0, dphase=0, power=0, comment='')

def __init__(self, sid, excite_id, rho, b,
delay=0, dphase=0, power=0, comment=''):
def __init__(self, sid: int, excite_id: int, rho: float, b: float,
delay: Union[int, float]=0,
dphase: Union[int, float]=0,
power: Union[int, float]=0, comment=''):
"""
Creates an ACSRCE card
Expand Down Expand Up @@ -104,7 +107,7 @@ def __init__(self, sid, excite_id, rho, b,
#self.delays_ref = None

@classmethod
def add_card(cls, card, comment=''):
def add_card(cls, card: BDFCard, comment: str=''):
"""
Adds a ACSRCE card from ``BDF.add_card(...)``
Expand All @@ -117,9 +120,9 @@ def add_card(cls, card, comment=''):
"""
sid = integer(card, 1, 'sid')
excite_id = integer(card, 2, 'excite_id') # DAREA, FBALOAD, SLOAD
delay = integer_double_or_blank(card, 3, 'delay', 0) # DELAY, FBADLAY
dphase = integer_double_or_blank(card, 4, 'dphase', 0) # DPHASE, FBAPHAS
power = integer_double_or_blank(card, 5, 'power/tp/rp', 0) # TABLEDi/power
delay = integer_double_or_blank(card, 3, 'delay', default=0) # DELAY, FBADLAY
dphase = integer_double_or_blank(card, 4, 'dphase', default=0) # DPHASE, FBAPHAS
power = integer_double_or_blank(card, 5, 'power/tp/rp', default=0) # TABLEDi/power
rho = double(card, 6, 'rho')
b = double(card, 7, 'bulk modulus')

Expand Down Expand Up @@ -254,7 +257,7 @@ def Power(self):
return self.power_ref.tid
return self.power

def get_load_at_freq(self, freq):
def get_load_at_freq(self, freq: float) -> float:
r"""
..math ::
C = \sqrt(B ⁄ ρ)
Expand All @@ -275,7 +278,9 @@ def get_load_at_freq(self, freq):
else:
#print('dphase\n', self.dphase_ref)
theta = self.dphase_ref.interpolate(freq)
strength = A / (2.* pi * freq) * np.sqrt(8*pi*C*Pf / self.rho) ** (ei*(theta + 2*pi*freq*tau))

omega = 2.* pi * freq
strength = A / omega * np.sqrt(8*pi*C*Pf / self.rho) ** (ei*(theta + omega*tau))

return 0.0

Expand Down
3 changes: 2 additions & 1 deletion pyNastran/bdf/cards/methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -1147,7 +1147,7 @@ class MODTRAK(BaseCard):
MODTRAK SID LOWRNG HIGHRNG MTFILTER
MODTRAK 100 1 26 0.80
"""
def __init__(self, sid, low_range, high_range, mt_filter, comment=''):
def __init__(self, sid: int, low_range: int, high_range: int, mt_filter: float, comment: str=''):
BaseCard.__init__(self)
self.sid = sid
self.low_range = low_range
Expand All @@ -1160,6 +1160,7 @@ def add_card(cls, card, comment=''):
low_range = integer_or_blank(card, 2, 'low_range', default=0)
high_range = integer(card, 3, 'high_range')
mt_filter = double_or_blank(card, 4, 'mt_filter', default=0.9)
assert len(card) <= 5, f'len(MODTRAK card) = {len(card):d}\ncard={card}'
return MODTRAK(sid, low_range, high_range, mt_filter, comment=comment)

def raw_fields(self) -> list[Any]:
Expand Down
2 changes: 1 addition & 1 deletion pyNastran/bdf/cards/optimization.py
Original file line number Diff line number Diff line change
Expand Up @@ -3463,7 +3463,7 @@ def __init__(self, rtype: str, trs: float=-0.5, nstr: int=20,
#'CEIG', 'LAMA', 'EIGN', 'VOLUME', 'DRESP3', 'WEIGHT'], str(self)

@classmethod
def add_card(cls, card, comment: str=''):
def add_card(cls, card: BDFCard, comment: str=''):
"""
Adds a DSCREEN card from ``BDF.add_card(...)``
Expand Down
49 changes: 46 additions & 3 deletions pyNastran/bdf/cards/params.py
Original file line number Diff line number Diff line change
Expand Up @@ -1484,6 +1484,43 @@ def write_card(self, size: int=8, is_double: bool=False) -> str:
# 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 = {
Expand Down Expand Up @@ -1555,11 +1592,17 @@ def add_card(cls, card: BDFCard, comment=''):
ifield += 2
continue
elif key in MDLPRM_INT_KEYS_1:
value = integer_or_blank(card, ifield+1, 'value')
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:
value = string(card, ifield+1, key)
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:
value = double(card, ifield+1, key)
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
Expand Down
8 changes: 8 additions & 0 deletions pyNastran/bdf/cards/test/test_optimization.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ def test_opt_1(self):
def test_opt_2(self):
"""tests updating model based on DESVARs"""
model = BDF(debug=False)

modtrak_id = 100
low_range = 3
high_range = 6
mt_filter = 0.9
model.add_modtrak(modtrak_id, low_range, high_range, mt_filter, comment='modtrak')

model.add_grid(1, [0., 0., 0.])
model.add_grid(2, [1., 0., 0.])
model.add_grid(3, [1., 1., 0.])
Expand Down Expand Up @@ -155,6 +162,7 @@ def test_opt_2(self):
assert model.Mass(eid_conm2).mass == mass_new, 'mass=%s mass_new=%s' % (model.Mass(eid_conm2).mass, mass_new)
assert model.Mass(eid_conm2).X[0] == x1_new, 'X1=%s x1_new=%s' % (model.Mass(eid_conm2).mass, x1_new)
assert model.properties[pid_pcomp].thicknesses[0] == tpcomp_new, 't=%s tnew=%s' % (model.properties[pid_pcomp].thicknesses[0], tpcomp_new)
save_load_deck(model)

def test_ddval(self):
"""tests a DDVAL"""
Expand Down
52 changes: 46 additions & 6 deletions pyNastran/bdf/mesh_utils/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -1667,7 +1667,7 @@ def _convert_optimization(model: BDF,

for unused_key, dvcrel in model.dvcrels.items():
if dvcrel.type == 'DVCREL1':
scale = _convert_dvcrel1(dvcrel, xyz_scale)
scale = _convert_dvcrel1(dvcrel, xyz_scale, mass_scale)
desvars = dvcrel.dvids_ref
assert len(desvars) == 1, len(desvars)
_convert_desvars(desvars, scale)
Expand All @@ -1679,15 +1679,21 @@ def _convert_optimization(model: BDF,
_convert_desvars(desvars, scale)

for unused_key, dvmrel in model.dvmrels.items():
raise NotImplementedError(dvmrel)
if dvmrel.type == 'DVMREL1':
scale = _convert_dvmrel1(dvmrel, xyz_scale, mass_scale, force_scale, time_scale)
desvars = dvmrel.dvids_ref
assert len(desvars) == 1, len(desvars)
_convert_desvars(desvars, scale)
else: # pragma: no cover
raise NotImplementedError(dvprel)

for unused_key, dvprel in model.dvprels.items():
if dvprel.type == 'DVPREL1':
scale = _convert_dvprel1(dvprel, xyz_scale, mass_scale, force_scale, time_scale)
desvars = dvprel.dvids_ref
assert len(desvars) == 1, len(desvars)
_convert_desvars(desvars, scale)
else:
else: # pragma: no cover
raise NotImplementedError(dvprel)
if dvprel.p_max != 1e20:
dvprel.p_max *= scale
Expand Down Expand Up @@ -1738,18 +1744,52 @@ def _convert_dconstr(model: BDF, dconstr: DCONSTR, pressure_scale: float) -> Non
print(msg)
raise NotImplementedError(msg)

def _convert_dvcrel1(dvcrel: Union[DVCREL1, DVCREL2], xyz_scale: float) -> float:
def _convert_dvcrel1(dvcrel: Union[DVCREL1, DVCREL2], xyz_scale: float, mass_scale: float) -> float:
"""helper for ``_convert_optimization``"""
element_type = dvcrel.element_type
if element_type == 'CBUSH':
if dvcrel.cp_name in ['X1', 'X2', 'X3', 'S', 'S1', 'S2', 'S3']:
if dvcrel.cp_name in {'X1', 'X2', 'X3', 'S', 'S1', 'S2', 'S3'}:
scale = xyz_scale
else:
else: # pragma: no cover
raise NotImplementedError(dvcrel)
elif element_type == 'CONM2':
if dvcrel.cp_name in ['M']:
scale = mass_scale
elif dvcrel.cp_name in {'X1', 'X2', 'X3'}:
scale = xyz_scale
else: # pragma: no cover
raise NotImplementedError(dvcrel)
else:
raise NotImplementedError(dvcrel)
return scale

def _convert_dvmrel1(dvmrel, xyz_scale: float,
mass_scale: float,
force_scale: float,
time_scale: float) -> float:
"""helper for ``_convert_optimization``"""
mat_type = dvmrel.mat_type
var_to_change = dvmrel.mp_name

#area_scale = xyz_scale ** 2
#inertia_scale = xyz_scale ** 4
#velocity_scale = xyz_scale / time_scale
pressure_scale = force_scale / xyz_scale ** 2
#stress_scale = force_scale / xyz_scale ** 2
#stiffness_scale = force_scale / xyz_scale

scale = 1.
if mat_type == 'MAT1':
if var_to_change == 'E':
scale = pressure_scale
#elif var_to_change in [6, 8]: # 12I/t^3, ts/t
#scale = 1.
else: # pragma: no cover
raise NotImplementedError('cannot convert %r\n%s' % (var_to_change, dvmrel))
else: # pragma: no cover
raise NotImplementedError('cannot convert %r\n%s' % (prop_type, dvprel))
return scale

def _convert_dvprel1(dvprel, xyz_scale: float,
mass_scale: float,
force_scale: float,
Expand Down
Loading

0 comments on commit 1cf6a12

Please sign in to comment.