Skip to content

Runtime configurable removal of frozen runoff associated with snowcapping#8384

Draft
stephenprice wants to merge 11 commits into
E3SM-Project:masterfrom
stephenprice:stephenprice/ocn/adjust-snowcapped-liquid-temperature
Draft

Runtime configurable removal of frozen runoff associated with snowcapping#8384
stephenprice wants to merge 11 commits into
E3SM-Project:masterfrom
stephenprice:stephenprice/ocn/adjust-snowcapped-liquid-temperature

Conversation

@stephenprice
Copy link
Copy Markdown
Contributor

@stephenprice stephenprice commented May 11, 2026

Overview

By default, frozen runoff from snowcapping is sent to coastal ocean cells via nearest neighbor mapping, where the necessary latent heat of fusion (to convert ice to liquid water) is extracted from the ocean water in those cells. This can lead to excessive cooling of the coastal ocean and, sometimes, non-physical sea ice formation (e.g., in low-lat. regions of the planet). The code changes in this PR add a runtime configurable option (via user namelist settings) to instead send that runoff to the rof stream where it enters the ocean at the same temperature as all other runoff. The latent heat is instead extracted from the snowpack where (and proportional to) the mass that was removed from the snowpack. Within each component section below is additional information on how to configure the necessary changes at run time.

** Note that below here, this description remains in draft form and is still being updated **

Changes by component

ELM (land model)SnowHydrologyMod.F90, elm_varctl.F90, controlMod.F90, elm_driver.F90, namelist XML files

  • New subroutine SnowCapLatentCoolingAndDiag: when the latitude-band snowcapping feature is enabled (convert_ice_to_river_runoff_latband = .true.), snowcapped ice within the configured band is rerouted through MOSART as liquid runoff rather than being sent to the ocean as ice. To conserve energy, this subroutine extracts the corresponding latent heat of fusion from the local snowpack by cooling snow layer temperatures. The cooling is distributed uniformly (or optionally surface-weighted) across all active snow layers with meaningful heat capacity. Columns outside the latitude band and all columns when the feature is disabled are unaffected — their snowcapped ice continues to the ocean as ice runoff, where the ocean handles the phase-change energy as in the default code path.

  • New subroutines SnowCappingDiagReset / SnowCappingDiagLog: accumulate and write per-timestep and cumulative snowcapping diagnostics to the ELM log, including total ice mass removed, latent energy extracted, area-weighted mean and maximum column cooling, and number of affected columns. Diagnostics use MPI_ALLREDUCE for global aggregation. Writing frequency is configurable using the user_nl_elm options noted below.

  • Called from elm_driver.F90: SnowCappingDiagReset is called once before the clump loop each timestep; SnowCapLatentCoolingAndDiag is called after drainage within each clump; SnowCappingDiagLog is called after write_diagnostic.

  • Four new namelist parameters in elm_inparm:

    • convert_ice_to_river_runoff_latband (logical, default .false.) — enable lat-band gating
    • convert_ice_to_river_runoff_latband_width_degrees (real, default 20.0) — half-width of the latitude band in degrees
    • snowcap_latband_diag_write (logical, default .false.) — enable diagnostic logging
    • snowcap_latband_diag_nstep (integer, default 1) — diagnostic write frequency in timesteps (e.g., for a land model timestep of 30 mins, setting equal to 48 will provide a single set of daily values for the diagnostics in the lnd.log file).

MOSART (river routing)rof_comp_mct.F90, RtmMod.F90, RtmVar.F90, namelist XML files

  • In the export routine (rof_export_mct), when convert_ice_to_river_runoff_latband is enabled, frozen runoff (rofi) is converted to liquid runoff (rofl) for grid cells within the configured latitude band. This ensures snowcapped ice mass is routed through the river network as liquid water rather than being passed to the ocean as ice runoff, which allows the mass to appear correctly in coupler budget tables.
  • Two new namelist parameters in mosart_inparm mirror the ELM settings:
    • convert_ice_to_river_runoff_latband (logical, default .false.)
    • convert_ice_to_river_runoff_latband_width_degrees (real, default 20.0)

MPAS-Oceanocn_comp_mct.F

  • Minor cleanup: whitespace normalization, added areaCell pointer declaration and loop variable i (supporting infrastructure for related ice-runoff diagnostics).
  • Removed a stray blank line in Registry.xml.

Key design decisions

  • Gated by lat-band feature: latent cooling of the snowpack is applied only when convert_ice_to_river_runoff_latband = .true. and only to columns within the configured band. When the feature is disabled (the default), no local cooling occurs — snowcapped ice is sent to the ocean as ice runoff and the ocean handles the phase-change energy, exactly as in the baseline code.
  • Decoupled from firn gating: when the lat-band feature is active, the latent cooling applies to all snowcapped ice (qflx_snwcp_ice) — including contributions from CanopyHydrology, SoilHydrology excess-ice, and SnowCapping — not just the portion gated by the firn percolation code path. This ensures energy conservation regardless of whether use_firn_percolation_and_compaction is active.
  • Lat-band consistency: the same latitude-band width parameter controls both the ELM-side cooling and the MOSART-side rofirofl conversion, ensuring the two are applied to the same geographic region.
  • Off by default: all new behavior is disabled by default (convert_ice_to_river_runoff_latband = .false.), preserving bit-for-bit results for existing configurations.
  • Thread safety: per-step diagnostic accumulators use !$omp atomic updates and !$omp critical for the max-cooling tracker.

Copilot-generated draft code to find snowcapped runoff within a user
specified latitude band and remove it from the frozen runoff stream
and put it in the river runoff stream, with the goal of raising the
temperature to river runoff temperatures, thus preventing snowcapped
runoff from leading to sea ice formation with that latitude band.
Yet to be implemented is energy conservation -- currently energy
violation is simply tracked and report in the mpas-o log file.

Add configurable conversion of frozen runoff to liquid runoff within a
symmetric equatorial latitude band:
config_convert_ice_to_river_runoff_latband
config_convert_ice_to_river_runoff_latband_width_degrees
Apply conversion in MCT ocean import while conserving local freshwater mass
(rofl += rofi, rofi = 0 in selected cells)
Add diagnostics for converted flux and associated energy deficit:
convertedIceRunoffFlux / avgConvertedIceRunoffFlux
convertedIceRunoffEnergyDeficitFlux /
avgConvertedIceRunoffEnergyDeficitFlux
Add runtime monitoring log output with global converted mass flux,
instantaneous estimated energy deficit power, and cumulative deficit energy
Update MPAS-O namelist registry/definition/defaults for new controls
version first routes removed snowcapped runoff through MOSART rather
than directly to the ocean, thereby allowing mass changes to show up
appropriately in coupler budget tables. Runs of <1 day, 1 day, and 1
month appear to converm overall mass conservation. Energy conservation
remains to be tested / confirmed.

- add ELM SnowCapping heat sink to cool snowpack by capped-ice latent energy
  (uniform vertical distribution)
- move rofi->rofl latitude-band conversion upstream into MOSART export
- add MOSART namelist controls for latitude-band conversion
- remove obsolete MPAS-O conversion options, diagnostics, and driver plumbing
- keep conversion upstream so coupler-side budget accounting remains consistent
CoPilot generated code towards fix to snowcapping-related sea ice
production in low-lat. coastal regions. Additions and edits on top of
previous two related commits.

Align snowcapping physics with the MOSART lat-band routing intent by making
ELM local latent-heat extraction conditional on the same latitude-band controls.
When the switch is enabled, ELM removes latent heat only within the configured
band; outside the band, behavior remains the default downstream treatment.

Add ELM namelist controls and defaults:

convert_ice_to_river_runoff_latband
convert_ice_to_river_runoff_latband_width_degrees
Wire controls through elm_varctl/control and apply latitude masking in
SnowCapping using topounit latitude.

Fix a coupled-build regression in MPAS-Ocean by removing a duplicate
declaration of avgRemovedIceRunoffHeatFlux in
mpas_ocn_time_average_coupled.

No behavior change when the new lat-band switch is disabled.
CoPilot generated code to add optional SnowCapping diagnostics in ELM to
quantify latent-energy removal and cooling where snowcapped ice conversion
is active in the configured latitude band.

Add new elm_inparm controls:
snowcap_latband_diag_write
snowcap_latband_diag_nstep
Wire controls through varctl, control namelist handling, definitions,
defaults, and MPI broadcast.
Extend SnowHydrology SnowCapping with per-step diagnostics for:
capped ice mass
latent energy removed
area-weighted mean cooling
max cooling
affected column count
Add OpenMP-safe local-to-step accumulation and MPI global reductions.
Add cumulative diagnostic tracking and master-task iulog reporting.
Add SnowCappingDiagReset and SnowCappingDiagLog APIs.
Hook reset and log calls in elm_driver so diagnostics are tied to the
land-model timestep and logged with diagnostics cadence.
ELM: use gridcell latitude for snowcap cooling lat-band gate

Switch SnowHydrology lat-band gating for local latent-cooling extraction from
topounit latitude to gridcell latitude.

This aligns the ELM gate with the lat basis used by runoff routing conversion
and avoids missing in-band cooling due to topounit-lat source differences.

Additional changes by SP (from Az) to support running E3SM on bebop.
CoPilot-authored code changes to do the following:

Extract latent-heat extraction and diagnostic accumulation from
SnowCapping into a new subroutine SnowCapLatentCoolingAndDiag, called
once per time step from elm_driver after HydrologyDrainage.

Previously, latent cooling was applied inside SnowCapping, which is
only called when use_firn_percolation_and_compaction=.true. This meant
that in standard (non-firn) configurations, snowcapped ice was silently
converted to liquid runoff downstream without any compensating thermal
adjustment to the snowpack.

The new design accumulates all sources of qflx_snwcp_ice first
(CanopyHydrology, SoilHydrology excess-ice, and SnowCapping for firn
configs), then applies the latent cooling in a single pass over all
columns, gated by the existing latitude-band flag and using gridcell
latitude (consistent with the runoff routing conversion gate).
@stephenprice stephenprice marked this pull request as draft May 11, 2026 19:26
@stephenprice stephenprice changed the title Stephenprice/ocn/adjust snowcapped liquid temperature Runtime configurable removal of frozen runoff associated with snowcapping May 11, 2026
Copilot code changes made during the process of writing the PR
description and double checking that copilot's description of all
the code changes is consistent with the requirements.

Fix SnowCapLatentCoolingAndDiag so that no local snowpack cooling is
applied when convert_ice_to_river_runoff_latband is .false. (the
default).  Previously, apply_cooling was initialized to .true. and the
latitude-band check was skipped entirely when the feature was disabled,
causing latent heat to be extracted from the snowpack unconditionally —
even though the snowcapped ice was still being sent to the ocean as ice
runoff, where the ocean would also account for the phase-change energy.

Change apply_cooling default from .true. to .false. so that cooling is
only activated when the lat-band feature is enabled and the column falls
within the configured band.
@stephenprice
Copy link
Copy Markdown
Contributor Author

Additional feature design discussion and initial evaluation via ad hoc analysis (e.g., visualization using ncview and paraview, coupler budget examination) can be found here: https://e3sm.atlassian.net/wiki/spaces/pd/pages/6082429113/V4+snowcapping+fixes

A set of copilot derived python scripts for analyzing a run with these fixes in place (for a given latitude band) relative to a control run where these features are inactive can be found here:

https://github.com/stephenprice/analysis-scripts/tree/main/snowcapping

The config.py file in the directory contains additional user defined variables for the analysis (e.g., simulations paths) and other options for doing a comparative analysis between simulations in order to look at outputs like sea ice concentration, ice runoff flux, river runoff flux, snowcapping flux, and snowpack temperatures.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant