Summary
uw.systems.FreeSurface accepts a composition field and advects it with the material-consistent surface velocity (the correct way to keep a free surface a material boundary). The constructor docstring lists temperature as an intended use ("a mesh level set holding a signed distance, or temperature"). But _build_composition_transport hardcodes level-set defaults that are wrong for a temperature/convection field:
diffusivity = 1.0e-7 (a level set carries no real diffusion; temperature needs the thermal κ),
bcs = [] (temperature needs Dirichlet BCs at the surface/base),
monotone_mode = None (a bounded [0,1] temperature typically wants monotone limiting).
Impact
Building a free-surface convection driver on the manager currently requires reaching into the private transport solver after construction:
fs = uw.systems.FreeSurface(stokes, "Upper", ..., composition=T)
fs._comp_adv.constitutive_model.Parameters.diffusivity = kappa # private
fs._comp_adv.add_dirichlet_bc(1.0, "Lower") # private
fs._comp_adv.add_dirichlet_bc(0.0, "Upper") # private
This works (a clean annulus FS-convection run is up and stable on it) but is fragile — it depends on the private _comp_adv name and on BCs being addable post-construction.
Suggested resolution (either)
- Parameterize the composition transport:
composition_diffusivity, composition_bcs, composition_monotone on the constructor; or
- Expose the material-consistent advection velocity publicly (e.g.
fs.advection_velocity) and run the consistent solve even when composition is None, so callers can drive their own AdvDiff with proper κ/BCs/monotone.
Option 2 is more flexible (temperature convection wants its own AdvDiff anyway); option 1 is more turnkey. Worth a design decision.
Context
Found while building a fresh annulus free-surface convection driver on the hardened FreeSurface manager (feature/free-surface-tangent). Reference: docs/developer/design/FREESLIP_DYNAMIC_TOPOGRAPHY_FREESURFACE.md, skill free-surface-convection.
Underworld development team with AI support from Claude Code
Summary
uw.systems.FreeSurfaceaccepts acompositionfield and advects it with the material-consistent surface velocity (the correct way to keep a free surface a material boundary). The constructor docstring lists temperature as an intended use ("a mesh level set holding a signed distance, or temperature"). But_build_composition_transporthardcodes level-set defaults that are wrong for a temperature/convection field:diffusivity = 1.0e-7(a level set carries no real diffusion; temperature needs the thermal κ),bcs = [](temperature needs Dirichlet BCs at the surface/base),monotone_mode = None(a bounded [0,1] temperature typically wants monotone limiting).Impact
Building a free-surface convection driver on the manager currently requires reaching into the private transport solver after construction:
This works (a clean annulus FS-convection run is up and stable on it) but is fragile — it depends on the private
_comp_advname and on BCs being addable post-construction.Suggested resolution (either)
composition_diffusivity,composition_bcs,composition_monotoneon the constructor; orfs.advection_velocity) and run the consistent solve even whencomposition is None, so callers can drive their own AdvDiff with proper κ/BCs/monotone.Option 2 is more flexible (temperature convection wants its own AdvDiff anyway); option 1 is more turnkey. Worth a design decision.
Context
Found while building a fresh annulus free-surface convection driver on the hardened
FreeSurfacemanager (feature/free-surface-tangent). Reference:docs/developer/design/FREESLIP_DYNAMIC_TOPOGRAPHY_FREESURFACE.md, skillfree-surface-convection.Underworld development team with AI support from Claude Code