Some checks failed
CI / lint (pull_request) Has been cancelled
CI / type (pull_request) Has been cancelled
CI / test-headless (macos-latest, 3.10) (pull_request) Has been cancelled
CI / test-headless (macos-latest, 3.11) (pull_request) Has been cancelled
CI / test-headless (macos-latest, 3.12) (pull_request) Has been cancelled
CI / test-headless (ubuntu-latest, 3.10) (pull_request) Has been cancelled
CI / test-headless (ubuntu-latest, 3.11) (pull_request) Has been cancelled
CI / test-headless (ubuntu-latest, 3.12) (pull_request) Has been cancelled
CI / test-headless (windows-latest, 3.10) (pull_request) Has been cancelled
CI / test-headless (windows-latest, 3.11) (pull_request) Has been cancelled
CI / test-headless (windows-latest, 3.12) (pull_request) Has been cancelled
CI / test-gui (pull_request) Has been cancelled
CI / test-integration (macos-latest) (pull_request) Has been cancelled
CI / test-integration (ubuntu-latest) (pull_request) Has been cancelled
CI / test-integration (windows-latest) (pull_request) Has been cancelled
Auto-fixes (UP037, UP038, F401, I001, SIM105, RUF100) plus hand-fixes: drop the now-unused `Union` imports, annotate mutable class attributes with ClassVar, raise ValidationError instead of blind Exception in the zero-length test, delete two dead locals, and bind the per-iteration grid-builder closures to their loop variables (B023).
107 lines
3.9 KiB
Python
107 lines
3.9 KiB
Python
"""Pushover curve axis labels must follow the project's unit system."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import numpy as np
|
|
import pytest
|
|
|
|
pytest.importorskip("PySide6")
|
|
|
|
from otko.core import UnitSystem
|
|
from otko.services.results import PushoverResults
|
|
from otko.views.docks.pushover_curve import (
|
|
PushoverCurveView,
|
|
_is_rotation_dof,
|
|
)
|
|
|
|
|
|
def _pushover(control_dof: int = 1) -> PushoverResults:
|
|
return PushoverResults(
|
|
case_id=1,
|
|
case_name="tst",
|
|
n_steps=5,
|
|
control_node=2,
|
|
control_dof=control_dof,
|
|
control_disp=np.array([0.0, 1.0, 2.0, 3.0, 4.0, 5.0]),
|
|
base_shear=np.array([0.0, 100.0, 200.0, 300.0, 400.0, 500.0]),
|
|
)
|
|
|
|
|
|
def test_is_rotation_dof_ndf3() -> None:
|
|
"""In a 2D/ndf=3 model, only DOF 3 is rotational."""
|
|
assert _is_rotation_dof(1, ndf=3) is False
|
|
assert _is_rotation_dof(2, ndf=3) is False
|
|
assert _is_rotation_dof(3, ndf=3) is True
|
|
|
|
|
|
def test_is_rotation_dof_ndf6() -> None:
|
|
"""In a 3D/ndf=6 model, DOFs 4, 5, 6 are rotational."""
|
|
assert _is_rotation_dof(1, ndf=6) is False
|
|
assert _is_rotation_dof(3, ndf=6) is False # Uz in 3D
|
|
assert _is_rotation_dof(4, ndf=6) is True # Rx
|
|
assert _is_rotation_dof(5, ndf=6) is True # Ry
|
|
assert _is_rotation_dof(6, ndf=6) is True # Rz
|
|
|
|
|
|
@pytest.mark.gui
|
|
def test_si_translation_labels(qtbot) -> None: # type: ignore[no-untyped-def]
|
|
v = PushoverCurveView(units=UnitSystem.SI_M_N, ndf=6)
|
|
qtbot.addWidget(v)
|
|
v.set_results(_pushover(control_dof=1))
|
|
assert "m" in v._plot.getAxis("bottom").labelText
|
|
assert "Displacement" in v._plot.getAxis("bottom").labelText
|
|
assert "N" in v._plot.getAxis("left").labelText
|
|
assert "Base shear" in v._plot.getAxis("left").labelText
|
|
|
|
|
|
@pytest.mark.gui
|
|
def test_si_rotation_labels_show_curvature_and_moment(qtbot) -> None: # type: ignore[no-untyped-def]
|
|
v = PushoverCurveView(units=UnitSystem.SI_M_N, ndf=3)
|
|
qtbot.addWidget(v)
|
|
v.set_results(_pushover(control_dof=3))
|
|
assert "1/m" in v._plot.getAxis("bottom").labelText
|
|
assert "Curvature" in v._plot.getAxis("bottom").labelText
|
|
assert "N·m" in v._plot.getAxis("left").labelText
|
|
assert "Moment" in v._plot.getAxis("left").labelText
|
|
|
|
|
|
@pytest.mark.gui
|
|
def test_us_in_kip_rotation_labels(qtbot) -> None: # type: ignore[no-untyped-def]
|
|
"""kip-in Moment-Curvature project must NOT show cm / kN anywhere."""
|
|
v = PushoverCurveView(units=UnitSystem.US_IN_KIP, ndf=3)
|
|
qtbot.addWidget(v)
|
|
v.set_results(_pushover(control_dof=3))
|
|
x_label = v._plot.getAxis("bottom").labelText
|
|
y_label = v._plot.getAxis("left").labelText
|
|
assert "1/in" in x_label
|
|
assert "kip·in" in y_label
|
|
assert "cm" not in x_label
|
|
assert "kN" not in y_label
|
|
|
|
|
|
@pytest.mark.gui
|
|
def test_us_in_kip_translation_labels(qtbot) -> None: # type: ignore[no-untyped-def]
|
|
v = PushoverCurveView(units=UnitSystem.US_IN_KIP, ndf=3)
|
|
qtbot.addWidget(v)
|
|
v.set_results(_pushover(control_dof=1))
|
|
assert "in" in v._plot.getAxis("bottom").labelText
|
|
assert "kip" in v._plot.getAxis("left").labelText
|
|
|
|
|
|
@pytest.mark.gui
|
|
def test_no_auto_scaling_applied_to_values(qtbot) -> None: # type: ignore[no-untyped-def]
|
|
"""Regression: earlier versions divided base_shear by 1000 to
|
|
display kN. The values must now be drawn exactly as stored so
|
|
kip-in users don't see nonsense scaling."""
|
|
v = PushoverCurveView(units=UnitSystem.US_IN_KIP, ndf=3)
|
|
qtbot.addWidget(v)
|
|
r = _pushover(control_dof=3)
|
|
v.set_results(r)
|
|
# Take the single line item that was added; the item's data
|
|
# should match the input arrays point-for-point.
|
|
items = [it for it in v._plot.listDataItems() if hasattr(it, "getData")]
|
|
assert items, "Pushover curve has no plot items"
|
|
xs, ys = items[0].getData()
|
|
# The first line item is the actual data (reference line is second).
|
|
np.testing.assert_allclose(xs, r.control_disp)
|
|
np.testing.assert_allclose(ys, r.base_shear)
|