Skip to content

Port CLM cryosphere and hydrology fixes into ELM - #8638

Open
daliwang wants to merge 5 commits into
E3SM-Project:masterfrom
daliwang:lnd/port-clm-cryosphere-fixes-master
Open

Port CLM cryosphere and hydrology fixes into ELM#8638
daliwang wants to merge 5 commits into
E3SM-Project:masterfrom
daliwang:lnd/port-clm-cryosphere-fixes-master

Conversation

@daliwang

Copy link
Copy Markdown
Contributor

Summary

  • Port CLM cryosphere / hydrology bug fixes into ELM (snow energy and melt compaction, bedrock heat capacity, active-element accumulator masking, surface-water runoff, snow balance accounting).
  • Changes are in ELM biogeophysics and accumulator code only.

Commits

  • Port CLM fractional-snow energy and melt-compaction fixes
  • Port CLM bedrock heat capacity fix in SoilTemperatureMod
  • Port CLM active-element masking for ELM accumulators
  • Bug fixes for surface water runoff calculation
  • Fix snow balance accounting issue

Summary

  • Port CLM cryosphere / hydrology bug fixes into ELM (fractional-snow energy and melt compaction, bedrock heat capacity, active-element accumulator masking, surface-water runoff, snow balance accounting).
  • ELM biogeophysics and accumulator code only.

Testing

e3sm_land_developer on Frontier / craygnu (project cli115), 2026-08-14.

  • Branch: lnd/port-clm-cryosphere-fixes-master @ fbfcc93f52
  • Gold generated from parent master @ a899004464, then compared on this branch
  • Personal baseline root (not shared Frontier gold): /lustre/orion/cli115/world-shared/wangd/kmELM/baselines
Result Count Notes
BASELINE DIFF 48 Expected: snow, soil T, runoff, coupled fluxes change vs a899004464
PASS vs gold 5 MOSART-only tests; bit-for-bit
RUN FAIL (walltime) 2 Same two r05 tests timed out on generate and compare
MEMLEAK FAIL 4 Already present on parent master; not new on this branch

Namelists (NLCOMP) unchanged. All completed ERS tests passed COMPARE_base_rest (restart is bit-for-bit with itself). Debug builds DIFF, they do not crash.

The two walltime FAILs (no gold, so no baseline compare):

  • ERS.r05_r05.ICNPRDCTCBC.frontier_craygnu.elm-cbudget
  • ERS.r05_r05.IELM.frontier_craygnu.elm-V2_ELM_MOSART_features

daliwang and others added 5 commits August 14, 2026 00:04
Allow frac_sno_eff and melt-compaction ddz3 fractional forms for all
non-urban, non-lake columns when subgrid fluxes are on, matching
ctsm5.4.042 behavior for glacier and wetland columns.

Co-authored-by: Cursor <cursoragent@cursor.com>
Do not scale bedrock volumetric heat capacity by soil porosity
(1-watsat). Below nlevbed, use solid-rock heat capacity times layer
thickness, consistent with ctsm5.4.042.

Co-authored-by: Cursor <cursoragent@cursor.com>
Skip inactive subgrid points when updating timeavg, runmean, and
runaccum fields; track per-point nsteps for correct averaging and
restart, matching the ctsm5.4.042 accumulator redesign.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment on lines +557 to +573
!if (use_modified_infil) then
if (frac_h2osfc_act(c) <= pc .and. frac_h2osfc(c) <= pc) then
frac_infclust=0.0_r8
else
if (frac_h2osfc(c) <= pc) then
if (frac_h2osfc_act(c) <= pc) then
frac_infclust=(frac_h2osfc_act(c)-pc)**mu
else
frac_infclust=(frac_h2osfc(c)-pc)**mu
frac_infclust=(frac_h2osfc_act(c)-pc)**mu
endif
endif
else
if (frac_h2osfc(c) <= pc) then
frac_infclust=0.0_r8
else
frac_infclust=(frac_h2osfc(c)-pc)**mu
endif
endif
!else
! if (frac_h2osfc(c) <= pc) then
! frac_infclust=0.0_r8
! else
! frac_infclust=(frac_h2osfc(c)-pc)**mu
! endif
!endif

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me that we are making the use_modified_infil scheme as the default. So, why are we not doing it through namelist instead of commented out the old code and making the use_modified_infil as the default?

Or, if use_modified_infil needs to be made default, let's remove it from the namelist and delete the code corresponding to .not. use_modified_infil.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use_modified_infil is still used to control how the infiltration capacity is computed for different sub fractions. This modification just remove the control of use_modified_infil on the surface water runoff generation.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request ports a set of CLM cryosphere and hydrology fixes into ELM, focusing on snow energy / compaction behavior, soil thermal properties, accumulator handling for inactive subgrid elements, surface-water runoff, and snow-balance accounting within ELM biogeophysics and accumulator logic.

Changes:

  • Update ELM accumulators to skip inactive / zero-weight subgrid elements and track active-step counts via restartable _NSTEPS.
  • Apply CLM fixes to bedrock heat capacity handling and fractional-snow treatments (energy and melt compaction) across glacier/wetland-related pathways.
  • Adjust surface-water runoff / infiltration logic and update glacier snow water-balance accounting for fractional snow cover effects.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
components/elm/src/main/accumulMod.F90 Adds active-element masking to accumulators and introduces per-point step counts persisted via restart.
components/elm/src/biogeophys/SoilTemperatureMod.F90 Fixes bedrock-layer heat capacity calculation below the soil-bedrock boundary.
components/elm/src/biogeophys/SoilHydrologyMod.F90 Updates surface-water runoff / infiltration fraction logic and runoff coefficient behavior.
components/elm/src/biogeophys/SnowHydrologyMod.F90 Adjusts melt-compaction gating to follow CLM fractional-snow behavior outside lake/urban points.
components/elm/src/biogeophys/CanopyHydrologyMod.F90 Extends fractional-snow effective coverage logic beyond soil/crop to non-urban, non-lake columns under subgrid fluxes.
components/elm/src/biogeophys/BalanceCheckMod.F90 Updates snow-balance accounting on glacier columns to reflect fractional snow-covered flux partitioning.
Suppressed comments (1)

components/elm/src/main/accumulMod.F90:588

  • Same issue as the single-level updater: in the multi-level timeavg path, reset and normalization are skipped for inactive points because they are inside if (accum(nf)%active(k)). This can leave stale val/nsteps for inactive points (especially after restart or dynamic reweighting) and can contaminate averages when points become active later. Apply reset/normalization for all points; only add field for active points.
       time_to_reset = (mod(nstep,accum(nf)%period) == 1 .or. accum(nf)%period == 1) .and. (nstep /= 0)
       do j = 1,numlev
          do k = beg,end
             if (accum(nf)%active(k)) then
                if (time_to_reset) then
                   accum(nf)%val(k,j) = 0._r8
                   accum(nf)%nsteps(k,j) = 0
                end if

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +461 to +478
time_to_reset = (mod(nstep,accum(nf)%period) == 1 .or. accum(nf)%period == 1) .and. (nstep /= 0)
do k = beg,end
if (accum(nf)%active(k)) then
if (time_to_reset) then
accum(nf)%val(k,1) = 0._r8
accum(nf)%nsteps(k,1) = 0
end if
accum(nf)%val(k,1) = accum(nf)%val(k,1) + field(k)
accum(nf)%nsteps(k,1) = accum(nf)%nsteps(k,1) + 1
if (mod(nstep,accum(nf)%period) == 0) then
if (accum(nf)%nsteps(k,1) > 0) then
accum(nf)%val(k,1) = accum(nf)%val(k,1) / real(accum(nf)%nsteps(k,1),r8)
else
accum(nf)%val(k,1) = accum(nf)%initval
end if
end if
end if
end do
Comment on lines 555 to 565
if (h2osfcflag==1) then
! calculate runoff from h2osfc -------------------------------------
if (use_modified_infil) then
!if (use_modified_infil) then
if (frac_h2osfc_act(c) <= pc .and. frac_h2osfc(c) <= pc) then
frac_infclust=0.0_r8
else
if (frac_h2osfc(c) <= pc) then
if (frac_h2osfc_act(c) <= pc) then
frac_infclust=(frac_h2osfc_act(c)-pc)**mu
else
frac_infclust=(frac_h2osfc(c)-pc)**mu
frac_infclust=(frac_h2osfc_act(c)-pc)**mu
endif

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with Copilot's review: Why is the second frac_infclust=(frac_h2osfc(c)-pc)**mu being changed to frac_infclust=(frac_h2osfc_act(c)-pc)**mu?

! Port of CLM fractional-snow energy fix: when subgrid fluxes are on,
! allow fractional frac_sno_eff for all non-urban, non-lake columns
! (including glacier and wetland), matching soil/crop treatment.
if (subgridflag == 1 .and. .not. urbpoi(l) .and. ltype(l) /= istdlak) then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the default value of subgridflag 1 or 0?

if(h2osfc(c) >= h2osfc_thresh(c) .and. h2osfcflag/=0) then
! spatially variable k_wet
k_wet=1.0_r8 * sin((rpi/180._r8) * col_pp%topo_slope(c))
k_wet=1.0e-4_r8 * sin((rpi/180._r8) * max(col_pp%topo_slope(c), 1.0e-3_r8))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the logic of reducing k_wet by four-orders of magnitude? Was this a bug identified by CLM that we are fixing here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bug from the misuse of unit

@czender czender left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes are beyond my level of ELM expertise. I couldn't find anything that looked problematic that had not already been noted.

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

Labels

bug fix PR ELM land model non-BFB PR makes roundoff changes to answers.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants