Skip to content

Commit

Permalink
fixing tests
Browse files Browse the repository at this point in the history
properly writing WKK
flutter response now takes custom lines, so you can set VL, VD, VF, etc. and specify colors/thickness/etc.
  • Loading branch information
Steve Doyle committed Nov 30, 2024
1 parent 1b904bc commit 55f7556
Show file tree
Hide file tree
Showing 10 changed files with 277 additions and 109 deletions.
28 changes: 1 addition & 27 deletions packages.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""helper for setup.py"""
import os
import sys
from typing import List
from pyNastran.utils.version_utils import int_version, str_version

EXCLUDE_WORDS = [
'pyNastran.f06.dev',
Expand Down Expand Up @@ -42,32 +42,6 @@ def check_python_version() -> None:
sys.exit('Upgrade your Python to 3.10+; version=(%s.%s.%s)' % (
imajor, minor1, minor2))

def int_version(name: str, version: str) -> List[int]:
"""splits the version into a tuple of integers"""
sversion = version.split('-')[0]
#numpy
#scipy
#matplotlib
#qtpy
#vtk
#cpylog
#pyNastran
if 'rc' not in name:
# it's gotta be something...
# matplotlib3.1rc1
sversion = sversion.split('rc')[0]

try:
return [int(val) for val in sversion.split('.')]
except ValueError:
raise SyntaxError('cannot determine version for %s %s' % (name, sversion))


def str_version(version: str) -> str:
"""converts a tuple of integers to a version number"""
return '.'.join(str(versioni) for versioni in version)


def update_version_file():
"""
Creates the version.py file with the github string
Expand Down
11 changes: 4 additions & 7 deletions pyNastran/bdf/bdf_interface/add_card.py
Original file line number Diff line number Diff line change
Expand Up @@ -9102,13 +9102,10 @@ def add_dense_dmi(self, name: str, myarray: np.ndarray,
raise NotImplementedError(str_form)

# ncols = 2
GC = np.repeat(list(range(1, nrows+1)), ncols, axis=0)
# print('GC =', GC)
GCi = GC.reshape(nrows, ncols)
# print('GCi =', GCi)
GCj = GCi.T.flatten()
GCi = GCi.flatten()

GCi = np.repeat(list(range(1, nrows+1)), ncols, axis=0).reshape(nrows, ncols).flatten()
GCj = np.repeat(list(range(1, ncols+1)), nrows, axis=0).reshape(nrows, ncols).flatten()
#self.log.warning(f'GCi = {GCi}')
#self.log.warning(f'GCj = {GCj}')

Real = myarray.real.flatten()
Complex = None
Expand Down
65 changes: 50 additions & 15 deletions pyNastran/bdf/cards/dmig.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,10 @@ def __deepcopy__(self, memo):
setattr(result, key, deepcopy(value, memo))
return result

@property
def matrix_form_str(self) -> str:
return DMI_MATRIX_MAP[self.matrix_form]

@classmethod
def add_card(cls, card, comment=''):
"""
Expand All @@ -496,7 +500,7 @@ def add_card(cls, card, comment=''):
name = string(card, 1, 'name')
#zero

matrix_form = integer(card, 3, 'ifo')
matrix_form = integer(card, 3, 'ifo/matrix_form')
tin = integer(card, 4, 'tin')
tout = integer_or_blank(card, 5, 'tout', default=0)
polar = integer_or_blank(card, 6, 'polar', default=0)
Expand Down Expand Up @@ -2265,7 +2269,9 @@ def get_matrix(self,
.. warning:: is_sparse=True WILL fail
"""
return get_dmi_matrix(self, is_sparse=is_sparse, apply_symmetry=apply_symmetry)
mat, rows, cols = get_dmi_matrix(
self, is_sparse=is_sparse, apply_symmetry=apply_symmetry)
return mat, rows, cols

def write_card_16(self):
"""writes the card in single precision"""
Expand Down Expand Up @@ -2770,27 +2776,41 @@ def get_dmi_matrix(matrix: DMI,
else:
data = matrix.Real

if ifo in {2, 9}:
matrix_form_str = matrix.matrix_form_str
if matrix_form_str in {'rectangular', 'identity'}: # 2, 9
# rectangular
nrows = matrix.nrows
ncols = matrix.ncols
try:
M = coo_matrix((data, (GCi, GCj)),
shape=(nrows, ncols), dtype=dtype)
except ValueError:
print(f'nrows, cols = ({nrows}, {ncols})')
print('data = ', data)
print('GCi = ', GCi)
print('GCj = ', GCj)
raise
M = _set_matrix(nrows, ncols,
data, GCi, GCj,
dtype)
elif matrix_form_str == 'diagonal':
nrows = max(matrix.nrows, matrix.ncols)
assert matrix.ncols == 1, (matrix.nrows, matrix.ncols)
GCj = np.zeros(len(GCi), dtype=GCi.dtype)
ncols = 1
M = _set_matrix(nrows, ncols,
data, GCi, GCj,
dtype)
elif matrix_form_str == 'square':
nrows = matrix.nrows
ncols = matrix.ncols
assert nrows == ncols, (nrows, ncols)
M = _set_matrix(nrows, ncols,
data, GCi, GCj,
dtype)
else:
raise RuntimeError(matrix_form_str)
nrows = matrix.nrows
ncols = matrix.ncols
if ifo == 6:
if matrix_form_str == 'symmetric':
nrows = max(nrows, ncols)
ncols = nrows
M = coo_matrix((data, (GCi, GCj)),
shape=(nrows, ncols), dtype=dtype)
#matrix_form_str = 'square'
M = _set_matrix(nrows, ncols,
data, GCi, GCj,
dtype)

if not is_sparse:
M = M.toarray()
#else:
Expand Down Expand Up @@ -2849,6 +2869,21 @@ def get_matrix(self: DMIG,
return M, rows_reversed, cols_reversed


def _set_matrix(nrows: int, ncols: int,
data: np.ndarray,
GCi: np.ndarray, GCj: np.ndarray,
dtype: str) -> coo_matrix:
try:
matrixi = coo_matrix((data, (GCi, GCj)),
shape=(nrows, ncols), dtype=dtype)
except ValueError:
print(f'nrows, cols = ({nrows}, {ncols})')
print('data = ', data)
print('GCi = ', GCi)
print('GCj = ', GCj)
raise
return matrixi

def _export_dmig_to_hdf5(h5_file, model: BDF, dict_obj, encoding: str) -> None:
"""export dmigs, dmij, dmiji, dmik, dmi"""
for name, dmig in dict_obj.items():
Expand Down
86 changes: 59 additions & 27 deletions pyNastran/bdf/mesh_utils/export_caero_mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ def export_caero_mesh(model: BDF,
def _write_subcases_loads(model: BDF,
aero_eid_map: dict[int, int],
is_subpanel_model: bool) -> tuple[str, str]:
"""writes the DMI, DMIJ, DMIK cards to a series of load cases"""
nsubpanels = len(aero_eid_map)
if len(model.dmi) == 0 and len(model.dmij) == 0 and len(model.dmik) == 0 and len(model.dmiji) == 0:
loads = ''
Expand Down Expand Up @@ -268,13 +269,16 @@ def _write_subcases_loads(model: BDF,

def _write_dmi(model: BDF,
aero_eid_map: dict[int, int]) -> tuple[int, str, str]:
"""writes the DMI cards to a series of load cases"""
isubcase = 1
loads = ''
subcases = ''
log = model.log
for name, dmi in model.dmi.items():
form_str = dmi.matrix_form_str
data, rows, cols = dmi.get_matrix(is_sparse=False, apply_symmetry=True)
log.info(f'{name}: shape={data.shape}')
log.info(f'{name}: shape={data.shape}; form_str={form_str}')

if name == 'WTFACT':
# square matrix of (neids,neids) that has values on only? the diagonal
subcases += (
Expand Down Expand Up @@ -326,35 +330,61 @@ def _write_dmi(model: BDF,
loads += f'PLOAD2,{isubcase},{value},{eid}\n'
elif name == 'WKK':
# column matrix of (neids*2,1)
assert data.shape[1] == 1, f'name={name}; shape={data.shape}' # (112,1)

subcases += (
f'SUBCASE {isubcase}\n'
f' SUBTITLE = DMI {name} - FORCE\n'
f' LOAD = {isubcase}\n')

nrows = data.shape[0] // 2
data = data.reshape(nrows, 2)
# TODO: assume first column is forces & second column is moments...verify
loads += f'$ {name} - FORCE\n'
loads += '$ PLOAD2 SID P EID1\n'
for ieid, value in enumerate(data[:, 0].ravel()):
eid = aero_eid_map[ieid]
loads += f'PLOAD2,{isubcase},{value},{eid}\n'
isubcase += 1

subcases += (
f'SUBCASE {isubcase}\n'
f' SUBTITLE = DMI {name} - MOMENT\n'
f' LOAD = {isubcase}\n')
loads += f'$ {name} - MOMENT\n'
loads += '$ PLOAD2 SID P EID1\n'
for ieid, value in enumerate(data[:, 1].ravel()):
eid = aero_eid_map[ieid]
loads += f'PLOAD2,{isubcase},{value},{eid}\n'
matrix_form_str = dmi.matrix_form_str
if matrix_form_str == 'diagonal':
pass
elif matrix_form_str == 'square':
pass
else:
matrix_form_str = 'column'
assert data.shape[1] == 1, f'name={name}; shape={data.shape}' # (112,1)

if matrix_form_str in {'diagonal', 'column'}:
assert data.shape[1] == 1, f'name={name}; shape={data.shape}' # (112,1)
nrows = data.shape[0] // 2
data = data.reshape(nrows, 2)
force_correction = data[:, 0]
moment_correction = data[:, 1]
corrections = [
('FORCE', force_correction),
('MOMENT', moment_correction),
]
elif matrix_form_str == 'square':
assert data.shape[0] == data.shape[1]
force = data[::2,::2]
moment = data[1::2, 1::2]
force_correction_row = force.sum(axis=0)
force_correction_col = force.sum(axis=1)
moment_correction_row = moment.sum(axis=0)
moment_correction_col = moment.sum(axis=1)

corrections = [
('FORCE_ROW', force_correction_row),
('FORCE_COL', force_correction_col),
('MOMENT_ROW', moment_correction_row),
('MOMENT_COL', moment_correction_col),
]
else: # pragma: no cover
raise NotImplementedError(matrix_form_str)

for result_name, correction_column in corrections:
#print(result_name, isubcase)
subcases += (
f'SUBCASE {isubcase}\n'
f' SUBTITLE = DMI {name} - {result_name}\n'
f' LOAD = {isubcase}\n')

loads += f'$ {name} - {result_name}\n'
loads += '$ PLOAD2 SID P EID1\n'
for ieid, value in enumerate(correction_column.ravel()):
eid = aero_eid_map[ieid]
loads += f'PLOAD2,{isubcase},{value},{eid}\n'
isubcase += 1
else: # pragma: no cover
msg = f'{name}:\n'
msg = f'{name} matrix_form_str={matrix_form_str}:\n'
msg += str(data)
#continue
raise NotImplementedError(msg)
isubcase += 1
return isubcase, loads, subcases
Expand Down Expand Up @@ -410,6 +440,7 @@ def _get_subpanel_property(model: BDF, caero_id: int, eid: int,

def _write_properties(model: BDF, bdf_file: TextIO,
pid_method: str='aesurf') -> None:
"""writes the PSHELL with a different comment depending on the pid_method flag"""
if pid_method == 'aesurf':
_write_aesurf_properties(model, bdf_file)
elif pid_method == 'paero':
Expand All @@ -427,6 +458,7 @@ def _write_properties(model: BDF, bdf_file: TextIO,


def _write_aesurf_properties(model: BDF, bdf_file: TextIO) -> None:
"""the AESURF ID will be the PSHELL ID"""
aesurf_mid = 1
for aesurf_id, aesurf in model.aesurf.items():
#cid = aesurf.cid1
Expand Down
25 changes: 24 additions & 1 deletion pyNastran/bdf/mesh_utils/test/test_mesh_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,31 @@ def test_export_caero_mesh_caero1_wkk(self):
GCj, GCi,
Real, Complex=None, comment='wkk')

def test_export_caero_mesh_caero1_wkk2(self):
model = BDF(debug=None)
model.bdf_filename = 'test'
p1 = [0., 0., 0.]
p4 = [0., 1., 0.]
eid = 10
pid = 11
igroup = 1
model.add_caero1(eid, pid, igroup,
p1=p1, x12=1.0,
p4=p4, x43=1.0,
nspan=2,
nchord=2)
model.add_paero1(pid)
model.add_aero(velocity=0., cref=1.0, rho_ref=1.0)
name = 'WKK'
form = 'rectangular'
tin = tout = 1
# nrows = 8
# ncols = 1
# GCj = [1, 1, 1, 1, 1, 1, 1, 1]
# GCi = [1, 2, 3, 4, 5, 6, 7, 8]
Real = [1., 2., 3., 4., 5., 6., 7., 8.]
real_array = np.ones((len(Real), 1))
#model.add_dense_dmi(name+'2', real_array, form, validate=True)
model.add_dense_dmi(name, real_array, form, validate=True)
export_caero_mesh(model, is_subpanel_model=True, )
save_load_deck(model, run_remove_unused=False)

Expand Down
Loading

0 comments on commit 55f7556

Please sign in to comment.