Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
SteveDoyle2 committed Aug 11, 2023
2 parents 202ce6a + 1da6df2 commit 640f647
Show file tree
Hide file tree
Showing 9 changed files with 385 additions and 208 deletions.
57 changes: 57 additions & 0 deletions pyNastran/bdf/bdf_interface/assign_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,63 @@ def parse_components(card: BDFCard, ifield: int, fieldname: str) -> str:
raise SyntaxError(msg)
return svalue3

def parse_components_or_blank(card: BDFCard, ifield: int, fieldname: str) -> str:
"""
Parameters
----------
card : BDFCard()
BDF card as a list
ifield : int
field number
fieldname : str
name of field
Returns
-------
components : str
a string of the dofs '0' or '123456' (not all are required)
"""
assert isinstance(card, BDFCard), type(card)
assert isinstance(ifield, int), type(ifield)
assert isinstance(fieldname, str), type(fieldname)
svalue = card.field(ifield)
if isinstance(svalue, integer_types):
pass
elif svalue is None:
return '0'
elif '.' in svalue:
dtype = _get_dtype(svalue)
msg = ('%s = %r (field #%s) on card must be an integer or blank (not %s).\n'
'card=%s' % (fieldname, svalue, ifield, dtype, card))
raise SyntaxError(msg)

try:
value = int(svalue)
except ValueError:
dtype = _get_dtype(svalue)
msg = ('%s = %r (field #%s) on card must be an integer or blank (not %s).\n'
'card=%s' % (fieldname, svalue, ifield, dtype, card))
raise SyntaxError(msg)
if value > 0 and isinstance(svalue, str):
if '0' in svalue:
value2 = str(svalue).replace('0', '')
msg = ('%s = %r (field #%s) on card must contain 0 or %s (not both).\n'
'card=%s' % (fieldname, svalue, ifield, value2, card))
raise SyntaxError(msg)
svalue2 = str(value)
svalue3 = ''.join(sorted(svalue2))
for i, component in enumerate(svalue3):
if component not in '0123456':
msg = ('%s = %r (field #%s) on card contains an invalid component %r.\n'
'card=%s' % (fieldname, svalue, ifield, component, card))
raise SyntaxError(msg)
if component in svalue3[i + 1:]:
msg = ('%s = %r (field #%s) on card must not contain duplicate entries.\n'
'card=%s' % (fieldname, svalue, ifield, card))
raise SyntaxError(msg)
return svalue3

def components_or_blank(card: BDFCard,
ifield: int,
fieldname: str,
Expand Down
20 changes: 11 additions & 9 deletions pyNastran/bdf/bdf_interface/subcase/cards.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any
from typing import Union, Any
from pyNastran.utils.numpy_utils import bytes_type
from .subcase_base import CaseControlCard

Expand All @@ -15,7 +15,8 @@
def encode_str_list(strings: list[str], encoding: str) -> list[bytes]:
return [stri.encode(encoding) for stri in strings]

def encode_str_value_list(strings: list[int, float, str], encoding: str) -> list[int, float, bytes]:
def encode_str_value_list(strings: list[Union[int, float, str]],
encoding: str) -> list[Union[int, float, bytes]]:
values_bytes = [stri.encode(encoding) if isinstance(stri, str) else stri
for stri in strings]
return values_bytes
Expand Down Expand Up @@ -147,8 +148,8 @@ def load_hdf5(cls, h5_file, encoding: str) -> Any:

return cls(values)

def _set_options_from_line(line: str, value: str, options: list[str]) -> None:
# ECHO = PUNCH,SORT(MAT1,PARAM)
def _set_options_from_line(line: str, value: str, options: list[str]) -> list[str]:
"""ECHO = PUNCH,SORT(MAT1,PARAM)"""
is_comma = ',' in value
is_paren = '(' in value
if is_comma and is_paren:
Expand Down Expand Up @@ -231,16 +232,16 @@ class CheckCard(CaseControlCard):
"""
type = 'CheckCard'
allowed_keys = set([]) # type: set[str]
allowed_keys: set[str] = set([])

# key:(type, allowed_values)
allowed_values = {} # type: dict[str, Union[float, str]]
allowed_values: dict[str, Union[float, str]] = {}

# the allowed value for the key, options, value approach
allowed_strings = set([]) # type: set[str]
allowed_strings: set[str] = set([])

# maps something like INIT to INITIAL
duplicate_names = {} # type: dict[Any, Any]
duplicate_names: dict[Any, Any] = {}

# enables values as integers instead of just strings
allow_ints = False
Expand Down Expand Up @@ -799,7 +800,8 @@ class EXTSEOUT(CaseControlCard):
'DAMP', 'DAMPING', 'K4DAMP',
'LOADS',
'DMIGOP2', 'DMIGPCH',
'MATOP4', 'MATRIXOP4'}
'MATOP4', 'MATRIXOP4',
'MODACC'}

def __init__(self, data):
super(EXTSEOUT, self).__init__()
Expand Down
35 changes: 18 additions & 17 deletions pyNastran/bdf/cards/bdf_sets.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
from pyNastran.bdf.bdf_interface.assign_type import (
integer, double, double_or_blank,
integer_or_blank, integer_or_string,
parse_components, components_or_blank as fcomponents_or_blank,
parse_components, parse_components_or_blank, components_or_blank as fcomponents_or_blank,
fields, string, integer_string_or_blank,
)
if TYPE_CHECKING: # pragma: no cover
Expand Down Expand Up @@ -143,7 +143,7 @@ def add_card(cls, card, comment=''):
for n in range(nterms):
i = n * 2 + 1
idi = integer(card, i, 'ID' + str(n))
component = parse_components(card, i + 1, 'component' + str(n))
component = parse_components_or_blank(card, i + 1, 'component' + str(n))
ids.append(idi)
components.append(component)
return cls(ids, components, comment=comment)
Expand Down Expand Up @@ -173,11 +173,12 @@ def uncross_reference(self) -> None:
self.ids_ref = None

@property
def node_ids(self):
def node_ids(self) -> list[int]:
if self.ids_ref is None:
return self.ids
msg = ', which is required by %s' % self.type
return _node_ids(self, self.ids, allow_empty_nodes=True, msg=msg)
nids = _node_ids(self, self.ids, allow_empty_nodes=True, msg=msg)
return nids

def raw_fields(self):
"""gets the "raw" card without any processing as a list for printing"""
Expand Down Expand Up @@ -243,7 +244,7 @@ def add_card(cls, card, comment=''):
for n in range(nterms):
i = n * 2 + 2
idi = integer(card, i, 'ID' + str(n))
component = parse_components(card, i + 1, 'component' + str(n))
component = parse_components_or_blank(card, i + 1, 'component' + str(n))
ids.append(idi)
components.append(component)
return cls(seid, ids, components, comment=comment)
Expand Down Expand Up @@ -564,7 +565,7 @@ def __repr__(self):
return self.comment + print_card_8(list_fields)


class SuperABQSet1(Set):
class SuperABCQSet1(Set):
"""
Generic Class SEBSET1, SEQSET1 cards inherit from.
Expand All @@ -580,7 +581,7 @@ class SuperABQSet1(Set):
| SEBSET1 | SEID | C | ID1 | THRU | ID2 | | | |
+----------+------+-----+------+------+-----+-----+-----+-----+
"""
type = 'SuperABQSet1'
type = 'SuperABCQSet1'
def _finalize_hdf5(self, encoding):
"""hdf5 helper function"""
if isinstance(self.ids, np.ndarray):
Expand Down Expand Up @@ -618,7 +619,7 @@ def add_card(cls, card, comment=''):
ids = []
i = 1
for ifield in range(3, nfields):
idi = integer_string_or_blank(card, ifield, 'ID%i' % i)
idi = integer_string_or_blank(card, ifield, 'ID%d' % i)
if idi:
i += 1
ids.append(idi)
Expand Down Expand Up @@ -1254,7 +1255,7 @@ def __init__(self, sid: int, macro: int,
sp1: float, sp2: float,
ch1: float, ch2: float,
zmax: float=0.0, zmin: float=0.0,
comment: str='') -> SET2:
comment: str='') -> None:
"""
Creates a SET2 card, which sefines a list of structural
grid points in terms of aerodynamic macro elements.
Expand Down Expand Up @@ -1332,7 +1333,7 @@ def raw_fields(self):
return ['SET2', self.sid, self.macro, self.sp1, self.sp2,
self.ch1, self.ch2, self.zmax, self.zmin]

def cross_reference_set(self, model, xref_type: str, msg=''):
def cross_reference_set(self, model, xref_type: Optional[str], msg=''):
"""
Cross links the card so referenced cards can be extracted directly
Expand All @@ -1354,7 +1355,7 @@ def cross_reference_set(self, model, xref_type: str, msg=''):
def get_ids(self):
return []

def safe_cross_reference(self, model: BDF, xref_type: str, msg=''):
def safe_cross_reference(self, model: BDF, xref_type: Optional[str], msg=''):
msg = f', which is required by SET2 sid={self.sid}{msg}'
if xref_type == 'MACRO':
self.macro_ref = model.CAero(self.macro, msg=msg)
Expand Down Expand Up @@ -1669,7 +1670,7 @@ def _init_from_empty(cls):
def __init__(self, seid, ids, components, comment=''):
SuperABCQSet.__init__(self, seid, ids, components, comment)

class SEBSET1(SuperABQSet1):
class SEBSET1(SuperABCQSet1):
"""
Defines boundary degrees-of-freedom to be fixed (b-set) during
generalized dynamic reduction or component mode synthesis
Expand Down Expand Up @@ -1697,7 +1698,7 @@ def _init_from_empty(cls):
return SEBSET1(seid, ids, components, comment='')

def __init__(self, seid, ids, components, comment=''):
SuperABQSet1.__init__(self, seid, ids, components, comment)
SuperABCQSet1.__init__(self, seid, ids, components, comment)


class SECSET(SuperABCQSet):
Expand All @@ -1714,7 +1715,7 @@ def _init_from_empty(cls):
def __init__(self, seid, ids, components, comment=''):
SuperABCQSet.__init__(self, seid, ids, components, comment)

class SECSET1(SuperABQSet1):
class SECSET1(SuperABCQSet1):
"""
Defines SECSET1
Expand All @@ -1740,7 +1741,7 @@ def _init_from_empty(cls):
return SECSET1(seid, ids, components, comment='')

def __init__(self, seid, ids, components, comment=''):
SuperABQSet1.__init__(self, seid, ids, components, comment)
SuperABCQSet1.__init__(self, seid, ids, components, comment)


class SEQSET(SuperABCQSet):
Expand All @@ -1757,7 +1758,7 @@ def _init_from_empty(cls):
def __init__(self, seid, ids, components, comment=''):
SuperABCQSet.__init__(self, seid, ids, components, comment)

class SEQSET1(SuperABQSet1):
class SEQSET1(SuperABCQSet1):
type = 'SEQSET1'
_properties = ['node_ids']

Expand All @@ -1769,7 +1770,7 @@ def _init_from_empty(cls):
return SEQSET1(seid, ids, components, comment='')

def __init__(self, seid, ids, components, comment=''):
SuperABQSet1.__init__(self, seid, ids, components, comment)
SuperABCQSet1.__init__(self, seid, ids, components, comment)


class SEQSEP(SetSuper): # not integrated...is this an SESET ???
Expand Down
25 changes: 22 additions & 3 deletions pyNastran/converters/nastran/gui/nastran_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
isgreater_int)
from pyNastran.femutils.utils import duplicates, is_monotonic, underflow_norm


from pyNastran.bdf.patran_utils.colon_syntax import _apply_colon_set
from pyNastran.bdf.bdf import (BDF,
CAERO1, CAERO2, CAERO3, CAERO4, CAERO5,
#CTRSHL,
Expand Down Expand Up @@ -355,7 +357,6 @@ def _remove_old_nastran_geometry(self, bdf_filename: str) -> bool:

#self.gui.eid_map = {}
#self.gui.nid_map = {}

self.gui.result_cases = {}
self.gui.ncases = 0

Expand Down Expand Up @@ -1969,6 +1970,21 @@ def set_spc_mpc_suport_grid(self, model, nid_to_pid_map, idtype):
mpc_id, model, rigid_lines,
depname, indname, linename, idtype)

for grid_name, group in model.model_groups.items():
if len(group.nodes):
nids_colon = []
for groupi in group.nodes:
colon_groupi = '%d:%d:%d' % groupi
expanded_nids = _apply_colon_set(colon_groupi)
nids_colon.extend(expanded_nids)
nids = np.unique(np.hstack(nids_colon))
msg = f', which is required by {grid_name!r}'
self.gui.create_alternate_vtk_grid(
grid_name, color=RED_FLOAT, opacity=1.0, point_size=4,
representation='point', is_visible=True)
self._add_nastran_nodes_to_grid(grid_name, nids, model, msg)
del nids, nids_colon

geometry_names = spc_names + mpc_names + suport_names
return geometry_names

Expand Down Expand Up @@ -2177,7 +2193,7 @@ def _fill_dependent_independent(self, unused_mpc_id: int, model: BDF, lines,
if line not in lines2:
lines2.append(line)
lines = np.array(lines2, dtype=idtype)
dependent = (lines[:, 0])
dependent = lines[:, 0]
independent = np.unique(lines[:, 1])
self.dependents_nodes.update(dependent)
unused_node_ids = np.unique(lines.ravel())
Expand All @@ -2194,18 +2210,21 @@ def _fill_dependent_independent(self, unused_mpc_id: int, model: BDF, lines,
mpc_names = [depname, indname, linename]
return mpc_names

def _add_nastran_nodes_to_grid(self, name, node_ids, model, msg, store_msg=False):
def _add_nastran_nodes_to_grid(self, name: str, node_ids: list[int],
model: BDF, msg: str, store_msg: bool=False):
"""used to create MPC independent/dependent nodes"""
nnodes = len(node_ids)
stored_msg = []
if nnodes == 0:
msg = '0 nodes added for %r' % name
out_msg = store_warning(model.log, store_msg, msg)
aa
return out_msg
self.gui.follower_nodes[name] = node_ids

#numpy_to_vtk_points(nodes)
points = vtkPoints()
print(name, 'nnodes', nnodes)
points.SetNumberOfPoints(nnodes)

j = 0
Expand Down
Loading

0 comments on commit 640f647

Please sign in to comment.