Explain the PROTEUS coupling and fill out the documentation - #13
Merged
Conversation
The coupling page documented the call signature and the record schema but never the coupling itself: what Morrigan is for inside a coupled run, when it runs, what happens when an impact lands, or why any of it is arranged that way. A reader could see the interface and still not know how to use it. It now leads with the property that makes this module unlike the others. Every other module is called inside the time loop and updates its slice of the state each pass; Morrigan runs once, before the loop, and returns a schedule the loop replays. That is why the coupling is one way, why the timestepper rather than the model owns the clock, and why nothing the coupled planet does feeds back into the dynamics. The page then covers how one survivor is chosen out of a whole system, which is the coupling's real free decision, how the configuration maps onto the model's arguments, and the order the six consequences of an impact are applied in, which matters because each reads state the previous one wrote. A companion how-to carries the practical side: the minimal block, choosing a selector, turning on volatile delivery and atmospheric erosion, a worked example with the log it produces, and the five ways a run goes wrong, of which "no impacts scheduled" is the most common and the least obvious. Adds the pages the module was missing next to its siblings: an entry point that routes a reader by what they want to do, the ecosystem page with the shared framework schematic, a code architecture page mapping the source files onto the physics, a configuration guide covering how the settings interact rather than what each one means, and a release guide. Adds contributing guidelines and a code of conduct, so that the path for someone wanting to change the model reaches an end. Corrects the description of how systems are seeded, which three pages still stated in the superseded additive form, and removes a migration note from the readme. Prose describes the current state. Adds the PyPI publish workflow so a release is distributable, with a guard that refuses to upload when the version has fallen back to 0.0.0, since that name cannot be reclaimed.
Several statements in the coupling and architecture pages did not match what the code does, and the worked example's sample log did not match what its own configuration produces. Impacts landing at or before the start of a run are discarded with a warning and their mass is never applied; the pages said they were folded into the initial condition, which would let a reader believe the planet starts already grown by them. Corrected in both coupling pages and in the PROTEUS-side field description the wording came from. The re-melt step resets the interior to its molten initial condition and reports the impact's kinetic energy for comparison; it does not book that energy into an energy budget, and the state is fully molten only for the temperature modes that guarantee it. The page claimed both. It also listed six consequences where there are seven: clearing the solidification latch is its own step, and it is the one that lets outgassing restart. The worked example claimed one impact where that seed and mass list give two, at different times and with a different impactor, so anyone running it would have concluded their install was broken. The log block is now generated from a real run, and the parts that depend on the coupled atmosphere state are described rather than pinned to invented numbers. The example is also no longer called an Earth analogue: eight embryos inside 0.1 AU going unstable in centuries is not one. Smaller corrections: the loop diagram put the time advance after the impact block rather than before it and mistyped three call signatures; the call graph named a `run_batch` function that does not exist; the settings page omitted four mandatory keys, so the documented file raised a bare KeyError; the release page described a PROTEUS version floor that does not exist, where the pin is a commit ref; the constants rule is scoped so fitted coefficients may stay beside their equations; the selector table now says which rules compare initial values and which compare final ones; and impact erosion is named as PROTEUS's call into ZEPHYRUS rather than something Morrigan does.
The selected body is reported by select_planet as soon as the dynamical run returns, before the impact count is logged, so the worked example's transcript had those two lines the wrong way round.
…curately The Aragog re-melt measures the heat it injects across the cooled-to-molten entropy jump and books it into the energy budget as step_dE_impact_J, so an impact enters the budget as a named source. What is logged rather than booked is the impact's kinetic energy, which is a different quantity. The page had conflated the two and said the heat was not booked at all. Of the temperature modes that suppress the start-up warning, only liquidus_super solves for a profile guaranteed fully molten; adiabatic_from_cmb reaches one only if tcmb_init is pinned high enough, and accretion is not checked against the liquidus at all. The page had presented all three as guarantees. Also: the impact block's line count depends on which consequences apply, so describe its shape rather than fixing it at five, and the eight embryos of the worked example run out to 0.11 AU rather than 0.10.
…e exactly The re-melt heat column is added to both sides of the energy budget, so the residual stays closed across an impact for any booked value and cannot validate the magnitude. Describing it as a named source that replaces an unexplained residual claimed a check the budget does not perform. The booking also needs a pre-impact entropy profile to measure against, which is now said rather than implied. Nothing checks the accretion temperature mode against the liquidus, so calling it usually molten asserted more than the code supports; only liquidus_super carries a guarantee, and it raises when the requested superheat is unreachable. SPIDER is the module accretion refuses, not the only one it accepts: dummy and boundary re-melt through a surface temperature, so tsurf_init governs their post-impact state and they book no heat. The pitfall now names the real constraint and says what the lighter backends do differently, which is what someone wanting a quick test of the coupling needs. The per-impact log description no longer implies the opening and closing lines are adjacent; the structure re-solve between them is a full interior calculation that prints its own output.
The absolute residual is what stays closed across an impact; the relative one carries the injection in its denominator and can spike on that row, which is the number a reader is most likely to be looking at. Say which is which. The temperature-mode discussion applies to Aragog. The scalar backends never read it: they reset to tsurf_init, so leaving that below the liquidus gives a partial re-melt, and the paragraph now says so instead of implying temperature_mode governs every backend. Also: boundary needs atmos_clim.surf_state = "fixed", so recommending it for a quick test without that lands the reader on a config error about something else entirely. Dummy carries no such condition and is the better suggestion.
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.
What this does
Explains how Morrigan couples to PROTEUS, which the documentation previously covered in a single thin page, and fills out the rest of the site so it matches what CALLIOPE and Zalmoxis offer. The docs go from 18 to 27 pages.
Why
Someone wanting to run Morrigan inside a coupled PROTEUS run could not find out from the docs how the two fit together: that Morrigan runs once rather than every iteration, how one planet is chosen out of a whole system, what each impact changes when it lands, or what the TOML for it looks like. The rest of the site was also missing the entry points the sibling modules have, and the repository had no contributor guide or code of conduct at all.
Changes
Explanations/proteus_coupling.mdrewritten as the theory (where Morrigan sits in the loop, the selector rules, the seven consequences of an impact, the ratio-not-absolute orbit rule, the record schema), and a newHow-to/proteus_coupling.mdwith the TOML recipe, a worked example and the common pitfalls.getting_started.md,proteus-framework.md(ecosystem placement with the shared module schematic),Explanations/code_architecture.md,How-to/configuration.mdandHow-to/releasing.md.CONTRIBUTING.mdandCODE_OF_CONDUCT.mdat the repository root, surfaced through a Community section in the nav..github/workflows/publish.yaml: release-triggered PyPI publishing via trusted publishing, with a guard that refuses to upload a0.0.0fallback version.Reference/parameters.mdand the how-to pages link to it rather than restating it; the same split applies between the two coupling pages.Returns:docstring section ininteraction_timescales.pythat was leaking griffe warnings into the API page.Testing
pytest -m "(unit or smoke) and not skip": 44 passed.zensical build --clean: no issues, no griffe warnings.ruff check src/ tests/ tools/,bash tools/validate_test_structure.sh(45/45 markers),python tools/check_test_quality.py --check(0 violations).run_systemcall with the configuration the page documents, the documented settings file is parsed and checked for every mandatory key, and the loop diagram, the selector rules and the seven impact consequences are each checked againstproteus.pyandaccretion/wrapper.py.