diff --git a/doc/.ChangeLog_template b/doc/.ChangeLog_template index 764bac023c..2603759310 100644 --- a/doc/.ChangeLog_template +++ b/doc/.ChangeLog_template @@ -147,8 +147,10 @@ Changes answers relative to baseline: changes to state fields usually grow to greater than roundoff as the simulation progresses. If this tag changes climate list the run(s) done to evaluate the new - climate (from https://github.com/NCAR/LMWG_dev) - - issue number(s): + climate. Preferably in https://github.com/NCAR/LMWG_dev (or give details below) + - LMWG_dev issue number(s): + + - details (casename, machine, user, link to plots etc.) [if not in LMWG_dev] Other details ------------- diff --git a/doc/ChangeLog b/doc/ChangeLog index d25e2bb56f..a699a80b9e 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,4 +1,94 @@ =============================================================== +Tag name: ctsm5.4.014 +Originator(s): mvdebolskiy +Date: Thu Jan 29 03:28:03 PM MST 2026 +One-line Summary: Fix for xm2 and revise logic for excess ice melt + +Purpose and description of changes +---------------------------------- + +A bug fix in excess ice melt calculation. Previously, we have set +incorrectly xm2=xm-h2osoi_ice after h2osoi_ice has already been updated. +This resulted in extra heat being available to spend on melting excess_ice +since when all h2osoi_ice has been melted (xm2=xm). This fixed now, in +addition Phasechange_beta subroutine in SoilTemperatureMod has been +renamed to Phasechange by swensosc's suggestion. + +The changes are generally small and only to a few points, so NOT marking it as a +significant change in answers. + +Significant changes to scientifically-supported configurations +-------------------------------------------------------------- + +Does this tag change answers significantly for any of the following physics configurations? +(Details of any changes will be given in the "Answer changes" section below.) + + [Put an [X] in the box for any configuration with significant answer changes.] + +[ ] clm6_0 + +[ ] clm5_0 + +[ ] ctsm5_0-nwp + +[ ] clm4_5 + + +Bugs fixed +---------- + +Fixes #3678 -- Logic error in excess ice melt calculation + +Notes of particular relevance for users +--------------------------------------- + +Caveats for users (e.g., need to interpolate initial conditions): + 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. + https://github.com/ESCOMP/CTSM/pull/3718#issuecomment-3810263334 + +Notes of particular relevance for developers: +--------------------------------------------- + +Testing summary: +---------------- + + [PASS means all tests PASS; OK means tests PASS other than expected fails.] + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- OK + izumi ------- OK + +If the tag used for baseline comparisons was NOT the previous tag, note that here: + + +Answer changes +-------------- + +Changes answers relative to baseline: Yes! when use_excess_ice is TRUE + + Summarize any changes to answers, i.e., + - any configuration with use_excess_ice=.true. + - larger than roundoff changes in the soil thermal and + moisture state in gridcells where excess ice is present + in the soil at the start of the simulations. Most of the + most of the gridcells will have little differences (1e-6), + however, the difference will grow for longer (>10y) runs. + + If this tag changes climate list the run(s) done to evaluate the new + climate (from https://github.com/NCAR/LMWG_dev) + - issue number(s): + - NCAR/LMWG_dev#140 + +Other details +------------- + +Pull Requests that document the changes (include PR ids): + + https://github.com/ESCOMP/CTSM/pull/3718 + +=============================================================== +=============================================================== Tag name: ctsm5.4.013 Originator(s): erik (Erik Kluzek,UCAR/TSS,303-497-1326) Date: Wed Jan 28 12:24:02 AM MST 2026 diff --git a/doc/ChangeSum b/doc/ChangeSum index 329a737237..4a66ef9b64 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,5 +1,6 @@ Tag Who Date Summary ============================================================================================================================ + ctsm5.4.014 mvdebols 01/29/2026 Fix for xm2 and revise logic for excess ice melt ctsm5.4.013 erik 01/28/2026 Patch the Greenland snow hole with initial conditions for ne30 and tweak the C14 isotope latitudes ctsm5.4.012 slevis 01/26/2026 Fix C-balance error for partly emerged crops ctsm5.4.011 slevis 01/22/2026 Merge b4b-dev to master diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index 2819894868..367da626e6 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -78,7 +78,7 @@ module SoilTemperatureMod ! !PRIVATE MEMBER FUNCTIONS: private :: SoilThermProp ! Set therm conduct. and heat cap of snow/soil layers private :: PhaseChangeH2osfc ! When surface water freezes move ice to bottom snow layer - private :: PhaseChange_beta ! Calculation of the phase change within snow and soil layers + private :: PhaseChange ! Calculation of the phase change within snow and soil layers private :: BuildingHAC ! Building Heating and Cooling for simpler method (introduced in CLM4.5) 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 dhsdT(bounds%begc:bounds%endc), & waterstatebulk_inst, waterdiagnosticbulk_inst, waterfluxbulk_inst, temperature_inst,energyflux_inst) - call Phasechange_beta (bounds, num_nolakec, filter_nolakec, & + call Phasechange (bounds, num_nolakec, filter_nolakec, & dhsdT(bounds%begc:bounds%endc), & soilstate_inst, waterstatebulk_inst, waterdiagnosticbulk_inst, waterfluxbulk_inst, energyflux_inst, temperature_inst) @@ -1130,7 +1130,7 @@ subroutine PhaseChangeH2osfc (bounds, num_nolakec, filter_nolakec, & end subroutine PhaseChangeH2osfc !----------------------------------------------------------------------- - subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & + subroutine Phasechange (bounds, num_nolakec, filter_nolakec, dhsdT, & soilstate_inst, waterstatebulk_inst, waterdiagnosticbulk_inst, waterfluxbulk_inst, energyflux_inst, temperature_inst) ! ! !DESCRIPTION: @@ -1186,7 +1186,7 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & !----------------------------------------------------------------------- - call t_startf( 'PhaseChangebeta' ) + call t_startf( 'PhaseChange' ) ! Enforce expected array sizes SHR_ASSERT_ALL_FL((ubound(dhsdT) == (/bounds%endc/)), sourcefile, __LINE__) @@ -1279,7 +1279,6 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & ! If ice exists above melt point, melt some to liquid. if (h2osoi_ice(c,j) > 0._r8 .and. t_soisno(c,j) > tfrz) then imelt(c,j) = 1 - ! tinc(c,j) = t_soisno(c,j) - tfrz tinc(c,j) = tfrz - t_soisno(c,j) t_soisno(c,j) = tfrz endif @@ -1288,7 +1287,6 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & ! If liquid exists below melt point, freeze some to ice. if (h2osoi_liq(c,j) > 0._r8 .AND. t_soisno(c,j) < tfrz) then imelt(c,j) = 2 - ! tinc(c,j) = t_soisno(c,j) - tfrz tinc(c,j) = tfrz - t_soisno(c,j) t_soisno(c,j) = tfrz endif @@ -1310,7 +1308,6 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & if (h2osoi_ice(c,j) > 0. .AND. t_soisno(c,j) > tfrz) then imelt(c,j) = 1 - ! tinc(c,j) = t_soisno(c,j) - tfrz tinc(c,j) = tfrz - t_soisno(c,j) t_soisno(c,j) = tfrz endif @@ -1334,7 +1331,6 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & if (h2osoi_liq(c,j) > supercool(c,j) .AND. t_soisno(c,j) < tfrz) then imelt(c,j) = 2 - ! tinc(c,j) = t_soisno(c,j) - tfrz tinc(c,j) = tfrz - t_soisno(c,j) t_soisno(c,j) = tfrz endif @@ -1343,7 +1339,6 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & if (h2osno_no_layers(c) > 0._r8 .AND. j == 1) then if (t_soisno(c,j) > tfrz) then imelt(c,j) = 1 - ! tincc,j) = t_soisno(c,j) - tfrz tinc(c,j) = tfrz - t_soisno(c,j) t_soisno(c,j) = tfrz endif @@ -1438,14 +1433,18 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & heatr = 0._r8 if (xm(c,j) > 0._r8) then !if there is excess heat to melt the ice h2osoi_ice(c,j) = max(0._r8, wice0(c,j)-xm(c,j)) - heatr = hm(c,j) - hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime - xm2(c,j) = xm(c,j) - h2osoi_ice(c,j) !excess ice melting - if (h2osoi_ice(c,j) == 0._r8) then ! this might be redundant - if (excess_ice(c,j) >= 0._r8 .and. xm2(c,j)>0._r8 .and. j>=2) then ! if there is excess ice to melt - excess_ice(c,j) = max(0._r8,wexice0(c,j) - xm2(c,j)) - heatr = hm(c,j) - hfus * (wexice0(c,j)-excess_ice(c,j)+wice0(c,j)-h2osoi_ice(c,j)) / dtime + ! If xm > wice0, then all soil ice melts, + ! and the remaining heat (xm2) is used to melt excess ice + xm2(c,j) = xm(c,j) - wice0(c,j) + if (j>=1) then ! soil + if (excess_ice(c,j) >= 0._r8 .and. xm2(c,j)>0._r8) then ! if there is excess ice to melt + excess_ice(c,j) = max(0._r8,wexice0(c,j) - xm2(c,j)) endif - endif !end of excess ice block + heatr = hm(c,j) - hfus * (wexice0(c,j)-excess_ice(c,j)+ & + wice0(c,j)-h2osoi_ice(c,j)) / dtime + else !snow + heatr = hm(c,j) - hfus * (wice0(c,j)-h2osoi_ice(c,j)) / dtime + endif else if (xm(c,j) < 0._r8) then if (j <= 0) then 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, & end if end do - call t_stopf( 'PhaseChangebeta' ) + call t_stopf( 'PhaseChange' ) end associate - end subroutine Phasechange_beta + end subroutine Phasechange !----------------------------------------------------------------------- subroutine ComputeGroundHeatFluxAndDeriv(bounds, &