chore: adopt remaining local development state

Catch-all for the intermixed residue of the unpushed otko-development
work ported into this tree: combinations/console-dock/quick-guide wiring
across commands, core, services, views and tests; repo-wide ruff-format
normalization; README/CONTRIBUTING updates; and the toolbar default
(both toolbars now open in the top area, quick guide text updated).

Splitting this further would require hunk-level surgery with low
confidence; the preceding commits in this branch isolate the
self-contained features.
This commit is contained in:
smillmorel 2026-09-16 12:03:22 -04:00
commit ba783718d4
152 changed files with 3394 additions and 1651 deletions

View file

@ -13,6 +13,8 @@ from otko.core import PushoverCase, TransientCase # noqa: E402
from otko.services import load_project, save_project # noqa: E402
from otko.services.opensees_runner import OpenSeesRunner # noqa: E402
pytestmark = pytest.mark.slow
def _reload(proj, tmp_path, stem: str): # type: ignore[no-untyped-def]
path = tmp_path / f"{stem}.osmodel"
@ -27,10 +29,16 @@ def _reload(proj, tmp_path, stem: str): # type: ignore[no-untyped-def]
[
("build_ex4_portal2d_elastic_element", "examples.ex4_portal2d_elastic_element", False),
("build_ex4_portal2d_inelastic_section", "examples.ex4_portal2d_inelastic_section", True),
("build_ex4_portal2d_inelastic_fiber_section", "examples.ex4_portal2d_inelastic_fiber_section", True),
(
"build_ex4_portal2d_inelastic_fiber_section",
"examples.ex4_portal2d_inelastic_fiber_section",
True,
),
],
)
def test_ex4_variant_pushover_runs(tmp_path, builder_name: str, module_name: str, nonlinear: bool) -> None: # type: ignore[no-untyped-def]
def test_ex4_variant_pushover_runs(
tmp_path, builder_name: str, module_name: str, nonlinear: bool
) -> None: # type: ignore[no-untyped-def]
mod = __import__(module_name, fromlist=[builder_name, "PUSH_STEP", "PUSH_TARGET"])
proj = _reload(getattr(mod, builder_name)(), tmp_path, builder_name)
push_case = next(c for c in proj.analyses if isinstance(c, PushoverCase))
@ -45,8 +53,12 @@ def test_ex4_variant_pushover_runs(tmp_path, builder_name: str, module_name: str
assert result.control_disp[-1] == pytest.approx(mod.PUSH_TARGET, abs=5e-3)
assert max(result.base_shear) > 0.0
early = (result.base_shear[5] - result.base_shear[0]) / (result.control_disp[5] - result.control_disp[0])
late = (result.base_shear[-1] - result.base_shear[-6]) / (result.control_disp[-1] - result.control_disp[-6])
early = (result.base_shear[5] - result.base_shear[0]) / (
result.control_disp[5] - result.control_disp[0]
)
late = (result.base_shear[-1] - result.base_shear[-6]) / (
result.control_disp[-1] - result.control_disp[-6]
)
if nonlinear:
assert early > 1.25 * late
else:
@ -58,7 +70,10 @@ def test_ex4_variant_pushover_runs(tmp_path, builder_name: str, module_name: str
[
("build_ex4_portal2d_elastic_element", "examples.ex4_portal2d_elastic_element"),
("build_ex4_portal2d_inelastic_section", "examples.ex4_portal2d_inelastic_section"),
("build_ex4_portal2d_inelastic_fiber_section", "examples.ex4_portal2d_inelastic_fiber_section"),
(
"build_ex4_portal2d_inelastic_fiber_section",
"examples.ex4_portal2d_inelastic_fiber_section",
),
],
)
def test_ex4_variant_sine_runs(tmp_path, builder_name: str, module_name: str) -> None: # type: ignore[no-untyped-def]