Skip to content

feat: Tower.attach_mudline_foundation + 1.15.1 bump#119

Merged
SMI-Lab-Inha merged 1 commit into
masterfrom
feat/attach-mudline-foundation
May 29, 2026
Merged

feat: Tower.attach_mudline_foundation + 1.15.1 bump#119
SMI-Lab-Inha merged 1 commit into
masterfrom
feat/attach-mudline-foundation

Conversation

@SMI-Lab-Inha
Copy link
Copy Markdown
Owner

Summary

Closes #117 and partially addresses #118.

Background

The 1.15.0 close-comment on #97 suggested mutating tower._bmi.support.sec_props.flp_stff[-1], which fails on a from_windio_with_monopile tower (the BMI's support is None and the section properties live at tower._sp instead). #117 reported the broken snippet. The right shape is a public method.

What ships

Tower.attach_mudline_foundation(foundation) wires a MudlineFoundation into a clamped monopile model in one call. It builds a fresh PlatformSupport carrying the foundation's 6 x 6 mooring_K block (with zero hydro, zero platform inertia, and empty distributed arrays), sets tow_support = 1, and flips hub_conn to 3. Returns self for chaining, so the canonical pattern is one expression:

modal = (
    Tower.from_windio_with_monopile("ontology.yaml", tip_mass=991000.0)
    .attach_mudline_foundation(foundation)
    .run(n_modes=4)
)

Rejects a free-base floating model (hub_conn = 2) and a pinned-free cable model (hub_conn = 4) with clear ValueError messages.

Affects the coupled-system frequency only; ElastoDyn polynomial coefficient generation continues to use the cantilever path regardless of soil flexibility (same architectural reason FLOATING_CASES.md records for floating platforms).

Test plan

  • tests/test_foundation.py adds 7 regression tests:
    • test_attach_mudline_foundation_flips_hub_conn_to_three
    • test_attach_mudline_foundation_writes_mooring_K
    • test_attach_mudline_foundation_zeroes_other_platform_blocks
    • test_attach_mudline_foundation_supports_chaining
    • test_attach_mudline_foundation_softens_first_frequency_vs_clamped (physics gate, soft monopile 1st FA < clamped 1st FA)
    • test_attach_mudline_foundation_rejects_floating_model
    • test_attach_mudline_foundation_rejects_pinned_free_model
  • Full default suite: 963 passed (up from 956), no regressions
  • ruff check src/pybmodes tests scripts clean
  • mypy src/pybmodes clean
  • sphinx-build docs clean
  • tests/test_version.py confirms pyproject.toml, __init__.py fallback, and CITATION.cff agree on 1.15.1

Out of scope (for #118)

Distributed Winkler distribution along the embedded length (mapped to distr_k per-station) stays as a separate scope to be addressed in a 1.16 minor release.

Closes #117 and partially addresses #118. Adds a one-call wiring
from MudlineFoundation into a clamped monopile model so users can
convert a from_windio_with_monopile or from_elastodyn_with_subdyn
tower to the hub_conn = 3 soft monopile path without hand-building
a PlatformSupport or mutating private BMI fields.

The 1.15.0 close-comment on #97 suggested mutating tower._bmi.support
.sec_props.flp_stff[-1], which fails on a from_windio_with_monopile
tower (the BMI's support is None and the section properties live at
tower._sp instead). #117 reported the broken snippet. The right shape
is a public method; 1.15.1 ships it.

Tower.attach_mudline_foundation creates a fresh PlatformSupport
carrying the foundation's 6 x 6 mooring_K block (with zero hydro,
zero platform inertia, and empty distributed arrays), sets
tow_support = 1, and flips hub_conn to 3. Returns self for chaining,
so the canonical pattern is one expression:

  Tower.from_windio_with_monopile(yaml, tip_mass=rna) \
      .attach_mudline_foundation(foundation) \
      .run(n_modes=4)

Refuses to wire onto a free-base floating model (hub_conn = 2) or a
pinned-free cable model (hub_conn = 4) with a clear ValueError. The
mudline stiffness affects the coupled-system frequency only;
ElastoDyn polynomial coefficient generation continues to use the
cantilever path regardless of soil flexibility, the same
architectural reason FLOATING_CASES.md records for floating
platforms.

Seven regression tests in tests/test_foundation.py cover:

- hub_conn transition from 1 to 3 with tow_support = 1
- foundation's mooring_K writes correctly to the new PlatformSupport
- hydro, inertia, and distributed arrays stay at zero / empty
- chaining: attach().run() works in one expression
- the physics check: soft-monopile 1st FA is lower than the clamped
  baseline on the same tower geometry (finite soil stiffness can
  only relax the BC vs the rigid clamp)
- ValueError on hub_conn = 2 (floating)
- ValueError on hub_conn = 4 (pinned-free)

Quickstart's soft-monopile recipe now leads with the canonical
.attach_mudline_foundation(f).run(...) chain and keeps
as_mooring_K() as a secondary compose-it-yourself snippet for callers
wiring into an existing PlatformSupport (the CS_Monopile.bmi deck
pattern).

Version bump 1.15.0 -> 1.15.1 across pyproject.toml,
src/pybmodes/__init__.py fallback, and CITATION.cff. CHANGELOG
promoted with the [1.15.1] block describing the ergonomic patch.

963 default-run tests pass, no regressions. Ruff and mypy clean.
Sphinx builds clean.
@SMI-Lab-Inha SMI-Lab-Inha merged commit 4b94add into master May 29, 2026
6 checks passed
@SMI-Lab-Inha SMI-Lab-Inha deleted the feat/attach-mudline-foundation branch May 29, 2026 23:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Issue 97 no attribute 'sec_props' in from_windio_with_monopile

1 participant