SurfaceLayerUpdate
Top-layer ice and liquid water mass-rate updates from surface dew, frost, and sublimation, following Oleson et al. (2010, CLM Tech Note Ch. 5) Eqs. 5.150-5.152. Migrated from UrbanCanopy.jl@9200edd4 src/hydrology.jl:860 (`SurfaceLayerUpdate` @component). Parameterized as observed-only: q_sdew, q_frost, q_subl are inputs (parameters); dw_liq_1, dw_ice_1_frost, dw_ice_1_subl are algebraic outputs that pass each input through (with a sign flip on sublimation). Applies to the top layer of all surfaces (roof, pervious road, impervious road).
Description
Top-layer ice and liquid water mass-rate updates from surface dew, frost, and sublimation, following Oleson et al. (2010, CLM Tech Note Ch. 5) Eqs. 5.150-5.152. Migrated from UrbanCanopy.jl@9200edd4 src/hydrology.jl:860 (SurfaceLayerUpdate @component). Parameterized as observed-only: q_sdew, q_frost, q_subl are inputs (parameters); dw_liq_1, dw_ice_1_frost, dw_ice_1_subl are algebraic outputs that pass each input through (with a sign flip on sublimation). Applies to the top layer of all surfaces (roof, pervious road, impervious road).
Reference
_source_ref: UrbanCanopy.jl@9200edd4f15609f20339d3a7d104de8064544310:src/hydrology.jl:860
Upstream SurfaceLayerUpdate is an MTK @component whose three inputs (q_sdew, q_frost, q_subl) are @parameters and whose three outputs (dw_liq_1, dw_ice_1_frost, dw_ice_1_subl) are time-indexed @variables with algebraic-only equations (no derivatives). The three equations are:
• dw_liq_1 ~ q_sdew (Eq. 5.150 — rate form)
• dw_ice_1_frost ~ q_frost (Eq. 5.151 — rate form)
• dw_ice_1_subl ~ -q_subl (Eq. 5.152 — rate form, sublimation removes ice)
Identical structure preserved here. The negation in Eq. 5.152 is encoded as multiplication by -1 — the same pattern used by snow_compaction.esm for C_R1 = -c_3 * ....
Observability classification: this component is functionally observed-only — every output is given by a single algebraic equation in terms of the parameters (and the (t) time index has no role since there is no derivative). Test scenarios use time_span: [0, 1] and sample at t=0 to mirror the convention used by the other observed-only ESM files in this rig (e.g. soil_water_content_calc.esm, snow_melt_no_layers.esm).
Tolerance rationale (model-level rel=1e-9): observed-only algebraic system (no ODE integration); two of the three equations are pass-through (zero floating-point ops), and the third is a single negation (one IEEE-754 sign flip — exact). Round-off is ~1e-16. 1e-9 leaves comfortable headroom and is well below any plausible physical-discrimination scale on surface mass fluxes (which are typically 1e-7 to 1e-3 kg/(m^2*s) for dew/frost/sublimation in CLMU). Branches where the expected value is exactly zero by construction add abs: 1e-15 to guard against silent stuck-at-large regressions._
Parameters
| Name | Units | Default | Description |
|---|---|---|---|
q_sdew | kg/(m^2*s) | 0.0 | Surface dew rate (liquid condensation onto the surface) |
q_frost | kg/(m^2*s) | 0.0 | Frost rate (vapor deposition as ice) |
q_subl | kg/(m^2*s) | 0.0 | Sublimation rate (ice → vapor; sign-flipped on the ice-mass tendency) |
Observed
| Name | Units | Default | Description |
|---|---|---|---|
dw_liq_1 | kg/(m^2*s) | Rate of change of top-layer liquid water from dew (Oleson Eq. 5.150): dw_liq_1 = q_sdew | |
dw_ice_1_frost | kg/(m^2*s) | Rate of change of top-layer ice from frost (Oleson Eq. 5.151): dw_ice_1_frost = q_frost | |
dw_ice_1_subl | kg/(m^2*s) | Rate of change of top-layer ice from sublimation (Oleson Eq. 5.152): dw_ice_1_subl = -q_subl |
Observed expressions
$$ dw_{liq\,1} = q_{sdew} $$Rate of change of top-layer liquid water from dew (Oleson Eq. 5.150): dw_liq_1 = q_sdew
$$ dw_{ice\,1\,frost} = q_{frost} $$Rate of change of top-layer ice from frost (Oleson Eq. 5.151): dw_ice_1_frost = q_frost
$$ dw_{ice\,1\,subl} = \left(-1\right) \cdot q_{subl} $$Rate of change of top-layer ice from sublimation (Oleson Eq. 5.152): dw_ice_1_subl = -q_subl
Analyses
sublimation_response_curve
Sweep the sublimation rate q_subl across the typical CLMU range (0 to 1e-5 kg/(m^2*s)). dw_ice_1_subl traces a straight line from 0 to -1e-5 — visualizing the sign-flip of Eq. 5.152. The other two tendencies stay pinned at zero across the sweep.
Time span: 0.0 → 1.0
Swept over: q_subl

dew_frost_phase_partition
Joint sweep of dew (q_sdew) and frost (q_frost) rates at fixed zero sublimation. Surfaces the independence of the liquid- and ice-tendency channels: dw_liq_1 depends only on q_sdew, dw_ice_1_frost only on q_frost. Useful as a regression baseline confirming that no cross-coupling has been silently introduced.
Time span: 0.0 → 1.0
Swept over: q_sdew, q_frost


Raw .esm
Raw .esm JSON (this component)
{
"reference": {
"notes": "source_ref: UrbanCanopy.jl@9200edd4f15609f20339d3a7d104de8064544310:src/hydrology.jl:860\nUpstream `SurfaceLayerUpdate` is an MTK `@component` whose three inputs (q_sdew, q_frost, q_subl) are `@parameters` and whose three outputs (dw_liq_1, dw_ice_1_frost, dw_ice_1_subl) are time-indexed `@variables` with algebraic-only equations (no derivatives). The three equations are:\n • dw_liq_1 ~ q_sdew (Eq. 5.150 — rate form)\n • dw_ice_1_frost ~ q_frost (Eq. 5.151 — rate form)\n • dw_ice_1_subl ~ -q_subl (Eq. 5.152 — rate form, sublimation removes ice)\nIdentical structure preserved here. The negation in Eq. 5.152 is encoded as multiplication by -1 — the same pattern used by snow_compaction.esm for `C_R1 = -c_3 * ...`.\n\nObservability classification: this component is functionally observed-only — every output is given by a single algebraic equation in terms of the parameters (and the `(t)` time index has no role since there is no derivative). Test scenarios use `time_span: [0, 1]` and sample at t=0 to mirror the convention used by the other observed-only ESM files in this rig (e.g. soil_water_content_calc.esm, snow_melt_no_layers.esm).\n\nTolerance rationale (model-level rel=1e-9): observed-only algebraic system (no ODE integration); two of the three equations are pass-through (zero floating-point ops), and the third is a single negation (one IEEE-754 sign flip — exact). Round-off is ~1e-16. 1e-9 leaves comfortable headroom and is well below any plausible physical-discrimination scale on surface mass fluxes (which are typically 1e-7 to 1e-3 kg/(m^2*s) for dew/frost/sublimation in CLMU). Branches where the expected value is exactly zero by construction add `abs: 1e-15` to guard against silent stuck-at-large regressions."
},
"tolerance": {
"rel": 1e-09
},
"variables": {
"q_sdew": {
"type": "parameter",
"units": "kg/(m^2*s)",
"default": 0.0,
"description": "Surface dew rate (liquid condensation onto the surface)"
},
"q_frost": {
"type": "parameter",
"units": "kg/(m^2*s)",
"default": 0.0,
"description": "Frost rate (vapor deposition as ice)"
},
"q_subl": {
"type": "parameter",
"units": "kg/(m^2*s)",
"default": 0.0,
"description": "Sublimation rate (ice → vapor; sign-flipped on the ice-mass tendency)"
},
"dw_liq_1": {
"type": "unknown",
"units": "kg/(m^2*s)",
"description": "Rate of change of top-layer liquid water from dew (Oleson Eq. 5.150): dw_liq_1 = q_sdew"
},
"dw_ice_1_frost": {
"type": "unknown",
"units": "kg/(m^2*s)",
"description": "Rate of change of top-layer ice from frost (Oleson Eq. 5.151): dw_ice_1_frost = q_frost"
},
"dw_ice_1_subl": {
"type": "unknown",
"units": "kg/(m^2*s)",
"description": "Rate of change of top-layer ice from sublimation (Oleson Eq. 5.152): dw_ice_1_subl = -q_subl"
}
},
"equations": [
{
"lhs": "dw_liq_1",
"rhs": "q_sdew"
},
{
"lhs": "dw_ice_1_frost",
"rhs": "q_frost"
},
{
"lhs": "dw_ice_1_subl",
"rhs": {
"op": "*",
"args": [
-1,
"q_subl"
]
}
}
],
"tests": [
{
"id": "all_zero",
"description": "No surface fluxes (all three rates zero). Each tendency must be exactly zero — the trivial baseline that confirms the equations and the runner do not introduce spurious offsets.",
"parameter_overrides": {
"q_sdew": 0.0,
"q_frost": 0.0,
"q_subl": 0.0
},
"time_span": {
"start": 0.0,
"end": 1.0
},
"assertions": [
{
"variable": "dw_liq_1",
"time": 0.0,
"expected": 0.0,
"tolerance": {
"abs": 1e-15
}
},
{
"variable": "dw_ice_1_frost",
"time": 0.0,
"expected": 0.0,
"tolerance": {
"abs": 1e-15
}
},
{
"variable": "dw_ice_1_subl",
"time": 0.0,
"expected": 0.0,
"tolerance": {
"abs": 1e-15
}
}
]
},
{
"id": "dew_only",
"description": "Surface dew at 1e-5 kg/(m^2*s) (a typical CLMU early-morning condensation rate, ~36 mm/hr peak), no frost, no sublimation. Eq. 5.150 routes the dew rate straight to dw_liq_1; the ice-tendency equations remain at zero.",
"parameter_overrides": {
"q_sdew": 1e-05,
"q_frost": 0.0,
"q_subl": 0.0
},
"time_span": {
"start": 0.0,
"end": 1.0
},
"assertions": [
{
"variable": "dw_liq_1",
"time": 0.0,
"expected": 1e-05
},
{
"variable": "dw_ice_1_frost",
"time": 0.0,
"expected": 0.0,
"tolerance": {
"abs": 1e-15
}
},
{
"variable": "dw_ice_1_subl",
"time": 0.0,
"expected": 0.0,
"tolerance": {
"abs": 1e-15
}
}
]
},
{
"id": "frost_only",
"description": "Vapor deposition as frost (q_frost = 5e-6 kg/(m^2*s)) on a sub-freezing surface, no dew, no sublimation. Eq. 5.151 routes the frost rate to dw_ice_1_frost; dw_liq_1 and dw_ice_1_subl stay at zero. Verifies the frost branch is decoupled from the liquid-water branch.",
"parameter_overrides": {
"q_sdew": 0.0,
"q_frost": 5e-06,
"q_subl": 0.0
},
"time_span": {
"start": 0.0,
"end": 1.0
},
"assertions": [
{
"variable": "dw_liq_1",
"time": 0.0,
"expected": 0.0,
"tolerance": {
"abs": 1e-15
}
},
{
"variable": "dw_ice_1_frost",
"time": 0.0,
"expected": 5e-06
},
{
"variable": "dw_ice_1_subl",
"time": 0.0,
"expected": 0.0,
"tolerance": {
"abs": 1e-15
}
}
]
},
{
"id": "sublimation_only",
"description": "Sublimation removes ice from the surface (q_subl = 2e-6 kg/(m^2*s)) with no dew or frost. Eq. 5.152 sign-flips the input: dw_ice_1_subl = -q_subl = -2e-6. The other two tendencies stay at zero. Crucial test of the only non-pass-through equation in the component.",
"parameter_overrides": {
"q_sdew": 0.0,
"q_frost": 0.0,
"q_subl": 2e-06
},
"time_span": {
"start": 0.0,
"end": 1.0
},
"assertions": [
{
"variable": "dw_liq_1",
"time": 0.0,
"expected": 0.0,
"tolerance": {
"abs": 1e-15
}
},
{
"variable": "dw_ice_1_frost",
"time": 0.0,
"expected": 0.0,
"tolerance": {
"abs": 1e-15
}
},
{
"variable": "dw_ice_1_subl",
"time": 0.0,
"expected": -2e-06
}
]
},
{
"id": "dew_plus_frost_morning",
"description": "Pre-dawn near-freezing surface: liquid dew co-deposits with frost (q_sdew = 8e-6, q_frost = 3e-6 kg/(m^2*s)), no sublimation. Both ice and liquid tendencies are positive; the sublimation channel stays at zero. Captures the diurnal-transition morning condition where the two condensation branches are simultaneously active.",
"parameter_overrides": {
"q_sdew": 8e-06,
"q_frost": 3e-06,
"q_subl": 0.0
},
"time_span": {
"start": 0.0,
"end": 1.0
},
"assertions": [
{
"variable": "dw_liq_1",
"time": 0.0,
"expected": 8e-06
},
{
"variable": "dw_ice_1_frost",
"time": 0.0,
"expected": 3e-06
},
{
"variable": "dw_ice_1_subl",
"time": 0.0,
"expected": 0.0,
"tolerance": {
"abs": 1e-15
}
}
]
},
{
"id": "dew_plus_sublimation",
"description": "Sun-warmed surface where existing snow/frost sublimates while new dew condenses (q_sdew = 4e-6, q_subl = 6e-6 kg/(m^2*s)), no fresh frost. dw_liq_1 = 4e-6 (positive — liquid accumulating); dw_ice_1_subl = -6e-6 (negative — ice mass leaving as vapor). The two phase tendencies have opposite signs, exercising the regime where the surface is gaining liquid but losing ice.",
"parameter_overrides": {
"q_sdew": 4e-06,
"q_frost": 0.0,
"q_subl": 6e-06
},
"time_span": {
"start": 0.0,
"end": 1.0
},
"assertions": [
{
"variable": "dw_liq_1",
"time": 0.0,
"expected": 4e-06
},
{
"variable": "dw_ice_1_frost",
"time": 0.0,
"expected": 0.0,
"tolerance": {
"abs": 1e-15
}
},
{
"variable": "dw_ice_1_subl",
"time": 0.0,
"expected": -6e-06
}
]
},
{
"id": "all_three_active",
"description": "All three vapor-exchange channels simultaneously active (q_sdew = 1.5e-5, q_frost = 7e-6, q_subl = 4e-6 kg/(m^2*s)) — a transition-period state where the surface is partly above and partly below freezing within a single tile. Verifies that the three equations are independent: each tendency depends only on its own input, regardless of the others' magnitudes.",
"parameter_overrides": {
"q_sdew": 1.5e-05,
"q_frost": 7e-06,
"q_subl": 4e-06
},
"time_span": {
"start": 0.0,
"end": 1.0
},
"assertions": [
{
"variable": "dw_liq_1",
"time": 0.0,
"expected": 1.5e-05
},
{
"variable": "dw_ice_1_frost",
"time": 0.0,
"expected": 7e-06
},
{
"variable": "dw_ice_1_subl",
"time": 0.0,
"expected": -4e-06
}
]
},
{
"id": "negative_q_sdew_evaporation",
"description": "Negative q_sdew (= -3e-6 kg/(m^2*s)) — physically a net surface evaporation rather than dew. Eq. 5.150 is sign-preserving, so dw_liq_1 = q_sdew = -3e-6 (negative tendency, liquid is leaving). The upstream MTK component does not clamp the sign of q_sdew; this test pins down that this ESM file inherits the same sign-preserving behavior.",
"parameter_overrides": {
"q_sdew": -3e-06,
"q_frost": 0.0,
"q_subl": 0.0
},
"time_span": {
"start": 0.0,
"end": 1.0
},
"assertions": [
{
"variable": "dw_liq_1",
"time": 0.0,
"expected": -3e-06
},
{
"variable": "dw_ice_1_frost",
"time": 0.0,
"expected": 0.0,
"tolerance": {
"abs": 1e-15
}
},
{
"variable": "dw_ice_1_subl",
"time": 0.0,
"expected": 0.0,
"tolerance": {
"abs": 1e-15
}
}
]
},
{
"id": "high_magnitude_storm",
"description": "Stress-test of the linear pass-through with high-magnitude inputs (1e-3 kg/(m^2*s) on each — an extreme rime-icing event in the upper bound of physical realism). The exact pass-through and sign-flip behavior must hold at three orders of magnitude above the typical scale, confirming the equations have no hidden non-linearity or saturation.",
"parameter_overrides": {
"q_sdew": 0.001,
"q_frost": 0.001,
"q_subl": 0.001
},
"time_span": {
"start": 0.0,
"end": 1.0
},
"assertions": [
{
"variable": "dw_liq_1",
"time": 0.0,
"expected": 0.001
},
{
"variable": "dw_ice_1_frost",
"time": 0.0,
"expected": 0.001
},
{
"variable": "dw_ice_1_subl",
"time": 0.0,
"expected": -0.001
}
]
}
],
"analyses": [
{
"id": "sublimation_response_curve",
"description": "Sweep the sublimation rate q_subl across the typical CLMU range (0 to 1e-5 kg/(m^2*s)). dw_ice_1_subl traces a straight line from 0 to -1e-5 — visualizing the sign-flip of Eq. 5.152. The other two tendencies stay pinned at zero across the sweep.",
"initial_state": {},
"parameters": {
"q_sdew": 0.0,
"q_frost": 0.0
},
"time_span": {
"start": 0.0,
"end": 1.0
},
"parameter_sweep": {
"type": "cartesian",
"dimensions": [
{
"parameter": "q_subl",
"range": {
"start": 0.0,
"stop": 1e-05,
"count": 21,
"scale": "linear"
}
}
]
},
"plots": [
{
"id": "dw_ice_subl_vs_q_subl",
"type": "line",
"description": "dw_ice_1_subl vs q_subl — straight line through the origin with slope -1, exhibiting Eq. 5.152.",
"x": {
"variable": "q_subl",
"label": "q_subl (kg/(m^2*s))"
},
"y": {
"variable": "dw_ice_1_subl",
"label": "dw_ice_1_subl (kg/(m^2*s))"
}
}
]
},
{
"id": "dew_frost_phase_partition",
"description": "Joint sweep of dew (q_sdew) and frost (q_frost) rates at fixed zero sublimation. Surfaces the independence of the liquid- and ice-tendency channels: dw_liq_1 depends only on q_sdew, dw_ice_1_frost only on q_frost. Useful as a regression baseline confirming that no cross-coupling has been silently introduced.",
"initial_state": {},
"parameters": {
"q_subl": 0.0
},
"time_span": {
"start": 0.0,
"end": 1.0
},
"parameter_sweep": {
"type": "cartesian",
"dimensions": [
{
"parameter": "q_sdew",
"range": {
"start": 0.0,
"stop": 1e-05,
"count": 11,
"scale": "linear"
}
},
{
"parameter": "q_frost",
"range": {
"start": 0.0,
"stop": 1e-05,
"count": 11,
"scale": "linear"
}
}
]
},
"plots": [
{
"id": "dw_liq_heatmap",
"type": "heatmap",
"description": "dw_liq_1 vs (q_sdew, q_frost) — must vary only along the q_sdew axis.",
"x": {
"variable": "q_sdew",
"label": "q_sdew (kg/(m^2*s))"
},
"y": {
"variable": "q_frost",
"label": "q_frost (kg/(m^2*s))"
},
"value": {
"variable": "dw_liq_1",
"reduce": "final"
}
},
{
"id": "dw_ice_frost_heatmap",
"type": "heatmap",
"description": "dw_ice_1_frost vs (q_sdew, q_frost) — must vary only along the q_frost axis.",
"x": {
"variable": "q_sdew",
"label": "q_sdew (kg/(m^2*s))"
},
"y": {
"variable": "q_frost",
"label": "q_frost (kg/(m^2*s))"
},
"value": {
"variable": "dw_ice_1_frost",
"reduce": "final"
}
}
]
}
]
}