feat: Tower.attach_mudline_foundation + 1.15.1 bump#119
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 afrom_windio_with_monopiletower (the BMI'ssupportisNoneand the section properties live attower._spinstead). #117 reported the broken snippet. The right shape is a public method.What ships
Tower.attach_mudline_foundation(foundation)wires aMudlineFoundationinto a clamped monopile model in one call. It builds a freshPlatformSupportcarrying the foundation's 6 x 6mooring_Kblock (with zero hydro, zero platform inertia, and empty distributed arrays), setstow_support = 1, and flipshub_connto3. Returnsselffor chaining, so the canonical pattern is one expression:Rejects a free-base floating model (
hub_conn = 2) and a pinned-free cable model (hub_conn = 4) with clearValueErrormessages.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.mdrecords for floating platforms).Test plan
tests/test_foundation.pyadds 7 regression tests:test_attach_mudline_foundation_flips_hub_conn_to_threetest_attach_mudline_foundation_writes_mooring_Ktest_attach_mudline_foundation_zeroes_other_platform_blockstest_attach_mudline_foundation_supports_chainingtest_attach_mudline_foundation_softens_first_frequency_vs_clamped(physics gate, soft monopile 1st FA < clamped 1st FA)test_attach_mudline_foundation_rejects_floating_modeltest_attach_mudline_foundation_rejects_pinned_free_modelruff check src/pybmodes tests scriptscleanmypy src/pybmodescleansphinx-build docscleantests/test_version.pyconfirmspyproject.toml,__init__.pyfallback, andCITATION.cffagree on 1.15.1Out of scope (for #118)
Distributed Winkler distribution along the embedded length (mapped to
distr_kper-station) stays as a separate scope to be addressed in a 1.16 minor release.