Skip to content

Commit 177aaf1

Browse files
committed
fixing IO for BCTPARA and BCTPARM
1 parent e19a7bb commit 177aaf1

File tree

4 files changed

+216
-154
lines changed

4 files changed

+216
-154
lines changed

pyNastran/bdf/bdf_interface/add_card.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4073,7 +4073,15 @@ def add_bctpara(self, csid: int,
40734073
self._add_methods.add_bctpara_object(bctpara)
40744074
return bctpara
40754075

4076-
def add_blseg(self, line_id, nodes, comment='') -> BLSEG:
4076+
def add_bctparm(self, csid: int,
4077+
params: dict[str, Any], comment: str='') -> BCTPARM:
4078+
"""Creates a BCTPARM card"""
4079+
bctparm = BCTPARM(csid, params, comment=comment)
4080+
self._add_methods.add_bctparam_object(bctparm)
4081+
return bctparm
4082+
4083+
def add_blseg(self, line_id: int, nodes: list[int],
4084+
comment: str='') -> BLSEG:
40774085
"""Creates a BLSEG card"""
40784086
blseg = BLSEG(line_id, nodes, comment=comment)
40794087
self._add_methods.add_blseg_object(blseg)

pyNastran/bdf/cards/contact.py

Lines changed: 181 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
5353
"""
5454
from __future__ import annotations
55+
import warnings
5556
from typing import Optional, Any, TYPE_CHECKING
5657

5758
from pyNastran.utils.numpy_utils import integer_types
@@ -1396,12 +1397,14 @@ def _init_from_empty(cls):
13961397
params = {'CSTIFF' : 1}
13971398
return BCTPARM(csid, params, comment='')
13981399

1399-
def _finalize_hdf5(self, encoding):
1400+
def _finalize_hdf5(self, encoding: str):
14001401
"""hdf5 helper function"""
14011402
keys, values = self.params
14021403
self.params = {key : value for key, value in zip(keys, values)}
14031404

1404-
def __init__(self, csid, params, comment=''):
1405+
def __init__(self, csid: int,
1406+
params: dict[str, int | float],
1407+
comment: str=''):
14051408
"""
14061409
Creates a BCTPARM card
14071410
@@ -1447,89 +1450,77 @@ def add_card(cls, card: BDFCard, comment: str=''):
14471450
14481451
"""
14491452
csid = integer(card, 1, 'csid')
1450-
i = 2
1451-
j = 1
1452-
params = {}
1453-
while i < card.nfields:
1454-
param = string(card, i, 'param%s' % j)
1455-
i += 1
1456-
if param == 'TYPE' and 0:
1457-
value = integer_or_blank(card, i, 'value%s' % j, default=0)
1458-
assert value in [0, 1, 2], 'TYPE must be [0, 1, 2]; TYPE=%r' % value
1459-
elif param == 'PENN':
1460-
#PENN 10.0
1461-
value = double(card, i, 'value%s' % j)
1462-
elif param == 'PENT':
1463-
#PENT 0.5
1464-
value = double(card, i, 'value%s' % j)
1465-
elif param == 'CTOL':
1466-
#CTOL 10.0
1467-
value = double(card, i, 'value%s' % j)
1468-
elif param == 'SHLTHK':
1469-
#SHLTHK 1
1470-
value = integer(card, i, 'value%s' % j)
1471-
#elif param == 'TYPE': # NX
1472-
#value = string_or_blank(card, i, 'value%s' % j, default='FLEX').upper()
1473-
#assert value in ['FLEX', 'RIGID', 'COATING'], 'TYPE must be [FLEX, RIGID, COATING.]; CSTIFF=%r' % value
1474-
1475-
#elif param == 'NSIDE':
1476-
#value = integer_or_blank(card, i, 'value%s' % j, default=1)
1477-
#assert value in [1, 2], 'NSIDE must be [1, 2]; NSIDE=%r' % value
1478-
#elif param == 'TBIRTH':
1479-
#value = double_or_blank(card, i, 'value%s' % j, default=0.0)
1480-
#elif param == 'TDEATH':
1481-
#value = double_or_blank(card, i, 'value%s' % j, default=0.0)
1482-
#elif param == 'INIPENE':
1483-
#value = integer_or_blank(card, i, 'value%s' % j, default=0)
1484-
#assert value in [0, 1, 2, 3], 'INIPENE must be [0, 1, 2]; INIPENE=%r' % value
1485-
#elif param == 'PDEPTH':
1486-
#value = double_or_blank(card, i, 'value%s' % j, default=0.0)
1487-
#elif param == 'SEGNORM':
1488-
#value = integer_or_blank(card, i, 'value%s' % j, default=0)
1489-
#assert value in [-1, 0, 1], 'SEGNORM must be [-1, 0, 1]; SEGNORM=%r' % value
1490-
#elif param == 'OFFTYPE':
1491-
#value = integer_or_blank(card, i, 'value%s' % j, default=0)
1492-
#assert value in [0, 1, 2], 'OFFTYPE must be [0, 1, 2]; OFFTYPE=%r' % value
1493-
#elif param == 'OFFSET':
1494-
#value = double_or_blank(card, i, 'value%s' % j, default=0.0)
1495-
#elif param == 'TZPENE':
1496-
#value = double_or_blank(card, i, 'value%s' % j, default=0.0)
1497-
1498-
#elif param == 'CSTIFF':
1499-
#value = integer_or_blank(card, i, 'value%s' % j, default=0)
1500-
#assert value in [0, 1], 'CSTIFF must be [0, 1]; CSTIFF=%r' % value
1501-
#elif param == 'TIED':
1502-
#value = integer_or_blank(card, i, 'value%s' % j, default=0)
1503-
#assert value in [0, 1], 'TIED must be [0, 1]; TIED=%r' % value
1504-
#elif param == 'TIEDTOL':
1505-
#value = double_or_blank(card, i, 'value%s' % j, default=0.0)
1506-
#elif param == 'EXTFAC':
1507-
#value = double_or_blank(card, i, 'value%s' % j, default=0.001)
1508-
#assert 1.0E-6 <= value <= 0.1, 'EXTFAC must be 1.0E-6 < EXTFAC < 0.1; EXTFAC=%r' % value
1509-
else:
1510-
# FRICMOD, FPARA1/2/3/4/5, EPSN, EPST, CFACTOR1, PENETOL
1511-
# NCMOD, TCMOD, RFORCE, LFORCE, RTPCHECK, RTPMAX, XTYPE
1512-
# ...
1513-
value = integer_double_or_blank(card, i, 'value%s' % j)
1514-
assert value is not None, '%s%i must not be None' % (param, j)
1515-
1516-
params[param] = value
1517-
i += 1
1518-
j += 1
1519-
if j == 4:
1520-
i += 1
1453+
params = read_param_dict(card, cls._get_param_value_from_card)
15211454
return BCTPARM(csid, params, comment=comment)
15221455

1523-
def raw_fields(self):
1456+
def _get_param_value_from_card(
1457+
card: BDFCard,
1458+
i: int, j: int) -> tuple[str, int | float]:
1459+
param = string(card, i, 'param%s' % j)
1460+
if param == 'TYPE' and 0:
1461+
value = integer_or_blank(card, i+1, f'value{j:d}', default=0)
1462+
assert value in [0, 1, 2], 'TYPE must be [0, 1, 2]; TYPE=%r' % value
1463+
elif param == 'PENN':
1464+
# PENN 10.0
1465+
value = double(card, i+1, 'value%s' % j)
1466+
elif param == 'PENT':
1467+
# PENT 0.5
1468+
value = double(card, i+1, 'value%s' % j)
1469+
elif param == 'CTOL':
1470+
# CTOL 10.0
1471+
value = double(card, i+1, 'value%s' % j)
1472+
elif param == 'SHLTHK':
1473+
# SHLTHK 1
1474+
value = integer(card, i+1, 'value%s' % j)
1475+
# elif param == 'TYPE': # NX
1476+
# value = string_or_blank(card, i, 'value%s' % j, default='FLEX').upper()
1477+
# assert value in ['FLEX', 'RIGID', 'COATING'], 'TYPE must be [FLEX, RIGID, COATING.]; CSTIFF=%r' % value
1478+
1479+
# elif param == 'NSIDE':
1480+
# value = integer_or_blank(card, i+1, 'value%s' % j, default=1)
1481+
# assert value in [1, 2], 'NSIDE must be [1, 2]; NSIDE=%r' % value
1482+
# elif param == 'TBIRTH':
1483+
# value = double_or_blank(card, i+1, 'value%s' % j, default=0.0)
1484+
# elif param == 'TDEATH':
1485+
# value = double_or_blank(card, i+1, 'value%s' % j, default=0.0)
1486+
# elif param == 'INIPENE':
1487+
# value = integer_or_blank(card, i+1, 'value%s' % j, default=0)
1488+
# assert value in [0, 1, 2, 3], 'INIPENE must be [0, 1, 2]; INIPENE=%r' % value
1489+
# elif param == 'PDEPTH':
1490+
# value = double_or_blank(card, i+1, 'value%s' % j, default=0.0)
1491+
# elif param == 'SEGNORM':
1492+
# value = integer_or_blank(card, i+1, 'value%s' % j, default=0)
1493+
# assert value in [-1, 0, 1], 'SEGNORM must be [-1, 0, 1]; SEGNORM=%r' % value
1494+
# elif param == 'OFFTYPE':
1495+
# value = integer_or_blank(card, i+1, 'value%s' % j, default=0)
1496+
# assert value in [0, 1, 2], 'OFFTYPE must be [0, 1, 2]; OFFTYPE=%r' % value
1497+
# elif param == 'OFFSET':
1498+
# value = double_or_blank(card, i+1, 'value%s' % j, default=0.0)
1499+
# elif param == 'TZPENE':
1500+
# value = double_or_blank(card, i+1, 'value%s' % j, default=0.0)
1501+
1502+
# elif param == 'CSTIFF':
1503+
# value = integer_or_blank(card, i+1, 'value%s' % j, default=0)
1504+
# assert value in [0, 1], 'CSTIFF must be [0, 1]; CSTIFF=%r' % value
1505+
# elif param == 'TIED':
1506+
# value = integer_or_blank(card, i+1, 'value%s' % j, default=0)
1507+
# assert value in [0, 1], 'TIED must be [0, 1]; TIED=%r' % value
1508+
# elif param == 'TIEDTOL':
1509+
# value = double_or_blank(card, i+1, 'value%s' % j, default=0.0)
1510+
# elif param == 'EXTFAC':
1511+
# value = double_or_blank(card, i+1, 'value%s' % j, default=0.001)
1512+
# assert 1.0E-6 <= value <= 0.1, 'EXTFAC must be 1.0E-6 < EXTFAC < 0.1; EXTFAC=%r' % value
1513+
else:
1514+
# FRICMOD, FPARA1/2/3/4/5, EPSN, EPST, CFACTOR1, PENETOL
1515+
# NCMOD, TCMOD, RFORCE, LFORCE, RTPCHECK, RTPMAX, XTYPE
1516+
# ...
1517+
value = integer_double_or_blank(card, i+1, 'value%s' % j)
1518+
assert value is not None, '%s%i must not be None' % (param, j)
1519+
return param, value
1520+
1521+
def raw_fields(self) -> list[str | int | float]:
15241522
fields = ['BCTPARM', self.csid]
1525-
i = 0
1526-
for key, value in sorted(self.params.items()):
1527-
if i == 3:
1528-
fields.append(None)
1529-
i = 0
1530-
fields.append(key)
1531-
fields.append(value)
1532-
i += 1
1523+
fields.extend(params_listify(self.params))
15331524
return fields
15341525

15351526
def write_card(self, size: int=8, is_double: bool=False) -> str:
@@ -1606,83 +1597,77 @@ def add_card(cls, card: BDFCard, comment: str=''):
16061597
16071598
"""
16081599
csid = integer(card, 1, 'csid')
1609-
i = 2
1610-
j = 1
1611-
params = {}
1600+
16121601
all_params = [
16131602
'TYPE', 'NSIDE', 'TBIRTH', 'TDEATH', 'INIPENE',
16141603
'PDEPTH', 'SEGNORM', 'OFFTYPE', 'OFFSET',
16151604
'TZPENE', 'CSTIFF', 'TIED', 'TIEDTOL', 'EXTFAC']
16161605
all_params.sort()
1617-
while i < card.nfields:
1618-
param = string(card, i, f'param{j}')
1619-
assert param in all_params, f'param={param!r} is not allowed; allowed={all_params}'
1620-
i += 1
1621-
if param == 'TYPE':
1622-
value = integer_or_blank(card, i, 'value%s' % j, default=0)
1623-
assert value in [0, 1, 2], 'TYPE must be [0, 1, 2]; TYPE=%r' % value
1624-
#elif param == 'TYPE': # NX
1625-
#value = string_or_blank(card, i, 'value%s' % j, 'FLEX').upper()
1626-
#assert value in ['FLEX', 'RIGID', 'COATING'], 'TYPE must be [FLEX, RIGID, COATING.]; CSTIFF=%r' % value
1627-
1628-
elif param == 'NSIDE':
1629-
value = integer_or_blank(card, i, 'value%s' % j, default=1)
1630-
assert value in [1, 2], 'NSIDE must be [1, 2]; NSIDE=%r' % value
1631-
elif param == 'TBIRTH':
1632-
value = double_or_blank(card, i, 'value%s' % j, default=0.0)
1633-
elif param == 'TDEATH':
1634-
value = double_or_blank(card, i, 'value%s' % j, default=0.0)
1635-
elif param == 'INIPENE':
1636-
value = integer_or_blank(card, i, 'value%s' % j, default=0)
1637-
assert value in [0, 1, 2, 3], 'INIPENE must be [0, 1, 2]; INIPENE=%r' % value
1638-
elif param == 'PDEPTH':
1639-
value = double_or_blank(card, i, 'value%s' % j, default=0.0)
1640-
elif param == 'SEGNORM':
1641-
value = integer_or_blank(card, i, 'value%s' % j, default=0)
1642-
assert value in [-1, 0, 1], 'SEGNORM must be [-1, 0, 1]; SEGNORM=%r' % value
1643-
elif param == 'OFFTYPE':
1644-
value = integer_or_blank(card, i, 'value%s' % j, default=0)
1645-
assert value in [0, 1, 2], 'OFFTYPE must be [0, 1, 2]; OFFTYPE=%r' % value
1646-
elif param == 'OFFSET':
1647-
value = double_or_blank(card, i, 'value%s' % j, default=0.0)
1648-
elif param == 'TZPENE':
1649-
value = double_or_blank(card, i, 'value%s' % j, default=0.0)
1650-
1651-
elif param == 'CSTIFF':
1652-
value = integer_or_blank(card, i, 'value%s' % j, default=0)
1653-
assert value in [0, 1], 'CSTIFF must be [0, 1]; CSTIFF=%r' % value
1654-
elif param == 'TIED':
1655-
value = integer_or_blank(card, i, 'value%s' % j, default=0)
1656-
assert value in [0, 1], 'TIED must be [0, 1]; TIED=%r' % value
1657-
elif param == 'TIEDTOL':
1658-
value = double_or_blank(card, i, 'value%s' % j, default=0.0)
1659-
elif param == 'EXTFAC':
1660-
value = double_or_blank(card, i, 'value%s' % j, default=0.001)
1661-
assert 1.0E-6 <= value <= 0.1, 'EXTFAC must be 1.0E-6 < EXTFAC < 0.1; EXTFAC=%r' % value
1662-
else:
1663-
# FRICMOD, FPARA1/2/3/4/5, EPSN, EPST, CFACTOR1, PENETOL
1664-
# NCMOD, TCMOD, RFORCE, LFORCE, RTPCHECK, RTPMAX, XTYPE
1665-
# ...
1666-
value = integer_double_or_blank(card, i, 'value%s' % j)
1667-
assert value is not None, '%s%i must not be None' % (param, j)
1606+
params = read_param_dict(card, cls._get_param_value_from_card)
1607+
for param in params:
1608+
if param not in all_params:
1609+
warnings.warn(f'param={param!r} is not allowed; allowed={all_params}\n{str(card)}')
16681610

1669-
params[param] = value
1670-
i += 1
1671-
j += 1
1672-
if j == 4:
1673-
i += 1
16741611
return BCTPARA(csid, params, comment=comment)
16751612

1613+
@staticmethod
1614+
def _get_param_value_from_card(card: BDFCard,
1615+
i: int, j: int) -> tuple[str, int | float]:
1616+
param = string(card, i, f'param{j}')
1617+
# assert param in all_params, f'param={param!r} is not allowed; allowed={all_params}'
1618+
i += 1
1619+
if param == 'TYPE':
1620+
value = integer_or_blank(card, i, 'value%s' % j, default=0)
1621+
assert value in [0, 1, 2], 'TYPE must be [0, 1, 2]; TYPE=%r' % value
1622+
#elif param == 'TYPE': # NX
1623+
#value = string_or_blank(card, i, 'value%s' % j, 'FLEX').upper()
1624+
#assert value in ['FLEX', 'RIGID', 'COATING'], 'TYPE must be [FLEX, RIGID, COATING.]; CSTIFF=%r' % value
1625+
1626+
elif param == 'NSIDE':
1627+
value = integer_or_blank(card, i, 'value%s' % j, default=1)
1628+
assert value in [1, 2], 'NSIDE must be [1, 2]; NSIDE=%r' % value
1629+
elif param == 'TBIRTH':
1630+
value = double_or_blank(card, i, 'value%s' % j, default=0.0)
1631+
elif param == 'TDEATH':
1632+
value = double_or_blank(card, i, 'value%s' % j, default=0.0)
1633+
elif param == 'INIPENE':
1634+
value = integer_or_blank(card, i, 'value%s' % j, default=0)
1635+
assert value in [0, 1, 2, 3], 'INIPENE must be [0, 1, 2]; INIPENE=%r' % value
1636+
elif param == 'PDEPTH':
1637+
value = double_or_blank(card, i, 'value%s' % j, default=0.0)
1638+
elif param == 'SEGNORM':
1639+
value = integer_or_blank(card, i, 'value%s' % j, default=0)
1640+
assert value in [-1, 0, 1], 'SEGNORM must be [-1, 0, 1]; SEGNORM=%r' % value
1641+
elif param == 'OFFTYPE':
1642+
value = integer_or_blank(card, i, 'value%s' % j, default=0)
1643+
assert value in [0, 1, 2], 'OFFTYPE must be [0, 1, 2]; OFFTYPE=%r' % value
1644+
elif param == 'OFFSET':
1645+
value = double_or_blank(card, i, 'value%s' % j, default=0.0)
1646+
elif param == 'TZPENE':
1647+
value = double_or_blank(card, i, 'value%s' % j, default=0.0)
1648+
1649+
elif param == 'CSTIFF':
1650+
value = integer_or_blank(card, i, 'value%s' % j, default=0)
1651+
assert value in [0, 1], 'CSTIFF must be [0, 1]; CSTIFF=%r' % value
1652+
elif param == 'TIED':
1653+
value = integer_or_blank(card, i, 'value%s' % j, default=0)
1654+
assert value in [0, 1], 'TIED must be [0, 1]; TIED=%r' % value
1655+
elif param == 'TIEDTOL':
1656+
value = double_or_blank(card, i, 'value%s' % j, default=0.0)
1657+
elif param == 'EXTFAC':
1658+
value = double_or_blank(card, i, 'value%s' % j, default=0.001)
1659+
assert 1.0E-6 <= value <= 0.1, 'EXTFAC must be 1.0E-6 < EXTFAC < 0.1; EXTFAC=%r' % value
1660+
else:
1661+
# FRICMOD, FPARA1/2/3/4/5, EPSN, EPST, CFACTOR1, PENETOL
1662+
# NCMOD, TCMOD, RFORCE, LFORCE, RTPCHECK, RTPMAX, XTYPE
1663+
# ...
1664+
value = integer_double_or_blank(card, i, 'value%s' % j)
1665+
assert value is not None, '%s%i must not be None' % (param, j)
1666+
return param, value
1667+
16761668
def raw_fields(self):
16771669
fields = ['BCTPARA', self.csid]
1678-
i = 0
1679-
for key, value in sorted(self.params.items()):
1680-
if i == 3:
1681-
fields.append(None)
1682-
i = 0
1683-
fields.append(key)
1684-
fields.append(value)
1685-
i += 1
1670+
fields.extend(params_listify(self.params))
16861671
return fields
16871672

16881673
def write_card(self, size: int=8, is_double: bool=False) -> str:
@@ -1912,3 +1897,50 @@ def write_card(self, size: int=8, is_double: bool=False) -> str:
19121897
if size == 8:
19131898
return self.comment + print_card_8(card)
19141899
return self.comment + print_card_16(card)
1900+
1901+
1902+
def params_listify(params: dict[str, int | float],
1903+
) -> list[str | int | float]:
1904+
"""
1905+
Annoying function for contact params.
1906+
1907+
3 sets of params are allowed per line, but:
1908+
- 1 blank on the first line
1909+
- 2 blanon the 2nd/3rd/etc. line
1910+
1911+
"""
1912+
i = 0
1913+
fields = []
1914+
for j, (key, value) in enumerate(sorted(params.items())):
1915+
if j == 3:
1916+
fields.append(None)
1917+
i = 0
1918+
elif j > 0 and i == 3:
1919+
fields.append(None)
1920+
fields.append(None)
1921+
i = 0
1922+
fields.append(key)
1923+
fields.append(value)
1924+
i += 1
1925+
return fields
1926+
1927+
1928+
def read_param_dict(card: BDFCard,
1929+
read_func) -> dict[str, int | float]:
1930+
"""reading version of params_listify"""
1931+
params = {}
1932+
iline = 0
1933+
ifield = 2
1934+
iparam = 0
1935+
while ifield < card.nfields:
1936+
param, value = read_func(card, ifield, iparam+1)
1937+
params[param] = value
1938+
iparam += 1
1939+
if iparam % 3 == 0:
1940+
# every 3 params, reset the line
1941+
ifield = 9 + 8 * iline
1942+
iline += 1
1943+
else:
1944+
ifield += 2
1945+
assert len(params) > 0, card
1946+
return params

0 commit comments

Comments
 (0)