Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/Reference/config/config_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2838,7 +2838,7 @@
"value": 1.0
}
],
"description": "Cryoscopic depression factor controlling the width of the mushy zone (partially molten region) in the PALEOS unified EOS. Defines the solidus as T_sol = T_liq * mushy_zone_factor. 1.0 = sharp phase boundary (no mushy zone). 0.8 = solidus at 80% of the liquidus temperature, roughly matching the Stixrude+2014 cryoscopic depression for MgSiO3. Must be in [0.7, 1.0]. Only applies to PALEOS unified EOS; ignored for WolfBower2018 and RTPress100TPa (which use explicit melting curve files). This factor is applied consistently across Zalmoxis (density interpolation), SPIDER (phase boundaries), and the VolatileProfile phi-blending.",
"description": "Cryoscopic depression factor controlling the width of the mushy zone (partially molten region) in the PALEOS EOS family. Defines the solidus as T_sol = T_liq * mushy_zone_factor. 1.0 = sharp phase boundary (no mushy zone). 0.8 = solidus at 80% of the liquidus temperature, roughly matching the Stixrude+2014 cryoscopic depression for MgSiO3. Must be in [0.7, 1.0]. Applies to the PALEOS EOS family (PALEOS, PALEOS-2phase, PALEOS-API, PALEOS-API-2phase); ignored for WolfBower2018 and RTPress100TPa (which use explicit melting curve files) and for Seager2007/Analytic (no derived solidus).",
"doc_source": "attributes",
"group_order": 0,
"group_position": 3,
Expand Down
2 changes: 1 addition & 1 deletion docs/Reference/config/interior.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ belong to the experimental binodal-aware mode.
| `core_eos` | str | `"PALEOS:iron"` | EOS for the core layer. Format: "<source>:<material>". Tabulated: "PALEOS:iron" (default), "Seager2007:iron". Analytic: "Analytic:iron", "Analytic:MgFeSiO3", etc. |
| `mantle_eos` | str | `"PALEOS:MgSiO3"` | EOS for the mantle layer. Format: "<source>:<material>". Tabulated: "PALEOS:MgSiO3" (default), "PALEOS-2phase:MgSiO3", "Seager2007:MgSiO3", "WolfBower2018:MgSiO3". Analytic: "Analytic:MgSiO3", "Analytic:MgFeSiO3", etc. |
| `ice_layer_eos` | str or none | `none` | EOS for the ice/water layer (3-layer model). 'none' for 2-layer model (core + mantle only). Tabulated: "PALEOS:H2O", "Seager2007:H2O". Analytic: "Analytic:H2O". |
| `mushy_zone_factor` | float | `0.8` | Cryoscopic depression factor controlling the width of the mushy zone (partially molten region) in the PALEOS unified EOS. Defines the solidus as T_sol = T_liq * mushy_zone_factor. 1.0 = sharp phase boundary (no mushy zone). 0.8 = solidus at 80% of the liquidus temperature, roughly matching the Stixrude+2014 cryoscopic depression for MgSiO3. Must be in \[0.7, 1.0\]. Only applies to PALEOS unified EOS; ignored for WolfBower2018 and RTPress100TPa (which use explicit melting curve files). This factor is applied consistently across Zalmoxis (density interpolation), SPIDER (phase boundaries), and the VolatileProfile phi-blending. Must be >= 0.7 and <= 1.0. |
| `mushy_zone_factor` | float | `0.8` | Cryoscopic depression factor controlling the width of the mushy zone (partially molten region) in the PALEOS EOS family. Defines the solidus as T_sol = T_liq * mushy_zone_factor. 1.0 = sharp phase boundary (no mushy zone). 0.8 = solidus at 80% of the liquidus temperature, roughly matching the Stixrude+2014 cryoscopic depression for MgSiO3. Must be in \[0.7, 1.0\]. Applies to the PALEOS EOS family (PALEOS, PALEOS-2phase, PALEOS-API, PALEOS-API-2phase); ignored for WolfBower2018 and RTPress100TPa (which use explicit melting curve files) and for Seager2007/Analytic (no derived solidus). Must be >= 0.7 and <= 1.0. |
| `mantle_mass_fraction` | float | `0` | Fraction of the planet's interior mass corresponding to the mantle. Required for 3-layer models (with ice layer) and for T-dependent 2-layer models (WolfBower2018, RTPress100TPa) where it partitions mass between core and mantle layers. Must be >= 0 and < 1. |
| `dry_mantle` | bool | `true` | Structure EOS assumes a dry mantle. Set False for melt-fraction-aware dissolved-volatile mixing in the mantle density (per-shell volatile profile); the dissolved mass then stays inside the interior mass target. |

Expand Down
18 changes: 9 additions & 9 deletions src/proteus/config/_struct.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,13 @@ def valid_zalmoxis(instance, attribute, value):
import logging as _logging

_log = _logging.getLogger('fwl.' + __name__)
# mushy_zone_factor only applies to PALEOS unified tables
# mushy_zone_factor scales the derived solidus only for the PALEOS EOS family
_MZF_EOS_PREFIXES = ('PALEOS:', 'PALEOS-2phase:', 'PALEOS-API:', 'PALEOS-API-2phase:')
mzf = getattr(instance.zalmoxis, 'mushy_zone_factor', 0.8)
if mzf < 1.0 and not mantle_eos.startswith('PALEOS:'):
if mzf < 1.0 and not mantle_eos.startswith(_MZF_EOS_PREFIXES):
_log.warning(
'mushy_zone_factor=%.2f has no effect with mantle EOS %s. '
'The mushy zone factor only applies to PALEOS unified tables. '
'The mushy zone factor applies only to the PALEOS EOS family. '
'For WolfBower2018/RTPress100TPa, the mushy zone is defined by '
'the solidus/liquidus melting curve files.',
mzf,
Expand Down Expand Up @@ -102,16 +103,15 @@ class Zalmoxis:
Tabulated: "PALEOS:H2O", "Seager2007:H2O". Analytic: "Analytic:H2O".
mushy_zone_factor: float
Cryoscopic depression factor controlling the width of the mushy
zone (partially molten region) in the PALEOS unified EOS.
zone (partially molten region) in the PALEOS EOS family.
Defines the solidus as T_sol = T_liq * mushy_zone_factor.
1.0 = sharp phase boundary (no mushy zone).
0.8 = solidus at 80% of the liquidus temperature, roughly
matching the Stixrude+2014 cryoscopic depression for MgSiO3.
Must be in [0.7, 1.0]. Only applies to PALEOS unified EOS;
ignored for WolfBower2018 and RTPress100TPa (which use explicit
melting curve files). This factor is applied consistently across
Zalmoxis (density interpolation), SPIDER (phase boundaries),
and the VolatileProfile phi-blending.
Must be in [0.7, 1.0]. Applies to the PALEOS EOS family (PALEOS,
PALEOS-2phase, PALEOS-API, PALEOS-API-2phase); ignored for
WolfBower2018 and RTPress100TPa (which use explicit melting curve
files) and for Seager2007/Analytic (no derived solidus).
mantle_mass_fraction: float
Fraction of the planet's interior mass corresponding to the mantle.
Required for 3-layer models (with ice layer) and for T-dependent
Expand Down
51 changes: 51 additions & 0 deletions tests/config/test_struct.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

from __future__ import annotations

import logging

import pytest

from proteus.config._struct import Struct, Zalmoxis
Expand Down Expand Up @@ -160,3 +162,52 @@ def test_spider_module_skips_the_gate(self):
# absent.
with pytest.raises(ValueError, match='core_eos'):
Struct(module='zalmoxis', zalmoxis=Zalmoxis(core_eos='no_colon'))


class TestZalmoxisMushyZoneWarning:
"""The mushy_zone_factor no-effect warning must fire only for the EOS
families that actually ignore the factor.

mushy_zone_factor scales the derived solidus ``T_sol = T_liq * mzf`` for
the PALEOS family (unified, 2-phase, and the API variants) through
``load_zalmoxis_solidus_liquidus_functions``. For WolfBower2018 and
RTPress100TPa the melting curves come from file and the factor is inert,
so there the warning is correct and must still fire.
"""

@staticmethod
def _warns(caplog, mantle_eos, mzf=0.8):
"""Construct a zalmoxis Struct and report whether the no-effect
warning fired for ``mantle_eos`` at the given factor."""
caplog.clear()
with caplog.at_level(logging.WARNING, logger='fwl.proteus.config._struct'):
Struct(
module='zalmoxis',
zalmoxis=Zalmoxis(mantle_eos=mantle_eos, mushy_zone_factor=mzf),
)
return any('has no effect' in r.getMessage() for r in caplog.records)

def test_warning_silent_for_the_paleos_family(self, caplog):
"""Each PALEOS-family EOS feeds the factor into the derived solidus, so
the no-effect warning must stay silent for all four."""
for eos in (
'PALEOS:MgSiO3',
'PALEOS-2phase:MgSiO3',
'PALEOS-API:MgSiO3',
'PALEOS-API-2phase:MgSiO3',
):
assert not self._warns(caplog, eos), eos

def test_warning_fires_for_file_curve_eos(self, caplog):
"""WolfBower2018 and RTPress100TPa read melting curves from file, so the
factor has no effect and the warning must fire."""
for eos in ('WolfBower2018:MgSiO3', 'RTPress100TPa:MgSiO3'):
assert self._warns(caplog, eos), eos

def test_warning_tracks_the_factor_not_only_the_eos(self, caplog):
"""The warning depends on mushy_zone_factor < 1: at the sharp-boundary
value 1.0 an ignored setting is not misreported."""
assert not self._warns(caplog, 'WolfBower2018:MgSiO3', mzf=1.0)
# Paired positive: the same EOS at 0.8 fires, so silence at 1.0 is the
# factor guard rather than the EOS being exempt.
assert self._warns(caplog, 'WolfBower2018:MgSiO3', mzf=0.8)
Loading