Skip to content

Commit 7871ea9

Browse files
authored
Merge pull request #3718 from mvdebolskiy/pr-fix-xm2-excess-ice
ctsm5.4.014: Fix for xm2 and revise logic for excess ice melt
2 parents 9f5c360 + 83c7b13 commit 7871ea9

4 files changed

Lines changed: 112 additions & 20 deletions

File tree

doc/.ChangeLog_template

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,10 @@ Changes answers relative to baseline:
147147
changes to state fields usually grow to greater than roundoff as the simulation progresses.
148148

149149
If this tag changes climate list the run(s) done to evaluate the new
150-
climate (from https://github.com/NCAR/LMWG_dev)
151-
- issue number(s):
150+
climate. Preferably in https://github.com/NCAR/LMWG_dev (or give details below)
151+
- LMWG_dev issue number(s):
152+
153+
- details (casename, machine, user, link to plots etc.) [if not in LMWG_dev]
152154

153155
Other details
154156
-------------

doc/ChangeLog

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,94 @@
11
===============================================================
2+
Tag name: ctsm5.4.014
3+
Originator(s): mvdebolskiy
4+
Date: Thu Jan 29 03:28:03 PM MST 2026
5+
One-line Summary: Fix for xm2 and revise logic for excess ice melt
6+
7+
Purpose and description of changes
8+
----------------------------------
9+
10+
A bug fix in excess ice melt calculation. Previously, we have set
11+
incorrectly xm2=xm-h2osoi_ice after h2osoi_ice has already been updated.
12+
This resulted in extra heat being available to spend on melting excess_ice
13+
since when all h2osoi_ice has been melted (xm2=xm). This fixed now, in
14+
addition Phasechange_beta subroutine in SoilTemperatureMod has been
15+
renamed to Phasechange by swensosc's suggestion.
16+
17+
The changes are generally small and only to a few points, so NOT marking it as a
18+
significant change in answers.
19+
20+
Significant changes to scientifically-supported configurations
21+
--------------------------------------------------------------
22+
23+
Does this tag change answers significantly for any of the following physics configurations?
24+
(Details of any changes will be given in the "Answer changes" section below.)
25+
26+
[Put an [X] in the box for any configuration with significant answer changes.]
27+
28+
[ ] clm6_0
29+
30+
[ ] clm5_0
31+
32+
[ ] ctsm5_0-nwp
33+
34+
[ ] clm4_5
35+
36+
37+
Bugs fixed
38+
----------
39+
40+
Fixes #3678 -- Logic error in excess ice melt calculation
41+
42+
Notes of particular relevance for users
43+
---------------------------------------
44+
45+
Caveats for users (e.g., need to interpolate initial conditions):
46+
The changes in short simulations are negligible, but a few points can show larger differences if run long enough. The following lists the min and max differences for a 40 year simulation.
47+
https://github.com/ESCOMP/CTSM/pull/3718#issuecomment-3810263334
48+
49+
Notes of particular relevance for developers:
50+
---------------------------------------------
51+
52+
Testing summary:
53+
----------------
54+
55+
[PASS means all tests PASS; OK means tests PASS other than expected fails.]
56+
57+
regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing):
58+
59+
derecho ----- OK
60+
izumi ------- OK
61+
62+
If the tag used for baseline comparisons was NOT the previous tag, note that here:
63+
64+
65+
Answer changes
66+
--------------
67+
68+
Changes answers relative to baseline: Yes! when use_excess_ice is TRUE
69+
70+
Summarize any changes to answers, i.e.,
71+
- any configuration with use_excess_ice=.true.
72+
- larger than roundoff changes in the soil thermal and
73+
moisture state in gridcells where excess ice is present
74+
in the soil at the start of the simulations. Most of the
75+
most of the gridcells will have little differences (1e-6),
76+
however, the difference will grow for longer (>10y) runs.
77+
78+
If this tag changes climate list the run(s) done to evaluate the new
79+
climate (from https://github.com/NCAR/LMWG_dev)
80+
- issue number(s):
81+
- NCAR/LMWG_dev#140
82+
83+
Other details
84+
-------------
85+
86+
Pull Requests that document the changes (include PR ids):
87+
88+
https://github.com/ESCOMP/CTSM/pull/3718
89+
90+
===============================================================
91+
===============================================================
292
Tag name: ctsm5.4.013
393
Originator(s): erik (Erik Kluzek,UCAR/TSS,303-497-1326)
494
Date: Wed Jan 28 12:24:02 AM MST 2026

doc/ChangeSum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
Tag Who Date Summary
22
============================================================================================================================
3+
ctsm5.4.014 mvdebols 01/29/2026 Fix for xm2 and revise logic for excess ice melt
34
ctsm5.4.013 erik 01/28/2026 Patch the Greenland snow hole with initial conditions for ne30 and tweak the C14 isotope latitudes
45
ctsm5.4.012 slevis 01/26/2026 Fix C-balance error for partly emerged crops
56
ctsm5.4.011 slevis 01/22/2026 Merge b4b-dev to master

src/biogeophys/SoilTemperatureMod.F90

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ module SoilTemperatureMod
7878
! !PRIVATE MEMBER FUNCTIONS:
7979
private :: SoilThermProp ! Set therm conduct. and heat cap of snow/soil layers
8080
private :: PhaseChangeH2osfc ! When surface water freezes move ice to bottom snow layer
81-
private :: PhaseChange_beta ! Calculation of the phase change within snow and soil layers
81+
private :: PhaseChange ! Calculation of the phase change within snow and soil layers
8282
private :: BuildingHAC ! Building Heating and Cooling for simpler method (introduced in CLM4.5)
8383

8484
real(r8), private, parameter :: thin_sfclayer = 1.0e-6_r8 ! Threshold for thin surface layer
@@ -517,7 +517,7 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter
517517
dhsdT(bounds%begc:bounds%endc), &
518518
waterstatebulk_inst, waterdiagnosticbulk_inst, waterfluxbulk_inst, temperature_inst,energyflux_inst)
519519

520-
call Phasechange_beta (bounds, num_nolakec, filter_nolakec, &
520+
call Phasechange (bounds, num_nolakec, filter_nolakec, &
521521
dhsdT(bounds%begc:bounds%endc), &
522522
soilstate_inst, waterstatebulk_inst, waterdiagnosticbulk_inst, waterfluxbulk_inst, energyflux_inst, temperature_inst)
523523

@@ -1130,7 +1130,7 @@ subroutine PhaseChangeH2osfc (bounds, num_nolakec, filter_nolakec, &
11301130
end subroutine PhaseChangeH2osfc
11311131

11321132
!-----------------------------------------------------------------------
1133-
subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, &
1133+
subroutine Phasechange (bounds, num_nolakec, filter_nolakec, dhsdT, &
11341134
soilstate_inst, waterstatebulk_inst, waterdiagnosticbulk_inst, waterfluxbulk_inst, energyflux_inst, temperature_inst)
11351135
!
11361136
! !DESCRIPTION:
@@ -1186,7 +1186,7 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, &
11861186

11871187
!-----------------------------------------------------------------------
11881188

1189-
call t_startf( 'PhaseChangebeta' )
1189+
call t_startf( 'PhaseChange' )
11901190

11911191
! Enforce expected array sizes
11921192
SHR_ASSERT_ALL_FL((ubound(dhsdT) == (/bounds%endc/)), sourcefile, __LINE__)
@@ -1279,7 +1279,6 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, &
12791279
! If ice exists above melt point, melt some to liquid.
12801280
if (h2osoi_ice(c,j) > 0._r8 .and. t_soisno(c,j) > tfrz) then
12811281
imelt(c,j) = 1
1282-
! tinc(c,j) = t_soisno(c,j) - tfrz
12831282
tinc(c,j) = tfrz - t_soisno(c,j)
12841283
t_soisno(c,j) = tfrz
12851284
endif
@@ -1288,7 +1287,6 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, &
12881287
! If liquid exists below melt point, freeze some to ice.
12891288
if (h2osoi_liq(c,j) > 0._r8 .AND. t_soisno(c,j) < tfrz) then
12901289
imelt(c,j) = 2
1291-
! tinc(c,j) = t_soisno(c,j) - tfrz
12921290
tinc(c,j) = tfrz - t_soisno(c,j)
12931291
t_soisno(c,j) = tfrz
12941292
endif
@@ -1310,7 +1308,6 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, &
13101308

13111309
if (h2osoi_ice(c,j) > 0. .AND. t_soisno(c,j) > tfrz) then
13121310
imelt(c,j) = 1
1313-
! tinc(c,j) = t_soisno(c,j) - tfrz
13141311
tinc(c,j) = tfrz - t_soisno(c,j)
13151312
t_soisno(c,j) = tfrz
13161313
endif
@@ -1334,7 +1331,6 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, &
13341331

13351332
if (h2osoi_liq(c,j) > supercool(c,j) .AND. t_soisno(c,j) < tfrz) then
13361333
imelt(c,j) = 2
1337-
! tinc(c,j) = t_soisno(c,j) - tfrz
13381334
tinc(c,j) = tfrz - t_soisno(c,j)
13391335
t_soisno(c,j) = tfrz
13401336
endif
@@ -1343,7 +1339,6 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, &
13431339
if (h2osno_no_layers(c) > 0._r8 .AND. j == 1) then
13441340
if (t_soisno(c,j) > tfrz) then
13451341
imelt(c,j) = 1
1346-
! tincc,j) = t_soisno(c,j) - tfrz
13471342
tinc(c,j) = tfrz - t_soisno(c,j)
13481343
t_soisno(c,j) = tfrz
13491344
endif
@@ -1438,14 +1433,18 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, &
14381433
heatr = 0._r8
14391434
if (xm(c,j) > 0._r8) then !if there is excess heat to melt the ice
14401435
h2osoi_ice(c,j) = max(0._r8, wice0(c,j)-xm(c,j))
1441-
heatr = hm(c,j) - hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime
1442-
xm2(c,j) = xm(c,j) - h2osoi_ice(c,j) !excess ice melting
1443-
if (h2osoi_ice(c,j) == 0._r8) then ! this might be redundant
1444-
if (excess_ice(c,j) >= 0._r8 .and. xm2(c,j)>0._r8 .and. j>=2) then ! if there is excess ice to melt
1445-
excess_ice(c,j) = max(0._r8,wexice0(c,j) - xm2(c,j))
1446-
heatr = hm(c,j) - hfus * (wexice0(c,j)-excess_ice(c,j)+wice0(c,j)-h2osoi_ice(c,j)) / dtime
1436+
! If xm > wice0, then all soil ice melts,
1437+
! and the remaining heat (xm2) is used to melt excess ice
1438+
xm2(c,j) = xm(c,j) - wice0(c,j)
1439+
if (j>=1) then ! soil
1440+
if (excess_ice(c,j) >= 0._r8 .and. xm2(c,j)>0._r8) then ! if there is excess ice to melt
1441+
excess_ice(c,j) = max(0._r8,wexice0(c,j) - xm2(c,j))
14471442
endif
1448-
endif !end of excess ice block
1443+
heatr = hm(c,j) - hfus * (wexice0(c,j)-excess_ice(c,j)+ &
1444+
wice0(c,j)-h2osoi_ice(c,j)) / dtime
1445+
else !snow
1446+
heatr = hm(c,j) - hfus * (wice0(c,j)-h2osoi_ice(c,j)) / dtime
1447+
endif
14491448
else if (xm(c,j) < 0._r8) then
14501449
if (j <= 0) then
14511450
h2osoi_ice(c,j) = min(wmass0(c,j), wice0(c,j)-xm(c,j)) ! snow
@@ -1535,10 +1534,10 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, &
15351534
end if
15361535
end do
15371536

1538-
call t_stopf( 'PhaseChangebeta' )
1537+
call t_stopf( 'PhaseChange' )
15391538
end associate
15401539

1541-
end subroutine Phasechange_beta
1540+
end subroutine Phasechange
15421541

15431542
!-----------------------------------------------------------------------
15441543
subroutine ComputeGroundHeatFluxAndDeriv(bounds, &

0 commit comments

Comments
 (0)