diff --git a/pytest.ini b/pytest.ini index 6e2d1ae52..9f230722f 100644 --- a/pytest.ini +++ b/pytest.ini @@ -2,3 +2,5 @@ markers = run: tests that exercise the `run` subpackage keywords: tests that exercies the `keyword` subpackage + viz: tests that do 3d visualization +xfail_strict = true \ No newline at end of file diff --git a/tests/conftest.py b/tests/conftest.py index a923d58c5..f726eb92f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -162,6 +162,8 @@ def pytest_collection_modifyitems(config, items): return # command line has a -k or -m, let pytest handle it skip_run = pytest.mark.skip(reason="run not selected for pytest run (`pytest -m run`). Skip by default") [item.add_marker(skip_run) for item in items if "run" in item.keywords] + skip_viz = pytest.mark.skip(reason="viz not selected for pytest run (`pytest -m viz`). Skip by default") + [item.add_marker(skip_viz) for item in items if "viz" in item.keywords] class StringUtils: diff --git a/tests/test_plotter.py b/tests/test_plotter.py new file mode 100644 index 000000000..e9765f2e5 --- /dev/null +++ b/tests/test_plotter.py @@ -0,0 +1,160 @@ +# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import numpy.testing +import pandas as pd +import pytest + +from ansys.dyna.core import Deck +from ansys.dyna.core.lib.deck_plotter import ( + extract_shell_facets, + get_polydata, + line_array, + map_facet_nid_to_index, + np, + shell_facet_array, +) + + +@pytest.mark.keywords +def test_shell_facet_array(): + na = pd.Int32Dtype().na_value + test_1_pddf = pd.DataFrame( + { + "n1": [1, 2, 106, 2, 0, 1], + "n2": [2, 3, 127, 4, 0, 2], + "n3": [3, 4, 128, 5, 0, 0], + "n4": [0, 1, 107, na, 0, 0], + } + ) + test = [x for x in test_1_pddf.itertuples(index=False)] + numpy.testing.assert_allclose(shell_facet_array(test[0]), np.array([3, 1, 2, 3])) + numpy.testing.assert_allclose(shell_facet_array(test[1]), np.array([4, 2, 3, 4, 1])) + numpy.testing.assert_allclose(shell_facet_array(test[2]), np.array([4, 106, 127, 128, 107])) + numpy.testing.assert_allclose(shell_facet_array(test[3]), np.array([3, 2, 4, 5])) + numpy.testing.assert_allclose(shell_facet_array(test[4]), np.array([])) + numpy.testing.assert_allclose(shell_facet_array(test[5]), np.array([])) + + test_2_pddf = pd.DataFrame( + { + "n1": [0, 1, 2, 3, 3, 1], + "n2": [0, 2, 3, 4, 4, 1], + "n3": [0, 3, 4, 5, 5, 1], + "n4": [0, 0, 1, 6, 6, 1], + "n5": [0, 4, 2, 7, 7, 1], + "n6": [0, 1, 3, 8, 8, 1], + "n7": [0, 2, 4, 0, na, 1], + "n8": [0, 3, 4, 0, na, 0], + } + ) + test = [x for x in test_2_pddf.itertuples(index=False)] + numpy.testing.assert_allclose(shell_facet_array(test[0]), np.array([])) + numpy.testing.assert_allclose(shell_facet_array(test[1]), np.array([3, 1, 2, 3])) + numpy.testing.assert_allclose(shell_facet_array(test[2]), np.array([4, 2, 3, 4, 1])) + numpy.testing.assert_allclose(shell_facet_array(test[3]), np.array([3, 3, 4, 5])) + numpy.testing.assert_allclose(shell_facet_array(test[4]), np.array([3, 3, 4, 5])) + numpy.testing.assert_allclose(shell_facet_array(test[5]), np.array([])) + + +@pytest.mark.keywords +def test_line_array(): + na = pd.Int32Dtype().na_value + test_1_pddf = pd.DataFrame( + { + "n1": [1, 2, 0, na, 1], + "n2": [2, 0, 0, 0, na], + } + ) + test = [x for x in test_1_pddf.itertuples(index=False)] + numpy.testing.assert_allclose(line_array(test[0]), np.array([2, 1, 2])) + numpy.testing.assert_allclose(line_array(test[1]), np.array([])) + numpy.testing.assert_allclose(line_array(test[2]), np.array([])) + numpy.testing.assert_allclose(line_array(test[3]), np.array([])) + numpy.testing.assert_allclose(line_array(test[4]), np.array([])) + + +@pytest.mark.keywords +def test_facet_nid_to_index(): + numpy.testing.assert_allclose( + map_facet_nid_to_index( + np.array([3, 1, 2, 3, 4, 1, 2, 3, 4, 4, 1, 2, 3, 4, 3, 1, 2, 3]), + {1: 2, 2: 3, 3: 4, 4: 5}, + ), + np.array([3, 2, 3, 4, 4, 2, 3, 4, 5, 4, 2, 3, 4, 5, 3, 2, 3, 4]), + ) + + +@pytest.mark.keywords +def test_extract_shell_facets(): + test_1_pddf = pd.DataFrame( + { + "eid": [1, 3], + "pid": [1, 3], + "n1": [1, 2], + "n2": [2, 3], + "n3": [3, 4], + "n4": [0, 1], + } + ) + numpy.testing.assert_allclose( + extract_shell_facets(test_1_pddf, {1: 1, 2: 2, 3: 3, 4: 4}), + [3, 1, 2, 3, 4, 2, 3, 4, 1], + ) + numpy.testing.assert_allclose( + extract_shell_facets(test_1_pddf, {1: 2, 2: 3, 3: 4, 4: 5}), + [3, 2, 3, 4, 4, 3, 4, 5, 2], + ) + + +@pytest.mark.viz +def test_get_polydata(file_utils): + deck = Deck() + keyword_string = file_utils.read_file(file_utils.assets_folder / "plot_test.k") + deck.loads(keyword_string) + + plot_data = get_polydata(deck) + numpy.testing.assert_allclose( + plot_data.faces, + np.array( + [ + 4, + 0, + 1, + 2, + 3, + 3, + 0, + 1, + 2, + 4, + 0, + 1, + 2, + 3, + 3, + 0, + 1, + 2, + ] + ), + ) + numpy.testing.assert_allclose(plot_data.lines, np.array([2, 19, 3, 2, 20, 9])) diff --git a/tests/test_variable_card.py b/tests/test_variable_card.py index e0e217343..145db0511 100644 --- a/tests/test_variable_card.py +++ b/tests/test_variable_card.py @@ -118,13 +118,3 @@ def test_variable_card_read_long(string_utils): assert v[0] == 1.0 assert v[1] == 2.0 assert math.isnan(v[2]) - - -@pytest.mark.xfail(reason = "Keyword module not yet available.") -@pytest.mark.keywords -def test_variable_card_read_write_set(ref_string): - """test to read and write variable cards, especially checking case where last card contains all fields""" - set_string = ref_string.test_variable_card_sets_string - input_deck = Deck() - input_deck.loads(set_string) - assert input_deck.write() == set_string diff --git a/tests/testfiles/keywords/plot_test.k b/tests/testfiles/keywords/plot_test.k new file mode 100644 index 000000000..50b8d92b0 --- /dev/null +++ b/tests/testfiles/keywords/plot_test.k @@ -0,0 +1,42 @@ +*KEYWORD +*ELEMENT_SHELL +$# eid pid n1 n2 n3 n4 n5 n6 n7 n8 + 2 1 1 2 3 4 0 0 0 0 + 3 1 1 2 3 0 0 0 0 0 + 7 1 1 2 3 4 5 6 7 0 + 8 1 1 2 3 4 5 6 7 8 + 9 1 1 2 3 4 5 6 0 0 + 10 1 1 2 + 11 1 1 + +*ELEMENT_BEAM +$ eid pid n1 n2 n3 + 45000 45 20 4 12 + 45001 45 21 10 + 45002 45 20 + 45003 45 20 0 0 + +*NODE +$# nid x y z tc rc + 1 -500.0 0.0 0.0 0 0 + 2 -450.0 0.0 0.0 0 0 + 3 -500.0 50.0 0.0 0 0 + 4 -450.0 50.0 0.0 0 0 + 5 -500.0 50.0 50.0 0 0 + 6 -450.0 50.0 50.0 0 0 + 7 -500.0 50.0 100.0 0 0 + 8 -450.0 50.0 100.0 0 0 + 9 -500.0 50.0 150.0 0 0 + 10 -450.0 50.0 150.0 0 0 + 11 -500.0 50.0 200.0 0 0 + 12 -450.0 50.0 200.0 0 0 + 13 -500.0 50.0 250.0 0 0 + 14 -450.0 50.0 250.0 0 0 + 15 -500.0 50.0 300.0 0 0 + 16 -450.0 50.0 300.0 0 0 + 17 -500.0 50.0 350.0 0 0 + 18 -450.0 50.0 350.0 0 0 + 19 -500.0 50.0 400.0 0 0 + 20 -450.0 50.0 400.0 0 0 + 21 -500.0 50.0 450.0 0 0 +*END