from pathlib import Path import numpy as np from femsurrogate.fea.benchmark import cantilever_tip_displacement from femsurrogate.fea.io import read_beam_example, read_expected_displacements from femsurrogate.fea.solver import solve_linear_static ROOT = Path(__file__).resolve().parents[1] INPUT_PATH = ROOT / "BeamExamples" / "CantileverBeam.txt" EXPECTED_PATH = ROOT / "BeamExamples" / "CantileverBeam_Displacements.txt" def test_solver_matches_cantilever_fixture_displacements(): model = read_beam_example(INPUT_PATH) actual = solve_linear_static(model) expected = read_expected_displacements(EXPECTED_PATH) assert set(actual) == set(expected) for node_id, expected_displacement in expected.items(): actual_displacement = actual[node_id] np.testing.assert_allclose( [actual_displacement.ux, actual_displacement.uy, actual_displacement.rz], [expected_displacement.ux, expected_displacement.uy, expected_displacement.rz], atol=5e-7, rtol=1e-6, ) def test_tip_displacement_matches_analytical_cantilever_magnitude(): model = read_beam_example(INPUT_PATH) actual_tip_uy = solve_linear_static(model)[6].uy node_x = [node.x for node in model.nodes.values()] length = max(node_x) - min(node_x) analytical_tip_uy = cantilever_tip_displacement( force_y=model.nodal_loads[6].fy, length=length, E=model.metadata["ElasticModulus"], Izz=model.metadata["Izz"], ) np.testing.assert_allclose(abs(actual_tip_uy), abs(analytical_tip_uy), rtol=1e-9, atol=0.0)