43 lines
1.6 KiB
Python
43 lines
1.6 KiB
Python
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)
|