From f84f1cc9259562bcb528ef71f21b816c74fd835f Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Wed, 19 Jan 2022 12:15:24 +0100 Subject: [PATCH 01/99] add namelist definitions and defaults to use excess ice --- bld/namelist_files/namelist_defaults_ctsm.xml | 15 ++++++++ .../namelist_definition_ctsm.xml | 38 +++++++++++++++++++ src/main/clm_initializeMod.F90 | 2 +- src/main/clm_instMod.F90 | 2 +- src/main/clm_varctl.F90 | 5 +++ src/main/controlMod.F90 | 5 +++ 6 files changed, 65 insertions(+), 2 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 1ee46abecb..165e53438b 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -2586,4 +2586,19 @@ lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts general + + + + +.false. +1901 +1901 +1901 + +lnd/clm2/prescribed_data/exice_init_0.9x1.25_c20211102.nc + +nearest +0 + + diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index a79991efd8..6a7d6d1511 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -2818,4 +2818,42 @@ use case.) + + + + +Toggle to turn on the excess ice physics, (Lee et al., 2014; Cai et al., 2020) + + + +First year to loop over for excess ice data + + + +Last year to loop over for excess ice data + + + +Simulation year that aligns with stream_year_first_exice value + + + +Filename of input stream data for excess ice data + + + +Time interpolation method to use for excess ice data + + + +Offset in time coordinate for excess ice streams (sec) + + diff --git a/src/main/clm_initializeMod.F90 b/src/main/clm_initializeMod.F90 index c9541376a2..32c368e40b 100644 --- a/src/main/clm_initializeMod.F90 +++ b/src/main/clm_initializeMod.F90 @@ -14,7 +14,7 @@ module clm_initializeMod use clm_varctl , only : is_cold_start, is_interpolated_start use clm_varctl , only : iulog use clm_varctl , only : use_lch4, use_cn, use_cndv, use_c13, use_c14, use_fates - use clm_varctl , only : use_soil_moisture_streams + use clm_varctl , only : use_soil_moisture_streams, use_excess_ice use clm_instur , only : wt_lunit, urban_valid, wt_nat_patch, wt_cft, fert_cft use clm_instur , only : irrig_method, wt_glc_mec, topo_glc_mec, haslake use perf_mod , only : t_startf, t_stopf diff --git a/src/main/clm_instMod.F90 b/src/main/clm_instMod.F90 index 44ab2f8ef2..b654ef5505 100644 --- a/src/main/clm_instMod.F90 +++ b/src/main/clm_instMod.F90 @@ -8,7 +8,7 @@ module clm_instMod use shr_kind_mod , only : r8 => shr_kind_r8 use decompMod , only : bounds_type use clm_varpar , only : ndecomp_pools, nlevdecomp_full - use clm_varctl , only : use_cn, use_c13, use_c14, use_lch4, use_cndv, use_fates + use clm_varctl , only : use_cn, use_c13, use_c14, use_lch4, use_cndv, use_fates, use_excess_ice use clm_varctl , only : use_crop, snow_cover_fraction_method, paramfile use SoilBiogeochemDecompCascadeConType , only : century_decomp, decomp_method use clm_varcon , only : bdsno, c13ratio, c14ratio diff --git a/src/main/clm_varctl.F90 b/src/main/clm_varctl.F90 index 3ad4b14bef..2d7af87cf4 100644 --- a/src/main/clm_varctl.F90 +++ b/src/main/clm_varctl.F90 @@ -298,6 +298,11 @@ module clm_varctl real(r8), public :: soil_layerstruct_userdefined(99) = rundef integer, public :: soil_layerstruct_userdefined_nlevsoi = iundef + !---------------------------------------------------------- + !excess ice physics switch + !---------------------------------------------------------- + logical, public :: use_excess_ice = .false. ! true. => use excess ice physics !MVD + !---------------------------------------------------------- ! plant hydraulic stress switch !---------------------------------------------------------- diff --git a/src/main/controlMod.F90 b/src/main/controlMod.F90 index 082d68e8eb..a52a52806e 100644 --- a/src/main/controlMod.F90 +++ b/src/main/controlMod.F90 @@ -242,6 +242,8 @@ subroutine control_init(dtime) namelist /clm_inparm/ use_soil_moisture_streams + namelist /clm_inparm/ use_excess_ice !MVD + namelist /clm_inparm/ use_lai_streams namelist /clm_inparm/ use_bedrock @@ -733,6 +735,8 @@ subroutine control_spmd() call mpi_bcast (use_soil_moisture_streams, 1, MPI_LOGICAL, 0, mpicom, ier) + call mpi_bcast (use_excess_ice, 1, MPI_LOGICAL, 0, mpicom,ier) !MVD + call mpi_bcast (use_lai_streams, 1, MPI_LOGICAL, 0, mpicom, ier) call mpi_bcast (use_bedrock, 1, MPI_LOGICAL, 0, mpicom, ier) @@ -866,6 +870,7 @@ subroutine control_print () write(iulog,*) ' use_nitrif_denitrif = ', use_nitrif_denitrif write(iulog,*) ' use_extralakelayers = ', use_extralakelayers write(iulog,*) ' use_vichydro = ', use_vichydro + write(iulog,*) ' use_excess_ice = ', use_excess_ice !MVD to check if the value is read from namelists write(iulog,*) ' use_cn = ', use_cn write(iulog,*) ' use_cndv = ', use_cndv write(iulog,*) ' use_crop = ', use_crop From 3feb457f9aa7eb0cfbe7f9becc94923691f9d9bf Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Tue, 25 Jan 2022 19:12:32 +0100 Subject: [PATCH 02/99] setup initialization and vars --- bld/namelist_files/namelist_defaults_ctsm.xml | 10 +- .../namelist_definition_ctsm.xml | 26 +- src/biogeophys/WaterStateType.F90 | 56 +++- src/cpl/share_esmf/ExcessIceStreamType.F90 | 256 ++++++++++++++++++ src/main/controlMod.F90 | 2 +- 5 files changed, 317 insertions(+), 33 deletions(-) create mode 100644 src/cpl/share_esmf/ExcessIceStreamType.F90 diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 165e53438b..775ed81105 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -2591,14 +2591,8 @@ lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts .false. -1901 -1901 -1901 - -lnd/clm2/prescribed_data/exice_init_0.9x1.25_c20211102.nc - -nearest -0 +lnd/clm2/paramdata/exice_init_0.9x1.25_c20211102.nc +lnd/clm2/paramdata/finundated_inversiondata_0.9x1_ESMFmesh_cdf5_130621.nc diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 6a7d6d1511..702b21b262 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -2826,34 +2826,14 @@ use case.) Toggle to turn on the excess ice physics, (Lee et al., 2014; Cai et al., 2020) - -First year to loop over for excess ice data - - - -Last year to loop over for excess ice data - - - -Simulation year that aligns with stream_year_first_exice value - - Filename of input stream data for excess ice data - -Time interpolation method to use for excess ice data - - - -Offset in time coordinate for excess ice streams (sec) + +mesh filename of input stream data for excess ice diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index c06f2333c9..4b2b37c267 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -13,7 +13,7 @@ module WaterStateType use abortutils , only : endrun use decompMod , only : bounds_type use decompMod , only : subgrid_level_patch, subgrid_level_column, subgrid_level_gridcell - use clm_varctl , only : use_bedrock, iulog + use clm_varctl , only : use_bedrock, use_excess_ice, iulog use clm_varctl , only : use_fates_planthydro use clm_varpar , only : nlevgrnd, nlevsoi, nlevurb, nlevmaxurbgrnd, nlevsno use clm_varcon , only : spval @@ -22,6 +22,7 @@ module WaterStateType use WaterInfoBaseType, only : water_info_base_type use WaterTracerContainerType, only : water_tracer_container_type use WaterTracerUtils, only : AllocateVar1d, AllocateVar2d + use ExcessIceStreamType, only : excessicestream_type ! implicit none save @@ -51,6 +52,14 @@ module WaterStateType real(r8) :: aquifer_water_baseline ! baseline value for water in the unconfined aquifer (wa_col) for this bulk / tracer (mm) + real(r8), pointer :: excess_ice_col (:,:) ! col excess ice lenses (kg/m2) (new) (1:nlevgrnd) + real(r8), pointer :: init_exice (:,:) ! initial value of col excess ice lens/(kg/m2) (new) (1:nlevgrnd) + real(r8), pointer :: exice_melt_lev (:,:) ! col excess ice melting (m) (new) + real(r8), pointer :: exice_melt (:) ! column-wide excess ice melting (m) (new) + + + type(excessicestream_type), private :: exicestream ! stream type for excess ice initialization NUOPC only + contains procedure, public :: Init @@ -150,6 +159,22 @@ subroutine InitAllocate(this, bounds, tracer_vars) call AllocateVar1d(var = this%dynbal_baseline_ice_col, name = 'dynbal_baseline_ice_col', & container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_column) + !excess ice vars + call AllocateVar2d(var = this%excess_ice_col, name = 'excess_ice_col', & + container = tracer_vars, & + bounds = bounds, subgrid_level = subgrid_level_column, & + dim2beg = 1, dim2end = nlevgrnd) + call AllocateVar2d(var = this%init_exice, name = 'init_exice', & + container = tracer_vars, & + bounds = bounds, subgrid_level = subgrid_level_column, & + dim2beg = 1, dim2end = nlevgrnd) + call AllocateVar2d(var = this%exice_melt_lev, name = 'exice_melt_lev', & + container = tracer_vars, & + bounds = bounds, subgrid_level = subgrid_level_column, & + dim2beg = 1, dim2end = nlevgrnd) + call AllocateVar1d(var = this%exice_melt, name = 'exice_melt', & + container = tracer_vars, & + bounds = bounds, subgrid_level = subgrid_level_column) end subroutine InitAllocate @@ -268,6 +293,17 @@ subroutine InitHistory(this, bounds, use_aquifer_layer) ptr_col=this%wa_col, l2g_scale_type='veg') end if + ! Add excess ice fields to history + data2dptr => this%excess_ice_col(begc:endc,1:nlevsoi) + call hist_addfld2d (fname='EXCESS_ICE', units='kg/m2', type2d='levsoi', & + avgflag='A', long_name='excess soil ice (vegetated landunits only)', & + ptr_col=this%excess_ice_col, l2g_scale_type='veg') + + this%exice_melt(begc:endc) = spval + call hist_addfld1d (fname='EXICE_MELT', units='m', & + avgflag='A', long_name='melt from excess ice (vegetated landunits only)', & + ptr_col=this%exice_melt, l2g_scale_type='veg') + ! (rgk 02-02-2017) There is intentionally no entry here for stored plant water ! I think that since the value is zero in all cases except ! for FATES plant hydraulics, it will be confusing for users @@ -505,6 +541,12 @@ subroutine InitCold(this, bounds, & this%dynbal_baseline_liq_col(bounds%begc:bounds%endc) = 0._r8 this%dynbal_baseline_ice_col(bounds%begc:bounds%endc) = 0._r8 + !Initialize excess ice + this%init_exice(:,:)=0.0_r8 + this%excess_ice_col(:,:)=0.0_r8 + this%exice_melt_lev(:,:)=0.0_r8 + this%exice_melt(:)=0.0_r8 + end associate end subroutine InitCold @@ -630,6 +672,18 @@ subroutine Restart(this, bounds, ncid, flag, & units='kg/m2', & interpinic_flag='interp', readvar=readvar, data=this%dynbal_baseline_ice_col) + ! Restart excess ice vars + call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('EXCESS_ICE'), xtype=ncd_double, & + dim1name='column', dim2name='levtot', switchdim=.true., & + long_name=this%info%lname('excess soil ice (vegetated landunits only)'), units='kg/m2', & + scale_by_thickness=.true., & + interpinic_flag='interp', readvar=readvar, data=this%excess_ice_col) + + call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('EXICE_MELT'), xtype=ncd_double, & + dim1name='column', & + long_name=this%info%lname('melt from excess ice (vegetated landunits only)'), units='m', & + interpinic_flag='interp', readvar=readvar, data=this%exice_melt) + ! Determine volumetric soil water (for read only) if (flag == 'read' ) then do c = bounds%begc, bounds%endc diff --git a/src/cpl/share_esmf/ExcessIceStreamType.F90 b/src/cpl/share_esmf/ExcessIceStreamType.F90 new file mode 100644 index 0000000000..8c08c766cd --- /dev/null +++ b/src/cpl/share_esmf/ExcessIceStreamType.F90 @@ -0,0 +1,256 @@ +module ExcessIceStreamType + +#include "shr_assert.h" + + !----------------------------------------------------------------------- + ! !DESCRIPTION: + ! Contains methods for reading in excess ice initial bulk values from data stream + ! + ! !USES + use ESMF + use dshr_strdata_mod , only : shr_strdata_type + use shr_kind_mod , only : r8 => shr_kind_r8, CL => shr_kind_cl + use shr_log_mod , only : errMsg => shr_log_errMsg + use spmdMod , only : mpicom, masterproc + use clm_varctl , only : iulog + use abortutils , only : endrun + use decompMod , only : bounds_type + + ! !PUBLIC TYPES: + implicit none + private + + type, public :: excessicestream_type + real(r8), pointer, private :: exice_bulk (:) ! excess ice bulk value (-) + contains + + ! !PUBLIC MEMBER FUNCTIONS: + procedure, public :: Init ! Initialize and read data in + procedure, public :: UseStreams ! If streams will be used + + ! !PRIVATE MEMBER FUNCTIONS: + procedure, private :: InitAllocate ! Allocate data + + end type excessicestream_type + ! ! PRIVATE DATA: + type, private :: streamcontrol_type + character(len=CL) :: stream_fldFileName_exice ! data Filename + character(len=CL) :: stream_meshfile_exice ! mesh Filename + character(len=CL) :: exicemapalgo ! map algo + contains + procedure, private :: ReadNML ! Read in namelist + end type streamcontrol_type + + type(streamcontrol_type), private :: control ! Stream control data + + character(len=*), parameter, private :: sourcefile = & + __FILE__ + +!============================================================================== +contains +!============================================================================== + + subroutine Init(this, bounds, NLFilename) + ! + use spmdMod , only : iam + use lnd_comp_shr , only : mesh, model_clock + use dshr_strdata_mod , only : shr_strdata_init_from_inline, shr_strdata_print + use dshr_strdata_mod , only : shr_strdata_advance + use dshr_methods_mod , only : dshr_fldbun_getfldptr + ! + ! arguments + implicit none + class(excessicestream_type) :: this + type(bounds_type), intent(in) :: bounds + character(len=*), intent(in) :: NLFilename ! Namelist filename + + ! + ! local variables + integer :: ig, g, n ! Indices + integer :: year ! year (0, ...) for nstep+1 + integer :: mon ! month (1, ..., 12) for nstep+1 + integer :: day ! day of month (1, ..., 31) for nstep+1 + integer :: sec ! seconds into current date for nstep+1 + integer :: mcdate ! Current model date (yyyymmdd) + type(shr_strdata_type) :: sdat_exice ! input data stream + character(len=16), allocatable :: stream_varnames(:) ! array of stream field names + integer :: rc ! error code + real(r8), pointer :: dataptr1d(:) ! temporary pointer + character(len=*), parameter :: stream_name = 'excess ice' + + call this%InitAllocate( bounds ) + call control%ReadNML( bounds, NLFileName ) + if ( this%useStreams() )then + allocate(stream_varnames(1)) + stream_varnames = (/"EXICE"/) + + if (masterproc) then + write(iulog,*) ' stream_varnames = ',stream_varnames + end if + + call shr_strdata_init_from_inline(sdat_exice, & + my_task = iam, & + logunit = iulog, & + compname = 'LND', & + model_clock = model_clock, & + model_mesh = mesh, & + stream_meshfile = control%stream_meshfile_exice, & + stream_lev_dimname = 'null', & + stream_mapalgo = 'nn', & + stream_filenames = (/trim(control%stream_fldFileName_exice)/), & + stream_fldlistFile = stream_varnames, & + stream_fldListModel = stream_varnames, & + stream_yearFirst = 1996, & + stream_yearLast = 1996, & + stream_yearAlign = 1, & + stream_offset = 0, & + stream_taxmode = 'extend', & + stream_dtlimit = 1.0e30_r8, & + stream_tintalgo = 'linear', & + stream_name = 'excess ice ', & + rc = rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) then + call ESMF_Finalize(endflag=ESMF_END_ABORT) + end if + + ! Explicitly set current date to a hardcoded constant value. Otherwise + ! using the real date can cause roundoff differences that are + ! detrected as issues with exact restart. EBK M05/20/2017 + ! call get_curr_date(year, mon, day, sec) + year = 1996 + mon = 12 + day = 31 + sec = 0 + mcdate = year*10000 + mon*100 + day + + call shr_strdata_advance(sdat_exice, ymd=mcdate, tod=sec, logunit=iulog, istr='ch4', rc=rc) !c4 is left in + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) then + call ESMF_Finalize(endflag=ESMF_END_ABORT) + end if + + ! Get pointer for stream data that is time and spatially interpolate to model time and grid + do n = 1,size(stream_varnames) + call dshr_fldbun_getFldPtr(sdat_exice%pstrm(1)%fldbun_model, stream_varnames(n), fldptr1=dataptr1d, rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) then + call ESMF_Finalize(endflag=ESMF_END_ABORT) + end if + if (trim(stream_varnames(n)) == 'EXICE') then + ig = 0 + do g = bounds%begg,bounds%endg + ig = ig+1 + this%exice_bulk(g) = dataptr1d(ig) + end do + end if + end do + end if + end subroutine Init + + subroutine InitAllocate(this, bounds) + ! + ! !DESCRIPTION: + ! Allocate module variables and data structures + ! + ! !USES: + use shr_infnan_mod, only: nan => shr_infnan_nan, assignment(=) + ! + ! !ARGUMENTS: + implicit none + class(excessicestream_type) :: this + type(bounds_type), intent(in) :: bounds + ! + ! !LOCAL VARIABLES: + integer :: begc, endc + integer :: begg, endg + !--------------------------------------------------------------------- + + begc = bounds%begc; endc = bounds%endc + begg = bounds%begg; endg = bounds%endg + + + allocate(this%exice_bulk(begg:endg)) ; this%exice_bulk(:) = nan + + end subroutine InitAllocate + + logical function UseStreams(this) + ! + ! !DESCRIPTION: + ! Return true if + ! + ! !USES: + ! + ! !ARGUMENTS: + implicit none + class(excessicestream_type) :: this + ! + ! !LOCAL VARIABLES: + if ( trim(control%stream_fldFileName_exice) == '' )then + UseStreams = .false. + else + UseStreams = .true. + end if +end function UseStreams + +subroutine ReadNML(this, bounds, NLFilename) + ! + ! Read the namelist data stream information. + ! + ! Uses: + use shr_nl_mod , only : shr_nl_find_group_name + use shr_log_mod , only : errMsg => shr_log_errMsg + use shr_mpi_mod , only : shr_mpi_bcast + ! + ! arguments + implicit none + class(streamcontrol_type) :: this + type(bounds_type), intent(in) :: bounds + character(len=*), intent(in) :: NLFilename ! Namelist filename + ! + ! local variables + integer :: nu_nml ! unit for namelist file + integer :: nml_error ! namelist i/o error flag + character(len=CL) :: stream_fldFileName_exice = ' ' + character(len=CL) :: stream_meshfile_exice = ' ' + character(len=CL) :: exicemapalgo = 'nn' + character(len=*), parameter :: namelist_name = 'exice' ! MUST agree with name in namelist and read + character(len=*), parameter :: subName = "('exice::ReadNML')" + !----------------------------------------------------------------------- + + namelist /exice/ & ! MUST agree with namelist_name above + exicemapalgo, stream_fldFileName_exice, stream_meshfile_exice + + ! Default values for namelist + + ! Read ch4finundated namelist + if (masterproc) then + open( newunit=nu_nml, file=trim(NLFilename), status='old', iostat=nml_error ) + call shr_nl_find_group_name(nu_nml, namelist_name, status=nml_error) + if (nml_error == 0) then + read(nu_nml, nml=exice,iostat=nml_error) ! MUST agree with namelist_name above + if (nml_error /= 0) then + call endrun(msg=' ERROR reading '//namelist_name//' namelist'//errMsg(sourcefile, __LINE__)) + end if + else + call endrun(msg=' ERROR finding '//namelist_name//' namelist'//errMsg(sourcefile, __LINE__)) + end if + close(nu_nml) + endif + + call shr_mpi_bcast(exicemapalgo , mpicom) + call shr_mpi_bcast(stream_fldFileName_exice , mpicom) + call shr_mpi_bcast(stream_meshfile_exice , mpicom) + + if (masterproc) then + write(iulog,*) ' ' + write(iulog,*) namelist_name, ' stream settings:' + write(iulog,*) ' stream_fldFileName_exice = ',stream_fldFileName_exice + write(iulog,*) ' stream_meshfile_exice = ',stream_meshfile_exice + write(iulog,*) ' exicemapalgo = ',exicemapalgo + endif + this%stream_fldFileName_exice = stream_fldFileName_exice + this%stream_meshfile_exice = stream_meshfile_exice + this%exicemapalgo = exicemapalgo + +end subroutine ReadNML + + +end module ExcessIceStreamType \ No newline at end of file diff --git a/src/main/controlMod.F90 b/src/main/controlMod.F90 index a52a52806e..98d9ab4081 100644 --- a/src/main/controlMod.F90 +++ b/src/main/controlMod.F90 @@ -870,7 +870,7 @@ subroutine control_print () write(iulog,*) ' use_nitrif_denitrif = ', use_nitrif_denitrif write(iulog,*) ' use_extralakelayers = ', use_extralakelayers write(iulog,*) ' use_vichydro = ', use_vichydro - write(iulog,*) ' use_excess_ice = ', use_excess_ice !MVD to check if the value is read from namelists + write(iulog,*) ' use_excess_ice = ', use_excess_ice !MVD to check if the value is read from namelists write(iulog,*) ' use_cn = ', use_cn write(iulog,*) ' use_cndv = ', use_cndv write(iulog,*) ' use_crop = ', use_crop From 21fca41896e972337447538e94c64af51993c2b8 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Wed, 26 Jan 2022 19:31:21 +0100 Subject: [PATCH 03/99] exice streams namelists and initialization at cold start --- bld/CLMBuildNamelist.pm | 20 ++++++++ src/biogeophys/WaterStateBulkType.F90 | 7 +-- src/biogeophys/WaterStateType.F90 | 53 +++++++++++++++++----- src/biogeophys/WaterType.F90 | 19 ++++++-- src/cpl/share_esmf/ExcessIceStreamType.F90 | 14 +++--- 5 files changed, 87 insertions(+), 26 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index a172ac445b..c7168e45e8 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -1732,6 +1732,11 @@ sub process_namelist_inline_logic { # namelist group: clm_initinterp_inparm # ######################################### setup_logic_initinterp($opts, $nl_flags, $definition, $defaults, $nl); + + ############################### + # namelist group: exice_streams # + ############################### + setup_logic_exice($opts, $nl_flags, $definition, $defaults, $nl); } #------------------------------------------------------------------------------- @@ -4137,6 +4142,20 @@ sub setup_logic_fates { } } +#------------------------------------------------------------------------------- +sub setup_logic_exice { + # + # excess ice streams + # + my ($opts, $nl_flags, $definition, $defaults, $nl) = @_; + + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_fldfilename_exice'); + if ($opts->{'driver'} eq "nuopc" ) { + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_meshfile_exice'); + } + +} # end exice streams + #------------------------------------------------------------------------------- sub setup_logic_misc { @@ -4204,6 +4223,7 @@ sub write_output_files { push @groups, "nitrif_inparm"; push @groups, "lifire_inparm"; push @groups, "ch4finundated"; + push @groups, "exice_streams"; push @groups, "soilbgc_decomp"; push @groups, "clm_canopy_inparm"; if (remove_leading_and_trailing_quotes($nl->get_value('snow_cover_fraction_method')) eq 'SwensonLawrence2012') { diff --git a/src/biogeophys/WaterStateBulkType.F90 b/src/biogeophys/WaterStateBulkType.F90 index 5c0298c8d5..18b9f34e3e 100644 --- a/src/biogeophys/WaterStateBulkType.F90 +++ b/src/biogeophys/WaterStateBulkType.F90 @@ -47,7 +47,7 @@ module WaterStateBulkType !------------------------------------------------------------------------ subroutine InitBulk(this, bounds, info, vars, & - h2osno_input_col, watsat_col, t_soisno_col, use_aquifer_layer) + h2osno_input_col, watsat_col, t_soisno_col, use_aquifer_layer, NLFilename) class(waterstatebulk_type), intent(inout) :: this type(bounds_type) , intent(in) :: bounds @@ -57,7 +57,7 @@ subroutine InitBulk(this, bounds, info, vars, & real(r8) , intent(in) :: watsat_col(bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) real(r8) , intent(in) :: t_soisno_col(bounds%begc:, -nlevsno+1:) ! col soil temperature (Kelvin) logical , intent(in) :: use_aquifer_layer ! whether an aquifer layer is used in this run - + character(len=*) , intent(in) :: NLFilename ! Namelist filename call this%Init(bounds = bounds, & info = info, & @@ -65,7 +65,8 @@ subroutine InitBulk(this, bounds, info, vars, & h2osno_input_col = h2osno_input_col, & watsat_col = watsat_col, & t_soisno_col = t_soisno_col, & - use_aquifer_layer = use_aquifer_layer) + use_aquifer_layer = use_aquifer_layer, & + NLFilename = NLFilename) call this%InitBulkAllocate(bounds) diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index 4b2b37c267..a5d62fb126 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -81,7 +81,7 @@ module WaterStateType !------------------------------------------------------------------------ subroutine Init(this, bounds, info, tracer_vars, & - h2osno_input_col, watsat_col, t_soisno_col, use_aquifer_layer) + h2osno_input_col, watsat_col, t_soisno_col, use_aquifer_layer, NLFilename) class(waterstate_type), intent(inout) :: this type(bounds_type) , intent(in) :: bounds @@ -91,18 +91,19 @@ subroutine Init(this, bounds, info, tracer_vars, & real(r8) , intent(in) :: watsat_col(bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) real(r8) , intent(in) :: t_soisno_col(bounds%begc:, -nlevsno+1:) ! col soil temperature (Kelvin) logical , intent(in) :: use_aquifer_layer ! whether an aquifer layer is used in this run + character(len=*) , intent(in) :: NLFilename ! Namelist filename this%info => info call this%InitAllocate(bounds, tracer_vars) call this%InitHistory(bounds, use_aquifer_layer) - call this%InitCold(bounds = bounds, & - h2osno_input_col = h2osno_input_col, & - watsat_col = watsat_col, & - t_soisno_col = t_soisno_col, & - use_aquifer_layer = use_aquifer_layer) + h2osno_input_col = h2osno_input_col, & + watsat_col = watsat_col, & + t_soisno_col = t_soisno_col, & + use_aquifer_layer = use_aquifer_layer, & + NLFilename = NLFilename) end subroutine Init @@ -317,7 +318,7 @@ end subroutine InitHistory !----------------------------------------------------------------------- subroutine InitCold(this, bounds, & - h2osno_input_col, watsat_col, t_soisno_col, use_aquifer_layer) + h2osno_input_col, watsat_col, t_soisno_col, use_aquifer_layer, NLFilename) ! ! !DESCRIPTION: ! Initialize time constant variables and cold start conditions @@ -336,9 +337,10 @@ subroutine InitCold(this, bounds, & real(r8) , intent(in) :: watsat_col(bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) real(r8) , intent(in) :: t_soisno_col(bounds%begc:, -nlevsno+1:) ! col soil temperature (Kelvin) logical , intent(in) :: use_aquifer_layer ! whether an aquifer layer is used in this run + character(len=*) , intent(in) :: NLFilename ! Namelist filename ! ! !LOCAL VARIABLES: - integer :: c,j,l,nlevs + integer :: c,j,l,nlevs,g integer :: nbedrock real(r8) :: ratio !----------------------------------------------------------------------- @@ -542,11 +544,38 @@ subroutine InitCold(this, bounds, & this%dynbal_baseline_ice_col(bounds%begc:bounds%endc) = 0._r8 !Initialize excess ice - this%init_exice(:,:)=0.0_r8 - this%excess_ice_col(:,:)=0.0_r8 - this%exice_melt_lev(:,:)=0.0_r8 - this%exice_melt(:)=0.0_r8 + write(iulog,*) 'nfl =', NLFilename + if (use_excess_ice .and. NLFilename /= '') then + + call this%exicestream%Init(bounds, NLFilename) ! get initial fraction of excess ice per column + do c = bounds%begc,bounds%endc + g = col%gridcell(c) + l = col%landunit(c) + if (.not. lun%lakpoi(l)) then !not lake + if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then + nlevs = nlevgrnd + do j = 1, nlevs + if (col%zi(c,j) <= 4._r8 .and. t_soisno_col(c,j) <= tfrz ) then + this%excess_ice_col(c,j) = col%dz(c,j)*denice*(this%exicestream%exice_bulk(g)) + else + this%excess_ice_col(c,j) = 0.0_r8 + endif + this%init_exice(c,j) = 0.0_r8 + this%init_exice(c,j) = this%excess_ice_col(c,j) + end do + endif + endif + enddo + this%exice_melt_lev(:,:)=0.0_r8 + this%exice_melt(:)=0.0_r8 + + else + this%init_exice(:,:)=0.0_r8 + this%excess_ice_col(:,:)=0.0_r8 + this%exice_melt_lev(:,:)=0.0_r8 + this%exice_melt(:)=0.0_r8 + end if end associate end subroutine InitCold diff --git a/src/biogeophys/WaterType.F90 b/src/biogeophys/WaterType.F90 index b8a05308b2..eb38459d4d 100644 --- a/src/biogeophys/WaterType.F90 +++ b/src/biogeophys/WaterType.F90 @@ -239,7 +239,8 @@ subroutine Init(this, bounds, NLFilename, & snow_depth_col = snow_depth_col, & watsat_col = watsat_col, & t_soisno_col = t_soisno_col, & - use_aquifer_layer = use_aquifer_layer) + use_aquifer_layer = use_aquifer_layer, & + NLFilename = NLFilename) end subroutine Init @@ -285,7 +286,7 @@ end subroutine InitForTesting !----------------------------------------------------------------------- subroutine DoInit(this, bounds, & - h2osno_col, snow_depth_col, watsat_col, t_soisno_col, use_aquifer_layer) + h2osno_col, snow_depth_col, watsat_col, t_soisno_col, use_aquifer_layer, NLFilename) ! ! !DESCRIPTION: ! Actually do the initialization (shared between main Init routine and InitForTesting) @@ -300,14 +301,22 @@ subroutine DoInit(this, bounds, & real(r8) , intent(in) :: watsat_col(bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) real(r8) , intent(in) :: t_soisno_col(bounds%begc:, -nlevsno+1:) ! col soil temperature (Kelvin) logical , intent(in) :: use_aquifer_layer ! whether an aquifer layer is used in this run + character(len=*) , intent(in) , optional :: NLFilename ! Namelist filename ! ! !LOCAL VARIABLES: integer :: begc, endc integer :: i + character(len=256) :: l_NLFilename ! local for namelist filename character(len=*), parameter :: subname = 'DoInit' !----------------------------------------------------------------------- + !check if NLFilename is passed + l_NLFilename = '' + if (present(NLFilename)) then + l_NLFilename = NLFilename + end if + begc = bounds%begc endc = bounds%endc @@ -333,7 +342,8 @@ subroutine DoInit(this, bounds, & h2osno_input_col = h2osno_col(begc:endc), & watsat_col = watsat_col(begc:endc, 1:), & t_soisno_col = t_soisno_col(begc:endc, -nlevsno+1:), & - use_aquifer_layer = use_aquifer_layer) + use_aquifer_layer = use_aquifer_layer, & + NLFilename = l_NLFilename) call this%waterdiagnosticbulk_inst%InitBulk(bounds, & bulk_info, & @@ -373,7 +383,8 @@ subroutine DoInit(this, bounds, & h2osno_input_col = h2osno_col(begc:endc), & watsat_col = watsat_col(begc:endc, 1:), & t_soisno_col = t_soisno_col(begc:endc, -nlevsno+1:), & - use_aquifer_layer = use_aquifer_layer) + use_aquifer_layer = use_aquifer_layer, & + NLFilename = l_NLFilename) call this%bulk_and_tracers(i)%waterdiagnostic_inst%Init(bounds, & this%bulk_and_tracers(i)%info, & diff --git a/src/cpl/share_esmf/ExcessIceStreamType.F90 b/src/cpl/share_esmf/ExcessIceStreamType.F90 index 8c08c766cd..04a235df0c 100644 --- a/src/cpl/share_esmf/ExcessIceStreamType.F90 +++ b/src/cpl/share_esmf/ExcessIceStreamType.F90 @@ -21,7 +21,7 @@ module ExcessIceStreamType private type, public :: excessicestream_type - real(r8), pointer, private :: exice_bulk (:) ! excess ice bulk value (-) + real(r8), pointer :: exice_bulk (:) ! excess ice bulk value (-) contains ! !PUBLIC MEMBER FUNCTIONS: @@ -106,7 +106,7 @@ subroutine Init(this, bounds, NLFilename) stream_offset = 0, & stream_taxmode = 'extend', & stream_dtlimit = 1.0e30_r8, & - stream_tintalgo = 'linear', & + stream_tintalgo = 'nearest', & stream_name = 'excess ice ', & rc = rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) then @@ -123,7 +123,7 @@ subroutine Init(this, bounds, NLFilename) sec = 0 mcdate = year*10000 + mon*100 + day - call shr_strdata_advance(sdat_exice, ymd=mcdate, tod=sec, logunit=iulog, istr='ch4', rc=rc) !c4 is left in + call shr_strdata_advance(sdat_exice, ymd=mcdate, tod=sec, logunit=iulog, istr='exice', rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) then call ESMF_Finalize(endflag=ESMF_END_ABORT) end if @@ -211,11 +211,11 @@ subroutine ReadNML(this, bounds, NLFilename) character(len=CL) :: stream_fldFileName_exice = ' ' character(len=CL) :: stream_meshfile_exice = ' ' character(len=CL) :: exicemapalgo = 'nn' - character(len=*), parameter :: namelist_name = 'exice' ! MUST agree with name in namelist and read - character(len=*), parameter :: subName = "('exice::ReadNML')" + character(len=*), parameter :: namelist_name = 'exice_streams' ! MUST agree with name in namelist and read + character(len=*), parameter :: subName = "('exice_streams::ReadNML')" !----------------------------------------------------------------------- - namelist /exice/ & ! MUST agree with namelist_name above + namelist /exice_streams/ & ! MUST agree with namelist_name above exicemapalgo, stream_fldFileName_exice, stream_meshfile_exice ! Default values for namelist @@ -225,7 +225,7 @@ subroutine ReadNML(this, bounds, NLFilename) open( newunit=nu_nml, file=trim(NLFilename), status='old', iostat=nml_error ) call shr_nl_find_group_name(nu_nml, namelist_name, status=nml_error) if (nml_error == 0) then - read(nu_nml, nml=exice,iostat=nml_error) ! MUST agree with namelist_name above + read(nu_nml, nml=exice_streams,iostat=nml_error) ! MUST agree with namelist_name above if (nml_error /= 0) then call endrun(msg=' ERROR reading '//namelist_name//' namelist'//errMsg(sourcefile, __LINE__)) end if From dcbeee02dde8bcc6c0eb262bbbe4cd9f59cf8703 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Thu, 27 Jan 2022 17:07:33 +0100 Subject: [PATCH 04/99] added bedrock and temperature to excess ice initialization + some comments --- src/biogeophys/TemperatureType.F90 | 12 +++++++----- src/biogeophys/WaterStateType.F90 | 19 ++++++++++++++++--- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/biogeophys/TemperatureType.F90 b/src/biogeophys/TemperatureType.F90 index f2d9317f82..e3ceaf3a41 100644 --- a/src/biogeophys/TemperatureType.F90 +++ b/src/biogeophys/TemperatureType.F90 @@ -647,11 +647,11 @@ subroutine InitCold(this, bounds, & ! !USES: use shr_kind_mod , only : r8 => shr_kind_r8 use shr_const_mod , only : SHR_CONST_TKFRZ - use clm_varcon , only : denice, denh2o, sb - use landunit_varcon, only : istwet, istsoil, istdlak, istice + use clm_varcon , only : denice, denh2o, sb !what's sb? how it's never used here + use landunit_varcon, only : istwet, istsoil, istdlak, istice, istcrop use column_varcon , only : icol_road_imperv, icol_roof, icol_sunwall use column_varcon , only : icol_shadewall, icol_road_perv - use clm_varctl , only : iulog, use_vancouver, use_mexicocity + use clm_varctl , only : iulog, use_vancouver, use_mexicocity, use_excess_ice ! ! !ARGUMENTS: class(temperature_type) :: this @@ -741,8 +741,10 @@ subroutine InitCold(this, bounds, & end if end if else - this%t_soisno_col(c,1:nlevgrnd) = 274._r8 - + this%t_soisno_col(c,1:nlevgrnd) = 274._r8 + if(use_excess_ice .and. (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop)) then + this%t_soisno_col(c,1:nlevgrnd) = SHR_CONST_TKFRZ-5.0_r8 !needs to be below freezing to properly initiate excess ice + end if endif endif end do diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index a5d62fb126..90e68ab5a3 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -299,6 +299,10 @@ subroutine InitHistory(this, bounds, use_aquifer_layer) call hist_addfld2d (fname='EXCESS_ICE', units='kg/m2', type2d='levsoi', & avgflag='A', long_name='excess soil ice (vegetated landunits only)', & ptr_col=this%excess_ice_col, l2g_scale_type='veg') + data2dptr => this%excess_ice_col(begc:endc,1:nlevsoi) + call hist_addfld2d (fname='EXICE_MELT_LEV', units='kg/m2', type2d='levsoi', & + avgflag='A', long_name='melt from excess ice per layer (vegetated landunits only)', & + ptr_col=this%exice_melt_lev, l2g_scale_type='veg') this%exice_melt(begc:endc) = spval call hist_addfld1d (fname='EXICE_MELT', units='m', & @@ -554,9 +558,13 @@ subroutine InitCold(this, bounds, & l = col%landunit(c) if (.not. lun%lakpoi(l)) then !not lake if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then - nlevs = nlevgrnd - do j = 1, nlevs - if (col%zi(c,j) <= 4._r8 .and. t_soisno_col(c,j) <= tfrz ) then + if (use_bedrock) then + nbedrock = col%nbedrock(c) + else + nbedrock = nlevsoi + endif + do j = 1, nlevgrnd + if (j Date: Wed, 2 Feb 2022 16:28:36 +0100 Subject: [PATCH 05/99] improved initialization --- src/biogeophys/WaterStateType.F90 | 44 ++++++++++++++++++------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index 90e68ab5a3..4c0575c8b7 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -164,15 +164,15 @@ subroutine InitAllocate(this, bounds, tracer_vars) call AllocateVar2d(var = this%excess_ice_col, name = 'excess_ice_col', & container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_column, & - dim2beg = 1, dim2end = nlevgrnd) + dim2beg = 1, dim2end = nlevmaxurbgrnd) call AllocateVar2d(var = this%init_exice, name = 'init_exice', & container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_column, & - dim2beg = 1, dim2end = nlevgrnd) + dim2beg = 1, dim2end = nlevmaxurbgrnd) call AllocateVar2d(var = this%exice_melt_lev, name = 'exice_melt_lev', & container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_column, & - dim2beg = 1, dim2end = nlevgrnd) + dim2beg = 1, dim2end = nlevmaxurbgrnd) call AllocateVar1d(var = this%exice_melt, name = 'exice_melt', & container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_column) @@ -550,7 +550,12 @@ subroutine InitCold(this, bounds, & !Initialize excess ice write(iulog,*) 'nfl =', NLFilename if (use_excess_ice .and. NLFilename /= '') then - + ! enforce initialization with 0 for everything + this%init_exice(:,:)=0.0_r8 + this%excess_ice_col(:,:)=0.0_r8 + this%exice_melt_lev(:,:)=0.0_r8 + this%exice_melt(:)=0.0_r8 + call this%exicestream%Init(bounds, NLFilename) ! get initial fraction of excess ice per column do c = bounds%begc,bounds%endc @@ -558,22 +563,25 @@ subroutine InitCold(this, bounds, & l = col%landunit(c) if (.not. lun%lakpoi(l)) then !not lake if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then - if (use_bedrock) then - nbedrock = col%nbedrock(c) - else - nbedrock = nlevsoi - endif - do j = 1, nlevgrnd - if (j Date: Wed, 2 Feb 2022 16:29:13 +0100 Subject: [PATCH 06/99] add excess ice to soil temperature mod --- src/biogeophys/SoilTemperatureMod.F90 | 129 ++++++++++++++++++++++++-- 1 file changed, 120 insertions(+), 9 deletions(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index ba4432cba2..3647534334 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -115,7 +115,7 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter use clm_time_manager , only : get_step_size_real use clm_varpar , only : nlevsno, nlevgrnd, nlevurb, nlevmaxurbgrnd use clm_varctl , only : iulog - use clm_varcon , only : cnfac, cpice, cpliq, denh2o + use clm_varcon , only : cnfac, cpice, cpliq, denh2o, denice use landunit_varcon , only : istsoil, istcrop use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall, icol_road_perv, icol_road_imperv use BandDiagonalMod , only : BandDiagonal @@ -171,6 +171,10 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter real(r8) :: hs_top_snow(bounds%begc:bounds%endc) ! heat flux on top snow layer [W/m2] real(r8) :: hs_h2osfc(bounds%begc:bounds%endc) ! heat flux on standing water [W/m2] integer :: jbot(bounds%begc:bounds%endc) ! bottom level at each column + real(r8) :: dz_0(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) ! original layer thickness [m] + real(r8) :: z_0(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) ! original layer depth [m] + real(r8) :: zi_0(bounds%begc:bounds%endc,-nlevsno+0:nlevmaxurbgrnd) ! original layer interface level bellow layer "z" [m] + !----------------------------------------------------------------------- associate( & @@ -194,6 +198,7 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter frac_sno_eff => waterdiagnosticbulk_inst%frac_sno_eff_col , & ! Input: [real(r8) (:) ] eff. fraction of ground covered by snow (0 to 1) snow_depth => waterdiagnosticbulk_inst%snow_depth_col , & ! Input: [real(r8) (:) ] snow height (m) h2osfc => waterstatebulk_inst%h2osfc_col , & ! Input: [real(r8) (:) ] surface water (mm) + excess_ice => waterstatebulk_inst%excess_ice_col , & ! Input: [real(r8) (:,:) ] excess ice lenses (kg/m2) (new) (1:nlevgrnd) frac_h2osfc => waterdiagnosticbulk_inst%frac_h2osfc_col , & ! Input: [real(r8) (:) ] fraction of ground covered by surface water (0 to 1) @@ -271,6 +276,29 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter endif end do + + !-------------------------------------------------------------- + ! Vertical coordinates adjustment for excess ice calculations + !-------------------------------------------------------------- + ! Save original soil depth to get put them back in et the end + dz_0(begc:endc,1:nlevmaxurbgrnd)=dz(begc:endc,1:nlevmaxurbgrnd) + zi_0(begc:endc,1:nlevmaxurbgrnd)=zi(begc:endc,1:nlevmaxurbgrnd) + z_0(begc:endc,1:nlevmaxurbgrnd)=z(begc:endc,1:nlevmaxurbgrnd) + ! Adjust column depth for excess ice thickness + do fc = 1,num_nolakec + c = filter_nolakec(fc) + l = col%landunit(c) + if( lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then + dz(c,1:nlevmaxurbgrnd)=dz(c,1:nlevmaxurbgrnd)+excess_ice(c,1:nlevmaxurbgrnd)/denice ! add extra layer thickness + do j=1,nlevmaxurbgrnd ! if excess ice amount dropped to zero there will be no adjustment + zi(c,j) = zi(c,j) + sum(excess_ice(c,1:j)) / denice + z(c,j) = (zi(c,j-1) + zi(c,j)) * 0.5_r8 + end do + endif + end do + + + !------------------------------------------------------ ! Compute ground surface and soil temperatures !------------------------------------------------------ @@ -488,6 +516,23 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter dhsdT(bounds%begc:bounds%endc), & soilstate_inst, waterstatebulk_inst, waterdiagnosticbulk_inst, waterfluxbulk_inst, energyflux_inst, temperature_inst) + !-------------------------------------------------------------- + ! Vertical coordinates adjustment for excess ice calculations + !-------------------------------------------------------------- + ! bringing back the soil depth to the original state + ! Adjust column depth for excess ice thickness + do fc = 1,num_nolakec + c = filter_nolakec(fc) + l = col%landunit(c) + if( lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then + dz(c,1:nlevmaxurbgrnd)=dz_0(c,1:nlevmaxurbgrnd) + zi(c,1:nlevmaxurbgrnd)=zi_0(c,1:nlevmaxurbgrnd) + z(c,1:nlevmaxurbgrnd)=z_0(c,1:nlevmaxurbgrnd) + endif + end do + + + if ( IsProgBuildTemp() )then call BuildingTemperature(bounds, num_urbanl, filter_urbanl, num_nolakec, filter_nolakec, & tk(bounds%begc:bounds%endc, :), urbanparams_inst, & @@ -628,6 +673,7 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter h2osno_no_layers => waterstatebulk_inst%h2osno_no_layers_col , & ! Input: [real(r8) (:) ] snow not resolved into layers (mm H2O) h2osoi_liq => waterstatebulk_inst%h2osoi_liq_col , & ! Input: [real(r8) (:,:) ] liquid water (kg/m2) h2osoi_ice => waterstatebulk_inst%h2osoi_ice_col , & ! Input: [real(r8) (:,:) ] ice lens (kg/m2) + excess_ice => waterstatebulk_inst%excess_ice_col , & ! Input: [real(r8) (:,:) ] excess ice lenses (kg/m2) (new) (1:nlevgrnd) bw => waterdiagnosticbulk_inst%bw_col , & ! Output: [real(r8) (:,:) ] partial density of water in the snow pack (ice + liquid) [kg/m3] tkmg => soilstate_inst%tkmg_col , & ! Input: [real(r8) (:,:) ] thermal conductivity, soil minerals [W/m-K] @@ -654,7 +700,8 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter col%itype(c) /= icol_roof .and. col%itype(c) /= icol_road_imperv) .or. & (col%itype(c) == icol_road_imperv .and. j > nlev_improad(l))) then - satw = (h2osoi_liq(c,j)/denh2o + h2osoi_ice(c,j)/denice)/(dz(c,j)*watsat(c,j)) + ! TODO recalculate watsat and satw to have excess ice included + satw = (h2osoi_liq(c,j)/denh2o + h2osoi_ice(c,j)/denice +excess_ice(c,j)/denice)/(dz(c,j)*watsat(c,j)) satw = min(1._r8, satw) if (satw > .1e-6_r8) then if (t_soisno(c,j) >= tfrz) then ! Unfrozen soil @@ -663,7 +710,7 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter dke = satw end if fl = (h2osoi_liq(c,j)/(denh2o*dz(c,j))) / (h2osoi_liq(c,j)/(denh2o*dz(c,j)) + & - h2osoi_ice(c,j)/(denice*dz(c,j))) + h2osoi_ice(c,j)/(denice*dz(c,j))+excess_ice(c,j)/denice) dksat = tkmg(c,j)*tkwat**(fl*watsat(c,j))*tkice**((1._r8-fl)*watsat(c,j)) thk(c,j) = dke*dksat + (1._r8-dke)*tkdry(c,j) else @@ -756,7 +803,7 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter .and. col%itype(c) /= icol_sunwall .and. col%itype(c) /= icol_shadewall .and. & col%itype(c) /= icol_roof .and. col%itype(c) /= icol_road_imperv) .or. & (col%itype(c) == icol_road_imperv .and. j > nlev_improad(l))) then - cv(c,j) = csol(c,j)*(1._r8-watsat(c,j))*dz(c,j) + (h2osoi_ice(c,j)*cpice + h2osoi_liq(c,j)*cpliq) + cv(c,j) = csol(c,j)*(1._r8-watsat(c,j))*dz(c,j) + (h2osoi_ice(c,j)*cpice + h2osoi_liq(c,j)*cpliq) + excess_ice(c,j)*cpice if (j > nbedrock(c)) cv(c,j) = csol_bedrock*dz(c,j) else if (lun%itype(l) == istwet) then cv(c,j) = (h2osoi_ice(c,j)*cpice + h2osoi_liq(c,j)*cpliq) @@ -1057,7 +1104,7 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & use clm_time_manager , only : get_step_size_real use clm_varpar , only : nlevsno, nlevgrnd, nlevurb, nlevmaxurbgrnd use clm_varctl , only : iulog - use clm_varcon , only : tfrz, hfus, grav + use clm_varcon , only : tfrz, hfus, grav, denice use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall, icol_road_perv use landunit_varcon , only : istsoil, istcrop, istice ! @@ -1088,6 +1135,11 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & real(r8) :: propor !proportionality constant (-) real(r8) :: tinc(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) !t(n+1)-t(n) [K] real(r8) :: smp !frozen water potential (mm) + real(r8) :: xm2(bounds%begc:bounds%endc,-nlevsno+1:nlevgrnd) !xm variable [kg/m2] + real(r8) :: xm3(bounds%begc:bounds%endc,-nlevsno+1:nlevgrnd) !xm variable [kg/m2] + real(r8) :: wexice0(bounds%begc:bounds%endc,-nlevsno+1:nlevgrnd)!initial mass of excess_ice at the timestep (kg/m2) + + !----------------------------------------------------------------------- call t_startf( 'PhaseChangebeta' ) @@ -1109,6 +1161,11 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & h2osno_no_layers => waterstatebulk_inst%h2osno_no_layers_col , & ! Output: [real(r8) (:) ] snow not resolved into layers (mm H2O) h2osoi_liq => waterstatebulk_inst%h2osoi_liq_col , & ! Output: [real(r8) (:,:) ] liquid water (kg/m2) (new) h2osoi_ice => waterstatebulk_inst%h2osoi_ice_col , & ! Output: [real(r8) (:,:) ] ice lens (kg/m2) (new) + excess_ice => waterstatebulk_inst%excess_ice_col , & ! Input: [real(r8) (:,:) ] excess ice lenses (kg/m2) (new) (1:nlevgrnd) + init_exice => waterstatebulk_inst%init_exice , & ! Input: [real(r8) (:) ] excess soil ice initial + exice_melt => waterstatebulk_inst%exice_melt , & ! Input: [real(r8) (:) ] excess soil ice + exice_melt_lev => waterstatebulk_inst%exice_melt_lev , & ! Input: [real(r8) (:,:) ] excess soil ice + qflx_snow_drain => waterfluxbulk_inst%qflx_snow_drain_col , & ! Output: [real(r8) (:) ] drainage from snow pack qflx_snofrz_lyr => waterfluxbulk_inst%qflx_snofrz_lyr_col , & ! Output: [real(r8) (:,:) ] snow freezing rate (positive definite) (col,lyr) [kg m-2 s-1] @@ -1152,9 +1209,12 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & imelt(c,j) = 0 hm(c,j) = 0._r8 xm(c,j) = 0._r8 + xm2(c,j)=0._r8 + xm3(c,j)=0._r8 wice0(c,j) = h2osoi_ice(c,j) wliq0(c,j) = h2osoi_liq(c,j) wmass0(c,j) = h2osoi_ice(c,j) + h2osoi_liq(c,j) + wexice0(c,j)=excess_ice(c,j) endif ! end of snow layer if-block if (j <= 0) then @@ -1211,6 +1271,13 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & t_soisno(c,j) = tfrz endif + ! melt excess ice after normal ice + if (excess_ice(c,j) > 0._r8 .AND. t_soisno(c,j) > tfrz) then + imelt(c,j) = 1 + tinc(c,j) = tfrz - t_soisno(c,j) + t_soisno(c,j) = tfrz + endif + ! from Zhao (1997) and Koren (1999) supercool(c,j) = 0.0_r8 if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop .or. col%itype(c) == icol_road_perv) then @@ -1325,9 +1392,49 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & endif heatr = 0._r8 - if (xm(c,j) > 0._r8) then - h2osoi_ice(c,j) = max(0._r8, wice0(c,j)-xm(c,j)) - heatr = hm(c,j) - hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime + if (xm(c,j) > 0._r8) then !if there is excess heat to melt the ice + !h2osoi_ice(c,j) = max(0._r8, wice0(c,j)-xm(c,j)) ! no excess ice + !heatr = hm(c,j) - hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime ! on excess ice + ! excess ice modifications + if (h2osoi_ice(c,j)>0._r8) then !if there is normal soil ice + if (xm(c,j)> h2osoi_ice(c,j)) then ! if we can melt all normal ice first + xm2(c,j) = xm(c,j) - h2osoi_ice(c,j) + h2osoi_ice(c,j) = 0._r8 + if (excess_ice(c,j) > 0._r8) then ! if there is excess ice to melt + if (xm2(c,j) > excess_ice(c,j)) then ! there is still enough heat left to melt all of the ice + xm3(c,j) = xm2(c,j) - excess_ice(c,j) + excess_ice(c,j) = 0._r8 + heatr = hfus * xm3(c,j) / dtime + else ! if there is not enough heat to melt all excess ice + excess_ice(c,j) = excess_ice(c,j)-xm2(c,j) + heatr = 0._r8 + xm3(c,j) = 0._r8 + endif + else !no excess ice to melt heat soil + heatr = hfus * xm2(c,j) / dtime + endif + else ! not enough heat to melt all normal ice + h2osoi_ice(c,j) = h2osoi_ice(c,j)-xm(c,j) + heatr = 0._r8 + xm2(c,j) = 0._r8 + endif + else !no normal ice present + xm2(c,j) = xm(c,j) + if (excess_ice(c,j) > 0._r8) then ! if there is excess ice to melt + if (xm2(c,j) > excess_ice(c,j)) then ! there is still enough heat left to melt all of the ice + xm3(c,j) = xm2(c,j)-excess_ice(c,j) + excess_ice(c,j) = 0._r8 + heatr = hfus * xm3(c,j) / dtime + else ! if there is not enough heat to melt all excess ice + excess_ice(c,j) = excess_ice(c,j)-xm2(c,j) + heatr = 0._r8 + xm3(c,j) = 0._r8 + endif + else !no excess ice to melt heat soil + heatr = hfus * xm2(c,j) / dtime + endif + endif + else if (xm(c,j) < 0._r8) then if (j <= 0) then h2osoi_ice(c,j) = min(wmass0(c,j), wice0(c,j)-xm(c,j)) ! snow @@ -1373,7 +1480,8 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & endif ! end of heatr > 0 if-block if (j >= 1) then - xmf(c) = xmf(c) + hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime + xmf(c) = xmf(c) + hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime +hfus*(wexice0(c,j)-excess_ice(c,j))/dtime + exice_melt_lev(c,j)=wexice0(c,j)-excess_ice(c,j) else xmf(c) = xmf(c) + hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime endif @@ -1398,17 +1506,20 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & end do ! end of column-loop enddo ! end of level-loop + ! Needed for history file output do fc = 1,num_nolakec c = filter_nolakec(fc) eflx_snomelt(c) = qflx_snomelt(c) * hfus + exice_melt(c) = 0.0_r8 l = col%landunit(c) if (lun%urbpoi(l)) then eflx_snomelt_u(c) = eflx_snomelt(c) else if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then eflx_snomelt_r(c) = eflx_snomelt(c) end if + exice_melt(c) = exice_melt(c) + SUM( exice_melt_lev(c,:) ) / denice end do call t_stopf( 'PhaseChangebeta' ) From 46b5d64dbc81165fb08925f1956ac36948d28634 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Thu, 17 Feb 2022 18:38:53 +0100 Subject: [PATCH 07/99] Revert "add excess ice to soil temperature mod" This reverts commit d55ba7c29a9680c33289930e6260084e9b4a601b. --- src/biogeophys/SoilTemperatureMod.F90 | 129 ++------------------------ 1 file changed, 9 insertions(+), 120 deletions(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index 3647534334..ba4432cba2 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -115,7 +115,7 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter use clm_time_manager , only : get_step_size_real use clm_varpar , only : nlevsno, nlevgrnd, nlevurb, nlevmaxurbgrnd use clm_varctl , only : iulog - use clm_varcon , only : cnfac, cpice, cpliq, denh2o, denice + use clm_varcon , only : cnfac, cpice, cpliq, denh2o use landunit_varcon , only : istsoil, istcrop use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall, icol_road_perv, icol_road_imperv use BandDiagonalMod , only : BandDiagonal @@ -171,10 +171,6 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter real(r8) :: hs_top_snow(bounds%begc:bounds%endc) ! heat flux on top snow layer [W/m2] real(r8) :: hs_h2osfc(bounds%begc:bounds%endc) ! heat flux on standing water [W/m2] integer :: jbot(bounds%begc:bounds%endc) ! bottom level at each column - real(r8) :: dz_0(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) ! original layer thickness [m] - real(r8) :: z_0(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) ! original layer depth [m] - real(r8) :: zi_0(bounds%begc:bounds%endc,-nlevsno+0:nlevmaxurbgrnd) ! original layer interface level bellow layer "z" [m] - !----------------------------------------------------------------------- associate( & @@ -198,7 +194,6 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter frac_sno_eff => waterdiagnosticbulk_inst%frac_sno_eff_col , & ! Input: [real(r8) (:) ] eff. fraction of ground covered by snow (0 to 1) snow_depth => waterdiagnosticbulk_inst%snow_depth_col , & ! Input: [real(r8) (:) ] snow height (m) h2osfc => waterstatebulk_inst%h2osfc_col , & ! Input: [real(r8) (:) ] surface water (mm) - excess_ice => waterstatebulk_inst%excess_ice_col , & ! Input: [real(r8) (:,:) ] excess ice lenses (kg/m2) (new) (1:nlevgrnd) frac_h2osfc => waterdiagnosticbulk_inst%frac_h2osfc_col , & ! Input: [real(r8) (:) ] fraction of ground covered by surface water (0 to 1) @@ -276,29 +271,6 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter endif end do - - !-------------------------------------------------------------- - ! Vertical coordinates adjustment for excess ice calculations - !-------------------------------------------------------------- - ! Save original soil depth to get put them back in et the end - dz_0(begc:endc,1:nlevmaxurbgrnd)=dz(begc:endc,1:nlevmaxurbgrnd) - zi_0(begc:endc,1:nlevmaxurbgrnd)=zi(begc:endc,1:nlevmaxurbgrnd) - z_0(begc:endc,1:nlevmaxurbgrnd)=z(begc:endc,1:nlevmaxurbgrnd) - ! Adjust column depth for excess ice thickness - do fc = 1,num_nolakec - c = filter_nolakec(fc) - l = col%landunit(c) - if( lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then - dz(c,1:nlevmaxurbgrnd)=dz(c,1:nlevmaxurbgrnd)+excess_ice(c,1:nlevmaxurbgrnd)/denice ! add extra layer thickness - do j=1,nlevmaxurbgrnd ! if excess ice amount dropped to zero there will be no adjustment - zi(c,j) = zi(c,j) + sum(excess_ice(c,1:j)) / denice - z(c,j) = (zi(c,j-1) + zi(c,j)) * 0.5_r8 - end do - endif - end do - - - !------------------------------------------------------ ! Compute ground surface and soil temperatures !------------------------------------------------------ @@ -516,23 +488,6 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter dhsdT(bounds%begc:bounds%endc), & soilstate_inst, waterstatebulk_inst, waterdiagnosticbulk_inst, waterfluxbulk_inst, energyflux_inst, temperature_inst) - !-------------------------------------------------------------- - ! Vertical coordinates adjustment for excess ice calculations - !-------------------------------------------------------------- - ! bringing back the soil depth to the original state - ! Adjust column depth for excess ice thickness - do fc = 1,num_nolakec - c = filter_nolakec(fc) - l = col%landunit(c) - if( lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then - dz(c,1:nlevmaxurbgrnd)=dz_0(c,1:nlevmaxurbgrnd) - zi(c,1:nlevmaxurbgrnd)=zi_0(c,1:nlevmaxurbgrnd) - z(c,1:nlevmaxurbgrnd)=z_0(c,1:nlevmaxurbgrnd) - endif - end do - - - if ( IsProgBuildTemp() )then call BuildingTemperature(bounds, num_urbanl, filter_urbanl, num_nolakec, filter_nolakec, & tk(bounds%begc:bounds%endc, :), urbanparams_inst, & @@ -673,7 +628,6 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter h2osno_no_layers => waterstatebulk_inst%h2osno_no_layers_col , & ! Input: [real(r8) (:) ] snow not resolved into layers (mm H2O) h2osoi_liq => waterstatebulk_inst%h2osoi_liq_col , & ! Input: [real(r8) (:,:) ] liquid water (kg/m2) h2osoi_ice => waterstatebulk_inst%h2osoi_ice_col , & ! Input: [real(r8) (:,:) ] ice lens (kg/m2) - excess_ice => waterstatebulk_inst%excess_ice_col , & ! Input: [real(r8) (:,:) ] excess ice lenses (kg/m2) (new) (1:nlevgrnd) bw => waterdiagnosticbulk_inst%bw_col , & ! Output: [real(r8) (:,:) ] partial density of water in the snow pack (ice + liquid) [kg/m3] tkmg => soilstate_inst%tkmg_col , & ! Input: [real(r8) (:,:) ] thermal conductivity, soil minerals [W/m-K] @@ -700,8 +654,7 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter col%itype(c) /= icol_roof .and. col%itype(c) /= icol_road_imperv) .or. & (col%itype(c) == icol_road_imperv .and. j > nlev_improad(l))) then - ! TODO recalculate watsat and satw to have excess ice included - satw = (h2osoi_liq(c,j)/denh2o + h2osoi_ice(c,j)/denice +excess_ice(c,j)/denice)/(dz(c,j)*watsat(c,j)) + satw = (h2osoi_liq(c,j)/denh2o + h2osoi_ice(c,j)/denice)/(dz(c,j)*watsat(c,j)) satw = min(1._r8, satw) if (satw > .1e-6_r8) then if (t_soisno(c,j) >= tfrz) then ! Unfrozen soil @@ -710,7 +663,7 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter dke = satw end if fl = (h2osoi_liq(c,j)/(denh2o*dz(c,j))) / (h2osoi_liq(c,j)/(denh2o*dz(c,j)) + & - h2osoi_ice(c,j)/(denice*dz(c,j))+excess_ice(c,j)/denice) + h2osoi_ice(c,j)/(denice*dz(c,j))) dksat = tkmg(c,j)*tkwat**(fl*watsat(c,j))*tkice**((1._r8-fl)*watsat(c,j)) thk(c,j) = dke*dksat + (1._r8-dke)*tkdry(c,j) else @@ -803,7 +756,7 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter .and. col%itype(c) /= icol_sunwall .and. col%itype(c) /= icol_shadewall .and. & col%itype(c) /= icol_roof .and. col%itype(c) /= icol_road_imperv) .or. & (col%itype(c) == icol_road_imperv .and. j > nlev_improad(l))) then - cv(c,j) = csol(c,j)*(1._r8-watsat(c,j))*dz(c,j) + (h2osoi_ice(c,j)*cpice + h2osoi_liq(c,j)*cpliq) + excess_ice(c,j)*cpice + cv(c,j) = csol(c,j)*(1._r8-watsat(c,j))*dz(c,j) + (h2osoi_ice(c,j)*cpice + h2osoi_liq(c,j)*cpliq) if (j > nbedrock(c)) cv(c,j) = csol_bedrock*dz(c,j) else if (lun%itype(l) == istwet) then cv(c,j) = (h2osoi_ice(c,j)*cpice + h2osoi_liq(c,j)*cpliq) @@ -1104,7 +1057,7 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & use clm_time_manager , only : get_step_size_real use clm_varpar , only : nlevsno, nlevgrnd, nlevurb, nlevmaxurbgrnd use clm_varctl , only : iulog - use clm_varcon , only : tfrz, hfus, grav, denice + use clm_varcon , only : tfrz, hfus, grav use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall, icol_road_perv use landunit_varcon , only : istsoil, istcrop, istice ! @@ -1135,11 +1088,6 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & real(r8) :: propor !proportionality constant (-) real(r8) :: tinc(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) !t(n+1)-t(n) [K] real(r8) :: smp !frozen water potential (mm) - real(r8) :: xm2(bounds%begc:bounds%endc,-nlevsno+1:nlevgrnd) !xm variable [kg/m2] - real(r8) :: xm3(bounds%begc:bounds%endc,-nlevsno+1:nlevgrnd) !xm variable [kg/m2] - real(r8) :: wexice0(bounds%begc:bounds%endc,-nlevsno+1:nlevgrnd)!initial mass of excess_ice at the timestep (kg/m2) - - !----------------------------------------------------------------------- call t_startf( 'PhaseChangebeta' ) @@ -1161,11 +1109,6 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & h2osno_no_layers => waterstatebulk_inst%h2osno_no_layers_col , & ! Output: [real(r8) (:) ] snow not resolved into layers (mm H2O) h2osoi_liq => waterstatebulk_inst%h2osoi_liq_col , & ! Output: [real(r8) (:,:) ] liquid water (kg/m2) (new) h2osoi_ice => waterstatebulk_inst%h2osoi_ice_col , & ! Output: [real(r8) (:,:) ] ice lens (kg/m2) (new) - excess_ice => waterstatebulk_inst%excess_ice_col , & ! Input: [real(r8) (:,:) ] excess ice lenses (kg/m2) (new) (1:nlevgrnd) - init_exice => waterstatebulk_inst%init_exice , & ! Input: [real(r8) (:) ] excess soil ice initial - exice_melt => waterstatebulk_inst%exice_melt , & ! Input: [real(r8) (:) ] excess soil ice - exice_melt_lev => waterstatebulk_inst%exice_melt_lev , & ! Input: [real(r8) (:,:) ] excess soil ice - qflx_snow_drain => waterfluxbulk_inst%qflx_snow_drain_col , & ! Output: [real(r8) (:) ] drainage from snow pack qflx_snofrz_lyr => waterfluxbulk_inst%qflx_snofrz_lyr_col , & ! Output: [real(r8) (:,:) ] snow freezing rate (positive definite) (col,lyr) [kg m-2 s-1] @@ -1209,12 +1152,9 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & imelt(c,j) = 0 hm(c,j) = 0._r8 xm(c,j) = 0._r8 - xm2(c,j)=0._r8 - xm3(c,j)=0._r8 wice0(c,j) = h2osoi_ice(c,j) wliq0(c,j) = h2osoi_liq(c,j) wmass0(c,j) = h2osoi_ice(c,j) + h2osoi_liq(c,j) - wexice0(c,j)=excess_ice(c,j) endif ! end of snow layer if-block if (j <= 0) then @@ -1271,13 +1211,6 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & t_soisno(c,j) = tfrz endif - ! melt excess ice after normal ice - if (excess_ice(c,j) > 0._r8 .AND. t_soisno(c,j) > tfrz) then - imelt(c,j) = 1 - tinc(c,j) = tfrz - t_soisno(c,j) - t_soisno(c,j) = tfrz - endif - ! from Zhao (1997) and Koren (1999) supercool(c,j) = 0.0_r8 if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop .or. col%itype(c) == icol_road_perv) then @@ -1392,49 +1325,9 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & endif heatr = 0._r8 - if (xm(c,j) > 0._r8) then !if there is excess heat to melt the ice - !h2osoi_ice(c,j) = max(0._r8, wice0(c,j)-xm(c,j)) ! no excess ice - !heatr = hm(c,j) - hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime ! on excess ice - ! excess ice modifications - if (h2osoi_ice(c,j)>0._r8) then !if there is normal soil ice - if (xm(c,j)> h2osoi_ice(c,j)) then ! if we can melt all normal ice first - xm2(c,j) = xm(c,j) - h2osoi_ice(c,j) - h2osoi_ice(c,j) = 0._r8 - if (excess_ice(c,j) > 0._r8) then ! if there is excess ice to melt - if (xm2(c,j) > excess_ice(c,j)) then ! there is still enough heat left to melt all of the ice - xm3(c,j) = xm2(c,j) - excess_ice(c,j) - excess_ice(c,j) = 0._r8 - heatr = hfus * xm3(c,j) / dtime - else ! if there is not enough heat to melt all excess ice - excess_ice(c,j) = excess_ice(c,j)-xm2(c,j) - heatr = 0._r8 - xm3(c,j) = 0._r8 - endif - else !no excess ice to melt heat soil - heatr = hfus * xm2(c,j) / dtime - endif - else ! not enough heat to melt all normal ice - h2osoi_ice(c,j) = h2osoi_ice(c,j)-xm(c,j) - heatr = 0._r8 - xm2(c,j) = 0._r8 - endif - else !no normal ice present - xm2(c,j) = xm(c,j) - if (excess_ice(c,j) > 0._r8) then ! if there is excess ice to melt - if (xm2(c,j) > excess_ice(c,j)) then ! there is still enough heat left to melt all of the ice - xm3(c,j) = xm2(c,j)-excess_ice(c,j) - excess_ice(c,j) = 0._r8 - heatr = hfus * xm3(c,j) / dtime - else ! if there is not enough heat to melt all excess ice - excess_ice(c,j) = excess_ice(c,j)-xm2(c,j) - heatr = 0._r8 - xm3(c,j) = 0._r8 - endif - else !no excess ice to melt heat soil - heatr = hfus * xm2(c,j) / dtime - endif - endif - + if (xm(c,j) > 0._r8) then + h2osoi_ice(c,j) = max(0._r8, wice0(c,j)-xm(c,j)) + heatr = hm(c,j) - hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime else if (xm(c,j) < 0._r8) then if (j <= 0) then h2osoi_ice(c,j) = min(wmass0(c,j), wice0(c,j)-xm(c,j)) ! snow @@ -1480,8 +1373,7 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & endif ! end of heatr > 0 if-block if (j >= 1) then - xmf(c) = xmf(c) + hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime +hfus*(wexice0(c,j)-excess_ice(c,j))/dtime - exice_melt_lev(c,j)=wexice0(c,j)-excess_ice(c,j) + xmf(c) = xmf(c) + hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime else xmf(c) = xmf(c) + hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime endif @@ -1506,20 +1398,17 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & end do ! end of column-loop enddo ! end of level-loop - ! Needed for history file output do fc = 1,num_nolakec c = filter_nolakec(fc) eflx_snomelt(c) = qflx_snomelt(c) * hfus - exice_melt(c) = 0.0_r8 l = col%landunit(c) if (lun%urbpoi(l)) then eflx_snomelt_u(c) = eflx_snomelt(c) else if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then eflx_snomelt_r(c) = eflx_snomelt(c) end if - exice_melt(c) = exice_melt(c) + SUM( exice_melt_lev(c,:) ) / denice end do call t_stopf( 'PhaseChangebeta' ) From 3ccbed909d3c8123b4abcb59dcd620fd30ec1949 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Wed, 30 Mar 2022 10:33:34 +0200 Subject: [PATCH 08/99] fixed restart --- src/biogeophys/WaterStateType.F90 | 96 +++++++++++++++++++------------ 1 file changed, 59 insertions(+), 37 deletions(-) diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index 4c0575c8b7..e5a4cf16e5 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -53,7 +53,7 @@ module WaterStateType real(r8) :: aquifer_water_baseline ! baseline value for water in the unconfined aquifer (wa_col) for this bulk / tracer (mm) real(r8), pointer :: excess_ice_col (:,:) ! col excess ice lenses (kg/m2) (new) (1:nlevgrnd) - real(r8), pointer :: init_exice (:,:) ! initial value of col excess ice lens/(kg/m2) (new) (1:nlevgrnd) + real(r8), pointer :: init_exice (:,:) ! initial value of col excess ice lens/(m/m) (new) (1:nlevgrnd) real(r8), pointer :: exice_melt_lev (:,:) ! col excess ice melting (m) (new) real(r8), pointer :: exice_melt (:) ! column-wide excess ice melting (m) (new) @@ -164,15 +164,15 @@ subroutine InitAllocate(this, bounds, tracer_vars) call AllocateVar2d(var = this%excess_ice_col, name = 'excess_ice_col', & container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_column, & - dim2beg = 1, dim2end = nlevmaxurbgrnd) + dim2beg = -nlevsno+1, dim2end = nlevmaxurbgrnd) call AllocateVar2d(var = this%init_exice, name = 'init_exice', & container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_column, & - dim2beg = 1, dim2end = nlevmaxurbgrnd) + dim2beg = -nlevsno+1, dim2end = nlevmaxurbgrnd) call AllocateVar2d(var = this%exice_melt_lev, name = 'exice_melt_lev', & container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_column, & - dim2beg = 1, dim2end = nlevmaxurbgrnd) + dim2beg = -nlevsno+1, dim2end = nlevmaxurbgrnd) call AllocateVar1d(var = this%exice_melt, name = 'exice_melt', & container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_column) @@ -299,7 +299,13 @@ subroutine InitHistory(this, bounds, use_aquifer_layer) call hist_addfld2d (fname='EXCESS_ICE', units='kg/m2', type2d='levsoi', & avgflag='A', long_name='excess soil ice (vegetated landunits only)', & ptr_col=this%excess_ice_col, l2g_scale_type='veg') - data2dptr => this%excess_ice_col(begc:endc,1:nlevsoi) + + data2dptr => this%init_exice(begc:endc,1:nlevsoi) + call hist_addfld2d (fname='EXICE_INIT', units='m/m', type2d='levsoi', & + avgflag='A', long_name='initial excess soil ice (vegetated landunits only)', & + ptr_col=this%excess_ice_col, l2g_scale_type='veg') + + data2dptr => this%exice_melt_lev(begc:endc,1:nlevsoi) call hist_addfld2d (fname='EXICE_MELT_LEV', units='kg/m2', type2d='levsoi', & avgflag='A', long_name='melt from excess ice per layer (vegetated landunits only)', & ptr_col=this%exice_melt_lev, l2g_scale_type='veg') @@ -341,7 +347,7 @@ subroutine InitCold(this, bounds, & real(r8) , intent(in) :: watsat_col(bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) real(r8) , intent(in) :: t_soisno_col(bounds%begc:, -nlevsno+1:) ! col soil temperature (Kelvin) logical , intent(in) :: use_aquifer_layer ! whether an aquifer layer is used in this run - character(len=*) , intent(in) :: NLFilename ! Namelist filename + character(len=*) , intent(in) :: NLFilename ! Namelist filename ! ! !LOCAL VARIABLES: integer :: c,j,l,nlevs,g @@ -548,13 +554,12 @@ subroutine InitCold(this, bounds, & this%dynbal_baseline_ice_col(bounds%begc:bounds%endc) = 0._r8 !Initialize excess ice - write(iulog,*) 'nfl =', NLFilename if (use_excess_ice .and. NLFilename /= '') then ! enforce initialization with 0 for everything - this%init_exice(:,:)=0.0_r8 - this%excess_ice_col(:,:)=0.0_r8 - this%exice_melt_lev(:,:)=0.0_r8 - this%exice_melt(:)=0.0_r8 + this%init_exice(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 + this%excess_ice_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 + this%exice_melt_lev(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 + this%exice_melt(bounds%begc:bounds%endc)=0.0_r8 call this%exicestream%Init(bounds, NLFilename) ! get initial fraction of excess ice per column @@ -575,22 +580,22 @@ subroutine InitCold(this, bounds, & this%excess_ice_col(c,j) = 0.0_r8 endif this%init_exice(c,j) = 0.0_r8 - this%init_exice(c,j) = this%excess_ice_col(c,j) + this%init_exice(c,j) = this%exicestream%exice_bulk(g) end do endif else ! just in case zeros for lakes and other columns - this%excess_ice_col(c,:) = 0.0_r8 - this%init_exice(c,:) = 0.0_r8 + this%excess_ice_col(c,-nlevsno+1:nlevmaxurbgrnd) = 0.0_r8 + this%init_exice(c,-nlevsno+1:nlevmaxurbgrnd) = 0.0_r8 end if - enddo - this%exice_melt_lev(:,:)=0.0_r8 - this%exice_melt(:)=0.0_r8 + enddo + this%exice_melt_lev(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 + this%exice_melt(bounds%begc:bounds%endc)=0.0_r8 else - this%init_exice(:,:)=0.0_r8 - this%excess_ice_col(:,:)=0.0_r8 - this%exice_melt_lev(:,:)=0.0_r8 - this%exice_melt(:)=0.0_r8 + this%init_exice(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 + this%excess_ice_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 + this%exice_melt_lev(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 + this%exice_melt(bounds%begc:bounds%endc)=0.0_r8 end if end associate @@ -718,22 +723,39 @@ subroutine Restart(this, bounds, ncid, flag, & interpinic_flag='interp', readvar=readvar, data=this%dynbal_baseline_ice_col) ! Restart excess ice vars - call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('EXCESS_ICE'), xtype=ncd_double, & - dim1name='column', dim2name='levtot', switchdim=.true., & - long_name=this%info%lname('excess soil ice (vegetated landunits only)'), units='kg/m2', & - scale_by_thickness=.true., & - interpinic_flag='interp', readvar=readvar, data=this%excess_ice_col) - call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('EXCESS_MELT_LEV'), xtype=ncd_double, & - dim1name='column', dim2name='levtot', switchdim=.true., & - long_name=this%info%lname('melt from excess ice per layer (vegetated landunits only)'), units='kg/m2', & - scale_by_thickness=.true., & - interpinic_flag='interp', readvar=readvar, data=this%exice_melt_lev) - - call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('EXICE_MELT'), xtype=ncd_double, & - dim1name='column', & - long_name=this%info%lname('melt from excess ice (vegetated landunits only)'), units='m', & - interpinic_flag='interp', readvar=readvar, data=this%exice_melt) - + !write(iulog,*) 'restarting excess ice wars' + if (.not. use_excess_ice .and. flag == 'read') then + ! no need to even define the restart vars + this%init_exice(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 + this%excess_ice_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 + this%exice_melt_lev(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 + this%exice_melt(bounds%begc:bounds%endc)=0.0_r8 + + else + ! have to at least define them + call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('EXCESS_ICE'), xtype=ncd_double, & + dim1name='column', dim2name='levtot', switchdim=.true., & + long_name=this%info%lname('excess soil ice (vegetated landunits only)'), units='kg/m2', & + scale_by_thickness=.true., & + interpinic_flag='interp', readvar=readvar, data=this%excess_ice_col) + + call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('EXICE_INIT'), xtype=ncd_double, & + dim1name='column', dim2name='levtot', switchdim=.true., & + long_name=this%info%lname('inital excess soil ice (vegetated landunits only)'), units='m/m', & + scale_by_thickness=.false., & + interpinic_flag='interp', readvar=readvar, data=this%init_exice) + + call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('EXCESS_MELT_LEV'), xtype=ncd_double, & + dim1name='column', dim2name='levtot', switchdim=.true., & + long_name=this%info%lname('melt from excess ice per layer (vegetated landunits only)'), units='kg/m2', & + scale_by_thickness=.true., & + interpinic_flag='interp', readvar=readvar, data=this%exice_melt_lev) + + call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('EXICE_MELT'), xtype=ncd_double, & + dim1name='column', & + long_name=this%info%lname('melt from excess ice (vegetated landunits only)'), units='m', & + interpinic_flag='interp', readvar=readvar, data=this%exice_melt) + endif ! Determine volumetric soil water (for read only) if (flag == 'read' ) then do c = bounds%begc, bounds%endc From f8edb891b630427b8781ea93ce579ea492a22af6 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Fri, 1 Apr 2022 19:01:44 +0200 Subject: [PATCH 09/99] first layer should have no excess ice. --- src/biogeophys/WaterStateType.F90 | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index e5a4cf16e5..cdbd232004 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -573,15 +573,14 @@ subroutine InitCold(this, bounds, & else nbedrock = nlevsoi endif - do j = 1, nlevmaxurbgrnd + do j = 2, nlevmaxurbgrnd ! ignore first layer if (j Date: Thu, 28 Apr 2022 14:07:24 +0200 Subject: [PATCH 10/99] fix stream memory leak and restart from old files --- src/biogeophys/WaterStateType.F90 | 22 ++++++------ src/cpl/share_esmf/ExcessIceStreamType.F90 | 39 +++++++++++++++++++++- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index cdbd232004..ab7517847e 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -353,6 +353,7 @@ subroutine InitCold(this, bounds, & integer :: c,j,l,nlevs,g integer :: nbedrock real(r8) :: ratio + real(r8) :: exice_bulk_init(bounds%begc:bounds%endc) !----------------------------------------------------------------------- SHR_ASSERT_ALL_FL((ubound(h2osno_input_col) == (/bounds%endc/)) , sourcefile, __LINE__) @@ -562,7 +563,7 @@ subroutine InitCold(this, bounds, & this%exice_melt(bounds%begc:bounds%endc)=0.0_r8 call this%exicestream%Init(bounds, NLFilename) ! get initial fraction of excess ice per column - + call this%exicestream%CalcExcessIce(bounds, exice_bulk_init) do c = bounds%begc,bounds%endc g = col%gridcell(c) l = col%landunit(c) @@ -573,19 +574,20 @@ subroutine InitCold(this, bounds, & else nbedrock = nlevsoi endif - do j = 2, nlevmaxurbgrnd ! ignore first layer - if (j Date: Fri, 29 Apr 2022 13:29:22 +0200 Subject: [PATCH 11/99] excess ice restart from old files --- src/biogeophys/WaterStateBulkType.F90 | 18 ++++-- src/biogeophys/WaterStateType.F90 | 86 +++++++++++++++++++++++++-- src/biogeophys/WaterType.F90 | 26 ++++++-- src/main/clm_instMod.F90 | 15 +++-- 4 files changed, 123 insertions(+), 22 deletions(-) diff --git a/src/biogeophys/WaterStateBulkType.F90 b/src/biogeophys/WaterStateBulkType.F90 index 18b9f34e3e..b317a4d32c 100644 --- a/src/biogeophys/WaterStateBulkType.F90 +++ b/src/biogeophys/WaterStateBulkType.F90 @@ -188,7 +188,7 @@ end subroutine InitBulkCold !------------------------------------------------------------------------ subroutine RestartBulk(this, bounds, ncid, flag, & - watsat_col) + watsat_col, NLFilename, t_soisno_col) ! ! !DESCRIPTION: ! Read/Write module information to/from restart file. @@ -196,6 +196,7 @@ subroutine RestartBulk(this, bounds, ncid, flag, & ! !USES: use ncdio_pio , only : file_desc_t, ncd_double use restUtilMod + use controlMod , only : use_excess_ice ! ! !ARGUMENTS: class(waterstatebulk_type), intent(in) :: this @@ -203,6 +204,8 @@ subroutine RestartBulk(this, bounds, ncid, flag, & type(file_desc_t), intent(inout) :: ncid ! netcdf id character(len=*) , intent(in) :: flag ! 'read' or 'write' real(r8) , intent(in) :: watsat_col (bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) + character(len=*) , intent(in), optional :: NLFilename ! Namelist filename + real(r8) , intent(in), optional :: t_soisno_col(bounds%begc:bounds%endc,:) ! Soil column temperature (Kelvin) ! ! !LOCAL VARIABLES: integer :: c,l,j @@ -210,10 +213,15 @@ subroutine RestartBulk(this, bounds, ncid, flag, & !------------------------------------------------------------------------ SHR_ASSERT_ALL_FL((ubound(watsat_col) == (/bounds%endc,nlevmaxurbgrnd/)) , sourcefile, __LINE__) - - call this%restart (bounds, ncid, flag=flag, & - watsat_col=watsat_col(bounds%begc:bounds%endc,:)) - + if(use_excess_ice .and. flag == 'read') then + call this%restart (bounds, ncid, flag=flag, & + watsat_col=watsat_col(bounds%begc:bounds%endc,:), & + NLFilename= NLFilename, & + t_soisno_col=t_soisno_col(bounds%begc:bounds%endc,:)) + else + call this%restart (bounds, ncid, flag=flag, & + watsat_col=watsat_col(bounds%begc:bounds%endc,:)) + endif call restartvar(ncid=ncid, flag=flag, & varname=this%info%fname('INT_SNOW'), & diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index ab7517847e..7fde8cedaf 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -353,7 +353,7 @@ subroutine InitCold(this, bounds, & integer :: c,j,l,nlevs,g integer :: nbedrock real(r8) :: ratio - real(r8) :: exice_bulk_init(bounds%begc:bounds%endc) + real(r8) :: exice_bulk_init(bounds%begc:bounds%endc) ! initial excess ice amount (m/m) !----------------------------------------------------------------------- SHR_ASSERT_ALL_FL((ubound(h2osno_input_col) == (/bounds%endc/)) , sourcefile, __LINE__) @@ -603,15 +603,16 @@ end subroutine InitCold !------------------------------------------------------------------------ subroutine Restart(this, bounds, ncid, flag, & - watsat_col) + watsat_col, NLFilename, t_soisno_col) ! ! !DESCRIPTION: ! Read/Write module information to/from restart file. ! ! !USES: - use clm_varcon , only : denice, denh2o, pondmx, watmin - use landunit_varcon , only : istcrop, istdlak, istsoil + use clm_varcon , only : denice, denh2o, pondmx, watmin, tfrz + use landunit_varcon , only : istcrop, istdlak, istsoil, istice use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall + use column_varcon , only : icol_road_imperv, icol_road_perv use clm_time_manager , only : is_first_step, is_restart use clm_varctl , only : bound_h2osoi use ncdio_pio , only : file_desc_t, ncd_double @@ -623,16 +624,28 @@ subroutine Restart(this, bounds, ncid, flag, & type(file_desc_t), intent(inout) :: ncid ! netcdf id character(len=*) , intent(in) :: flag ! 'read' or 'write' real(r8) , intent(in) :: watsat_col (bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) + character(len=*) , intent(in), optional :: NLFilename ! Namelist filename + real(r8) , intent(in), optional :: t_soisno_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) ! Soil column temperature (Kelvin) ! ! !LOCAL VARIABLES: - integer :: p,c,l,j,nlevs + integer :: p,c,l,j,nlevs,g + integer :: nbedrock logical :: readvar real(r8) :: maxwatsat ! maximum porosity real(r8) :: excess ! excess volumetric soil water real(r8) :: totwat ! total soil water (mm) + character(len=256) :: l_NLFilename !local namelist filename var + real(r8) :: l_t_soisno_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) !local soil column temperature (Kelvin) + real(r8) :: exice_bulk_init(bounds%begc:bounds%endc) !Initial excess ice ammout (m/m) !------------------------------------------------------------------------ - + l_NLFilename = '' + l_t_soisno_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) = tfrz + 1.0_r8 + if (present(NLFilename)) then + l_NLFilename = NLFilename + l_t_soisno_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) = t_soisno_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) + end if SHR_ASSERT_ALL_FL((ubound(watsat_col) == (/bounds%endc,nlevmaxurbgrnd/)) , sourcefile, __LINE__) + SHR_ASSERT_ALL_FL((ubound(t_soisno_col) == (/bounds%endc,nlevmaxurbgrnd/)) , sourcefile, __LINE__) call restartvar(ncid=ncid, flag=flag, & varname=this%info%fname('H2OSFC'), & @@ -730,7 +743,68 @@ subroutine Restart(this, bounds, ncid, flag, & this%excess_ice_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 this%exice_melt_lev(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 this%exice_melt(bounds%begc:bounds%endc)=0.0_r8 + else if (use_excess_ice .and. flag == 'read') then + ! try to read the first variable + call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('EXCESS_ICE'), xtype=ncd_double, & + dim1name='column', dim2name='levtot', switchdim=.true., & + long_name=this%info%lname('excess soil ice (vegetated landunits only)'), units='kg/m2', & + scale_by_thickness=.true., & + interpinic_flag='interp', readvar=readvar, data=this%excess_ice_col) + if (.not. readvar) then + ! did not read the first variable + this%init_exice(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 + this%excess_ice_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 + this%exice_melt_lev(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 + this%exice_melt(bounds%begc:bounds%endc)=0.0_r8 + call this%exicestream%Init(bounds, l_NLFilename) ! get initial fraction of excess ice per column + call this%exicestream%CalcExcessIce(bounds, exice_bulk_init) + do c = bounds%begc,bounds%endc + g = col%gridcell(c) + l = col%landunit(c) + if (.not. lun%lakpoi(l)) then !not lake + if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then + if (use_bedrock) then + nbedrock = col%nbedrock(c) + else + nbedrock = nlevsoi + endif + do j = 2, nlevmaxurbgrnd ! ignore first layer + if (j Date: Fri, 29 Apr 2022 15:02:30 +0200 Subject: [PATCH 12/99] Revert "excess ice restart from old files" This reverts commit 54ccc3b7be5de6db765691b63b77f74b1673c199. --- src/biogeophys/WaterStateBulkType.F90 | 18 ++---- src/biogeophys/WaterStateType.F90 | 86 ++------------------------- src/biogeophys/WaterType.F90 | 26 ++------ src/main/clm_instMod.F90 | 15 ++--- 4 files changed, 22 insertions(+), 123 deletions(-) diff --git a/src/biogeophys/WaterStateBulkType.F90 b/src/biogeophys/WaterStateBulkType.F90 index b317a4d32c..18b9f34e3e 100644 --- a/src/biogeophys/WaterStateBulkType.F90 +++ b/src/biogeophys/WaterStateBulkType.F90 @@ -188,7 +188,7 @@ end subroutine InitBulkCold !------------------------------------------------------------------------ subroutine RestartBulk(this, bounds, ncid, flag, & - watsat_col, NLFilename, t_soisno_col) + watsat_col) ! ! !DESCRIPTION: ! Read/Write module information to/from restart file. @@ -196,7 +196,6 @@ subroutine RestartBulk(this, bounds, ncid, flag, & ! !USES: use ncdio_pio , only : file_desc_t, ncd_double use restUtilMod - use controlMod , only : use_excess_ice ! ! !ARGUMENTS: class(waterstatebulk_type), intent(in) :: this @@ -204,8 +203,6 @@ subroutine RestartBulk(this, bounds, ncid, flag, & type(file_desc_t), intent(inout) :: ncid ! netcdf id character(len=*) , intent(in) :: flag ! 'read' or 'write' real(r8) , intent(in) :: watsat_col (bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) - character(len=*) , intent(in), optional :: NLFilename ! Namelist filename - real(r8) , intent(in), optional :: t_soisno_col(bounds%begc:bounds%endc,:) ! Soil column temperature (Kelvin) ! ! !LOCAL VARIABLES: integer :: c,l,j @@ -213,15 +210,10 @@ subroutine RestartBulk(this, bounds, ncid, flag, & !------------------------------------------------------------------------ SHR_ASSERT_ALL_FL((ubound(watsat_col) == (/bounds%endc,nlevmaxurbgrnd/)) , sourcefile, __LINE__) - if(use_excess_ice .and. flag == 'read') then - call this%restart (bounds, ncid, flag=flag, & - watsat_col=watsat_col(bounds%begc:bounds%endc,:), & - NLFilename= NLFilename, & - t_soisno_col=t_soisno_col(bounds%begc:bounds%endc,:)) - else - call this%restart (bounds, ncid, flag=flag, & - watsat_col=watsat_col(bounds%begc:bounds%endc,:)) - endif + + call this%restart (bounds, ncid, flag=flag, & + watsat_col=watsat_col(bounds%begc:bounds%endc,:)) + call restartvar(ncid=ncid, flag=flag, & varname=this%info%fname('INT_SNOW'), & diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index 7fde8cedaf..ab7517847e 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -353,7 +353,7 @@ subroutine InitCold(this, bounds, & integer :: c,j,l,nlevs,g integer :: nbedrock real(r8) :: ratio - real(r8) :: exice_bulk_init(bounds%begc:bounds%endc) ! initial excess ice amount (m/m) + real(r8) :: exice_bulk_init(bounds%begc:bounds%endc) !----------------------------------------------------------------------- SHR_ASSERT_ALL_FL((ubound(h2osno_input_col) == (/bounds%endc/)) , sourcefile, __LINE__) @@ -603,16 +603,15 @@ end subroutine InitCold !------------------------------------------------------------------------ subroutine Restart(this, bounds, ncid, flag, & - watsat_col, NLFilename, t_soisno_col) + watsat_col) ! ! !DESCRIPTION: ! Read/Write module information to/from restart file. ! ! !USES: - use clm_varcon , only : denice, denh2o, pondmx, watmin, tfrz - use landunit_varcon , only : istcrop, istdlak, istsoil, istice + use clm_varcon , only : denice, denh2o, pondmx, watmin + use landunit_varcon , only : istcrop, istdlak, istsoil use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall - use column_varcon , only : icol_road_imperv, icol_road_perv use clm_time_manager , only : is_first_step, is_restart use clm_varctl , only : bound_h2osoi use ncdio_pio , only : file_desc_t, ncd_double @@ -624,28 +623,16 @@ subroutine Restart(this, bounds, ncid, flag, & type(file_desc_t), intent(inout) :: ncid ! netcdf id character(len=*) , intent(in) :: flag ! 'read' or 'write' real(r8) , intent(in) :: watsat_col (bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) - character(len=*) , intent(in), optional :: NLFilename ! Namelist filename - real(r8) , intent(in), optional :: t_soisno_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) ! Soil column temperature (Kelvin) ! ! !LOCAL VARIABLES: - integer :: p,c,l,j,nlevs,g - integer :: nbedrock + integer :: p,c,l,j,nlevs logical :: readvar real(r8) :: maxwatsat ! maximum porosity real(r8) :: excess ! excess volumetric soil water real(r8) :: totwat ! total soil water (mm) - character(len=256) :: l_NLFilename !local namelist filename var - real(r8) :: l_t_soisno_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) !local soil column temperature (Kelvin) - real(r8) :: exice_bulk_init(bounds%begc:bounds%endc) !Initial excess ice ammout (m/m) !------------------------------------------------------------------------ - l_NLFilename = '' - l_t_soisno_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) = tfrz + 1.0_r8 - if (present(NLFilename)) then - l_NLFilename = NLFilename - l_t_soisno_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) = t_soisno_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) - end if + SHR_ASSERT_ALL_FL((ubound(watsat_col) == (/bounds%endc,nlevmaxurbgrnd/)) , sourcefile, __LINE__) - SHR_ASSERT_ALL_FL((ubound(t_soisno_col) == (/bounds%endc,nlevmaxurbgrnd/)) , sourcefile, __LINE__) call restartvar(ncid=ncid, flag=flag, & varname=this%info%fname('H2OSFC'), & @@ -743,68 +730,7 @@ subroutine Restart(this, bounds, ncid, flag, & this%excess_ice_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 this%exice_melt_lev(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 this%exice_melt(bounds%begc:bounds%endc)=0.0_r8 - else if (use_excess_ice .and. flag == 'read') then - ! try to read the first variable - call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('EXCESS_ICE'), xtype=ncd_double, & - dim1name='column', dim2name='levtot', switchdim=.true., & - long_name=this%info%lname('excess soil ice (vegetated landunits only)'), units='kg/m2', & - scale_by_thickness=.true., & - interpinic_flag='interp', readvar=readvar, data=this%excess_ice_col) - if (.not. readvar) then - ! did not read the first variable - this%init_exice(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 - this%excess_ice_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 - this%exice_melt_lev(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 - this%exice_melt(bounds%begc:bounds%endc)=0.0_r8 - call this%exicestream%Init(bounds, l_NLFilename) ! get initial fraction of excess ice per column - call this%exicestream%CalcExcessIce(bounds, exice_bulk_init) - do c = bounds%begc,bounds%endc - g = col%gridcell(c) - l = col%landunit(c) - if (.not. lun%lakpoi(l)) then !not lake - if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then - if (use_bedrock) then - nbedrock = col%nbedrock(c) - else - nbedrock = nlevsoi - endif - do j = 2, nlevmaxurbgrnd ! ignore first layer - if (j Date: Mon, 16 May 2022 12:16:13 +0200 Subject: [PATCH 13/99] excess calc. and melt in soiltemperaturemod --- src/biogeophys/SoilTemperatureMod.F90 | 108 ++++++++++++++++++++---- src/biogeophys/TotalWaterAndHeatMod.F90 | 5 +- 2 files changed, 96 insertions(+), 17 deletions(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index ba4432cba2..f96fee7558 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -115,7 +115,7 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter use clm_time_manager , only : get_step_size_real use clm_varpar , only : nlevsno, nlevgrnd, nlevurb, nlevmaxurbgrnd use clm_varctl , only : iulog - use clm_varcon , only : cnfac, cpice, cpliq, denh2o + use clm_varcon , only : cnfac, cpice, cpliq, denh2o, denice use landunit_varcon , only : istsoil, istcrop use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall, icol_road_perv, icol_road_imperv use BandDiagonalMod , only : BandDiagonal @@ -171,6 +171,10 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter real(r8) :: hs_top_snow(bounds%begc:bounds%endc) ! heat flux on top snow layer [W/m2] real(r8) :: hs_h2osfc(bounds%begc:bounds%endc) ! heat flux on standing water [W/m2] integer :: jbot(bounds%begc:bounds%endc) ! bottom level at each column + real(r8) :: dz_0(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) ! original layer thickness [m] + real(r8) :: z_0(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) ! original layer depth [m] + real(r8) :: zi_0(bounds%begc:bounds%endc,-nlevsno+0:nlevmaxurbgrnd) ! original layer interface level bellow layer "z" [m] + !----------------------------------------------------------------------- associate( & @@ -194,6 +198,7 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter frac_sno_eff => waterdiagnosticbulk_inst%frac_sno_eff_col , & ! Input: [real(r8) (:) ] eff. fraction of ground covered by snow (0 to 1) snow_depth => waterdiagnosticbulk_inst%snow_depth_col , & ! Input: [real(r8) (:) ] snow height (m) h2osfc => waterstatebulk_inst%h2osfc_col , & ! Input: [real(r8) (:) ] surface water (mm) + excess_ice => waterstatebulk_inst%excess_ice_col , & ! Input: [real(r8) (:,:) ] excess ice lenses (kg/m2) (new) (1:nlevgrnd) frac_h2osfc => waterdiagnosticbulk_inst%frac_h2osfc_col , & ! Input: [real(r8) (:) ] fraction of ground covered by surface water (0 to 1) @@ -271,6 +276,29 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter endif end do + + !-------------------------------------------------------------- + ! Vertical coordinates adjustment for excess ice calculations + !-------------------------------------------------------------- + ! Save original soil depth to get put them back in et the end + dz_0(begc:endc,-nlevsno+1:nlevmaxurbgrnd)=dz(begc:endc,-nlevsno+1:nlevmaxurbgrnd) + zi_0(begc:endc,-nlevsno+0:nlevmaxurbgrnd)=zi(begc:endc,-nlevsno+0:nlevmaxurbgrnd) + z_0(begc:endc,-nlevsno+1:nlevmaxurbgrnd)=z(begc:endc,-nlevsno+1:nlevmaxurbgrnd) + ! Adjust column depth for excess ice thickness + do fc = 1,num_nolakec + c = filter_nolakec(fc) + l = col%landunit(c) + if( lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then + dz(c,1:nlevmaxurbgrnd)=dz(c,1:nlevmaxurbgrnd)+excess_ice(c,1:nlevmaxurbgrnd)/denice ! add extra layer thickness + do j=1,nlevmaxurbgrnd ! if excess ice amount dropped to zero there will be no adjustment + zi(c,j) = zi(c,j) + sum(excess_ice(c,1:j)) / denice + z(c,j) = (zi(c,j-1) + zi(c,j)) * 0.5_r8 + end do + endif + end do + + + !------------------------------------------------------ ! Compute ground surface and soil temperatures !------------------------------------------------------ @@ -488,6 +516,23 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter dhsdT(bounds%begc:bounds%endc), & soilstate_inst, waterstatebulk_inst, waterdiagnosticbulk_inst, waterfluxbulk_inst, energyflux_inst, temperature_inst) + !-------------------------------------------------------------- + ! Vertical coordinates adjustment for excess ice calculations + !-------------------------------------------------------------- + ! bringing back the soil depth to the original state + ! Adjust column depth for excess ice thickness + do fc = 1,num_nolakec + c = filter_nolakec(fc) + l = col%landunit(c) + if( lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then + dz(c,1:nlevmaxurbgrnd)=dz_0(c,1:nlevmaxurbgrnd) + zi(c,1:nlevmaxurbgrnd)=zi_0(c,1:nlevmaxurbgrnd) + z(c,1:nlevmaxurbgrnd)=z_0(c,1:nlevmaxurbgrnd) + endif + end do + + + if ( IsProgBuildTemp() )then call BuildingTemperature(bounds, num_urbanl, filter_urbanl, num_nolakec, filter_nolakec, & tk(bounds%begc:bounds%endc, :), urbanparams_inst, & @@ -628,6 +673,7 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter h2osno_no_layers => waterstatebulk_inst%h2osno_no_layers_col , & ! Input: [real(r8) (:) ] snow not resolved into layers (mm H2O) h2osoi_liq => waterstatebulk_inst%h2osoi_liq_col , & ! Input: [real(r8) (:,:) ] liquid water (kg/m2) h2osoi_ice => waterstatebulk_inst%h2osoi_ice_col , & ! Input: [real(r8) (:,:) ] ice lens (kg/m2) + excess_ice => waterstatebulk_inst%excess_ice_col , & ! Input: [real(r8) (:,:) ] excess ice lenses (kg/m2) (new) (1:nlevgrnd) bw => waterdiagnosticbulk_inst%bw_col , & ! Output: [real(r8) (:,:) ] partial density of water in the snow pack (ice + liquid) [kg/m3] tkmg => soilstate_inst%tkmg_col , & ! Input: [real(r8) (:,:) ] thermal conductivity, soil minerals [W/m-K] @@ -654,7 +700,8 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter col%itype(c) /= icol_roof .and. col%itype(c) /= icol_road_imperv) .or. & (col%itype(c) == icol_road_imperv .and. j > nlev_improad(l))) then - satw = (h2osoi_liq(c,j)/denh2o + h2osoi_ice(c,j)/denice)/(dz(c,j)*watsat(c,j)) + ! TODO recalculate watsat and satw to have excess ice included + satw = (h2osoi_liq(c,j)/denh2o + h2osoi_ice(c,j)/denice +excess_ice(c,j)/denice)/(dz(c,j)*watsat(c,j)) satw = min(1._r8, satw) if (satw > .1e-6_r8) then if (t_soisno(c,j) >= tfrz) then ! Unfrozen soil @@ -663,7 +710,7 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter dke = satw end if fl = (h2osoi_liq(c,j)/(denh2o*dz(c,j))) / (h2osoi_liq(c,j)/(denh2o*dz(c,j)) + & - h2osoi_ice(c,j)/(denice*dz(c,j))) + h2osoi_ice(c,j)/(denice*dz(c,j))+excess_ice(c,j)/denice) dksat = tkmg(c,j)*tkwat**(fl*watsat(c,j))*tkice**((1._r8-fl)*watsat(c,j)) thk(c,j) = dke*dksat + (1._r8-dke)*tkdry(c,j) else @@ -756,7 +803,7 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter .and. col%itype(c) /= icol_sunwall .and. col%itype(c) /= icol_shadewall .and. & col%itype(c) /= icol_roof .and. col%itype(c) /= icol_road_imperv) .or. & (col%itype(c) == icol_road_imperv .and. j > nlev_improad(l))) then - cv(c,j) = csol(c,j)*(1._r8-watsat(c,j))*dz(c,j) + (h2osoi_ice(c,j)*cpice + h2osoi_liq(c,j)*cpliq) + cv(c,j) = csol(c,j)*(1._r8-watsat(c,j))*dz(c,j) + (h2osoi_ice(c,j)*cpice + h2osoi_liq(c,j)*cpliq) + excess_ice(c,j)*cpice if (j > nbedrock(c)) cv(c,j) = csol_bedrock*dz(c,j) else if (lun%itype(l) == istwet) then cv(c,j) = (h2osoi_ice(c,j)*cpice + h2osoi_liq(c,j)*cpliq) @@ -1057,7 +1104,7 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & use clm_time_manager , only : get_step_size_real use clm_varpar , only : nlevsno, nlevgrnd, nlevurb, nlevmaxurbgrnd use clm_varctl , only : iulog - use clm_varcon , only : tfrz, hfus, grav + use clm_varcon , only : tfrz, hfus, grav, denice use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall, icol_road_perv use landunit_varcon , only : istsoil, istcrop, istice ! @@ -1088,6 +1135,11 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & real(r8) :: propor !proportionality constant (-) real(r8) :: tinc(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) !t(n+1)-t(n) [K] real(r8) :: smp !frozen water potential (mm) + real(r8) :: xm2(bounds%begc:bounds%endc,-nlevsno+1:nlevgrnd) !xm variable [kg/m2] + real(r8) :: xm3(bounds%begc:bounds%endc,-nlevsno+1:nlevgrnd) !xm variable [kg/m2] + real(r8) :: wexice0(bounds%begc:bounds%endc,-nlevsno+1:nlevgrnd)!initial mass of excess_ice at the timestep (kg/m2) + + !----------------------------------------------------------------------- call t_startf( 'PhaseChangebeta' ) @@ -1109,6 +1161,11 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & h2osno_no_layers => waterstatebulk_inst%h2osno_no_layers_col , & ! Output: [real(r8) (:) ] snow not resolved into layers (mm H2O) h2osoi_liq => waterstatebulk_inst%h2osoi_liq_col , & ! Output: [real(r8) (:,:) ] liquid water (kg/m2) (new) h2osoi_ice => waterstatebulk_inst%h2osoi_ice_col , & ! Output: [real(r8) (:,:) ] ice lens (kg/m2) (new) + excess_ice => waterstatebulk_inst%excess_ice_col , & ! Input: [real(r8) (:,:) ] excess ice lenses (kg/m2) (new) (1:nlevgrnd) + init_exice => waterstatebulk_inst%init_exice , & ! Input: [real(r8) (:) ] excess soil ice initial + exice_melt => waterstatebulk_inst%exice_melt , & ! Input: [real(r8) (:) ] excess soil ice + exice_melt_lev => waterstatebulk_inst%exice_melt_lev , & ! Input: [real(r8) (:,:) ] excess soil ice + qflx_snow_drain => waterfluxbulk_inst%qflx_snow_drain_col , & ! Output: [real(r8) (:) ] drainage from snow pack qflx_snofrz_lyr => waterfluxbulk_inst%qflx_snofrz_lyr_col , & ! Output: [real(r8) (:,:) ] snow freezing rate (positive definite) (col,lyr) [kg m-2 s-1] @@ -1152,9 +1209,12 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & imelt(c,j) = 0 hm(c,j) = 0._r8 xm(c,j) = 0._r8 + xm2(c,j)=0._r8 + xm3(c,j)=0._r8 wice0(c,j) = h2osoi_ice(c,j) wliq0(c,j) = h2osoi_liq(c,j) - wmass0(c,j) = h2osoi_ice(c,j) + h2osoi_liq(c,j) + wexice0(c,j)=excess_ice(c,j) + wmass0(c,j) = h2osoi_ice(c,j) + h2osoi_liq(c,j) + wexice0(c,j) endif ! end of snow layer if-block if (j <= 0) then @@ -1211,6 +1271,13 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & t_soisno(c,j) = tfrz endif + ! melt excess ice after normal ice + if (excess_ice(c,j) > 0._r8 .AND. t_soisno(c,j) > tfrz) then + imelt(c,j) = 1 + tinc(c,j) = tfrz - t_soisno(c,j) + t_soisno(c,j) = tfrz + endif + ! from Zhao (1997) and Koren (1999) supercool(c,j) = 0.0_r8 if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop .or. col%itype(c) == icol_road_perv) then @@ -1325,23 +1392,30 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & endif heatr = 0._r8 - if (xm(c,j) > 0._r8) then - h2osoi_ice(c,j) = max(0._r8, wice0(c,j)-xm(c,j)) - heatr = hm(c,j) - hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime + if (xm(c,j) > 0._r8) then !if there is excess heat to melt the ice + h2osoi_ice(c,j) = max(0._r8, wice0(c,j)-xm(c,j)) + heatr = hm(c,j) - hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime + xm2(c,j) = xm(c,j) - h2osoi_ice(c,j) !excess ice modifications + if (h2osoi_ice(c,j) == 0._r8) then ! this might be redundant + if (excess_ice(c,j) >= 0._r8 .and. xm2(c,j)>0._r8 .and. j>=2) then ! if there is excess ice to melt + excess_ice(c,j) = max(0._r8,wexice0(c,j) - xm2(c,j)) + heatr = hm(c,j) - hfus * (wexice0(c,j)-excess_ice(c,j)+wice0(c,j)-h2osoi_ice(c,j)) / dtime + endif + endif !end of excess ice block else if (xm(c,j) < 0._r8) then if (j <= 0) then h2osoi_ice(c,j) = min(wmass0(c,j), wice0(c,j)-xm(c,j)) ! snow else - if (wmass0(c,j) < supercool(c,j)) then + if (wmass0(c,j) - wexice0(c,j) < supercool(c,j)) then !even if excess ice is present, it cannot refreeze h2osoi_ice(c,j) = 0._r8 else - h2osoi_ice(c,j) = min(wmass0(c,j) - supercool(c,j),wice0(c,j)-xm(c,j)) + h2osoi_ice(c,j) = min(wmass0(c,j) - wexice0(c,j) - supercool(c,j),wice0(c,j)-xm(c,j)) endif endif heatr = hm(c,j) - hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime endif - h2osoi_liq(c,j) = max(0._r8,wmass0(c,j)-h2osoi_ice(c,j)) + h2osoi_liq(c,j) = max(0._r8,wmass0(c,j)-h2osoi_ice(c,j)-excess_ice(c,j)) !melted exice is added to the respective soil layers if (abs(heatr) > 0._r8) then if (j == snl(c)+1) then @@ -1372,12 +1446,13 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & end if endif ! end of heatr > 0 if-block - if (j >= 1) then - xmf(c) = xmf(c) + hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime + if (j >= 1) then !why before it was two same statements? + xmf(c) = xmf(c) + hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime +hfus*(wexice0(c,j)-excess_ice(c,j))/dtime else xmf(c) = xmf(c) + hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime endif - + init_exice(c,j)=wexice0(c,j) + exice_melt_lev(c,j)=wexice0(c,j)-excess_ice(c,j) if (imelt(c,j) == 1 .AND. j < 1) then qflx_snomelt_lyr(c,j) = max(0._r8,(wice0(c,j)-h2osoi_ice(c,j)))/dtime qflx_snomelt(c) = qflx_snomelt(c) + qflx_snomelt_lyr(c,j) @@ -1398,16 +1473,19 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & end do ! end of column-loop enddo ! end of level-loop + ! Needed for history file output do fc = 1,num_nolakec c = filter_nolakec(fc) eflx_snomelt(c) = qflx_snomelt(c) * hfus + exice_melt(c) = 0.0_r8 l = col%landunit(c) if (lun%urbpoi(l)) then eflx_snomelt_u(c) = eflx_snomelt(c) else if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then eflx_snomelt_r(c) = eflx_snomelt(c) + exice_melt(c) = exice_melt(c) + SUM( exice_melt_lev(c,:) ) / denice end if end do diff --git a/src/biogeophys/TotalWaterAndHeatMod.F90 b/src/biogeophys/TotalWaterAndHeatMod.F90 index bfeea81949..3f4877d093 100644 --- a/src/biogeophys/TotalWaterAndHeatMod.F90 +++ b/src/biogeophys/TotalWaterAndHeatMod.F90 @@ -358,7 +358,8 @@ subroutine AccumulateSoilLiqIceMassNonLake(bounds, num_c, filter_c, & associate( & h2osoi_ice => waterstate_inst%h2osoi_ice_col , & ! Input: [real(r8) (:,:) ] ice lens (kg/m2) - h2osoi_liq => waterstate_inst%h2osoi_liq_col & ! Input: [real(r8) (:,:) ] liquid water (kg/m2) + h2osoi_liq => waterstate_inst%h2osoi_liq_col , & ! Input: [real(r8) (:,:) ] liquid water (kg/m2) + excess_ice => waterstate_inst%excess_ice_col & ! Input [real(r8) (:,:) ] excess ice (kg/m2) ) do j = 1, nlevmaxurbgrnd @@ -382,7 +383,7 @@ subroutine AccumulateSoilLiqIceMassNonLake(bounds, num_c, filter_c, & if (has_h2o) then liquid_mass(c) = liquid_mass(c) + h2osoi_liq(c,j) - ice_mass(c) = ice_mass(c) + h2osoi_ice(c,j) + ice_mass(c) = ice_mass(c) + h2osoi_ice(c,j) +excess_ice(c,j) end if end do end do From afeb00a772ead5a505ffebf952266ef810d652c8 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Mon, 16 May 2022 12:20:03 +0200 Subject: [PATCH 14/99] 0.125x0.125 initial ex. ice concentration stream --- bld/namelist_files/namelist_defaults_ctsm.xml | 4 ++-- src/cpl/share_esmf/ExcessIceStreamType.F90 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 775ed81105..54bec90957 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -2592,7 +2592,7 @@ lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts .false. -lnd/clm2/paramdata/exice_init_0.9x1.25_c20211102.nc -lnd/clm2/paramdata/finundated_inversiondata_0.9x1_ESMFmesh_cdf5_130621.nc +lnd/clm2/paramdata/exice_init_0.125x0.125_c20220516.nc +lnd/clm2/paramdata/exice_init_0.125x0.125_ESMFmesh_c20220516.nc diff --git a/src/cpl/share_esmf/ExcessIceStreamType.F90 b/src/cpl/share_esmf/ExcessIceStreamType.F90 index b857b4e214..9bafd61524 100644 --- a/src/cpl/share_esmf/ExcessIceStreamType.F90 +++ b/src/cpl/share_esmf/ExcessIceStreamType.F90 @@ -247,7 +247,7 @@ subroutine ReadNML(this, bounds, NLFilename) integer :: nml_error ! namelist i/o error flag character(len=CL) :: stream_fldFileName_exice = ' ' character(len=CL) :: stream_meshfile_exice = ' ' - character(len=CL) :: exicemapalgo = 'nn' + character(len=CL) :: exicemapalgo = 'bilinear' character(len=*), parameter :: namelist_name = 'exice_streams' ! MUST agree with name in namelist and read character(len=*), parameter :: subName = "('exice_streams::ReadNML')" !----------------------------------------------------------------------- From bee1b47365065edd224bbd953894c74b5d32bdfe Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Thu, 19 May 2022 16:59:06 +0200 Subject: [PATCH 15/99] added exice to the ice fraction in soilhydrology --- src/biogeophys/SoilHydrologyMod.F90 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/biogeophys/SoilHydrologyMod.F90 b/src/biogeophys/SoilHydrologyMod.F90 index 0a62d45c38..8ef690d5b9 100644 --- a/src/biogeophys/SoilHydrologyMod.F90 +++ b/src/biogeophys/SoilHydrologyMod.F90 @@ -179,6 +179,7 @@ subroutine SetSoilWaterFractions(bounds, num_hydrologyc, filter_hydrologyc, & integer :: j, fc, c real(r8) :: vol_ice(bounds%begc:bounds%endc,1:nlevsoi) !partial volume of ice lens in layer real(r8) :: icefrac_orig ! original formulation for icefrac + real(r8) :: dz_ext(bounds%begc:bounds%endc,1:nlevsoi) character(len=*), parameter :: subname = 'SetSoilWaterFractions' !----------------------------------------------------------------------- @@ -191,6 +192,7 @@ subroutine SetSoilWaterFractions(bounds, num_hydrologyc, filter_hydrologyc, & h2osoi_liq => waterstatebulk_inst%h2osoi_liq_col , & ! Input: [real(r8) (:,:) ] liquid water (kg/m2) h2osoi_ice => waterstatebulk_inst%h2osoi_ice_col , & ! Input: [real(r8) (:,:) ] ice water (kg/m2) + excess_ice => waterstatebulk_inst%excess_ice_col , & ! Input: [real(r8) (:,:) ] excess ice (kg/m2) origflag => soilhydrology_inst%origflag , & ! Input: logical icefrac => soilhydrology_inst%icefrac_col , & ! Output: [real(r8) (:,:) ] @@ -203,7 +205,8 @@ subroutine SetSoilWaterFractions(bounds, num_hydrologyc, filter_hydrologyc, & ! Porosity of soil, partial volume of ice and liquid, fraction of ice in each layer, ! fractional impermeability - vol_ice(c,j) = min(watsat(c,j), h2osoi_ice(c,j)/(dz(c,j)*denice)) + dz_ext(c,j) = dz(c,j) + excess_ice(c,j)/denice ! extended layer thickness, should be good for all the columns + vol_ice(c,j) = min(watsat(c,j), (h2osoi_ice(c,j) + excess_ice(c,j))/(dz_ext(c,j)*denice)) eff_porosity(c,j) = max(0.01_r8,watsat(c,j)-vol_ice(c,j)) icefrac(c,j) = min(1._r8,vol_ice(c,j)/watsat(c,j)) From 0f5f4a5518474906546cc05828787fca6fd0a9e1 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Sun, 22 May 2022 19:33:15 +0200 Subject: [PATCH 16/99] Rremove extra exice vars --- src/biogeophys/SoilTemperatureMod.F90 | 9 +-- src/biogeophys/WaterStateType.F90 | 83 +++------------------- src/cpl/share_esmf/ExcessIceStreamType.F90 | 2 +- 3 files changed, 13 insertions(+), 81 deletions(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index f96fee7558..22042bec3b 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -1162,10 +1162,6 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & h2osoi_liq => waterstatebulk_inst%h2osoi_liq_col , & ! Output: [real(r8) (:,:) ] liquid water (kg/m2) (new) h2osoi_ice => waterstatebulk_inst%h2osoi_ice_col , & ! Output: [real(r8) (:,:) ] ice lens (kg/m2) (new) excess_ice => waterstatebulk_inst%excess_ice_col , & ! Input: [real(r8) (:,:) ] excess ice lenses (kg/m2) (new) (1:nlevgrnd) - init_exice => waterstatebulk_inst%init_exice , & ! Input: [real(r8) (:) ] excess soil ice initial - exice_melt => waterstatebulk_inst%exice_melt , & ! Input: [real(r8) (:) ] excess soil ice - exice_melt_lev => waterstatebulk_inst%exice_melt_lev , & ! Input: [real(r8) (:,:) ] excess soil ice - qflx_snow_drain => waterfluxbulk_inst%qflx_snow_drain_col , & ! Output: [real(r8) (:) ] drainage from snow pack qflx_snofrz_lyr => waterfluxbulk_inst%qflx_snofrz_lyr_col , & ! Output: [real(r8) (:,:) ] snow freezing rate (positive definite) (col,lyr) [kg m-2 s-1] @@ -1451,8 +1447,7 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & else xmf(c) = xmf(c) + hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime endif - init_exice(c,j)=wexice0(c,j) - exice_melt_lev(c,j)=wexice0(c,j)-excess_ice(c,j) + ! put exice melt here if (imelt(c,j) == 1 .AND. j < 1) then qflx_snomelt_lyr(c,j) = max(0._r8,(wice0(c,j)-h2osoi_ice(c,j)))/dtime qflx_snomelt(c) = qflx_snomelt(c) + qflx_snomelt_lyr(c,j) @@ -1479,13 +1474,11 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & do fc = 1,num_nolakec c = filter_nolakec(fc) eflx_snomelt(c) = qflx_snomelt(c) * hfus - exice_melt(c) = 0.0_r8 l = col%landunit(c) if (lun%urbpoi(l)) then eflx_snomelt_u(c) = eflx_snomelt(c) else if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then eflx_snomelt_r(c) = eflx_snomelt(c) - exice_melt(c) = exice_melt(c) + SUM( exice_melt_lev(c,:) ) / denice end if end do diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index ab7517847e..513830576d 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -53,9 +53,6 @@ module WaterStateType real(r8) :: aquifer_water_baseline ! baseline value for water in the unconfined aquifer (wa_col) for this bulk / tracer (mm) real(r8), pointer :: excess_ice_col (:,:) ! col excess ice lenses (kg/m2) (new) (1:nlevgrnd) - real(r8), pointer :: init_exice (:,:) ! initial value of col excess ice lens/(m/m) (new) (1:nlevgrnd) - real(r8), pointer :: exice_melt_lev (:,:) ! col excess ice melting (m) (new) - real(r8), pointer :: exice_melt (:) ! column-wide excess ice melting (m) (new) type(excessicestream_type), private :: exicestream ! stream type for excess ice initialization NUOPC only @@ -161,22 +158,10 @@ subroutine InitAllocate(this, bounds, tracer_vars) container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_column) !excess ice vars - call AllocateVar2d(var = this%excess_ice_col, name = 'excess_ice_col', & - container = tracer_vars, & - bounds = bounds, subgrid_level = subgrid_level_column, & - dim2beg = -nlevsno+1, dim2end = nlevmaxurbgrnd) - call AllocateVar2d(var = this%init_exice, name = 'init_exice', & - container = tracer_vars, & - bounds = bounds, subgrid_level = subgrid_level_column, & - dim2beg = -nlevsno+1, dim2end = nlevmaxurbgrnd) - call AllocateVar2d(var = this%exice_melt_lev, name = 'exice_melt_lev', & - container = tracer_vars, & - bounds = bounds, subgrid_level = subgrid_level_column, & - dim2beg = -nlevsno+1, dim2end = nlevmaxurbgrnd) - call AllocateVar1d(var = this%exice_melt, name = 'exice_melt', & - container = tracer_vars, & - bounds = bounds, subgrid_level = subgrid_level_column) - + call AllocateVar2d(var = this%excess_ice_col, name = 'excess_ice_col', & + container = tracer_vars, & + bounds = bounds, subgrid_level = subgrid_level_column, & + dim2beg = -nlevsno+1, dim2end = nlevmaxurbgrnd) end subroutine InitAllocate !------------------------------------------------------------------------ @@ -294,26 +279,12 @@ subroutine InitHistory(this, bounds, use_aquifer_layer) ptr_col=this%wa_col, l2g_scale_type='veg') end if - ! Add excess ice fields to history - data2dptr => this%excess_ice_col(begc:endc,1:nlevsoi) - call hist_addfld2d (fname='EXCESS_ICE', units='kg/m2', type2d='levsoi', & - avgflag='A', long_name='excess soil ice (vegetated landunits only)', & - ptr_col=this%excess_ice_col, l2g_scale_type='veg') - - data2dptr => this%init_exice(begc:endc,1:nlevsoi) - call hist_addfld2d (fname='EXICE_INIT', units='m/m', type2d='levsoi', & - avgflag='A', long_name='initial excess soil ice (vegetated landunits only)', & - ptr_col=this%excess_ice_col, l2g_scale_type='veg') - - data2dptr => this%exice_melt_lev(begc:endc,1:nlevsoi) - call hist_addfld2d (fname='EXICE_MELT_LEV', units='kg/m2', type2d='levsoi', & - avgflag='A', long_name='melt from excess ice per layer (vegetated landunits only)', & - ptr_col=this%exice_melt_lev, l2g_scale_type='veg') - - this%exice_melt(begc:endc) = spval - call hist_addfld1d (fname='EXICE_MELT', units='m', & - avgflag='A', long_name='melt from excess ice (vegetated landunits only)', & - ptr_col=this%exice_melt, l2g_scale_type='veg') + ! Add excess ice fields to history + data2dptr => this%excess_ice_col(begc:endc,1:nlevsoi) + call hist_addfld2d (fname='EXCESS_ICE', units='kg/m2', type2d='levsoi', & + avgflag='A', long_name='excess soil ice (vegetated landunits only)', & + ptr_col=this%excess_ice_col, l2g_scale_type='veg', & + default='inactive' ) ! (rgk 02-02-2017) There is intentionally no entry here for stored plant water ! I think that since the value is zero in all cases except @@ -557,10 +528,7 @@ subroutine InitCold(this, bounds, & !Initialize excess ice if (use_excess_ice .and. NLFilename /= '') then ! enforce initialization with 0 for everything - this%init_exice(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 this%excess_ice_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 - this%exice_melt_lev(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 - this%exice_melt(bounds%begc:bounds%endc)=0.0_r8 call this%exicestream%Init(bounds, NLFilename) ! get initial fraction of excess ice per column call this%exicestream%CalcExcessIce(bounds, exice_bulk_init) @@ -577,25 +545,17 @@ subroutine InitCold(this, bounds, & do j = 2, nlevmaxurbgrnd ! ignore first layer if (j Date: Sun, 29 May 2022 15:19:45 +0200 Subject: [PATCH 17/99] add restart for exice from no exice inital condi --- src/biogeophys/WaterStateBulkType.F90 | 6 ++-- src/biogeophys/WaterStateType.F90 | 52 +++++++++++++++++++++------ src/biogeophys/WaterType.F90 | 9 +++-- src/main/clm_instMod.F90 | 4 ++- 4 files changed, 55 insertions(+), 16 deletions(-) diff --git a/src/biogeophys/WaterStateBulkType.F90 b/src/biogeophys/WaterStateBulkType.F90 index 18b9f34e3e..fcb7e2cda7 100644 --- a/src/biogeophys/WaterStateBulkType.F90 +++ b/src/biogeophys/WaterStateBulkType.F90 @@ -188,7 +188,7 @@ end subroutine InitBulkCold !------------------------------------------------------------------------ subroutine RestartBulk(this, bounds, ncid, flag, & - watsat_col) + watsat_col, t_soisno_col) ! ! !DESCRIPTION: ! Read/Write module information to/from restart file. @@ -203,6 +203,7 @@ subroutine RestartBulk(this, bounds, ncid, flag, & type(file_desc_t), intent(inout) :: ncid ! netcdf id character(len=*) , intent(in) :: flag ! 'read' or 'write' real(r8) , intent(in) :: watsat_col (bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) + real(r8) , intent(in) :: t_soisno_col(bounds%begc:, -nlevsno+1:) ! col soil temperature (Kelvin) ! ! !LOCAL VARIABLES: integer :: c,l,j @@ -212,7 +213,8 @@ subroutine RestartBulk(this, bounds, ncid, flag, & SHR_ASSERT_ALL_FL((ubound(watsat_col) == (/bounds%endc,nlevmaxurbgrnd/)) , sourcefile, __LINE__) call this%restart (bounds, ncid, flag=flag, & - watsat_col=watsat_col(bounds%begc:bounds%endc,:)) + watsat_col=watsat_col(bounds%begc:bounds%endc,:), & + t_soisno_col=t_soisno_col(bounds%begc:, -nlevsno+1:)) call restartvar(ncid=ncid, flag=flag, & diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index 513830576d..8b17f1ea15 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -52,9 +52,10 @@ module WaterStateType real(r8) :: aquifer_water_baseline ! baseline value for water in the unconfined aquifer (wa_col) for this bulk / tracer (mm) - real(r8), pointer :: excess_ice_col (:,:) ! col excess ice lenses (kg/m2) (new) (1:nlevgrnd) - + real(r8), pointer :: excess_ice_col (:,:) ! col excess ice lenses (kg/m2) (new) (-nlevsno+1:nlevgrnd) + real(r8), pointer :: exice_bulk_init (:) ! inital value for excess ice (new) (unitless) + logical, pointer, private :: exice_first_time_col (:) ! col whether excess ice is turned on first time type(excessicestream_type), private :: exicestream ! stream type for excess ice initialization NUOPC only contains @@ -162,6 +163,11 @@ subroutine InitAllocate(this, bounds, tracer_vars) container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_column, & dim2beg = -nlevsno+1, dim2end = nlevmaxurbgrnd) + allocate(this%exice_first_time_col (bounds%begc:bounds%endc)) ; this%exice_first_time_col (:) = .true. !should be true during initialize1 + call AllocateVar1d(var = this%exice_bulk_init, name = 'exice_bulk_init', & + container = tracer_vars, & + bounds = bounds, subgrid_level = subgrid_level_column) + end subroutine InitAllocate !------------------------------------------------------------------------ @@ -324,7 +330,6 @@ subroutine InitCold(this, bounds, & integer :: c,j,l,nlevs,g integer :: nbedrock real(r8) :: ratio - real(r8) :: exice_bulk_init(bounds%begc:bounds%endc) !----------------------------------------------------------------------- SHR_ASSERT_ALL_FL((ubound(h2osno_input_col) == (/bounds%endc/)) , sourcefile, __LINE__) @@ -529,9 +534,9 @@ subroutine InitCold(this, bounds, & if (use_excess_ice .and. NLFilename /= '') then ! enforce initialization with 0 for everything this%excess_ice_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 - + this%exice_bulk_init(bounds%begc:bounds%endc)=0.0_r8 call this%exicestream%Init(bounds, NLFilename) ! get initial fraction of excess ice per column - call this%exicestream%CalcExcessIce(bounds, exice_bulk_init) + call this%exicestream%CalcExcessIce(bounds, this%exice_bulk_init) do c = bounds%begc,bounds%endc g = col%gridcell(c) l = col%landunit(c) @@ -544,7 +549,7 @@ subroutine InitCold(this, bounds, & endif do j = 2, nlevmaxurbgrnd ! ignore first layer if (j Date: Sun, 29 May 2022 15:20:15 +0200 Subject: [PATCH 18/99] add exice to ice mass --- src/biogeophys/TotalWaterAndHeatMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/biogeophys/TotalWaterAndHeatMod.F90 b/src/biogeophys/TotalWaterAndHeatMod.F90 index 3f4877d093..885222f33b 100644 --- a/src/biogeophys/TotalWaterAndHeatMod.F90 +++ b/src/biogeophys/TotalWaterAndHeatMod.F90 @@ -383,7 +383,7 @@ subroutine AccumulateSoilLiqIceMassNonLake(bounds, num_c, filter_c, & if (has_h2o) then liquid_mass(c) = liquid_mass(c) + h2osoi_liq(c,j) - ice_mass(c) = ice_mass(c) + h2osoi_ice(c,j) +excess_ice(c,j) + ice_mass(c) = ice_mass(c) + h2osoi_ice(c,j) + excess_ice(c,j) end if end do end do From 628bb9f8292ae45b5154da44eea06ad9f81d8b3a Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Sun, 29 May 2022 15:21:06 +0200 Subject: [PATCH 19/99] add subsidence to water diagnostic vars --- src/biogeophys/SoilTemperatureMod.F90 | 3 ++ src/biogeophys/WaterDiagnosticBulkType.F90 | 35 ++++++++++++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index 22042bec3b..1205c04424 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -1158,6 +1158,7 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & frac_sno_eff => waterdiagnosticbulk_inst%frac_sno_eff_col , & ! Input: [real(r8) (:) ] eff. fraction of ground covered by snow (0 to 1) frac_h2osfc => waterdiagnosticbulk_inst%frac_h2osfc_col , & ! Input: [real(r8) (:) ] fraction of ground covered by surface water (0 to 1) snow_depth => waterdiagnosticbulk_inst%snow_depth_col , & ! Input: [real(r8) (:) ] snow height (m) + exice_subs_col => waterdiagnosticbulk_inst%exice_subs_col , & ! Output: [real(r8) (:,:) ] per layer subsidence due to excess ice melt (mm/s) h2osno_no_layers => waterstatebulk_inst%h2osno_no_layers_col , & ! Output: [real(r8) (:) ] snow not resolved into layers (mm H2O) h2osoi_liq => waterstatebulk_inst%h2osoi_liq_col , & ! Output: [real(r8) (:,:) ] liquid water (kg/m2) (new) h2osoi_ice => waterstatebulk_inst%h2osoi_ice_col , & ! Output: [real(r8) (:,:) ] ice lens (kg/m2) (new) @@ -1412,6 +1413,7 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & endif h2osoi_liq(c,j) = max(0._r8,wmass0(c,j)-h2osoi_ice(c,j)-excess_ice(c,j)) !melted exice is added to the respective soil layers + if (abs(heatr) > 0._r8) then if (j == snl(c)+1) then @@ -1444,6 +1446,7 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & if (j >= 1) then !why before it was two same statements? xmf(c) = xmf(c) + hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime +hfus*(wexice0(c,j)-excess_ice(c,j))/dtime + exice_subs_col(c,j) = max(0._r8, (wexice0(c,j)-excess_ice(c,j))/denice/dtime*1000.0_r8) else xmf(c) = xmf(c) + hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime endif diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index 7804fa3746..b709a3cb8b 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -48,6 +48,8 @@ module WaterDiagnosticBulkType real(r8), pointer :: air_vol_col (:,:) ! col air filled porosity real(r8), pointer :: h2osoi_liqvol_col (:,:) ! col volumetric liquid water content (v/v) real(r8), pointer :: swe_old_col (:,:) ! col initial snow water + real(r8), pointer :: exice_subs_tot_col (:) ! col total subsidence due to excess ice melt + real(r8), pointer :: exice_subs_col (:,:) ! col per layer subsidence due to excess ice melt real(r8), pointer :: snw_rds_col (:,:) ! col snow grain radius (col,lyr) [m^-6, microns] real(r8), pointer :: snw_rds_top_col (:) ! col snow grain radius (top layer) [m^-6, microns] @@ -194,6 +196,8 @@ subroutine InitBulkAllocate(this, bounds) allocate(this%h2osoi_ice_tot_col (begc:endc)) ; this%h2osoi_ice_tot_col (:) = nan allocate(this%h2osoi_liq_tot_col (begc:endc)) ; this%h2osoi_liq_tot_col (:) = nan allocate(this%swe_old_col (begc:endc,-nlevsno+1:0)) ; this%swe_old_col (:,:) = nan + allocate(this%exice_subs_tot_col (begc:endc)) ; this%exice_subs_tot_col (:) = 0.0_r8 + allocate(this%exice_subs_col (begc:endc, 1:nlevgrnd)) ; this%exice_subs_col (:,:) = 0.0_r8 allocate(this%snw_rds_col (begc:endc,-nlevsno+1:0)) ; this%snw_rds_col (:,:) = nan allocate(this%snw_rds_top_col (begc:endc)) ; this%snw_rds_top_col (:) = nan @@ -280,6 +284,15 @@ subroutine InitBulkHistory(this, bounds) long_name=this%info%lname('vertically summed soil cie (veg landunits only)'), & ptr_col=this%h2osoi_ice_tot_col, l2g_scale_type='veg') + this%exice_subs_tot_col(begc:endc) = 0.0_r8 + call hist_addfld1d ( & + fname=this%info%fname('EXICE_SUBS'), & + units='mm/s', & + avgflag='A', & + l2g_scale_type='veg', default='inactive', & + long_name=this%info%lname('subsidence due to excess ice melt'), & + ptr_col=this%exice_subs_tot_col) + this%iwue_ln_patch(begp:endp) = spval call hist_addfld1d ( & fname=this%info%fname('IWUELN'), & @@ -741,7 +754,7 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil use spmdMod , only : masterproc use clm_varcon , only : pondmx, watmin, spval, nameg use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall - use clm_varctl , only : bound_h2osoi + use clm_varctl , only : bound_h2osoi, use_excess_ice use ncdio_pio , only : file_desc_t, ncd_io, ncd_double use restUtilMod ! @@ -875,7 +888,19 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil interpinic_flag='interp', readvar=readvar, data=this%wf_col) end if - + if (.not. use_excess_ice .and. flag == 'read') then + ! no need to even define the restart vars + this%exice_subs_tot_col(bounds%begc:bounds%endc)=0.0_r8 + else + ! have to at least define them + call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('EXICE_SUBS'), & + dim1name='column', xtype=ncd_double, & + long_name=this%info%lname('subsidence due to excess ice melt'), units='mm/s', & + interpinic_flag='interp', readvar=readvar, data=this%exice_subs_tot_col) + if (use_excess_ice .and. flag == 'read' .and. (.not. readvar)) then ! when reading restart that does not have excess ice in it + this%exice_subs_tot_col(bounds%begc:bounds%endc)=0.0_r8 + endif + endif end subroutine RestartBulk @@ -1006,10 +1031,12 @@ subroutine Summary(this, bounds, & h2osoi_ice => waterstate_inst%h2osoi_ice_col, & ! Output: [real(r8) (:,:) ] ice lens (kg/m2) h2osoi_liq => waterstate_inst%h2osoi_liq_col, & ! Output: [real(r8) (:,:) ] liquid water (kg/m2) + exice_subs_col => this%exice_subs_col , & ! Output: [real(r8) (:,:) ] per layer subsidence due to excess ice melt (mm/s) h2osoi_ice_tot => this%h2osoi_ice_tot_col , & ! Output: [real(r8) (:) ] vertically summed ice lens (kg/m2) h2osoi_liq_tot => this%h2osoi_liq_tot_col , & ! Output: [real(r8) (:) ] vertically summed liquid water (kg/m2) - h2osoi_liqice_10cm => this%h2osoi_liqice_10cm_col & ! Output: [real(r8) (:) ] liquid water + ice lens in top 10cm of soil (kg/m2) + h2osoi_liqice_10cm => this%h2osoi_liqice_10cm_col , & ! Output: [real(r8) (:) ] liquid water + ice lens in top 10cm of soil (kg/m2) + exice_subs_tot_col => this%exice_subs_tot_col & ! Output [real(r8) (:) ] total subsidence due to excess ice melt (mm/s) ) call this%waterdiagnostic_type%Summary(bounds, & @@ -1042,6 +1069,7 @@ subroutine Summary(this, bounds, & h2osoi_liqice_10cm(c) = 0.0_r8 h2osoi_liq_tot(c) = 0._r8 h2osoi_ice_tot(c) = 0._r8 + exice_subs_tot_col(c) = 0._r8 end if end do do j = 1, nlevsoi @@ -1064,6 +1092,7 @@ subroutine Summary(this, bounds, & end if h2osoi_liq_tot(c) = h2osoi_liq_tot(c) + h2osoi_liq(c,j) h2osoi_ice_tot(c) = h2osoi_ice_tot(c) + h2osoi_ice(c,j) + exice_subs_tot_col(c) = exice_subs_tot_col(c) + exice_subs_col(c,j) end if end do end do From 60e94480740efdaa2598d2bd018c01a940fa5ed2 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Sun, 5 Jun 2022 18:36:57 +0200 Subject: [PATCH 20/99] added one more diag var and cleanup --- src/biogeophys/SoilTemperatureMod.F90 | 8 +-- src/biogeophys/WaterDiagnosticBulkType.F90 | 79 ++++++++++++++++++---- src/biogeophys/WaterStateType.F90 | 8 +-- src/main/clm_initializeMod.F90 | 2 +- src/main/clm_instMod.F90 | 2 +- 5 files changed, 75 insertions(+), 24 deletions(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index 1205c04424..5c5427ea81 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -1128,6 +1128,7 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & real(r8) :: temp1 !temporary variables [kg/m2] real(r8) :: hm(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) !energy residual [W/m2] real(r8) :: xm(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) !melting or freezing within a time step [kg/m2] + real(r8) :: xm2(bounds%begc:bounds%endc,-nlevsno+1:nlevgrnd) !additional melting or freezing within a time step [kg/m2] (needed for excess ice melt) real(r8) :: wmass0(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)!initial mass of ice and liquid (kg/m2) real(r8) :: wice0 (bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)!initial mass of ice (kg/m2) real(r8) :: wliq0 (bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)!initial mass of liquid (kg/m2) @@ -1135,8 +1136,6 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & real(r8) :: propor !proportionality constant (-) real(r8) :: tinc(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) !t(n+1)-t(n) [K] real(r8) :: smp !frozen water potential (mm) - real(r8) :: xm2(bounds%begc:bounds%endc,-nlevsno+1:nlevgrnd) !xm variable [kg/m2] - real(r8) :: xm3(bounds%begc:bounds%endc,-nlevsno+1:nlevgrnd) !xm variable [kg/m2] real(r8) :: wexice0(bounds%begc:bounds%endc,-nlevsno+1:nlevgrnd)!initial mass of excess_ice at the timestep (kg/m2) @@ -1207,7 +1206,6 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & hm(c,j) = 0._r8 xm(c,j) = 0._r8 xm2(c,j)=0._r8 - xm3(c,j)=0._r8 wice0(c,j) = h2osoi_ice(c,j) wliq0(c,j) = h2osoi_liq(c,j) wexice0(c,j)=excess_ice(c,j) @@ -1446,11 +1444,11 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & if (j >= 1) then !why before it was two same statements? xmf(c) = xmf(c) + hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime +hfus*(wexice0(c,j)-excess_ice(c,j))/dtime - exice_subs_col(c,j) = max(0._r8, (wexice0(c,j)-excess_ice(c,j))/denice/dtime*1000.0_r8) + exice_subs_col(c,j) = max(0._r8, (wexice0(c,j)-excess_ice(c,j))/denice) else xmf(c) = xmf(c) + hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime endif - ! put exice melt here + if (imelt(c,j) == 1 .AND. j < 1) then qflx_snomelt_lyr(c,j) = max(0._r8,(wice0(c,j)-h2osoi_ice(c,j)))/dtime qflx_snomelt(c) = qflx_snomelt(c) + qflx_snomelt_lyr(c,j) diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index b709a3cb8b..0f7b60532d 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -48,8 +48,10 @@ module WaterDiagnosticBulkType real(r8), pointer :: air_vol_col (:,:) ! col air filled porosity real(r8), pointer :: h2osoi_liqvol_col (:,:) ! col volumetric liquid water content (v/v) real(r8), pointer :: swe_old_col (:,:) ! col initial snow water - real(r8), pointer :: exice_subs_tot_col (:) ! col total subsidence due to excess ice melt - real(r8), pointer :: exice_subs_col (:,:) ! col per layer subsidence due to excess ice melt + real(r8), pointer :: exice_subs_tot_col (:) ! col total subsidence due to excess ice melt (m) + real(r8), pointer :: exice_subs_col (:,:) ! col per layer subsidence due to excess ice melt (m) + real(r8), pointer :: exice_vol_col (:,:) ! col per layer volumetric excess ice content (m3/m3) + real(r8), pointer :: exice_vol_tot_col (:) ! col averaged volumetric excess ice content (m3/m3) real(r8), pointer :: snw_rds_col (:,:) ! col snow grain radius (col,lyr) [m^-6, microns] real(r8), pointer :: snw_rds_top_col (:) ! col snow grain radius (top layer) [m^-6, microns] @@ -198,6 +200,8 @@ subroutine InitBulkAllocate(this, bounds) allocate(this%swe_old_col (begc:endc,-nlevsno+1:0)) ; this%swe_old_col (:,:) = nan allocate(this%exice_subs_tot_col (begc:endc)) ; this%exice_subs_tot_col (:) = 0.0_r8 allocate(this%exice_subs_col (begc:endc, 1:nlevgrnd)) ; this%exice_subs_col (:,:) = 0.0_r8 + allocate(this%exice_vol_col (begc:endc, 1:nlevgrnd)) ; this%exice_vol_col (:,:) = 0.0_r8 + allocate(this%exice_vol_tot_col (begc:endc)) ; this%exice_vol_tot_col (:) = 0.0_r8 allocate(this%snw_rds_col (begc:endc,-nlevsno+1:0)) ; this%snw_rds_col (:,:) = nan allocate(this%snw_rds_top_col (begc:endc)) ; this%snw_rds_top_col (:) = nan @@ -281,16 +285,25 @@ subroutine InitBulkHistory(this, bounds) fname=this%info%fname('TOTSOILICE'), & units='kg/m2', & avgflag='A', & - long_name=this%info%lname('vertically summed soil cie (veg landunits only)'), & + long_name=this%info%lname('vertically summed soil ice (veg landunits only)'), & ptr_col=this%h2osoi_ice_tot_col, l2g_scale_type='veg') + this%exice_vol_tot_col(begc:endc) = 0.0_r8 + call hist_addfld1d ( & + fname=this%info%fname('TOTEXICE_VOL'), & + units='m3/m3', & + avgflag='A', & + l2g_scale_type='veg', default='inactive', & + long_name=this%info%lname('vertically averaged volumetric excess ice concentration (veg landunits only)'), & + ptr_col=this%exice_vol_tot_col) + this%exice_subs_tot_col(begc:endc) = 0.0_r8 call hist_addfld1d ( & fname=this%info%fname('EXICE_SUBS'), & - units='mm/s', & - avgflag='A', & + units='m', & + avgflag='SUM', & l2g_scale_type='veg', default='inactive', & - long_name=this%info%lname('subsidence due to excess ice melt'), & + long_name=this%info%lname('subsidence due to excess ice melt (veg landunits only)'), & ptr_col=this%exice_subs_tot_col) this%iwue_ln_patch(begp:endp) = spval @@ -888,18 +901,31 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil interpinic_flag='interp', readvar=readvar, data=this%wf_col) end if - if (.not. use_excess_ice .and. flag == 'read') then + if (.not. use_excess_ice) then ! no need to even define the restart vars this%exice_subs_tot_col(bounds%begc:bounds%endc)=0.0_r8 + this%exice_vol_tot_col(bounds%begc:bounds%endc)=0.0_r8 + this%exice_subs_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 + this%exice_vol_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 else ! have to at least define them call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('EXICE_SUBS'), & dim1name='column', xtype=ncd_double, & - long_name=this%info%lname('subsidence due to excess ice melt'), units='mm/s', & + long_name=this%info%lname('vertically summed volumetric excess ice concentration (veg landunits only)'), units='mm/s', & interpinic_flag='interp', readvar=readvar, data=this%exice_subs_tot_col) - if (use_excess_ice .and. flag == 'read' .and. (.not. readvar)) then ! when reading restart that does not have excess ice in it + ! initialization of these to zero is ok, since they are not in history anyway + this%exice_subs_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 + this%exice_vol_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 + if (flag == 'read' .and. (.not. readvar)) then ! when reading restart that does not have excess ice in it this%exice_subs_tot_col(bounds%begc:bounds%endc)=0.0_r8 + this%exice_vol_tot_col(bounds%begc:bounds%endc)=0.0_r8 + this%exice_subs_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 + this%exice_vol_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 endif + call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('TOTEXICE_VOL'), & + dim1name='column', xtype=ncd_double, & + long_name=this%info%lname('vertically averaged volumetric excess ice concentration (veg landunits only)'), units='m3/m3', & + interpinic_flag='interp', readvar=readvar, data=this%exice_vol_tot_col) endif end subroutine RestartBulk @@ -1006,7 +1032,9 @@ subroutine Summary(this, bounds, & ! Compute end-of-timestep summaries of water diagnostic terms ! ! !USES: - use clm_varpar , only : nlevsoi + use clm_varpar , only : nlevsoi + use clm_varcon , only : denice + use landunit_varcon, only : istsoil, istcrop ! !ARGUMENTS: class(waterdiagnosticbulk_type) , intent(inout) :: this type(bounds_type) , intent(in) :: bounds @@ -1022,6 +1050,8 @@ subroutine Summary(this, bounds, & ! !LOCAL VARIABLES: integer :: fp, p, j, l, fc, c ! Indices real(r8):: fracl ! fraction of soil layer contributing to 10cm total soil water + real(r8):: dz_ext ! extended layer thickness due to excess ice + real(r8):: dz_tot ! total depth with extended thicknesses character(len=*), parameter :: subname = 'Summary' !----------------------------------------------------------------------- @@ -1031,12 +1061,15 @@ subroutine Summary(this, bounds, & h2osoi_ice => waterstate_inst%h2osoi_ice_col, & ! Output: [real(r8) (:,:) ] ice lens (kg/m2) h2osoi_liq => waterstate_inst%h2osoi_liq_col, & ! Output: [real(r8) (:,:) ] liquid water (kg/m2) - exice_subs_col => this%exice_subs_col , & ! Output: [real(r8) (:,:) ] per layer subsidence due to excess ice melt (mm/s) + excess_ice => waterstate_inst%excess_ice_col, & ! Input: [real(r8) (:,:) ] excess ice lenses (kg/m2) (new) (1:nlevgrnd) + exice_subs_col => this%exice_subs_col , & ! Output: [real(r8) (:,:) ] per layer subsidence due to excess ice melt (m) + exice_vol_col => this%exice_vol_col , & ! Output: [real(r8) (:,:) ] per layer volumetric excess ice content (m3/m3) h2osoi_ice_tot => this%h2osoi_ice_tot_col , & ! Output: [real(r8) (:) ] vertically summed ice lens (kg/m2) h2osoi_liq_tot => this%h2osoi_liq_tot_col , & ! Output: [real(r8) (:) ] vertically summed liquid water (kg/m2) h2osoi_liqice_10cm => this%h2osoi_liqice_10cm_col , & ! Output: [real(r8) (:) ] liquid water + ice lens in top 10cm of soil (kg/m2) - exice_subs_tot_col => this%exice_subs_tot_col & ! Output [real(r8) (:) ] total subsidence due to excess ice melt (mm/s) + exice_subs_tot_col => this%exice_subs_tot_col , & ! Output [real(r8) (:) ] vertically summed subsidence due to excess ice melt (m) + exice_vol_tot_col => this%exice_vol_tot_col & ! Output [real(r8) (:) ] vertically averaged volumetric excess ice content (m3/m3) ) call this%waterdiagnostic_type%Summary(bounds, & @@ -1092,11 +1125,31 @@ subroutine Summary(this, bounds, & end if h2osoi_liq_tot(c) = h2osoi_liq_tot(c) + h2osoi_liq(c,j) h2osoi_ice_tot(c) = h2osoi_ice_tot(c) + h2osoi_ice(c,j) - exice_subs_tot_col(c) = exice_subs_tot_col(c) + exice_subs_col(c,j) + if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then + exice_subs_tot_col(c) = exice_subs_tot_col(c) + exice_subs_col(c,j) + endif end if end do end do + do fc = 1, num_nolakec ! extra loop needed since the one above has outer loop with layers + c = filter_nolakec(fc) + l = col%landunit(c) + if (.not. lun%urbpoi(l)) then + if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then + dz_tot = 0.0_r8 + exice_vol_tot_col(c)=0.0_r8 + do j = 1, nlevsoi + dz_ext = dz(c,j)+excess_ice(c,j)/denice + exice_vol_col(c,j)=excess_ice(c,j)/(denice*dz_ext) + dz_tot=dz_tot+dz_ext + exice_vol_tot_col(c)=exice_vol_tot_col(c)+exice_vol_col(c,j)*dz_ext ! (m) + enddo + exice_vol_tot_col(c)=exice_vol_tot_col(c)/dz_tot ! (m3/m3) + end if + end if + end do + end associate end subroutine Summary diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index 8b17f1ea15..dcf49b39d6 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -690,8 +690,7 @@ subroutine Restart(this, bounds, ncid, flag, & interpinic_flag='interp', readvar=readvar, data=this%dynbal_baseline_ice_col) ! Restart excess ice vars - !write(iulog,*) 'restarting excess ice wars' - if (.not. use_excess_ice .and. flag == 'read') then + if (.not. use_excess_ice) then ! no need to even define the restart vars this%excess_ice_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 else @@ -699,9 +698,9 @@ subroutine Restart(this, bounds, ncid, flag, & call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('EXCESS_ICE'), xtype=ncd_double, & dim1name='column', dim2name='levtot', switchdim=.true., & long_name=this%info%lname('excess soil ice (vegetated landunits only)'), units='kg/m2', & - scale_by_thickness=.false., & + scale_by_thickness=.true., & interpinic_flag='interp', readvar=readvar, data=this%excess_ice_col) - if (use_excess_ice .and. flag == 'read' .and. (.not. readvar)) then ! when reading restart that does not have excess ice in it + if (flag == 'read' .and. (.not. readvar)) then ! when reading restart that does not have excess ice in it this%exice_first_time_col(bounds%begc:bounds%endc) = .false. do c = bounds%begc,bounds%endc @@ -727,6 +726,7 @@ subroutine Restart(this, bounds, ncid, flag, & end do endif! end of old file restart endif ! end of exice restart + ! Determine volumetric soil water (for read only) if (flag == 'read' ) then do c = bounds%begc, bounds%endc diff --git a/src/main/clm_initializeMod.F90 b/src/main/clm_initializeMod.F90 index 32c368e40b..c9541376a2 100644 --- a/src/main/clm_initializeMod.F90 +++ b/src/main/clm_initializeMod.F90 @@ -14,7 +14,7 @@ module clm_initializeMod use clm_varctl , only : is_cold_start, is_interpolated_start use clm_varctl , only : iulog use clm_varctl , only : use_lch4, use_cn, use_cndv, use_c13, use_c14, use_fates - use clm_varctl , only : use_soil_moisture_streams, use_excess_ice + use clm_varctl , only : use_soil_moisture_streams use clm_instur , only : wt_lunit, urban_valid, wt_nat_patch, wt_cft, fert_cft use clm_instur , only : irrig_method, wt_glc_mec, topo_glc_mec, haslake use perf_mod , only : t_startf, t_stopf diff --git a/src/main/clm_instMod.F90 b/src/main/clm_instMod.F90 index 836e9586bd..35428f0f02 100644 --- a/src/main/clm_instMod.F90 +++ b/src/main/clm_instMod.F90 @@ -8,7 +8,7 @@ module clm_instMod use shr_kind_mod , only : r8 => shr_kind_r8 use decompMod , only : bounds_type use clm_varpar , only : ndecomp_pools, nlevdecomp_full - use clm_varctl , only : use_cn, use_c13, use_c14, use_lch4, use_cndv, use_fates, use_excess_ice + use clm_varctl , only : use_cn, use_c13, use_c14, use_lch4, use_cndv, use_fates use clm_varctl , only : use_crop, snow_cover_fraction_method, paramfile use SoilBiogeochemDecompCascadeConType , only : century_decomp, decomp_method use clm_varcon , only : bdsno, c13ratio, c14ratio From 57c8a8cb12eb0dd21c0ba624931946c05a396e6b Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Sun, 12 Jun 2022 17:37:12 +0200 Subject: [PATCH 21/99] fix diag vars --- src/biogeophys/SoilTemperatureMod.F90 | 3 +++ src/biogeophys/WaterDiagnosticBulkType.F90 | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index 5c5427ea81..383024351b 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -1210,6 +1210,9 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & wliq0(c,j) = h2osoi_liq(c,j) wexice0(c,j)=excess_ice(c,j) wmass0(c,j) = h2osoi_ice(c,j) + h2osoi_liq(c,j) + wexice0(c,j) + if (j>=1) then + exice_subs_col(c,j)=0._r8 + endif endif ! end of snow layer if-block if (j <= 0) then diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index 0f7b60532d..824217c1fc 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -287,7 +287,7 @@ subroutine InitBulkHistory(this, bounds) avgflag='A', & long_name=this%info%lname('vertically summed soil ice (veg landunits only)'), & ptr_col=this%h2osoi_ice_tot_col, l2g_scale_type='veg') - + ! excess ice vars this%exice_vol_tot_col(begc:endc) = 0.0_r8 call hist_addfld1d ( & fname=this%info%fname('TOTEXICE_VOL'), & @@ -911,7 +911,7 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil ! have to at least define them call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('EXICE_SUBS'), & dim1name='column', xtype=ncd_double, & - long_name=this%info%lname('vertically summed volumetric excess ice concentration (veg landunits only)'), units='mm/s', & + long_name=this%info%lname('vertically summed volumetric excess ice concentration (veg landunits only)'), units='m', & interpinic_flag='interp', readvar=readvar, data=this%exice_subs_tot_col) ! initialization of these to zero is ok, since they are not in history anyway this%exice_subs_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 From 492300989978a774d8bd1203ba95c080ba196b9a Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Thu, 16 Jun 2022 13:26:07 +0200 Subject: [PATCH 22/99] make history active only when exice is used --- src/biogeophys/WaterDiagnosticBulkType.F90 | 37 ++++++++++++---------- src/biogeophys/WaterStateType.F90 | 12 ++++--- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index 824217c1fc..55c19fcfe2 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -241,6 +241,7 @@ subroutine InitBulkHistory(this, bounds) ! !USES: use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=) use histFileMod , only : hist_addfld1d, hist_addfld2d, no_snow_normal, no_snow_zero + use clm_varctl , only : use_excess_ice ! ! !ARGUMENTS: class(waterdiagnosticbulk_type), intent(in) :: this @@ -288,23 +289,25 @@ subroutine InitBulkHistory(this, bounds) long_name=this%info%lname('vertically summed soil ice (veg landunits only)'), & ptr_col=this%h2osoi_ice_tot_col, l2g_scale_type='veg') ! excess ice vars - this%exice_vol_tot_col(begc:endc) = 0.0_r8 - call hist_addfld1d ( & - fname=this%info%fname('TOTEXICE_VOL'), & - units='m3/m3', & - avgflag='A', & - l2g_scale_type='veg', default='inactive', & - long_name=this%info%lname('vertically averaged volumetric excess ice concentration (veg landunits only)'), & - ptr_col=this%exice_vol_tot_col) - - this%exice_subs_tot_col(begc:endc) = 0.0_r8 - call hist_addfld1d ( & - fname=this%info%fname('EXICE_SUBS'), & - units='m', & - avgflag='SUM', & - l2g_scale_type='veg', default='inactive', & - long_name=this%info%lname('subsidence due to excess ice melt (veg landunits only)'), & - ptr_col=this%exice_subs_tot_col) + if (use_excess_ice) then + this%exice_vol_tot_col(begc:endc) = 0.0_r8 + call hist_addfld1d ( & + fname=this%info%fname('TOTEXICE_VOL'), & + units='m3/m3', & + avgflag='A', & + l2g_scale_type='veg', & + long_name=this%info%lname('vertically averaged volumetric excess ice concentration (veg landunits only)'), & + ptr_col=this%exice_vol_tot_col) + + this%exice_subs_tot_col(begc:endc) = 0.0_r8 + call hist_addfld1d ( & + fname=this%info%fname('EXICE_SUBS'), & + units='m', & + avgflag='SUM', & + l2g_scale_type='veg', & + long_name=this%info%lname('subsidence due to excess ice melt (veg landunits only)'), & + ptr_col=this%exice_subs_tot_col) + end if this%iwue_ln_patch(begp:endp) = spval call hist_addfld1d ( & diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index dcf49b39d6..1f8a12cd4a 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -286,11 +286,13 @@ subroutine InitHistory(this, bounds, use_aquifer_layer) end if ! Add excess ice fields to history - data2dptr => this%excess_ice_col(begc:endc,1:nlevsoi) - call hist_addfld2d (fname='EXCESS_ICE', units='kg/m2', type2d='levsoi', & - avgflag='A', long_name='excess soil ice (vegetated landunits only)', & - ptr_col=this%excess_ice_col, l2g_scale_type='veg', & - default='inactive' ) + + if (use_excess_ice) then + data2dptr => this%excess_ice_col(begc:endc,1:nlevsoi) + call hist_addfld2d (fname='EXCESS_ICE', units='kg/m2', type2d='levsoi', & + avgflag='A', long_name='excess soil ice (vegetated landunits only)', & + ptr_col=this%excess_ice_col, l2g_scale_type='veg') + end if ! (rgk 02-02-2017) There is intentionally no entry here for stored plant water ! I think that since the value is zero in all cases except From 805a3bad69444f598814bf3a5dbb85b620f5d9ba Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Thu, 16 Jun 2022 13:26:49 +0200 Subject: [PATCH 23/99] add mapalgo to namelists and stream --- bld/CLMBuildNamelist.pm | 1 + bld/namelist_files/namelist_defaults_ctsm.xml | 1 + .../namelist_definition_ctsm.xml | 10 ++++++++- src/cpl/share_esmf/ExcessIceStreamType.F90 | 22 +++++++++---------- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index c7168e45e8..96bd99efd8 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -4153,6 +4153,7 @@ sub setup_logic_exice { if ($opts->{'driver'} eq "nuopc" ) { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_meshfile_exice'); } + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_mapalgo_exice'); } # end exice streams diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 54bec90957..b0d2c35ddf 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -2594,5 +2594,6 @@ lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts lnd/clm2/paramdata/exice_init_0.125x0.125_c20220516.nc lnd/clm2/paramdata/exice_init_0.125x0.125_ESMFmesh_c20220516.nc +bilinear diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 702b21b262..d598b4ed57 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -2823,7 +2823,7 @@ use case.) -Toggle to turn on the excess ice physics, (Lee et al., 2014; Cai et al., 2020) +If TRUE turn on the excess ice physics, (Lee et al., 2014; Cai et al., 2020) + +Mapping method from excess ice input stream data to the model resolution + bilinear = bilinear interpolation + nn = nearest neighbor + + + diff --git a/src/cpl/share_esmf/ExcessIceStreamType.F90 b/src/cpl/share_esmf/ExcessIceStreamType.F90 index 63c7e69dc1..ae79cad626 100644 --- a/src/cpl/share_esmf/ExcessIceStreamType.F90 +++ b/src/cpl/share_esmf/ExcessIceStreamType.F90 @@ -37,7 +37,7 @@ module ExcessIceStreamType type, private :: streamcontrol_type character(len=CL) :: stream_fldFileName_exice ! data Filename character(len=CL) :: stream_meshfile_exice ! mesh Filename - character(len=CL) :: exicemapalgo ! map algo + character(len=CL) :: stream_mapalgo_exice ! map algo contains procedure, private :: ReadNML ! Read in namelist end type streamcontrol_type @@ -95,10 +95,10 @@ subroutine Init(this, bounds, NLFilename) compname = 'LND', & model_clock = model_clock, & model_mesh = mesh, & - stream_meshfile = control%stream_meshfile_exice, & + stream_meshfile = control%stream_meshfile_exice, & stream_lev_dimname = 'null', & - stream_mapalgo = 'nn', & - stream_filenames = (/trim(control%stream_fldFileName_exice)/), & + stream_mapalgo = control%stream_mapalgo_exice, & + stream_filenames = (/trim(control%stream_fldFileName_exice)/), & stream_fldlistFile = stream_varnames, & stream_fldListModel = stream_varnames, & stream_yearFirst = 1996, & @@ -107,8 +107,8 @@ subroutine Init(this, bounds, NLFilename) stream_offset = 0, & stream_taxmode = 'extend', & stream_dtlimit = 1.0e30_r8, & - stream_tintalgo = 'nearest', & - stream_name = 'excess ice ', & + stream_tintalgo = 'nearest', & + stream_name = 'excess ice ', & rc = rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) then call ESMF_Finalize(endflag=ESMF_END_ABORT) @@ -247,13 +247,13 @@ subroutine ReadNML(this, bounds, NLFilename) integer :: nml_error ! namelist i/o error flag character(len=CL) :: stream_fldFileName_exice = ' ' character(len=CL) :: stream_meshfile_exice = ' ' - character(len=CL) :: exicemapalgo = 'bilinear' + character(len=CL) :: stream_mapalgo_exice = 'bilinear' character(len=*), parameter :: namelist_name = 'exice_streams' ! MUST agree with name in namelist and read character(len=*), parameter :: subName = "('exice_streams::ReadNML')" !----------------------------------------------------------------------- namelist /exice_streams/ & ! MUST agree with namelist_name above - exicemapalgo, stream_fldFileName_exice, stream_meshfile_exice + stream_mapalgo_exice, stream_fldFileName_exice, stream_meshfile_exice ! Default values for namelist @@ -272,7 +272,7 @@ subroutine ReadNML(this, bounds, NLFilename) close(nu_nml) endif - call shr_mpi_bcast(exicemapalgo , mpicom) + call shr_mpi_bcast(stream_mapalgo_exice , mpicom) call shr_mpi_bcast(stream_fldFileName_exice , mpicom) call shr_mpi_bcast(stream_meshfile_exice , mpicom) @@ -281,11 +281,11 @@ subroutine ReadNML(this, bounds, NLFilename) write(iulog,*) namelist_name, ' stream settings:' write(iulog,*) ' stream_fldFileName_exice = ',stream_fldFileName_exice write(iulog,*) ' stream_meshfile_exice = ',stream_meshfile_exice - write(iulog,*) ' exicemapalgo = ',exicemapalgo + write(iulog,*) ' stream_mapalgo_exice = ',stream_mapalgo_exice endif this%stream_fldFileName_exice = stream_fldFileName_exice this%stream_meshfile_exice = stream_meshfile_exice - this%exicemapalgo = exicemapalgo + this%stream_mapalgo_exice = stream_mapalgo_exice end subroutine ReadNML From 3169a42d174a51ed83a34ed233db94a00427b142 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Thu, 16 Jun 2022 13:27:46 +0200 Subject: [PATCH 24/99] pass alm_lastyear_indx to restart and improve cold --- src/biogeophys/WaterStateBulkType.F90 | 6 ++-- src/biogeophys/WaterStateType.F90 | 41 +++++++++++++++++---------- src/biogeophys/WaterType.F90 | 9 ++++-- src/main/clm_instMod.F90 | 3 +- 4 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/biogeophys/WaterStateBulkType.F90 b/src/biogeophys/WaterStateBulkType.F90 index fcb7e2cda7..74dae314e8 100644 --- a/src/biogeophys/WaterStateBulkType.F90 +++ b/src/biogeophys/WaterStateBulkType.F90 @@ -188,7 +188,7 @@ end subroutine InitBulkCold !------------------------------------------------------------------------ subroutine RestartBulk(this, bounds, ncid, flag, & - watsat_col, t_soisno_col) + watsat_col, t_soisno_col, altmax_lastyear_indx) ! ! !DESCRIPTION: ! Read/Write module information to/from restart file. @@ -204,6 +204,7 @@ subroutine RestartBulk(this, bounds, ncid, flag, & character(len=*) , intent(in) :: flag ! 'read' or 'write' real(r8) , intent(in) :: watsat_col (bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) real(r8) , intent(in) :: t_soisno_col(bounds%begc:, -nlevsno+1:) ! col soil temperature (Kelvin) + integer , intent(in) :: altmax_lastyear_indx(bounds%begc:) !col active layer index last year ! ! !LOCAL VARIABLES: integer :: c,l,j @@ -214,7 +215,8 @@ subroutine RestartBulk(this, bounds, ncid, flag, & call this%restart (bounds, ncid, flag=flag, & watsat_col=watsat_col(bounds%begc:bounds%endc,:), & - t_soisno_col=t_soisno_col(bounds%begc:, -nlevsno+1:)) + t_soisno_col=t_soisno_col(bounds%begc:, -nlevsno+1:), & + altmax_lastyear_indx=altmax_lastyear_indx(bounds%begc:)) call restartvar(ncid=ncid, flag=flag, & diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index 1f8a12cd4a..318990b42c 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -55,7 +55,6 @@ module WaterStateType real(r8), pointer :: excess_ice_col (:,:) ! col excess ice lenses (kg/m2) (new) (-nlevsno+1:nlevgrnd) real(r8), pointer :: exice_bulk_init (:) ! inital value for excess ice (new) (unitless) - logical, pointer, private :: exice_first_time_col (:) ! col whether excess ice is turned on first time type(excessicestream_type), private :: exicestream ! stream type for excess ice initialization NUOPC only contains @@ -163,7 +162,6 @@ subroutine InitAllocate(this, bounds, tracer_vars) container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_column, & dim2beg = -nlevsno+1, dim2end = nlevmaxurbgrnd) - allocate(this%exice_first_time_col (bounds%begc:bounds%endc)) ; this%exice_first_time_col (:) = .true. !should be true during initialize1 call AllocateVar1d(var = this%exice_bulk_init, name = 'exice_bulk_init', & container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_column) @@ -330,7 +328,7 @@ subroutine InitCold(this, bounds, & ! ! !LOCAL VARIABLES: integer :: c,j,l,nlevs,g - integer :: nbedrock + integer :: nbedrock, n1m real(r8) :: ratio !----------------------------------------------------------------------- @@ -544,17 +542,27 @@ subroutine InitCold(this, bounds, & l = col%landunit(c) if (.not. lun%lakpoi(l)) then !not lake if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then - if (use_bedrock) then + n1m=3 + do j = 3, nlevsoi ! get layer with 1 m depth + if (col%zi(c,j-1)<=1.0_r8 .and. col%zi(c,j)>1.0_r8) then + n1m=j + end if + end do + if (use_bedrock .and. nbedrock<=nlevsoi) then nbedrock = col%nbedrock(c) else nbedrock = nlevsoi endif do j = 2, nlevmaxurbgrnd ! ignore first layer - if (j= n1m .and. jaltmax_lastyear_indx(c) .and. j Date: Fri, 24 Jun 2022 16:24:04 +0200 Subject: [PATCH 25/99] fix namelists so exice files are not always downloaded --- bld/CLMBuildNamelist.pm | 12 +++++++----- bld/namelist_files/namelist_defaults_ctsm.xml | 6 +++--- bld/namelist_files/namelist_definition_ctsm.xml | 4 ++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 96bd99efd8..17bcf04d04 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -2137,6 +2137,7 @@ sub setup_logic_soilstate { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'organic_frac_squared' ); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_bedrock', 'use_fates'=>$nl_flags->{'use_fates'}, 'vichydro'=>$nl_flags->{'vichydro'} ); + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_excess_ice'); # excess ice flag should be read before stream vars my $var1 = "soil_layerstruct_predefined"; my $var2 = "soil_layerstruct_userdefined"; @@ -4148,12 +4149,13 @@ sub setup_logic_exice { # excess ice streams # my ($opts, $nl_flags, $definition, $defaults, $nl) = @_; - - add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_fldfilename_exice'); - if ($opts->{'driver'} eq "nuopc" ) { + my $use_exice = $nl->get_value( 'use_excess_ice' ); + if (defined($use_exice) && $opts->{'driver'} eq "nuopc" && value_is_true($use_exice)) { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_meshfile_exice'); - } - add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_mapalgo_exice'); + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_fldfilename_exice'); + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_mapalgo_exice'); + } + } # end exice streams diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index b0d2c35ddf..911ed296cf 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -2592,8 +2592,8 @@ lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts .false. -lnd/clm2/paramdata/exice_init_0.125x0.125_c20220516.nc -lnd/clm2/paramdata/exice_init_0.125x0.125_ESMFmesh_c20220516.nc -bilinear +lnd/clm2/paramdata/exice_init_0.125x0.125_c20220516.nc +lnd/clm2/paramdata/exice_init_0.125x0.125_ESMFmesh_c20220516.nc +bilinear diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index d598b4ed57..bcee47aed5 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -2819,9 +2819,9 @@ use case.) - + - If TRUE turn on the excess ice physics, (Lee et al., 2014; Cai et al., 2020) From d284f3191ae6a8371e8a4f7be58b188366311a61 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Fri, 24 Jun 2022 20:40:08 +0200 Subject: [PATCH 26/99] added error message for non-nuopc driver --- bld/CLMBuildNamelist.pm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 17bcf04d04..357eb2d4d2 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -4154,7 +4154,9 @@ sub setup_logic_exice { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_meshfile_exice'); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_fldfilename_exice'); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_mapalgo_exice'); - } + } elsif (defined($use_exice) && (! $opts->{'driver'} eq "nuopc") && value_is_true($use_exice)) { + $log->fatal_error("nuopc driver is required when use_excess_ice is set to true" ); +} } # end exice streams From 4e3610a4ec92af6b59b58463ea5ba99179d771ef Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Fri, 24 Jun 2022 20:40:41 +0200 Subject: [PATCH 27/99] cleanup, comments and rename diagnostic history vars --- src/biogeophys/SoilTemperatureMod.F90 | 9 +++++---- src/biogeophys/WaterDiagnosticBulkType.F90 | 10 +++++----- src/biogeophys/WaterStateType.F90 | 6 +++--- src/cpl/share_esmf/ExcessIceStreamType.F90 | 2 ++ 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index 383024351b..1f58cf25cb 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -198,7 +198,7 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter frac_sno_eff => waterdiagnosticbulk_inst%frac_sno_eff_col , & ! Input: [real(r8) (:) ] eff. fraction of ground covered by snow (0 to 1) snow_depth => waterdiagnosticbulk_inst%snow_depth_col , & ! Input: [real(r8) (:) ] snow height (m) h2osfc => waterstatebulk_inst%h2osfc_col , & ! Input: [real(r8) (:) ] surface water (mm) - excess_ice => waterstatebulk_inst%excess_ice_col , & ! Input: [real(r8) (:,:) ] excess ice lenses (kg/m2) (new) (1:nlevgrnd) + excess_ice => waterstatebulk_inst%excess_ice_col , & ! Input: [real(r8) (:,:) ] excess ice (kg/m2) (new) (1:nlevgrnd) frac_h2osfc => waterdiagnosticbulk_inst%frac_h2osfc_col , & ! Input: [real(r8) (:) ] fraction of ground covered by surface water (0 to 1) @@ -1161,7 +1161,7 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & h2osno_no_layers => waterstatebulk_inst%h2osno_no_layers_col , & ! Output: [real(r8) (:) ] snow not resolved into layers (mm H2O) h2osoi_liq => waterstatebulk_inst%h2osoi_liq_col , & ! Output: [real(r8) (:,:) ] liquid water (kg/m2) (new) h2osoi_ice => waterstatebulk_inst%h2osoi_ice_col , & ! Output: [real(r8) (:,:) ] ice lens (kg/m2) (new) - excess_ice => waterstatebulk_inst%excess_ice_col , & ! Input: [real(r8) (:,:) ] excess ice lenses (kg/m2) (new) (1:nlevgrnd) + excess_ice => waterstatebulk_inst%excess_ice_col , & ! Input: [real(r8) (:,:) ] excess ice (kg/m2) (new) (1:nlevgrnd) qflx_snow_drain => waterfluxbulk_inst%qflx_snow_drain_col , & ! Output: [real(r8) (:) ] drainage from snow pack qflx_snofrz_lyr => waterfluxbulk_inst%qflx_snofrz_lyr_col , & ! Output: [real(r8) (:,:) ] snow freezing rate (positive definite) (col,lyr) [kg m-2 s-1] @@ -1393,7 +1393,7 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & if (xm(c,j) > 0._r8) then !if there is excess heat to melt the ice h2osoi_ice(c,j) = max(0._r8, wice0(c,j)-xm(c,j)) heatr = hm(c,j) - hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime - xm2(c,j) = xm(c,j) - h2osoi_ice(c,j) !excess ice modifications + xm2(c,j) = xm(c,j) - h2osoi_ice(c,j) !excess ice melting if (h2osoi_ice(c,j) == 0._r8) then ! this might be redundant if (excess_ice(c,j) >= 0._r8 .and. xm2(c,j)>0._r8 .and. j>=2) then ! if there is excess ice to melt excess_ice(c,j) = max(0._r8,wexice0(c,j) - xm2(c,j)) @@ -1413,7 +1413,7 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & heatr = hm(c,j) - hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime endif - h2osoi_liq(c,j) = max(0._r8,wmass0(c,j)-h2osoi_ice(c,j)-excess_ice(c,j)) !melted exice is added to the respective soil layers + h2osoi_liq(c,j) = max(0._r8,wmass0(c,j)-h2osoi_ice(c,j)-excess_ice(c,j)) !melted excess ice is added to the respective soil layers if (abs(heatr) > 0._r8) then @@ -1447,6 +1447,7 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & if (j >= 1) then !why before it was two same statements? xmf(c) = xmf(c) + hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime +hfus*(wexice0(c,j)-excess_ice(c,j))/dtime + ! subsidence calculation exice_subs_col(c,j) = max(0._r8, (wexice0(c,j)-excess_ice(c,j))/denice) else xmf(c) = xmf(c) + hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index 55c19fcfe2..6b150ceaf5 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -301,7 +301,7 @@ subroutine InitBulkHistory(this, bounds) this%exice_subs_tot_col(begc:endc) = 0.0_r8 call hist_addfld1d ( & - fname=this%info%fname('EXICE_SUBS'), & + fname=this%info%fname('SUBSIDENCE'), & units='m', & avgflag='SUM', & l2g_scale_type='veg', & @@ -911,14 +911,14 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil this%exice_subs_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 this%exice_vol_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 else + ! initialization of these to zero is ok, since they might not be in the restart file + this%exice_subs_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 + this%exice_vol_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 ! have to at least define them - call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('EXICE_SUBS'), & + call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('SUBSIDENCE'), & dim1name='column', xtype=ncd_double, & long_name=this%info%lname('vertically summed volumetric excess ice concentration (veg landunits only)'), units='m', & interpinic_flag='interp', readvar=readvar, data=this%exice_subs_tot_col) - ! initialization of these to zero is ok, since they are not in history anyway - this%exice_subs_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 - this%exice_vol_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 if (flag == 'read' .and. (.not. readvar)) then ! when reading restart that does not have excess ice in it this%exice_subs_tot_col(bounds%begc:bounds%endc)=0.0_r8 this%exice_vol_tot_col(bounds%begc:bounds%endc)=0.0_r8 diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index 318990b42c..944f4a72f5 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -52,7 +52,7 @@ module WaterStateType real(r8) :: aquifer_water_baseline ! baseline value for water in the unconfined aquifer (wa_col) for this bulk / tracer (mm) - real(r8), pointer :: excess_ice_col (:,:) ! col excess ice lenses (kg/m2) (new) (-nlevsno+1:nlevgrnd) + real(r8), pointer :: excess_ice_col (:,:) ! col excess ice (kg/m2) (new) (-nlevsno+1:nlevgrnd) real(r8), pointer :: exice_bulk_init (:) ! inital value for excess ice (new) (unitless) type(excessicestream_type), private :: exicestream ! stream type for excess ice initialization NUOPC only @@ -554,7 +554,7 @@ subroutine InitCold(this, bounds, & nbedrock = nlevsoi endif do j = 2, nlevmaxurbgrnd ! ignore first layer - if (n1m= n1m .and. j Date: Sun, 26 Jun 2022 15:43:09 +0200 Subject: [PATCH 28/99] fixed comments --- src/biogeophys/SoilTemperatureMod.F90 | 4 ++-- src/main/clm_varctl.F90 | 2 +- src/main/controlMod.F90 | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index 1f58cf25cb..da755bf9cf 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -700,7 +700,7 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter col%itype(c) /= icol_roof .and. col%itype(c) /= icol_road_imperv) .or. & (col%itype(c) == icol_road_imperv .and. j > nlev_improad(l))) then - ! TODO recalculate watsat and satw to have excess ice included + !TODO recalculate watsat and satw to have excess ice included satw = (h2osoi_liq(c,j)/denh2o + h2osoi_ice(c,j)/denice +excess_ice(c,j)/denice)/(dz(c,j)*watsat(c,j)) satw = min(1._r8, satw) if (satw > .1e-6_r8) then @@ -1445,7 +1445,7 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & end if endif ! end of heatr > 0 if-block - if (j >= 1) then !why before it was two same statements? + if (j >= 1) then xmf(c) = xmf(c) + hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime +hfus*(wexice0(c,j)-excess_ice(c,j))/dtime ! subsidence calculation exice_subs_col(c,j) = max(0._r8, (wexice0(c,j)-excess_ice(c,j))/denice) diff --git a/src/main/clm_varctl.F90 b/src/main/clm_varctl.F90 index 2d7af87cf4..79f1837ffb 100644 --- a/src/main/clm_varctl.F90 +++ b/src/main/clm_varctl.F90 @@ -301,7 +301,7 @@ module clm_varctl !---------------------------------------------------------- !excess ice physics switch !---------------------------------------------------------- - logical, public :: use_excess_ice = .false. ! true. => use excess ice physics !MVD + logical, public :: use_excess_ice = .false. ! true. => use excess ice physics !---------------------------------------------------------- ! plant hydraulic stress switch diff --git a/src/main/controlMod.F90 b/src/main/controlMod.F90 index 98d9ab4081..194e1704aa 100644 --- a/src/main/controlMod.F90 +++ b/src/main/controlMod.F90 @@ -242,7 +242,7 @@ subroutine control_init(dtime) namelist /clm_inparm/ use_soil_moisture_streams - namelist /clm_inparm/ use_excess_ice !MVD + namelist /clm_inparm/ use_excess_ice namelist /clm_inparm/ use_lai_streams @@ -735,7 +735,7 @@ subroutine control_spmd() call mpi_bcast (use_soil_moisture_streams, 1, MPI_LOGICAL, 0, mpicom, ier) - call mpi_bcast (use_excess_ice, 1, MPI_LOGICAL, 0, mpicom,ier) !MVD + call mpi_bcast (use_excess_ice, 1, MPI_LOGICAL, 0, mpicom,ier) call mpi_bcast (use_lai_streams, 1, MPI_LOGICAL, 0, mpicom, ier) From b8fe30ddb413ad14135686c1f338491c8671b7f8 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Sun, 26 Jun 2022 20:02:23 +0200 Subject: [PATCH 29/99] nlfilename passing --- src/biogeophys/WaterType.F90 | 25 ++++++++----------- .../unittestWaterTypeFactory.F90 | 3 ++- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/biogeophys/WaterType.F90 b/src/biogeophys/WaterType.F90 index 76776eca93..bc257f27ad 100644 --- a/src/biogeophys/WaterType.F90 +++ b/src/biogeophys/WaterType.F90 @@ -246,7 +246,8 @@ end subroutine Init !----------------------------------------------------------------------- subroutine InitForTesting(this, bounds, params, & - h2osno_col, snow_depth_col, watsat_col, t_soisno_col, use_aquifer_layer) + h2osno_col, snow_depth_col, watsat_col, & + t_soisno_col, use_aquifer_layer, NLFilename) ! ! !DESCRIPTION: ! Version of Init routine just for unit tests @@ -259,9 +260,10 @@ subroutine InitForTesting(this, bounds, params, & type(water_params_type), intent(in) :: params real(r8) , intent(in) :: h2osno_col(bounds%begc:) real(r8) , intent(in) :: snow_depth_col(bounds%begc:) - real(r8) , intent(in) :: watsat_col(bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) + real(r8) , intent(in) :: watsat_col(bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) real(r8) , intent(in) :: t_soisno_col(bounds%begc:, -nlevsno+1:) ! col soil temperature (Kelvin) - logical , intent(in), optional :: use_aquifer_layer ! whether an aquifer layer is used in this run (false by default) + character(len=*) , intent(in) :: NLFilename ! Namelist filename + logical , intent(in), optional :: use_aquifer_layer ! whether an aquifer layer is used in this run (false by default) ! ! !LOCAL VARIABLES: logical :: l_use_aquifer_layer @@ -280,7 +282,8 @@ subroutine InitForTesting(this, bounds, params, & snow_depth_col = snow_depth_col, & watsat_col = watsat_col, & t_soisno_col = t_soisno_col, & - use_aquifer_layer = l_use_aquifer_layer) + use_aquifer_layer = l_use_aquifer_layer, & + NLFilename = NLFilename) end subroutine InitForTesting @@ -300,22 +303,16 @@ subroutine DoInit(this, bounds, & real(r8) , intent(in) :: snow_depth_col(bounds%begc:) real(r8) , intent(in) :: watsat_col(bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) real(r8) , intent(in) :: t_soisno_col(bounds%begc:, -nlevsno+1:) ! col soil temperature (Kelvin) - logical , intent(in) :: use_aquifer_layer ! whether an aquifer layer is used in this run - character(len=*) , intent(in) , optional :: NLFilename ! Namelist filename + logical , intent(in) :: use_aquifer_layer ! whether an aquifer layer is used in this run + character(len=*) , intent(in) :: NLFilename ! Namelist filename ! ! !LOCAL VARIABLES: integer :: begc, endc integer :: i - character(len=256) :: l_NLFilename ! local for namelist filename character(len=*), parameter :: subname = 'DoInit' !----------------------------------------------------------------------- - !check if NLFilename is passed - l_NLFilename = '' - if (present(NLFilename)) then - l_NLFilename = NLFilename - end if begc = bounds%begc endc = bounds%endc @@ -343,7 +340,7 @@ subroutine DoInit(this, bounds, & watsat_col = watsat_col(begc:endc, 1:), & t_soisno_col = t_soisno_col(begc:endc, -nlevsno+1:), & use_aquifer_layer = use_aquifer_layer, & - NLFilename = l_NLFilename) + NLFilename = NLFilename) call this%waterdiagnosticbulk_inst%InitBulk(bounds, & bulk_info, & @@ -384,7 +381,7 @@ subroutine DoInit(this, bounds, & watsat_col = watsat_col(begc:endc, 1:), & t_soisno_col = t_soisno_col(begc:endc, -nlevsno+1:), & use_aquifer_layer = use_aquifer_layer, & - NLFilename = l_NLFilename) + NLFilename = NLFilename) call this%bulk_and_tracers(i)%waterdiagnostic_inst%Init(bounds, & this%bulk_and_tracers(i)%info, & diff --git a/src/unit_test_shr/unittestWaterTypeFactory.F90 b/src/unit_test_shr/unittestWaterTypeFactory.F90 index cc3510e881..f5f417f9ce 100644 --- a/src/unit_test_shr/unittestWaterTypeFactory.F90 +++ b/src/unit_test_shr/unittestWaterTypeFactory.F90 @@ -161,7 +161,8 @@ subroutine create_water_type(this, water_inst, & h2osno_col = col_array(0._r8), & snow_depth_col = col_array(0._r8), & watsat_col = l_watsat_col, & - t_soisno_col = l_t_soisno_col) + t_soisno_col = l_t_soisno_col, & + NLFilename = ' ') end subroutine create_water_type subroutine teardown(this, water_inst) From 5caa1792f90b3a9564e93f8def521fdfbeaef049 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Sun, 26 Jun 2022 20:07:56 +0200 Subject: [PATCH 30/99] indent and comment spaces fix --- bld/CLMBuildNamelist.pm | 2 +- bld/namelist_files/namelist_defaults_ctsm.xml | 2 +- src/biogeophys/SoilHydrologyMod.F90 | 6 +- src/biogeophys/SoilTemperatureMod.F90 | 62 +++--- src/biogeophys/WaterDiagnosticBulkType.F90 | 48 ++--- src/biogeophys/WaterStateBulkType.F90 | 14 +- src/biogeophys/WaterStateType.F90 | 193 +++++++++--------- 7 files changed, 166 insertions(+), 161 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 357eb2d4d2..606f182667 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -4156,7 +4156,7 @@ sub setup_logic_exice { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_mapalgo_exice'); } elsif (defined($use_exice) && (! $opts->{'driver'} eq "nuopc") && value_is_true($use_exice)) { $log->fatal_error("nuopc driver is required when use_excess_ice is set to true" ); -} + } } # end exice streams diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 911ed296cf..d8e3eaa810 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -2587,7 +2587,7 @@ lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts general - + .false. diff --git a/src/biogeophys/SoilHydrologyMod.F90 b/src/biogeophys/SoilHydrologyMod.F90 index 8ef690d5b9..c46d23f870 100644 --- a/src/biogeophys/SoilHydrologyMod.F90 +++ b/src/biogeophys/SoilHydrologyMod.F90 @@ -190,9 +190,9 @@ subroutine SetSoilWaterFractions(bounds, num_hydrologyc, filter_hydrologyc, & watsat => soilstate_inst%watsat_col , & ! Input: [real(r8) (:,:) ] volumetric soil water at saturation (porosity) eff_porosity => soilstate_inst%eff_porosity_col , & ! Output: [real(r8) (:,:) ] effective porosity = porosity - vol_ice - h2osoi_liq => waterstatebulk_inst%h2osoi_liq_col , & ! Input: [real(r8) (:,:) ] liquid water (kg/m2) - h2osoi_ice => waterstatebulk_inst%h2osoi_ice_col , & ! Input: [real(r8) (:,:) ] ice water (kg/m2) - excess_ice => waterstatebulk_inst%excess_ice_col , & ! Input: [real(r8) (:,:) ] excess ice (kg/m2) + h2osoi_liq => waterstatebulk_inst%h2osoi_liq_col , & ! Input: [real(r8) (:,:) ] liquid water (kg/m2) + h2osoi_ice => waterstatebulk_inst%h2osoi_ice_col , & ! Input: [real(r8) (:,:) ] ice water (kg/m2) + excess_ice => waterstatebulk_inst%excess_ice_col , & ! Input: [real(r8) (:,:) ] excess ice (kg/m2) origflag => soilhydrology_inst%origflag , & ! Input: logical icefrac => soilhydrology_inst%icefrac_col , & ! Output: [real(r8) (:,:) ] diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index da755bf9cf..112346d74d 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -288,7 +288,7 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter do fc = 1,num_nolakec c = filter_nolakec(fc) l = col%landunit(c) - if( lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then + if( lun%itype(l) == istsoil .or. lun%itype(l) == istcrop ) then dz(c,1:nlevmaxurbgrnd)=dz(c,1:nlevmaxurbgrnd)+excess_ice(c,1:nlevmaxurbgrnd)/denice ! add extra layer thickness do j=1,nlevmaxurbgrnd ! if excess ice amount dropped to zero there will be no adjustment zi(c,j) = zi(c,j) + sum(excess_ice(c,1:j)) / denice @@ -524,7 +524,7 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter do fc = 1,num_nolakec c = filter_nolakec(fc) l = col%landunit(c) - if( lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then + if( lun%itype(l) == istsoil .or. lun%itype(l) == istcrop ) then dz(c,1:nlevmaxurbgrnd)=dz_0(c,1:nlevmaxurbgrnd) zi(c,1:nlevmaxurbgrnd)=zi_0(c,1:nlevmaxurbgrnd) z(c,1:nlevmaxurbgrnd)=z_0(c,1:nlevmaxurbgrnd) @@ -673,7 +673,7 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter h2osno_no_layers => waterstatebulk_inst%h2osno_no_layers_col , & ! Input: [real(r8) (:) ] snow not resolved into layers (mm H2O) h2osoi_liq => waterstatebulk_inst%h2osoi_liq_col , & ! Input: [real(r8) (:,:) ] liquid water (kg/m2) h2osoi_ice => waterstatebulk_inst%h2osoi_ice_col , & ! Input: [real(r8) (:,:) ] ice lens (kg/m2) - excess_ice => waterstatebulk_inst%excess_ice_col , & ! Input: [real(r8) (:,:) ] excess ice lenses (kg/m2) (new) (1:nlevgrnd) + excess_ice => waterstatebulk_inst%excess_ice_col , & ! Input: [real(r8) (:,:) ] excess ice lenses (kg/m2) (new) (1:nlevgrnd) bw => waterdiagnosticbulk_inst%bw_col , & ! Output: [real(r8) (:,:) ] partial density of water in the snow pack (ice + liquid) [kg/m3] tkmg => soilstate_inst%tkmg_col , & ! Input: [real(r8) (:,:) ] thermal conductivity, soil minerals [W/m-K] @@ -700,7 +700,7 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter col%itype(c) /= icol_roof .and. col%itype(c) /= icol_road_imperv) .or. & (col%itype(c) == icol_road_imperv .and. j > nlev_improad(l))) then - !TODO recalculate watsat and satw to have excess ice included + !TODO recalculate watsat and satw to have excess ice included satw = (h2osoi_liq(c,j)/denh2o + h2osoi_ice(c,j)/denice +excess_ice(c,j)/denice)/(dz(c,j)*watsat(c,j)) satw = min(1._r8, satw) if (satw > .1e-6_r8) then @@ -803,7 +803,8 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter .and. col%itype(c) /= icol_sunwall .and. col%itype(c) /= icol_shadewall .and. & col%itype(c) /= icol_roof .and. col%itype(c) /= icol_road_imperv) .or. & (col%itype(c) == icol_road_imperv .and. j > nlev_improad(l))) then - cv(c,j) = csol(c,j)*(1._r8-watsat(c,j))*dz(c,j) + (h2osoi_ice(c,j)*cpice + h2osoi_liq(c,j)*cpliq) + excess_ice(c,j)*cpice + cv(c,j) = csol(c,j)*(1._r8-watsat(c,j))*dz(c,j) + (h2osoi_ice(c,j)*cpice + & + h2osoi_liq(c,j)*cpliq) + excess_ice(c,j)*cpice if (j > nbedrock(c)) cv(c,j) = csol_bedrock*dz(c,j) else if (lun%itype(l) == istwet) then cv(c,j) = (h2osoi_ice(c,j)*cpice + h2osoi_liq(c,j)*cpliq) @@ -1133,10 +1134,10 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & real(r8) :: wice0 (bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)!initial mass of ice (kg/m2) real(r8) :: wliq0 (bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)!initial mass of liquid (kg/m2) real(r8) :: supercool(bounds%begc:bounds%endc,nlevmaxurbgrnd) !supercooled water in soil (kg/m2) - real(r8) :: propor !proportionality constant (-) + real(r8) :: propor !proportionality constant (-) real(r8) :: tinc(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) !t(n+1)-t(n) [K] - real(r8) :: smp !frozen water potential (mm) - real(r8) :: wexice0(bounds%begc:bounds%endc,-nlevsno+1:nlevgrnd)!initial mass of excess_ice at the timestep (kg/m2) + real(r8) :: smp !frozen water potential (mm) + real(r8) :: wexice0(bounds%begc:bounds%endc,-nlevsno+1:nlevgrnd) !initial mass of excess_ice at the timestep (kg/m2) !----------------------------------------------------------------------- @@ -1159,9 +1160,9 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & snow_depth => waterdiagnosticbulk_inst%snow_depth_col , & ! Input: [real(r8) (:) ] snow height (m) exice_subs_col => waterdiagnosticbulk_inst%exice_subs_col , & ! Output: [real(r8) (:,:) ] per layer subsidence due to excess ice melt (mm/s) h2osno_no_layers => waterstatebulk_inst%h2osno_no_layers_col , & ! Output: [real(r8) (:) ] snow not resolved into layers (mm H2O) - h2osoi_liq => waterstatebulk_inst%h2osoi_liq_col , & ! Output: [real(r8) (:,:) ] liquid water (kg/m2) (new) - h2osoi_ice => waterstatebulk_inst%h2osoi_ice_col , & ! Output: [real(r8) (:,:) ] ice lens (kg/m2) (new) - excess_ice => waterstatebulk_inst%excess_ice_col , & ! Input: [real(r8) (:,:) ] excess ice (kg/m2) (new) (1:nlevgrnd) + h2osoi_liq => waterstatebulk_inst%h2osoi_liq_col , & ! Output: [real(r8) (:,:) ] liquid water (kg/m2) (new) + h2osoi_ice => waterstatebulk_inst%h2osoi_ice_col , & ! Output: [real(r8) (:,:) ] ice lens (kg/m2) (new) + excess_ice => waterstatebulk_inst%excess_ice_col , & ! Input: [real(r8) (:,:) ] excess ice (kg/m2) (new) (1:nlevgrnd) qflx_snow_drain => waterfluxbulk_inst%qflx_snow_drain_col , & ! Output: [real(r8) (:) ] drainage from snow pack qflx_snofrz_lyr => waterfluxbulk_inst%qflx_snofrz_lyr_col , & ! Output: [real(r8) (:,:) ] snow freezing rate (positive definite) (col,lyr) [kg m-2 s-1] @@ -1210,9 +1211,9 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & wliq0(c,j) = h2osoi_liq(c,j) wexice0(c,j)=excess_ice(c,j) wmass0(c,j) = h2osoi_ice(c,j) + h2osoi_liq(c,j) + wexice0(c,j) - if (j>=1) then - exice_subs_col(c,j)=0._r8 - endif + if (j>=1) then + exice_subs_col(c,j)=0._r8 + endif endif ! end of snow layer if-block if (j <= 0) then @@ -1271,9 +1272,9 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & ! melt excess ice after normal ice if (excess_ice(c,j) > 0._r8 .AND. t_soisno(c,j) > tfrz) then - imelt(c,j) = 1 - tinc(c,j) = tfrz - t_soisno(c,j) - t_soisno(c,j) = tfrz + imelt(c,j) = 1 + tinc(c,j) = tfrz - t_soisno(c,j) + t_soisno(c,j) = tfrz endif ! from Zhao (1997) and Koren (1999) @@ -1391,24 +1392,24 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & heatr = 0._r8 if (xm(c,j) > 0._r8) then !if there is excess heat to melt the ice - h2osoi_ice(c,j) = max(0._r8, wice0(c,j)-xm(c,j)) - heatr = hm(c,j) - hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime - xm2(c,j) = xm(c,j) - h2osoi_ice(c,j) !excess ice melting - if (h2osoi_ice(c,j) == 0._r8) then ! this might be redundant + h2osoi_ice(c,j) = max(0._r8, wice0(c,j)-xm(c,j)) + heatr = hm(c,j) - hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime + xm2(c,j) = xm(c,j) - h2osoi_ice(c,j) !excess ice melting + if (h2osoi_ice(c,j) == 0._r8) then ! this might be redundant if (excess_ice(c,j) >= 0._r8 .and. xm2(c,j)>0._r8 .and. j>=2) then ! if there is excess ice to melt - excess_ice(c,j) = max(0._r8,wexice0(c,j) - xm2(c,j)) - heatr = hm(c,j) - hfus * (wexice0(c,j)-excess_ice(c,j)+wice0(c,j)-h2osoi_ice(c,j)) / dtime + excess_ice(c,j) = max(0._r8,wexice0(c,j) - xm2(c,j)) + heatr = hm(c,j) - hfus * (wexice0(c,j)-excess_ice(c,j)+wice0(c,j)-h2osoi_ice(c,j)) / dtime endif - endif !end of excess ice block + endif !end of excess ice block else if (xm(c,j) < 0._r8) then if (j <= 0) then h2osoi_ice(c,j) = min(wmass0(c,j), wice0(c,j)-xm(c,j)) ! snow else - if (wmass0(c,j) - wexice0(c,j) < supercool(c,j)) then !even if excess ice is present, it cannot refreeze - h2osoi_ice(c,j) = 0._r8 - else - h2osoi_ice(c,j) = min(wmass0(c,j) - wexice0(c,j) - supercool(c,j),wice0(c,j)-xm(c,j)) - endif + if (wmass0(c,j) - wexice0(c,j) < supercool(c,j)) then !even if excess ice is present, it cannot refreeze + h2osoi_ice(c,j) = 0._r8 + else + h2osoi_ice(c,j) = min(wmass0(c,j) - wexice0(c,j) - supercool(c,j),wice0(c,j)-xm(c,j)) + endif endif heatr = hm(c,j) - hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime endif @@ -1446,7 +1447,8 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & endif ! end of heatr > 0 if-block if (j >= 1) then - xmf(c) = xmf(c) + hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime +hfus*(wexice0(c,j)-excess_ice(c,j))/dtime + xmf(c) = xmf(c) + hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime + & + hfus*(wexice0(c,j)-excess_ice(c,j))/dtime ! subsidence calculation exice_subs_col(c,j) = max(0._r8, (wexice0(c,j)-excess_ice(c,j))/denice) else diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index 6b150ceaf5..d7413fb740 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -905,30 +905,32 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil end if if (.not. use_excess_ice) then - ! no need to even define the restart vars - this%exice_subs_tot_col(bounds%begc:bounds%endc)=0.0_r8 - this%exice_vol_tot_col(bounds%begc:bounds%endc)=0.0_r8 - this%exice_subs_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 - this%exice_vol_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 + ! no need to even define the restart vars + this%exice_subs_tot_col(bounds%begc:bounds%endc)=0.0_r8 + this%exice_vol_tot_col(bounds%begc:bounds%endc)=0.0_r8 + this%exice_subs_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 + this%exice_vol_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 else - ! initialization of these to zero is ok, since they might not be in the restart file - this%exice_subs_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 - this%exice_vol_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 - ! have to at least define them - call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('SUBSIDENCE'), & - dim1name='column', xtype=ncd_double, & - long_name=this%info%lname('vertically summed volumetric excess ice concentration (veg landunits only)'), units='m', & - interpinic_flag='interp', readvar=readvar, data=this%exice_subs_tot_col) - if (flag == 'read' .and. (.not. readvar)) then ! when reading restart that does not have excess ice in it - this%exice_subs_tot_col(bounds%begc:bounds%endc)=0.0_r8 - this%exice_vol_tot_col(bounds%begc:bounds%endc)=0.0_r8 - this%exice_subs_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 - this%exice_vol_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 - endif - call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('TOTEXICE_VOL'), & - dim1name='column', xtype=ncd_double, & - long_name=this%info%lname('vertically averaged volumetric excess ice concentration (veg landunits only)'), units='m3/m3', & - interpinic_flag='interp', readvar=readvar, data=this%exice_vol_tot_col) + ! initialization of these to zero is ok, since they might not be in the restart file + this%exice_subs_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 + this%exice_vol_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 + ! have to at least define them + call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('SUBSIDENCE'), & + dim1name='column', xtype=ncd_double, & + long_name=this%info%lname('vertically summed volumetric excess ice concentration (veg landunits only)'), & + units='m', & + interpinic_flag='interp', readvar=readvar, data=this%exice_subs_tot_col) + if (flag == 'read' .and. (.not. readvar)) then ! when reading restart that does not have excess ice in it + this%exice_subs_tot_col(bounds%begc:bounds%endc)=0.0_r8 + this%exice_vol_tot_col(bounds%begc:bounds%endc)=0.0_r8 + this%exice_subs_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 + this%exice_vol_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 + endif + call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('TOTEXICE_VOL'), & + dim1name='column', xtype=ncd_double, & + long_name=this%info%lname('vertically averaged volumetric excess ice concentration (veg landunits only)'), & + units='m3/m3', & + interpinic_flag='interp', readvar=readvar, data=this%exice_vol_tot_col) endif end subroutine RestartBulk diff --git a/src/biogeophys/WaterStateBulkType.F90 b/src/biogeophys/WaterStateBulkType.F90 index 74dae314e8..ba3f0513c5 100644 --- a/src/biogeophys/WaterStateBulkType.F90 +++ b/src/biogeophys/WaterStateBulkType.F90 @@ -54,10 +54,10 @@ subroutine InitBulk(this, bounds, info, vars, & class(water_info_base_type), intent(in), target :: info type(water_tracer_container_type), intent(inout) :: vars real(r8) , intent(in) :: h2osno_input_col(bounds%begc:) - real(r8) , intent(in) :: watsat_col(bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) + real(r8) , intent(in) :: watsat_col(bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) real(r8) , intent(in) :: t_soisno_col(bounds%begc:, -nlevsno+1:) ! col soil temperature (Kelvin) - logical , intent(in) :: use_aquifer_layer ! whether an aquifer layer is used in this run - character(len=*) , intent(in) :: NLFilename ! Namelist filename + logical , intent(in) :: use_aquifer_layer ! whether an aquifer layer is used in this run + character(len=*) , intent(in) :: NLFilename ! Namelist filename call this%Init(bounds = bounds, & info = info, & @@ -200,11 +200,11 @@ subroutine RestartBulk(this, bounds, ncid, flag, & ! !ARGUMENTS: class(waterstatebulk_type), intent(in) :: this type(bounds_type), intent(in) :: bounds - type(file_desc_t), intent(inout) :: ncid ! netcdf id - character(len=*) , intent(in) :: flag ! 'read' or 'write' - real(r8) , intent(in) :: watsat_col (bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) + type(file_desc_t), intent(inout) :: ncid ! netcdf id + character(len=*) , intent(in) :: flag ! 'read' or 'write' + real(r8) , intent(in) :: watsat_col (bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) real(r8) , intent(in) :: t_soisno_col(bounds%begc:, -nlevsno+1:) ! col soil temperature (Kelvin) - integer , intent(in) :: altmax_lastyear_indx(bounds%begc:) !col active layer index last year + integer , intent(in) :: altmax_lastyear_indx(bounds%begc:) !col active layer index last year ! ! !LOCAL VARIABLES: integer :: c,l,j diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index 944f4a72f5..c33880a3c3 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -47,13 +47,13 @@ module WaterStateType ! For the following dynbal baseline variables: positive values are subtracted to ! avoid counting liquid water content of "virtual" states; negative values are added ! to account for missing states in the model. - real(r8), pointer :: dynbal_baseline_liq_col(:) ! baseline liquid water content subtracted from each column's total liquid water calculation (mm H2O) - real(r8), pointer :: dynbal_baseline_ice_col(:) ! baseline ice content subtracted from each column's total ice calculation (mm H2O) + real(r8), pointer :: dynbal_baseline_liq_col(:) ! baseline liquid water content subtracted from each column's total liquid water calculation (mm H2O) + real(r8), pointer :: dynbal_baseline_ice_col(:) ! baseline ice content subtracted from each column's total ice calculation (mm H2O) - real(r8) :: aquifer_water_baseline ! baseline value for water in the unconfined aquifer (wa_col) for this bulk / tracer (mm) + real(r8) :: aquifer_water_baseline ! baseline value for water in the unconfined aquifer (wa_col) for this bulk / tracer (mm) - real(r8), pointer :: excess_ice_col (:,:) ! col excess ice (kg/m2) (new) (-nlevsno+1:nlevgrnd) - real(r8), pointer :: exice_bulk_init (:) ! inital value for excess ice (new) (unitless) + real(r8), pointer :: excess_ice_col (:,:) ! col excess ice (kg/m2) (new) (-nlevsno+1:nlevgrnd) + real(r8), pointer :: exice_bulk_init (:) ! inital value for excess ice (new) (unitless) type(excessicestream_type), private :: exicestream ! stream type for excess ice initialization NUOPC only @@ -158,13 +158,13 @@ subroutine InitAllocate(this, bounds, tracer_vars) container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_column) !excess ice vars - call AllocateVar2d(var = this%excess_ice_col, name = 'excess_ice_col', & - container = tracer_vars, & - bounds = bounds, subgrid_level = subgrid_level_column, & - dim2beg = -nlevsno+1, dim2end = nlevmaxurbgrnd) - call AllocateVar1d(var = this%exice_bulk_init, name = 'exice_bulk_init', & - container = tracer_vars, & - bounds = bounds, subgrid_level = subgrid_level_column) + call AllocateVar2d(var = this%excess_ice_col, name = 'excess_ice_col', & + container = tracer_vars, & + bounds = bounds, subgrid_level = subgrid_level_column, & + dim2beg = -nlevsno+1, dim2end = nlevmaxurbgrnd) + call AllocateVar1d(var = this%exice_bulk_init, name = 'exice_bulk_init', & + container = tracer_vars, & + bounds = bounds, subgrid_level = subgrid_level_column) end subroutine InitAllocate @@ -283,14 +283,14 @@ subroutine InitHistory(this, bounds, use_aquifer_layer) ptr_col=this%wa_col, l2g_scale_type='veg') end if - ! Add excess ice fields to history + ! Add excess ice fields to history - if (use_excess_ice) then - data2dptr => this%excess_ice_col(begc:endc,1:nlevsoi) - call hist_addfld2d (fname='EXCESS_ICE', units='kg/m2', type2d='levsoi', & - avgflag='A', long_name='excess soil ice (vegetated landunits only)', & - ptr_col=this%excess_ice_col, l2g_scale_type='veg') - end if + if (use_excess_ice) then + data2dptr => this%excess_ice_col(begc:endc,1:nlevsoi) + call hist_addfld2d (fname='EXCESS_ICE', units='kg/m2', type2d='levsoi', & + avgflag='A', long_name='excess soil ice (vegetated landunits only)', & + ptr_col=this%excess_ice_col, l2g_scale_type='veg') + end if ! (rgk 02-02-2017) There is intentionally no entry here for stored plant water ! I think that since the value is zero in all cases except @@ -321,10 +321,10 @@ subroutine InitCold(this, bounds, & class(waterstate_type), intent(inout) :: this type(bounds_type) , intent(in) :: bounds real(r8) , intent(in) :: h2osno_input_col(bounds%begc:) - real(r8) , intent(in) :: watsat_col(bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) + real(r8) , intent(in) :: watsat_col(bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) real(r8) , intent(in) :: t_soisno_col(bounds%begc:, -nlevsno+1:) ! col soil temperature (Kelvin) - logical , intent(in) :: use_aquifer_layer ! whether an aquifer layer is used in this run - character(len=*) , intent(in) :: NLFilename ! Namelist filename + logical , intent(in) :: use_aquifer_layer ! whether an aquifer layer is used in this run + character(len=*) , intent(in) :: NLFilename ! Namelist filename ! ! !LOCAL VARIABLES: integer :: c,j,l,nlevs,g @@ -532,46 +532,46 @@ subroutine InitCold(this, bounds, & !Initialize excess ice if (use_excess_ice .and. NLFilename /= '') then - ! enforce initialization with 0 for everything - this%excess_ice_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 - this%exice_bulk_init(bounds%begc:bounds%endc)=0.0_r8 - call this%exicestream%Init(bounds, NLFilename) ! get initial fraction of excess ice per column - call this%exicestream%CalcExcessIce(bounds, this%exice_bulk_init) - do c = bounds%begc,bounds%endc - g = col%gridcell(c) - l = col%landunit(c) - if (.not. lun%lakpoi(l)) then !not lake - if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then - n1m=3 - do j = 3, nlevsoi ! get layer with 1 m depth - if (col%zi(c,j-1)<=1.0_r8 .and. col%zi(c,j)>1.0_r8) then - n1m=j - end if - end do - if (use_bedrock .and. nbedrock<=nlevsoi) then - nbedrock = col%nbedrock(c) - else - nbedrock = nlevsoi - endif - do j = 2, nlevmaxurbgrnd ! ignore first layer - if (n1m= n1m .and. j1.0_r8) then + n1m=j + end if + end do + if (use_bedrock .and. nbedrock<=nlevsoi) then + nbedrock = col%nbedrock(c) + else + nbedrock = nlevsoi + endif + do j = 2, nlevmaxurbgrnd ! ignore first layer + if (n1m= n1m .and. jaltmax_lastyear_indx(c) .and. jaltmax_lastyear_indx(c) .and. j Date: Sun, 26 Jun 2022 20:08:15 +0200 Subject: [PATCH 31/99] removed sb --- src/biogeophys/TemperatureType.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/biogeophys/TemperatureType.F90 b/src/biogeophys/TemperatureType.F90 index e3ceaf3a41..995496b388 100644 --- a/src/biogeophys/TemperatureType.F90 +++ b/src/biogeophys/TemperatureType.F90 @@ -647,7 +647,7 @@ subroutine InitCold(this, bounds, & ! !USES: use shr_kind_mod , only : r8 => shr_kind_r8 use shr_const_mod , only : SHR_CONST_TKFRZ - use clm_varcon , only : denice, denh2o, sb !what's sb? how it's never used here + use clm_varcon , only : denice, denh2o use landunit_varcon, only : istwet, istsoil, istdlak, istice, istcrop use column_varcon , only : icol_road_imperv, icol_roof, icol_sunwall use column_varcon , only : icol_shadewall, icol_road_perv From 6ecc63b36bb19439ebbc38087189e7a47cf6f4b0 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Sun, 26 Jun 2022 20:09:25 +0200 Subject: [PATCH 32/99] stream descirption, private usestreams, indents --- src/cpl/share_esmf/ExcessIceStreamType.F90 | 36 ++++++++++++++-------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/cpl/share_esmf/ExcessIceStreamType.F90 b/src/cpl/share_esmf/ExcessIceStreamType.F90 index 260a194dc5..134810ba1b 100644 --- a/src/cpl/share_esmf/ExcessIceStreamType.F90 +++ b/src/cpl/share_esmf/ExcessIceStreamType.F90 @@ -4,7 +4,16 @@ module ExcessIceStreamType !----------------------------------------------------------------------- ! !DESCRIPTION: - ! Contains methods for reading in excess ice initial bulk values from data stream + ! Contains methods for reading in excess ice initial bulk values from data stream. + ! Needed in parameterization for excess ice in soil (Lee et al., 2014). + ! Used when use_excess_ice is true for initialization: + ! startup type runs starting from coldstart and initial datasets + ! that do not have required variables + ! or hybrid runs from cases with use_excess_ice was false. + ! Dataset is interpolated to 0.125x0.125 degrees grid from Brown et al., 1997 + ! with values derived from permafrost types. + ! Values represent fraction of excess ice within soil column + ! and are distributed within it later in initialization ! ! !USES use ESMF @@ -25,9 +34,9 @@ module ExcessIceStreamType contains ! !PUBLIC MEMBER FUNCTIONS: - procedure, public :: Init ! Initialize and read data in - procedure, public :: UseStreams ! If streams will be used - procedure, public :: CalcExcessIce ! Calculate excess ice ammount + procedure, public :: Init ! Initialize and read data in + procedure, private :: UseStreams ! If streams will be used + procedure, public :: CalcExcessIce ! Calculate excess ice ammount ! !PRIVATE MEMBER FUNCTIONS: procedure, private :: InitAllocate ! Allocate data @@ -107,6 +116,7 @@ subroutine Init(this, bounds, NLFilename) stream_offset = 0, & stream_taxmode = 'extend', & stream_dtlimit = 1.0e30_r8, & + ! in ch4FinundatedStreamType it is set to linear but we have a single date dataset stream_tintalgo = 'nearest', & stream_name = 'excess ice ', & rc = rc) @@ -125,24 +135,24 @@ subroutine Init(this, bounds, NLFilename) mcdate = year*10000 + mon*100 + day call shr_strdata_advance(sdat_exice, ymd=mcdate, tod=sec, logunit=iulog, istr='exice', rc=rc) - if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) then - call ESMF_Finalize(endflag=ESMF_END_ABORT) - end if + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) then + call ESMF_Finalize(endflag=ESMF_END_ABORT) + end if - ! Get pointer for stream data that is time and spatially interpolate to model time and grid - do n = 1,size(stream_varnames) + ! Get pointer for stream data that is time and spatially interpolate to model time and grid + do n = 1,size(stream_varnames) call dshr_fldbun_getFldPtr(sdat_exice%pstrm(1)%fldbun_model, stream_varnames(n), fldptr1=dataptr1d, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) then - call ESMF_Finalize(endflag=ESMF_END_ABORT) + call ESMF_Finalize(endflag=ESMF_END_ABORT) end if if (trim(stream_varnames(n)) == 'EXICE') then ig = 0 do g = bounds%begg,bounds%endg - ig = ig+1 - this%exice_bulk(g) = dataptr1d(ig) + ig = ig+1 + this%exice_bulk(g) = dataptr1d(ig) end do end if - end do + end do end if end subroutine Init From e3051554246ea6253882f7e7b36abf7c83edb307 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Tue, 2 Aug 2022 16:34:52 +0200 Subject: [PATCH 33/99] change initial depth InitCold to 0.5 --- src/biogeophys/WaterStateType.F90 | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index c33880a3c3..081a6d78e3 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -314,8 +314,9 @@ subroutine InitCold(this, bounds, & use shr_const_mod , only : SHR_CONST_TKFRZ use landunit_varcon , only : istwet, istsoil, istcrop, istice use column_varcon , only : icol_road_perv, icol_road_imperv - use clm_varcon , only : denice, denh2o, bdsno + use clm_varcon , only : denice, denh2o, bdsno , zisoi use clm_varcon , only : tfrz, aquifer_water_baseline + use initVerticalMod , only : find_soil_layer_containing_depth ! ! !ARGUMENTS: class(waterstate_type), intent(inout) :: this @@ -328,7 +329,7 @@ subroutine InitCold(this, bounds, & ! ! !LOCAL VARIABLES: integer :: c,j,l,nlevs,g - integer :: nbedrock, n1m + integer :: nbedrock, n05m ! layer containing 0.5 m real(r8) :: ratio !----------------------------------------------------------------------- @@ -542,20 +543,19 @@ subroutine InitCold(this, bounds, & l = col%landunit(c) if (.not. lun%lakpoi(l)) then !not lake if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then - n1m=3 - do j = 3, nlevsoi ! get layer with 1 m depth - if (col%zi(c,j-1)<=1.0_r8 .and. col%zi(c,j)>1.0_r8) then - n1m=j - end if - end do + if (zisoi(nlevsoi) >= 0.5_r8) then + call find_soil_layer_containing_depth(0.5_r8,n05m) + else + n05m=nlevsoi-1 + endif if (use_bedrock .and. nbedrock<=nlevsoi) then nbedrock = col%nbedrock(c) else nbedrock = nlevsoi endif do j = 2, nlevmaxurbgrnd ! ignore first layer - if (n1m= n1m .and. j= n05m .and. j Date: Tue, 2 Aug 2022 12:45:08 -0600 Subject: [PATCH 34/99] Change name of mesh file to one in CDF5 format --- bld/namelist_files/namelist_defaults_ctsm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index d8e3eaa810..bbd6949f92 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -2593,7 +2593,7 @@ lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts .false. lnd/clm2/paramdata/exice_init_0.125x0.125_c20220516.nc -lnd/clm2/paramdata/exice_init_0.125x0.125_ESMFmesh_c20220516.nc +lnd/clm2/paramdata/exice_init_0.125x0.125_ESMFmesh_cdf5_c20220802.nc bilinear From 88b8feaa7dd614a859c60b5687c76bb285c25d93 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Wed, 3 Aug 2022 10:16:33 +0200 Subject: [PATCH 35/99] fixed indent WaterState --- src/biogeophys/WaterStateType.F90 | 54 +++++++++++++++---------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index 081a6d78e3..9678e8c4c1 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -541,33 +541,33 @@ subroutine InitCold(this, bounds, & do c = bounds%begc,bounds%endc g = col%gridcell(c) l = col%landunit(c) - if (.not. lun%lakpoi(l)) then !not lake - if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then - if (zisoi(nlevsoi) >= 0.5_r8) then - call find_soil_layer_containing_depth(0.5_r8,n05m) - else - n05m=nlevsoi-1 - endif - if (use_bedrock .and. nbedrock<=nlevsoi) then - nbedrock = col%nbedrock(c) - else - nbedrock = nlevsoi - endif - do j = 2, nlevmaxurbgrnd ! ignore first layer - if (n05m= n05m .and. j= 0.5_r8) then + call find_soil_layer_containing_depth(0.5_r8,n05m) + else + n05m=nlevsoi-1 + endif + if (use_bedrock .and. nbedrock<=nlevsoi) then + nbedrock = col%nbedrock(c) + else + nbedrock = nlevsoi + endif + do j = 2, nlevmaxurbgrnd ! ignore first layer + if (n05m= n05m .and. j Date: Wed, 3 Aug 2022 10:19:10 +0200 Subject: [PATCH 36/99] add TODO to ExcessIceStream --- src/cpl/share_esmf/ExcessIceStreamType.F90 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpl/share_esmf/ExcessIceStreamType.F90 b/src/cpl/share_esmf/ExcessIceStreamType.F90 index 134810ba1b..b0f79d1bfa 100644 --- a/src/cpl/share_esmf/ExcessIceStreamType.F90 +++ b/src/cpl/share_esmf/ExcessIceStreamType.F90 @@ -124,6 +124,7 @@ subroutine Init(this, bounds, NLFilename) call ESMF_Finalize(endflag=ESMF_END_ABORT) end if + !TODO ! Explicitly set current date to a hardcoded constant value. Otherwise ! using the real date can cause roundoff differences that are ! detrected as issues with exact restart. EBK M05/20/2017 From 444d5b6af89cde56798bc2e47df16d1d72a37bf5 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Wed, 3 Aug 2022 12:54:16 +0200 Subject: [PATCH 37/99] Fixed typo --- src/biogeophys/SoilTemperatureMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index 112346d74d..f149208ba5 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -710,7 +710,7 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter dke = satw end if fl = (h2osoi_liq(c,j)/(denh2o*dz(c,j))) / (h2osoi_liq(c,j)/(denh2o*dz(c,j)) + & - h2osoi_ice(c,j)/(denice*dz(c,j))+excess_ice(c,j)/denice) + h2osoi_ice(c,j)/(denice*dz(c,j))+excess_ice(c,j)/(denice*dz)) dksat = tkmg(c,j)*tkwat**(fl*watsat(c,j))*tkice**((1._r8-fl)*watsat(c,j)) thk(c,j) = dke*dksat + (1._r8-dke)*tkdry(c,j) else From ddd7a82ecfff31a8aa6497675b380180d4055278 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Wed, 3 Aug 2022 13:16:27 +0200 Subject: [PATCH 38/99] another typo --- src/biogeophys/SoilTemperatureMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index f149208ba5..c42130d8d2 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -710,7 +710,7 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter dke = satw end if fl = (h2osoi_liq(c,j)/(denh2o*dz(c,j))) / (h2osoi_liq(c,j)/(denh2o*dz(c,j)) + & - h2osoi_ice(c,j)/(denice*dz(c,j))+excess_ice(c,j)/(denice*dz)) + h2osoi_ice(c,j)/(denice*dz(c,j))+excess_ice(c,j)/(denice*dz(c,j))) dksat = tkmg(c,j)*tkwat**(fl*watsat(c,j))*tkice**((1._r8-fl)*watsat(c,j)) thk(c,j) = dke*dksat + (1._r8-dke)*tkdry(c,j) else From b75e6ba25b7010dd26ebb2d87351999123bbb124 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Wed, 3 Aug 2022 17:39:34 +0200 Subject: [PATCH 39/99] remove MVD --- src/main/controlMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/controlMod.F90 b/src/main/controlMod.F90 index 194e1704aa..48564c8855 100644 --- a/src/main/controlMod.F90 +++ b/src/main/controlMod.F90 @@ -870,7 +870,7 @@ subroutine control_print () write(iulog,*) ' use_nitrif_denitrif = ', use_nitrif_denitrif write(iulog,*) ' use_extralakelayers = ', use_extralakelayers write(iulog,*) ' use_vichydro = ', use_vichydro - write(iulog,*) ' use_excess_ice = ', use_excess_ice !MVD to check if the value is read from namelists + write(iulog,*) ' use_excess_ice = ', use_excess_ice write(iulog,*) ' use_cn = ', use_cn write(iulog,*) ' use_cndv = ', use_cndv write(iulog,*) ' use_crop = ', use_crop From e83925016b09ff51351a1d8cf222b3beb43860d2 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 4 Aug 2022 16:53:38 -0600 Subject: [PATCH 40/99] Add an excess ice test to the testlist --- cime_config/testdefs/testlist_clm.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 29205014cf..b2a063d011 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -168,6 +168,15 @@ + + + + + + + + + From 5dd8aa5f1cf0a9103d83877c67e0da9c5c4f502d Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 4 Aug 2022 16:53:55 -0600 Subject: [PATCH 41/99] Add excess ice testmod --- .../testdefs/testmods_dirs/clm/ExcessIce/include_user_mods | 1 + cime_config/testdefs/testmods_dirs/clm/ExcessIce/user_nl_clm | 1 + 2 files changed, 2 insertions(+) create mode 100644 cime_config/testdefs/testmods_dirs/clm/ExcessIce/include_user_mods create mode 100644 cime_config/testdefs/testmods_dirs/clm/ExcessIce/user_nl_clm diff --git a/cime_config/testdefs/testmods_dirs/clm/ExcessIce/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/ExcessIce/include_user_mods new file mode 100644 index 0000000000..fe0e18cf88 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/ExcessIce/include_user_mods @@ -0,0 +1 @@ +../default diff --git a/cime_config/testdefs/testmods_dirs/clm/ExcessIce/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/ExcessIce/user_nl_clm new file mode 100644 index 0000000000..d9e52c6cf9 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/ExcessIce/user_nl_clm @@ -0,0 +1 @@ + use_excess_ice = .true. From a9848ada0c19d9a56a4dfc6f7f351d1d6f934710 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Sat, 15 Oct 2022 01:19:08 +0200 Subject: [PATCH 42/99] history vars and issue 1819 --- src/biogeophys/SoilTemperatureMod.F90 | 1 - src/biogeophys/WaterStateType.F90 | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index c42130d8d2..f7b970c057 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -700,7 +700,6 @@ subroutine SoilThermProp (bounds, num_urbanc, filter_urbanc, num_nolakec, filter col%itype(c) /= icol_roof .and. col%itype(c) /= icol_road_imperv) .or. & (col%itype(c) == icol_road_imperv .and. j > nlev_improad(l))) then - !TODO recalculate watsat and satw to have excess ice included satw = (h2osoi_liq(c,j)/denh2o + h2osoi_ice(c,j)/denice +excess_ice(c,j)/denice)/(dz(c,j)*watsat(c,j)) satw = min(1._r8, satw) if (satw > .1e-6_r8) then diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index 9678e8c4c1..135d5f61d8 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -289,7 +289,7 @@ subroutine InitHistory(this, bounds, use_aquifer_layer) data2dptr => this%excess_ice_col(begc:endc,1:nlevsoi) call hist_addfld2d (fname='EXCESS_ICE', units='kg/m2', type2d='levsoi', & avgflag='A', long_name='excess soil ice (vegetated landunits only)', & - ptr_col=this%excess_ice_col, l2g_scale_type='veg') + ptr_col=this%excess_ice_col, l2g_scale_type='veg', default = 'inactive') end if ! (rgk 02-02-2017) There is intentionally no entry here for stored plant water From 5928f7caa7c37c6b928face74c63f205a09f87eb Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Sat, 15 Oct 2022 01:21:13 +0200 Subject: [PATCH 43/99] iulog for restart and stream --- src/biogeophys/WaterStateType.F90 | 4 ++++ src/cpl/share_esmf/ExcessIceStreamType.F90 | 1 + 2 files changed, 5 insertions(+) diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index 135d5f61d8..7630c1f763 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -14,6 +14,7 @@ module WaterStateType use decompMod , only : bounds_type use decompMod , only : subgrid_level_patch, subgrid_level_column, subgrid_level_gridcell use clm_varctl , only : use_bedrock, use_excess_ice, iulog + use spmdMod , only : masterproc use clm_varctl , only : use_fates_planthydro use clm_varpar , only : nlevgrnd, nlevsoi, nlevurb, nlevmaxurbgrnd, nlevsno use clm_varcon , only : spval @@ -712,6 +713,9 @@ subroutine Restart(this, bounds, ncid, flag, & units='kg/m2', scale_by_thickness=.true., & interpinic_flag='interp', readvar=readvar, data=this%excess_ice_col) if (flag == 'read' .and. (.not. readvar)) then ! when reading restart that does not have excess ice in it + if (masterproc) then + write(iulog,*) 'Excess ice data is read from the stream and not from restart file!' + endif do c = bounds%begc,bounds%endc l = col%landunit(c) if (.not. lun%lakpoi(l)) then !not lake diff --git a/src/cpl/share_esmf/ExcessIceStreamType.F90 b/src/cpl/share_esmf/ExcessIceStreamType.F90 index b0f79d1bfa..9b9a7c058c 100644 --- a/src/cpl/share_esmf/ExcessIceStreamType.F90 +++ b/src/cpl/share_esmf/ExcessIceStreamType.F90 @@ -96,6 +96,7 @@ subroutine Init(this, bounds, NLFilename) if (masterproc) then write(iulog,*) ' stream_varnames = ',stream_varnames + write(iulog,*) ' Values will be used if the variable is not on the initial conditions dataset' end if call shr_strdata_init_from_inline(sdat_exice, & From 5dc5f59f10dad61539f99b78ae3ac23e533afb75 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 22 Nov 2022 15:21:59 -0700 Subject: [PATCH 44/99] Add logical use_excess_ice_streams to control if streams file is used when use_excess_ice is on, and add some testing for it --- .../namelist_definition_ctsm.xml | 10 ++++++- bld/unit_testers/build-namelist_test.pl | 29 ++++++++++++++++--- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index bcee47aed5..b718b7cbf6 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -2826,6 +2826,13 @@ use case.) If TRUE turn on the excess ice physics, (Lee et al., 2014; Cai et al., 2020) + +If TRUE and use_excess_ice is TRUE, use the excess ice stream to determine the initial values of the excess ice field +if FALSE and use_excess_ice is TRUE, expect excess ice to come from the initial conditions or restart file +Expect to be FALSE is use_excess_ice is FALSE + + Filename of input stream data for excess ice data @@ -2837,10 +2844,11 @@ mesh filename of input stream data for excess ice + group="exice_streams" valid_values="bilinear,nn,none" > Mapping method from excess ice input stream data to the model resolution bilinear = bilinear interpolation nn = nearest neighbor + none = no interpolation diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index 5b2ae9c9b9..156b84ba51 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -163,9 +163,9 @@ sub cat_and_create_namelistinfile { # # Figure out number of tests that will run # -my $ntests = 1844; +my $ntests = 1855; if ( defined($opts{'compare'}) ) { - $ntests += 1254; + $ntests += 1262; } plan( tests=>$ntests ); @@ -323,6 +323,7 @@ sub cat_and_create_namelistinfile { "-structure fast", "-namelist '&a irrigate=.true./'", "-verbose", "-ssp_rcp SSP1-2.6", "-test", "-sim_year 1850", "-namelist '&a use_lai_streams=.true.,use_soil_moisture_streams=.true./'", + "-namelist '&a use_excess_ice=.true. use_excess_ice_streams=.true./'", "-use_case 1850_control", "-res 1x1pt_US-UMB -clm_usr_name 1x1pt_US-UMB -namelist '&a fsurdat=\"/dev/null\"/'", "-res 1x1_brazil", @@ -521,8 +522,28 @@ sub cat_and_create_namelistinfile { GLC_TWO_WAY_COUPLING=>"FALSE", phys=>"clm4_5", }, - "soilm_stream wo use" =>{ options=>"-res 0.9x1.25 -envxml_dir .", - namelst=>"use_soil_moisture_streams = .false.,stream_fldfilename_soilm='missing_file'", + "soilm_stream off w file" =>{ options=>"-res 0.9x1.25 -envxml_dir .", + namelst=>"use_soil_moisture_streams = .false.,stream_fldfilename_soilm='file_provided_when_off'", + GLC_TWO_WAY_COUPLING=>"FALSE", + phys=>"clm5_0", + }, + "exice_stream off w file" =>{ options=>"-res 0.9x1.25 -envxml_dir .", + namelst=>"use_excess_ice=.true., use_excess_ice_streams = .false.,stream_fldfilename_exice='file_provided_when_off'", + GLC_TWO_WAY_COUPLING=>"FALSE", + phys=>"clm5_0", + }, + "exice_stream off w mesh" =>{ options=>"-res 0.9x1.25 -envxml_dir .", + namelst=>"use_excess_ice=.true., use_excess_ice_streams = .false.,stream_meshfile_exice='file_provided_when_off'", + GLC_TWO_WAY_COUPLING=>"FALSE", + phys=>"clm5_0", + }, + "exice off, but stream on" =>{ options=>"-res 0.9x1.25 -envxml_dir .", + namelst=>"use_excess_ice=.false., use_excess_ice_streams = .true.,stream_fldfilename_exice='file_provided', stream_meshfile_exice='file_provided'", + GLC_TWO_WAY_COUPLING=>"FALSE", + phys=>"clm5_0", + }, + "exice stream off, but setmap"=>{ options=>"-res 0.9x1.25 -envxml_dir .", + namelst=>"use_excess_ice=.true., use_excess_ice_streams = .false.,stream_mapalgo_exice='bilinear'", GLC_TWO_WAY_COUPLING=>"FALSE", phys=>"clm5_0", }, From 34604989401baa634fa72c02d3f1bffe42578f85 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 22 Nov 2022 15:34:01 -0700 Subject: [PATCH 45/99] Fix number of tests, by the way in the spirit of test-driven development the 4 new fail tests added fail at this point --- bld/unit_testers/build-namelist_test.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index 156b84ba51..bf416deacd 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -163,9 +163,9 @@ sub cat_and_create_namelistinfile { # # Figure out number of tests that will run # -my $ntests = 1855; +my $ntests = 1856; if ( defined($opts{'compare'}) ) { - $ntests += 1262; + $ntests += 1260; } plan( tests=>$ntests ); From d39715715eb081dd77d0c510be482da6a392a6a6 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 22 Nov 2022 16:07:57 -0700 Subject: [PATCH 46/99] Add the error checking for excess ice and excess ice streams, this gets the tests working --- bld/CLMBuildNamelist.pm | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 606f182667..906c3be2dd 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -4149,13 +4149,40 @@ sub setup_logic_exice { # excess ice streams # my ($opts, $nl_flags, $definition, $defaults, $nl) = @_; - my $use_exice = $nl->get_value( 'use_excess_ice' ); - if (defined($use_exice) && $opts->{'driver'} eq "nuopc" && value_is_true($use_exice)) { - add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_meshfile_exice'); - add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_fldfilename_exice'); - add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_mapalgo_exice'); - } elsif (defined($use_exice) && (! $opts->{'driver'} eq "nuopc") && value_is_true($use_exice)) { - $log->fatal_error("nuopc driver is required when use_excess_ice is set to true" ); + my $use_exice = $nl->get_value( 'use_excess_ice' ); + my $use_exice_streams = $nl->get_value( 'use_excess_ice_streams' ); + # IF excess ice streams is on + if (defined($use_exice_streams) && value_is_true($use_exice_streams)) { + # Can only be true if excess ice is also on, otherwise fail + if (defined($use_exice) && not value_is_true($use_exice)) { + $log->fatal_error("use_excess_ice_streams can NOT be TRUE when use_excess_ice is FALSE" ); + } + # Otherwise if ice streams are off + } else { + my @list = ( "stream_meshfile_exice", "stream_fldfilename_exice" ); + # fail is excess ice streams files are set + foreach my $var ( @list ) { + if ( defined($nl->get_value($var)) ) { + $log->fatal_error("$var should NOT be set when use_excess_ice_streams=FALSE" ); + } + } + # mapalgo can only be none, if excess ice streams are off + my $map_algo = $nl->get_value("stream_mapalgo_exice"); + if ( defined($map_algo) && ($map_algo ne "none") ) { + $log->fatal_error("stream_mapalgo_exice can ONLY be none when use_excess_ice_streams=FALSE" ); + } + } + # If excess ice is on + if (defined($use_exice) && value_is_true($use_exice)) { + # IF nuopc driver and excess ice streams are on get the stream defaults + if (defined($use_exice_streams) && $opts->{'driver'} eq "nuopc" && value_is_true($use_exice_streams)) { + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_meshfile_exice'); + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_fldfilename_exice'); + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_mapalgo_exice'); + # If excess ice streams on, but NOT the NUOPC driver fail + } elsif (defined($use_exice_streams) && (! $opts->{'driver'} eq "nuopc") && value_is_true($use_exice_streams)) { + $log->fatal_error("nuopc driver is required when use_excess_ice_streams is set to true" ); + } } From 53e272b28610460747b3e054faa09384abbe3945 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 22 Nov 2022 16:58:22 -0700 Subject: [PATCH 47/99] Add an execess ice test with and without excess ice streams --- bld/unit_testers/build-namelist_test.pl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index bf416deacd..f56e6631fa 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -163,9 +163,9 @@ sub cat_and_create_namelistinfile { # # Figure out number of tests that will run # -my $ntests = 1856; +my $ntests = 1864; if ( defined($opts{'compare'}) ) { - $ntests += 1260; + $ntests += 1266; } plan( tests=>$ntests ); @@ -324,6 +324,7 @@ sub cat_and_create_namelistinfile { "-namelist '&a irrigate=.true./'", "-verbose", "-ssp_rcp SSP1-2.6", "-test", "-sim_year 1850", "-namelist '&a use_lai_streams=.true.,use_soil_moisture_streams=.true./'", "-namelist '&a use_excess_ice=.true. use_excess_ice_streams=.true./'", + "-namelist '&a use_excess_ice=.true. use_excess_ice_streams=.false./'", "-use_case 1850_control", "-res 1x1pt_US-UMB -clm_usr_name 1x1pt_US-UMB -namelist '&a fsurdat=\"/dev/null\"/'", "-res 1x1_brazil", From 5a56434568109ce8c4a8f848410dda8eb1ce1866 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 23 Nov 2022 10:38:23 -0700 Subject: [PATCH 48/99] Add use_excess_ice_streams to excess ice namelist, make UseStreams a public method --- src/cpl/share_esmf/ExcessIceStreamType.F90 | 32 +++++++++++++++++----- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/cpl/share_esmf/ExcessIceStreamType.F90 b/src/cpl/share_esmf/ExcessIceStreamType.F90 index 9b9a7c058c..9955b03156 100644 --- a/src/cpl/share_esmf/ExcessIceStreamType.F90 +++ b/src/cpl/share_esmf/ExcessIceStreamType.F90 @@ -35,7 +35,7 @@ module ExcessIceStreamType ! !PUBLIC MEMBER FUNCTIONS: procedure, public :: Init ! Initialize and read data in - procedure, private :: UseStreams ! If streams will be used + procedure, public :: UseStreams ! If streams will be used procedure, public :: CalcExcessIce ! Calculate excess ice ammount ! !PRIVATE MEMBER FUNCTIONS: @@ -51,6 +51,7 @@ module ExcessIceStreamType procedure, private :: ReadNML ! Read in namelist end type streamcontrol_type + logical :: namelist_read = .false. type(streamcontrol_type), private :: control ! Stream control data character(len=*), parameter, private :: sourcefile = & @@ -234,6 +235,9 @@ logical function UseStreams(this) class(excessicestream_type) :: this ! ! !LOCAL VARIABLES: + if ( .not. read_namelist ) then + call endrun(msg=' ERROR UseStreams being called, but namelist has not been read yet'//errMsg(sourcefile, __LINE__)) + end if if ( trim(control%stream_fldFileName_exice) == '' )then UseStreams = .false. else @@ -259,6 +263,7 @@ subroutine ReadNML(this, bounds, NLFilename) ! local variables integer :: nu_nml ! unit for namelist file integer :: nml_error ! namelist i/o error flag + logical :: use_excess_ice_streams = .false. ! logical to turn on use of excess ice streams character(len=CL) :: stream_fldFileName_exice = ' ' character(len=CL) :: stream_meshfile_exice = ' ' character(len=CL) :: stream_mapalgo_exice = 'bilinear' @@ -267,7 +272,7 @@ subroutine ReadNML(this, bounds, NLFilename) !----------------------------------------------------------------------- namelist /exice_streams/ & ! MUST agree with namelist_name above - stream_mapalgo_exice, stream_fldFileName_exice, stream_meshfile_exice + stream_mapalgo_exice, stream_fldFileName_exice, stream_meshfile_exice, use_excess_ice_streams ! Default values for namelist @@ -286,22 +291,35 @@ subroutine ReadNML(this, bounds, NLFilename) close(nu_nml) endif + call shr_mpi_bcast(use_excess_ice_streams , mpicom) call shr_mpi_bcast(stream_mapalgo_exice , mpicom) call shr_mpi_bcast(stream_fldFileName_exice , mpicom) call shr_mpi_bcast(stream_meshfile_exice , mpicom) if (masterproc) then write(iulog,*) ' ' - write(iulog,*) namelist_name, ' stream settings:' - write(iulog,*) ' stream_fldFileName_exice = ',stream_fldFileName_exice - write(iulog,*) ' stream_meshfile_exice = ',stream_meshfile_exice - write(iulog,*) ' stream_mapalgo_exice = ',stream_mapalgo_exice + if ( use_excess_ice_streams ) then + write(iulog,*) 'excess ice streams are enabled: ' + write(iulog,*) namelist_name, ' stream settings:' + write(iulog,*) ' stream_fldFileName_exice = ',stream_fldFileName_exice + write(iulog,*) ' stream_meshfile_exice = ',stream_meshfile_exice + write(iulog,*) ' stream_mapalgo_exice = ',stream_mapalgo_exice + if ( trim(stream_fldFileName_exice) == '' )then + call endrun(msg=' ERROR excess ice streams are on, but stream_fldFileName_exice is NOT set'//errMsg(sourcefile, __LINE__)) + end if + else + write(iulog,*) 'excess ice streams are off' + if ( trim(stream_fldFileName_exice) /= '' )then + call endrun(msg=' ERROR excess ice streams are off, but stream_fldFileName_exice is set'//errMsg(sourcefile, __LINE__)) + end if + end if endif this%stream_fldFileName_exice = stream_fldFileName_exice this%stream_meshfile_exice = stream_meshfile_exice this%stream_mapalgo_exice = stream_mapalgo_exice + namelist_read = .true. end subroutine ReadNML -end module ExcessIceStreamType \ No newline at end of file +end module ExcessIceStreamType From 2703c0446e5e57f925b78a5ad96dbf2936ed63d5 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 23 Nov 2022 10:43:43 -0700 Subject: [PATCH 49/99] Turn on excess ice streams --- cime_config/testdefs/testmods_dirs/clm/ExcessIce/user_nl_clm | 1 + 1 file changed, 1 insertion(+) diff --git a/cime_config/testdefs/testmods_dirs/clm/ExcessIce/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/ExcessIce/user_nl_clm index d9e52c6cf9..f61ca32a79 100644 --- a/cime_config/testdefs/testmods_dirs/clm/ExcessIce/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/ExcessIce/user_nl_clm @@ -1 +1,2 @@ use_excess_ice = .true. + use_excess_ice_streams = .true. From 2dfc71f73163802fc3a0e3c63ed8a4497b73a866 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 23 Nov 2022 10:47:16 -0700 Subject: [PATCH 50/99] Add another excess ice test that starts up from a restart file --- .../clm/{ExcessIce => ExcessIceRestart}/include_user_mods | 0 .../testdefs/testmods_dirs/clm/ExcessIceRestart/user_nl_clm | 1 + .../testmods_dirs/clm/ExcessIceStreams/include_user_mods | 1 + .../clm/{ExcessIce => ExcessIceStreams}/user_nl_clm | 0 4 files changed, 2 insertions(+) rename cime_config/testdefs/testmods_dirs/clm/{ExcessIce => ExcessIceRestart}/include_user_mods (100%) create mode 100644 cime_config/testdefs/testmods_dirs/clm/ExcessIceRestart/user_nl_clm create mode 100644 cime_config/testdefs/testmods_dirs/clm/ExcessIceStreams/include_user_mods rename cime_config/testdefs/testmods_dirs/clm/{ExcessIce => ExcessIceStreams}/user_nl_clm (100%) diff --git a/cime_config/testdefs/testmods_dirs/clm/ExcessIce/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/ExcessIceRestart/include_user_mods similarity index 100% rename from cime_config/testdefs/testmods_dirs/clm/ExcessIce/include_user_mods rename to cime_config/testdefs/testmods_dirs/clm/ExcessIceRestart/include_user_mods diff --git a/cime_config/testdefs/testmods_dirs/clm/ExcessIceRestart/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/ExcessIceRestart/user_nl_clm new file mode 100644 index 0000000000..d9e52c6cf9 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/ExcessIceRestart/user_nl_clm @@ -0,0 +1 @@ + use_excess_ice = .true. diff --git a/cime_config/testdefs/testmods_dirs/clm/ExcessIceStreams/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/ExcessIceStreams/include_user_mods new file mode 100644 index 0000000000..fe0e18cf88 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/ExcessIceStreams/include_user_mods @@ -0,0 +1 @@ +../default diff --git a/cime_config/testdefs/testmods_dirs/clm/ExcessIce/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/ExcessIceStreams/user_nl_clm similarity index 100% rename from cime_config/testdefs/testmods_dirs/clm/ExcessIce/user_nl_clm rename to cime_config/testdefs/testmods_dirs/clm/ExcessIceStreams/user_nl_clm From 0035dc7db10c9b1cc8c9c4ff15181f6be3038b2a Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 23 Nov 2022 10:59:26 -0700 Subject: [PATCH 51/99] Fill out all the options for the excess ice tests, add a higher resolution test to start from a restart file, and make the main excess ice test with restart --- cime_config/testdefs/testlist_clm.xml | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index b2a063d011..18d6c56f73 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -168,13 +168,29 @@ - + + + + + + + + + + + + + + + + + - + From 58e52555b7d8f884eb3e7d9aad94bf8f91d07ea9 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sat, 26 Nov 2022 13:45:54 -0700 Subject: [PATCH 52/99] Put use_excess_ice_streams in the right namelist --- bld/namelist_files/namelist_definition_ctsm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index b718b7cbf6..91bc00e7d6 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -2827,7 +2827,7 @@ If TRUE turn on the excess ice physics, (Lee et al., 2014; Cai et al., 2020) + group="exice_streams" valid_values="" > If TRUE and use_excess_ice is TRUE, use the excess ice stream to determine the initial values of the excess ice field if FALSE and use_excess_ice is TRUE, expect excess ice to come from the initial conditions or restart file Expect to be FALSE is use_excess_ice is FALSE From 6597b7b219bf3296635b94c92a5ade1a66aae410 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sat, 26 Nov 2022 13:46:20 -0700 Subject: [PATCH 53/99] Fix name of variable --- src/cpl/share_esmf/ExcessIceStreamType.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpl/share_esmf/ExcessIceStreamType.F90 b/src/cpl/share_esmf/ExcessIceStreamType.F90 index 9955b03156..414f635eeb 100644 --- a/src/cpl/share_esmf/ExcessIceStreamType.F90 +++ b/src/cpl/share_esmf/ExcessIceStreamType.F90 @@ -235,7 +235,7 @@ logical function UseStreams(this) class(excessicestream_type) :: this ! ! !LOCAL VARIABLES: - if ( .not. read_namelist ) then + if ( .not. namelist_read ) then call endrun(msg=' ERROR UseStreams being called, but namelist has not been read yet'//errMsg(sourcefile, __LINE__)) end if if ( trim(control%stream_fldFileName_exice) == '' )then From 2bf87975248f45c10e2758eb9865bb084149bc7f Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 28 Nov 2022 15:38:56 -0700 Subject: [PATCH 54/99] Add test for excess_ice streams on, but mct, that fails --- bld/unit_testers/build-namelist_test.pl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index f56e6631fa..bbe71406b8 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -163,7 +163,7 @@ sub cat_and_create_namelistinfile { # # Figure out number of tests that will run # -my $ntests = 1864; +my $ntests = 1865; if ( defined($opts{'compare'}) ) { $ntests += 1266; } @@ -548,6 +548,11 @@ sub cat_and_create_namelistinfile { GLC_TWO_WAY_COUPLING=>"FALSE", phys=>"clm5_0", }, + "exice stream on, but mct" =>{ options=>"--res 0.9x1.25 --envxml_dir . --driver mct --lnd_frac $DOMFILE ", + namelst=>"use_excess_ice=.true., use_excess_ice_streams=.true.", + GLC_TWO_WAY_COUPLING=>"FALSE", + phys=>"clm5_0", + }, "clm50CNDVwtransient" =>{ options=>" -envxml_dir . -use_case 20thC_transient -dynamic_vegetation -res 10x15 -ignore_warnings", namelst=>"", GLC_TWO_WAY_COUPLING=>"FALSE", From 4af3fd583e9f281d474855c92b253fb089536cfd Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 28 Nov 2022 16:04:11 -0700 Subject: [PATCH 55/99] Fix the check for MCT driver with excess ice streams --- bld/CLMBuildNamelist.pm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 906c3be2dd..10d8fd0923 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -4175,13 +4175,14 @@ sub setup_logic_exice { # If excess ice is on if (defined($use_exice) && value_is_true($use_exice)) { # IF nuopc driver and excess ice streams are on get the stream defaults - if (defined($use_exice_streams) && $opts->{'driver'} eq "nuopc" && value_is_true($use_exice_streams)) { + if (defined($use_exice_streams) && value_is_true($use_exice_streams)) { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_meshfile_exice'); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_fldfilename_exice'); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_mapalgo_exice'); - # If excess ice streams on, but NOT the NUOPC driver fail - } elsif (defined($use_exice_streams) && (! $opts->{'driver'} eq "nuopc") && value_is_true($use_exice_streams)) { + # If excess ice streams on, but NOT the NUOPC driver fail + if ( not $opts->{'driver'} eq "nuopc" ) { $log->fatal_error("nuopc driver is required when use_excess_ice_streams is set to true" ); + } } } From 5aaef812c4e0ab48f7a50686f8d763882c54409c Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 28 Nov 2022 16:04:33 -0700 Subject: [PATCH 56/99] Don't run the MCT driver test with excess ice stremas --- bld/unit_testers/build-namelist_test.pl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index bbe71406b8..1bdb59f72a 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -163,9 +163,9 @@ sub cat_and_create_namelistinfile { # # Figure out number of tests that will run # -my $ntests = 1865; +my $ntests = 1861; if ( defined($opts{'compare'}) ) { - $ntests += 1266; + $ntests += 1263; } plan( tests=>$ntests ); @@ -339,6 +339,10 @@ sub cat_and_create_namelistinfile { my $base_options = "-res 0.9x1.25 -envxml_dir . -driver $driver"; if ( $driver eq "mct" ) { $base_options = "$base_options -lnd_frac $DOMFILE"; + # Skip the MCT test for excess ice streams + if ( $options =~ /use_excess_ice_streams=.true./ ) { + next; + } } else { $base_options = "$base_options -namelist '&a force_send_to_atm = .false./'"; } From 33c760ee561f843da74cdf094ef5e8e45c33a3f4 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 28 Nov 2022 16:24:04 -0700 Subject: [PATCH 57/99] Add stub excess ice streams for MCT, so MCT driver cases can build --- src/cpl/mct/ExcessIceStreamType.F90 | 136 ++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 src/cpl/mct/ExcessIceStreamType.F90 diff --git a/src/cpl/mct/ExcessIceStreamType.F90 b/src/cpl/mct/ExcessIceStreamType.F90 new file mode 100644 index 0000000000..a1d2fe7ff9 --- /dev/null +++ b/src/cpl/mct/ExcessIceStreamType.F90 @@ -0,0 +1,136 @@ +module ExcessIceStreamType + + !----------------------------------------------------------------------- + ! !DESCRIPTION: + ! Stub for ExcessIceStreams for the MCT driver. So that MCT can be used + ! without excess ice streams. + ! + ! !USES + use shr_kind_mod , only : r8 => shr_kind_r8 + use shr_log_mod , only : errMsg => shr_log_errMsg + use spmdMod , only : mpicom, masterproc + use clm_varctl , only : iulog + use abortutils , only : endrun + use decompMod , only : bounds_type + + ! !PUBLIC TYPES: + implicit none + private + + procedure, public :: UseExcessIceStreams ! If streams will be used + + type, public :: excessicestream_type + contains + + ! !PUBLIC MEMBER FUNCTIONS: + procedure, public :: Init ! Initialize and read data in + procedure, public :: CalcExcessIce ! Calculate excess ice ammount + + ! !PRIVATE MEMBER FUNCTIONS: + procedure, private :: ReadNML ! Read in namelist + + end type excessicestream_type + ! ! PRIVATE DATA: + + character(len=*), parameter, private :: sourcefile = & + __FILE__ + +!============================================================================== +contains +!============================================================================== + + subroutine Init(this, bounds, NLFilename) + ! + ! + ! arguments + implicit none + class(excessicestream_type) :: this + type(bounds_type), intent(in) :: bounds + character(len=*), intent(in) :: NLFilename ! Namelist filename + + ! + ! local variables + + call this%ReadNML( bounds, NLFileName ) + end subroutine Init + + subroutine CalcExcessIce(this,bounds,exice_bulk_init) + + ! only transfers grid values to columns + implicit none + class(excessicestream_type) :: this + type(bounds_type), intent(in) :: bounds + real(r8) , intent(inout) :: exice_bulk_init(bounds%begc:bounds%endc) + ! + ! !LOCAL VARIABLES: + + end subroutine CalcExcessIce + + logical function UseExcessIceStreams() + ! + ! !DESCRIPTION: + ! Return true if + ! + ! !USES: + ! + ! !ARGUMENTS: + implicit none + ! + ! !LOCAL VARIABLES: + UseExcessIceStreams = .false. +end function UseExcessIceStreams + +subroutine ReadNML(this, bounds, NLFilename) + ! + ! Read the namelist data stream information. + ! + ! Uses: + use shr_nl_mod , only : shr_nl_find_group_name + use shr_log_mod , only : errMsg => shr_log_errMsg + use shr_mpi_mod , only : shr_mpi_bcast + ! + ! arguments + implicit none + class(streamcontrol_type) :: this + type(bounds_type), intent(in) :: bounds + character(len=*), intent(in) :: NLFilename ! Namelist filename + ! + ! local variables + integer :: nu_nml ! unit for namelist file + integer :: nml_error ! namelist i/o error flag + logical :: use_excess_ice_streams = .false. ! logical to turn on use of excess ice streams + character(len=*), parameter :: namelist_name = 'exice_streams' ! MUST agree with name in namelist and read + character(len=*), parameter :: subName = "('exice_streams::ReadNML')" + !----------------------------------------------------------------------- + + namelist /exice_streams/ & ! MUST agree with namelist_name above + use_excess_ice_streams + + ! Default values for namelist + + ! Read excess ice namelist + if (masterproc) then + open( newunit=nu_nml, file=trim(NLFilename), status='old', iostat=nml_error ) + call shr_nl_find_group_name(nu_nml, namelist_name, status=nml_error) + if (nml_error == 0) then + read(nu_nml, nml=exice_streams,iostat=nml_error) ! MUST agree with namelist_name above + if (nml_error /= 0) then + call endrun(msg=' ERROR reading '//namelist_name//' namelist'//errMsg(sourcefile, __LINE__)) + end if + else + call endrun(msg=' ERROR finding '//namelist_name//' namelist'//errMsg(sourcefile, __LINE__)) + end if + close(nu_nml) + endif + + call shr_mpi_bcast(use_excess_ice_streams , mpicom) + + if (masterproc) then + if ( use_excess_ice_streams ) then + call endrun(msg=' ERROR excess ice streams can NOT be on for the MCT driver'//errMsg(sourcefile, __LINE__)) + end if + endif + +end subroutine ReadNML + +end module ExcessIceStreamType From d0e1e8e9f8914d6b4af40fedd81e4df188395308 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 28 Nov 2022 16:39:39 -0700 Subject: [PATCH 58/99] Fix so can compiler --- src/cpl/mct/ExcessIceStreamType.F90 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cpl/mct/ExcessIceStreamType.F90 b/src/cpl/mct/ExcessIceStreamType.F90 index a1d2fe7ff9..dd0c682e0c 100644 --- a/src/cpl/mct/ExcessIceStreamType.F90 +++ b/src/cpl/mct/ExcessIceStreamType.F90 @@ -17,7 +17,7 @@ module ExcessIceStreamType implicit none private - procedure, public :: UseExcessIceStreams ! If streams will be used + public :: UseExcessIceStreams ! If streams will be used type, public :: excessicestream_type contains @@ -63,6 +63,7 @@ subroutine CalcExcessIce(this,bounds,exice_bulk_init) real(r8) , intent(inout) :: exice_bulk_init(bounds%begc:bounds%endc) ! ! !LOCAL VARIABLES: + call endrun(msg=' ERROR CalcExcessIce should NOT be called for the MCT driver'//errMsg(sourcefile, __LINE__)) end subroutine CalcExcessIce @@ -91,7 +92,7 @@ subroutine ReadNML(this, bounds, NLFilename) ! ! arguments implicit none - class(streamcontrol_type) :: this + class(excessicestream_type) :: this type(bounds_type), intent(in) :: bounds character(len=*), intent(in) :: NLFilename ! Namelist filename ! From 621f35336dfb5e09c71b01c4f93783a3a19258b7 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 28 Nov 2022 17:01:23 -0700 Subject: [PATCH 59/99] Add stream_fldFileName_exice and stream_mapalgo_exice to MCT excess ice stream namelist just to check that they aren't set --- src/cpl/mct/ExcessIceStreamType.F90 | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/cpl/mct/ExcessIceStreamType.F90 b/src/cpl/mct/ExcessIceStreamType.F90 index dd0c682e0c..a65eb600c5 100644 --- a/src/cpl/mct/ExcessIceStreamType.F90 +++ b/src/cpl/mct/ExcessIceStreamType.F90 @@ -6,7 +6,7 @@ module ExcessIceStreamType ! without excess ice streams. ! ! !USES - use shr_kind_mod , only : r8 => shr_kind_r8 + use shr_kind_mod , only : r8 => shr_kind_r8, CL => shr_kind_CL use shr_log_mod , only : errMsg => shr_log_errMsg use spmdMod , only : mpicom, masterproc use clm_varctl , only : iulog @@ -100,13 +100,15 @@ subroutine ReadNML(this, bounds, NLFilename) integer :: nu_nml ! unit for namelist file integer :: nml_error ! namelist i/o error flag logical :: use_excess_ice_streams = .false. ! logical to turn on use of excess ice streams + character(len=CL) :: stream_fldFileName_exice = ' ' + character(len=CL) :: stream_mapalgo_exice = 'none' character(len=*), parameter :: namelist_name = 'exice_streams' ! MUST agree with name in namelist and read character(len=*), parameter :: subName = "('exice_streams::ReadNML')" !----------------------------------------------------------------------- namelist /exice_streams/ & ! MUST agree with namelist_name above - use_excess_ice_streams - + stream_mapalgo_exice, stream_fldFileName_exice, use_excess_ice_streams + !----------------------------------------------------------------------- ! Default values for namelist ! Read excess ice namelist @@ -130,6 +132,12 @@ subroutine ReadNML(this, bounds, NLFilename) if ( use_excess_ice_streams ) then call endrun(msg=' ERROR excess ice streams can NOT be on for the MCT driver'//errMsg(sourcefile, __LINE__)) end if + if ( trim(stream_fldFileName_exice) /= '' ) then + call endrun(msg=' ERROR stream_fldFileName_exice can NOT be set for the MCT driver'//errMsg(sourcefile, __LINE__)) + end if + if ( trim(stream_mapalgo_exice) /= 'none' ) then + call endrun(msg=' ERROR stream_mapalgo_exice can only be none for the MCT driver'//errMsg(sourcefile, __LINE__)) + end if endif end subroutine ReadNML From 4813ff6cd71df9a2859cb5d3e7966fa564cd4d3d Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 28 Nov 2022 17:07:06 -0700 Subject: [PATCH 60/99] handle the excess ice streams difference for MCT and NUOPC a little better --- bld/CLMBuildNamelist.pm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 10d8fd0923..8447fde52a 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -4176,12 +4176,14 @@ sub setup_logic_exice { if (defined($use_exice) && value_is_true($use_exice)) { # IF nuopc driver and excess ice streams are on get the stream defaults if (defined($use_exice_streams) && value_is_true($use_exice_streams)) { - add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_meshfile_exice'); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_fldfilename_exice'); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_mapalgo_exice'); # If excess ice streams on, but NOT the NUOPC driver fail if ( not $opts->{'driver'} eq "nuopc" ) { $log->fatal_error("nuopc driver is required when use_excess_ice_streams is set to true" ); + # NUOPC driver needs a mesh file + } else { + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_meshfile_exice'); } } } From 6344bb3bf235d3bb1ebe804d976dbf058bef5990 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 28 Nov 2022 17:15:32 -0700 Subject: [PATCH 61/99] Don't call abort on call of CalcExcessIce as it's always called --- src/cpl/mct/ExcessIceStreamType.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cpl/mct/ExcessIceStreamType.F90 b/src/cpl/mct/ExcessIceStreamType.F90 index a65eb600c5..5c5394233c 100644 --- a/src/cpl/mct/ExcessIceStreamType.F90 +++ b/src/cpl/mct/ExcessIceStreamType.F90 @@ -63,7 +63,6 @@ subroutine CalcExcessIce(this,bounds,exice_bulk_init) real(r8) , intent(inout) :: exice_bulk_init(bounds%begc:bounds%endc) ! ! !LOCAL VARIABLES: - call endrun(msg=' ERROR CalcExcessIce should NOT be called for the MCT driver'//errMsg(sourcefile, __LINE__)) end subroutine CalcExcessIce From 8cd39560da909dc35c0c4c56c86334edc58ab085 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 28 Nov 2022 17:24:18 -0700 Subject: [PATCH 62/99] Change name of UseStreams to UseExcessIceStreams, make it public and not a method --- src/cpl/share_esmf/ExcessIceStreamType.F90 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cpl/share_esmf/ExcessIceStreamType.F90 b/src/cpl/share_esmf/ExcessIceStreamType.F90 index 414f635eeb..92d5632aff 100644 --- a/src/cpl/share_esmf/ExcessIceStreamType.F90 +++ b/src/cpl/share_esmf/ExcessIceStreamType.F90 @@ -29,13 +29,14 @@ module ExcessIceStreamType implicit none private + public :: UseExcessIceStreams ! If streams will be used + type, public :: excessicestream_type real(r8), pointer, private :: exice_bulk (:) ! excess ice bulk value (-) contains ! !PUBLIC MEMBER FUNCTIONS: procedure, public :: Init ! Initialize and read data in - procedure, public :: UseStreams ! If streams will be used procedure, public :: CalcExcessIce ! Calculate excess ice ammount ! !PRIVATE MEMBER FUNCTIONS: @@ -91,7 +92,7 @@ subroutine Init(this, bounds, NLFilename) call this%InitAllocate( bounds ) call control%ReadNML( bounds, NLFileName ) - if ( this%useStreams() )then + if ( UseExcessIceStreams() )then allocate(stream_varnames(1)) stream_varnames = (/"EXICE"/) @@ -223,7 +224,7 @@ subroutine CalcExcessIce(this,bounds,exice_bulk_init) end subroutine CalcExcessIce - logical function UseStreams(this) + logical function UseExcessIceStreams() ! ! !DESCRIPTION: ! Return true if @@ -232,18 +233,17 @@ logical function UseStreams(this) ! ! !ARGUMENTS: implicit none - class(excessicestream_type) :: this ! ! !LOCAL VARIABLES: if ( .not. namelist_read ) then - call endrun(msg=' ERROR UseStreams being called, but namelist has not been read yet'//errMsg(sourcefile, __LINE__)) + call endrun(msg=' ERROR UseExcessIceStreams being called, but namelist has not been read yet'//errMsg(sourcefile, __LINE__)) end if if ( trim(control%stream_fldFileName_exice) == '' )then - UseStreams = .false. + UseExcessIceStreams = .false. else - UseStreams = .true. + UseExcessIceStreams = .true. end if -end function UseStreams +end function UseExcessIceStreams subroutine ReadNML(this, bounds, NLFilename) ! From eb20a75a1a5b068a4fc4f6f35466bb9392c752ff Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 28 Nov 2022 18:03:53 -0700 Subject: [PATCH 63/99] Add check that new excess ice fields are on the restart file and if not excess ice streams are on --- src/biogeophys/WaterDiagnosticBulkType.F90 | 17 ++++++++++++++++- src/biogeophys/WaterStateType.F90 | 11 ++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index d7413fb740..3ecae66b28 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -770,9 +770,10 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil use spmdMod , only : masterproc use clm_varcon , only : pondmx, watmin, spval, nameg use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall - use clm_varctl , only : bound_h2osoi, use_excess_ice + use clm_varctl , only : bound_h2osoi, use_excess_ice, nsrest, nsrContinue use ncdio_pio , only : file_desc_t, ncd_io, ncd_double use restUtilMod + use ExcessIceStreamType, only : UseExcessIceStreams ! ! !ARGUMENTS: class(waterdiagnosticbulk_type), intent(inout) :: this @@ -921,6 +922,14 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil units='m', & interpinic_flag='interp', readvar=readvar, data=this%exice_subs_tot_col) if (flag == 'read' .and. (.not. readvar)) then ! when reading restart that does not have excess ice in it + if (nsrest == nsrContinue) then + call endrun(msg = "On a continue run, excess ice fields MUST be on the restart file "// & + errMsg(sourcefile, __LINE__)) + else if ( .not. UseExcessIceStreams() )then + call endrun(msg = "This input initial conditions file does NOT include excess ice fields" // & + ", and use_excess_ice_streams is off, one or the other needs to be changed "// & + errMsg(sourcefile, __LINE__)) + end if this%exice_subs_tot_col(bounds%begc:bounds%endc)=0.0_r8 this%exice_vol_tot_col(bounds%begc:bounds%endc)=0.0_r8 this%exice_subs_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 @@ -931,6 +940,12 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil long_name=this%info%lname('vertically averaged volumetric excess ice concentration (veg landunits only)'), & units='m3/m3', & interpinic_flag='interp', readvar=readvar, data=this%exice_vol_tot_col) + if (flag == 'read' .and. (.not. readvar)) then ! when reading restart that does not have excess ice in it + if (nsrest == nsrContinue) then + call endrun(msg = "On a continue run, excess ice fields MUST be on the restart file "// & + errMsg(sourcefile, __LINE__)) + end if + end if endif end subroutine RestartBulk diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index 7630c1f763..944a6bfc85 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -590,8 +590,9 @@ subroutine Restart(this, bounds, ncid, flag, & use landunit_varcon , only : istcrop, istdlak, istsoil use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall use clm_time_manager , only : is_first_step, is_restart - use clm_varctl , only : bound_h2osoi + use clm_varctl , only : bound_h2osoi, nsrest, nsrContinue use ncdio_pio , only : file_desc_t, ncd_double + use ExcessIceStreamType, only : UseExcessIceStreams use restUtilMod ! ! !ARGUMENTS: @@ -713,6 +714,14 @@ subroutine Restart(this, bounds, ncid, flag, & units='kg/m2', scale_by_thickness=.true., & interpinic_flag='interp', readvar=readvar, data=this%excess_ice_col) if (flag == 'read' .and. (.not. readvar)) then ! when reading restart that does not have excess ice in it + if (nsrest == nsrContinue) then + call endrun(msg = "On a continue run, excess ice fields MUST be on the restart file "// & + errMsg(sourcefile, __LINE__)) + else if ( .not. UseExcessIceStreams() )then + call endrun(msg = "This input initial conditions file does NOT include excess ice fields" // & + ", and use_excess_ice_streams is off, one or the other needs to be changed "// & + errMsg(sourcefile, __LINE__)) + end if if (masterproc) then write(iulog,*) 'Excess ice data is read from the stream and not from restart file!' endif From 03ff5a20c5b48a18af58fbd18c442434aa83390c Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 2 Dec 2022 10:11:36 -0700 Subject: [PATCH 64/99] Add a check for issue 1787 about excess ice fields, if they aren't on the IC file abort with an error, and I showed this works --- src/biogeophys/WaterDiagnosticBulkType.F90 | 58 +++++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index 3ecae66b28..df8ba553a3 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -100,6 +100,7 @@ module WaterDiagnosticBulkType procedure, private :: InitBulkHistory procedure, private :: InitBulkCold procedure, private :: RestartBackcompatIssue783 + procedure, private :: RestartExcessIceIssue1787 end type waterdiagnosticbulk_type @@ -785,6 +786,7 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil ! ! !LOCAL VARIABLES: logical :: readvar + logical :: excess_ice_on_restart !------------------------------------------------------------------------ @@ -915,13 +917,18 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil ! initialization of these to zero is ok, since they might not be in the restart file this%exice_subs_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 this%exice_vol_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 + call this%RestartExcessIceIssue1787( & + ncid = ncid, & + flag = flag, & + writing_finidat_interp_dest_file = writing_finidat_interp_dest_file, & + excess_ice_on_restart = excess_ice_on_restart) ! have to at least define them call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('SUBSIDENCE'), & dim1name='column', xtype=ncd_double, & long_name=this%info%lname('vertically summed volumetric excess ice concentration (veg landunits only)'), & units='m', & interpinic_flag='interp', readvar=readvar, data=this%exice_subs_tot_col) - if (flag == 'read' .and. (.not. readvar)) then ! when reading restart that does not have excess ice in it + if (flag == 'read' .and. ((.not. readvar) .or. (.not. excess_ice_on_restart)) ) then ! when reading restart that does not have excess ice in it if (nsrest == nsrContinue) then call endrun(msg = "On a continue run, excess ice fields MUST be on the restart file "// & errMsg(sourcefile, __LINE__)) @@ -940,7 +947,7 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil long_name=this%info%lname('vertically averaged volumetric excess ice concentration (veg landunits only)'), & units='m3/m3', & interpinic_flag='interp', readvar=readvar, data=this%exice_vol_tot_col) - if (flag == 'read' .and. (.not. readvar)) then ! when reading restart that does not have excess ice in it + if (flag == 'read' .and. ((.not. readvar) .or. (.not. excess_ice_on_restart)) ) then ! when reading restart that does not have excess ice in it if (nsrest == nsrContinue) then call endrun(msg = "On a continue run, excess ice fields MUST be on the restart file "// & errMsg(sourcefile, __LINE__)) @@ -1041,6 +1048,53 @@ subroutine RestartBackcompatIssue783(this, bounds, ncid, flag, & end subroutine RestartBackcompatIssue783 + !----------------------------------------------------------------------- + subroutine RestartExcessIceIssue1787(this, ncid, flag, & + writing_finidat_interp_dest_file, excess_ice_on_restart) + ! + ! !DESCRIPTION: + ! + ! !USES: + use ncdio_pio , only : file_desc_t + use IssueFixedMetadataHandler, only : write_issue_fixed_metadata, read_issue_fixed_metadata + use clm_time_manager , only : is_restart + ! + ! !ARGUMENTS: + class(waterdiagnosticbulk_type), intent(inout) :: this + type(file_desc_t), intent(inout) :: ncid ! netcdf id + character(len=*) , intent(in) :: flag ! 'read' or 'write' + logical, intent(in) :: writing_finidat_interp_dest_file ! true if this is a finidat_interp_dest file + logical, intent(out) :: excess_ice_on_restart ! If excess ice is on the restart file + ! + ! !LOCAL VARIABLES: + integer :: attribute_value + + integer, parameter :: issue_num = 1787 + + character(len=*), parameter :: subname = 'RestartExcessIceISsue1787' + !----------------------------------------------------------------------- + + if (flag == 'define') then + call write_issue_fixed_metadata( & + ncid = ncid, & + writing_finidat_interp_dest_file = writing_finidat_interp_dest_file, & + issue_num = issue_num) + + else if (flag == 'read' .and. .not. is_restart()) then + call read_issue_fixed_metadata( & + ncid = ncid, & + issue_num = issue_num, & + attribute_value = attribute_value) + if (attribute_value == 0) then + excess_ice_on_restart = .false. + else + excess_ice_on_restart = .true. + end if + + end if + + end subroutine RestartExcessIceIssue1787 + !----------------------------------------------------------------------- subroutine Summary(this, bounds, & num_soilp, filter_soilp, & From ca96f76e5cd80bc64d5519e262031d98b4c3974a Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sun, 4 Dec 2022 18:34:23 -0700 Subject: [PATCH 65/99] Move RestartExcessIceIssu to restartUtils so that it can be used by more than one restart subroutine in different modules --- src/biogeophys/WaterDiagnosticBulkType.F90 | 50 +-------------------- src/main/restFileMod.F90 | 5 +++ src/utils/restUtilMod.F90.in | 51 ++++++++++++++++++++++ 3 files changed, 57 insertions(+), 49 deletions(-) diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index df8ba553a3..fdbbcec566 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -100,7 +100,6 @@ module WaterDiagnosticBulkType procedure, private :: InitBulkHistory procedure, private :: InitBulkCold procedure, private :: RestartBackcompatIssue783 - procedure, private :: RestartExcessIceIssue1787 end type waterdiagnosticbulk_type @@ -917,7 +916,7 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil ! initialization of these to zero is ok, since they might not be in the restart file this%exice_subs_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 this%exice_vol_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 - call this%RestartExcessIceIssue1787( & + call RestartExcessIceIssue( & ncid = ncid, & flag = flag, & writing_finidat_interp_dest_file = writing_finidat_interp_dest_file, & @@ -1048,53 +1047,6 @@ subroutine RestartBackcompatIssue783(this, bounds, ncid, flag, & end subroutine RestartBackcompatIssue783 - !----------------------------------------------------------------------- - subroutine RestartExcessIceIssue1787(this, ncid, flag, & - writing_finidat_interp_dest_file, excess_ice_on_restart) - ! - ! !DESCRIPTION: - ! - ! !USES: - use ncdio_pio , only : file_desc_t - use IssueFixedMetadataHandler, only : write_issue_fixed_metadata, read_issue_fixed_metadata - use clm_time_manager , only : is_restart - ! - ! !ARGUMENTS: - class(waterdiagnosticbulk_type), intent(inout) :: this - type(file_desc_t), intent(inout) :: ncid ! netcdf id - character(len=*) , intent(in) :: flag ! 'read' or 'write' - logical, intent(in) :: writing_finidat_interp_dest_file ! true if this is a finidat_interp_dest file - logical, intent(out) :: excess_ice_on_restart ! If excess ice is on the restart file - ! - ! !LOCAL VARIABLES: - integer :: attribute_value - - integer, parameter :: issue_num = 1787 - - character(len=*), parameter :: subname = 'RestartExcessIceISsue1787' - !----------------------------------------------------------------------- - - if (flag == 'define') then - call write_issue_fixed_metadata( & - ncid = ncid, & - writing_finidat_interp_dest_file = writing_finidat_interp_dest_file, & - issue_num = issue_num) - - else if (flag == 'read' .and. .not. is_restart()) then - call read_issue_fixed_metadata( & - ncid = ncid, & - issue_num = issue_num, & - attribute_value = attribute_value) - if (attribute_value == 0) then - excess_ice_on_restart = .false. - else - excess_ice_on_restart = .true. - end if - - end if - - end subroutine RestartExcessIceIssue1787 - !----------------------------------------------------------------------- subroutine Summary(this, bounds, & num_soilp, filter_soilp, & diff --git a/src/main/restFileMod.F90 b/src/main/restFileMod.F90 index f0b2b4fb01..720fd5a092 100644 --- a/src/main/restFileMod.F90 +++ b/src/main/restFileMod.F90 @@ -62,6 +62,7 @@ module restFileMod ! Issue numbers for issue-fixed metadata integer, parameter :: lake_dynbal_baseline_issue = 1140 + integer, parameter :: excess_ice_issue = 1787 character(len=*), parameter, private :: sourcefile = & __FILE__ @@ -604,6 +605,10 @@ subroutine restFile_write_issues_fixed(ncid, writing_finidat_interp_dest_file) ncid = ncid, & writing_finidat_interp_dest_file = writing_finidat_interp_dest_file, & issue_num = lake_dynbal_baseline_issue) + call write_issue_fixed_metadata( & + ncid = ncid, & + writing_finidat_interp_dest_file = writing_finidat_interp_dest_file, & + issue_num = excess_ice_issue) end subroutine restFile_write_issues_fixed diff --git a/src/utils/restUtilMod.F90.in b/src/utils/restUtilMod.F90.in index 4271271097..da22ea2d60 100644 --- a/src/utils/restUtilMod.F90.in +++ b/src/utils/restUtilMod.F90.in @@ -88,6 +88,8 @@ module restUtilMod end interface set_missing_vals_to_constant public :: set_missing_vals_to_constant + public :: RestartExcessIceIssue + private :: missing_field_possibly_abort private :: write_interpinic_flag @@ -740,5 +742,54 @@ contains end subroutine write_interpinic_flag + !----------------------------------------------------------------------- + subroutine RestartExcessIceIssue(ncid, flag, & + writing_finidat_interp_dest_file, excess_ice_on_restart) + ! + ! !DESCRIPTION: + ! Is excess ice on the originating restart file? This is important to have + ! because the init_interp process copies the cold-start values to the + ! interpolated file if they aren't there, and we need to know if good values + ! exist on the originating restart file. + ! + ! !USES: + use ncdio_pio , only : file_desc_t + use IssueFixedMetadataHandler, only : write_issue_fixed_metadata, read_issue_fixed_metadata + use clm_time_manager , only : is_restart + ! + ! !ARGUMENTS: + type(file_desc_t), intent(inout) :: ncid ! netcdf id + character(len=*) , intent(in) :: flag ! 'read' or 'write' + logical, intent(in) :: writing_finidat_interp_dest_file ! true if this is a finidat_interp_dest file + logical, intent(out) :: excess_ice_on_restart ! If excess ice is on the restart file + ! + ! !LOCAL VARIABLES: + integer :: attribute_value + integer, parameter :: excess_ice_issue = 1787 + + + character(len=*), parameter :: subname = 'RestartExcessIceIssue' + !----------------------------------------------------------------------- + + if (flag == 'define') then + call write_issue_fixed_metadata( & + ncid = ncid, & + writing_finidat_interp_dest_file = writing_finidat_interp_dest_file, & + issue_num = excess_ice_issue) + + else if (flag == 'read' .and. .not. is_restart()) then + call read_issue_fixed_metadata( & + ncid = ncid, & + issue_num = excess_ice_issue, & + attribute_value = attribute_value) + if (attribute_value == 0) then + excess_ice_on_restart = .false. + else + excess_ice_on_restart = .true. + end if + + end if + + end subroutine RestartExcessIceIssue end module restUtilMod From 0e09dd4264d241ca25aff6d7951e008cd6cca6a2 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sun, 4 Dec 2022 18:37:54 -0700 Subject: [PATCH 66/99] Only write excess ice issue to restart metadata if excess ice is on --- src/main/restFileMod.F90 | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/restFileMod.F90 b/src/main/restFileMod.F90 index 720fd5a092..f3f4354650 100644 --- a/src/main/restFileMod.F90 +++ b/src/main/restFileMod.F90 @@ -591,6 +591,8 @@ subroutine restFile_write_issues_fixed(ncid, writing_finidat_interp_dest_file) ! !DESCRIPTION: ! Write metadata for issues fixed ! + ! !USES: + use clm_varctl, only : use_excess_ice ! !ARGUMENTS: type(file_desc_t), intent(inout) :: ncid ! local file id logical , intent(in) :: writing_finidat_interp_dest_file ! true if we are writing a finidat_interp_dest file @@ -605,10 +607,13 @@ subroutine restFile_write_issues_fixed(ncid, writing_finidat_interp_dest_file) ncid = ncid, & writing_finidat_interp_dest_file = writing_finidat_interp_dest_file, & issue_num = lake_dynbal_baseline_issue) - call write_issue_fixed_metadata( & - ncid = ncid, & - writing_finidat_interp_dest_file = writing_finidat_interp_dest_file, & - issue_num = excess_ice_issue) + ! If running with execess ice then mark the restart file as having excess ice fixed + if ( use_excess_ice ) then + call write_issue_fixed_metadata( & + ncid = ncid, & + writing_finidat_interp_dest_file = writing_finidat_interp_dest_file, & + issue_num = excess_ice_issue) + end if end subroutine restFile_write_issues_fixed From b2d469b1d1e51ea4655d89c9dfb37bb18b99197d Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Sun, 4 Dec 2022 19:51:38 -0700 Subject: [PATCH 67/99] Add RestartExcessIceIssue in WaterStateType and send down the logical about writing finidat file --- src/biogeophys/WaterStateBulkType.F90 | 3 +++ src/biogeophys/WaterStateType.F90 | 10 +++++++++- src/biogeophys/WaterType.F90 | 2 ++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/biogeophys/WaterStateBulkType.F90 b/src/biogeophys/WaterStateBulkType.F90 index ba3f0513c5..1326d64a33 100644 --- a/src/biogeophys/WaterStateBulkType.F90 +++ b/src/biogeophys/WaterStateBulkType.F90 @@ -188,6 +188,7 @@ end subroutine InitBulkCold !------------------------------------------------------------------------ subroutine RestartBulk(this, bounds, ncid, flag, & + writing_finidat_interp_dest_file, & watsat_col, t_soisno_col, altmax_lastyear_indx) ! ! !DESCRIPTION: @@ -202,6 +203,7 @@ subroutine RestartBulk(this, bounds, ncid, flag, & type(bounds_type), intent(in) :: bounds type(file_desc_t), intent(inout) :: ncid ! netcdf id character(len=*) , intent(in) :: flag ! 'read' or 'write' + logical , intent(in) :: writing_finidat_interp_dest_file ! true if we are writing a finidat_interp_dest file (ignored for flag=='read') real(r8) , intent(in) :: watsat_col (bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) real(r8) , intent(in) :: t_soisno_col(bounds%begc:, -nlevsno+1:) ! col soil temperature (Kelvin) integer , intent(in) :: altmax_lastyear_indx(bounds%begc:) !col active layer index last year @@ -214,6 +216,7 @@ subroutine RestartBulk(this, bounds, ncid, flag, & SHR_ASSERT_ALL_FL((ubound(watsat_col) == (/bounds%endc,nlevmaxurbgrnd/)) , sourcefile, __LINE__) call this%restart (bounds, ncid, flag=flag, & + writing_finidat_interp_dest_file=writing_finidat_interp_dest_file, & watsat_col=watsat_col(bounds%begc:bounds%endc,:), & t_soisno_col=t_soisno_col(bounds%begc:, -nlevsno+1:), & altmax_lastyear_indx=altmax_lastyear_indx(bounds%begc:)) diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index 944a6bfc85..243214132d 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -580,6 +580,7 @@ end subroutine InitCold !------------------------------------------------------------------------ subroutine Restart(this, bounds, ncid, flag, & + writing_finidat_interp_dest_file, & watsat_col, t_soisno_col, altmax_lastyear_indx) ! ! !DESCRIPTION: @@ -603,6 +604,7 @@ subroutine Restart(this, bounds, ncid, flag, & real(r8) , intent(in) :: watsat_col (bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) real(r8) , intent(in) :: t_soisno_col(bounds%begc:, -nlevsno+1:) ! col soil temperature (Kelvin) integer , intent(in) :: altmax_lastyear_indx(bounds%begc:) !col active layer index last year + logical , intent(in) :: writing_finidat_interp_dest_file ! true if we are writing a finidat_interp_dest file (ignored for flag=='read') ! ! !LOCAL VARIABLES: integer :: p,c,l,j,nlevs,nbedrock @@ -610,6 +612,7 @@ subroutine Restart(this, bounds, ncid, flag, & real(r8) :: maxwatsat ! maximum porosity real(r8) :: excess ! excess volumetric soil water real(r8) :: totwat ! total soil water (mm) + logical :: excess_ice_on_restart ! Excess ice fields are on the restart file !------------------------------------------------------------------------ SHR_ASSERT_ALL_FL((ubound(watsat_col) == (/bounds%endc,nlevmaxurbgrnd/)) , sourcefile, __LINE__) @@ -707,13 +710,18 @@ subroutine Restart(this, bounds, ncid, flag, & ! no need to even define the restart vars this%excess_ice_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 else + call RestartExcessIceIssue( & + ncid = ncid, & + flag = flag, & + writing_finidat_interp_dest_file = writing_finidat_interp_dest_file, & + excess_ice_on_restart = excess_ice_on_restart) ! have to at least define them call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('EXCESS_ICE'), xtype=ncd_double, & dim1name='column', dim2name='levtot', switchdim=.true., & long_name=this%info%lname('excess soil ice (vegetated landunits only)'), & units='kg/m2', scale_by_thickness=.true., & interpinic_flag='interp', readvar=readvar, data=this%excess_ice_col) - if (flag == 'read' .and. (.not. readvar)) then ! when reading restart that does not have excess ice in it + if (flag == 'read' .and. ((.not. readvar) .or. (.not. excess_ice_on_restart)) ) then ! when reading restart that does not have excess ice in it if (nsrest == nsrContinue) then call endrun(msg = "On a continue run, excess ice fields MUST be on the restart file "// & errMsg(sourcefile, __LINE__)) diff --git a/src/biogeophys/WaterType.F90 b/src/biogeophys/WaterType.F90 index bc257f27ad..24cf85d49f 100644 --- a/src/biogeophys/WaterType.F90 +++ b/src/biogeophys/WaterType.F90 @@ -750,6 +750,7 @@ subroutine Restart(this, bounds, ncid, flag, writing_finidat_interp_dest_file, & call this%waterfluxbulk_inst%restartBulk (bounds, ncid, flag=flag) call this%waterstatebulk_inst%restartBulk (bounds, ncid, flag=flag, & + writing_finidat_interp_dest_file=writing_finidat_interp_dest_file, & watsat_col=watsat_col(bounds%begc:bounds%endc,:), & t_soisno_col=t_soisno_col(bounds%begc:, -nlevsno+1:), & altmax_lastyear_indx=altmax_lastyear_indx(bounds%begc:)) @@ -763,6 +764,7 @@ subroutine Restart(this, bounds, ncid, flag, writing_finidat_interp_dest_file, & call this%bulk_and_tracers(i)%waterflux_inst%Restart(bounds, ncid, flag=flag) call this%bulk_and_tracers(i)%waterstate_inst%Restart(bounds, ncid, flag=flag, & + writing_finidat_interp_dest_file=writing_finidat_interp_dest_file, & watsat_col=watsat_col(bounds%begc:bounds%endc,:), & t_soisno_col=t_soisno_col(bounds%begc:, -nlevsno+1:), & altmax_lastyear_indx=altmax_lastyear_indx(bounds%begc:)) From 212e10476a64911da1ca9dff9f1a172515c4707a Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 5 Dec 2022 12:26:03 -0700 Subject: [PATCH 68/99] Prevent nbedrock from being used before it's set --- src/biogeophys/WaterStateType.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index 243214132d..7ada7b8cb2 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -367,7 +367,7 @@ subroutine InitCold(this, bounds, & if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then nlevs = nlevgrnd do j = 1, nlevs - if (use_bedrock) then + if (use_bedrock .and. col%nbedrock(c) <=nlevsoi) then nbedrock = col%nbedrock(c) else nbedrock = nlevsoi @@ -549,7 +549,7 @@ subroutine InitCold(this, bounds, & else n05m=nlevsoi-1 endif - if (use_bedrock .and. nbedrock<=nlevsoi) then + if (use_bedrock .and. col%nbedrock(c) <=nlevsoi) then nbedrock = col%nbedrock(c) else nbedrock = nlevsoi @@ -737,7 +737,7 @@ subroutine Restart(this, bounds, ncid, flag, & l = col%landunit(c) if (.not. lun%lakpoi(l)) then !not lake if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then - if (use_bedrock .and. nbedrock<=nlevsoi) then + if (use_bedrock .and. col%nbedrock(c)>nlevsoi) then nbedrock = col%nbedrock(c) else nbedrock = nlevsoi From 9432c90493c381e6d6b57bfd26eaae7b96507e71 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 5 Dec 2022 13:36:52 -0700 Subject: [PATCH 69/99] Handle InitCold for excess ice when excess ice streams are off --- src/biogeophys/WaterStateType.F90 | 68 +++++++++++++++++-------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index 7ada7b8cb2..0b628e5678 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -23,7 +23,7 @@ module WaterStateType use WaterInfoBaseType, only : water_info_base_type use WaterTracerContainerType, only : water_tracer_container_type use WaterTracerUtils, only : AllocateVar1d, AllocateVar2d - use ExcessIceStreamType, only : excessicestream_type + use ExcessIceStreamType, only : excessicestream_type, UseExcessIceStreams ! implicit none save @@ -538,38 +538,44 @@ subroutine InitCold(this, bounds, & this%excess_ice_col(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)=0.0_r8 this%exice_bulk_init(bounds%begc:bounds%endc)=0.0_r8 call this%exicestream%Init(bounds, NLFilename) ! get initial fraction of excess ice per column - call this%exicestream%CalcExcessIce(bounds, this%exice_bulk_init) - do c = bounds%begc,bounds%endc - g = col%gridcell(c) - l = col%landunit(c) - if (.not. lun%lakpoi(l)) then !not lake - if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then - if (zisoi(nlevsoi) >= 0.5_r8) then - call find_soil_layer_containing_depth(0.5_r8,n05m) - else - n05m=nlevsoi-1 - endif - if (use_bedrock .and. col%nbedrock(c) <=nlevsoi) then - nbedrock = col%nbedrock(c) - else - nbedrock = nlevsoi - endif - do j = 2, nlevmaxurbgrnd ! ignore first layer - if (n05m= n05m .and. j= 0.5_r8) then + call find_soil_layer_containing_depth(0.5_r8,n05m) + else + n05m=nlevsoi-1 + endif + if (use_bedrock .and. col%nbedrock(c) <=nlevsoi) then + nbedrock = col%nbedrock(c) + else + nbedrock = nlevsoi + endif + do j = 2, nlevmaxurbgrnd ! ignore first layer + if (n05m= n05m .and. j Date: Mon, 5 Dec 2022 15:55:58 -0700 Subject: [PATCH 70/99] Don't do the write in ExcessIceRestart so writing_finidat_interp_dest_file doesn't need to be passed as many places --- src/biogeophys/WaterDiagnosticBulkType.F90 | 1 - src/biogeophys/WaterStateBulkType.F90 | 3 --- src/biogeophys/WaterStateType.F90 | 3 --- src/biogeophys/WaterType.F90 | 2 -- 4 files changed, 9 deletions(-) diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index fdbbcec566..98e5e9532c 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -919,7 +919,6 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil call RestartExcessIceIssue( & ncid = ncid, & flag = flag, & - writing_finidat_interp_dest_file = writing_finidat_interp_dest_file, & excess_ice_on_restart = excess_ice_on_restart) ! have to at least define them call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('SUBSIDENCE'), & diff --git a/src/biogeophys/WaterStateBulkType.F90 b/src/biogeophys/WaterStateBulkType.F90 index 1326d64a33..ba3f0513c5 100644 --- a/src/biogeophys/WaterStateBulkType.F90 +++ b/src/biogeophys/WaterStateBulkType.F90 @@ -188,7 +188,6 @@ end subroutine InitBulkCold !------------------------------------------------------------------------ subroutine RestartBulk(this, bounds, ncid, flag, & - writing_finidat_interp_dest_file, & watsat_col, t_soisno_col, altmax_lastyear_indx) ! ! !DESCRIPTION: @@ -203,7 +202,6 @@ subroutine RestartBulk(this, bounds, ncid, flag, & type(bounds_type), intent(in) :: bounds type(file_desc_t), intent(inout) :: ncid ! netcdf id character(len=*) , intent(in) :: flag ! 'read' or 'write' - logical , intent(in) :: writing_finidat_interp_dest_file ! true if we are writing a finidat_interp_dest file (ignored for flag=='read') real(r8) , intent(in) :: watsat_col (bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) real(r8) , intent(in) :: t_soisno_col(bounds%begc:, -nlevsno+1:) ! col soil temperature (Kelvin) integer , intent(in) :: altmax_lastyear_indx(bounds%begc:) !col active layer index last year @@ -216,7 +214,6 @@ subroutine RestartBulk(this, bounds, ncid, flag, & SHR_ASSERT_ALL_FL((ubound(watsat_col) == (/bounds%endc,nlevmaxurbgrnd/)) , sourcefile, __LINE__) call this%restart (bounds, ncid, flag=flag, & - writing_finidat_interp_dest_file=writing_finidat_interp_dest_file, & watsat_col=watsat_col(bounds%begc:bounds%endc,:), & t_soisno_col=t_soisno_col(bounds%begc:, -nlevsno+1:), & altmax_lastyear_indx=altmax_lastyear_indx(bounds%begc:)) diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index 0b628e5678..457f238de2 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -586,7 +586,6 @@ end subroutine InitCold !------------------------------------------------------------------------ subroutine Restart(this, bounds, ncid, flag, & - writing_finidat_interp_dest_file, & watsat_col, t_soisno_col, altmax_lastyear_indx) ! ! !DESCRIPTION: @@ -610,7 +609,6 @@ subroutine Restart(this, bounds, ncid, flag, & real(r8) , intent(in) :: watsat_col (bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) real(r8) , intent(in) :: t_soisno_col(bounds%begc:, -nlevsno+1:) ! col soil temperature (Kelvin) integer , intent(in) :: altmax_lastyear_indx(bounds%begc:) !col active layer index last year - logical , intent(in) :: writing_finidat_interp_dest_file ! true if we are writing a finidat_interp_dest file (ignored for flag=='read') ! ! !LOCAL VARIABLES: integer :: p,c,l,j,nlevs,nbedrock @@ -719,7 +717,6 @@ subroutine Restart(this, bounds, ncid, flag, & call RestartExcessIceIssue( & ncid = ncid, & flag = flag, & - writing_finidat_interp_dest_file = writing_finidat_interp_dest_file, & excess_ice_on_restart = excess_ice_on_restart) ! have to at least define them call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('EXCESS_ICE'), xtype=ncd_double, & diff --git a/src/biogeophys/WaterType.F90 b/src/biogeophys/WaterType.F90 index 24cf85d49f..bc257f27ad 100644 --- a/src/biogeophys/WaterType.F90 +++ b/src/biogeophys/WaterType.F90 @@ -750,7 +750,6 @@ subroutine Restart(this, bounds, ncid, flag, writing_finidat_interp_dest_file, & call this%waterfluxbulk_inst%restartBulk (bounds, ncid, flag=flag) call this%waterstatebulk_inst%restartBulk (bounds, ncid, flag=flag, & - writing_finidat_interp_dest_file=writing_finidat_interp_dest_file, & watsat_col=watsat_col(bounds%begc:bounds%endc,:), & t_soisno_col=t_soisno_col(bounds%begc:, -nlevsno+1:), & altmax_lastyear_indx=altmax_lastyear_indx(bounds%begc:)) @@ -764,7 +763,6 @@ subroutine Restart(this, bounds, ncid, flag, writing_finidat_interp_dest_file, & call this%bulk_and_tracers(i)%waterflux_inst%Restart(bounds, ncid, flag=flag) call this%bulk_and_tracers(i)%waterstate_inst%Restart(bounds, ncid, flag=flag, & - writing_finidat_interp_dest_file=writing_finidat_interp_dest_file, & watsat_col=watsat_col(bounds%begc:bounds%endc,:), & t_soisno_col=t_soisno_col(bounds%begc:, -nlevsno+1:), & altmax_lastyear_indx=altmax_lastyear_indx(bounds%begc:)) From 0ff6d4dadd53e8022350d5336b0342f98f74d588 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 5 Dec 2022 17:26:46 -0700 Subject: [PATCH 71/99] Don't do the write in ExcessIceRestart so writing_finidat_interp_dest_file doesn't need to be passed as many places --- src/utils/restUtilMod.F90.in | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/utils/restUtilMod.F90.in b/src/utils/restUtilMod.F90.in index da22ea2d60..58da88ed50 100644 --- a/src/utils/restUtilMod.F90.in +++ b/src/utils/restUtilMod.F90.in @@ -743,8 +743,7 @@ contains end subroutine write_interpinic_flag !----------------------------------------------------------------------- - subroutine RestartExcessIceIssue(ncid, flag, & - writing_finidat_interp_dest_file, excess_ice_on_restart) + subroutine RestartExcessIceIssue(ncid, flag, excess_ice_on_restart) ! ! !DESCRIPTION: ! Is excess ice on the originating restart file? This is important to have @@ -753,15 +752,13 @@ contains ! exist on the originating restart file. ! ! !USES: - use ncdio_pio , only : file_desc_t - use IssueFixedMetadataHandler, only : write_issue_fixed_metadata, read_issue_fixed_metadata - use clm_time_manager , only : is_restart + use ncdio_pio , only : file_desc_t + use IssueFixedMetadataHandler, only : read_issue_fixed_metadata ! ! !ARGUMENTS: - type(file_desc_t), intent(inout) :: ncid ! netcdf id - character(len=*) , intent(in) :: flag ! 'read' or 'write' - logical, intent(in) :: writing_finidat_interp_dest_file ! true if this is a finidat_interp_dest file - logical, intent(out) :: excess_ice_on_restart ! If excess ice is on the restart file + type(file_desc_t), intent(inout) :: ncid ! netcdf id + character(len=*) , intent(in) :: flag ! 'read' or 'write' + logical, intent(out) :: excess_ice_on_restart ! If excess ice is on the restart file ! ! !LOCAL VARIABLES: integer :: attribute_value @@ -771,13 +768,9 @@ contains character(len=*), parameter :: subname = 'RestartExcessIceIssue' !----------------------------------------------------------------------- - if (flag == 'define') then - call write_issue_fixed_metadata( & - ncid = ncid, & - writing_finidat_interp_dest_file = writing_finidat_interp_dest_file, & - issue_num = excess_ice_issue) - - else if (flag == 'read' .and. .not. is_restart()) then + excess_ice_on_restart = .false. + ! The write of the issue metadata is in restFileMod::: restFile_write_issues_fixed + if (flag == 'read' )then call read_issue_fixed_metadata( & ncid = ncid, & issue_num = excess_ice_issue, & From 2581d079526ede3464cba916f8f6ea65765dd403 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 6 Dec 2022 10:59:56 -0700 Subject: [PATCH 72/99] Point to a finidat file that has excess ice on it --- .../testdefs/testmods_dirs/clm/ExcessIceRestart/user_nl_clm | 1 + 1 file changed, 1 insertion(+) diff --git a/cime_config/testdefs/testmods_dirs/clm/ExcessIceRestart/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/ExcessIceRestart/user_nl_clm index d9e52c6cf9..98fc5ea574 100644 --- a/cime_config/testdefs/testmods_dirs/clm/ExcessIceRestart/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/ExcessIceRestart/user_nl_clm @@ -1 +1,2 @@ use_excess_ice = .true. + finidat = '$DIN_LOC_ROOT/lnd/clm2/initdata_map/clmi.I1850Clm50Sp.0003-01-01.0.9x1.25_gx1v7_exice_simyr1850_c221205.nc' From d4c4efca4f3c84ddcf20067b8cc28c71f50a7202 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 6 Dec 2022 11:08:54 -0700 Subject: [PATCH 73/99] Add an excess ice test to the ctsm_sci list and lengthen the time --- cime_config/testdefs/testlist_clm.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 18d6c56f73..201d699847 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -186,10 +186,11 @@ + - + From dcaaf69da84c5a3db4db2aed41c15e20e9810fc6 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 6 Dec 2022 11:48:37 -0700 Subject: [PATCH 74/99] Add an output user-mod option for excessice to the yearly file, change testmod names, use startup and output_sp_exice for test mod from a startup file --- cime_config/testdefs/testlist_clm.xml | 4 ++-- .../testmods_dirs/clm/ExcessIceRestart/include_user_mods | 1 - .../ExcessIceStartup_output_sp_exice/include_user_mods | 2 ++ .../user_nl_clm | 0 .../usermods_dirs/output_sp_exice/include_user_mods | 2 ++ cime_config/usermods_dirs/output_sp_exice/user_nl_clm | 8 ++++++++ 6 files changed, 14 insertions(+), 3 deletions(-) delete mode 100644 cime_config/testdefs/testmods_dirs/clm/ExcessIceRestart/include_user_mods create mode 100644 cime_config/testdefs/testmods_dirs/clm/ExcessIceStartup_output_sp_exice/include_user_mods rename cime_config/testdefs/testmods_dirs/clm/{ExcessIceRestart => ExcessIceStartup_output_sp_exice}/user_nl_clm (100%) create mode 100644 cime_config/usermods_dirs/output_sp_exice/include_user_mods create mode 100644 cime_config/usermods_dirs/output_sp_exice/user_nl_clm diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 201d699847..bf3e143166 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -182,7 +182,7 @@ - + @@ -191,7 +191,7 @@ - + diff --git a/cime_config/testdefs/testmods_dirs/clm/ExcessIceRestart/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/ExcessIceRestart/include_user_mods deleted file mode 100644 index fe0e18cf88..0000000000 --- a/cime_config/testdefs/testmods_dirs/clm/ExcessIceRestart/include_user_mods +++ /dev/null @@ -1 +0,0 @@ -../default diff --git a/cime_config/testdefs/testmods_dirs/clm/ExcessIceStartup_output_sp_exice/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/ExcessIceStartup_output_sp_exice/include_user_mods new file mode 100644 index 0000000000..6d8de3732a --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/ExcessIceStartup_output_sp_exice/include_user_mods @@ -0,0 +1,2 @@ +../monthly +../../../../usermods_dirs/output_sp_exice diff --git a/cime_config/testdefs/testmods_dirs/clm/ExcessIceRestart/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/ExcessIceStartup_output_sp_exice/user_nl_clm similarity index 100% rename from cime_config/testdefs/testmods_dirs/clm/ExcessIceRestart/user_nl_clm rename to cime_config/testdefs/testmods_dirs/clm/ExcessIceStartup_output_sp_exice/user_nl_clm diff --git a/cime_config/usermods_dirs/output_sp_exice/include_user_mods b/cime_config/usermods_dirs/output_sp_exice/include_user_mods new file mode 100644 index 0000000000..4b75b772c0 --- /dev/null +++ b/cime_config/usermods_dirs/output_sp_exice/include_user_mods @@ -0,0 +1,2 @@ +../_include/output_base +../output_sp diff --git a/cime_config/usermods_dirs/output_sp_exice/user_nl_clm b/cime_config/usermods_dirs/output_sp_exice/user_nl_clm new file mode 100644 index 0000000000..48e680df67 --- /dev/null +++ b/cime_config/usermods_dirs/output_sp_exice/user_nl_clm @@ -0,0 +1,8 @@ +!---------------------------------------------------------------------------------- +! Settings from output_sp_exice +!---------------------------------------------------------------------------------- + +! h3 stream (yearly average, gridcell-level) +! Eyr +hist_fincl4 += 'EXCESS_ICE' + From b848a7afde03059b2f185b61c9b93bd90ca2f6b9 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 7 Dec 2022 09:30:38 -0700 Subject: [PATCH 75/99] Add in needed stubs for unit-testing to work --- src/biogeophys/WaterStateType.F90 | 2 +- src/unit_test_stubs/CMakeLists.txt | 1 + src/unit_test_stubs/share_esmf/CMakeLists.txt | 5 ++ .../share_esmf/ExcessIceStreamType.F90 | 79 +++++++++++++++++++ .../utils/restUtilMod_stub.F90.in | 25 ++++++ 5 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 src/unit_test_stubs/share_esmf/CMakeLists.txt create mode 100644 src/unit_test_stubs/share_esmf/ExcessIceStreamType.F90 diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index 457f238de2..3af85650c2 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -599,7 +599,7 @@ subroutine Restart(this, bounds, ncid, flag, & use clm_varctl , only : bound_h2osoi, nsrest, nsrContinue use ncdio_pio , only : file_desc_t, ncd_double use ExcessIceStreamType, only : UseExcessIceStreams - use restUtilMod + use restUtilMod , only : restartvar, RestartExcessIceIssue ! ! !ARGUMENTS: class(waterstate_type), intent(in) :: this diff --git a/src/unit_test_stubs/CMakeLists.txt b/src/unit_test_stubs/CMakeLists.txt index 38abfb1633..2d7fe23378 100644 --- a/src/unit_test_stubs/CMakeLists.txt +++ b/src/unit_test_stubs/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(csm_share) add_subdirectory(dyn_subgrid) add_subdirectory(main) +add_subdirectory(share_esmf) add_subdirectory(utils) sourcelist_to_parent(clm_sources) diff --git a/src/unit_test_stubs/share_esmf/CMakeLists.txt b/src/unit_test_stubs/share_esmf/CMakeLists.txt new file mode 100644 index 0000000000..5eb2d42415 --- /dev/null +++ b/src/unit_test_stubs/share_esmf/CMakeLists.txt @@ -0,0 +1,5 @@ +list(APPEND clm_sources + ExcessIceStreamType.F90 + ) + +sourcelist_to_parent(clm_sources) diff --git a/src/unit_test_stubs/share_esmf/ExcessIceStreamType.F90 b/src/unit_test_stubs/share_esmf/ExcessIceStreamType.F90 new file mode 100644 index 0000000000..60bac5ad28 --- /dev/null +++ b/src/unit_test_stubs/share_esmf/ExcessIceStreamType.F90 @@ -0,0 +1,79 @@ +module ExcessIceStreamType + + !----------------------------------------------------------------------- + ! !DESCRIPTION: + ! Stub module for Excess ice streams + ! + ! !USES + use shr_kind_mod , only : r8 => shr_kind_r8, CL => shr_kind_cl + use shr_log_mod , only : errMsg => shr_log_errMsg + use abortutils , only : endrun + use decompMod , only : bounds_type + + ! !PUBLIC TYPES: + implicit none + private + + public :: UseExcessIceStreams ! If streams will be used + + type, public :: excessicestream_type + contains + + ! !PUBLIC MEMBER FUNCTIONS: + procedure, public :: Init ! Initialize and read data in + procedure, public :: CalcExcessIce ! Calculate excess ice ammount + end type excessicestream_type + ! ! PRIVATE DATA: + + logical :: namelist_read = .false. + + character(len=*), parameter, private :: sourcefile = & + __FILE__ + +!============================================================================== +contains +!============================================================================== + + subroutine Init(this, bounds, NLFilename) + ! + ! arguments + implicit none + class(excessicestream_type) :: this + type(bounds_type), intent(in) :: bounds + character(len=*), intent(in) :: NLFilename ! Namelist filename + + namelist_read = .true. + + end subroutine Init + + subroutine CalcExcessIce(this,bounds,exice_bulk_init) + + ! only transfers grid values to columns + implicit none + class(excessicestream_type) :: this + type(bounds_type), intent(in) :: bounds + real(r8) , intent(inout) :: exice_bulk_init(bounds%begc:bounds%endc) + ! + ! !LOCAL VARIABLES: + call endrun(msg=' ERROR CalcExcessIce stub is being called and should NOT be'//errMsg(sourcefile, __LINE__)) + + end subroutine CalcExcessIce + + logical function UseExcessIceStreams() + ! + ! !DESCRIPTION: + ! Return true if + ! + ! !USES: + ! + ! !ARGUMENTS: + implicit none + ! + ! !LOCAL VARIABLES: + if ( .not. namelist_read ) then + call endrun(msg=' ERROR UseExcessIceStreams being called, but namelist has not been read yet'//errMsg(sourcefile, __LINE__)) + end if + UseExcessIceStreams = .false. +end function UseExcessIceStreams + +end module ExcessIceStreamType diff --git a/src/unit_test_stubs/utils/restUtilMod_stub.F90.in b/src/unit_test_stubs/utils/restUtilMod_stub.F90.in index b6e3ba4f19..a3a59f842c 100644 --- a/src/unit_test_stubs/utils/restUtilMod_stub.F90.in +++ b/src/unit_test_stubs/utils/restUtilMod_stub.F90.in @@ -21,6 +21,8 @@ module restUtilMod public :: restartvar + public :: RestartExcessIceIssue + public :: set_missing_from_template contains @@ -149,4 +151,27 @@ contains end subroutine set_missing_from_template + !----------------------------------------------------------------------- + subroutine RestartExcessIceIssue(ncid, flag, excess_ice_on_restart) + ! + ! !DESCRIPTION: + ! + ! !USES: + ! + ! !ARGUMENTS: + type(file_desc_t), intent(inout) :: ncid ! netcdf id + character(len=*) , intent(in) :: flag ! 'read' or 'write' + logical, intent(out) :: excess_ice_on_restart ! If excess ice is on the restart file + ! + ! !LOCAL VARIABLES: + integer :: attribute_value + + character(len=*), parameter :: subname = 'RestartExcessIceIssue' + !----------------------------------------------------------------------- + + excess_ice_on_restart = .false. + + end subroutine RestartExcessIceIssue + + end module restUtilMod From f258b5d3a147200bedf8b75993afdbf5f1f01c33 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 7 Dec 2022 10:29:00 -0700 Subject: [PATCH 76/99] ERS tests can't be a single day, use the default length --- 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 bf3e143166..a540807c83 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -168,7 +168,7 @@ - + From 2ae796bb1a2c7a881602c28085b0078c987f50b8 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 7 Dec 2022 10:29:19 -0700 Subject: [PATCH 77/99] Correct directory name --- cime_config/usermods_dirs/output_sp_exice/include_user_mods | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/usermods_dirs/output_sp_exice/include_user_mods b/cime_config/usermods_dirs/output_sp_exice/include_user_mods index 4b75b772c0..786fa907a9 100644 --- a/cime_config/usermods_dirs/output_sp_exice/include_user_mods +++ b/cime_config/usermods_dirs/output_sp_exice/include_user_mods @@ -1,2 +1,2 @@ -../_include/output_base +../_includes/output_base ../output_sp From f599275fed106aef57088a8a11b2f928bf17c4c8 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 7 Dec 2022 13:28:25 -0700 Subject: [PATCH 78/99] Change dimension of local varialbes from nlevgrnd to nlevmaxurbgrnd because of issues the the izumi_nag compiler found --- src/biogeophys/SoilTemperatureMod.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index f7b970c057..5d84655493 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -1128,7 +1128,7 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & real(r8) :: temp1 !temporary variables [kg/m2] real(r8) :: hm(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) !energy residual [W/m2] real(r8) :: xm(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) !melting or freezing within a time step [kg/m2] - real(r8) :: xm2(bounds%begc:bounds%endc,-nlevsno+1:nlevgrnd) !additional melting or freezing within a time step [kg/m2] (needed for excess ice melt) + real(r8) :: xm2(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) !additional melting or freezing within a time step [kg/m2] (needed for excess ice melt) real(r8) :: wmass0(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)!initial mass of ice and liquid (kg/m2) real(r8) :: wice0 (bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)!initial mass of ice (kg/m2) real(r8) :: wliq0 (bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd)!initial mass of liquid (kg/m2) @@ -1136,7 +1136,7 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & real(r8) :: propor !proportionality constant (-) real(r8) :: tinc(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) !t(n+1)-t(n) [K] real(r8) :: smp !frozen water potential (mm) - real(r8) :: wexice0(bounds%begc:bounds%endc,-nlevsno+1:nlevgrnd) !initial mass of excess_ice at the timestep (kg/m2) + real(r8) :: wexice0(bounds%begc:bounds%endc,-nlevsno+1:nlevmaxurbgrnd) !initial mass of excess_ice at the timestep (kg/m2) !----------------------------------------------------------------------- From 307ebfb90a02e12da792fec3dc7a65ded96b9ba1 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 7 Dec 2022 17:23:04 -0700 Subject: [PATCH 79/99] Make note of PGI test for excess ice that fails --- cime_config/testdefs/ExpectedTestFails.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cime_config/testdefs/ExpectedTestFails.xml b/cime_config/testdefs/ExpectedTestFails.xml index 2656079bf7..a081684acb 100644 --- a/cime_config/testdefs/ExpectedTestFails.xml +++ b/cime_config/testdefs/ExpectedTestFails.xml @@ -29,6 +29,13 @@ + + + FAIL + PGI problems with the nuopc driver + + + From 782fc1923e8e050358588937d112cd20f6ed7712 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 7 Dec 2022 21:32:12 -0700 Subject: [PATCH 80/99] Only adjust soil depths for excess ice calculations if excess ice is on --- src/biogeophys/SoilTemperatureMod.F90 | 60 ++++++++++++++------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index 5d84655493..a49ac9c662 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -114,7 +114,7 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter ! !USES: use clm_time_manager , only : get_step_size_real use clm_varpar , only : nlevsno, nlevgrnd, nlevurb, nlevmaxurbgrnd - use clm_varctl , only : iulog + use clm_varctl , only : iulog, use_excess_ice use clm_varcon , only : cnfac, cpice, cpliq, denh2o, denice use landunit_varcon , only : istsoil, istcrop use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall, icol_road_perv, icol_road_imperv @@ -280,24 +280,24 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter !-------------------------------------------------------------- ! Vertical coordinates adjustment for excess ice calculations !-------------------------------------------------------------- - ! Save original soil depth to get put them back in et the end - dz_0(begc:endc,-nlevsno+1:nlevmaxurbgrnd)=dz(begc:endc,-nlevsno+1:nlevmaxurbgrnd) - zi_0(begc:endc,-nlevsno+0:nlevmaxurbgrnd)=zi(begc:endc,-nlevsno+0:nlevmaxurbgrnd) - z_0(begc:endc,-nlevsno+1:nlevmaxurbgrnd)=z(begc:endc,-nlevsno+1:nlevmaxurbgrnd) - ! Adjust column depth for excess ice thickness - do fc = 1,num_nolakec - c = filter_nolakec(fc) - l = col%landunit(c) - if( lun%itype(l) == istsoil .or. lun%itype(l) == istcrop ) then - dz(c,1:nlevmaxurbgrnd)=dz(c,1:nlevmaxurbgrnd)+excess_ice(c,1:nlevmaxurbgrnd)/denice ! add extra layer thickness - do j=1,nlevmaxurbgrnd ! if excess ice amount dropped to zero there will be no adjustment - zi(c,j) = zi(c,j) + sum(excess_ice(c,1:j)) / denice - z(c,j) = (zi(c,j-1) + zi(c,j)) * 0.5_r8 - end do - endif - end do - - + if ( use_excess_ice )then + ! Save original soil depth to get put them back in et the end + dz_0(begc:endc,-nlevsno+1:nlevmaxurbgrnd)=dz(begc:endc,-nlevsno+1:nlevmaxurbgrnd) + zi_0(begc:endc,-nlevsno+0:nlevmaxurbgrnd)=zi(begc:endc,-nlevsno+0:nlevmaxurbgrnd) + z_0(begc:endc,-nlevsno+1:nlevmaxurbgrnd)=z(begc:endc,-nlevsno+1:nlevmaxurbgrnd) + ! Adjust column depth for excess ice thickness + do fc = 1,num_nolakec + c = filter_nolakec(fc) + l = col%landunit(c) + if( lun%itype(l) == istsoil .or. lun%itype(l) == istcrop ) then + dz(c,1:nlevmaxurbgrnd)=dz(c,1:nlevmaxurbgrnd)+excess_ice(c,1:nlevmaxurbgrnd)/denice ! add extra layer thickness + do j=1,nlevmaxurbgrnd ! if excess ice amount dropped to zero there will be no adjustment + zi(c,j) = zi(c,j) + sum(excess_ice(c,1:j)) / denice + z(c,j) = (zi(c,j-1) + zi(c,j)) * 0.5_r8 + end do + endif + end do + end if !------------------------------------------------------ ! Compute ground surface and soil temperatures @@ -520,16 +520,18 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter ! Vertical coordinates adjustment for excess ice calculations !-------------------------------------------------------------- ! bringing back the soil depth to the original state - ! Adjust column depth for excess ice thickness - do fc = 1,num_nolakec - c = filter_nolakec(fc) - l = col%landunit(c) - if( lun%itype(l) == istsoil .or. lun%itype(l) == istcrop ) then - dz(c,1:nlevmaxurbgrnd)=dz_0(c,1:nlevmaxurbgrnd) - zi(c,1:nlevmaxurbgrnd)=zi_0(c,1:nlevmaxurbgrnd) - z(c,1:nlevmaxurbgrnd)=z_0(c,1:nlevmaxurbgrnd) - endif - end do + if ( use_excess_ice )then + ! Adjust column depth for excess ice thickness + do fc = 1,num_nolakec + c = filter_nolakec(fc) + l = col%landunit(c) + if( lun%itype(l) == istsoil .or. lun%itype(l) == istcrop ) then + dz(c,1:nlevmaxurbgrnd)=dz_0(c,1:nlevmaxurbgrnd) + zi(c,1:nlevmaxurbgrnd)=zi_0(c,1:nlevmaxurbgrnd) + z(c,1:nlevmaxurbgrnd)=z_0(c,1:nlevmaxurbgrnd) + endif + end do + end if From bbd90a1689130678cf70e0eba124139b5f96611f Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 9 Dec 2022 02:01:32 -0700 Subject: [PATCH 81/99] Add setting for initial interpolation for excess ice startup file --- .../clm/ExcessIceStartup_output_sp_exice/user_nl_clm | 1 + 1 file changed, 1 insertion(+) diff --git a/cime_config/testdefs/testmods_dirs/clm/ExcessIceStartup_output_sp_exice/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/ExcessIceStartup_output_sp_exice/user_nl_clm index 98fc5ea574..e479af9449 100644 --- a/cime_config/testdefs/testmods_dirs/clm/ExcessIceStartup_output_sp_exice/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/ExcessIceStartup_output_sp_exice/user_nl_clm @@ -1,2 +1,3 @@ use_excess_ice = .true. finidat = '$DIN_LOC_ROOT/lnd/clm2/initdata_map/clmi.I1850Clm50Sp.0003-01-01.0.9x1.25_gx1v7_exice_simyr1850_c221205.nc' + use_init_interp = .true. From 4be8cc091b5f22f266545be8ce7e48ef114f3ff4 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 9 Dec 2022 02:03:03 -0700 Subject: [PATCH 82/99] Dimension exice_subs_col as noticed by izumi case --- src/biogeophys/WaterDiagnosticBulkType.F90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index 98e5e9532c..4ec96820b6 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -170,6 +170,7 @@ subroutine InitBulkAllocate(this, bounds) ! ! !USES: use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=) + use clm_varpar , only : nlevmaxurbgrnd ! ! !ARGUMENTS: class(waterdiagnosticbulk_type), intent(inout) :: this @@ -199,7 +200,7 @@ subroutine InitBulkAllocate(this, bounds) allocate(this%h2osoi_liq_tot_col (begc:endc)) ; this%h2osoi_liq_tot_col (:) = nan allocate(this%swe_old_col (begc:endc,-nlevsno+1:0)) ; this%swe_old_col (:,:) = nan allocate(this%exice_subs_tot_col (begc:endc)) ; this%exice_subs_tot_col (:) = 0.0_r8 - allocate(this%exice_subs_col (begc:endc, 1:nlevgrnd)) ; this%exice_subs_col (:,:) = 0.0_r8 + allocate(this%exice_subs_col (begc:endc, 1:nlevmaxurbgrnd)) ; this%exice_subs_col (:,:) = 0.0_r8 allocate(this%exice_vol_col (begc:endc, 1:nlevgrnd)) ; this%exice_vol_col (:,:) = 0.0_r8 allocate(this%exice_vol_tot_col (begc:endc)) ; this%exice_vol_tot_col (:) = 0.0_r8 From 689fb3f1b92fa9d424c9c8b5233d03b557ab944e Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 9 Dec 2022 09:55:38 -0700 Subject: [PATCH 83/99] Cut back on the excess ice tests --- cime_config/testdefs/testlist_clm.xml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index d6c1a196e3..cb44a75cc8 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -171,11 +171,7 @@ - - - - @@ -184,10 +180,7 @@ - - - From fc2844896f5a2b54ad6f18c13fa806879f9f4f07 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 9 Dec 2022 09:56:32 -0700 Subject: [PATCH 84/99] Remove expected fail as removed the PGI excess ice test --- cime_config/testdefs/ExpectedTestFails.xml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/cime_config/testdefs/ExpectedTestFails.xml b/cime_config/testdefs/ExpectedTestFails.xml index 58b3c004ef..52a5828f5d 100644 --- a/cime_config/testdefs/ExpectedTestFails.xml +++ b/cime_config/testdefs/ExpectedTestFails.xml @@ -29,14 +29,6 @@ - - - FAIL - PGI problems with the nuopc driver - - - - FAIL From 6a07efb0c3fa9e5670294950072748e42a9d5995 Mon Sep 17 00:00:00 2001 From: mvdebolskiy <80036033+mvdebolskiy@users.noreply.github.com> Date: Sun, 11 Dec 2022 19:07:04 +0100 Subject: [PATCH 85/99] initial technote writeup --- ...CLM50_Tech_Note_Soil_Snow_Temperatures.rst | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/doc/source/tech_note/Soil_Snow_Temperatures/CLM50_Tech_Note_Soil_Snow_Temperatures.rst b/doc/source/tech_note/Soil_Snow_Temperatures/CLM50_Tech_Note_Soil_Snow_Temperatures.rst index 72040a1514..4430c54fa5 100644 --- a/doc/source/tech_note/Soil_Snow_Temperatures/CLM50_Tech_Note_Soil_Snow_Temperatures.rst +++ b/doc/source/tech_note/Soil_Snow_Temperatures/CLM50_Tech_Note_Soil_Snow_Temperatures.rst @@ -979,3 +979,40 @@ the top layer is a blend of ice and soil heat capacity c_{1} =c_{1}^{*} +\frac{C_{ice} W_{sno} }{\Delta z_{1} } where :math:`c_{1}^{*}` is calculated from :eq:`6.89` or :eq:`6.92`. + + +.. _Excess Ground Ice: + +Excess Ground Ice +------------------------------------ + +An optional parameterization of excess ground ice melt and respective subsidence based on (:ref:`Lee et al., (2014) `). +Initial excess ice concentrations for soil columns are derived from (:ref:`Brown et al., (1997) `). +When the excess ice is present in the soil column soil depth for a given layer (:math:`z_{i}`) +is adjusted be the ammount of excess ice in the column: + +.. math:: + :label: 6.94 + + z_{i}^{'}=\Sigma_{j=1}^{i} \ z_{j}^{'}+\frac{w_{exice,\, j}}{\rho_{ice} } + +where :math:`w_{exice,\,j}` is excess ground ice ammount (kg m :sup:`-2`) in layer :math:`j` and :math:`\rho_{ice}` is the density of ice (kg m :sup:`-3`). +After adjustment of layer depths have been made all of the soil temperature equations (from :eq:`6.80` to :eq:`6.89`) +are calculted based on the adjusted depths. Thermal properties are additionally adjusted (:eq:`6.8` and :eq:`6.8`) in the following way: + +.. math:: + :label: 6.95 + + \begin{array}{lr} + \theta_{sat}^{'} =\frac{\theta _{liq} }{\theta _{liq} +\theta _{ice} +\theta_{exice}}{\theta_{sat}} \\ + \lambda _{sat}^{'} =\lambda _{s}^{1-\theta _{sat}^{'} } \lambda _{liq}^{\frac{\theta _{liq} }{\theta _{liq} +\theta _{ice} +\theta_{exice}} \theta _{sat}^{'} } \lambda _{ice}^{\theta _{sat}^{'} \left(1-\frac{\theta _{liq} }{\theta _{liq} +\theta _{ice} +\theta_{exice}} \right)} \\ + c_{i}^{'} =c_{s,\, i} \left(1-\theta _{sat,\, i}^{'} \right)+\frac{w_{ice,\, i} +w_{exice,\,j}}{\Delta z_{i}^{'} } C_{ice} +\frac{w_{liq,\, i} }{\Delta z_{i}^{'} } C_{liq} + \end{array} + +Soil subsidence at the timestep :math:`n+1` (:math:`z_{exice}^{n+1}`, m) is then calculated as: + +.. math:: + :label: 6.96 + + z_{exice}^{n+1}=\Sigma_{i=1}^{N_{levgrnd}} \ z_{j}^{',\ ,n+1}-z_{j}^{',\ ,n} + From c3fd679c311ea1d0145112a5523d7111881fa63b Mon Sep 17 00:00:00 2001 From: mvdebolskiy <80036033+mvdebolskiy@users.noreply.github.com> Date: Sun, 11 Dec 2022 19:07:16 +0100 Subject: [PATCH 86/99] added references --- .../References/CLM50_Tech_Note_References.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doc/source/tech_note/References/CLM50_Tech_Note_References.rst b/doc/source/tech_note/References/CLM50_Tech_Note_References.rst index 4bd7a2cf9b..46b835a76d 100644 --- a/doc/source/tech_note/References/CLM50_Tech_Note_References.rst +++ b/doc/source/tech_note/References/CLM50_Tech_Note_References.rst @@ -223,6 +223,13 @@ Geosci. Model Dev., 7, 2193-2222, doi:10.5194/gmd-7-2193-2014. Botta, A et al., 2000. A global prognostic scheme of leaf onset using satellite data. Global Change Biology 6.7, pp. 709-725. +.. _Brownetal1997: + +Brown J., Ferrians O. J. Jr, Heginbottom J. A. and Melnikov E. S. 1997. + Circum-Arctic Map of Permafrost and Ground-Ice Conditions +(Boulder, CO: National Snow and Ice Data Center) version 2, +DOI: 10.3133/cp45 + .. _Brun1989: Brun, E. 1989. Investigation of wet-snow metamorphism in respect of @@ -1085,6 +1092,12 @@ Climate 25:3071-3095. DOI:10.1175/JCLI-D-11-00256.1. Lehner, B. and Döll, P., 2004. Development and validation of a global database of lakes, reservoirs and wetlands, J. Hydrol., 296, 1–22. +.. _Leeetal2014: + +Lee, H., Swenson, S.C., Slater A.G. and Lawrence D.M., 2014. Effects +of excess ground ice on projections of permafrost in a warming climate. +Environmental Research Letters 9:12 124006. DOI: 10.1088/1748-9326/9/12/124006 + .. _Lehneretal2008: Lehner, B., Verdin, K. and Jarvis, A., 2008. New global hydrograhy From 60589cd4710510ba4c3d542051b391126156e57a Mon Sep 17 00:00:00 2001 From: mvdebolskiy <80036033+mvdebolskiy@users.noreply.github.com> Date: Mon, 19 Dec 2022 23:12:02 +0100 Subject: [PATCH 87/99] fixed typos, punctuation, added more description --- ...CLM50_Tech_Note_Soil_Snow_Temperatures.rst | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/doc/source/tech_note/Soil_Snow_Temperatures/CLM50_Tech_Note_Soil_Snow_Temperatures.rst b/doc/source/tech_note/Soil_Snow_Temperatures/CLM50_Tech_Note_Soil_Snow_Temperatures.rst index 4430c54fa5..ab10547339 100644 --- a/doc/source/tech_note/Soil_Snow_Temperatures/CLM50_Tech_Note_Soil_Snow_Temperatures.rst +++ b/doc/source/tech_note/Soil_Snow_Temperatures/CLM50_Tech_Note_Soil_Snow_Temperatures.rst @@ -987,17 +987,18 @@ Excess Ground Ice ------------------------------------ An optional parameterization of excess ground ice melt and respective subsidence based on (:ref:`Lee et al., (2014) `). -Initial excess ice concentrations for soil columns are derived from (:ref:`Brown et al., (1997) `). -When the excess ice is present in the soil column soil depth for a given layer (:math:`z_{i}`) -is adjusted be the ammount of excess ice in the column: +Initial excess ground ice concentrations for soil columns are derived from (:ref:`Brown et al., (1997) `). +When the excess ground ice is present in the soil column, soil depth for a given layer (:math:`z_{i}`) +is adjusted by the amount of excess ice in the column: .. math:: :label: 6.94 z_{i}^{'}=\Sigma_{j=1}^{i} \ z_{j}^{'}+\frac{w_{exice,\, j}}{\rho_{ice} } -where :math:`w_{exice,\,j}` is excess ground ice ammount (kg m :sup:`-2`) in layer :math:`j` and :math:`\rho_{ice}` is the density of ice (kg m :sup:`-3`). -After adjustment of layer depths have been made all of the soil temperature equations (from :eq:`6.80` to :eq:`6.89`) +where :math:`w_{exice,\,j}` is excess ground ice amount (kg m :sup:`-2`) in layer :math:`j` +and :math:`\rho_{ice}` is the density of ice (kg m :sup:`-3`). +After adjustment of layer depths have been made, all of the soil temperature equations (from :eq:`6.80` to :eq:`6.89`) are calculted based on the adjusted depths. Thermal properties are additionally adjusted (:eq:`6.8` and :eq:`6.8`) in the following way: .. math:: @@ -1014,5 +1015,14 @@ Soil subsidence at the timestep :math:`n+1` (:math:`z_{exice}^{n+1}`, m) is then .. math:: :label: 6.96 - z_{exice}^{n+1}=\Sigma_{i=1}^{N_{levgrnd}} \ z_{j}^{',\ ,n+1}-z_{j}^{',\ ,n} + z_{exice}^{n+1}=\Sigma_{i=1}^{N_{levgrnd}} \ z_{j}^{',\ ,n+1}-z_{j}^{',\ ,n } + +With regards to hydraulic counductivity, excess ground ice is treated the same way normal soil +ice is treated in :numref:`Frozen Soils and Perched Water Table`. +When a soil layer thaws, excess ground ice is only allowed +to melt when no normals soil ice is present in the layer. +When a soil layer refreezes, liquid soil water can only turn into normal soil ice, thus, no new of excess ice can be created but only melted. +The excess liquid soil moisture from excess ice melt is distributed within the soil column according +to :numref:`Lateral Sub-surface Runoff`. + From 608d2fd977548857cb8dcb7d5809495e9499322b Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Tue, 27 Jun 2023 12:32:42 -0600 Subject: [PATCH 88/99] Change syntax in 5 NEON tests from L10d to Ld10 --- cime_config/testdefs/testlist_clm.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 9421209fe4..2e4742de92 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -1588,7 +1588,7 @@ - + @@ -1598,7 +1598,7 @@ - + @@ -1608,7 +1608,7 @@ - + @@ -1618,7 +1618,7 @@ - + @@ -1629,7 +1629,7 @@ - + From 85eea6b21d6a4f4a42fb04c1c88e42b148d565a8 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 6 Jul 2023 16:29:30 -0600 Subject: [PATCH 89/99] Remove excess ice test from cheyenne aux_clm suite (keep it on izumi) --- cime_config/testdefs/testlist_clm.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 2e4742de92..e8c636efd9 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -179,7 +179,6 @@ - From 65f492ac5a39d58092a248b11bb302d9ce87e59c Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 6 Jul 2023 16:57:03 -0600 Subject: [PATCH 90/99] Adding comment to restart issue handling for issue #1787 --- src/main/restFileMod.F90 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/restFileMod.F90 b/src/main/restFileMod.F90 index 028c609ed4..30b8349778 100644 --- a/src/main/restFileMod.F90 +++ b/src/main/restFileMod.F90 @@ -610,6 +610,8 @@ subroutine restFile_write_issues_fixed(ncid, writing_finidat_interp_dest_file) writing_finidat_interp_dest_file = writing_finidat_interp_dest_file, & issue_num = lake_dynbal_baseline_issue) ! If running with execess ice then mark the restart file as having excess ice fixed + ! This is a permanent feature, i.e. not expected to be removed from here. + ! It would only be removed if we decided to make use_excess_ice = .true. the default. if ( use_excess_ice ) then call write_issue_fixed_metadata( & ncid = ncid, & From d67e3bf5b5019755b875ca7d2f4a960f4e280ed4 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 6 Jul 2023 18:17:20 -0600 Subject: [PATCH 91/99] Declare parameter excess_ice_issue once --- src/main/restFileMod.F90 | 2 +- src/utils/restUtilMod.F90.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/restFileMod.F90 b/src/main/restFileMod.F90 index 30b8349778..6a574406fd 100644 --- a/src/main/restFileMod.F90 +++ b/src/main/restFileMod.F90 @@ -27,6 +27,7 @@ module restFileMod use glcBehaviorMod , only : glc_behavior_type use reweightMod , only : reweight_wrapup use IssueFixedMetadataHandler, only : write_issue_fixed_metadata, read_issue_fixed_metadata + use restUtilMod , only : excess_ice_issue ! ! !PUBLIC TYPES: implicit none @@ -62,7 +63,6 @@ module restFileMod ! Issue numbers for issue-fixed metadata integer, parameter :: lake_dynbal_baseline_issue = 1140 - integer, parameter :: excess_ice_issue = 1787 character(len=*), parameter, private :: sourcefile = & __FILE__ diff --git a/src/utils/restUtilMod.F90.in b/src/utils/restUtilMod.F90.in index 58da88ed50..9b6fe596b1 100644 --- a/src/utils/restUtilMod.F90.in +++ b/src/utils/restUtilMod.F90.in @@ -19,6 +19,7 @@ module restUtilMod implicit none save private + integer, parameter, public :: excess_ice_issue = 1787 ! save ! !----------------------------------------------------------------------- @@ -762,7 +763,6 @@ contains ! ! !LOCAL VARIABLES: integer :: attribute_value - integer, parameter :: excess_ice_issue = 1787 character(len=*), parameter :: subname = 'RestartExcessIceIssue' From 66e2843f2d20cde5f45338a7386b6d829ab9725a Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 7 Jul 2023 17:58:09 -0600 Subject: [PATCH 92/99] Resolved conflict in $ntests BUT DID I PICK THE RIGHT VALUES? --- bld/unit_testers/build-namelist_test.pl | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index e00f69b2c3..590ead1399 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -163,21 +163,9 @@ sub cat_and_create_namelistinfile { # # Figure out number of tests that will run # -<<<<<<< HEAD -my $ntests = 1863; -||||||| 17e2acb6a -my $ntests = 1846; -======= my $ntests = 1975; ->>>>>>> escomp/master if ( defined($opts{'compare'}) ) { -<<<<<<< HEAD - $ntests += 1263; -||||||| 17e2acb6a - $ntests += 1254; -======= $ntests += 1344; ->>>>>>> escomp/master } plan( tests=>$ntests ); From d4be4e29dac703a4027e672f8db0342e019f08a6 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 7 Jul 2023 18:39:43 -0600 Subject: [PATCH 93/99] Format changes to adhere to ctsm coding practices --- src/biogeophys/SoilTemperatureMod.F90 | 67 +++++++++++----------- src/biogeophys/TemperatureType.F90 | 8 +-- src/biogeophys/WaterDiagnosticBulkType.F90 | 58 +++++++++---------- src/biogeophys/WaterStateType.F90 | 12 ++-- 4 files changed, 72 insertions(+), 73 deletions(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index e952614032..50c3cf15e5 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -280,22 +280,22 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter !-------------------------------------------------------------- ! Vertical coordinates adjustment for excess ice calculations !-------------------------------------------------------------- - if ( use_excess_ice )then + if ( use_excess_ice ) then ! Save original soil depth to get put them back in et the end - dz_0(begc:endc,-nlevsno+1:nlevmaxurbgrnd)=dz(begc:endc,-nlevsno+1:nlevmaxurbgrnd) - zi_0(begc:endc,-nlevsno+0:nlevmaxurbgrnd)=zi(begc:endc,-nlevsno+0:nlevmaxurbgrnd) - z_0(begc:endc,-nlevsno+1:nlevmaxurbgrnd)=z(begc:endc,-nlevsno+1:nlevmaxurbgrnd) + dz_0(begc:endc,-nlevsno+1:nlevmaxurbgrnd) = dz(begc:endc,-nlevsno+1:nlevmaxurbgrnd) + zi_0(begc:endc,-nlevsno+0:nlevmaxurbgrnd) = zi(begc:endc,-nlevsno+0:nlevmaxurbgrnd) + z_0(begc:endc,-nlevsno+1:nlevmaxurbgrnd) = z(begc:endc,-nlevsno+1:nlevmaxurbgrnd) ! Adjust column depth for excess ice thickness - do fc = 1,num_nolakec - c = filter_nolakec(fc) - l = col%landunit(c) - if( lun%itype(l) == istsoil .or. lun%itype(l) == istcrop ) then - dz(c,1:nlevmaxurbgrnd)=dz(c,1:nlevmaxurbgrnd)+excess_ice(c,1:nlevmaxurbgrnd)/denice ! add extra layer thickness - do j=1,nlevmaxurbgrnd ! if excess ice amount dropped to zero there will be no adjustment - zi(c,j) = zi(c,j) + sum(excess_ice(c,1:j)) / denice - z(c,j) = (zi(c,j-1) + zi(c,j)) * 0.5_r8 - end do - endif + do fc = 1, num_nolakec + c = filter_nolakec(fc) + l = col%landunit(c) + if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then + dz(c,1:nlevmaxurbgrnd) = dz(c,1:nlevmaxurbgrnd) + excess_ice(c,1:nlevmaxurbgrnd) / denice ! add extra layer thickness + do j = 1, nlevmaxurbgrnd ! if excess ice amount dropped to zero there will be no adjustment + zi(c,j) = zi(c,j) + sum(excess_ice(c,1:j)) / denice + z(c,j) = (zi(c,j-1) + zi(c,j)) * 0.5_r8 + end do + end if end do end if @@ -520,19 +520,18 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter ! Vertical coordinates adjustment for excess ice calculations !-------------------------------------------------------------- ! bringing back the soil depth to the original state - if ( use_excess_ice )then + if (use_excess_ice) then ! Adjust column depth for excess ice thickness - do fc = 1,num_nolakec - c = filter_nolakec(fc) - l = col%landunit(c) - if( lun%itype(l) == istsoil .or. lun%itype(l) == istcrop ) then - dz(c,1:nlevmaxurbgrnd)=dz_0(c,1:nlevmaxurbgrnd) - zi(c,1:nlevmaxurbgrnd)=zi_0(c,1:nlevmaxurbgrnd) - z(c,1:nlevmaxurbgrnd)=z_0(c,1:nlevmaxurbgrnd) - endif + do fc = 1, num_nolakec + c = filter_nolakec(fc) + l = col%landunit(c) + if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then + dz(c,1:nlevmaxurbgrnd)=dz_0(c,1:nlevmaxurbgrnd) + zi(c,1:nlevmaxurbgrnd)=zi_0(c,1:nlevmaxurbgrnd) + z(c,1:nlevmaxurbgrnd)=z_0(c,1:nlevmaxurbgrnd) + end if end do end if - if ( IsProgBuildTemp() )then @@ -1207,13 +1206,13 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & imelt(c,j) = 0 hm(c,j) = 0._r8 xm(c,j) = 0._r8 - xm2(c,j)=0._r8 + xm2(c,j) = 0._r8 wice0(c,j) = h2osoi_ice(c,j) wliq0(c,j) = h2osoi_liq(c,j) - wexice0(c,j)=excess_ice(c,j) + wexice0(c,j) = excess_ice(c,j) wmass0(c,j) = h2osoi_ice(c,j) + h2osoi_liq(c,j) + wexice0(c,j) - if (j>=1) then - exice_subs_col(c,j)=0._r8 + if (j >= 1) then + exice_subs_col(c,j) = 0._r8 endif endif ! end of snow layer if-block @@ -1233,7 +1232,7 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & ! Melting identification ! If ice exists above melt point, melt some to liquid. - if (h2osoi_ice(c,j) > 0._r8 .AND. t_soisno(c,j) > tfrz) then + if (h2osoi_ice(c,j) > 0._r8 .and. t_soisno(c,j) > tfrz) then imelt(c,j) = 1 ! tinc(c,j) = t_soisno(c,j) - tfrz tinc(c,j) = tfrz - t_soisno(c,j) @@ -1406,11 +1405,11 @@ subroutine Phasechange_beta (bounds, num_nolakec, filter_nolakec, dhsdT, & if (j <= 0) then h2osoi_ice(c,j) = min(wmass0(c,j), wice0(c,j)-xm(c,j)) ! snow else - if (wmass0(c,j) - wexice0(c,j) < supercool(c,j)) then !even if excess ice is present, it cannot refreeze - h2osoi_ice(c,j) = 0._r8 - else - h2osoi_ice(c,j) = min(wmass0(c,j) - wexice0(c,j) - supercool(c,j),wice0(c,j)-xm(c,j)) - endif + if (wmass0(c,j) - wexice0(c,j) < supercool(c,j)) then ! even if excess ice is present, it cannot refreeze + h2osoi_ice(c,j) = 0._r8 + else + h2osoi_ice(c,j) = min(wmass0(c,j) - wexice0(c,j) - supercool(c,j),wice0(c,j)-xm(c,j)) + endif endif heatr = hm(c,j) - hfus*(wice0(c,j)-h2osoi_ice(c,j))/dtime endif diff --git a/src/biogeophys/TemperatureType.F90 b/src/biogeophys/TemperatureType.F90 index 995496b388..d20fc862b1 100644 --- a/src/biogeophys/TemperatureType.F90 +++ b/src/biogeophys/TemperatureType.F90 @@ -741,10 +741,10 @@ subroutine InitCold(this, bounds, & end if end if else - this%t_soisno_col(c,1:nlevgrnd) = 274._r8 - if(use_excess_ice .and. (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop)) then - this%t_soisno_col(c,1:nlevgrnd) = SHR_CONST_TKFRZ-5.0_r8 !needs to be below freezing to properly initiate excess ice - end if + this%t_soisno_col(c,1:nlevgrnd) = 274._r8 + if (use_excess_ice .and. (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop)) then + this%t_soisno_col(c,1:nlevgrnd) = SHR_CONST_TKFRZ - 5.0_r8 !needs to be below freezing to properly initiate excess ice + end if endif endif end do diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index 4ec96820b6..ae7af4992e 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -291,23 +291,23 @@ subroutine InitBulkHistory(this, bounds) ptr_col=this%h2osoi_ice_tot_col, l2g_scale_type='veg') ! excess ice vars if (use_excess_ice) then - this%exice_vol_tot_col(begc:endc) = 0.0_r8 - call hist_addfld1d ( & - fname=this%info%fname('TOTEXICE_VOL'), & - units='m3/m3', & - avgflag='A', & - l2g_scale_type='veg', & - long_name=this%info%lname('vertically averaged volumetric excess ice concentration (veg landunits only)'), & - ptr_col=this%exice_vol_tot_col) - - this%exice_subs_tot_col(begc:endc) = 0.0_r8 - call hist_addfld1d ( & - fname=this%info%fname('SUBSIDENCE'), & - units='m', & - avgflag='SUM', & - l2g_scale_type='veg', & - long_name=this%info%lname('subsidence due to excess ice melt (veg landunits only)'), & - ptr_col=this%exice_subs_tot_col) + this%exice_vol_tot_col(begc:endc) = 0.0_r8 + call hist_addfld1d ( & + fname=this%info%fname('TOTEXICE_VOL'), & + units='m3/m3', & + avgflag='A', & + l2g_scale_type='veg', & + long_name=this%info%lname('vertically averaged volumetric excess ice concentration (veg landunits only)'), & + ptr_col=this%exice_vol_tot_col) + + this%exice_subs_tot_col(begc:endc) = 0.0_r8 + call hist_addfld1d ( & + fname=this%info%fname('SUBSIDENCE'), & + units='m', & + avgflag='SUM', & + l2g_scale_type='veg', & + long_name=this%info%lname('subsidence due to excess ice melt (veg landunits only)'), & + ptr_col=this%exice_subs_tot_col) end if this%iwue_ln_patch(begp:endp) = spval @@ -928,14 +928,14 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil units='m', & interpinic_flag='interp', readvar=readvar, data=this%exice_subs_tot_col) if (flag == 'read' .and. ((.not. readvar) .or. (.not. excess_ice_on_restart)) ) then ! when reading restart that does not have excess ice in it - if (nsrest == nsrContinue) then - call endrun(msg = "On a continue run, excess ice fields MUST be on the restart file "// & - errMsg(sourcefile, __LINE__)) - else if ( .not. UseExcessIceStreams() )then - call endrun(msg = "This input initial conditions file does NOT include excess ice fields" // & - ", and use_excess_ice_streams is off, one or the other needs to be changed "// & - errMsg(sourcefile, __LINE__)) - end if + if (nsrest == nsrContinue) then + call endrun(msg = "On a continue run, excess ice fields MUST be on the restart file "// & + errMsg(sourcefile, __LINE__)) + else if ( .not. UseExcessIceStreams() )then + call endrun(msg = "This input initial conditions file does NOT include excess ice fields" // & + ", and use_excess_ice_streams is off, one or the other needs to be changed "// & + errMsg(sourcefile, __LINE__)) + end if this%exice_subs_tot_col(bounds%begc:bounds%endc)=0.0_r8 this%exice_vol_tot_col(bounds%begc:bounds%endc)=0.0_r8 this%exice_subs_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 @@ -947,10 +947,10 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil units='m3/m3', & interpinic_flag='interp', readvar=readvar, data=this%exice_vol_tot_col) if (flag == 'read' .and. ((.not. readvar) .or. (.not. excess_ice_on_restart)) ) then ! when reading restart that does not have excess ice in it - if (nsrest == nsrContinue) then - call endrun(msg = "On a continue run, excess ice fields MUST be on the restart file "// & - errMsg(sourcefile, __LINE__)) - end if + if (nsrest == nsrContinue) then + call endrun(msg = "On a continue run, excess ice fields MUST be on the restart file "// & + errMsg(sourcefile, __LINE__)) + end if end if endif diff --git a/src/biogeophys/WaterStateType.F90 b/src/biogeophys/WaterStateType.F90 index 3018649020..cdbefa2a04 100644 --- a/src/biogeophys/WaterStateType.F90 +++ b/src/biogeophys/WaterStateType.F90 @@ -287,8 +287,8 @@ subroutine InitHistory(this, bounds, use_aquifer_layer) ! Add excess ice fields to history if (use_excess_ice) then - data2dptr => this%excess_ice_col(begc:endc,1:nlevsoi) - call hist_addfld2d (fname='EXCESS_ICE', units='kg/m2', type2d='levsoi', & + data2dptr => this%excess_ice_col(begc:endc,1:nlevsoi) + call hist_addfld2d (fname='EXCESS_ICE', units='kg/m2', type2d='levsoi', & avgflag='A', long_name='excess soil ice (vegetated landunits only)', & ptr_col=this%excess_ice_col, l2g_scale_type='veg', default = 'inactive') end if @@ -744,7 +744,7 @@ subroutine Restart(this, bounds, ncid, flag, & nbedrock = col%nbedrock(c) else nbedrock = nlevsoi - endif + end if do j = 2, nlevmaxurbgrnd ! ignore first layer if(altmax_lastyear_indx(c) < nbedrock) then if (j>altmax_lastyear_indx(c) .and. j Date: Mon, 10 Jul 2023 14:07:24 -0600 Subject: [PATCH 94/99] Change exice_vol_col dimension from nlevgrnd to nlevsoi --- src/biogeophys/WaterDiagnosticBulkType.F90 | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index ae7af4992e..9ecf7208a7 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -17,7 +17,7 @@ module WaterDiagnosticBulkType use decompMod , only : bounds_type use abortutils , only : endrun use clm_varctl , only : use_cn, iulog, use_luna - use clm_varpar , only : nlevgrnd, nlevsno, nlevcan + use clm_varpar , only : nlevgrnd, nlevsno, nlevcan, nlevsoi use clm_varcon , only : spval use LandunitType , only : lun use ColumnType , only : col @@ -201,7 +201,7 @@ subroutine InitBulkAllocate(this, bounds) allocate(this%swe_old_col (begc:endc,-nlevsno+1:0)) ; this%swe_old_col (:,:) = nan allocate(this%exice_subs_tot_col (begc:endc)) ; this%exice_subs_tot_col (:) = 0.0_r8 allocate(this%exice_subs_col (begc:endc, 1:nlevmaxurbgrnd)) ; this%exice_subs_col (:,:) = 0.0_r8 - allocate(this%exice_vol_col (begc:endc, 1:nlevgrnd)) ; this%exice_vol_col (:,:) = 0.0_r8 + allocate(this%exice_vol_col (begc:endc, 1:nlevsoi)) ; this%exice_vol_col (:,:) = 0.0_r8 allocate(this%exice_vol_tot_col (begc:endc)) ; this%exice_vol_tot_col (:) = 0.0_r8 allocate(this%snw_rds_col (begc:endc,-nlevsno+1:0)) ; this%snw_rds_col (:,:) = nan @@ -912,11 +912,11 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil this%exice_subs_tot_col(bounds%begc:bounds%endc)=0.0_r8 this%exice_vol_tot_col(bounds%begc:bounds%endc)=0.0_r8 this%exice_subs_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 - this%exice_vol_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 + this%exice_vol_col(bounds%begc:bounds%endc,1:nlevsoi)=0.0_r8 else ! initialization of these to zero is ok, since they might not be in the restart file this%exice_subs_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 - this%exice_vol_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 + this%exice_vol_col(bounds%begc:bounds%endc,1:nlevsoi)=0.0_r8 call RestartExcessIceIssue( & ncid = ncid, & flag = flag, & @@ -939,7 +939,7 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil this%exice_subs_tot_col(bounds%begc:bounds%endc)=0.0_r8 this%exice_vol_tot_col(bounds%begc:bounds%endc)=0.0_r8 this%exice_subs_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 - this%exice_vol_col(bounds%begc:bounds%endc,1:nlevgrnd)=0.0_r8 + this%exice_vol_col(bounds%begc:bounds%endc,1:nlevsoi)=0.0_r8 endif call restartvar(ncid=ncid, flag=flag, varname=this%info%fname('TOTEXICE_VOL'), & dim1name='column', xtype=ncd_double, & @@ -1058,7 +1058,6 @@ subroutine Summary(this, bounds, & ! Compute end-of-timestep summaries of water diagnostic terms ! ! !USES: - use clm_varpar , only : nlevsoi use clm_varcon , only : denice use landunit_varcon, only : istsoil, istcrop ! !ARGUMENTS: From 62b376b67b4be7f8c36d89cfe04cd4568c82201b Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 10 Jul 2023 14:13:26 -0600 Subject: [PATCH 95/99] Update $ntests following @ekluzek's suggestion (not tested, yet) --- bld/unit_testers/build-namelist_test.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index 590ead1399..82a178bf03 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -163,9 +163,9 @@ sub cat_and_create_namelistinfile { # # Figure out number of tests that will run # -my $ntests = 1975; +my $ntests = 1992; if ( defined($opts{'compare'}) ) { - $ntests += 1344; + $ntests += 1353; } plan( tests=>$ntests ); From 97632977d46469948416faf30acb19c37d04bd24 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 28 Jul 2023 12:49:38 -0600 Subject: [PATCH 96/99] First draft of ChangeLog/Sum --- doc/ChangeLog | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++ doc/ChangeSum | 1 + 2 files changed, 114 insertions(+) diff --git a/doc/ChangeLog b/doc/ChangeLog index ec7f8303a1..ed78cea5eb 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,4 +1,117 @@ =============================================================== +Tag name: ctsm5.1.dev133 +Originator(s): mvdebolskiy (NORCE, Bergen, Norway), slevis (Samuel Levis,UCAR/TSS,303-665-1310) +Date: Thu Jul 27 17:30:25 MDT 2023 +One-line Summary: Add parameterization to allow excess ice in soil and subsidence + +Purpose and description of changes +---------------------------------- + +As described in PR #1787: + +Parameterization for excess ice described in Lee et al. (2014): +http://dx.doi.org/10.1088/1748-9326/9/12/124006 + +This code is a modified version of code provided by Lei Cai: +https://github.com/lca041/ctsm/tree/clm5.0.dev92_exice + +Works only for the nuopc driver. + +Files changed: +bld/CLMBuildNamelist.pm, bld/namelist_files/namelist_defaults_ctsm.xml, bld/namelist_files/namelist_definitionss_ctsm.xml -- added namelist options; +src/main/clm_varctl.F90, src/main/controlMod.F90 -- added option to switch excess ice physics and read namelist option; +src/biogeophys/WaterStateType.F90 -- added prognostic excess ice variable and a history field; +src/biogeophys/WaterStateBulkType.F90, src/main/clm_instMod.F90, -- added arguments to soubrutiens for proper initialization; +src/biogeophys/TemperatureType.F90 -- initial soil temperature set to 268.15 K at the cold start (possibly redundant because #1460 is closed) +src/biogeophys/WaterDiagnosticBulkType.F90 -- added two diagnostic excess ice variables and two history fields; +src/biogeophys/SoilTemperatureMod.F90 -- added main excess ice calculations; +src/biogeophys/TotalWaterAndHeatMod.F90 -- added excess ice to total water for balance checks; +src/biogeophys/SoilHydrologyMod.F90 -- added excess ice for ice fraction calculation; + +New files: +src/cpl/share_esmf/ExcessIceStreamType.F90 -- routines to read dataset with initial excess ice concentration + + +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_1 + +[ ] clm5_0 + +[ ] ctsm5_0-nwp + +[ ] clm4_5 + + +Bugs fixed or introduced +------------------------ +CTSM issues fixed (include CTSM Issue #): +#1229 + + +Notes of particular relevance for users +--------------------------------------- +Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables): + New namelist options added: + - use_excess_ice (logical, in clm_inparm) default = .false.; turns on excess ice physics + - stream_meshfile_exice, stream_fldfilename_exice, stream_mapalgo_exice (char, in exice_streams) + meshfile, stream file, spatial interpolation algorithm for initial values of excess ice + defaults - lnd/clm2/paramdata/exice_init_0.125x0.125_ESMFmesh_c20220516.nc, + lnd/clm2/paramdata/exice_init_0.125x0.125_c20220516.nc + and bilinear + Dataset interpolated to 0.125x0.125 degrees grid from Brown et al. (1997) can be found here: + https://drive.google.com/file/d/1mA457Oa52zG_MtLGB7KHuUYQvsS2-P5o/view?usp=sharing + Dataset used only in cold start or hybrid runs (or starting with finidat) that do not have excess ice + + +Notes of particular relevance for developers: +--------------------------------------------- +Changes to tests or testing: + New tests in place for this new code + +Testing summary: +---------------- +[Remove any lines that don't apply.] + + [PASS means all tests PASS; OK means tests PASS other than expected fails.] + + build-namelist tests (if CLMBuildNamelist.pm has changed): + + cheyenne - PASS + + tools-tests (test/tools) (if tools have been changed): + + cheyenne - + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + cheyenne ---- OK + izumi ------- OK + + any other testing (give details below): + +If the tag used for baseline comparisons was NOT the previous tag, note that here: + + +Answer changes +-------------- + +Changes answers relative to baseline: No + + +Other details +------------- +Pull Requests that document the changes (include PR ids): + https://github.com/ESCOMP/ctsm/pull/1787 + +=============================================================== +=============================================================== Tag name: ctsm5.1.dev131 Originator(s): samrabin (Sam Rabin,UCAR/TSS) Date: Thu Jul 27 14:24:07 MDT 2023 diff --git a/doc/ChangeSum b/doc/ChangeSum index 2d1812cd13..a1a326e65a 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,5 +1,6 @@ Tag Who Date Summary ============================================================================================================================ + ctsm5.1.dev133 slevis 07/27/2023 Add parameterization to allow excess ice in soil and subsidence ctsm5.1.dev131 samrabin 07/27/2023 Enable prescribed crop calendars ctsm5.1.dev130 glemieux 07/09/2023 FATES parameter file and test definition update ctsm5.1.dev129 erik 06/22/2023 NEON fixes for TOOL and user-mods, add SP for NEON, some history file updates, black refactor for buildlib/buildnml From 34900bcc237f09be7f8f491f5361aac193911ea9 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 3 Aug 2023 17:21:11 -0600 Subject: [PATCH 97/99] Corrected new tag number in ChangeLog/Sum --- doc/ChangeLog | 4 ++-- doc/ChangeSum | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index ed78cea5eb..fb58cbfb90 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,7 +1,7 @@ =============================================================== -Tag name: ctsm5.1.dev133 +Tag name: ctsm5.1.dev132 Originator(s): mvdebolskiy (NORCE, Bergen, Norway), slevis (Samuel Levis,UCAR/TSS,303-665-1310) -Date: Thu Jul 27 17:30:25 MDT 2023 +Date: Thu Aug 3 17:03:44 MDT 2023 One-line Summary: Add parameterization to allow excess ice in soil and subsidence Purpose and description of changes diff --git a/doc/ChangeSum b/doc/ChangeSum index a1a326e65a..9cfa433000 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,6 +1,6 @@ Tag Who Date Summary ============================================================================================================================ - ctsm5.1.dev133 slevis 07/27/2023 Add parameterization to allow excess ice in soil and subsidence + ctsm5.1.dev132 slevis 08/03/2023 Add parameterization to allow excess ice in soil and subsidence ctsm5.1.dev131 samrabin 07/27/2023 Enable prescribed crop calendars ctsm5.1.dev130 glemieux 07/09/2023 FATES parameter file and test definition update ctsm5.1.dev129 erik 06/22/2023 NEON fixes for TOOL and user-mods, add SP for NEON, some history file updates, black refactor for buildlib/buildnml From 4905a09bf2a5529658c1349aa98728af0de34ee7 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 4 Aug 2023 13:09:45 -0600 Subject: [PATCH 98/99] Rm test that I prob. reintroduced when resolving conflicts: ERI_D_Ld9_P48x1_Vmct --- cime_config/testdefs/testlist_clm.xml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index feb5f52033..aa5dd98697 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -158,15 +158,6 @@ - - - - - - - - - From 29816874e2b6ce922a85d8e7cc3238d93f95affd Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 4 Aug 2023 17:59:23 -0600 Subject: [PATCH 99/99] Update change files --- doc/ChangeLog | 10 ++++++++-- doc/ChangeSum | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index fb58cbfb90..7fa07e58cf 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,7 +1,7 @@ =============================================================== Tag name: ctsm5.1.dev132 Originator(s): mvdebolskiy (NORCE, Bergen, Norway), slevis (Samuel Levis,UCAR/TSS,303-665-1310) -Date: Thu Aug 3 17:03:44 MDT 2023 +Date: Fri Aug 4 17:52:45 MDT 2023 One-line Summary: Add parameterization to allow excess ice in soil and subsidence Purpose and description of changes @@ -52,11 +52,17 @@ Does this tag change answers significantly for any of the following physics conf Bugs fixed or introduced ------------------------ CTSM issues fixed (include CTSM Issue #): -#1229 + Fixes #1229 -- excess ice Notes of particular relevance for users --------------------------------------- + +Caveats for users (e.g., need to interpolate initial conditions): + Excess ice can EITHER be turned on by using the stream file, OR a restart file that has excess ice on it. + Since, excess ice is expected to melt as time goes on, the use of a restart file is preferred. + But, use of a restart file requires a simulation that was spun up to that point. + Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables): New namelist options added: - use_excess_ice (logical, in clm_inparm) default = .false.; turns on excess ice physics diff --git a/doc/ChangeSum b/doc/ChangeSum index 9cfa433000..1702a919d0 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,6 +1,6 @@ Tag Who Date Summary ============================================================================================================================ - ctsm5.1.dev132 slevis 08/03/2023 Add parameterization to allow excess ice in soil and subsidence + ctsm5.1.dev132 slevis 08/04/2023 Add parameterization to allow excess ice in soil and subsidence ctsm5.1.dev131 samrabin 07/27/2023 Enable prescribed crop calendars ctsm5.1.dev130 glemieux 07/09/2023 FATES parameter file and test definition update ctsm5.1.dev129 erik 06/22/2023 NEON fixes for TOOL and user-mods, add SP for NEON, some history file updates, black refactor for buildlib/buildnml