Skip to content

Commit 98054f5

Browse files
authored
Snow thermal conductivity changes: Sturm1997 and Jordan1991 (#101)
This PR implements @AdrienDams snow thermal conductivity fixes in CLM5. > Damseaux, A., Matthes, H., Dutch, V. R., Wake, L., and Rutter, N.: **Impact of snow thermal conductivity schemes on pan-Arctic permafrost dynamics in the Community Land Model version 5.0**, The Cryosphere, 19, 1539–1558, https://doi.org/10.5194/tc-19-1539-2025, 2025. ## New namelist parameters in `lnd_in` These fixes allow changing the snow thermal conductivity per land unit type. New namelist switches must be added in the `lnd_in` with defaults set to [CLM6 defaults](https://github.com/ESCOMP/CTSM/blob/9f5c3602f9efea2ade07a8f5dcf9eb2b0425d540/bld/namelist_files/namelist_defaults_ctsm.xml#L576-L583). ```fortran &clm_inparm snow_thermal_cond_method = 'Sturm1997' snow_thermal_cond_glc_method = 'Sturm1997' snow_thermal_cond_lake_method = 'Jordan1991' ``` For reference the namelist parameters reproducing the **old defaults** ```fortran &clm_inparm snow_thermal_cond_method = 'Jordan1991' snow_thermal_cond_glc_method = 'Jordan1991' snow_thermal_cond_lake_method = 'Jordan1991' ``` ## Code changes Changes were based from these upstream PRs: - ESCOMP/CTSM#2148 - ESCOMP/CTSM#3072
1 parent e7786dd commit 98054f5

5 files changed

Lines changed: 95 additions & 8 deletions

File tree

src/clm5/biogeophys/LakeFluxesMod.F90

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ module LakeFluxesMod
88
! !USES
99
use shr_kind_mod , only : r8 => shr_kind_r8
1010
use shr_log_mod , only : errMsg => shr_log_errMsg
11+
use abortutils , only : endrun
12+
use clm_varctl , only : iulog
1113
use decompMod , only : bounds_type
1214
use atm2lndType , only : atm2lnd_type
1315
use EnergyFluxType , only : energyflux_type
@@ -29,6 +31,9 @@ module LakeFluxesMod
2931
!
3032
! !PUBLIC MEMBER FUNCTIONS:
3133
public :: LakeFluxes
34+
35+
character(len=*), parameter, private :: sourcefile = &
36+
__FILE__
3237
!-----------------------------------------------------------------------
3338

3439
contains
@@ -50,6 +55,7 @@ subroutine LakeFluxes(bounds, num_lakec, filter_lakec, num_lakep, filter_lakep,
5055
use clm_varcon , only : hvap, hsub, hfus, cpair, cpliq, tkwat, tkice, tkair
5156
use clm_varcon , only : sb, vkc, grav, denh2o, tfrz, spval, zsno
5257
use clm_varctl , only : use_lch4
58+
use clm_varctl , only : snow_thermal_cond_lake_method
5359
use LakeCon , only : betavis, z0frzlake, tdmax, emg_lake
5460
use LakeCon , only : lake_use_old_fcrit_minz0
5561
use LakeCon , only : minz0lake, cur0, cus, curm, fcrit
@@ -403,7 +409,20 @@ subroutine LakeFluxes(bounds, num_lakec, filter_lakec, num_lakep, filter_lakep,
403409
else
404410
!Need to calculate thermal conductivity of the top snow layer
405411
bw = (h2osoi_ice(c,jtop(c))+h2osoi_liq(c,jtop(c)))/dz(c,jtop(c))
406-
tksur(c) = tkair + (7.75e-5_r8 *bw + 1.105e-6_r8*bw*bw)*(tkice-tkair)
412+
select case (snow_thermal_cond_lake_method)
413+
case ('Jordan1991')
414+
tksur(c) = tkair + (7.75e-5_r8 *bw + 1.105e-6_r8*bw*bw)*(tkice-tkair)
415+
case ('Sturm1997')
416+
if (bw <= 156) then
417+
tksur(c) = 0.023 + 0.234*(bw/1000)
418+
else
419+
tksur(c) = 0.138 - 1.01*(bw/1000) +(3.233*((bw/1000)*(bw/1000)))
420+
end if
421+
case default
422+
write(iulog,*) ' ERROR: unknown snow_thermal_cond_lake_method value: ', snow_thermal_cond_lake_method
423+
call endrun(msg=errMsg(sourcefile, __LINE__))
424+
end select
425+
407426
tsur(c) = t_soisno(c,jtop(c))
408427
end if
409428

src/clm5/biogeophys/LakeTemperatureMod.F90

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ module LakeTemperatureMod
99
!
1010
! !USES
1111
use shr_kind_mod , only : r8 => shr_kind_r8
12+
use abortutils , only : endrun
1213
use shr_log_mod , only : errMsg => shr_log_errMsg
1314
use decompMod , only : bounds_type
1415
use ch4Mod , only : ch4_type
@@ -19,6 +20,7 @@ module LakeTemperatureMod
1920
use TemperatureType , only : temperature_type
2021
use WaterfluxType , only : waterflux_type
2122
use WaterstateType , only : waterstate_type
23+
use clm_varctl , only : iulog
2224
use ColumnType , only : col
2325
use PatchType , only : patch
2426
!
@@ -117,7 +119,7 @@ subroutine LakeTemperature(bounds, num_lakec, filter_lakec, num_lakep, filter_la
117119
use clm_time_manager , only : get_step_size
118120
use clm_varcon , only : hfus, cpliq, cpice, tkwat, tkice, denice
119121
use clm_varcon , only : vkc, grav, denh2o, tfrz, cnfac
120-
use clm_varctl , only : iulog, use_lch4
122+
use clm_varctl , only : use_lch4
121123
!
122124
! !ARGUMENTS:
123125
type(bounds_type) , intent(in) :: bounds
@@ -1074,6 +1076,7 @@ subroutine SoilThermProp_Lake (bounds, num_lakec, filter_lakec, tk, cv, tktopso
10741076
use clm_varcon , only : denh2o, denice, tfrz, tkwat, tkice, tkair
10751077
use clm_varcon , only : cpice, cpliq, thk_bedrock, csol_bedrock
10761078
use clm_varpar , only : nlevsno, nlevsoi, nlevgrnd
1079+
use clm_varctl , only : snow_thermal_cond_lake_method
10771080
!
10781081
! !ARGUMENTS:
10791082
type(bounds_type) , intent(in) :: bounds
@@ -1170,7 +1173,20 @@ subroutine SoilThermProp_Lake (bounds, num_lakec, filter_lakec, tk, cv, tktopso
11701173
! Only examine levels from snl(c)+1 -> 0 where snl(c) < 1
11711174
if (snl(c)+1 < 1 .AND. (j >= snl(c)+1) .AND. (j <= 0)) then
11721175
bw = (h2osoi_ice(c,j)+h2osoi_liq(c,j))/dz(c,j)
1173-
thk(c,j) = tkair + (7.75e-5_r8 *bw + 1.105e-6_r8*bw*bw)*(tkice-tkair)
1176+
select case (snow_thermal_cond_lake_method)
1177+
case ('Jordan1991')
1178+
thk(c,j) = tkair + (7.75e-5_r8 *bw + 1.105e-6_r8*bw*bw)*(tkice-tkair)
1179+
case ('Sturm1997')
1180+
if (bw <= 156) then
1181+
thk(c,j) = 0.023 + 0.234*(bw/1000)
1182+
else
1183+
thk(c,j) = 0.138 - 1.01*(bw/1000) +(3.233*((bw/1000)*(bw/1000)))
1184+
end if
1185+
case default
1186+
write(iulog,*) ' ERROR: unknown snow_thermal_cond_lake_method value: ', snow_thermal_cond_lake_method
1187+
call endrun(msg=errMsg(sourcefile, __LINE__))
1188+
end select
1189+
11741190
end if
11751191

11761192
end do

src/clm5/biogeophys/SoilTemperatureMod.F90

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ module SoilTemperatureMod
4747
! o The thermal conductivity of soil is computed from
4848
! the algorithm of Johansen (as reported by Farouki 1981), and the
4949
! conductivity of snow is from the formulation used in
50-
! SNTHERM (Jordan 1991).
50+
! Sturm (1997) or Jordan (1991) p. 18 depending on namelist option.
5151
! o Boundary conditions:
5252
! F = Rnet - Hg - LEg (top), F= 0 (base of the soil column).
5353
! o Soil / snow temperature is predicted from heat conduction
@@ -598,7 +598,7 @@ subroutine SoilThermProp (bounds, num_nolakec, filter_nolakec, &
598598
use clm_varcon , only : denh2o, denice, tfrz, tkwat, tkice, tkair, cpice, cpliq, thk_bedrock, csol_bedrock
599599
use landunit_varcon , only : istice_mec, istwet
600600
use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall, icol_road_perv, icol_road_imperv
601-
use clm_varctl , only : iulog
601+
use clm_varctl , only : iulog, snow_thermal_cond_method, snow_thermal_cond_glc_method
602602
!
603603
! !ARGUMENTS:
604604
type(bounds_type) , intent(in) :: bounds
@@ -712,12 +712,50 @@ subroutine SoilThermProp (bounds, num_nolakec, filter_nolakec, &
712712
endif
713713
endif
714714

715-
! Thermal conductivity of snow, which from Jordan (1991) pp. 18
715+
! Thermal conductivity of snow
716716
! Only examine levels from snl(c)+1 -> 0 where snl(c) < 1
717717
if (snl(c)+1 < 1 .AND. (j >= snl(c)+1) .AND. (j <= 0)) then
718718
bw(c,j) = (h2osoi_ice(c,j)+h2osoi_liq(c,j))/(frac_sno(c)*dz(c,j))
719-
thk(c,j) = tkair + (7.75e-5_r8 *bw(c,j) + 1.105e-6_r8*bw(c,j)*bw(c,j))*(tkice-tkair)
720-
end if
719+
l = col%landunit(c)
720+
721+
! Select method over glacier land unit
722+
if (lun%itype(l) == istice_mec) then
723+
select case (snow_thermal_cond_glc_method)
724+
! TODO, this code duplication isn't ideal and should likely be in it's own subroutine
725+
case('Jordan1991')
726+
thk(c,j) = tkair + (7.75e-5_r8 *bw(c,j) + 1.105e-6_r8*bw(c,j)*bw(c,j))*(tkice-tkair)
727+
case ('Sturm1997')
728+
if (bw(c,j) <= 156) then !LMW or 0.156 ?
729+
thk(c,j) = 0.023 + 0.234*(bw(c,j)/1000) !LMW - units changed by VRD
730+
else
731+
thk(c,j) = 0.138 - 1.01*(bw(c,j)/1000) +(3.233*((bw(c,j)/1000)*(bw(c,j)/1000)))
732+
end if
733+
case default
734+
write(iulog,*) ' ERROR: unknown snow_thermal_cond_glc_method value: ', snow_thermal_cond_glc_method
735+
call endrun(msg=errMsg(sourcefile, __LINE__))
736+
end select
737+
738+
else
739+
select case (snow_thermal_cond_method)
740+
case ('Jordan1991')
741+
thk(c,j) = tkair + (7.75e-5_r8 *bw(c,j) + 1.105e-6_r8*bw(c,j)*bw(c,j))*(tkice-tkair)
742+
case ('Sturm1997')
743+
! Implemented by Vicky Dutch (VRD), Nick Rutter, and
744+
! Leanne Wake (LMW)
745+
! https://tc.copernicus.org/articles/16/4201/2022/
746+
! See also https://tc.copernicus.org/articles/19/1539/2025/
747+
! Code provided by Adrien Dams to Will Wieder
748+
if (bw(c,j) <= 156) then !LMW or 0.156 ?
749+
thk(c,j) = 0.023 + 0.234*(bw(c,j)/1000) !LMW - units changed by VRD
750+
else
751+
thk(c,j) = 0.138 - 1.01*(bw(c,j)/1000) +(3.233*((bw(c,j)/1000)*(bw(c,j)/1000)))
752+
end if
753+
case default
754+
write(iulog,*) ' ERROR: unknown snow_thermal_cond_method value: ', snow_thermal_cond_method
755+
call endrun(msg=errMsg(sourcefile, __LINE__))
756+
end select
757+
end if ! close land unit if statement
758+
end if
721759

722760
end do
723761
end do

src/clm5/main/clm_varctl.F90

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,11 @@ module clm_varctl
176176
! use subgrid fluxes
177177
integer, public :: subgridflag = 1
178178

179+
! which snow thermal conductivity parameterization to use
180+
character(len=25), public :: snow_thermal_cond_method
181+
character(len=25), public :: snow_thermal_cond_glc_method
182+
character(len=25), public :: snow_thermal_cond_lake_method
183+
179184
! true => write global average diagnostics to std out
180185
logical, public :: wrtdia = .false.
181186

src/clm5/main/controlMod.F90

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,12 @@ subroutine control_init( )
204204
albice, soil_layerstruct, subgridflag, &
205205
irrigate, run_zero_weight_urban, all_active
206206

207+
! Snow thermal conductivity
208+
namelist /clm_inparm/ &
209+
snow_thermal_cond_method, &
210+
snow_thermal_cond_glc_method, &
211+
snow_thermal_cond_lake_method
212+
207213
! vertical soil mixing variables
208214
namelist /clm_inparm/ &
209215
som_adv_flux, max_depth_cryoturb
@@ -718,6 +724,9 @@ subroutine control_spmd()
718724
call mpi_bcast (co2_ppmv, 1, MPI_REAL8,0, mpicom, ier)
719725
call mpi_bcast (albice, 2, MPI_REAL8,0, mpicom, ier)
720726
call mpi_bcast (soil_layerstruct,len(soil_layerstruct), MPI_CHARACTER, 0, mpicom, ier)
727+
call mpi_bcast (snow_thermal_cond_method, len(snow_thermal_cond_method), MPI_CHARACTER, 0, mpicom, ier)
728+
call mpi_bcast (snow_thermal_cond_glc_method, len(snow_thermal_cond_glc_method), MPI_CHARACTER, 0, mpicom, ier)
729+
call mpi_bcast (snow_thermal_cond_lake_method, len(snow_thermal_cond_lake_method), MPI_CHARACTER, 0, mpicom, ier)
721730

722731
! snow pack variables
723732
call mpi_bcast (nlevsno, 1, MPI_INTEGER, 0, mpicom, ier)

0 commit comments

Comments
 (0)