From cd05cc7033fbfbe4bc6f39e5074f09a96804919d Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 5 Jul 2019 17:48:51 -0600 Subject: [PATCH 01/29] First draft: soil layer definition clean-up and user-defined option 1) Clean-up following @swensosc and @billsacks suggestions in issue #279 2) Initial proposal for user-defined option of soil layer structure: - Use existing namelist variable soil_layerstruct - Instead of setting to an existing option (e.g. '5SL_3m', etc.), set soil_layerstruct = 'user:aa,bb,cc,dd,ee,ff,gg,...' where the string is declared of len=256 and 'user:' tells the code to expect a user defined structure, aa gets assigned to nlevsoi and nlevgrnd in the code, bb gets assigned to dzsoi(1) in the code, cc gets assigned to dzsoi(2) in the code, and so on to dzsoi(nlevgrnd). --- src/main/clm_varctl.F90 | 2 +- src/main/clm_varpar.F90 | 3 + src/main/initVerticalMod.F90 | 154 +++++++++++++++-------------------- 3 files changed, 71 insertions(+), 88 deletions(-) diff --git a/src/main/clm_varctl.F90 b/src/main/clm_varctl.F90 index a6668a8148..ee94e5ef57 100644 --- a/src/main/clm_varctl.F90 +++ b/src/main/clm_varctl.F90 @@ -264,7 +264,7 @@ module clm_varctl !---------------------------------------------------------- logical, public :: use_bedrock = .false. ! true => use spatially variable soil depth - character(len=16), public :: soil_layerstruct = '10SL_3.5m' + character(len=256), public :: soil_layerstruct = '10SL_3.5m' !---------------------------------------------------------- ! plant hydraulic stress switch diff --git a/src/main/clm_varpar.F90 b/src/main/clm_varpar.F90 index c19caf5bd5..8da45f7075 100644 --- a/src/main/clm_varpar.F90 +++ b/src/main/clm_varpar.F90 @@ -158,6 +158,9 @@ subroutine clm_varpar_init(actual_maxsoil_patches, actual_numcft) else if ( soil_layerstruct == '5SL_3m' ) then nlevsoi = 5 nlevgrnd = 5 + else if (soil_layerstruct(1:5) == 'user:') then + read(soil_layerstruct(6:7),*) nlevsoi + nlevgrnd = nlevsoi else write(iulog,*) subname//' ERROR: Unrecognized soil layer structure: ', trim(soil_layerstruct) call shr_sys_abort(subname//' ERROR: Unrecognized soil layer structure') diff --git a/src/main/initVerticalMod.F90 b/src/main/initVerticalMod.F90 index f4fc4cea4b..16ed742fc2 100644 --- a/src/main/initVerticalMod.F90 +++ b/src/main/initVerticalMod.F90 @@ -157,6 +157,7 @@ subroutine initVertical(bounds, glc_behavior, snow_depth, thick_wall, thick_roof integer :: ier ! error status real(r8) :: scalez = 0.025_r8 ! Soil layer thickness discretization (m) real(r8) :: thick_equal = 0.2 + character(len=20) :: calc_method ! soil layer calculation method real(r8) ,pointer :: zbedrock_in(:) ! read in - z_bedrock real(r8) ,pointer :: lakedepth_in(:) ! read in - lakedepth real(r8), allocatable :: zurb_wall(:,:) ! wall (layer node depth) @@ -213,41 +214,34 @@ subroutine initVertical(bounds, glc_behavior, snow_depth, thick_wall, thick_roof ! Soil layers and interfaces (assumed same for all non-lake patches) ! "0" refers to soil surface and "nlevsoi" refers to the bottom of model soil - if ( soil_layerstruct == '10SL_3.5m' ) then - do j = 1, nlevgrnd - zsoi(j) = scalez*(exp(0.5_r8*(j-0.5_r8))-1._r8) !node depths - enddo - - dzsoi(1) = 0.5_r8*(zsoi(1)+zsoi(2)) !thickness b/n two interfaces - do j = 2,nlevgrnd-1 - dzsoi(j)= 0.5_r8*(zsoi(j+1)-zsoi(j-1)) - enddo - dzsoi(nlevgrnd) = zsoi(nlevgrnd)-zsoi(nlevgrnd-1) - - zisoi(0) = 0._r8 - do j = 1, nlevgrnd-1 - zisoi(j) = 0.5_r8*(zsoi(j)+zsoi(j+1)) !interface depths - enddo - zisoi(nlevgrnd) = zsoi(nlevgrnd) + 0.5_r8*dzsoi(nlevgrnd) + if (soil_layerstruct == '10SL_3.5m' .or. soil_layerstruct == '23SL_3.5m') then + calc_method = 'node-based' + else if (soil_layerstruct == '49SL_10m' .or. soil_layerstruct == '20SL_8.5m' .or. soil_layerstruct == '5SL_3m' .or. soil_layerstruct(1:5) == 'user:') then + calc_method = 'thickness-based' + else + write(iulog,*) subname//' ERROR: Unrecognized soil layer structure: ', trim(soil_layerstruct) + call endrun(subname//' ERROR: Unrecognized soil layer structure') + end if - else if ( soil_layerstruct == '23SL_3.5m' )then - ! Soil layer structure that starts with standard exponential - ! and then has several evenly spaced layers, then finishes off exponential. - ! this allows the upper soil to behave as standard, but then continues - ! with higher resolution to a deeper depth, so that, for example, permafrost - ! dynamics are not lost due to an inability to resolve temperature, moisture, - ! and biogeochemical dynamics at the base of the active layer - do j = 1, toplev_equalspace + if (calc_method == 'node-based') then + do j = 1, nlevgrnd zsoi(j) = scalez*(exp(0.5_r8*(j-0.5_r8))-1._r8) !node depths enddo - do j = toplev_equalspace+1,toplev_equalspace + nlev_equalspace - zsoi(j) = zsoi(j-1) + thick_equal - enddo - - do j = toplev_equalspace + nlev_equalspace +1, nlevgrnd - zsoi(j) = scalez*(exp(0.5_r8*((j - nlev_equalspace)-0.5_r8))-1._r8) + nlev_equalspace * thick_equal - enddo + if (soil_layerstruct == '23SL_3.5m') then + ! Soil layer structure that starts with standard exponential, + ! then has several evenly spaced layers and finishes off exponential. + ! This allows the upper soil to behave as standard, but then continues + ! with higher resolution to a deeper depth, so that, e.g., permafrost + ! dynamics are not lost due to an inability to resolve temperature, + ! moisture, and biogeochemical dynamics at the base of the active layer + do j = toplev_equalspace + 1, toplev_equalspace + nlev_equalspace + zsoi(j) = zsoi(j-1) + thick_equal + enddo + do j = toplev_equalspace + nlev_equalspace + 1, nlevgrnd + zsoi(j) = scalez * (exp(0.5_r8 * (j - nlev_equalspace - 0.5_r8)) - 1._r8) + nlev_equalspace * thick_equal + enddo + end if ! soil_layerstruct == '23SL_3.5m' dzsoi(1) = 0.5_r8*(zsoi(1)+zsoi(2)) !thickness b/n two interfaces do j = 2,nlevgrnd-1 @@ -257,24 +251,50 @@ subroutine initVertical(bounds, glc_behavior, snow_depth, thick_wall, thick_roof zisoi(0) = 0._r8 do j = 1, nlevgrnd-1 - zisoi(j) = 0.5_r8*(zsoi(j)+zsoi(j+1)) !interface depths + zisoi(j) = 0.5_r8*(zsoi(j)+zsoi(j+1)) !interface depths enddo zisoi(nlevgrnd) = zsoi(nlevgrnd) + 0.5_r8*dzsoi(nlevgrnd) - else if ( soil_layerstruct == '49SL_10m' ) then - !scs: 10 meter soil column, nlevsoi set to 49 in clm_varpar - do j = 1,10 - dzsoi(j)= 1.e-2_r8 !10mm layers - enddo - do j = 11,19 - dzsoi(j)= 1.e-1_r8 !100 mm layers - enddo - do j = 20,nlevsoi+1 !300 mm layers - dzsoi(j)= 3.e-1_r8 - enddo - do j = nlevsoi+2,nlevgrnd !10 meter bedrock layers - dzsoi(j)= 10._r8 - enddo + else if (calc_method == 'thickness-based') then + if (soil_layerstruct == '49SL_10m') then + !scs: 10 meter soil column, nlevsoi set to 49 in clm_varpar + do j = 1, 10 + dzsoi(j) = 1.e-2_r8 ! 10-mm layers + enddo + do j = 11, 19 + dzsoi(j) = 1.e-1_r8 ! 100-mm layers + enddo + do j = 20, nlevsoi+1 ! 300-mm layers + dzsoi(j) = 3.e-1_r8 + enddo + do j = nlevsoi+2,nlevgrnd ! 10-m bedrock layers + dzsoi(j) = 10._r8 + enddo + else if (soil_layerstruct == '20SL_8.5m') then + do j = 1, 4 ! linear increase in layer thickness of... + dzsoi(j) = j * 0.02_r8 ! ...2 cm each layer + enddo + do j = 5, 13 + dzsoi(j) = dzsoi(4) + (j - 4) * 0.04_r8 ! ...4 cm each layer + enddo + do j = 14, nlevsoi + dzsoi(j) = dzsoi(13) + (j - 13) * 0.10_r8 ! ...10 cm each layer + enddo + do j = nlevsoi + 1, nlevgrnd ! bedrock layers + dzsoi(j) = dzsoi(nlevsoi) + (((j - nlevsoi) * 25._r8)**1.5_r8) / 100._r8 + enddo + else if (soil_layerstruct == '5SL_3m') then + dzsoi(1) = 0.1_r8 + dzsoi(2) = 0.3_r8 + dzsoi(3) = 0.6_r8 + dzsoi(4) = 1.0_r8 + dzsoi(5) = 1.0_r8 + else if (soil_layerstruct(1:5) == 'user:') then + do j = 1, nlevgrnd + ! read string indices 8 to 9, 11 to 12, 14 to 15, and so on + read(soil_layerstruct(3*(j+2)-1:3*(j+2)),*) dzsoi(j) + end do + end if ! soil_layerstruct options zisoi(0) = 0._r8 do j = 1,nlevgrnd @@ -285,46 +305,6 @@ subroutine initVertical(bounds, glc_behavior, snow_depth, thick_wall, thick_roof zsoi(j) = 0.5*(zisoi(j-1) + zisoi(j)) enddo - else if ( soil_layerstruct == '20SL_8.5m' ) then - do j = 1,4 - dzsoi(j)= j*0.02_r8 ! linear increase in layer thickness of 2cm each layer - enddo - do j = 5,13 - dzsoi(j)= dzsoi(4)+(j-4)*0.04_r8 ! linear increase in layer thickness of 2cm each layer - enddo - do j = 14,nlevsoi - dzsoi(j)= dzsoi(13)+(j-13)*0.10_r8 ! linear increase in layer thickness of 2cm each layer - enddo - do j = nlevsoi+1,nlevgrnd !bedrock layers - dzsoi(j)= dzsoi(nlevsoi)+(((j-nlevsoi)*25._r8)**1.5_r8)/100._r8 ! bedrock layers - enddo - - zisoi(0) = 0._r8 - do j = 1,nlevgrnd - zisoi(j)= sum(dzsoi(1:j)) - enddo - - do j = 1, nlevgrnd - zsoi(j) = 0.5*(zisoi(j-1) + zisoi(j)) - enddo - else if ( soil_layerstruct == '5SL_3m' ) then - dzsoi(1)= 0.1_r8 - dzsoi(2)= 0.3_r8 - dzsoi(3)= 0.6_r8 - dzsoi(4)= 1.0_r8 - dzsoi(5)= 1.0_r8 - - zisoi(0) = 0._r8 - do j = 1,nlevgrnd - zisoi(j)= sum(dzsoi(1:j)) - enddo - - do j = 1, nlevgrnd - zsoi(j) = 0.5*(zisoi(j-1) + zisoi(j)) - enddo - else - write(iulog,*) subname//' ERROR: Unrecognized soil layer structure: ', trim(soil_layerstruct) - call endrun(subname//' ERROR: Unrecognized soil layer structure') end if ! define a vertical grid spacing such that it is the normal dzsoi if @@ -332,7 +312,7 @@ subroutine initVertical(bounds, glc_behavior, snow_depth, thick_wall, thick_roof if (use_vertsoilc) then dzsoi_decomp = dzsoi !thickness b/n two interfaces else - dzsoi_decomp(1) = 1. + dzsoi_decomp(1) = 1._r8 end if if (masterproc) then From 68d5e54fe963a5f80c96c1b29183751d9026a4d7 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 5 Jul 2019 19:05:24 -0600 Subject: [PATCH 02/29] Change user-defined option to allow min(dzsoi(j)) = .001 m --- src/main/initVerticalMod.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/initVerticalMod.F90 b/src/main/initVerticalMod.F90 index 16ed742fc2..28fd91f54b 100644 --- a/src/main/initVerticalMod.F90 +++ b/src/main/initVerticalMod.F90 @@ -291,8 +291,8 @@ subroutine initVertical(bounds, glc_behavior, snow_depth, thick_wall, thick_roof dzsoi(5) = 1.0_r8 else if (soil_layerstruct(1:5) == 'user:') then do j = 1, nlevgrnd - ! read string indices 8 to 9, 11 to 12, 14 to 15, and so on - read(soil_layerstruct(3*(j+2)-1:3*(j+2)),*) dzsoi(j) + ! read string indices 8 to 11, 13 to 16, 18 to 21, and so on + read(soil_layerstruct(5*j+3:5*j+6),*) dzsoi(j) end do end if ! soil_layerstruct options From 048199d2b4e31c248815dc8ef4017e904748fd21 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 12 Jul 2019 04:14:33 -0600 Subject: [PATCH 03/29] Introducing soil_layerstruct_userdefined and nlevsoinl - soil_layerstruct_userdefined is a namelist vector that allows the user to enter dzsoi values for their simulation; the number of dzsoi values entered determines nlevgrnd in clm_varpar - nlevsoinl is a namelist scalar required when soil_layerstruct_userdefined is used; it sets nlevsoi in clm_varpar - soil_layerstruct_predefined is a slightly modified version of preexisting namelist variable soil_layerstruct - a one-line bug-fix appears in LakeTemperatureMod.F90 that changes dz to dz_lake and is required for the code to work when there are fewer soil layers than lake layers; this changes answers --- bld/CLMBuildNamelist.pm | 2 +- bld/namelist_files/namelist_defaults_ctsm.xml | 9 ++- .../namelist_definition_ctsm.xml | 19 ++++- .../testmods_dirs/clm/vrtlay/user_nl_clm | 2 +- src/biogeophys/LakeTemperatureMod.F90 | 4 +- .../SoilHydrologyInitTimeConstMod.F90 | 6 +- src/biogeophys/SoilStateInitTimeConstMod.F90 | 4 +- src/main/clm_varctl.F90 | 4 +- src/main/clm_varpar.F90 | 76 +++++++++++++------ src/main/controlMod.F90 | 11 ++- src/main/initVerticalMod.F90 | 30 ++++---- 11 files changed, 110 insertions(+), 57 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 42e0b35b92..3a6fc690f4 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -2089,7 +2089,7 @@ sub setup_logic_soilstate { my ($opts, $nl_flags, $definition, $defaults, $nl) = @_; add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'organic_frac_squared' ); - add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'soil_layerstruct', + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'soil_layerstruct_predefined', 'structure'=>$nl_flags->{'structure'}); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_bedrock', 'use_fates'=>$nl_flags->{'use_fates'}, 'vichydro'=>$nl_flags->{'vichydro'} ); diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index ef7f2498ad..91591ed99c 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -125,9 +125,12 @@ attributes from the config_cache.xml file (with keys converted to upper-case). .true. .false. -5SL_3m -20SL_8.5m -10SL_3.5m +5SL_3m +UNSET +10SL_3.5m + +-9999999._r8 +-9999999 .false. .false. diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 33947ebe4d..8380596a8c 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -114,13 +114,26 @@ If TRUE, square the organic fraction when it's used (as was done in CLM4.5) Otherwise use the fraction straight up (the default for CLM5.0) - + 10SL_3.5m = standard CLM4 and CLM4.5 version 23SL_3.5m = more vertical layers for permafrost simulations 49SL_10m = 49 layer soil column, 10m of soil, 5 bedrock layers 20SL_8.5m = 20 layer soil column, 8m of soil, 5 bedrock layers -5SL_3m = 5 layer soil column, 3m of soil, 0 bedrock layers +4SL_2m = 4 layer soil column, 2m of soil, 0 bedrock layers +UNSET = required when setting soil_layerstruct_userdefined in clm5 + + + +User-defined vector of dzsoi. The length of this vector determines nlevgrnd. When the user sets this vector, they have to set nlevsoinl in the namelist, too; nlevsoinl must be less than nlevgrnd in this version of the model, even though ideally nlevsoinl could also equal nlevgrnd. +Default: rundef + + + +User-defined number of soil layers required to be set in the namelist when the user sets soil_layerstruct_userdefined in the namelist. +Default: iundef jconvect(c) .and. j < jconvectbot(c)) then ! Assume resistance is zero for levels that convect - lakeresist(c) = lakeresist(c) + dz(c,j)/kme(c,j) ! dz/eddy or molecular diffusivity + lakeresist(c) = lakeresist(c) + dz_lake(c,j)/kme(c,j) ! dz/eddy or molecular diffusivity end if if (j == nlevlak) then ! Calculate grnd_ch4_cond diff --git a/src/biogeophys/SoilHydrologyInitTimeConstMod.F90 b/src/biogeophys/SoilHydrologyInitTimeConstMod.F90 index d10a842015..2a2142acd6 100644 --- a/src/biogeophys/SoilHydrologyInitTimeConstMod.F90 +++ b/src/biogeophys/SoilHydrologyInitTimeConstMod.F90 @@ -38,7 +38,7 @@ subroutine SoilHydrologyInitTimeConst(bounds, soilhydrology_inst) use shr_spfn_mod , only : shr_spfn_erf use abortutils , only : endrun use spmdMod , only : masterproc - use clm_varctl , only : fsurdat, paramfile, iulog, use_vichydro, soil_layerstruct + use clm_varctl , only : fsurdat, paramfile, iulog, use_vichydro, soil_layerstruct_predefined use clm_varpar , only : nlevsoifl, toplev_equalspace use clm_varpar , only : nlevsoi, nlevgrnd, nlevsno, nlevlak, nlevurb, nlayer, nlayert use clm_varcon , only : zsoi, dzsoi, zisoi, spval, nlvic, dzvic, pc, grlnd @@ -198,7 +198,7 @@ subroutine SoilHydrologyInitTimeConst(bounds, soilhydrology_inst) zisoifl(nlevsoifl) = zsoifl(nlevsoifl) + 0.5_r8*dzsoifl(nlevsoifl) if ( masterproc )then - if ( soil_layerstruct /= '10SL_3.5m' ) write(iulog,*) 'Setting clay, sand, organic, in Soil Hydrology for VIC' + if ( soil_layerstruct_predefined /= '10SL_3.5m' ) write(iulog,*) 'Setting clay, sand, organic, in Soil Hydrology for VIC' end if do c = bounds%begc, bounds%endc g = col%gridcell(c) @@ -211,7 +211,7 @@ subroutine SoilHydrologyInitTimeConst(bounds, soilhydrology_inst) ! do nothing else do lev = 1,nlevgrnd - if ( soil_layerstruct /= '10SL_3.5m' )then + if ( soil_layerstruct_predefined /= '10SL_3.5m' )then if (lev .eq. 1) then clay = clay3d(g,1) sand = sand3d(g,1) diff --git a/src/biogeophys/SoilStateInitTimeConstMod.F90 b/src/biogeophys/SoilStateInitTimeConstMod.F90 index 136c21ca1c..b5d0abd899 100644 --- a/src/biogeophys/SoilStateInitTimeConstMod.F90 +++ b/src/biogeophys/SoilStateInitTimeConstMod.F90 @@ -100,7 +100,7 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) use clm_varcon , only : zsoi, dzsoi, zisoi, spval use clm_varcon , only : secspday, pc, mu, denh2o, denice, grlnd use clm_varctl , only : use_cn, use_lch4, use_fates - use clm_varctl , only : iulog, fsurdat, paramfile, soil_layerstruct + use clm_varctl , only : iulog, fsurdat, paramfile, soil_layerstruct_predefined use landunit_varcon , only : istdlak, istwet, istsoil, istcrop, istice_mec use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall, icol_road_perv, icol_road_imperv use fileutils , only : getfil @@ -389,7 +389,7 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) do lev = 1,nlevgrnd ! DML - this if statement could probably be removed and just the ! top part used for all soil layer structures - if ( soil_layerstruct /= '10SL_3.5m' )then ! apply soil texture from 10 layer input dataset + if ( soil_layerstruct_predefined /= '10SL_3.5m' )then ! apply soil texture from 10 layer input dataset if (lev .eq. 1) then clay = clay3d(g,1) sand = sand3d(g,1) diff --git a/src/main/clm_varctl.F90 b/src/main/clm_varctl.F90 index ee94e5ef57..5e957ab898 100644 --- a/src/main/clm_varctl.F90 +++ b/src/main/clm_varctl.F90 @@ -264,7 +264,9 @@ module clm_varctl !---------------------------------------------------------- logical, public :: use_bedrock = .false. ! true => use spatially variable soil depth - character(len=256), public :: soil_layerstruct = '10SL_3.5m' + character(len=16), public :: soil_layerstruct_predefined = 'UNSET' + real(r8), public :: soil_layerstruct_userdefined(99) = rundef + integer, public :: nlevsoinl = iundef !---------------------------------------------------------- ! plant hydraulic stress switch diff --git a/src/main/clm_varpar.F90 b/src/main/clm_varpar.F90 index 8da45f7075..2f8ffae407 100644 --- a/src/main/clm_varpar.F90 +++ b/src/main/clm_varpar.F90 @@ -11,7 +11,8 @@ module clm_varpar use clm_varctl , only: use_extralakelayers, use_vertsoilc use clm_varctl , only: use_century_decomp, use_c13, use_c14 use clm_varctl , only: iulog, use_crop, create_crop_landunit, irrigate - use clm_varctl , only: use_vichydro, soil_layerstruct + use clm_varctl , only: use_vichydro, nlevsoinl, rundef + use clm_varctl , only: soil_layerstruct_predefined, soil_layerstruct_userdefined use clm_varctl , only: use_fates ! @@ -106,6 +107,7 @@ subroutine clm_varpar_init(actual_maxsoil_patches, actual_numcft) ! ! !LOCAL VARIABLES: ! + integer :: j ! loop index character(len=32) :: subname = 'clm_varpar_init' ! subroutine name !------------------------------------------------------------------------------ @@ -141,31 +143,55 @@ subroutine clm_varpar_init(actual_maxsoil_patches, actual_numcft) nlevsoifl = 10 nlevurb = 5 - if ( masterproc ) write(iulog, *) 'soil_layerstruct varpar ',soil_layerstruct - if ( soil_layerstruct == '10SL_3.5m' ) then - nlevsoi = nlevsoifl - nlevgrnd = 15 - else if ( soil_layerstruct == '23SL_3.5m' ) then - nlevsoi = 8 + nlev_equalspace - nlevgrnd = 15 + nlev_equalspace - else if ( soil_layerstruct == '49SL_10m' ) then - nlevsoi = 49 ! 10x10 + 9x100 + 30x300 = 1e4mm = 10m -! nlevsoi = 29 ! 10x10 + 9x100 + 10x300 = 4e3mm = 4m - nlevgrnd = nlevsoi+5 - else if ( soil_layerstruct == '20SL_8.5m' ) then - nlevsoi = 20 - nlevgrnd = nlevsoi+5 - else if ( soil_layerstruct == '5SL_3m' ) then - nlevsoi = 5 - nlevgrnd = 5 - else if (soil_layerstruct(1:5) == 'user:') then - read(soil_layerstruct(6:7),*) nlevsoi - nlevgrnd = nlevsoi - else - write(iulog,*) subname//' ERROR: Unrecognized soil layer structure: ', trim(soil_layerstruct) - call shr_sys_abort(subname//' ERROR: Unrecognized soil layer structure') + + if ( masterproc ) write(iulog, *) 'soil_layerstruct_predefined varpar ', soil_layerstruct_predefined + if ( masterproc ) write(iulog, *) 'soil_layerstruct_userdefined varpar ', soil_layerstruct_userdefined + + if (soil_layerstruct_userdefined(1) /= rundef) then ! user defined soil layers + if (soil_layerstruct_predefined /= 'UNSET') then + write(iulog,*) subname//' ERROR: Both soil_layerstruct_predefined and soil_layer_userdefined have values' + call shr_sys_abort(subname//' ERROR: Cannot decide how to set the soil layer structure') + else + nlevgrnd = size(soil_layerstruct_userdefined) + do j = nlevgrnd,1,-1 + if (soil_layerstruct_userdefined(j) /= rundef) then + exit + else + nlevgrnd = nlevgrnd - 1 + end if + end do + nlevsoi = nlevsoinl ! value read in namelist + if (nlevsoi >= nlevgrnd) then + write(iulog,*) subname//' ERROR: nlevsoi >= nlevgrnd NOT allowed' + call shr_sys_abort(subname//' ERROR: nlevsoi must be less than nlevgrnd') + end if + end if + else ! pre-defined soil structure options + if ( soil_layerstruct_predefined == '10SL_3.5m' ) then + nlevsoi = nlevsoifl + nlevgrnd = 15 + else if ( soil_layerstruct_predefined == '23SL_3.5m' ) then + nlevsoi = 8 + nlev_equalspace + nlevgrnd = 15 + nlev_equalspace + else if ( soil_layerstruct_predefined == '49SL_10m' ) then + nlevsoi = 49 ! 10x10 + 9x100 + 30x300 = 1e4mm = 10m +! nlevsoi = 29 ! 10x10 + 9x100 + 10x300 = 4e3mm = 4m + nlevgrnd = nlevsoi+5 + else if ( soil_layerstruct_predefined == '20SL_8.5m' ) then + nlevsoi = 20 + nlevgrnd = nlevsoi+5 + else if ( soil_layerstruct_predefined == '4SL_2m' ) then + nlevsoi = 4 + nlevgrnd = 5 + else if (soil_layerstruct_predefined == 'UNSET') then + write(iulog,*) subname//' ERROR: Both soil_layerstruct_predefined and soil_layer_userdefined currently undefined' + call shr_sys_abort(subname//' ERROR: Cannot set the soil layer structure') + else + write(iulog,*) subname//' ERROR: Unrecognized pre-defined soil layer structure: ', trim(soil_layerstruct_predefined) + call shr_sys_abort(subname//' ERROR: Unrecognized pre-defined soil layer structure') + end if endif - if ( masterproc ) write(iulog, *) 'soil_layerstruct varpar ',soil_layerstruct,nlevsoi,nlevgrnd + if ( masterproc ) write(iulog, *) 'nlevsoi, nlevgrnd varpar ', nlevsoi, nlevgrnd if (use_vichydro) then nlayert = nlayer + (nlevgrnd -nlevsoi) diff --git a/src/main/controlMod.F90 b/src/main/controlMod.F90 index 59c4273277..ecc9ba7281 100644 --- a/src/main/controlMod.F90 +++ b/src/main/controlMod.F90 @@ -203,7 +203,8 @@ subroutine control_init( ) namelist /clm_inparm/ & clump_pproc, wrtdia, & create_crop_landunit, nsegspc, co2_ppmv, override_nsrest, & - albice, soil_layerstruct, subgridflag, & + albice, soil_layerstruct_predefined, soil_layerstruct_userdefined, & + nlevsoinl, subgridflag, & irrigate, run_zero_weight_urban, all_active, & crop_fsat_equals_zero @@ -812,7 +813,9 @@ subroutine control_spmd() call mpi_bcast (scmlon, 1, MPI_REAL8,0, mpicom, ier) call mpi_bcast (co2_ppmv, 1, MPI_REAL8,0, mpicom, ier) call mpi_bcast (albice, 2, MPI_REAL8,0, mpicom, ier) - call mpi_bcast (soil_layerstruct,len(soil_layerstruct), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (soil_layerstruct_predefined,len(soil_layerstruct_predefined), MPI_CHARACTER, 0, mpicom, ier) + call mpi_bcast (soil_layerstruct_userdefined,size(soil_layerstruct_userdefined), MPI_REAL8, 0, mpicom, ier) + call mpi_bcast (nlevsoinl, 1, MPI_INTEGER, 0, mpicom, ier) ! snow pack variables call mpi_bcast (nlevsno, 1, MPI_INTEGER, 0, mpicom, ier) @@ -1028,7 +1031,9 @@ subroutine control_print () end if write(iulog,*) ' land-ice albedos (unitless 0-1) = ', albice - write(iulog,*) ' soil layer structure = ', soil_layerstruct + write(iulog,*) ' pre-defined soil layer structure = ', soil_layerstruct_predefined + write(iulog,*) ' user-defined soil layer structure = ', soil_layerstruct_userdefined + write(iulog,*) ' user-defined number of soil layers = ', nlevsoinl write(iulog,*) ' plant hydraulic stress = ', use_hydrstress write(iulog,*) ' dynamic roots = ', use_dynroot if (nsrest == nsrContinue) then diff --git a/src/main/initVerticalMod.F90 b/src/main/initVerticalMod.F90 index 28fd91f54b..956dbb2160 100644 --- a/src/main/initVerticalMod.F90 +++ b/src/main/initVerticalMod.F90 @@ -17,7 +17,8 @@ module initVerticalMod use clm_varpar , only : nlevsoi, nlevsoifl, nlevurb use clm_varctl , only : fsurdat, iulog use clm_varctl , only : use_vancouver, use_mexicocity, use_vertsoilc, use_extralakelayers - use clm_varctl , only : use_bedrock, soil_layerstruct + use clm_varctl , only : use_bedrock, nlevsoinl, rundef + use clm_varctl , only : soil_layerstruct_predefined, soil_layerstruct_userdefined use clm_varctl , only : use_fates use clm_varcon , only : zlak, dzlak, zsoi, dzsoi, zisoi, dzsoi_decomp, spval, ispval, grlnd use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall, is_hydrologically_active @@ -214,12 +215,15 @@ subroutine initVertical(bounds, glc_behavior, snow_depth, thick_wall, thick_roof ! Soil layers and interfaces (assumed same for all non-lake patches) ! "0" refers to soil surface and "nlevsoi" refers to the bottom of model soil - if (soil_layerstruct == '10SL_3.5m' .or. soil_layerstruct == '23SL_3.5m') then + if (soil_layerstruct_predefined == '10SL_3.5m' .or. soil_layerstruct_predefined == '23SL_3.5m') then calc_method = 'node-based' - else if (soil_layerstruct == '49SL_10m' .or. soil_layerstruct == '20SL_8.5m' .or. soil_layerstruct == '5SL_3m' .or. soil_layerstruct(1:5) == 'user:') then + else if (soil_layerstruct_predefined == '49SL_10m' .or. & + soil_layerstruct_predefined == '20SL_8.5m' .or. & + soil_layerstruct_predefined == '4SL_2m' .or. & + soil_layerstruct_userdefined(1) /= rundef) then calc_method = 'thickness-based' else - write(iulog,*) subname//' ERROR: Unrecognized soil layer structure: ', trim(soil_layerstruct) + write(iulog,*) subname//' ERROR: Unrecognized pre-defined and user-defined soil layer structures: ', trim(soil_layerstruct_predefined), soil_layerstruct_userdefined call endrun(subname//' ERROR: Unrecognized soil layer structure') end if @@ -228,7 +232,7 @@ subroutine initVertical(bounds, glc_behavior, snow_depth, thick_wall, thick_roof zsoi(j) = scalez*(exp(0.5_r8*(j-0.5_r8))-1._r8) !node depths enddo - if (soil_layerstruct == '23SL_3.5m') then + if (soil_layerstruct_predefined == '23SL_3.5m') then ! Soil layer structure that starts with standard exponential, ! then has several evenly spaced layers and finishes off exponential. ! This allows the upper soil to behave as standard, but then continues @@ -241,7 +245,7 @@ subroutine initVertical(bounds, glc_behavior, snow_depth, thick_wall, thick_roof do j = toplev_equalspace + nlev_equalspace + 1, nlevgrnd zsoi(j) = scalez * (exp(0.5_r8 * (j - nlev_equalspace - 0.5_r8)) - 1._r8) + nlev_equalspace * thick_equal enddo - end if ! soil_layerstruct == '23SL_3.5m' + end if ! soil_layerstruct_predefined == '23SL_3.5m' dzsoi(1) = 0.5_r8*(zsoi(1)+zsoi(2)) !thickness b/n two interfaces do j = 2,nlevgrnd-1 @@ -256,7 +260,7 @@ subroutine initVertical(bounds, glc_behavior, snow_depth, thick_wall, thick_roof zisoi(nlevgrnd) = zsoi(nlevgrnd) + 0.5_r8*dzsoi(nlevgrnd) else if (calc_method == 'thickness-based') then - if (soil_layerstruct == '49SL_10m') then + if (soil_layerstruct_predefined == '49SL_10m') then !scs: 10 meter soil column, nlevsoi set to 49 in clm_varpar do j = 1, 10 dzsoi(j) = 1.e-2_r8 ! 10-mm layers @@ -270,7 +274,7 @@ subroutine initVertical(bounds, glc_behavior, snow_depth, thick_wall, thick_roof do j = nlevsoi+2,nlevgrnd ! 10-m bedrock layers dzsoi(j) = 10._r8 enddo - else if (soil_layerstruct == '20SL_8.5m') then + else if (soil_layerstruct_predefined == '20SL_8.5m') then do j = 1, 4 ! linear increase in layer thickness of... dzsoi(j) = j * 0.02_r8 ! ...2 cm each layer enddo @@ -283,18 +287,18 @@ subroutine initVertical(bounds, glc_behavior, snow_depth, thick_wall, thick_roof do j = nlevsoi + 1, nlevgrnd ! bedrock layers dzsoi(j) = dzsoi(nlevsoi) + (((j - nlevsoi) * 25._r8)**1.5_r8) / 100._r8 enddo - else if (soil_layerstruct == '5SL_3m') then + else if (soil_layerstruct_predefined == '4SL_2m') then dzsoi(1) = 0.1_r8 dzsoi(2) = 0.3_r8 dzsoi(3) = 0.6_r8 dzsoi(4) = 1.0_r8 dzsoi(5) = 1.0_r8 - else if (soil_layerstruct(1:5) == 'user:') then + else if (soil_layerstruct_userdefined(1) /= rundef) then do j = 1, nlevgrnd - ! read string indices 8 to 11, 13 to 16, 18 to 21, and so on - read(soil_layerstruct(5*j+3:5*j+6),*) dzsoi(j) + ! read dzsoi from user-entered namelist vector + dzsoi(j) = soil_layerstruct_userdefined(j) end do - end if ! soil_layerstruct options + end if ! thickness-based options zisoi(0) = 0._r8 do j = 1,nlevgrnd From ebe5997006297210ad0f29127d181e6bd1340f5d Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 12 Jul 2019 04:37:23 -0600 Subject: [PATCH 04/29] Minor update of the wording of an error check in clm_varpar --- src/main/clm_varpar.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/clm_varpar.F90 b/src/main/clm_varpar.F90 index 2f8ffae407..f904efd3bd 100644 --- a/src/main/clm_varpar.F90 +++ b/src/main/clm_varpar.F90 @@ -162,7 +162,7 @@ subroutine clm_varpar_init(actual_maxsoil_patches, actual_numcft) end do nlevsoi = nlevsoinl ! value read in namelist if (nlevsoi >= nlevgrnd) then - write(iulog,*) subname//' ERROR: nlevsoi >= nlevgrnd NOT allowed' + write(iulog,*) subname//' ERROR: nlevsoi >= nlevgrnd; did you enter nlevsoinl correctly in user_nl_clm?' call shr_sys_abort(subname//' ERROR: nlevsoi must be less than nlevgrnd') end if end if From ecb7d4a80ef890d8b3787b077bf1a948dac97122 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 15 Jul 2019 13:25:56 -0600 Subject: [PATCH 05/29] namelist_defaults correction and ChangLog first draft --- bld/namelist_files/namelist_defaults_ctsm.xml | 2 +- doc/ChangeLog | 123 ++++++++++++++++++ doc/ChangeSum | 1 + 3 files changed, 125 insertions(+), 1 deletion(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 91591ed99c..02fb780330 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -125,7 +125,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). .true. .false. -5SL_3m +4SL_2m UNSET 10SL_3.5m diff --git a/doc/ChangeLog b/doc/ChangeLog index 3d44f1ff19..5c497d664e 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,4 +1,127 @@ =============================================================== +Tag name: ctsm1.0.dev051 +Originator(s): slevis (Samuel Levis,SLevis Consulting LLC,303-665-1310) +Date: Mon Jul 15 12:13:39 MDT 2019 +One-line Summary: Soil layer definition clean-up and user-defined option + +Purpose of changes +------------------ + + Code clean-up clarifes that there are two types of soil layer + definition: the node-based and the thickness-based. + + User-defined option allows user to specify a soil layer profile in the + form of a vector of dzsoi values in meters in the thickness-based + approach. + + +Bugs fixed or introduced +------------------------ + +Issues fixed (include CTSM Issue #): #279 #728 + +Known bugs found since the previous tag (include github issue ID): #761 and bug in this PR (#759) causing model to abort when nlevsoi = nlevgrnd + + +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.] + +[ ] clm5_0 + +[X] ctsm5_0-nwp + +[ ] clm4_5 + +Notes of particular relevance for users +--------------------------------------- + +Caveats for users (e.g., need to interpolate initial conditions): specify at least one, either soil_layerstruct_predefined or soil_layerstruct_userdefined in the namelist + +Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables): renamed soil_layerstruct to soil_layerstruct_predefined and added soil_layerstruct_userdefined + +Changes made to namelist defaults (e.g., changed parameter values): soil_layerstruct_predefined clm5 default changed from 20SL_8.5m to UNSET + +Changes to the datasets (e.g., parameter, surface or initial files): none + +Substantial timing or memory changes: none + +Notes of particular relevance for developers +-------------------------------------------- +NOTE: Be sure to review the steps in README.CHECKLIST.master_tags as well as the coding style in the Developers Guide + +Caveats for developers (e.g., code that is duplicated that requires double maintenance): none + +Changes to tests or testing: TEST(S) ADDED TO THE TEST SUITE. Also specified soil_layerstruct_predefined in all pre-existing tests in the test suite. + +Code reviewed by: @billsacks + + +CTSM testing: + +[... Remove before making master tag. Available test levels: + + a) regular (must be run before handing off a tag to SEs and must be run + before committing a tag) + b) build_namelist (if namelists and/or build_system changed)) + c) tools (only if tools are modified and no CTSM source is modified) + d) short (for use during development and in rare cases where only a small + change with known behavior is added ... eg. a minor bug fix) + e) doc (no source testing required) + +... ] + + [PASS means all tests PASS and OK means tests PASS other than expected fails.] + + build-namelist tests: + + cheyenne - + + tools-tests (test/tools): + + cheyenne - + + PTCLM testing (tools/shared/PTCLM/test): + + cheyenne - + + python testing (see instructions in python/README.md; document testing done): + + (any machine) - + + regular tests (aux_clm): + + cheyenne ---- + hobart ------ + +If the tag used for baseline comparisons was NOT the previous tag, note that here: + + +Answer changes +-------------- + +Changes answers relative to baseline: + + Summarize any changes to answers, i.e., + - what code configurations: nwp + - what platforms/compilers: all + - nature of change: larger than roundoff/same climate + + +Detailed list of changes +------------------------ + +List any externals directories updated (cime, rtm, mosart, cism, fates, etc.): none + +Pull Requests that document the changes (include PR ids): + https://github.com/ESCOMP/ctsm/pull/759 + +=============================================================== +=============================================================== Tag name: ctsm1.0.dev049 Originator(s): erik (Erik Kluzek) Date: Sun Jun 23 20:56:55 MDT 2019 diff --git a/doc/ChangeSum b/doc/ChangeSum index a777fe0da2..d0d677dc08 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,5 +1,6 @@ Tag Who Date Summary ============================================================================================================================ + ctsm1.0.dev051 slevis 07/15/2019 Soil layer definition clean-up and user-defined option ctsm1.0.dev049 erik 06/23/2019 Update mosart and intel to intel-19 on cheyenne ctsm1.0.dev048 erik 06/23/2019 Updates for buildlib changes and cime and externals updates ctsm1.0.dev047 sacks 06/16/2019 Fix negative snow compaction during snow melt From 4d97279fb8ad3cfa2568c90b10ce70272a2261ce Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 15 Jul 2019 16:12:57 -0600 Subject: [PATCH 06/29] New error checks in CLMBuildNamelist.pm And revert to the original standard case clm5 default value for soil_layerstruct_predefined --- bld/CLMBuildNamelist.pm | 24 +++++++++++++++++-- bld/namelist_files/namelist_defaults_ctsm.xml | 2 +- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 3a6fc690f4..64a2325f27 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -2089,10 +2089,30 @@ sub setup_logic_soilstate { my ($opts, $nl_flags, $definition, $defaults, $nl) = @_; add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'organic_frac_squared' ); - add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'soil_layerstruct_predefined', - 'structure'=>$nl_flags->{'structure'}); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_bedrock', 'use_fates'=>$nl_flags->{'use_fates'}, 'vichydro'=>$nl_flags->{'vichydro'} ); + + my $var1 = "soil_layerstruct_predefined"; + my $var2 = "soil_layerstruct_userdefined"; + my $soil_layerstruct_predefined = $nl->get_value($var1); + my $soil_layerstruct_userdefined = $nl->get_value($var2); + + if (defined($soil_layerstruct_userdefined)) { + if (defined($soil_layerstruct_predefined)) { + $log->fatal_error("You have set both soil_layerstruct_userdefined and soil_layerstruct_predefined in your namelist; model cannot determine which to use"); + } else { + my $group = $definition->get_group_name($var1); + $nl->set_variable_value($group, $var1, 'UNSET' ); + } + } else { + if (defined($soil_layerstruct_predefined)) { + my $group = $definition->get_group_name($var2); + $nl->set_variable_value($group, $var2, -9999999.); + } else { + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'soil_layerstruct_predefined', + 'structure'=>$nl_flags->{'structure'}); + } + } } #------------------------------------------------------------------------------- diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 02fb780330..30e1c2c05d 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -126,7 +126,7 @@ attributes from the config_cache.xml file (with keys converted to upper-case). .false. 4SL_2m -UNSET +20SL_8.5m 10SL_3.5m -9999999._r8 From 907432dcac9061ae0fe52bd6bdd36c370026b406 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 15 Jul 2019 16:29:35 -0600 Subject: [PATCH 07/29] Remove UNSET from list of soil_layerstruct_predefined valid_values --- bld/namelist_files/namelist_definition_ctsm.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 8380596a8c..3a6678c9b8 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -115,13 +115,12 @@ Otherwise use the fraction straight up (the default for CLM5.0) + group="clm_inparm" valid_values="10SL_3.5m,23SL_3.5m,49SL_10m,20SL_8.5m,4SL_2m" > 10SL_3.5m = standard CLM4 and CLM4.5 version 23SL_3.5m = more vertical layers for permafrost simulations 49SL_10m = 49 layer soil column, 10m of soil, 5 bedrock layers 20SL_8.5m = 20 layer soil column, 8m of soil, 5 bedrock layers 4SL_2m = 4 layer soil column, 2m of soil, 0 bedrock layers -UNSET = required when setting soil_layerstruct_userdefined in clm5 Date: Wed, 17 Jul 2019 18:24:59 -0600 Subject: [PATCH 08/29] Introduce new test-suite tests Also update error checks in CLMBuildNamelist.pm and update the ChangeLog --- bld/CLMBuildNamelist.pm | 8 +------ cime_config/testdefs/testlist_clm.xml | 16 ++++++++++++-- .../README | 10 --------- .../user_nl_clm | 9 -------- .../testmods_dirs/clm/soil_layerstruct/README | 5 +++++ .../include_user_mods | 0 .../clm/soil_layerstruct/user_nl_clm | 2 ++ doc/ChangeLog | 21 +++++++++++++------ doc/ChangeSum | 2 +- 9 files changed, 38 insertions(+), 35 deletions(-) delete mode 100644 cime_config/testdefs/testmods_dirs/clm/rm_indiv_lunits_and_collapse_to_dom/README delete mode 100644 cime_config/testdefs/testmods_dirs/clm/rm_indiv_lunits_and_collapse_to_dom/user_nl_clm create mode 100644 cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/README rename cime_config/testdefs/testmods_dirs/clm/{rm_indiv_lunits_and_collapse_to_dom => soil_layerstruct}/include_user_mods (100%) create mode 100644 cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/user_nl_clm diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 64a2325f27..6d04d01da9 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -2100,15 +2100,9 @@ sub setup_logic_soilstate { if (defined($soil_layerstruct_userdefined)) { if (defined($soil_layerstruct_predefined)) { $log->fatal_error("You have set both soil_layerstruct_userdefined and soil_layerstruct_predefined in your namelist; model cannot determine which to use"); - } else { - my $group = $definition->get_group_name($var1); - $nl->set_variable_value($group, $var1, 'UNSET' ); } } else { - if (defined($soil_layerstruct_predefined)) { - my $group = $definition->get_group_name($var2); - $nl->set_variable_value($group, $var2, -9999999.); - } else { + if (not defined($soil_layerstruct_predefined)) { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'soil_layerstruct_predefined', 'structure'=>$nl_flags->{'structure'}); } diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 8966bacc3d..2b8478f305 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -787,13 +787,13 @@ - + - + @@ -1667,6 +1667,18 @@ + + + + + + + + + + + + diff --git a/cime_config/testdefs/testmods_dirs/clm/rm_indiv_lunits_and_collapse_to_dom/README b/cime_config/testdefs/testmods_dirs/clm/rm_indiv_lunits_and_collapse_to_dom/README deleted file mode 100644 index 15d6992b29..0000000000 --- a/cime_config/testdefs/testmods_dirs/clm/rm_indiv_lunits_and_collapse_to_dom/README +++ /dev/null @@ -1,10 +0,0 @@ -This test -1) Keeps landunits with areas exceeding the correspondng "toosmall_*" namelist - thresholds and removes the rest -2) Collapses unmanaged pfts to the 2 dominant ones -3) Collapses urban landunits to the dominant landunit -4) Collapses all landunits to the two dominant ones - -All this simplifies the gridcell representation so as to run faster. - -NB: This test is testing the 10x15 resolution only. diff --git a/cime_config/testdefs/testmods_dirs/clm/rm_indiv_lunits_and_collapse_to_dom/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/rm_indiv_lunits_and_collapse_to_dom/user_nl_clm deleted file mode 100644 index 1ed05f191b..0000000000 --- a/cime_config/testdefs/testmods_dirs/clm/rm_indiv_lunits_and_collapse_to_dom/user_nl_clm +++ /dev/null @@ -1,9 +0,0 @@ -toosmall_soil = 5.0 -toosmall_crop = 5.0 -toosmall_glacier = 5.0 -toosmall_lake = 5.0 -toosmall_wetland = 5.0 -toosmall_urban = 5.0 -n_dom_pfts = 2 -n_dom_landunits = 2 -collapse_urban = .true. diff --git a/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/README b/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/README new file mode 100644 index 0000000000..12c758c02b --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/README @@ -0,0 +1,5 @@ +This test sets soil_layerstruct_userdefined to the dzsoi values of the +predefined case 4SL_2m and checks for bfb same answers. + + +NB: This test is testing the 10x15 resolution only. diff --git a/cime_config/testdefs/testmods_dirs/clm/rm_indiv_lunits_and_collapse_to_dom/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/include_user_mods similarity index 100% rename from cime_config/testdefs/testmods_dirs/clm/rm_indiv_lunits_and_collapse_to_dom/include_user_mods rename to cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/include_user_mods diff --git a/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/user_nl_clm new file mode 100644 index 0000000000..a90b5356dd --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/user_nl_clm @@ -0,0 +1,2 @@ +nlevsoinl = 4 +soil_layerstruct_userdefined = 0.1d0,0.3d0,0.6d0,1.0d0,1.0d0 diff --git a/doc/ChangeLog b/doc/ChangeLog index e46ccea253..67751ee127 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,7 +1,7 @@ =============================================================== Tag name: ctsm1.0.dev051 Originator(s): slevis (Samuel Levis,SLevis Consulting LLC,303-665-1310) -Date: Mon Jul 15 12:13:39 MDT 2019 +Date: Wed Jul 17 17:55:52 MDT 2019 One-line Summary: Soil layer definition clean-up and user-defined option Purpose of changes @@ -11,7 +11,7 @@ Purpose of changes definition: the node-based and the thickness-based. User-defined option allows user to specify a soil layer profile in the - form of a vector of dzsoi values in meters in the thickness-based + form of a dzsoi vector (values in meters) in the thickness-based approach. @@ -20,7 +20,7 @@ Bugs fixed or introduced Issues fixed (include CTSM Issue #): #279 #728 -Known bugs found since the previous tag (include github issue ID): #761 and bug in this PR (#759) causing model to abort when nlevsoi = nlevgrnd +Known bugs found since the previous tag (include github issue ID): #759 (this PR) bug causes model to abort when nlevsoi = nlevgrnd; bug has been corrected with an error check Significant changes to scientifically-supported configurations @@ -40,11 +40,11 @@ Does this tag change answers significantly for any of the following physics conf Notes of particular relevance for users --------------------------------------- -Caveats for users (e.g., need to interpolate initial conditions): specify at least one, either soil_layerstruct_predefined or soil_layerstruct_userdefined in the namelist +Caveats for users (e.g., need to interpolate initial conditions): if neither soil_layerstruct_predefined nor soil_layerstruct_userdefined get specified in the namelist, then the model sets soil_layerstruct_predefined to the old default setting for soil_layerstruct, i.e. 20SL_8.5m Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables): renamed soil_layerstruct to soil_layerstruct_predefined and added soil_layerstruct_userdefined -Changes made to namelist defaults (e.g., changed parameter values): soil_layerstruct_predefined clm5 default changed from 20SL_8.5m to UNSET +Changes made to namelist defaults (e.g., changed parameter values): none Changes to the datasets (e.g., parameter, surface or initial files): none @@ -56,7 +56,16 @@ NOTE: Be sure to review the steps in README.CHECKLIST.master_tags as well as the Caveats for developers (e.g., code that is duplicated that requires double maintenance): none -Changes to tests or testing: TEST(S) ADDED TO THE TEST SUITE. Also specified soil_layerstruct_predefined in all pre-existing tests in the test suite. +Changes to tests or testing: + 1) New test... + ERP_P36x2_D_Ld5.f10_f10_musgs.I2000Ctsm50NwpBgcCropGswpGs.cheyenne_intel.clm-default + replaces existing test + ERS_D_Ld10.f10_f10_musgs.I2000Clm50BgcCropGs.cheyenne_intel.clm-rm_indiv_lunits_and_collapse_to_dom + to check the correction described in known bugs above. The new test together with existing unit tests cover what the old test was testing. + + 2) New test... + ERS_D_Ld5.f10_f10_musgs.I2000Clm50BgcCropGs.cheyenne_intel.clm-soil_layerstruct + ensures that soil_layerstruct_userdefined will give bfb same answers as soil_layerstruct_predefined = '4SL_2m' when set with the same dzsoi values Code reviewed by: @billsacks diff --git a/doc/ChangeSum b/doc/ChangeSum index 836b109fa9..7542deef32 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,6 +1,6 @@ Tag Who Date Summary ============================================================================================================================ - ctsm1.0.dev051 slevis 07/15/2019 Soil layer definition clean-up and user-defined option + ctsm1.0.dev051 slevis 07/17/2019 Soil layer definition clean-up and user-defined option ctsm1.0.dev050 slevis 07/15/2019 dz --> dz_lake bug-fix in LakeTemperatureMod.F90 line 960 ctsm1.0.dev049 erik 06/23/2019 Update mosart and intel to intel-19 on cheyenne ctsm1.0.dev048 erik 06/23/2019 Updates for buildlib changes and cime and externals updates From a47e3cb289f9fd80923f65207ca0f5d3b94dd6de Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 18 Jul 2019 13:41:43 -0600 Subject: [PATCH 09/29] Changed new test from ERS to ERP_P36x2 --- cime_config/testdefs/testlist_clm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 2b8478f305..e62cccbcba 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -787,7 +787,7 @@ - + From d4ba7f5451a0d1756cd6770da0e0b7c824638c7e Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 22 Jul 2019 12:13:07 -0600 Subject: [PATCH 10/29] Revisions in /bld directory based on @billsacks' comments --- bld/CLMBuildNamelist.pm | 9 ++++++++- bld/namelist_files/namelist_defaults_ctsm.xml | 3 --- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 6d04d01da9..b8e614a71f 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -2094,15 +2094,22 @@ sub setup_logic_soilstate { my $var1 = "soil_layerstruct_predefined"; my $var2 = "soil_layerstruct_userdefined"; + my $var3 = "nlevsoinl"; my $soil_layerstruct_predefined = $nl->get_value($var1); my $soil_layerstruct_userdefined = $nl->get_value($var2); + my $nlevsoinl = $nl->get_value($var3); if (defined($soil_layerstruct_userdefined)) { if (defined($soil_layerstruct_predefined)) { $log->fatal_error("You have set both soil_layerstruct_userdefined and soil_layerstruct_predefined in your namelist; model cannot determine which to use"); } + if (not defined($nlevsoinl)) { + $log->fatal_error("You have set soil_layerstruct_userdefined and NOT set nlevsoinl in your namelist; both MUST be set"); + } } else { - if (not defined($soil_layerstruct_predefined)) { + if (defined($nlevsoinl)) { + $log->fatal_error("You have set nlevsoinl and NOT set soil_layerstruct_userdefined in your namelist; EITHER set both OR neither; in the latter case soil_layerstruct_predefined will be assigned a default value"); + } else { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'soil_layerstruct_predefined', 'structure'=>$nl_flags->{'structure'}); } diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index d02070060b..d024a8cf43 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -129,9 +129,6 @@ attributes from the config_cache.xml file (with keys converted to upper-case). 20SL_8.5m 10SL_3.5m --9999999._r8 --9999999 - .false. .false. .true. From 63fdbd4297f45f889e8f143f5c132e55356b4a57 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 22 Jul 2019 18:18:52 -0600 Subject: [PATCH 11/29] Revisions (part 2) in response to @billsacks review --- bld/CLMBuildNamelist.pm | 12 +++--- .../namelist_definition_ctsm.xml | 4 +- cime_config/config_compsets.xml | 5 +++ .../clm/soil_layerstruct/user_nl_clm | 2 +- doc/ChangeLog | 27 +++++++++--- src/main/clm_varctl.F90 | 2 +- src/main/clm_varpar.F90 | 11 +++-- src/main/controlMod.F90 | 6 +-- src/main/initVerticalMod.F90 | 42 +++++++++++++------ 9 files changed, 76 insertions(+), 35 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index b8e614a71f..1ca5bebdc7 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -2094,21 +2094,21 @@ sub setup_logic_soilstate { my $var1 = "soil_layerstruct_predefined"; my $var2 = "soil_layerstruct_userdefined"; - my $var3 = "nlevsoinl"; + my $var3 = "soil_layerstruct_userdefined_nlevsoi"; my $soil_layerstruct_predefined = $nl->get_value($var1); my $soil_layerstruct_userdefined = $nl->get_value($var2); - my $nlevsoinl = $nl->get_value($var3); + my $soil_layerstruct_userdefined_nlevsoi = $nl->get_value($var3); if (defined($soil_layerstruct_userdefined)) { if (defined($soil_layerstruct_predefined)) { $log->fatal_error("You have set both soil_layerstruct_userdefined and soil_layerstruct_predefined in your namelist; model cannot determine which to use"); } - if (not defined($nlevsoinl)) { - $log->fatal_error("You have set soil_layerstruct_userdefined and NOT set nlevsoinl in your namelist; both MUST be set"); + if (not defined($soil_layerstruct_userdefined_nlevsoi)) { + $log->fatal_error("You have set soil_layerstruct_userdefined and NOT set soil_layerstruct_userdefined_nlevsoi in your namelist; both MUST be set"); } } else { - if (defined($nlevsoinl)) { - $log->fatal_error("You have set nlevsoinl and NOT set soil_layerstruct_userdefined in your namelist; EITHER set both OR neither; in the latter case soil_layerstruct_predefined will be assigned a default value"); + if (defined($soil_layerstruct_userdefined_nlevsoi)) { + $log->fatal_error("You have set soil_layerstruct_userdefined_nlevsoi and NOT set soil_layerstruct_userdefined in your namelist; EITHER set both OR neither; in the latter case soil_layerstruct_predefined will be assigned a default value"); } else { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'soil_layerstruct_predefined', 'structure'=>$nl_flags->{'structure'}); diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 3a6678c9b8..6e85a95fd4 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -125,11 +125,11 @@ Otherwise use the fraction straight up (the default for CLM5.0) -User-defined vector of dzsoi. The length of this vector determines nlevgrnd. When the user sets this vector, they have to set nlevsoinl in the namelist, too; nlevsoinl must be less than nlevgrnd in this version of the model, even though ideally nlevsoinl could also equal nlevgrnd. +User-defined vector of dzsoi. The length of this vector determines nlevgrnd. When the user sets this vector, they have to set soil_layerstruct_userdefined_nlevsoi in the namelist, too; soil_layerstruct_userdefined_nlevsoi must be less than nlevgrnd in this version of the model, even though ideally soil_layerstruct_userdefined_nlevsoi could also equal nlevgrnd. Default: rundef - User-defined number of soil layers required to be set in the namelist when the user sets soil_layerstruct_userdefined in the namelist. Default: iundef diff --git a/cime_config/config_compsets.xml b/cime_config/config_compsets.xml index e0acc4f4f3..f807de2d3f 100644 --- a/cime_config/config_compsets.xml +++ b/cime_config/config_compsets.xml @@ -248,6 +248,11 @@ 2000_DATM%GSWP3v1_CLM50%NWP-SP_SICE_SOCN_MOSART_SGLC_SWAV + + I2000Ctsm50NwpBgcCropGswpGs + 2000_DATM%GSWP3v1_CLM50%NWP-BGC-CROP_SICE_SOCN_MOSART_SGLC_SWAV + + diff --git a/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/user_nl_clm index a90b5356dd..9f7acb8ecf 100644 --- a/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/user_nl_clm @@ -1,2 +1,2 @@ -nlevsoinl = 4 +soil_layerstruct_userdefined_nlevsoi = 4 soil_layerstruct_userdefined = 0.1d0,0.3d0,0.6d0,1.0d0,1.0d0 diff --git a/doc/ChangeLog b/doc/ChangeLog index a7569fc647..300edf9f29 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -14,13 +14,17 @@ Purpose of changes form of a dzsoi vector (values in meters) in the thickness-based approach. + Default nlevsoi for NWP configurations had to change from 5 to 4 for + consistency with the new error check described in known bugs below. Bugs fixed or introduced ------------------------ Issues fixed (include CTSM Issue #): #279 #728 -Known bugs found since the previous tag (include github issue ID): #759 (this PR) bug causes model to abort when nlevsoi = nlevgrnd; bug has been corrected with an error check +Known bugs found since the previous tag (include github issue ID): + #759 (this PR) bug causes model to abort when nlevsoi = nlevgrnd; + bug has been corrected with an error check Significant changes to scientifically-supported configurations @@ -40,11 +44,19 @@ Does this tag change answers significantly for any of the following physics conf Notes of particular relevance for users --------------------------------------- -Caveats for users (e.g., need to interpolate initial conditions): if neither soil_layerstruct_predefined nor soil_layerstruct_userdefined get specified in the namelist, then the model sets soil_layerstruct_predefined to the old default setting for soil_layerstruct, i.e. 20SL_8.5m +Caveats for users (e.g., need to interpolate initial conditions): + if neither soil_layerstruct_predefined nor soil_layerstruct_userdefined + get specified in the namelist, then the model sets + soil_layerstruct_predefined to the old default setting for + soil_layerstruct, i.e. 20SL_8.5m -Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables): renamed soil_layerstruct to soil_layerstruct_predefined and added soil_layerstruct_userdefined +Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables): + renamed soil_layerstruct to soil_layerstruct_predefined and added + soil_layerstruct_userdefined -Changes made to namelist defaults (e.g., changed parameter values): none +Changes made to namelist defaults (e.g., changed parameter values): + Default nlevsoi for NWP configurations had to change from 5 to 4 for + consistency with the new error check described in known bugs below Changes to the datasets (e.g., parameter, surface or initial files): none @@ -61,11 +73,14 @@ Changes to tests or testing: ERP_P36x2_D_Ld5.f10_f10_musgs.I2000Ctsm50NwpBgcCropGswpGs.cheyenne_intel.clm-default replaces existing test ERS_D_Ld10.f10_f10_musgs.I2000Clm50BgcCropGs.cheyenne_intel.clm-rm_indiv_lunits_and_collapse_to_dom - to check the correction described in known bugs above. The new test together with existing unit tests cover what the old test was testing. + to check the correction described in known bugs above; the new test + together with existing unit tests cover what the old test was testing 2) New test... ERS_D_Ld5.f10_f10_musgs.I2000Clm50BgcCropGs.cheyenne_intel.clm-soil_layerstruct - ensures that soil_layerstruct_userdefined will give bfb same answers as soil_layerstruct_predefined = '4SL_2m' when set with the same dzsoi values + ensures that soil_layerstruct_userdefined will give bfb same answers + as soil_layerstruct_predefined = '4SL_2m' when set with the same dzsoi + values Code reviewed by: @billsacks diff --git a/src/main/clm_varctl.F90 b/src/main/clm_varctl.F90 index 5e957ab898..0b100af1cf 100644 --- a/src/main/clm_varctl.F90 +++ b/src/main/clm_varctl.F90 @@ -266,7 +266,7 @@ module clm_varctl logical, public :: use_bedrock = .false. ! true => use spatially variable soil depth character(len=16), public :: soil_layerstruct_predefined = 'UNSET' real(r8), public :: soil_layerstruct_userdefined(99) = rundef - integer, public :: nlevsoinl = iundef + integer, public :: soil_layerstruct_userdefined_nlevsoi = iundef !---------------------------------------------------------- ! plant hydraulic stress switch diff --git a/src/main/clm_varpar.F90 b/src/main/clm_varpar.F90 index f904efd3bd..6d0e7b6bd6 100644 --- a/src/main/clm_varpar.F90 +++ b/src/main/clm_varpar.F90 @@ -11,8 +11,10 @@ module clm_varpar use clm_varctl , only: use_extralakelayers, use_vertsoilc use clm_varctl , only: use_century_decomp, use_c13, use_c14 use clm_varctl , only: iulog, use_crop, create_crop_landunit, irrigate - use clm_varctl , only: use_vichydro, nlevsoinl, rundef - use clm_varctl , only: soil_layerstruct_predefined, soil_layerstruct_userdefined + use clm_varctl , only: use_vichydro, rundef + use clm_varctl , only: soil_layerstruct_predefined + use clm_varctl , only: soil_layerstruct_userdefined + use clm_varctl , only: soil_layerstruct_userdefined_nlevsoi use clm_varctl , only: use_fates ! @@ -153,6 +155,7 @@ subroutine clm_varpar_init(actual_maxsoil_patches, actual_numcft) call shr_sys_abort(subname//' ERROR: Cannot decide how to set the soil layer structure') else nlevgrnd = size(soil_layerstruct_userdefined) + ! loops backwards until it hits the last valid user-defined value do j = nlevgrnd,1,-1 if (soil_layerstruct_userdefined(j) /= rundef) then exit @@ -160,9 +163,9 @@ subroutine clm_varpar_init(actual_maxsoil_patches, actual_numcft) nlevgrnd = nlevgrnd - 1 end if end do - nlevsoi = nlevsoinl ! value read in namelist + nlevsoi = soil_layerstruct_userdefined_nlevsoi ! read in namelist if (nlevsoi >= nlevgrnd) then - write(iulog,*) subname//' ERROR: nlevsoi >= nlevgrnd; did you enter nlevsoinl correctly in user_nl_clm?' + write(iulog,*) subname//' ERROR: nlevsoi >= nlevgrnd; did you enter soil_layerstruct_userdefined_nlevsoi correctly in user_nl_clm?' call shr_sys_abort(subname//' ERROR: nlevsoi must be less than nlevgrnd') end if end if diff --git a/src/main/controlMod.F90 b/src/main/controlMod.F90 index ecc9ba7281..3caea85a35 100644 --- a/src/main/controlMod.F90 +++ b/src/main/controlMod.F90 @@ -204,7 +204,7 @@ subroutine control_init( ) clump_pproc, wrtdia, & create_crop_landunit, nsegspc, co2_ppmv, override_nsrest, & albice, soil_layerstruct_predefined, soil_layerstruct_userdefined, & - nlevsoinl, subgridflag, & + soil_layerstruct_userdefined_nlevsoi, subgridflag, & irrigate, run_zero_weight_urban, all_active, & crop_fsat_equals_zero @@ -815,7 +815,7 @@ subroutine control_spmd() call mpi_bcast (albice, 2, MPI_REAL8,0, mpicom, ier) call mpi_bcast (soil_layerstruct_predefined,len(soil_layerstruct_predefined), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (soil_layerstruct_userdefined,size(soil_layerstruct_userdefined), MPI_REAL8, 0, mpicom, ier) - call mpi_bcast (nlevsoinl, 1, MPI_INTEGER, 0, mpicom, ier) + call mpi_bcast (soil_layerstruct_userdefined_nlevsoi, 1, MPI_INTEGER, 0, mpicom, ier) ! snow pack variables call mpi_bcast (nlevsno, 1, MPI_INTEGER, 0, mpicom, ier) @@ -1033,7 +1033,7 @@ subroutine control_print () write(iulog,*) ' land-ice albedos (unitless 0-1) = ', albice write(iulog,*) ' pre-defined soil layer structure = ', soil_layerstruct_predefined write(iulog,*) ' user-defined soil layer structure = ', soil_layerstruct_userdefined - write(iulog,*) ' user-defined number of soil layers = ', nlevsoinl + write(iulog,*) ' user-defined number of soil layers = ', soil_layerstruct_userdefined_nlevsoi write(iulog,*) ' plant hydraulic stress = ', use_hydrstress write(iulog,*) ' dynamic roots = ', use_dynroot if (nsrest == nsrContinue) then diff --git a/src/main/initVerticalMod.F90 b/src/main/initVerticalMod.F90 index 956dbb2160..eef64a6aa5 100644 --- a/src/main/initVerticalMod.F90 +++ b/src/main/initVerticalMod.F90 @@ -17,7 +17,7 @@ module initVerticalMod use clm_varpar , only : nlevsoi, nlevsoifl, nlevurb use clm_varctl , only : fsurdat, iulog use clm_varctl , only : use_vancouver, use_mexicocity, use_vertsoilc, use_extralakelayers - use clm_varctl , only : use_bedrock, nlevsoinl, rundef + use clm_varctl , only : use_bedrock, rundef use clm_varctl , only : soil_layerstruct_predefined, soil_layerstruct_userdefined use clm_varctl , only : use_fates use clm_varcon , only : zlak, dzlak, zsoi, dzsoi, zisoi, dzsoi_decomp, spval, ispval, grlnd @@ -216,13 +216,28 @@ subroutine initVertical(bounds, glc_behavior, snow_depth, thick_wall, thick_roof ! "0" refers to soil surface and "nlevsoi" refers to the bottom of model soil if (soil_layerstruct_predefined == '10SL_3.5m' .or. soil_layerstruct_predefined == '23SL_3.5m') then - calc_method = 'node-based' + calc_method = 'node-based' ! node-based followed by error check + if (soil_layerstruct_userdefined(1) /= rundef) then + write(iulog,*) subname//' ERROR: Both soil_layerstruct_predefined and soil_layer_userdefined have values' + call shr_sys_abort(subname//' ERROR: Cannot decide how to set the soil layer structure') + end if + ! thickness-based (part 1) and error check else if (soil_layerstruct_predefined == '49SL_10m' .or. & soil_layerstruct_predefined == '20SL_8.5m' .or. & - soil_layerstruct_predefined == '4SL_2m' .or. & - soil_layerstruct_userdefined(1) /= rundef) then + soil_layerstruct_predefined == '4SL_2m') then calc_method = 'thickness-based' - else + if (soil_layerstruct_userdefined(1) /= rundef) then + write(iulog,*) subname//' ERROR: Both soil_layerstruct_predefined and soil_layer_userdefined have values' + call shr_sys_abort(subname//' ERROR: Cannot decide how to set the soil layer structure') + end if + ! thickness-based (part 2) and error check + else if (soil_layerstruct_userdefined(1) /= rundef) then + calc_method = 'thickness-based' + if (soil_layerstruct_predefined /= 'UNSET') then + write(iulog,*) subname//' ERROR: Both soil_layerstruct_predefined and soil_layer_userdefined have values' + call shr_sys_abort(subname//' ERROR: Cannot decide how to set the soil layer structure') + end if + else ! error check write(iulog,*) subname//' ERROR: Unrecognized pre-defined and user-defined soil layer structures: ', trim(soil_layerstruct_predefined), soil_layerstruct_userdefined call endrun(subname//' ERROR: Unrecognized soil layer structure') end if @@ -260,7 +275,12 @@ subroutine initVertical(bounds, glc_behavior, snow_depth, thick_wall, thick_roof zisoi(nlevgrnd) = zsoi(nlevgrnd) + 0.5_r8*dzsoi(nlevgrnd) else if (calc_method == 'thickness-based') then - if (soil_layerstruct_predefined == '49SL_10m') then + if (soil_layerstruct_userdefined(1) /= rundef) then + do j = 1, nlevgrnd + ! read dzsoi from user-entered namelist vector + dzsoi(j) = soil_layerstruct_userdefined(j) + end do + else if (soil_layerstruct_predefined == '49SL_10m') then !scs: 10 meter soil column, nlevsoi set to 49 in clm_varpar do j = 1, 10 dzsoi(j) = 1.e-2_r8 ! 10-mm layers @@ -293,11 +313,6 @@ subroutine initVertical(bounds, glc_behavior, snow_depth, thick_wall, thick_roof dzsoi(3) = 0.6_r8 dzsoi(4) = 1.0_r8 dzsoi(5) = 1.0_r8 - else if (soil_layerstruct_userdefined(1) /= rundef) then - do j = 1, nlevgrnd - ! read dzsoi from user-entered namelist vector - dzsoi(j) = soil_layerstruct_userdefined(j) - end do end if ! thickness-based options zisoi(0) = 0._r8 @@ -309,7 +324,10 @@ subroutine initVertical(bounds, glc_behavior, snow_depth, thick_wall, thick_roof zsoi(j) = 0.5*(zisoi(j-1) + zisoi(j)) enddo - end if + else ! error check + write(iulog,*) subname//' ERROR: Unrecognized calc_method: ', trim(calc_method) + call endrun(subname//' ERROR: Unrecognized calc_method') + end if ! calc_method is node-based or thickness-based ! define a vertical grid spacing such that it is the normal dzsoi if ! nlevdecomp =nlevgrnd, or else 1 meter From 260e9ebfbe6ecb40fa1d0421642373e6c389a75d Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 23 Jul 2019 15:54:05 -0600 Subject: [PATCH 12/29] Change new soil_layerstruct test from ERP to SOILSTRUCTUD Introducing new test type SOILSTRUCTUD that runs the model twice: 1) with user-defined dzsoil matching the 4SL_2m predefined values 2) with the 4SL_2m predefined option and compares the output looking for bfb identical results. --- cime_config/SystemTests/soilstructud.py | 37 +++++++++++++++++++ cime_config/config_tests.xml | 10 +++++ cime_config/testdefs/testlist_clm.xml | 2 +- .../testmods_dirs/clm/soil_layerstruct/README | 5 +++ .../clm/soil_layerstruct/user_nl_clm | 2 - 5 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 cime_config/SystemTests/soilstructud.py delete mode 100644 cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/user_nl_clm diff --git a/cime_config/SystemTests/soilstructud.py b/cime_config/SystemTests/soilstructud.py new file mode 100644 index 0000000000..c59ab8b4f6 --- /dev/null +++ b/cime_config/SystemTests/soilstructud.py @@ -0,0 +1,37 @@ +""" +Implementation of the CIME SOILSTRUCTUD test. + +This is a CLM specific test: +Verifies that a simulation that points to user_nl_clm containing +soil_layerstruct_userdefined_nlevsoi = 4 +soil_layerstruct_userdefined = 0.1d0,0.3d0,0.6d0,1.0d0,1.0d0 +gives bfb same results as one that points to user_nl_clm containing +soil_layerstruct_predefined = '4SL_2m' + +""" + +from CIME.SystemTests.system_tests_compare_two import SystemTestsCompareTwo +from CIME.XML.standard_module_setup import * +from CIME.SystemTests.test_utils.user_nl_utils import append_to_user_nl_files + +logger = logging.getLogger(__name__) + +class SOILSTRUCTUD(SystemTestsCompareTwo): + + def __init__(self, case): + SystemTestsCompareTwo.__init__(self, case, + separate_builds = False, + run_two_suffix = '4SL_2m', + run_one_description = 'soil_layerstruct_userdefined', + run_two_description = 'soil_layerstruct_predefined') + + def _case_one_setup(self): + append_to_user_nl_files(caseroot = self._get_caseroot(), + component = "clm", + contents = "soil_layerstruct_userdefined_nlevsoi = 4,soil_layerstruct_userdefined = 0.1d0,0.3d0,0.6d0,1.0d0,1.0d0") + + def _case_two_setup(self): + append_to_user_nl_files(caseroot = self._get_caseroot(), + component = "clm", + contents = "soil_layerstruct_predefined = '4SL_2m'") + diff --git a/cime_config/config_tests.xml b/cime_config/config_tests.xml index dbcd59eb6c..2d86e3b71d 100644 --- a/cime_config/config_tests.xml +++ b/cime_config/config_tests.xml @@ -87,4 +87,14 @@ SSP smoke CLM spinup test (only valid for CLM compsets with CLM45) $STOP_N + + CLM user-defined soil structure test + 1 + FALSE + FALSE + never + $STOP_OPTION + $STOP_N + + diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 5d2e77ea49..99394084e5 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -787,7 +787,7 @@ - + diff --git a/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/README b/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/README index 12c758c02b..b9ca48dc1c 100644 --- a/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/README +++ b/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/README @@ -1,5 +1,10 @@ This test sets soil_layerstruct_userdefined to the dzsoi values of the predefined case 4SL_2m and checks for bfb same answers. +This is done by +(a) listing the test in (1) testlist_clm.xml (as all tests) and + (2) config_tests.xml +(b) creating the file .../cime_config/SystemTests/soilstructud.py +named after the test in lower case NB: This test is testing the 10x15 resolution only. diff --git a/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/user_nl_clm deleted file mode 100644 index 9f7acb8ecf..0000000000 --- a/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/user_nl_clm +++ /dev/null @@ -1,2 +0,0 @@ -soil_layerstruct_userdefined_nlevsoi = 4 -soil_layerstruct_userdefined = 0.1d0,0.3d0,0.6d0,1.0d0,1.0d0 From 1bc0f1d43e719426becf1e707560f3fe2b3e3f69 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 24 Jul 2019 16:13:37 -0600 Subject: [PATCH 13/29] Repl. soil_layerstruct_predefined /= '10SL_3.5m' w organic_frac_squared Committing and pushing from cheyenne so as to pull on hobart and perform tests while cheyenne's compute nodes are unavailable. --- .../SoilHydrologyInitTimeConstMod.F90 | 38 ++++++++------ src/biogeophys/SoilStateInitTimeConstMod.F90 | 52 ++++++++++++------- 2 files changed, 54 insertions(+), 36 deletions(-) diff --git a/src/biogeophys/SoilHydrologyInitTimeConstMod.F90 b/src/biogeophys/SoilHydrologyInitTimeConstMod.F90 index 2a2142acd6..906fdc921d 100644 --- a/src/biogeophys/SoilHydrologyInitTimeConstMod.F90 +++ b/src/biogeophys/SoilHydrologyInitTimeConstMod.F90 @@ -48,6 +48,7 @@ subroutine SoilHydrologyInitTimeConst(bounds, soilhydrology_inst) use fileutils , only : getfil use organicFileMod , only : organicrd use ncdio_pio , only : file_desc_t, ncd_io, ncd_pio_openfile, ncd_pio_closefile + use SoilStateInitTimeConstMod, only: organic_frac_squared ! ! !ARGUMENTS: type(bounds_type) , intent(in) :: bounds @@ -152,6 +153,8 @@ subroutine SoilHydrologyInitTimeConst(bounds, soilhydrology_inst) end do end do +! slevis: Much of this code runs in SoilStateInitTimeConst first and +! repeats identically here allocate(sand3d(bounds%begg:bounds%endg,nlevsoifl)) allocate(clay3d(bounds%begg:bounds%endg,nlevsoifl)) allocate(organic3d(bounds%begg:bounds%endg,nlevsoifl)) @@ -198,7 +201,7 @@ subroutine SoilHydrologyInitTimeConst(bounds, soilhydrology_inst) zisoifl(nlevsoifl) = zsoifl(nlevsoifl) + 0.5_r8*dzsoifl(nlevsoifl) if ( masterproc )then - if ( soil_layerstruct_predefined /= '10SL_3.5m' ) write(iulog,*) 'Setting clay, sand, organic, in Soil Hydrology for VIC' + write(iulog,*) 'Setting clay, sand, organic, in Soil Hydrology for VIC' end if do c = bounds%begc, bounds%endc g = col%gridcell(c) @@ -211,17 +214,17 @@ subroutine SoilHydrologyInitTimeConst(bounds, soilhydrology_inst) ! do nothing else do lev = 1,nlevgrnd - if ( soil_layerstruct_predefined /= '10SL_3.5m' )then +! if ( soil_layerstruct_predefined /= '10SL_3.5m' )then if (lev .eq. 1) then clay = clay3d(g,1) sand = sand3d(g,1) - om_frac = organic3d(g,1)/organic_max + om_frac = organic3d(g,1)/organic_max else if (lev <= nlevsoi) then do j = 1,nlevsoifl-1 if (zisoi(lev) >= zisoifl(j) .AND. zisoi(lev) < zisoifl(j+1)) then clay = clay3d(g,j+1) sand = sand3d(g,j+1) - om_frac = organic3d(g,j+1)/organic_max + om_frac = organic3d(g,j+1)/organic_max endif end do else @@ -229,18 +232,21 @@ subroutine SoilHydrologyInitTimeConst(bounds, soilhydrology_inst) sand = sand3d(g,nlevsoifl) om_frac = 0._r8 endif - else - ! duplicate clay and sand values from 10th soil layer - if (lev <= nlevsoi) then - clay = clay3d(g,lev) - sand = sand3d(g,lev) - om_frac = (organic3d(g,lev)/organic_max)**2._r8 - else - clay = clay3d(g,nlevsoi) - sand = sand3d(g,nlevsoi) - om_frac = 0._r8 - endif - end if + if ( organic_frac_squared )then + om_frac = om_frac**2._r8 + end if +! else +! ! duplicate clay and sand values from 10th soil layer +! if (lev <= nlevsoi) then +! clay = clay3d(g,lev) +! sand = sand3d(g,lev) +! om_frac = (organic3d(g,lev)/organic_max)**2._r8 +! else +! clay = clay3d(g,nlevsoi) +! sand = sand3d(g,nlevsoi) +! om_frac = 0._r8 +! endif +! end if if (lun%urbpoi(l)) om_frac = 0._r8 claycol(c,lev) = clay diff --git a/src/biogeophys/SoilStateInitTimeConstMod.F90 b/src/biogeophys/SoilStateInitTimeConstMod.F90 index b5d0abd899..0bc7b92f86 100644 --- a/src/biogeophys/SoilStateInitTimeConstMod.F90 +++ b/src/biogeophys/SoilStateInitTimeConstMod.F90 @@ -21,7 +21,7 @@ module SoilStateInitTimeConstMod ! ! !PRIVATE DATA: ! Control variables (from namelist) - logical, private :: organic_frac_squared ! If organic fraction should be squared (as in CLM4.5) + logical, public :: organic_frac_squared ! If organic fraction should be squared (as in CLM4.5) character(len=*), parameter, private :: sourcefile = & __FILE__ @@ -358,6 +358,8 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) soilstate_inst%csol_col(c,lev)= spval end do +! slevis: Safer and more organized to make this else-if part of the if +! because the two codes are identical else if (lun%urbpoi(l) .and. (col%itype(c) /= icol_road_perv) .and. (col%itype(c) /= icol_road_imperv) )then ! Urban Roof, sunwall, shadewall properties set to special value @@ -389,17 +391,17 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) do lev = 1,nlevgrnd ! DML - this if statement could probably be removed and just the ! top part used for all soil layer structures - if ( soil_layerstruct_predefined /= '10SL_3.5m' )then ! apply soil texture from 10 layer input dataset +! if ( soil_layerstruct_predefined /= '10SL_3.5m' )then ! apply soil texture from 10 layer input dataset if (lev .eq. 1) then clay = clay3d(g,1) sand = sand3d(g,1) - om_frac = organic3d(g,1)/organic_max + om_frac = organic3d(g,1)/organic_max else if (lev <= nlevsoi) then do j = 1,nlevsoifl-1 if (zisoi(lev) >= zisoifl(j) .AND. zisoi(lev) < zisoifl(j+1)) then clay = clay3d(g,j+1) sand = sand3d(g,j+1) - om_frac = organic3d(g,j+1)/organic_max + om_frac = organic3d(g,j+1)/organic_max endif end do else @@ -407,22 +409,32 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) sand = sand3d(g,nlevsoifl) om_frac = 0._r8 endif - else - if (lev <= nlevsoi) then ! duplicate clay and sand values from 10th soil layer - clay = clay3d(g,lev) - sand = sand3d(g,lev) - if ( organic_frac_squared )then - om_frac = (organic3d(g,lev)/organic_max)**2._r8 - else - om_frac = organic3d(g,lev)/organic_max - end if - else - clay = clay3d(g,nlevsoi) - sand = sand3d(g,nlevsoi) - om_frac = 0._r8 - endif - end if - + if ( organic_frac_squared )then + om_frac = om_frac**2._r8 + end if +! else +! if (lev <= nlevsoi) then ! duplicate clay and sand values from 10th soil layer +! clay = clay3d(g,lev) +! sand = sand3d(g,lev) +! if ( organic_frac_squared )then +! om_frac = (organic3d(g,lev)/organic_max)**2._r8 +! else +! om_frac = organic3d(g,lev)/organic_max +! end if +! else +! clay = clay3d(g,nlevsoi) +! sand = sand3d(g,nlevsoi) +! om_frac = 0._r8 +! endif +! end if + +! slevis: Seems inconsistent and disorganized to have the next if-statmt +! here and then have it again in a separate do-loop a few lines +! down. I propose that we bring the lake section up here. +! slevis: Also I would pull out here the "No organic matter for urban" +! and consolidate the two identical codes repeated just below. +! slevis: This section runs before SoilHydrologyInitTimeConst, so let's +! also simplify codes there with data gathered here. if (lun%itype(l) == istdlak) then if (lev <= nlevsoi) then From 2618b2c938fd8487dde24bc2bc62879a1889b8e1 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 24 Jul 2019 18:10:29 -0600 Subject: [PATCH 14/29] Follow-up to last commit that gives bfb same answers as clm4.5 test Backed out part of the change in the last commit because answers changed --- .../SoilHydrologyInitTimeConstMod.F90 | 29 ++++++++--------- src/biogeophys/SoilStateInitTimeConstMod.F90 | 31 +++++++------------ 2 files changed, 25 insertions(+), 35 deletions(-) diff --git a/src/biogeophys/SoilHydrologyInitTimeConstMod.F90 b/src/biogeophys/SoilHydrologyInitTimeConstMod.F90 index 906fdc921d..1bc350b861 100644 --- a/src/biogeophys/SoilHydrologyInitTimeConstMod.F90 +++ b/src/biogeophys/SoilHydrologyInitTimeConstMod.F90 @@ -214,7 +214,7 @@ subroutine SoilHydrologyInitTimeConst(bounds, soilhydrology_inst) ! do nothing else do lev = 1,nlevgrnd -! if ( soil_layerstruct_predefined /= '10SL_3.5m' )then + if (.not. organic_frac_squared) then if (lev .eq. 1) then clay = clay3d(g,1) sand = sand3d(g,1) @@ -232,21 +232,18 @@ subroutine SoilHydrologyInitTimeConst(bounds, soilhydrology_inst) sand = sand3d(g,nlevsoifl) om_frac = 0._r8 endif - if ( organic_frac_squared )then - om_frac = om_frac**2._r8 - end if -! else -! ! duplicate clay and sand values from 10th soil layer -! if (lev <= nlevsoi) then -! clay = clay3d(g,lev) -! sand = sand3d(g,lev) -! om_frac = (organic3d(g,lev)/organic_max)**2._r8 -! else -! clay = clay3d(g,nlevsoi) -! sand = sand3d(g,nlevsoi) -! om_frac = 0._r8 -! endif -! end if + else + ! duplicate clay and sand values from 10th soil layer + if (lev <= nlevsoi) then + clay = clay3d(g,lev) + sand = sand3d(g,lev) + om_frac = (organic3d(g,lev)/organic_max)**2._r8 + else + clay = clay3d(g,nlevsoi) + sand = sand3d(g,nlevsoi) + om_frac = 0._r8 + endif + end if if (lun%urbpoi(l)) om_frac = 0._r8 claycol(c,lev) = clay diff --git a/src/biogeophys/SoilStateInitTimeConstMod.F90 b/src/biogeophys/SoilStateInitTimeConstMod.F90 index 0bc7b92f86..e1050cc529 100644 --- a/src/biogeophys/SoilStateInitTimeConstMod.F90 +++ b/src/biogeophys/SoilStateInitTimeConstMod.F90 @@ -391,7 +391,7 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) do lev = 1,nlevgrnd ! DML - this if statement could probably be removed and just the ! top part used for all soil layer structures -! if ( soil_layerstruct_predefined /= '10SL_3.5m' )then ! apply soil texture from 10 layer input dataset + if (.not. organic_frac_squared) then if (lev .eq. 1) then clay = clay3d(g,1) sand = sand3d(g,1) @@ -409,24 +409,17 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) sand = sand3d(g,nlevsoifl) om_frac = 0._r8 endif - if ( organic_frac_squared )then - om_frac = om_frac**2._r8 - end if -! else -! if (lev <= nlevsoi) then ! duplicate clay and sand values from 10th soil layer -! clay = clay3d(g,lev) -! sand = sand3d(g,lev) -! if ( organic_frac_squared )then -! om_frac = (organic3d(g,lev)/organic_max)**2._r8 -! else -! om_frac = organic3d(g,lev)/organic_max -! end if -! else -! clay = clay3d(g,nlevsoi) -! sand = sand3d(g,nlevsoi) -! om_frac = 0._r8 -! endif -! end if + else + if (lev <= nlevsoi) then ! duplicate clay and sand values from 10th soil layer + clay = clay3d(g,lev) + sand = sand3d(g,lev) + om_frac = (organic3d(g,lev)/organic_max)**2._r8 + else + clay = clay3d(g,nlevsoi) + sand = sand3d(g,nlevsoi) + om_frac = 0._r8 + endif + end if ! slevis: Seems inconsistent and disorganized to have the next if-statmt ! here and then have it again in a separate do-loop a few lines From eeead76534b547a95bba9f1934ef8e86894c34ef Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 24 Jul 2019 18:28:06 -0600 Subject: [PATCH 15/29] Consolidated code that repeated --- src/biogeophys/SoilStateInitTimeConstMod.F90 | 34 +++----------------- 1 file changed, 5 insertions(+), 29 deletions(-) diff --git a/src/biogeophys/SoilStateInitTimeConstMod.F90 b/src/biogeophys/SoilStateInitTimeConstMod.F90 index e1050cc529..528eef5dc0 100644 --- a/src/biogeophys/SoilStateInitTimeConstMod.F90 +++ b/src/biogeophys/SoilStateInitTimeConstMod.F90 @@ -333,7 +333,11 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) g = col%gridcell(c) l = col%landunit(c) - if (lun%itype(l)==istwet .or. lun%itype(l)==istice_mec) then + ! istwet and istice_mec and + ! urban roof, sunwall, shadewall properties set to special value + if (lun%itype(l)==istwet .or. lun%itype(l)==istice_mec .or. & + (lun%urbpoi(l) .and. col%itype(c) /= icol_road_perv .and. & + col%itype(c) /= icol_road_imperv)) then do lev = 1,nlevgrnd soilstate_inst%bsw_col(c,lev) = spval @@ -358,34 +362,6 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) soilstate_inst%csol_col(c,lev)= spval end do -! slevis: Safer and more organized to make this else-if part of the if -! because the two codes are identical - else if (lun%urbpoi(l) .and. (col%itype(c) /= icol_road_perv) .and. (col%itype(c) /= icol_road_imperv) )then - - ! Urban Roof, sunwall, shadewall properties set to special value - do lev = 1,nlevgrnd - soilstate_inst%watsat_col(c,lev) = spval - soilstate_inst%watfc_col(c,lev) = spval - soilstate_inst%bsw_col(c,lev) = spval - soilstate_inst%hksat_col(c,lev) = spval - soilstate_inst%sucsat_col(c,lev) = spval - soilstate_inst%watdry_col(c,lev) = spval - soilstate_inst%watopt_col(c,lev) = spval - soilstate_inst%bd_col(c,lev) = spval - if (lev <= nlevsoi) then - soilstate_inst%cellsand_col(c,lev) = spval - soilstate_inst%cellclay_col(c,lev) = spval - soilstate_inst%cellorg_col(c,lev) = spval - end if - end do - - do lev = 1,nlevgrnd - soilstate_inst%tkmg_col(c,lev) = spval - soilstate_inst%tksatu_col(c,lev) = spval - soilstate_inst%tkdry_col(c,lev) = spval - soilstate_inst%csol_col(c,lev) = spval - end do - else do lev = 1,nlevgrnd From 6b5259910af800898cf78f086548fb0f1523b976 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 25 Jul 2019 14:58:47 -0600 Subject: [PATCH 16/29] Changed new test to clm-default because its /testmods_dirs was empty --- cime_config/testdefs/testlist_clm.xml | 2 +- .../testdefs/testmods_dirs/clm/soil_layerstruct/README | 10 ---------- .../clm/soil_layerstruct/include_user_mods | 1 - doc/ChangeLog | 10 ++++++---- doc/ChangeSum | 2 +- 5 files changed, 8 insertions(+), 17 deletions(-) delete mode 100644 cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/README delete mode 100644 cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/include_user_mods diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 99394084e5..f68c877ed2 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -787,7 +787,7 @@ - + diff --git a/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/README b/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/README deleted file mode 100644 index b9ca48dc1c..0000000000 --- a/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/README +++ /dev/null @@ -1,10 +0,0 @@ -This test sets soil_layerstruct_userdefined to the dzsoi values of the -predefined case 4SL_2m and checks for bfb same answers. - -This is done by -(a) listing the test in (1) testlist_clm.xml (as all tests) and - (2) config_tests.xml -(b) creating the file .../cime_config/SystemTests/soilstructud.py -named after the test in lower case - -NB: This test is testing the 10x15 resolution only. diff --git a/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/include_user_mods deleted file mode 100644 index fe0e18cf88..0000000000 --- a/cime_config/testdefs/testmods_dirs/clm/soil_layerstruct/include_user_mods +++ /dev/null @@ -1 +0,0 @@ -../default diff --git a/doc/ChangeLog b/doc/ChangeLog index f8ee327b6d..de55211c9d 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,7 +1,7 @@ =============================================================== Tag name: ctsm1.0.dev053 Originator(s): slevis (Samuel Levis,SLevis Consulting LLC,303-665-1310) -Date: Tue Jul 23 16:14:53 MDT 2019 +Date: Thu Jul 25 14:57:31 MDT 2019 One-line Summary: Soil layer definition clean-up and user-defined option Purpose of changes @@ -48,7 +48,7 @@ Caveats for users (e.g., need to interpolate initial conditions): if neither soil_layerstruct_predefined nor soil_layerstruct_userdefined get specified in the namelist, then the model sets soil_layerstruct_predefined to the old default setting for - soil_layerstruct, i.e. 20SL_8.5m + soil_layerstruct (clm5: 20SL_8.5m, clm4.5: 10SL_3.5m) Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables): renamed soil_layerstruct to soil_layerstruct_predefined and added @@ -77,10 +77,12 @@ Changes to tests or testing: together with existing unit tests cover what the old test was testing 2) New test and new test type... - SOILSTRUCTUD_Ld5.f10_f10_musgs.I2000Clm50BgcCropGs.cheyenne_intel.clm-soil_layerstruct + SOILSTRUCTUD_Ld5.f10_f10_musgs.I2000Clm50BgcCropGs.cheyenne_intel.clm-default ensures that soil_layerstruct_userdefined gives bfb same answers as soil_layerstruct_predefined = '4SL_2m' when set with the same dzsoi - values + values. The new test type was put together by: + - listing the test in (1) testlist_clm.xml (as all tests) and (2) config_tests.xml + - creating the file .../cime_config/SystemTests/soilstructud.py named after the test in lower case Code reviewed by: @billsacks diff --git a/doc/ChangeSum b/doc/ChangeSum index 3fc9f0578b..10faee139b 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,6 +1,6 @@ Tag Who Date Summary ============================================================================================================================ - ctsm1.0.dev053 slevis 07/23/2019 Soil layer definition clean-up and user-defined option + ctsm1.0.dev053 slevis 07/25/2019 Soil layer definition clean-up and user-defined option ctsm1.0.dev052 sacks 07/22/2019 Fix rare soil color bug in mksurfdata_map ctsm1.0.dev051 sacks 07/19/2019 Update water tracers for remainder of first stage of hydrology ctsm1.0.dev050 slevis 07/15/2019 dz --> dz_lake bug-fix in LakeTemperatureMod.F90 line 960 From 2ce604de57eda19cb2e71ffdef2dcb5c7842913f Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 25 Jul 2019 17:25:17 -0600 Subject: [PATCH 17/29] Consilidating repetitive code intended for initializing VIC This test PASSes: ./create_test ERP_D_Ld5.f10_f10_musgs.I2000Clm50Vic.cheyenne_intel.clm-vrtlay -c /glade/p/cgd/tss/ctsm_baselines/ctsm1.0.dev052 --- .../SoilHydrologyInitTimeConstMod.F90 | 97 +++---------------- src/biogeophys/SoilStateInitTimeConstMod.F90 | 8 +- src/main/clm_instMod.F90 | 2 +- 3 files changed, 17 insertions(+), 90 deletions(-) diff --git a/src/biogeophys/SoilHydrologyInitTimeConstMod.F90 b/src/biogeophys/SoilHydrologyInitTimeConstMod.F90 index 1bc350b861..d9dc1fd071 100644 --- a/src/biogeophys/SoilHydrologyInitTimeConstMod.F90 +++ b/src/biogeophys/SoilHydrologyInitTimeConstMod.F90 @@ -8,10 +8,12 @@ module SoilHydrologyInitTimeConstMod use shr_kind_mod , only : r8 => shr_kind_r8 use shr_log_mod , only : errMsg => shr_log_errMsg use decompMod , only : bounds_type + use SoilStateType , only : soilstate_type use SoilHydrologyType , only : soilhydrology_type use WaterStateBulkType, only : waterstatebulk_type use LandunitType , only : lun use ColumnType , only : col + use SoilStateInitTimeConstMod, only: organic_max ! implicit none private @@ -31,7 +33,7 @@ module SoilHydrologyInitTimeConstMod contains !----------------------------------------------------------------------- - subroutine SoilHydrologyInitTimeConst(bounds, soilhydrology_inst) + subroutine SoilHydrologyInitTimeConst(bounds, soilhydrology_inst, soilstate_inst) ! ! !USES: use shr_const_mod , only : shr_const_pi @@ -53,6 +55,7 @@ subroutine SoilHydrologyInitTimeConst(bounds, soilhydrology_inst) ! !ARGUMENTS: type(bounds_type) , intent(in) :: bounds type(soilhydrology_type) , intent(inout) :: soilhydrology_inst + type(soilstate_type) , intent(in) :: soilstate_inst ! ! !LOCAL VARIABLES: integer :: p,c,j,l,g,lev,nlevs @@ -65,7 +68,6 @@ subroutine SoilHydrologyInitTimeConst(bounds, soilhydrology_inst) character(len=256) :: locfn real(r8) :: clay,sand ! temporaries real(r8) :: om_frac ! organic matter fraction - real(r8) :: organic_max ! organic matter (kg/m3) where soil is assumed to act like peat real(r8) ,pointer :: b2d (:) ! read in - VIC b real(r8) ,pointer :: ds2d (:) ! read in - VIC Ds real(r8) ,pointer :: dsmax2d (:) ! read in - VIC Dsmax @@ -153,56 +155,6 @@ subroutine SoilHydrologyInitTimeConst(bounds, soilhydrology_inst) end do end do -! slevis: Much of this code runs in SoilStateInitTimeConst first and -! repeats identically here - allocate(sand3d(bounds%begg:bounds%endg,nlevsoifl)) - allocate(clay3d(bounds%begg:bounds%endg,nlevsoifl)) - allocate(organic3d(bounds%begg:bounds%endg,nlevsoifl)) - - call organicrd(organic3d) - - call getfil (fsurdat, locfn, 0) - call ncd_pio_openfile (ncid, locfn, 0) - call ncd_io(ncid=ncid, varname='PCT_SAND', flag='read', data=sand3d, dim1name=grlnd, readvar=readvar) - if (.not. readvar) then - call endrun(msg=' ERROR: PCT_SAND NOT on surfdata file'//errMsg(sourcefile, __LINE__)) - end if - call ncd_io(ncid=ncid, varname='PCT_CLAY', flag='read', data=clay3d, dim1name=grlnd, readvar=readvar) - if (.not. readvar) then - call endrun(msg=' ERROR: PCT_CLAY NOT on surfdata file'//errMsg(sourcefile, __LINE__)) - end if - call ncd_pio_closefile(ncid) - - ! Determine organic_max - call getfil (paramfile, locfn, 0) - call ncd_pio_openfile (ncid, trim(locfn), 0) - call ncd_io(ncid=ncid, varname='organic_max', flag='read', data=organic_max, readvar=readvar) - if ( .not. readvar ) then - call endrun(msg=' ERROR: organic_max not on param file'//errMsg(sourcefile, __LINE__)) - end if - call ncd_pio_closefile(ncid) - - ! get original soil depths to be used in interpolation of sand and clay - allocate(zsoifl(1:nlevsoifl), zisoifl(0:nlevsoifl), dzsoifl(1:nlevsoifl)) - do j = 1, nlevsoifl - zsoifl(j) = 0.025*(exp(0.5_r8*(j-0.5_r8))-1._r8) !node depths - enddo - - dzsoifl(1) = 0.5_r8*(zsoifl(1)+zsoifl(2)) !thickness b/n two interfaces - do j = 2,nlevsoifl-1 - dzsoifl(j)= 0.5_r8*(zsoifl(j+1)-zsoifl(j-1)) - enddo - dzsoifl(nlevsoifl) = zsoifl(nlevsoifl)-zsoifl(nlevsoifl-1) - - zisoifl(0) = 0._r8 - do j = 1, nlevsoifl-1 - zisoifl(j) = 0.5_r8*(zsoifl(j)+zsoifl(j+1)) !interface depths - enddo - zisoifl(nlevsoifl) = zsoifl(nlevsoifl) + 0.5_r8*dzsoifl(nlevsoifl) - - if ( masterproc )then - write(iulog,*) 'Setting clay, sand, organic, in Soil Hydrology for VIC' - end if do c = bounds%begc, bounds%endc g = col%gridcell(c) l = col%landunit(c) @@ -214,41 +166,16 @@ subroutine SoilHydrologyInitTimeConst(bounds, soilhydrology_inst) ! do nothing else do lev = 1,nlevgrnd - if (.not. organic_frac_squared) then - if (lev .eq. 1) then - clay = clay3d(g,1) - sand = sand3d(g,1) - om_frac = organic3d(g,1)/organic_max - else if (lev <= nlevsoi) then - do j = 1,nlevsoifl-1 - if (zisoi(lev) >= zisoifl(j) .AND. zisoi(lev) < zisoifl(j+1)) then - clay = clay3d(g,j+1) - sand = sand3d(g,j+1) - om_frac = organic3d(g,j+1)/organic_max - endif - end do - else - clay = clay3d(g,nlevsoifl) - sand = sand3d(g,nlevsoifl) - om_frac = 0._r8 - endif + if ( lev <= nlevsoi )then + claycol(c,lev) = soilstate_inst%cellclay_col(c,lev) + sandcol(c,lev) = soilstate_inst%cellsand_col(c,lev) + om_fraccol(c,lev) = soilstate_inst%cellorg_col(c,lev) / organic_max else - ! duplicate clay and sand values from 10th soil layer - if (lev <= nlevsoi) then - clay = clay3d(g,lev) - sand = sand3d(g,lev) - om_frac = (organic3d(g,lev)/organic_max)**2._r8 - else - clay = clay3d(g,nlevsoi) - sand = sand3d(g,nlevsoi) - om_frac = 0._r8 - endif + claycol(c,lev) = soilstate_inst%cellclay_col(c,nlevsoi) + sandcol(c,lev) = soilstate_inst%cellsand_col(c,nlevsoi) + om_fraccol(c,lev) = 0.0_r8 end if - if (lun%urbpoi(l)) om_frac = 0._r8 - claycol(c,lev) = clay - sandcol(c,lev) = sand - om_fraccol(c,lev) = om_frac end do end if end if ! end of if not lake @@ -279,8 +206,6 @@ subroutine SoilHydrologyInitTimeConst(bounds, soilhydrology_inst) deallocate(b2d, ds2d, dsmax2d, ws2d) deallocate(sandcol, claycol, om_fraccol) - deallocate(sand3d, clay3d, organic3d) - deallocate(zisoifl, zsoifl, dzsoifl) end if ! end of if use_vichydro diff --git a/src/biogeophys/SoilStateInitTimeConstMod.F90 b/src/biogeophys/SoilStateInitTimeConstMod.F90 index 528eef5dc0..5402f59375 100644 --- a/src/biogeophys/SoilStateInitTimeConstMod.F90 +++ b/src/biogeophys/SoilStateInitTimeConstMod.F90 @@ -5,6 +5,7 @@ module SoilStateInitTimeConstMod ! Set hydraulic and thermal properties ! ! !USES + use shr_kind_mod , only : r8 => shr_kind_r8 use SoilStateType , only : soilstate_type use LandunitType , only : lun use ColumnType , only : col @@ -19,10 +20,13 @@ module SoilStateInitTimeConstMod ! !PRIVATE MEMBER FUNCTIONS: private :: ReadNL ! - ! !PRIVATE DATA: + ! !PUBLIC DATA: + real(r8), public :: organic_max ! organic matter (kg/m3) where soil is assumed to act like peat + ! Control variables (from namelist) logical, public :: organic_frac_squared ! If organic fraction should be squared (as in CLM4.5) + ! !PRIVATE DATA: character(len=*), parameter, private :: sourcefile = & __FILE__ !----------------------------------------------------------------------- @@ -87,7 +91,6 @@ end subroutine ReadNL subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) ! ! !USES: - use shr_kind_mod , only : r8 => shr_kind_r8 use shr_log_mod , only : errMsg => shr_log_errMsg use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=) use decompMod , only : bounds_type @@ -140,7 +143,6 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) real(r8) :: tkm ! mineral conductivity real(r8) :: xksat ! maximum hydraulic conductivity of soil [mm/s] real(r8) :: clay,sand ! temporaries - real(r8) :: organic_max ! organic matter (kg/m3) where soil is assumed to act like peat integer :: dimid ! dimension id logical :: readvar type(file_desc_t) :: ncid ! netcdf id diff --git a/src/main/clm_instMod.F90 b/src/main/clm_instMod.F90 index 7fa31ab4cd..406fa45224 100644 --- a/src/main/clm_instMod.F90 +++ b/src/main/clm_instMod.F90 @@ -306,7 +306,7 @@ subroutine clm_instInit(bounds) call soilhydrology_inst%Init(bounds, nlfilename, water_inst%waterstatebulk_inst, & use_aquifer_layer = use_aquifer_layer()) - call SoilHydrologyInitTimeConst(bounds, soilhydrology_inst) + call SoilHydrologyInitTimeConst(bounds, soilhydrology_inst, soilstate_inst) call saturated_excess_runoff_inst%Init(bounds) call infiltration_excess_runoff_inst%Init(bounds) From 506ee20f85e4127ce974d451133288c5fa0e49ba Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 25 Jul 2019 17:51:03 -0600 Subject: [PATCH 18/29] Clean-up related to the previous commit Eg, in the use statements and variable declarations --- .../SoilHydrologyInitTimeConstMod.F90 | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/biogeophys/SoilHydrologyInitTimeConstMod.F90 b/src/biogeophys/SoilHydrologyInitTimeConstMod.F90 index d9dc1fd071..64ede52fc4 100644 --- a/src/biogeophys/SoilHydrologyInitTimeConstMod.F90 +++ b/src/biogeophys/SoilHydrologyInitTimeConstMod.F90 @@ -40,17 +40,15 @@ subroutine SoilHydrologyInitTimeConst(bounds, soilhydrology_inst, soilstate_inst use shr_spfn_mod , only : shr_spfn_erf use abortutils , only : endrun use spmdMod , only : masterproc - use clm_varctl , only : fsurdat, paramfile, iulog, use_vichydro, soil_layerstruct_predefined - use clm_varpar , only : nlevsoifl, toplev_equalspace - use clm_varpar , only : nlevsoi, nlevgrnd, nlevsno, nlevlak, nlevurb, nlayer, nlayert - use clm_varcon , only : zsoi, dzsoi, zisoi, spval, nlvic, dzvic, pc, grlnd + use clm_varctl , only : fsurdat, iulog, use_vichydro + use clm_varpar , only : toplev_equalspace + use clm_varpar , only : nlevsoi, nlevgrnd, nlayer, nlayert + use clm_varcon , only : dzsoi, spval, nlvic, dzvic, pc, grlnd use clm_varcon , only : aquifer_water_baseline - use landunit_varcon , only : istwet, istsoil, istdlak, istcrop, istice_mec + use landunit_varcon , only : istwet, istdlak, istice_mec use column_varcon , only : icol_shadewall, icol_road_perv, icol_road_imperv, icol_roof, icol_sunwall use fileutils , only : getfil - use organicFileMod , only : organicrd use ncdio_pio , only : file_desc_t, ncd_io, ncd_pio_openfile, ncd_pio_closefile - use SoilStateInitTimeConstMod, only: organic_frac_squared ! ! !ARGUMENTS: type(bounds_type) , intent(in) :: bounds @@ -66,8 +64,6 @@ subroutine SoilHydrologyInitTimeConst(bounds, soilhydrology_inst, soilstate_inst logical :: readvar type(file_desc_t) :: ncid character(len=256) :: locfn - real(r8) :: clay,sand ! temporaries - real(r8) :: om_frac ! organic matter fraction real(r8) ,pointer :: b2d (:) ! read in - VIC b real(r8) ,pointer :: ds2d (:) ! read in - VIC Ds real(r8) ,pointer :: dsmax2d (:) ! read in - VIC Dsmax @@ -75,12 +71,6 @@ subroutine SoilHydrologyInitTimeConst(bounds, soilhydrology_inst, soilstate_inst real(r8), pointer :: sandcol (:,:) ! column level sand fraction for calculating VIC parameters real(r8), pointer :: claycol (:,:) ! column level clay fraction for calculating VIC parameters real(r8), pointer :: om_fraccol (:,:) ! column level organic matter fraction for calculating VIC parameters - real(r8) ,pointer :: sand3d (:,:) ! read in - soil texture: percent sand - real(r8) ,pointer :: clay3d (:,:) ! read in - soil texture: percent clay - real(r8) ,pointer :: organic3d (:,:) ! read in - organic matter: kg/m3 - real(r8) ,pointer :: zisoifl (:) ! original soil interface depth - real(r8) ,pointer :: zsoifl (:) ! original soil midpoint - real(r8) ,pointer :: dzsoifl (:) ! original soil thickness !----------------------------------------------------------------------- ! Initialize VIC variables From 938f12579200fd784bffe8b3ccd2e782b5078344 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 25 Jul 2019 18:15:34 -0600 Subject: [PATCH 19/29] Consolidation of repetitive code --- src/biogeophys/SoilStateInitTimeConstMod.F90 | 33 +++++++------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/src/biogeophys/SoilStateInitTimeConstMod.F90 b/src/biogeophys/SoilStateInitTimeConstMod.F90 index 5402f59375..c5a02d685f 100644 --- a/src/biogeophys/SoilStateInitTimeConstMod.F90 +++ b/src/biogeophys/SoilStateInitTimeConstMod.F90 @@ -399,33 +399,24 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) endif end if + if (lun%urbpoi(l)) then + om_frac = 0._r8 ! No organic matter for urban + end if + + if (lev <= nlevsoi) then + soilstate_inst%cellsand_col(c,lev) = sand + soilstate_inst%cellclay_col(c,lev) = clay + soilstate_inst%cellorg_col(c,lev) = om_frac*organic_max + end if + + if (lun%itype(l) == istdlak) then + ! slevis: Seems inconsistent and disorganized to have the next if-statmt ! here and then have it again in a separate do-loop a few lines ! down. I propose that we bring the lake section up here. -! slevis: Also I would pull out here the "No organic matter for urban" -! and consolidate the two identical codes repeated just below. -! slevis: This section runs before SoilHydrologyInitTimeConst, so let's -! also simplify codes there with data gathered here. - if (lun%itype(l) == istdlak) then - - if (lev <= nlevsoi) then - soilstate_inst%cellsand_col(c,lev) = sand - soilstate_inst%cellclay_col(c,lev) = clay - soilstate_inst%cellorg_col(c,lev) = om_frac*organic_max - end if else if (lun%itype(l) /= istdlak) then ! soil columns of both urban and non-urban types - if (lun%urbpoi(l)) then - om_frac = 0._r8 ! No organic matter for urban - end if - - if (lev <= nlevsoi) then - soilstate_inst%cellsand_col(c,lev) = sand - soilstate_inst%cellclay_col(c,lev) = clay - soilstate_inst%cellorg_col(c,lev) = om_frac*organic_max - end if - ! Note that the following properties are overwritten for urban impervious road ! layers that are not soil in SoilThermProp.F90 within SoilTemperatureMod.F90 From f62c5d04de3aa4b6334eeb60313df6f3c31e9602 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 25 Jul 2019 19:10:49 -0600 Subject: [PATCH 20/29] Improved code organization --- src/biogeophys/SoilStateInitTimeConstMod.F90 | 148 ++++++++----------- 1 file changed, 61 insertions(+), 87 deletions(-) diff --git a/src/biogeophys/SoilStateInitTimeConstMod.F90 b/src/biogeophys/SoilStateInitTimeConstMod.F90 index c5a02d685f..64cf9c3527 100644 --- a/src/biogeophys/SoilStateInitTimeConstMod.F90 +++ b/src/biogeophys/SoilStateInitTimeConstMod.F90 @@ -409,11 +409,69 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) soilstate_inst%cellorg_col(c,lev) = om_frac*organic_max end if + ! -------------------------------------------------------------------- + ! Set soil hydraulic and thermal properties: lake + ! -------------------------------------------------------------------- + if (lun%itype(l) == istdlak) then -! slevis: Seems inconsistent and disorganized to have the next if-statmt -! here and then have it again in a separate do-loop a few lines -! down. I propose that we bring the lake section up here. + soilstate_inst%watsat_col(c,lev) = 0.489_r8 - 0.00126_r8*sand + + soilstate_inst%bsw_col(c,lev) = 2.91 + 0.159*clay + + soilstate_inst%sucsat_col(c,lev) = 10._r8 * ( 10._r8**(1.88_r8-0.0131_r8*sand) ) + + bd = (1._r8-soilstate_inst%watsat_col(c,lev))*2.7e3_r8 + + soilstate_inst%watsat_col(c,lev) = (1._r8 - om_frac)*soilstate_inst%watsat_col(c,lev) + om_watsat_lake * om_frac + + tkm = (1._r8-om_frac)*(8.80_r8*sand+2.92_r8*clay)/(sand+clay) + om_tkm * om_frac ! W/(m K) + + soilstate_inst%bsw_col(c,lev) = (1._r8-om_frac)*(2.91_r8 + 0.159_r8*clay) + om_frac * om_b_lake + + soilstate_inst%sucsat_col(c,lev) = (1._r8-om_frac)*soilstate_inst%sucsat_col(c,lev) + om_sucsat_lake * om_frac + + xksat = 0.0070556 *( 10.**(-0.884+0.0153*sand) ) ! mm/s + + ! perc_frac is zero unless perf_frac greater than percolation threshold + if (om_frac > pc_lake) then + perc_norm = (1._r8 - pc_lake)**(-pcbeta) + perc_frac = perc_norm*(om_frac - pc_lake)**pcbeta + else + perc_frac = 0._r8 + endif + + ! uncon_frac is fraction of mineral soil plus fraction of "nonpercolating" organic soil + uncon_frac = (1._r8-om_frac) + (1._r8-perc_frac)*om_frac + + ! uncon_hksat is series addition of mineral/organic conductivites + if (om_frac < 1._r8) then + xksat = 0.0070556 *( 10.**(-0.884+0.0153*sand) ) ! mm/s + uncon_hksat = uncon_frac/((1._r8-om_frac)/xksat + ((1._r8-perc_frac)*om_frac)/om_hksat_lake) + else + uncon_hksat = 0._r8 + end if + + soilstate_inst%hksat_col(c,lev) = uncon_frac*uncon_hksat + (perc_frac*om_frac)*om_hksat_lake + soilstate_inst%tkmg_col(c,lev) = tkm ** (1._r8- soilstate_inst%watsat_col(c,lev)) + soilstate_inst%tksatu_col(c,lev) = soilstate_inst%tkmg_col(c,lev)*0.57_r8**soilstate_inst%watsat_col(c,lev) + soilstate_inst%tkdry_col(c,lev) = ((0.135_r8*bd + 64.7_r8) / & + (2.7e3_r8 - 0.947_r8*bd)) * (1._r8-om_frac) + & + om_tkd * om_frac + soilstate_inst%csol_col(c,lev) = ((1._r8-om_frac) * & + (2.128_r8*sand + 2.385_r8*clay) / (sand + clay) + & + om_csol * om_frac) * 1.e6_r8 ! J/(m3 K) + soilstate_inst%watdry_col(c,lev) = soilstate_inst%watsat_col(c,lev) & + * (316230._r8/soilstate_inst%sucsat_col(c,lev)) ** (-1._r8/soilstate_inst%bsw_col(c,lev)) + soilstate_inst%watopt_col(c,lev) = soilstate_inst%watsat_col(c,lev) & + * (158490._r8/soilstate_inst%sucsat_col(c,lev)) ** (-1._r8/soilstate_inst%bsw_col(c,lev)) + + !! added by K.Sakaguchi for beta from Lee and Pielke, 1992 + ! water content at field capacity, defined as hk = 0.1 mm/day + ! used eqn (7.70) in CLM3 technote with k = 0.1 (mm/day) / (# seconds/day) + soilstate_inst%watfc_col(c,lev) = soilstate_inst%watsat_col(c,lev) * & + (0.1_r8 / & + (soilstate_inst%hksat_col(c,lev)*secspday))**(1._r8/(2._r8*soilstate_inst%bsw_col(c,lev)+3._r8)) else if (lun%itype(l) /= istdlak) then ! soil columns of both urban and non-urban types @@ -497,90 +555,6 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) end if end do - ! -------------------------------------------------------------------- - ! Set soil hydraulic and thermal properties: lake - ! -------------------------------------------------------------------- - - do c = begc, endc - g = col%gridcell(c) - l = col%landunit(c) - - if (lun%itype(l)==istdlak) then - - do lev = 1,nlevgrnd - if ( lev <= nlevsoi )then - clay = soilstate_inst%cellclay_col(c,lev) - sand = soilstate_inst%cellsand_col(c,lev) - if ( organic_frac_squared )then - om_frac = (soilstate_inst%cellorg_col(c,lev)/organic_max)**2._r8 - else - om_frac = soilstate_inst%cellorg_col(c,lev)/organic_max - end if - else - clay = soilstate_inst%cellclay_col(c,nlevsoi) - sand = soilstate_inst%cellsand_col(c,nlevsoi) - om_frac = 0.0_r8 - end if - - soilstate_inst%watsat_col(c,lev) = 0.489_r8 - 0.00126_r8*sand - - soilstate_inst%bsw_col(c,lev) = 2.91 + 0.159*clay - - soilstate_inst%sucsat_col(c,lev) = 10._r8 * ( 10._r8**(1.88_r8-0.0131_r8*sand) ) - - bd = (1._r8-soilstate_inst%watsat_col(c,lev))*2.7e3_r8 - - soilstate_inst%watsat_col(c,lev) = (1._r8 - om_frac)*soilstate_inst%watsat_col(c,lev) + om_watsat_lake * om_frac - - tkm = (1._r8-om_frac)*(8.80_r8*sand+2.92_r8*clay)/(sand+clay) + om_tkm * om_frac ! W/(m K) - - soilstate_inst%bsw_col(c,lev) = (1._r8-om_frac)*(2.91_r8 + 0.159_r8*clay) + om_frac * om_b_lake - - soilstate_inst%sucsat_col(c,lev) = (1._r8-om_frac)*soilstate_inst%sucsat_col(c,lev) + om_sucsat_lake * om_frac - - xksat = 0.0070556 *( 10.**(-0.884+0.0153*sand) ) ! mm/s - - ! perc_frac is zero unless perf_frac greater than percolation threshold - if (om_frac > pc_lake) then - perc_norm = (1._r8 - pc_lake)**(-pcbeta) - perc_frac = perc_norm*(om_frac - pc_lake)**pcbeta - else - perc_frac = 0._r8 - endif - - ! uncon_frac is fraction of mineral soil plus fraction of "nonpercolating" organic soil - uncon_frac = (1._r8-om_frac) + (1._r8-perc_frac)*om_frac - - ! uncon_hksat is series addition of mineral/organic conductivites - if (om_frac < 1._r8) then - xksat = 0.0070556 *( 10.**(-0.884+0.0153*sand) ) ! mm/s - uncon_hksat = uncon_frac/((1._r8-om_frac)/xksat + ((1._r8-perc_frac)*om_frac)/om_hksat_lake) - else - uncon_hksat = 0._r8 - end if - - soilstate_inst%hksat_col(c,lev) = uncon_frac*uncon_hksat + (perc_frac*om_frac)*om_hksat_lake - soilstate_inst%tkmg_col(c,lev) = tkm ** (1._r8- soilstate_inst%watsat_col(c,lev)) - soilstate_inst%tksatu_col(c,lev) = soilstate_inst%tkmg_col(c,lev)*0.57_r8**soilstate_inst%watsat_col(c,lev) - soilstate_inst%tkdry_col(c,lev) = ((0.135_r8*bd + 64.7_r8) / (2.7e3_r8 - 0.947_r8*bd))*(1._r8-om_frac) + & - om_tkd * om_frac - soilstate_inst%csol_col(c,lev) = ((1._r8-om_frac)*(2.128_r8*sand+2.385_r8*clay) / (sand+clay) + & - om_csol * om_frac)*1.e6_r8 ! J/(m3 K) - soilstate_inst%watdry_col(c,lev) = soilstate_inst%watsat_col(c,lev) & - * (316230._r8/soilstate_inst%sucsat_col(c,lev)) ** (-1._r8/soilstate_inst%bsw_col(c,lev)) - soilstate_inst%watopt_col(c,lev) = soilstate_inst%watsat_col(c,lev) & - * (158490._r8/soilstate_inst%sucsat_col(c,lev)) ** (-1._r8/soilstate_inst%bsw_col(c,lev)) - - !! added by K.Sakaguchi for beta from Lee and Pielke, 1992 - ! water content at field capacity, defined as hk = 0.1 mm/day - ! used eqn (7.70) in CLM3 technote with k = 0.1 (mm/day) / (# seconds/day) - soilstate_inst%watfc_col(c,lev) = soilstate_inst%watsat_col(c,lev) * (0.1_r8 / & - (soilstate_inst%hksat_col(c,lev)*secspday))**(1._r8/(2._r8*soilstate_inst%bsw_col(c,lev)+3._r8)) - end do - endif - - end do - ! -------------------------------------------------------------------- ! Initialize threshold soil moisture and mass fracion of clay limited to 0.20 ! -------------------------------------------------------------------- From 094e3be5cfd3c7734b81f9d11d0ebe40dd71613b Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 29 Jul 2019 12:02:36 -0600 Subject: [PATCH 21/29] Revert "Improved code organization" This reverts commit f62c5d04de3aa4b6334eeb60313df6f3c31e9602 because the tests suites on hobart and cheyenne failed for all clm4.5 tests. I repeated testing by temporarity returning to the previous commit using (git checkout 938f125) and this time all tests passed that I expected to pass. --- src/biogeophys/SoilStateInitTimeConstMod.F90 | 148 +++++++++++-------- 1 file changed, 87 insertions(+), 61 deletions(-) diff --git a/src/biogeophys/SoilStateInitTimeConstMod.F90 b/src/biogeophys/SoilStateInitTimeConstMod.F90 index 64cf9c3527..c5a02d685f 100644 --- a/src/biogeophys/SoilStateInitTimeConstMod.F90 +++ b/src/biogeophys/SoilStateInitTimeConstMod.F90 @@ -409,69 +409,11 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) soilstate_inst%cellorg_col(c,lev) = om_frac*organic_max end if - ! -------------------------------------------------------------------- - ! Set soil hydraulic and thermal properties: lake - ! -------------------------------------------------------------------- - if (lun%itype(l) == istdlak) then - soilstate_inst%watsat_col(c,lev) = 0.489_r8 - 0.00126_r8*sand - - soilstate_inst%bsw_col(c,lev) = 2.91 + 0.159*clay - - soilstate_inst%sucsat_col(c,lev) = 10._r8 * ( 10._r8**(1.88_r8-0.0131_r8*sand) ) - - bd = (1._r8-soilstate_inst%watsat_col(c,lev))*2.7e3_r8 - - soilstate_inst%watsat_col(c,lev) = (1._r8 - om_frac)*soilstate_inst%watsat_col(c,lev) + om_watsat_lake * om_frac - - tkm = (1._r8-om_frac)*(8.80_r8*sand+2.92_r8*clay)/(sand+clay) + om_tkm * om_frac ! W/(m K) - - soilstate_inst%bsw_col(c,lev) = (1._r8-om_frac)*(2.91_r8 + 0.159_r8*clay) + om_frac * om_b_lake - - soilstate_inst%sucsat_col(c,lev) = (1._r8-om_frac)*soilstate_inst%sucsat_col(c,lev) + om_sucsat_lake * om_frac - - xksat = 0.0070556 *( 10.**(-0.884+0.0153*sand) ) ! mm/s - - ! perc_frac is zero unless perf_frac greater than percolation threshold - if (om_frac > pc_lake) then - perc_norm = (1._r8 - pc_lake)**(-pcbeta) - perc_frac = perc_norm*(om_frac - pc_lake)**pcbeta - else - perc_frac = 0._r8 - endif - - ! uncon_frac is fraction of mineral soil plus fraction of "nonpercolating" organic soil - uncon_frac = (1._r8-om_frac) + (1._r8-perc_frac)*om_frac - - ! uncon_hksat is series addition of mineral/organic conductivites - if (om_frac < 1._r8) then - xksat = 0.0070556 *( 10.**(-0.884+0.0153*sand) ) ! mm/s - uncon_hksat = uncon_frac/((1._r8-om_frac)/xksat + ((1._r8-perc_frac)*om_frac)/om_hksat_lake) - else - uncon_hksat = 0._r8 - end if - - soilstate_inst%hksat_col(c,lev) = uncon_frac*uncon_hksat + (perc_frac*om_frac)*om_hksat_lake - soilstate_inst%tkmg_col(c,lev) = tkm ** (1._r8- soilstate_inst%watsat_col(c,lev)) - soilstate_inst%tksatu_col(c,lev) = soilstate_inst%tkmg_col(c,lev)*0.57_r8**soilstate_inst%watsat_col(c,lev) - soilstate_inst%tkdry_col(c,lev) = ((0.135_r8*bd + 64.7_r8) / & - (2.7e3_r8 - 0.947_r8*bd)) * (1._r8-om_frac) + & - om_tkd * om_frac - soilstate_inst%csol_col(c,lev) = ((1._r8-om_frac) * & - (2.128_r8*sand + 2.385_r8*clay) / (sand + clay) + & - om_csol * om_frac) * 1.e6_r8 ! J/(m3 K) - soilstate_inst%watdry_col(c,lev) = soilstate_inst%watsat_col(c,lev) & - * (316230._r8/soilstate_inst%sucsat_col(c,lev)) ** (-1._r8/soilstate_inst%bsw_col(c,lev)) - soilstate_inst%watopt_col(c,lev) = soilstate_inst%watsat_col(c,lev) & - * (158490._r8/soilstate_inst%sucsat_col(c,lev)) ** (-1._r8/soilstate_inst%bsw_col(c,lev)) - - !! added by K.Sakaguchi for beta from Lee and Pielke, 1992 - ! water content at field capacity, defined as hk = 0.1 mm/day - ! used eqn (7.70) in CLM3 technote with k = 0.1 (mm/day) / (# seconds/day) - soilstate_inst%watfc_col(c,lev) = soilstate_inst%watsat_col(c,lev) * & - (0.1_r8 / & - (soilstate_inst%hksat_col(c,lev)*secspday))**(1._r8/(2._r8*soilstate_inst%bsw_col(c,lev)+3._r8)) +! slevis: Seems inconsistent and disorganized to have the next if-statmt +! here and then have it again in a separate do-loop a few lines +! down. I propose that we bring the lake section up here. else if (lun%itype(l) /= istdlak) then ! soil columns of both urban and non-urban types @@ -555,6 +497,90 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) end if end do + ! -------------------------------------------------------------------- + ! Set soil hydraulic and thermal properties: lake + ! -------------------------------------------------------------------- + + do c = begc, endc + g = col%gridcell(c) + l = col%landunit(c) + + if (lun%itype(l)==istdlak) then + + do lev = 1,nlevgrnd + if ( lev <= nlevsoi )then + clay = soilstate_inst%cellclay_col(c,lev) + sand = soilstate_inst%cellsand_col(c,lev) + if ( organic_frac_squared )then + om_frac = (soilstate_inst%cellorg_col(c,lev)/organic_max)**2._r8 + else + om_frac = soilstate_inst%cellorg_col(c,lev)/organic_max + end if + else + clay = soilstate_inst%cellclay_col(c,nlevsoi) + sand = soilstate_inst%cellsand_col(c,nlevsoi) + om_frac = 0.0_r8 + end if + + soilstate_inst%watsat_col(c,lev) = 0.489_r8 - 0.00126_r8*sand + + soilstate_inst%bsw_col(c,lev) = 2.91 + 0.159*clay + + soilstate_inst%sucsat_col(c,lev) = 10._r8 * ( 10._r8**(1.88_r8-0.0131_r8*sand) ) + + bd = (1._r8-soilstate_inst%watsat_col(c,lev))*2.7e3_r8 + + soilstate_inst%watsat_col(c,lev) = (1._r8 - om_frac)*soilstate_inst%watsat_col(c,lev) + om_watsat_lake * om_frac + + tkm = (1._r8-om_frac)*(8.80_r8*sand+2.92_r8*clay)/(sand+clay) + om_tkm * om_frac ! W/(m K) + + soilstate_inst%bsw_col(c,lev) = (1._r8-om_frac)*(2.91_r8 + 0.159_r8*clay) + om_frac * om_b_lake + + soilstate_inst%sucsat_col(c,lev) = (1._r8-om_frac)*soilstate_inst%sucsat_col(c,lev) + om_sucsat_lake * om_frac + + xksat = 0.0070556 *( 10.**(-0.884+0.0153*sand) ) ! mm/s + + ! perc_frac is zero unless perf_frac greater than percolation threshold + if (om_frac > pc_lake) then + perc_norm = (1._r8 - pc_lake)**(-pcbeta) + perc_frac = perc_norm*(om_frac - pc_lake)**pcbeta + else + perc_frac = 0._r8 + endif + + ! uncon_frac is fraction of mineral soil plus fraction of "nonpercolating" organic soil + uncon_frac = (1._r8-om_frac) + (1._r8-perc_frac)*om_frac + + ! uncon_hksat is series addition of mineral/organic conductivites + if (om_frac < 1._r8) then + xksat = 0.0070556 *( 10.**(-0.884+0.0153*sand) ) ! mm/s + uncon_hksat = uncon_frac/((1._r8-om_frac)/xksat + ((1._r8-perc_frac)*om_frac)/om_hksat_lake) + else + uncon_hksat = 0._r8 + end if + + soilstate_inst%hksat_col(c,lev) = uncon_frac*uncon_hksat + (perc_frac*om_frac)*om_hksat_lake + soilstate_inst%tkmg_col(c,lev) = tkm ** (1._r8- soilstate_inst%watsat_col(c,lev)) + soilstate_inst%tksatu_col(c,lev) = soilstate_inst%tkmg_col(c,lev)*0.57_r8**soilstate_inst%watsat_col(c,lev) + soilstate_inst%tkdry_col(c,lev) = ((0.135_r8*bd + 64.7_r8) / (2.7e3_r8 - 0.947_r8*bd))*(1._r8-om_frac) + & + om_tkd * om_frac + soilstate_inst%csol_col(c,lev) = ((1._r8-om_frac)*(2.128_r8*sand+2.385_r8*clay) / (sand+clay) + & + om_csol * om_frac)*1.e6_r8 ! J/(m3 K) + soilstate_inst%watdry_col(c,lev) = soilstate_inst%watsat_col(c,lev) & + * (316230._r8/soilstate_inst%sucsat_col(c,lev)) ** (-1._r8/soilstate_inst%bsw_col(c,lev)) + soilstate_inst%watopt_col(c,lev) = soilstate_inst%watsat_col(c,lev) & + * (158490._r8/soilstate_inst%sucsat_col(c,lev)) ** (-1._r8/soilstate_inst%bsw_col(c,lev)) + + !! added by K.Sakaguchi for beta from Lee and Pielke, 1992 + ! water content at field capacity, defined as hk = 0.1 mm/day + ! used eqn (7.70) in CLM3 technote with k = 0.1 (mm/day) / (# seconds/day) + soilstate_inst%watfc_col(c,lev) = soilstate_inst%watsat_col(c,lev) * (0.1_r8 / & + (soilstate_inst%hksat_col(c,lev)*secspday))**(1._r8/(2._r8*soilstate_inst%bsw_col(c,lev)+3._r8)) + end do + endif + + end do + ! -------------------------------------------------------------------- ! Initialize threshold soil moisture and mass fracion of clay limited to 0.20 ! -------------------------------------------------------------------- From d3c518fde6766e43e4242ec24c66cf7998742802 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 29 Jul 2019 12:10:51 -0600 Subject: [PATCH 22/29] New test info in config_component.xml to avoid abort Also updated a user_nl_clm that I had missed in earlier commits. This also avoids abort. --- cime_config/config_component.xml | 3 ++- .../testdefs/testmods_dirs/clm/deepsoil_bedrock/user_nl_clm | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index 56971672dc..5600c2b29c 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -15,7 +15,7 @@ clm4.5: - clm5.0: + clm5.0: Satellite phenology: CN: Carbon Nitrogen model CNDV: CN with Dynamic Vegetation @@ -32,6 +32,7 @@ BGC (vert. resol. CN and methane) with prognostic crop, with modifications appropriate for CMIP6 WACCM DECK experiments: NWP configuration with satellite phenology: + NWP configuration with BGC and CROP: diff --git a/cime_config/testdefs/testmods_dirs/clm/deepsoil_bedrock/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/deepsoil_bedrock/user_nl_clm index 0c98d81ff0..daaf704226 100644 --- a/cime_config/testdefs/testmods_dirs/clm/deepsoil_bedrock/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/deepsoil_bedrock/user_nl_clm @@ -1,3 +1,3 @@ lower_boundary_condition = 2 -soil_layerstruct = '49SL_10m' +soil_layerstruct_predefined = '49SL_10m' use_bedrock = .true. From b4e19f95f397d5396cc8a4077a4f955d712979c5 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 29 Jul 2019 12:26:37 -0600 Subject: [PATCH 23/29] Updated ChangeLog/ChangeSum --- doc/ChangeLog | 24 ++++++++---------------- doc/ChangeSum | 2 +- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index de55211c9d..c712779f1e 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,7 +1,7 @@ =============================================================== Tag name: ctsm1.0.dev053 Originator(s): slevis (Samuel Levis,SLevis Consulting LLC,303-665-1310) -Date: Thu Jul 25 14:57:31 MDT 2019 +Date: Mon Jul 29 12:19:02 MDT 2019 One-line Summary: Soil layer definition clean-up and user-defined option Purpose of changes @@ -17,6 +17,8 @@ Purpose of changes Default nlevsoi for NWP configurations had to change from 5 to 4 for consistency with the new error check described in known bugs below. + Other code clean-up removes a couple of sections of repeating code. + Bugs fixed or introduced ------------------------ @@ -89,18 +91,6 @@ Code reviewed by: @billsacks CTSM testing: -[... Remove before making master tag. Available test levels: - - a) regular (must be run before handing off a tag to SEs and must be run - before committing a tag) - b) build_namelist (if namelists and/or build_system changed)) - c) tools (only if tools are modified and no CTSM source is modified) - d) short (for use during development and in rare cases where only a small - change with known behavior is added ... eg. a minor bug fix) - e) doc (no source testing required) - -... ] - [PASS means all tests PASS and OK means tests PASS other than expected fails.] build-namelist tests: @@ -121,8 +111,8 @@ CTSM testing: regular tests (aux_clm): - cheyenne ---- - hobart ------ + cheyenne ---- OK + hobart ------ OK If the tag used for baseline comparisons was NOT the previous tag, note that here: @@ -136,7 +126,9 @@ Changes answers relative to baseline: - what code configurations: nwp - what platforms/compilers: all - nature of change: larger than roundoff/same climate - + This is due to the change of nlevsoi from 5 to 4 (more info above). + I confirmed that nwp does return bfb same answers when I revert this + change. Detailed list of changes ------------------------ diff --git a/doc/ChangeSum b/doc/ChangeSum index 10faee139b..e7c9504039 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,6 +1,6 @@ Tag Who Date Summary ============================================================================================================================ - ctsm1.0.dev053 slevis 07/25/2019 Soil layer definition clean-up and user-defined option + ctsm1.0.dev053 slevis 07/29/2019 Soil layer definition clean-up and user-defined option ctsm1.0.dev052 sacks 07/22/2019 Fix rare soil color bug in mksurfdata_map ctsm1.0.dev051 sacks 07/19/2019 Update water tracers for remainder of first stage of hydrology ctsm1.0.dev050 slevis 07/15/2019 dz --> dz_lake bug-fix in LakeTemperatureMod.F90 line 960 From 3fffb028ea4820fcd1e956aec6fb2e34e49e4f50 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 29 Jul 2019 12:31:40 -0600 Subject: [PATCH 24/29] Remove unused if-statement --- src/biogeophys/SoilStateInitTimeConstMod.F90 | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/biogeophys/SoilStateInitTimeConstMod.F90 b/src/biogeophys/SoilStateInitTimeConstMod.F90 index c5a02d685f..3251a8bc1b 100644 --- a/src/biogeophys/SoilStateInitTimeConstMod.F90 +++ b/src/biogeophys/SoilStateInitTimeConstMod.F90 @@ -409,13 +409,7 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) soilstate_inst%cellorg_col(c,lev) = om_frac*organic_max end if - if (lun%itype(l) == istdlak) then - -! slevis: Seems inconsistent and disorganized to have the next if-statmt -! here and then have it again in a separate do-loop a few lines -! down. I propose that we bring the lake section up here. - - else if (lun%itype(l) /= istdlak) then ! soil columns of both urban and non-urban types + if (lun%itype(l) /= istdlak) then ! soil columns of both urban and non-urban types ! Note that the following properties are overwritten for urban impervious road ! layers that are not soil in SoilThermProp.F90 within SoilTemperatureMod.F90 From 342207f2f48b3bfd54cb0b63265a009613710bd3 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 31 Jul 2019 16:28:24 -0600 Subject: [PATCH 25/29] Reversing changes made in commits 1bc0f1d and 2618b2c Directly related to #771 --- src/biogeophys/SoilStateInitTimeConstMod.F90 | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/biogeophys/SoilStateInitTimeConstMod.F90 b/src/biogeophys/SoilStateInitTimeConstMod.F90 index 3251a8bc1b..3a1ccb137b 100644 --- a/src/biogeophys/SoilStateInitTimeConstMod.F90 +++ b/src/biogeophys/SoilStateInitTimeConstMod.F90 @@ -24,7 +24,7 @@ module SoilStateInitTimeConstMod real(r8), public :: organic_max ! organic matter (kg/m3) where soil is assumed to act like peat ! Control variables (from namelist) - logical, public :: organic_frac_squared ! If organic fraction should be squared (as in CLM4.5) + logical, private :: organic_frac_squared ! If organic fraction should be squared (as in CLM4.5) ! !PRIVATE DATA: character(len=*), parameter, private :: sourcefile = & @@ -369,7 +369,7 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) do lev = 1,nlevgrnd ! DML - this if statement could probably be removed and just the ! top part used for all soil layer structures - if (.not. organic_frac_squared) then + if ( soil_layerstruct /= '10SL_3.5m' )then if (lev .eq. 1) then clay = clay3d(g,1) sand = sand3d(g,1) @@ -387,11 +387,15 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) sand = sand3d(g,nlevsoifl) om_frac = 0._r8 endif - else + else ! apply soil texture from 10 layer input dataset if (lev <= nlevsoi) then ! duplicate clay and sand values from 10th soil layer clay = clay3d(g,lev) sand = sand3d(g,lev) - om_frac = (organic3d(g,lev)/organic_max)**2._r8 + if (organic_frac_squared) then + om_frac = (organic3d(g,lev)/organic_max)**2._r8 + else + om_frac = organic3d(g,lev)/organic_max + end if else clay = clay3d(g,nlevsoi) sand = sand3d(g,nlevsoi) From d1eca83196b49ab6821125410e1ab6ae4e45b291 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 31 Jul 2019 16:48:39 -0600 Subject: [PATCH 26/29] Minor comment correction --- src/biogeophys/SoilStateInitTimeConstMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/biogeophys/SoilStateInitTimeConstMod.F90 b/src/biogeophys/SoilStateInitTimeConstMod.F90 index 3a1ccb137b..4b6d5a697b 100644 --- a/src/biogeophys/SoilStateInitTimeConstMod.F90 +++ b/src/biogeophys/SoilStateInitTimeConstMod.F90 @@ -23,10 +23,10 @@ module SoilStateInitTimeConstMod ! !PUBLIC DATA: real(r8), public :: organic_max ! organic matter (kg/m3) where soil is assumed to act like peat + ! !PRIVATE DATA: ! Control variables (from namelist) logical, private :: organic_frac_squared ! If organic fraction should be squared (as in CLM4.5) - ! !PRIVATE DATA: character(len=*), parameter, private :: sourcefile = & __FILE__ !----------------------------------------------------------------------- From 6d2fa7673ac60d64924db0e958ffa826ed00aaeb Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 31 Jul 2019 18:39:49 -0600 Subject: [PATCH 27/29] Minor comment placement correction --- src/biogeophys/SoilStateInitTimeConstMod.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/biogeophys/SoilStateInitTimeConstMod.F90 b/src/biogeophys/SoilStateInitTimeConstMod.F90 index 4b6d5a697b..bcdbdbd546 100644 --- a/src/biogeophys/SoilStateInitTimeConstMod.F90 +++ b/src/biogeophys/SoilStateInitTimeConstMod.F90 @@ -369,7 +369,7 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) do lev = 1,nlevgrnd ! DML - this if statement could probably be removed and just the ! top part used for all soil layer structures - if ( soil_layerstruct /= '10SL_3.5m' )then + if ( soil_layerstruct /= '10SL_3.5m' )then ! apply soil texture from 10 layer input dataset if (lev .eq. 1) then clay = clay3d(g,1) sand = sand3d(g,1) @@ -387,7 +387,7 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) sand = sand3d(g,nlevsoifl) om_frac = 0._r8 endif - else ! apply soil texture from 10 layer input dataset + else if (lev <= nlevsoi) then ! duplicate clay and sand values from 10th soil layer clay = clay3d(g,lev) sand = sand3d(g,lev) From f40533cda6f2dd736118453c28dff8d330516b83 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 1 Aug 2019 14:02:46 -0600 Subject: [PATCH 28/29] Silly mistake that justifies the motto: RUN AT LEAST ONE TEST! --- src/biogeophys/SoilStateInitTimeConstMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/biogeophys/SoilStateInitTimeConstMod.F90 b/src/biogeophys/SoilStateInitTimeConstMod.F90 index bcdbdbd546..0a1e205c3a 100644 --- a/src/biogeophys/SoilStateInitTimeConstMod.F90 +++ b/src/biogeophys/SoilStateInitTimeConstMod.F90 @@ -369,7 +369,7 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename) do lev = 1,nlevgrnd ! DML - this if statement could probably be removed and just the ! top part used for all soil layer structures - if ( soil_layerstruct /= '10SL_3.5m' )then ! apply soil texture from 10 layer input dataset + if ( soil_layerstruct_predefined /= '10SL_3.5m' )then ! apply soil texture from 10 layer input dataset if (lev .eq. 1) then clay = clay3d(g,1) sand = sand3d(g,1) From 72d598b831f62263654140c25d0635b9140f1f56 Mon Sep 17 00:00:00 2001 From: Bill Sacks Date: Thu, 1 Aug 2019 16:56:25 -0600 Subject: [PATCH 29/29] Update ChangeLog with new date --- doc/ChangeLog | 2 +- doc/ChangeSum | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index c712779f1e..ea2eb10e9b 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,7 +1,7 @@ =============================================================== Tag name: ctsm1.0.dev053 Originator(s): slevis (Samuel Levis,SLevis Consulting LLC,303-665-1310) -Date: Mon Jul 29 12:19:02 MDT 2019 +Date: Thu Aug 1 16:56:09 MDT 2019 One-line Summary: Soil layer definition clean-up and user-defined option Purpose of changes diff --git a/doc/ChangeSum b/doc/ChangeSum index e7c9504039..ab379bb589 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,6 +1,6 @@ Tag Who Date Summary ============================================================================================================================ - ctsm1.0.dev053 slevis 07/29/2019 Soil layer definition clean-up and user-defined option + ctsm1.0.dev053 slevis 08/01/2019 Soil layer definition clean-up and user-defined option ctsm1.0.dev052 sacks 07/22/2019 Fix rare soil color bug in mksurfdata_map ctsm1.0.dev051 sacks 07/19/2019 Update water tracers for remainder of first stage of hydrology ctsm1.0.dev050 slevis 07/15/2019 dz --> dz_lake bug-fix in LakeTemperatureMod.F90 line 960