From ab94ab484bc15405788ffe6c1e061778eeb3d337 Mon Sep 17 00:00:00 2001 From: AdrienDams Date: Fri, 8 Sep 2023 10:44:52 +0200 Subject: [PATCH 1/5] Replace thermal conductivity of snow of Jordan with Sturm --- src/biogeophys/SoilTemperatureMod.F90 | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index b868224a60..caeedd1603 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -47,7 +47,7 @@ module SoilTemperatureMod ! o The thermal conductivity of soil is computed from ! the algorithm of Johansen (as reported by Farouki 1981), and the ! conductivity of snow is from the formulation used in - ! SNTHERM (Jordan 1991). + ! Sturm (1997). ! o Boundary conditions: ! F = Rnet - Hg - LEg (top), F= 0 (base of the soil column). ! o Soil / snow temperature is predicted from heat conduction @@ -100,7 +100,7 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter ! o The thermal conductivity of soil is computed from ! the algorithm of Johansen (as reported by Farouki 1981), and the ! conductivity of snow is from the formulation used in - ! SNTHERM (Jordan 1991). + ! Sturm (1997). ! o Boundary conditions: ! F = Rnet - Hg - LEg (top), F= 0 (base of the soil column). ! o Soil / snow temperature is predicted from heat conduction @@ -611,7 +611,7 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter ! ! (2) The thermal conductivity of soil is computed from the algorithm of ! Johansen (as reported by Farouki 1981), and of snow is from the - ! formulation used in SNTHERM (Jordan 1991). + ! formulation used in Sturm (1997). ! The thermal conductivities at the interfaces between two neighboring ! layers (j, j+1) are derived from an assumption that the flux across ! the interface is equal to that from the node j to the interface and the @@ -734,11 +734,16 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter endif endif - ! Thermal conductivity of snow, which from Jordan (1991) pp. 18 + ! Thermal conductivity of snow, which from Sturm (1997) ! Only examine levels from snl(c)+1 -> 0 where snl(c) < 1 if (snl(c)+1 < 1 .AND. (j >= snl(c)+1) .AND. (j <= 0)) then - bw(c,j) = (h2osoi_ice(c,j)+h2osoi_liq(c,j))/(frac_sno(c)*dz(c,j)) - thk(c,j) = tkair + (7.75e-5_r8 *bw(c,j) + 1.105e-6_r8*bw(c,j)*bw(c,j))*(tkice-tkair) + bw(c,j) = ((h2osoi_ice(c,j)*1)+h2osoi_liq(c,j))/(frac_sno(c)*dz(c,j)) ! ==RHOS + ! thk(c,j) = tkair + (7.75e-5_r8 *bw(c,j) + 1.105e-6_r8*bw(c,j)*bw(c,j))*(tkice-tkair) ! Original (Jordan) Parameterisation + if (bw(c,j) <= 156) then !LMW or 0.156 ? + thk(c,j) = 0.023 + 0.234*(bw(c,j)/1000) !LMW - units changed by VRD + else !LMW + thk(c,j) = 0.138 - 1.01*(bw(c,j)/1000) +(3.233*((bw(c,j)/1000)*(bw(c,j)/1000))) ! LMW Sturm I think + end if end if end do From 37db306904dbc8649a76c0b5b7d04eb022013116 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 30 Oct 2023 17:56:15 -0600 Subject: [PATCH 2/5] Update comments, add placeholder for thermal_cond_snow option --- src/biogeophys/SoilTemperatureMod.F90 | 36 +++++++++++++++++++-------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index caeedd1603..d3e797631b 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -47,7 +47,7 @@ module SoilTemperatureMod ! o The thermal conductivity of soil is computed from ! the algorithm of Johansen (as reported by Farouki 1981), and the ! conductivity of snow is from the formulation used in - ! Sturm (1997). + ! Sturm (1997) or Jordan (1991) p. 18 depending on namelist option. ! o Boundary conditions: ! F = Rnet - Hg - LEg (top), F= 0 (base of the soil column). ! o Soil / snow temperature is predicted from heat conduction @@ -100,7 +100,7 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter ! o The thermal conductivity of soil is computed from ! the algorithm of Johansen (as reported by Farouki 1981), and the ! conductivity of snow is from the formulation used in - ! Sturm (1997). + ! Sturm (1997) or Jordan (1991) p. 18 depending on namelist option. ! o Boundary conditions: ! F = Rnet - Hg - LEg (top), F= 0 (base of the soil column). ! o Soil / snow temperature is predicted from heat conduction @@ -611,7 +611,8 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter ! ! (2) The thermal conductivity of soil is computed from the algorithm of ! Johansen (as reported by Farouki 1981), and of snow is from the - ! formulation used in Sturm (1997). + ! formulation used in Sturm (1997) or Jordan (1991) p. 18 depending on + ! namelist option. ! The thermal conductivities at the interfaces between two neighboring ! layers (j, j+1) are derived from an assumption that the flux across ! the interface is equal to that from the node j to the interface and the @@ -734,16 +735,29 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter endif endif - ! Thermal conductivity of snow, which from Sturm (1997) + ! Thermal conductivity of snow ! Only examine levels from snl(c)+1 -> 0 where snl(c) < 1 if (snl(c)+1 < 1 .AND. (j >= snl(c)+1) .AND. (j <= 0)) then - bw(c,j) = ((h2osoi_ice(c,j)*1)+h2osoi_liq(c,j))/(frac_sno(c)*dz(c,j)) ! ==RHOS - ! thk(c,j) = tkair + (7.75e-5_r8 *bw(c,j) + 1.105e-6_r8*bw(c,j)*bw(c,j))*(tkice-tkair) ! Original (Jordan) Parameterisation - if (bw(c,j) <= 156) then !LMW or 0.156 ? - thk(c,j) = 0.023 + 0.234*(bw(c,j)/1000) !LMW - units changed by VRD - else !LMW - thk(c,j) = 0.138 - 1.01*(bw(c,j)/1000) +(3.233*((bw(c,j)/1000)*(bw(c,j)/1000))) ! LMW Sturm I think - end if + bw(c,j) = (h2osoi_ice(c,j)+h2osoi_liq(c,j))/(frac_sno(c)*dz(c,j)) +! TODO slevis: Add namelist option thermal_cond_snow and then +! uncomment relevant lines below +! select case (thermal_cond_snow) +! case ('Jordan1991') +! thk(c,j) = tkair + (7.75e-5_r8 *bw(c,j) + 1.105e-6_r8*bw(c,j)*bw(c,j))*(tkice-tkair) +! case ('Sturm1997') + ! Implemented by Vicky Dutch (VRD), Nick Rutter, and + ! Leanne Wake (LMW) + ! https://tc.copernicus.org/articles/16/4201/2022/ + ! Code provided by Adrien Dams to Will Wieder + if (bw(c,j) <= 156) then !LMW or 0.156 ? + thk(c,j) = 0.023 + 0.234*(bw(c,j)/1000) !LMW - units changed by VRD + else !LMW + thk(c,j) = 0.138 - 1.01*(bw(c,j)/1000) +(3.233*((bw(c,j)/1000)*(bw(c,j)/1000))) ! LMW Sturm I think + end if +! case default +! write(iulog,*) subname//' ERROR: unknown thermal_cond_snow value: ', thermal_cond_snow +! call endrun(msg=errMsg(sourcefile, __LINE__)) +! end select end if end do From 75d5f10f09fd7b9ef3e2cb535a5e4d30976d28a1 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 1 Nov 2023 16:53:23 -0600 Subject: [PATCH 3/5] Add new namelist variable snow_thermal_cond_method (not tested) --- bld/CLMBuildNamelist.pm | 7 +++++++ bld/namelist_files/namelist_defaults_ctsm.xml | 1 + .../namelist_definition_ctsm.xml | 5 +++++ src/biogeophys/SoilTemperatureMod.F90 | 21 +++++++++---------- src/main/clm_varctl.F90 | 2 ++ src/main/controlMod.F90 | 4 +++- 6 files changed, 28 insertions(+), 12 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index c12c54645f..5afaaab40d 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -2031,6 +2031,13 @@ sub setup_logic_snicar_methods { sub setup_logic_snow { my ($opts, $nl_flags, $definition, $defaults, $nl) = @_; + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'snow_thermal_cond_method' ); + + my $var = $nl->get_value('snow_thermal_cond_method'); + if ( $var ne 'Jordan1991' && $var ne 'Sturm1997' ) { + $log->fatal_error("$var is incorrect entry for the namelist variable snow_thermal_cond_method; expected Jordan1991 or Sturm1997"); + } + my $numrad_snw = $nl->get_value('snicar_numrad_snw'); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fsnowoptics', 'snicar_numrad_snw' => $numrad_snw); diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 2e57391df7..b23e67ed6b 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -445,6 +445,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). 1.e9 SwensonLawrence2012 +Jordan1991 diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index d3e797631b..69f9958efa 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -623,7 +623,8 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter use clm_varcon , only : denh2o, denice, tfrz, tkwat, tkice, tkair, cpice, cpliq, thk_bedrock, csol_bedrock use landunit_varcon , only : istice, istwet use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall, icol_road_perv, icol_road_imperv - use clm_varctl , only : iulog + use clm_varctl , only : iulog, snow_thermal_cond_method + ! ! !ARGUMENTS: type(bounds_type) , intent(in) :: bounds @@ -739,12 +740,10 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter ! Only examine levels from snl(c)+1 -> 0 where snl(c) < 1 if (snl(c)+1 < 1 .AND. (j >= snl(c)+1) .AND. (j <= 0)) then bw(c,j) = (h2osoi_ice(c,j)+h2osoi_liq(c,j))/(frac_sno(c)*dz(c,j)) -! TODO slevis: Add namelist option thermal_cond_snow and then -! uncomment relevant lines below -! select case (thermal_cond_snow) -! case ('Jordan1991') -! thk(c,j) = tkair + (7.75e-5_r8 *bw(c,j) + 1.105e-6_r8*bw(c,j)*bw(c,j))*(tkice-tkair) -! case ('Sturm1997') + select case (snow_thermal_cond_method) + case ('Jordan1991') + thk(c,j) = tkair + (7.75e-5_r8 *bw(c,j) + 1.105e-6_r8*bw(c,j)*bw(c,j))*(tkice-tkair) + case ('Sturm1997') ! Implemented by Vicky Dutch (VRD), Nick Rutter, and ! Leanne Wake (LMW) ! https://tc.copernicus.org/articles/16/4201/2022/ @@ -754,10 +753,10 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter else !LMW thk(c,j) = 0.138 - 1.01*(bw(c,j)/1000) +(3.233*((bw(c,j)/1000)*(bw(c,j)/1000))) ! LMW Sturm I think end if -! case default -! write(iulog,*) subname//' ERROR: unknown thermal_cond_snow value: ', thermal_cond_snow -! call endrun(msg=errMsg(sourcefile, __LINE__)) -! end select + case default + write(iulog,*) subname//' ERROR: unknown snow_thermal_cond_method value: ', snow_thermal_cond_method + call endrun(msg=errMsg(sourcefile, __LINE__)) + end select end if end do diff --git a/src/main/clm_varctl.F90 b/src/main/clm_varctl.F90 index 95c800504b..a5201a53cf 100644 --- a/src/main/clm_varctl.F90 +++ b/src/main/clm_varctl.F90 @@ -221,6 +221,8 @@ module clm_varctl ! which snow cover fraction parameterization to use character(len=64), public :: snow_cover_fraction_method + ! which snow thermal conductivity parameterization to use + character(len=25), public :: snow_thermal_cond_method ! atmospheric CO2 molar ratio (by volume) (umol/mol) real(r8), public :: co2_ppmv = 355._r8 ! diff --git a/src/main/controlMod.F90 b/src/main/controlMod.F90 index 5937e55b04..deb8c044d8 100644 --- a/src/main/controlMod.F90 +++ b/src/main/controlMod.F90 @@ -199,7 +199,8 @@ subroutine control_init(dtime) clump_pproc, & create_crop_landunit, nsegspc, co2_ppmv, & albice, soil_layerstruct_predefined, soil_layerstruct_userdefined, & - soil_layerstruct_userdefined_nlevsoi, use_subgrid_fluxes, snow_cover_fraction_method, & + soil_layerstruct_userdefined_nlevsoi, use_subgrid_fluxes, & + snow_thermal_cond_method, snow_cover_fraction_method, & irrigate, run_zero_weight_urban, all_active, & crop_fsat_equals_zero, for_testing_run_ncdiopio_tests, & for_testing_use_second_grain_pool, for_testing_use_repr_structure_pool, & @@ -850,6 +851,7 @@ subroutine control_spmd() ! physics variables call mpi_bcast (nsegspc, 1, MPI_INTEGER, 0, mpicom, ier) call mpi_bcast (use_subgrid_fluxes , 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (snow_thermal_cond_method, len(snow_thermal_cond_method), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (snow_cover_fraction_method , len(snow_cover_fraction_method), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (z0param_method , len(z0param_method), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (use_z0m_snowmelt, 1, MPI_LOGICAL, 0, mpicom, ier) From 239a5524e697e2274f10d206f79c2b91e8d4cdcc Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 3 Nov 2023 10:59:00 -0600 Subject: [PATCH 4/5] Change snow_thermal_cond_method to char*25 --- bld/namelist_files/namelist_definition_ctsm.xml | 2 +- src/biogeophys/SoilTemperatureMod.F90 | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 23f6063a97..58c1980232 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -2835,7 +2835,7 @@ NiuYang2007: Niu and Yang 2007 SwensonLawrence2012: Swenson and Lawrence 2012 - Parameterization to use for snow thermal conductivity diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index 69f9958efa..bd7efc0788 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -624,7 +624,6 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter use landunit_varcon , only : istice, istwet use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall, icol_road_perv, icol_road_imperv use clm_varctl , only : iulog, snow_thermal_cond_method - ! ! !ARGUMENTS: type(bounds_type) , intent(in) :: bounds From b626e88a2e930e61e440783cbbadaccae06ed81a Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 3 Nov 2023 15:36:01 -0600 Subject: [PATCH 5/5] Small corrections for tests to run --- bld/CLMBuildNamelist.pm | 2 +- src/biogeophys/SoilTemperatureMod.F90 | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 9a039b1cfc..116a585270 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -2034,7 +2034,7 @@ sub setup_logic_snow { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'snow_thermal_cond_method' ); my $var = $nl->get_value('snow_thermal_cond_method'); - if ( $var ne 'Jordan1991' && $var ne 'Sturm1997' ) { + if ( $var ne "'Jordan1991'" && $var ne "'Sturm1997'" ) { $log->fatal_error("$var is incorrect entry for the namelist variable snow_thermal_cond_method; expected Jordan1991 or Sturm1997"); } diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index bd7efc0788..0dc8876d24 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -619,6 +619,7 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter ! flux from the interface to the node j+1. ! ! !USES: + use shr_log_mod , only : errMsg => shr_log_errMsg use clm_varpar , only : nlevsno, nlevgrnd, nlevurb, nlevsoi, nlevmaxurbgrnd use clm_varcon , only : denh2o, denice, tfrz, tkwat, tkice, tkair, cpice, cpliq, thk_bedrock, csol_bedrock use landunit_varcon , only : istice, istwet @@ -648,6 +649,8 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter real(r8) :: fl ! volume fraction of liquid or unfrozen water to total water real(r8) :: satw ! relative total water content of soil. real(r8) :: zh2osfc + + character(len=*),parameter :: subname = 'SoilThermProp' !----------------------------------------------------------------------- call t_startf( 'SoilThermProp' )