From e44c19d5959d7d1cdfe82b7047fcca263a6e0280 Mon Sep 17 00:00:00 2001 From: ivanderkelen Date: Mon, 24 Aug 2020 06:16:59 -0600 Subject: [PATCH 1/4] Remove temperature_inst%lake_heat as not used, remove comments on saving lake heat in LakeTemperatureMod --- src/biogeophys/LakeTemperatureMod.F90 | 6 +----- src/biogeophys/TemperatureType.F90 | 3 --- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/biogeophys/LakeTemperatureMod.F90 b/src/biogeophys/LakeTemperatureMod.F90 index 6a20856f67..280020b6ef 100644 --- a/src/biogeophys/LakeTemperatureMod.F90 +++ b/src/biogeophys/LakeTemperatureMod.F90 @@ -248,7 +248,6 @@ subroutine LakeTemperature(bounds, num_lakec, filter_lakec, num_lakep, filter_la t_grnd => temperature_inst%t_grnd_col , & ! Input: [real(r8) (:) ] ground temperature (Kelvin) t_soisno => temperature_inst%t_soisno_col , & ! Output: [real(r8) (:,:) ] soil (or snow) temperature (Kelvin) t_lake => temperature_inst%t_lake_col , & ! Output: [real(r8) (:,:) ] col lake temperature (Kelvin) - lake_heat => temperature_inst%lake_heat , & ! Output: [real(r8) (:) ] col lake heat (J/m²) beta => lakestate_inst%betaprime_col , & ! Output: [real(r8) (:) ] col effective beta: sabg_lyr(p,jtop) for snow layers, beta otherwise lake_icefrac => lakestate_inst%lake_icefrac_col , & ! Output: [real(r8) (:,:) ] col mass fraction of lake layer that is frozen @@ -1004,10 +1003,7 @@ subroutine LakeTemperature(bounds, num_lakec, filter_lakec, num_lakep, filter_la end do end do - ! write(iulog,*)'Energy content of lake after calculating lake temperature (J/m²)', ncvts - - ! IV: currently commented out: caused crash. To do: look at this part of the code!!! - ! lake_heat(c) = ncvts(c) + call waterstatebulk_inst%CalculateTotalH2osno(bounds, num_lakec, filter_lakec, & caller = 'LakeTemperature-2', & diff --git a/src/biogeophys/TemperatureType.F90 b/src/biogeophys/TemperatureType.F90 index 5dacf3fa55..b165ed0796 100644 --- a/src/biogeophys/TemperatureType.F90 +++ b/src/biogeophys/TemperatureType.F90 @@ -116,9 +116,6 @@ module TemperatureType real(r8), pointer :: xmf_h2osfc_col (:) ! latent heat of phase change of surface water real(r8), pointer :: fact_col (:,:) ! used in computing tridiagonal matrix real(r8), pointer :: c_h2osfc_col (:) ! heat capacity of surface water - - ! lake heat - real(r8), pointer :: lake_heat (:) ! total heat of lake water (J/m²) contains From 2bfb8d7d39cd07469919dd04c402df5cb3e43a82 Mon Sep 17 00:00:00 2001 From: ivanderkelen Date: Mon, 24 Aug 2020 07:36:17 -0600 Subject: [PATCH 2/4] Add description on dynamical lakes for AdjustDeltaHeatForDeltaLiq module and clean up --- src/biogeophys/TotalWaterAndHeatMod.F90 | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/biogeophys/TotalWaterAndHeatMod.F90 b/src/biogeophys/TotalWaterAndHeatMod.F90 index e5f5b17fa7..6e4ae8624d 100644 --- a/src/biogeophys/TotalWaterAndHeatMod.F90 +++ b/src/biogeophys/TotalWaterAndHeatMod.F90 @@ -1093,7 +1093,7 @@ subroutine AccumulateHeatLake(bounds, num_c, filter_c, & end do end do - ! add ice heat and liquid heat together (look at this part) + ! add ice heat and liquid heat together do fc = 1, num_c c = filter_c(fc) heat(c) = heat(c) + lake_heat_ice(c) + & @@ -1130,11 +1130,15 @@ subroutine AdjustDeltaHeatForDeltaLiq(bounds, delta_liq, & ! ice runoff is at heat_base_temp (which is reasonable as long as heat_base_temp = ! tfrz). ! + ! With dynamical lakes, the adjusted delta_heat does not account for the added lake + ! water content due to growing lakes. This is because lake depth is constant, the + ! total lake water content (kg/m^2) does not change. The change in water content of + ! the snow and soil in the lake column are accounted for. + ! ! Eventually, if we begin to explicitly account for the temperature / heat content of ! liquid and ice runoff in CLM, then this routine should be reworked to use the true ! heat contents of both liquid and ice runoff. ! - ! ADD HERE NOTES ABOUT LAKES!!! lake water not accounted. because baselines ! ! Sign convention: delta_liq and delta_heat are positive if the post-landcover change ! value is greater than the pre-landcover change value. From e37d269fe0e98e1aa0fd223196ea02e87fc59328 Mon Sep 17 00:00:00 2001 From: ivanderkelen Date: Mon, 24 Aug 2020 08:49:02 -0600 Subject: [PATCH 3/4] remove lake_heat allocation and history field --- src/biogeophys/TemperatureType.F90 | 7 ------- src/biogeophys/TotalWaterAndHeatMod.F90 | 1 - 2 files changed, 8 deletions(-) diff --git a/src/biogeophys/TemperatureType.F90 b/src/biogeophys/TemperatureType.F90 index b165ed0796..d9ef9f5cb6 100644 --- a/src/biogeophys/TemperatureType.F90 +++ b/src/biogeophys/TemperatureType.F90 @@ -279,7 +279,6 @@ subroutine InitAllocate(this, bounds) allocate(this%fact_col (begc:endc, -nlevsno+1:nlevgrnd)) ; this%fact_col (:,:) = nan allocate(this%c_h2osfc_col (begc:endc)) ; this%c_h2osfc_col (:) = nan - allocate(this%lake_heat (begc:endc)) ; this%lake_heat (:) = nan end subroutine InitAllocate !------------------------------------------------------------------------ @@ -621,12 +620,6 @@ subroutine InitHistory(this, bounds, is_simple_buildtemp, is_prog_buildtemp ) ptr_patch=this%t_veg10_night_patch, default='inactive') endif - ! add lake heat history field here - this%lake_heat(begc:endc) = spval - call hist_addfld1d (fname='LAKE_HEAT', units='J/m^2', & - avgflag='A', long_name='Heat content of gridcell lake water', & - ptr_col=this%lake_heat, default='active') - end subroutine InitHistory !----------------------------------------------------------------------- diff --git a/src/biogeophys/TotalWaterAndHeatMod.F90 b/src/biogeophys/TotalWaterAndHeatMod.F90 index 6e4ae8624d..b774fe9761 100644 --- a/src/biogeophys/TotalWaterAndHeatMod.F90 +++ b/src/biogeophys/TotalWaterAndHeatMod.F90 @@ -919,7 +919,6 @@ subroutine ComputeHeatLake(bounds, num_lakec, filter_lakec, & csol => soilstate_inst%csol_col, & ! heat capacity, soil solids (J/m**3/Kelvin) t_soisno => temperature_inst%t_soisno_col, & ! soil temperature (Kelvin) dynbal_baseline_heat => temperature_inst%dynbal_baseline_heat_col, & ! Input: [real(r8) (:) ] baseline heat content subtracted from each column's total heat calculation (J/m2) - lake_heat => temperature_inst%lake_heat, & ! total heat of lake water (J/m²) h2osoi_liq => waterstatebulk_inst%h2osoi_liq_col, & ! liquid water (kg/m2) h2osoi_ice => waterstatebulk_inst%h2osoi_ice_col & ! frozen water (kg/m2) ) From 30394f88b806ddc6f349572efc45e5fe000a83df Mon Sep 17 00:00:00 2001 From: ivanderkelen Date: Mon, 24 Aug 2020 10:09:06 -0600 Subject: [PATCH 4/4] Move code to read lakemask to surfd_lakemask routine and clean up --- src/main/surfrdMod.F90 | 75 +++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/src/main/surfrdMod.F90 b/src/main/surfrdMod.F90 index af092daa6b..b9d2e1bb3d 100644 --- a/src/main/surfrdMod.F90 +++ b/src/main/surfrdMod.F90 @@ -292,9 +292,10 @@ subroutine surfrd_get_data (begg, endg, ldomain, lfsurdat, actual_numcft) use fileutils , only : getfil use domainMod , only : domain_type, domain_init, domain_clean use clm_instur , only : wt_lunit, topo_glc_mec - use landunit_varcon, only: max_lunit, istsoil, isturb_MIN, isturb_MAX + use landunit_varcon , only : max_lunit, istsoil, isturb_MIN, isturb_MAX use dynSubgridControlMod, only : get_flanduse_timeseries - use clm_varctl , only : fname_len + use dynSubgridControlMod, only : get_do_transient_lakes + ! ! !ARGUMENTS: integer, intent(in) :: begg, endg, actual_numcft @@ -312,10 +313,8 @@ subroutine surfrd_get_data (begg, endg, ldomain, lfsurdat, actual_numcft) logical :: readvar ! true => variable is on dataset real(r8) :: rmaxlon,rmaxlat ! local min/max vars type(file_desc_t) :: ncid ! netcdf id - type(file_desc_t) :: ncid_dynuse ! netcdf id for landuse timeseries file logical :: istype_domain ! true => input file is of type domain logical :: isgrid2d ! true => intut grid is 2d - character(len=fname_len) :: fdynuse ! landuse.timeseries filename character(len=32) :: subname = 'surfrd_get_data' ! subroutine name !----------------------------------------------------------------------- @@ -450,33 +449,11 @@ subroutine surfrd_get_data (begg, endg, ldomain, lfsurdat, actual_numcft) write(iulog,*) end if + ! read the lakemask (necessary for initialisation of dynamical lakes) + if (get_do_transient_lakes()) then + call surfrd_lakemask(begg, endg) + end if - ! IV: add here call to subroutine to read in lake mask (necessary for initialisation of dynamical lakes) - ! First open landuse.timeseries file for this. - - if (masterproc) then - write(iulog,*) 'Attempting to read landuse.timeseries data .....' - if (lfsurdat == ' ') then - write(iulog,*)'fdynuse must be specified' - call endrun(msg=errMsg(sourcefile, __LINE__)) - endif - endif - - - ! open landuse_timeseries file - fdynuse = get_flanduse_timeseries() - - call getfil(fdynuse, locfn, 0 ) - - call ncd_pio_openfile (ncid_dynuse, trim(locfn), 0) - - ! read the lakemask - call surfrd_lakemask(begg, endg, ncid_dynuse) - - ! close landuse_timeseries file again - call ncd_pio_closefile(ncid_dynuse) - - end subroutine surfrd_get_data !----------------------------------------------------------------------- @@ -979,7 +956,7 @@ subroutine surfrd_veg_dgvm(begg, endg) end subroutine surfrd_veg_dgvm !----------------------------------------------------------------------- - subroutine surfrd_lakemask(begg, endg, ncid) + subroutine surfrd_lakemask(begg, endg) ! ! !DESCRIPTION: ! Reads the lake mask, indicating where lakes are and will grow @@ -987,25 +964,47 @@ subroutine surfrd_lakemask(begg, endg, ncid) ! Necessary for the initialisation of the lake land units ! ! !USES: - use clm_instur , only : haslake + use clm_instur , only : haslake + use dynSubgridControlMod , only : get_flanduse_timeseries + use clm_varctl , only : fname_len + use fileutils , only : getfil + ! ! !ARGUMENTS: integer, intent(in) :: begg, endg - type(file_desc_t), intent(inout) :: ncid ! ! ! !LOCAL VARIABLES: - logical :: readvar - real(r8),pointer :: haslake_id(:) - ! + type(file_desc_t) :: ncid_dynuse ! netcdf id for landuse timeseries file + character(len=256) :: locfn ! local file name + character(len=fname_len) :: fdynuse ! landuse.timeseries filename + logical :: readvar + real(r8),pointer :: haslake_id(:) ! character(len=*), parameter :: subname = 'surfrd_lakemask' ! !----------------------------------------------------------------------- + ! get filename of landuse_timeseries file + fdynuse = get_flanduse_timeseries() + + if (masterproc) then + write(iulog,*) 'Attempting to read landuse.timeseries data .....' + if (fdynuse == ' ') then + write(iulog,*)'fdynuse must be specified' + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if + end if + + call getfil(fdynuse, locfn, 0 ) + + ! open landuse_timeseries file + call ncd_pio_openfile (ncid_dynuse, trim(locfn), 0) + allocate(haslake_id(begg:endg)) - call ncd_io(ncid=ncid, varname='HASLAKE' , flag='read', data=haslake_id, & + ! read the lakemask + call ncd_io(ncid=ncid_dynuse, varname='HASLAKE' , flag='read', data=haslake_id, & dim1name=grlnd, readvar=readvar) if (.not. readvar) call endrun( msg=' ERROR: HASLAKE is not on landuse.timeseries file'//errMsg(sourcefile, __LINE__)) @@ -1015,6 +1014,8 @@ subroutine surfrd_lakemask(begg, endg, ncid) haslake = .false. end where + ! close landuse_timeseries file again + call ncd_pio_closefile(ncid_dynuse) deallocate(haslake_id)