Version: dev

SnowLayerCombination

Combined-layer properties when two snow layers are merged (Oleson et al. 2010, Section 5.1.5.1, Eqs. 5.38–5.42). Migrated from UrbanCanopy.jl@9200edd4 src/hydrology.jl:253 (`SnowLayerCombination` @component). Observed-only: per-layer thicknesses, water/ice contents, and temperatures are inputs (parameters); combined thickness/water/ice/enthalpies/temperature are algebraic outputs.

.esm schema
1.0.0
Source
components/urban_canopy/hydro/snow_layer_combination.esm

Description

Combined-layer properties when two snow layers are merged (Oleson et al. 2010, Section 5.1.5.1, Eqs. 5.38–5.42). Migrated from UrbanCanopy.jl@9200edd4 src/hydrology.jl:253 (SnowLayerCombination @component). Observed-only: per-layer thicknesses, water/ice contents, and temperatures are inputs (parameters); combined thickness/water/ice/enthalpies/temperature are algebraic outputs.

Reference

_source_ref: UrbanCanopy.jl@9200edd4f15609f20339d3a7d104de8064544310:src/hydrology.jl:253 Upstream SnowLayerCombination is an MTK @component whose per-layer inputs (Δz_1, Δz_2, w_liq_1, w_liq_2, w_ice_1, w_ice_2, T_1, T_2) are @parameters and whose outputs (Δz_c, w_liq_c, w_ice_c, T_c, h_1, h_2) are time-indexed @variables with algebraic-only equations. Identical structure preserved here; the unicode Δz symbol is rendered as ASCII Dz (other ESM components in this rig use ASCII identifiers — see e.g. components/wildland_fire/terrain_slope.esm tan_phi). The upstream @constants block (T_f, L_f, C_ice, C_liq) is preserved as zero-tolerance parameters with the upstream default values; they are physical constants from Oleson 2010 Table 1.4 and are not intended to be tuned.

The combined-temperature equation T_c = T_f + (h_1 + h_2 - L_f * w_liq_c) / (C_ice * w_ice_c + C_liq * w_liq_c) requires a non-zero denominator C_ice * w_ice_c + C_liq * w_liq_c — i.e. the merged layer must contain at least some ice or liquid water. All test cases below preserve that invariant.

Tolerance rationale (model-level rel=1e-9): observed-only algebraic system (no ODE integration); the equations are products, sums, and one division — five floating-point operations on hardware-supported intrinsics — so float64 roundoff is ~1e-15. 1e-9 leaves comfortable headroom above ULP roundoff and is well below any plausible physical-discrimination scale on snow layer enthalpies (which are O(1e5–1e6 J/m^2) and combined temperatures (which carry K resolution ~1e-2 in practice)._

Parameters

NameUnitsDefaultDescription
T_fK273.15Freezing temperature of water (Oleson et al. 2010 Table 1.4)
L_fJ/kg333700.0Latent heat of fusion of water (Oleson et al. 2010 Table 1.4; 3.337e5 J/kg)
C_iceJ/kg/K2117.27Specific heat of ice (Oleson et al. 2010 Table 1.4)
C_liqJ/kg/K4188.0Specific heat of liquid water (Oleson et al. 2010 Table 1.4)
Dz_1m0.05Thickness of layer 1
Dz_2m0.05Thickness of layer 2
w_liq_1kg/m^21.0Liquid water in layer 1
w_liq_2kg/m^21.0Liquid water in layer 2
w_ice_1kg/m^25.0Ice content in layer 1
w_ice_2kg/m^25.0Ice content in layer 2
T_1K270.0Temperature of layer 1
T_2K270.0Temperature of layer 2

Observed

NameUnitsDefaultDescription
Dz_cmCombined thickness (Eq. 5.38)
w_liq_ckg/m^2Combined liquid water (Eq. 5.39)
w_ice_ckg/m^2Combined ice content (Eq. 5.40)
T_cKCombined temperature (Eq. 5.41)
h_1J/m^2Enthalpy of layer 1 (Eq. 5.42)
h_2J/m^2Enthalpy of layer 2 (Eq. 5.42)

Observed expressions

$$ Dz_{c} = Dz_{1} + Dz_{2} $$

Combined thickness (Eq. 5.38)

$$ w_{liq\,c} = w_{liq\,1} + w_{liq\,2} $$

Combined liquid water (Eq. 5.39)

$$ w_{ice\,c} = w_{ice\,1} + w_{ice\,2} $$

Combined ice content (Eq. 5.40)

$$ T_{c} = T_{f} + \frac{h_{1} + h_{2} - L_{f} \cdot w_{liq\,c}}{C_{ice} \cdot w_{ice\,c} + C_{liq} \cdot w_{liq\,c}} $$

Combined temperature (Eq. 5.41)

$$ h_{1} = \left(C_{ice} \cdot w_{ice\,1} + C_{liq} \cdot w_{liq\,1}\right) \cdot \left(T_{1} - T_{f}\right) + L_{f} \cdot w_{liq\,1} $$

Enthalpy of layer 1 (Eq. 5.42)

$$ h_{2} = \left(C_{ice} \cdot w_{ice\,2} + C_{liq} \cdot w_{liq\,2}\right) \cdot \left(T_{2} - T_{f}\right) + L_{f} \cdot w_{liq\,2} $$

Enthalpy of layer 2 (Eq. 5.42)

Analyses

Tc_vs_T1_isothermal_pair_T2

Sweep T_1 across the cold-snow range (250–273.15 K) at fixed T_2 = 270 K with equal-mass layers. The combined temperature traces the mass-weighted average — a straight line from (250, 260) to (273.15, 271.575) on the T_1 axis, demonstrating linear blending when the two heat capacities are matched.

Time span: 0.0 → 1.0

Swept over: T_1

Combined temperature T_c as a function of layer-1 temperature T_1 at fixed T_2 = 270 K (equal-mass mixing).

Layer-1 enthalpy h_1 as a function of layer-1 temperature — linear, with intercept set by the latent-heat term L_f * w_liq_1.

Tc_heatmap_T1_T2

Two-dimensional sweep over (T_1, T_2) covering the cold-snow range (250–273.15 K) — surfaces the planar mass-weighted T_c surface that drives the layer-merging step in the CLM4-Urban snow scheme.

Time span: 0.0 → 1.0

Swept over: T_1, T_2

Combined temperature T_c(T_1, T_2) for equal-mass layers — symmetric about the T_1 = T_2 diagonal.

Raw .esm

Raw .esm JSON (this component)
{
  "reference": {
    "notes": "source_ref: UrbanCanopy.jl@9200edd4f15609f20339d3a7d104de8064544310:src/hydrology.jl:253\nUpstream `SnowLayerCombination` is an MTK `@component` whose per-layer inputs (Δz_1, Δz_2, w_liq_1, w_liq_2, w_ice_1, w_ice_2, T_1, T_2) are `@parameters` and whose outputs (Δz_c, w_liq_c, w_ice_c, T_c, h_1, h_2) are time-indexed `@variables` with algebraic-only equations. Identical structure preserved here; the unicode `Δz` symbol is rendered as ASCII `Dz` (other ESM components in this rig use ASCII identifiers — see e.g. components/wildland_fire/terrain_slope.esm `tan_phi`). The upstream `@constants` block (T_f, L_f, C_ice, C_liq) is preserved as zero-tolerance parameters with the upstream default values; they are physical constants from Oleson 2010 Table 1.4 and are not intended to be tuned.\n\nThe combined-temperature equation T_c = T_f + (h_1 + h_2 - L_f * w_liq_c) / (C_ice * w_ice_c + C_liq * w_liq_c) requires a non-zero denominator C_ice * w_ice_c + C_liq * w_liq_c — i.e. the merged layer must contain at least some ice or liquid water. All test cases below preserve that invariant.\n\nTolerance rationale (model-level rel=1e-9): observed-only algebraic system (no ODE integration); the equations are products, sums, and one division — five floating-point operations on hardware-supported intrinsics — so float64 roundoff is ~1e-15. 1e-9 leaves comfortable headroom above ULP roundoff and is well below any plausible physical-discrimination scale on snow layer enthalpies (which are O(1e5–1e6 J/m^2) and combined temperatures (which carry K resolution ~1e-2 in practice)."
  },
  "tolerance": {
    "rel": 1e-09
  },
  "variables": {
    "T_f": {
      "type": "parameter",
      "units": "K",
      "default": 273.15,
      "description": "Freezing temperature of water (Oleson et al. 2010 Table 1.4)"
    },
    "L_f": {
      "type": "parameter",
      "units": "J/kg",
      "default": 333700.0,
      "description": "Latent heat of fusion of water (Oleson et al. 2010 Table 1.4; 3.337e5 J/kg)"
    },
    "C_ice": {
      "type": "parameter",
      "units": "J/kg/K",
      "default": 2117.27,
      "description": "Specific heat of ice (Oleson et al. 2010 Table 1.4)"
    },
    "C_liq": {
      "type": "parameter",
      "units": "J/kg/K",
      "default": 4188.0,
      "description": "Specific heat of liquid water (Oleson et al. 2010 Table 1.4)"
    },
    "Dz_1": {
      "type": "parameter",
      "units": "m",
      "default": 0.05,
      "description": "Thickness of layer 1"
    },
    "Dz_2": {
      "type": "parameter",
      "units": "m",
      "default": 0.05,
      "description": "Thickness of layer 2"
    },
    "w_liq_1": {
      "type": "parameter",
      "units": "kg/m^2",
      "default": 1.0,
      "description": "Liquid water in layer 1"
    },
    "w_liq_2": {
      "type": "parameter",
      "units": "kg/m^2",
      "default": 1.0,
      "description": "Liquid water in layer 2"
    },
    "w_ice_1": {
      "type": "parameter",
      "units": "kg/m^2",
      "default": 5.0,
      "description": "Ice content in layer 1"
    },
    "w_ice_2": {
      "type": "parameter",
      "units": "kg/m^2",
      "default": 5.0,
      "description": "Ice content in layer 2"
    },
    "T_1": {
      "type": "parameter",
      "units": "K",
      "default": 270.0,
      "description": "Temperature of layer 1"
    },
    "T_2": {
      "type": "parameter",
      "units": "K",
      "default": 270.0,
      "description": "Temperature of layer 2"
    },
    "Dz_c": {
      "type": "unknown",
      "units": "m",
      "description": "Combined thickness (Eq. 5.38)"
    },
    "w_liq_c": {
      "type": "unknown",
      "units": "kg/m^2",
      "description": "Combined liquid water (Eq. 5.39)"
    },
    "w_ice_c": {
      "type": "unknown",
      "units": "kg/m^2",
      "description": "Combined ice content (Eq. 5.40)"
    },
    "T_c": {
      "type": "unknown",
      "units": "K",
      "description": "Combined temperature (Eq. 5.41)"
    },
    "h_1": {
      "type": "unknown",
      "units": "J/m^2",
      "description": "Enthalpy of layer 1 (Eq. 5.42)"
    },
    "h_2": {
      "type": "unknown",
      "units": "J/m^2",
      "description": "Enthalpy of layer 2 (Eq. 5.42)"
    }
  },
  "equations": [
    {
      "lhs": "Dz_c",
      "rhs": {
        "op": "+",
        "args": [
          "Dz_1",
          "Dz_2"
        ]
      }
    },
    {
      "lhs": "w_liq_c",
      "rhs": {
        "op": "+",
        "args": [
          "w_liq_1",
          "w_liq_2"
        ]
      }
    },
    {
      "lhs": "w_ice_c",
      "rhs": {
        "op": "+",
        "args": [
          "w_ice_1",
          "w_ice_2"
        ]
      }
    },
    {
      "lhs": "h_1",
      "rhs": {
        "op": "+",
        "args": [
          {
            "op": "*",
            "args": [
              {
                "op": "+",
                "args": [
                  {
                    "op": "*",
                    "args": [
                      "C_ice",
                      "w_ice_1"
                    ]
                  },
                  {
                    "op": "*",
                    "args": [
                      "C_liq",
                      "w_liq_1"
                    ]
                  }
                ]
              },
              {
                "op": "-",
                "args": [
                  "T_1",
                  "T_f"
                ]
              }
            ]
          },
          {
            "op": "*",
            "args": [
              "L_f",
              "w_liq_1"
            ]
          }
        ]
      }
    },
    {
      "lhs": "h_2",
      "rhs": {
        "op": "+",
        "args": [
          {
            "op": "*",
            "args": [
              {
                "op": "+",
                "args": [
                  {
                    "op": "*",
                    "args": [
                      "C_ice",
                      "w_ice_2"
                    ]
                  },
                  {
                    "op": "*",
                    "args": [
                      "C_liq",
                      "w_liq_2"
                    ]
                  }
                ]
              },
              {
                "op": "-",
                "args": [
                  "T_2",
                  "T_f"
                ]
              }
            ]
          },
          {
            "op": "*",
            "args": [
              "L_f",
              "w_liq_2"
            ]
          }
        ]
      }
    },
    {
      "lhs": "T_c",
      "rhs": {
        "op": "+",
        "args": [
          "T_f",
          {
            "op": "/",
            "args": [
              {
                "op": "-",
                "args": [
                  {
                    "op": "+",
                    "args": [
                      "h_1",
                      "h_2"
                    ]
                  },
                  {
                    "op": "*",
                    "args": [
                      "L_f",
                      "w_liq_c"
                    ]
                  }
                ]
              },
              {
                "op": "+",
                "args": [
                  {
                    "op": "*",
                    "args": [
                      "C_ice",
                      "w_ice_c"
                    ]
                  },
                  {
                    "op": "*",
                    "args": [
                      "C_liq",
                      "w_liq_c"
                    ]
                  }
                ]
              }
            ]
          }
        ]
      }
    }
  ],
  "tests": [
    {
      "id": "equal_layers_isothermal_270K",
      "description": "Two identical layers at 270 K. Combined T_c must equal each layer's T (no thermal mixing); combined Δz/w_liq/w_ice are simple sums; h_1 and h_2 must be equal.",
      "parameter_overrides": {
        "Dz_1": 0.05,
        "Dz_2": 0.05,
        "w_liq_1": 1.0,
        "w_liq_2": 1.0,
        "w_ice_1": 5.0,
        "w_ice_2": 5.0,
        "T_1": 270.0,
        "T_2": 270.0
      },
      "time_span": {
        "start": 0.0,
        "end": 1.0
      },
      "assertions": [
        {
          "variable": "Dz_c",
          "time": 0.0,
          "expected": 0.1
        },
        {
          "variable": "w_liq_c",
          "time": 0.0,
          "expected": 2.0
        },
        {
          "variable": "w_ice_c",
          "time": 0.0,
          "expected": 10.0
        },
        {
          "variable": "h_1",
          "time": 0.0,
          "expected": 287160.79750000034
        },
        {
          "variable": "h_2",
          "time": 0.0,
          "expected": 287160.79750000034
        },
        {
          "variable": "T_c",
          "time": 0.0,
          "expected": 270.0
        }
      ]
    },
    {
      "id": "upstream_test_reference",
      "description": "Reproduces the parameter point used by the upstream Julia `SnowLayerCombination - Equation Verification` testitem (UrbanCanopy.jl test/hydrology_test.jl:571). Asymmetric layers (Δz, w_liq, w_ice, T all differ) — exercises the full mixing formula end-to-end.",
      "parameter_overrides": {
        "Dz_1": 0.05,
        "Dz_2": 0.1,
        "w_liq_1": 0.5,
        "w_liq_2": 1.0,
        "w_ice_1": 3.0,
        "w_ice_2": 5.0,
        "T_1": 270.0,
        "T_2": 265.0
      },
      "time_span": {
        "start": 0.0,
        "end": 1.0
      },
      "assertions": [
        {
          "variable": "Dz_c",
          "time": 0.0,
          "expected": 0.15000000000000002
        },
        {
          "variable": "w_liq_c",
          "time": 0.0,
          "expected": 1.5
        },
        {
          "variable": "w_ice_c",
          "time": 0.0,
          "expected": 8.0
        },
        {
          "variable": "h_1",
          "time": 0.0,
          "expected": 140245.6985000002
        },
        {
          "variable": "h_2",
          "time": 0.0,
          "expected": 213289.04750000034
        },
        {
          "variable": "T_c",
          "time": 0.0,
          "expected": 266.8186373392776
        }
      ]
    },
    {
      "id": "freezing_isothermal",
      "description": "Both layers at the freezing point (T_1 = T_2 = T_f = 273.15 K). The (T_i - T_f) term collapses to zero, leaving only the latent-heat term: h_i = L_f * w_liq_i. T_c = T_f exactly.",
      "parameter_overrides": {
        "Dz_1": 0.05,
        "Dz_2": 0.05,
        "w_liq_1": 1.0,
        "w_liq_2": 1.0,
        "w_ice_1": 5.0,
        "w_ice_2": 5.0,
        "T_1": 273.15,
        "T_2": 273.15
      },
      "time_span": {
        "start": 0.0,
        "end": 1.0
      },
      "assertions": [
        {
          "variable": "h_1",
          "time": 0.0,
          "expected": 333700.0
        },
        {
          "variable": "h_2",
          "time": 0.0,
          "expected": 333700.0
        },
        {
          "variable": "T_c",
          "time": 0.0,
          "expected": 273.15
        }
      ]
    },
    {
      "id": "no_liquid_cold",
      "description": "Dry-snow regime: w_liq_1 = w_liq_2 = 0 (no latent-heat contribution). Mass-weighted temperature mixing reduces to T_c = T_f + (C_ice * (w_ice_1 * (T_1 - T_f) + w_ice_2 * (T_2 - T_f))) / (C_ice * w_ice_c) = T_f + ((10 * (-13.15) + 20 * (-23.15)) / 30) = 253.333... K. Exercises the C_liq * w_liq term collapsing to zero on both sides of the division.",
      "parameter_overrides": {
        "Dz_1": 0.1,
        "Dz_2": 0.2,
        "w_liq_1": 0.0,
        "w_liq_2": 0.0,
        "w_ice_1": 10.0,
        "w_ice_2": 20.0,
        "T_1": 260.0,
        "T_2": 250.0
      },
      "time_span": {
        "start": 0.0,
        "end": 1.0
      },
      "assertions": [
        {
          "variable": "Dz_c",
          "time": 0.0,
          "expected": 0.30000000000000004
        },
        {
          "variable": "w_liq_c",
          "time": 0.0,
          "expected": 0.0,
          "tolerance": {
            "abs": 1e-15
          }
        },
        {
          "variable": "w_ice_c",
          "time": 0.0,
          "expected": 30.0
        },
        {
          "variable": "h_1",
          "time": 0.0,
          "expected": -278421.00499999954
        },
        {
          "variable": "h_2",
          "time": 0.0,
          "expected": -980296.0099999991
        },
        {
          "variable": "T_c",
          "time": 0.0,
          "expected": 253.33333333333331
        }
      ]
    },
    {
      "id": "no_ice_warm",
      "description": "Slush/melt-pool regime: w_ice = 0 in both layers (only liquid water). The (h_1 + h_2 - L_f * w_liq_c) numerator cancels the latent-heat term, leaving the sensible-heat balance over C_liq alone. T_c collapses to the common T = 274 K.",
      "parameter_overrides": {
        "Dz_1": 0.05,
        "Dz_2": 0.05,
        "w_liq_1": 5.0,
        "w_liq_2": 5.0,
        "w_ice_1": 0.0,
        "w_ice_2": 0.0,
        "T_1": 274.0,
        "T_2": 274.0
      },
      "time_span": {
        "start": 0.0,
        "end": 1.0
      },
      "assertions": [
        {
          "variable": "w_ice_c",
          "time": 0.0,
          "expected": 0.0,
          "tolerance": {
            "abs": 1e-15
          }
        },
        {
          "variable": "h_1",
          "time": 0.0,
          "expected": 1686299.0000000005
        },
        {
          "variable": "h_2",
          "time": 0.0,
          "expected": 1686299.0000000005
        },
        {
          "variable": "T_c",
          "time": 0.0,
          "expected": 274.0
        }
      ]
    },
    {
      "id": "asymmetric_thickness",
      "description": "Highly asymmetric thicknesses (Δz_1 = 0.02 m vs Δz_2 = 0.18 m, 9× ratio) with proportionally scaled water/ice contents (w_*_2 = 9 * w_*_1). The mass-weighted T_c lies near the temperature of the larger thermal mass (T_2 = 271 K) — exercises the heat-capacity-weighted mixing in the (h_1 + h_2)/(C_ice w_ice_c + C_liq w_liq_c) division.",
      "parameter_overrides": {
        "Dz_1": 0.02,
        "Dz_2": 0.18,
        "w_liq_1": 0.5,
        "w_liq_2": 4.5,
        "w_ice_1": 2.0,
        "w_ice_2": 18.0,
        "T_1": 268.0,
        "T_2": 271.0
      },
      "time_span": {
        "start": 0.0,
        "end": 1.0
      },
      "assertions": [
        {
          "variable": "Dz_c",
          "time": 0.0,
          "expected": 0.19999999999999998
        },
        {
          "variable": "w_liq_c",
          "time": 0.0,
          "expected": 5.0
        },
        {
          "variable": "w_ice_c",
          "time": 0.0,
          "expected": 20.0
        },
        {
          "variable": "h_1",
          "time": 0.0,
          "expected": 134258.01900000015
        },
        {
          "variable": "h_2",
          "time": 0.0,
          "expected": 1379192.7510000013
        },
        {
          "variable": "T_c",
          "time": 0.0,
          "expected": 270.7
        }
      ]
    },
    {
      "id": "different_temps_equal_mass",
      "description": "Equal-mass layers at different temperatures (T_1 = 268 K, T_2 = 272 K). Heat capacities cancel; T_c = (T_1 + T_2)/2 = 270 K. Cross-checks that the latent-heat term contributes equally to both numerator (via h_1, h_2) and the L_f * w_liq_c subtraction in the (h_1+h_2-L_f*w_liq_c) numerator.",
      "parameter_overrides": {
        "Dz_1": 0.05,
        "Dz_2": 0.05,
        "w_liq_1": 1.0,
        "w_liq_2": 1.0,
        "w_ice_1": 5.0,
        "w_ice_2": 5.0,
        "T_1": 268.0,
        "T_2": 272.0
      },
      "time_span": {
        "start": 0.0,
        "end": 1.0
      },
      "assertions": [
        {
          "variable": "h_1",
          "time": 0.0,
          "expected": 257612.09750000032
        },
        {
          "variable": "h_2",
          "time": 0.0,
          "expected": 316709.49750000035
        },
        {
          "variable": "T_c",
          "time": 0.0,
          "expected": 270.0
        }
      ]
    },
    {
      "id": "thick_warm_thin_cold",
      "description": "Thin cold layer (Δz_1 = 0.01 m, T_1 = 265 K) merged with a thick warm layer (Δz_2 = 0.20 m, T_2 = 272.5 K). Combined T_c is heavily weighted toward the larger-mass warm layer (T_c ≈ 272.21 K, much closer to T_2 than to (T_1+T_2)/2 = 268.75 K). Exercises mass-weighted mixing across a 20× thickness ratio.",
      "parameter_overrides": {
        "Dz_1": 0.01,
        "Dz_2": 0.2,
        "w_liq_1": 0.1,
        "w_liq_2": 5.0,
        "w_ice_1": 1.0,
        "w_ice_2": 20.0,
        "T_1": 265.0,
        "T_2": 272.5
      },
      "time_span": {
        "start": 0.0,
        "end": 1.0
      },
      "assertions": [
        {
          "variable": "Dz_c",
          "time": 0.0,
          "expected": 0.21000000000000002
        },
        {
          "variable": "w_liq_c",
          "time": 0.0,
          "expected": 5.1
        },
        {
          "variable": "w_ice_c",
          "time": 0.0,
          "expected": 21.0
        },
        {
          "variable": "h_1",
          "time": 0.0,
          "expected": 12701.029500000055
        },
        {
          "variable": "h_2",
          "time": 0.0,
          "expected": 1627364.4900000014
        },
        {
          "variable": "T_c",
          "time": 0.0,
          "expected": 272.21102855952626
        }
      ]
    }
  ],
  "analyses": [
    {
      "id": "Tc_vs_T1_isothermal_pair_T2",
      "description": "Sweep T_1 across the cold-snow range (250–273.15 K) at fixed T_2 = 270 K with equal-mass layers. The combined temperature traces the mass-weighted average — a straight line from (250, 260) to (273.15, 271.575) on the T_1 axis, demonstrating linear blending when the two heat capacities are matched.",
      "initial_state": {},
      "parameters": {
        "Dz_1": 0.05,
        "Dz_2": 0.05,
        "w_liq_1": 1.0,
        "w_liq_2": 1.0,
        "w_ice_1": 5.0,
        "w_ice_2": 5.0,
        "T_2": 270.0
      },
      "time_span": {
        "start": 0.0,
        "end": 1.0
      },
      "parameter_sweep": {
        "type": "cartesian",
        "dimensions": [
          {
            "parameter": "T_1",
            "range": {
              "start": 250.0,
              "stop": 273.15,
              "count": 24,
              "scale": "linear"
            }
          }
        ]
      },
      "plots": [
        {
          "id": "Tc_curve",
          "type": "line",
          "description": "Combined temperature T_c as a function of layer-1 temperature T_1 at fixed T_2 = 270 K (equal-mass mixing).",
          "x": {
            "variable": "T_1",
            "label": "Layer 1 temperature (K)"
          },
          "y": {
            "variable": "T_c",
            "label": "Combined temperature (K)"
          }
        },
        {
          "id": "h1_curve",
          "type": "line",
          "description": "Layer-1 enthalpy h_1 as a function of layer-1 temperature — linear, with intercept set by the latent-heat term L_f * w_liq_1.",
          "x": {
            "variable": "T_1",
            "label": "Layer 1 temperature (K)"
          },
          "y": {
            "variable": "h_1",
            "label": "Layer 1 enthalpy (J/m^2)"
          }
        }
      ]
    },
    {
      "id": "Tc_heatmap_T1_T2",
      "description": "Two-dimensional sweep over (T_1, T_2) covering the cold-snow range (250–273.15 K) — surfaces the planar mass-weighted T_c surface that drives the layer-merging step in the CLM4-Urban snow scheme.",
      "initial_state": {},
      "parameters": {
        "Dz_1": 0.05,
        "Dz_2": 0.05,
        "w_liq_1": 1.0,
        "w_liq_2": 1.0,
        "w_ice_1": 5.0,
        "w_ice_2": 5.0
      },
      "time_span": {
        "start": 0.0,
        "end": 1.0
      },
      "parameter_sweep": {
        "type": "cartesian",
        "dimensions": [
          {
            "parameter": "T_1",
            "range": {
              "start": 250.0,
              "stop": 273.15,
              "count": 12,
              "scale": "linear"
            }
          },
          {
            "parameter": "T_2",
            "range": {
              "start": 250.0,
              "stop": 273.15,
              "count": 12,
              "scale": "linear"
            }
          }
        ]
      },
      "plots": [
        {
          "id": "Tc_surface",
          "type": "heatmap",
          "description": "Combined temperature T_c(T_1, T_2) for equal-mass layers — symmetric about the T_1 = T_2 diagonal.",
          "x": {
            "variable": "T_1",
            "label": "Layer 1 temperature (K)"
          },
          "y": {
            "variable": "T_2",
            "label": "Layer 2 temperature (K)"
          },
          "value": {
            "variable": "T_c",
            "reduce": "final"
          }
        }
      ]
    }
  ]
}