Skip to content

Commit 23d10e4

Browse files
committed
more tests
1 parent 6ac7149 commit 23d10e4

File tree

7 files changed

+120
-26
lines changed

7 files changed

+120
-26
lines changed

pyNastran/converters/nastran/gui/nastran_io.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ def get_xyz_in_coord(self, model: BDF,
418418
'renumbering; duplicate nids=\n%s' % duplicates(all_nids))
419419
raise NotImplementedError(msg)
420420

421-
if not is_monotonic(all_nids):
421+
if not is_monotonic(all_nids, is_strict=True):
422422
# msg = ('superelement nodes are not monotonic; use superelement_renumber\n'
423423
# 'renumbering; nids=\n%s' % all_nids)
424424
# self.log.warning(msg)

pyNastran/f06/dev/flutter/test_gui_flutter.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,14 @@ def test_action(self) -> None:
2828

2929
def test_load_f06_op2(self) -> None:
3030
f06_filename = MODEL_PATH / 'aero' / '2_mode_flutter' / '0012_flutter.op2'
31-
log = SimpleLogger(level='debug')
31+
log = SimpleLogger(level='info')
3232
in_units = 'si'
3333
out_units = 'si'
3434
load_f06_op2(f06_filename, log, in_units, out_units, use_rhoref=False)
3535

36+
op2_filename = MODEL_PATH / 'bwb' / 'bwb_saero.op2'
37+
load_f06_op2(op2_filename, log, in_units, out_units, use_rhoref=False)
38+
3639

3740
if __name__ == '__main__':
3841
unittest.main()

pyNastran/f06/test/all_tests.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
from pyNastran.f06.test.test_f06_formatting import TestF06Formatting
22
from pyNastran.f06.test.test_f06_utils import (
33
TestF06Utils, TestF06Flutter, TestZonaFlutter)
4+
45
from pyNastran.f06.dev.flutter.test_zona import TestZona
6+
from pyNastran.f06.dev.flutter.test_gui_flutter import TestGuiFlutter
57

68

79
if __name__ == "__main__": # pragma: no cover

pyNastran/femutils/coord_utils.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from .matrix3d import axes_stack, normalize_vector2d
1212

1313

14-
def coords_from_vector_1d(v_array):
14+
def coords_from_vector_1d(v_array: np.ndarray) -> np.ndarray:
1515
"""
1616
Gets the coordinate systems for a series of 1D vectors.
1717
Fakes the j and k axes.
@@ -209,7 +209,8 @@ def hexa_coord(xyz1, xyz2, xyz3, xyz4,
209209
#return coords
210210

211211

212-
def _coordinate_system_from_vector_2d(v21, normal):
212+
def _coordinate_system_from_vector_2d(v21: np.ndarray,
213+
normal: np.ndarray) -> np.ndarray:
213214
r"""
214215
Helper method::
215216

pyNastran/femutils/matrix3d.py

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,25 @@
1414
import numpy as np
1515

1616

17-
def norm2d(v):
17+
def norm2d(v: np.ndarray) -> np.ndarray:
1818
"""takes N norms of a (N,3) set of vectors"""
1919
mag = np.linalg.norm(v, axis=1)
2020
assert v.shape[0] == len(mag)
2121
return mag
2222

2323

24-
def normalize_vector2d(v):
24+
def normalize_vector2d(v: np.ndarray) -> tuple[np.ndarray, np.ndarray]:
2525
"""normalzes a series of (N,3) vectors"""
2626
mag = norm2d(v)
2727
nmag = len(mag)
2828
i = v / mag[:, np.newaxis]
2929
return i, nmag
3030

3131

32-
def axes_stack(i, j, k, nmag):
32+
def axes_stack(i: np.ndarray,
33+
j: np.ndarray,
34+
k: np.ndarray,
35+
nmag: int) -> np.ndarray:
3336
"""stack coordinate axes in 3d"""
3437
i.shape = (nmag, 1, 3)
3538
j.shape = (nmag, 1, 3)
@@ -38,7 +41,8 @@ def axes_stack(i, j, k, nmag):
3841
return ijk
3942

4043

41-
def dot_33_n33(A, B, debug=True):
44+
def dot_33_n33(A: np.ndarray, B: np.ndarray,
45+
debug: bool=False) -> np.ndarray:
4246
"""
4347
Multiplies a (3x3) matrix by a Nx3x3 matrix
4448
@@ -62,19 +66,20 @@ def dot_33_n33(A, B, debug=True):
6266
dtype = A.dtype
6367
#print('------------------------')
6468
D = np.zeros(B.shape, dtype=dtype)
65-
print('A.shape =', A.shape)
69+
# print('A.shape =', A.shape)
6670
for i, Bi in zip(count(), B):
67-
print('Bi.shape =', Bi.shape)
71+
# print('Bi.shape =', Bi.shape)
6872
ABi = A @ Bi
69-
print('A @ Bi.shape =', ABi.shape)
73+
# print('A @ Bi.shape =', ABi.shape)
7074
D[i, :, :] = ABi
7175
#print(D[i, :, :])
7276
#print('------------------------')
7377
assert np.all(np.allclose(C, D))
7478
return D
7579

7680

77-
def dot_n33_33(A, B, debug=True):
81+
def dot_n33_33(A: np.ndarray, B: np.ndarray,
82+
debug: bool=False) -> np.ndarray:
7883
"""
7984
Multiplies a (3x3) matrix by a Nx3x3 matrix
8085
@@ -113,7 +118,8 @@ def dot_n33_33(A, B, debug=True):
113118
return C
114119

115120

116-
def dot_n33_n33(A: np.ndarray, B: np.ndarray, debug: bool=True) -> np.ndarray:
121+
def dot_n33_n33(A: np.ndarray, B: np.ndarray,
122+
debug: bool=False) -> np.ndarray:
117123
"""
118124
Multiplies two matrices together
119125
@@ -131,7 +137,8 @@ def dot_n33_n33(A: np.ndarray, B: np.ndarray, debug: bool=True) -> np.ndarray:
131137
assert A.shape[1:] == (3, 3), A.shape
132138
assert len(B.shape) == 3, B.shape
133139
assert B.shape[1:] == (3, 3), B.shape
134-
#C = np.matmul(A, B)
140+
141+
C = np.einsum('ijk,ikm->ijm', A, B)
135142
if debug:
136143
dtype = A.dtype
137144
#print('------------------------')
@@ -140,13 +147,15 @@ def dot_n33_n33(A: np.ndarray, B: np.ndarray, debug: bool=True) -> np.ndarray:
140147
D[i, :, :] = Ai @ Bi
141148
#print(D[i, :, :])
142149
#print('------------------------')
150+
assert np.allclose(C, D)
143151
#if not np.all(np.allclose(C, D)):
144152
#print('C:\n%s'% C)
145153
#print('D:\n%s'% D)
146-
return D
154+
return C
147155

148156

149-
def dot_n33_n3(A: np.ndarray, B: np.ndarray, debug: bool=True) -> np.ndarray:
157+
def dot_n33_n3(A: np.ndarray, B: np.ndarray,
158+
debug: bool=False) -> np.ndarray:
150159
"""
151160
Multiplies two N x 3 x 3 matrices together
152161
@@ -189,7 +198,7 @@ def transpose3d(T: np.ndarray) -> np.ndarray:
189198
"""
190199
return np.transpose(T, axes=(0, 2, 1))
191200

192-
def triple_n33_n33(A, T, transpose: bool=False, debug: bool=True) -> np.ndarray:
201+
def triple_n33_n33(A, T, transpose: bool=False, debug: bool=False) -> np.ndarray:
193202
"""
194203
Calculates the matrix triple product for a series of::
195204

pyNastran/femutils/test/test_utils.py

Lines changed: 76 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
import pyNastran
1414
from pyNastran.femutils.io import loadtxt_nice, savetxt_nice
1515
from pyNastran.femutils.matrix3d import dot_n33_n33, transpose3d, triple_n33_n33, triple_n33_33
16-
from pyNastran.femutils.utils import augmented_identity, perpendicular_vector, perpendicular_vector2d
16+
from pyNastran.femutils.utils import (
17+
augmented_identity, perpendicular_vector,
18+
perpendicular_vector2d, vstack_lists,
19+
is_monotonic, duplicates, hstack_unique)
1720
from pyNastran.femutils.coord_transforms import cylindrical_rotation_matrix
1821

1922
from pyNastran.femutils.test.utils import is_array_close
@@ -103,7 +106,8 @@ def test_triple_n33_n33(self):
103106
[0., 0., 1.],
104107
[1., 0., 9.],],
105108
])
106-
TtAT_actual = triple_n33_n33(A, T, transpose=False)
109+
TtAT_actual = triple_n33_n33(A, T, transpose=False, debug=False)
110+
TtAT_actual = triple_n33_n33(A, T, transpose=False, debug=True)
107111
TtAT_expected = [
108112
[[5., 6., 58.],
109113
[8., 9., 88.],
@@ -114,7 +118,8 @@ def test_triple_n33_n33(self):
114118
[74., 84., 820.],],
115119
]
116120
assert is_array_close(TtAT_expected, TtAT_actual)
117-
TATt_actual = triple_n33_n33(A, T, transpose=True)
121+
TATt_actual = triple_n33_n33(A, T, transpose=True, debug=False)
122+
TATt_actual = triple_n33_n33(A, T, transpose=True, debug=True)
118123
TATt_expected = [
119124
[[9., 7., 89.],
120125
[3., 1., 29.],
@@ -142,7 +147,8 @@ def test_triple_n33_33(self):
142147
[0., 0., 1.],
143148
[1., 0., 9.],
144149
])
145-
TtAT_actual = triple_n33_33(A, T, transpose=False)
150+
TtAT_actual = triple_n33_33(A, T, transpose=False, debug=False)
151+
TtAT_actual = triple_n33_33(A, T, transpose=False, debug=True)
146152
TtAT_expected = [
147153
[[5., 6., 58.],
148154
[8., 9., 88.],
@@ -153,7 +159,8 @@ def test_triple_n33_33(self):
153159
[74., 84., 820.],],
154160
]
155161
assert is_array_close(TtAT_expected, TtAT_actual)
156-
TATt_actual = triple_n33_33(A, T, transpose=True)
162+
TATt_actual = triple_n33_33(A, T, transpose=True, debug=False)
163+
TATt_actual = triple_n33_33(A, T, transpose=True, debug=True)
157164
TATt_expected = [
158165
[[9., 7., 89.],
159166
[3., 1., 29.],
@@ -168,6 +175,70 @@ def test_triple_n33_33(self):
168175

169176
class TestNumpyUtils(unittest.TestCase):
170177
"""tests functions in femutils.utils"""
178+
def test_hstack_unique(self):
179+
list_of_arrays = [
180+
[1, 2, 3], [4, 5, 6, 7, 3],
181+
]
182+
stacked = [1, 2, 3, 4, 5, 6, 7, 3]
183+
unique_stacked = [1, 2, 3, 4, 5, 6, 7]
184+
a = hstack_unique(list_of_arrays, unique=False)
185+
b = hstack_unique(list_of_arrays, unique=True)
186+
assert np.array_equal(a, stacked)
187+
assert np.array_equal(b, unique_stacked)
188+
189+
list_of_arrays = [
190+
[1, 2, 3, 4, 5, 6, 7, 3],
191+
]
192+
c = hstack_unique(list_of_arrays, unique=False)
193+
d = hstack_unique(list_of_arrays, unique=True)
194+
assert np.array_equal(c, stacked)
195+
assert np.array_equal(d, unique_stacked)
196+
197+
def test_vstack_list(self):
198+
list_of_arrays = [
199+
[[1, 2, 3]],
200+
[
201+
[1, 2, 3],
202+
[1, 2, 3],
203+
]
204+
]
205+
stacked = [
206+
[1, 2, 3],
207+
[1, 2, 3],
208+
[1, 2, 3],
209+
]
210+
stacked_array = vstack_lists(list_of_arrays)
211+
assert np.array_equal(stacked_array, stacked)
212+
213+
list_of_arrays = [
214+
[[1, 2, 3]],
215+
]
216+
stacked = [[1, 2, 3]]
217+
stacked_array = vstack_lists(list_of_arrays)
218+
assert np.array_equal(stacked_array, stacked), stacked_array
219+
220+
def test_duplicates(self):
221+
a = [1, 2, 3, 4, 5, 2, 3]
222+
b= duplicates(a)
223+
assert np.array_equal(b, [2, 3])
224+
225+
a = [3, 2, 1, 3, 2, 4, 5]
226+
b= duplicates(a)
227+
assert np.array_equal(b, [2, 3])
228+
229+
def test_is_monotonic(self):
230+
a = np.array([1, 2, 3])
231+
b = np.array([1, -2, 3])
232+
c = np.array([1, 2, 2, 3])
233+
234+
assert is_monotonic(a, is_strict=True), (np.diff(a), aa)
235+
assert not is_monotonic(b, is_strict=True), np.diff(b)
236+
assert not is_monotonic(c, is_strict=True), np.diff(c)
237+
238+
assert is_monotonic(a, is_strict=False)
239+
assert not is_monotonic(b, is_strict=False)
240+
assert is_monotonic(c, is_strict=False)
241+
171242
def test_perpendicular_vector(self):
172243
"""tests perpendicular_vector"""
173244
with self.assertRaises(ValueError):

pyNastran/femutils/utils.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,15 @@ def vstack_lists(list_of_arrays: list[np.ndarray]) -> np.ndarray:
7272
Stacks an array
7373
7474
list_of_arrays = [
75+
[
7576
[1, 2, 3],
7677
],
7778
[
7879
[1, 2, 3],
7980
[1, 2, 3],
8081
]
8182
]
82-
stacked [
83+
stacked = [
8384
[1, 2, 3],
8485
[1, 2, 3],
8586
[1, 2, 3],
@@ -210,15 +211,22 @@ def unique2d(a: np.ndarray, return_index=False):
210211
#return uniq.view(data.dtype).reshape(-1, data.shape[1])
211212

212213

213-
def duplicates(ids):
214+
def duplicates(ids: np.ndarray) -> np.ndarray:
214215
"""finds the duplicate ids"""
215216
counts = np.bincount(ids)
216217
return np.where(counts > 1)[0]
217218

218219

219-
def is_monotonic(int_array: np.ndarray) -> bool:
220+
def is_monotonic(int_array: np.ndarray,
221+
is_strict: bool=False,
222+
) -> bool:
220223
"""is the array monotonic?"""
221-
return np.all(int_array[1:] >= int_array[:-1])
224+
diff = np.diff(int_array, n=1)
225+
if is_strict:
226+
out = np.all(diff > 0)
227+
else:
228+
out = np.all(diff >= 0)
229+
return out
222230

223231

224232
def unique_rows(A: np.ndarray, return_index=False, return_inverse=False):

0 commit comments

Comments
 (0)