Skip to content

Commit

Permalink
Merge branch 'has_urban'
Browse files Browse the repository at this point in the history
Implement PCT_URBAN_MAX to minimize dynamic urban memory

Read in 'PCT_URBAN_MAX' from the landuse timeseries file (maximum urban
percentage throughout timeseries) and initialize urban landunits in
memory only where PCT_URBAN_MAX is greater than zero.

Resolves #1572 (Improve mechanism for determining where to
allocate memory for urban when running with dynamic urban)
  • Loading branch information
billsacks committed Mar 8, 2022
2 parents 157f719 + 2caf9ee commit bf958ac
Show file tree
Hide file tree
Showing 9 changed files with 230 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
; NCL script
; modify_smallville_with_dynurban.ncl
; Keith Oleson, Dec 2021
; Purpose is to create a dynamic urban file for the smallville grid for test
; Feb 23, 2022: Change HASURBAN to PCT_URBAN_MAX. The output file date has been updated from
; c211206 to c220223.
; Purpose is to create a transient landuse file for the smallville grid for dynamic urban testing
; ERS_Lm25.1x1_smallvilleIA.IHistClm50BgcCropQianRs.cheyenne_gnu.clm-smallville_dynurban_monthly
;**************************************

Expand All @@ -17,7 +19,7 @@ begin
print ("=========================================")

infile = "/glade/p/cgd/tss/people/oleson/modify_surfdata/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_c160127.nc"
outfile = "/glade/p/cgd/tss/people/oleson/modify_surfdata/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_dynUrban_c211206.nc"
outfile = "/glade/p/cgd/tss/people/oleson/modify_surfdata/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_dynUrban_c220223.nc"

system("cp " + infile + " " + outfile)

Expand All @@ -37,24 +39,29 @@ begin
pct_urban@units = "unitless"
printVarSummary(pct_urban)

hasurban = new((/numurbl,dimsizes(pct_crop(0,:,0)),dimsizes(pct_crop(0,0,:))/),double,"No_FillValue")
hasurban!0 = pct_urban!1
hasurban!1 = pct_urban!2
hasurban!2 = pct_urban!3
hasurban = 1.d
printVarSummary(hasurban)

pct_urban(:,0,0,0) = (/0.d,20.d,10.d,10.d,10.d,10.d/)
pct_urban(:,1,0,0) = (/0.d,15.d, 8.d, 8.d, 8.d, 8.d/)
pct_urban(:,2,0,0) = (/0.d,10.d, 5.d, 5.d, 5.d, 5.d/)
;pct_urban(:,2,0,0) = (/0.d,10.d, 5.d, 5.d, 5.d, 5.d/)
pct_urban(:,2,0,0) = (/0.d, 0.d, 0.d, 0.d, 0.d, 0.d/)

pct_urban_max = new((/numurbl,dimsizes(pct_crop(0,:,0)),dimsizes(pct_crop(0,0,:))/),double,"No_FillValue")
pct_urban_max!0 = pct_urban!1
pct_urban_max!1 = pct_urban!2
pct_urban_max!2 = pct_urban!3
pct_urban_max(0,:,:) = max(pct_urban(:,0,0,0))
pct_urban_max(1,:,:) = max(pct_urban(:,1,0,0))
pct_urban_max(2,:,:) = max(pct_urban(:,2,0,0))
printVarSummary(pct_urban_max)
pct_urban_max@units = "unitless"
pct_urban_max@long_name = "maximum percent urban for each density type (tbd, hd, md)"

pct_crop(:,0,0) = (/0.,25.,12.,12.,12.,12./)

outf->HASURBAN = hasurban
outf->PCT_URBAN_MAX = pct_urban_max
outf->PCT_URBAN = pct_urban
outf->PCT_CROP = pct_crop

outf@history = "This file was created with the following NCL script: /glade/p/cgd/tss/people/oleson/modify_surfdata/modify_smallville_with_dynurban.ncl. The file used as a template is: /glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_c160127.nc. Key points are that urban area starts as 0, increases after the first year, then decreases after the second year. PCT_CROP is also changed so that PCT_URBAN + PCT_CROP <= 100. (Here, PCT_CROP increases and decreases at the same time as PCT_URBAN in order to exercise the simultaneous increase or decrease of two landunits, but that isn't a critical part of this test.). Note that the use of this file means that this testmod can only be used with the 1x1_smallvilleIA grid."
outf@history = "This file was created with the following NCL script: /glade/p/cgd/tss/people/oleson/modify_surfdata/modify_smallville_with_dynurban.ncl. The file used as a template is: /glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_c160127.nc. Key points are that urban area starts as 0, increases after the first year, then decreases after the second year. Medium density urban is set to zero to test the memory-saving behavior of PCT_URBAN_MAX. PCT_CROP is also changed so that PCT_URBAN + PCT_CROP <= 100. (Here, PCT_CROP increases and decreases at the same time as PCT_URBAN in order to exercise the simultaneous increase or decrease of two landunits, but that isn't a critical part of this test.). Note that the use of this file means that this testmod can only be used with the 1x1_smallvilleIA grid."

print ("=========================================")
print ("Finish Time: "+systemfunc("date") )
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
do_transient_urban = .true.
!KO The following run_zero_weight_urban setting is temporary until the HASURBAN methdology is implemented.
run_zero_weight_urban = .true.

! This file was created with the following NCL script:
! The flanduse_timeseries file was created with the following NCL script (a copy of this script is in cime_config/testdefs/testmods_dirs/clm/smallville_dynurban_monthly):
! /glade/p/cgd/tss/people/oleson/modify_surfdata/modify_smallville_with_dynurban.ncl
! The file used as a template is:
! /glade/p/cesm/cseg/inputdata/lnd/clm2/surfdata_map/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_c160127.nc
! Key points are that urban area starts as 0, increases after the first year, then decreases after the second year.
! Medium density urban is set to zero to test the memory-saving behavior of PCT_URBAN_MAX.
! PCT_CROP is also changed so that PCT_URBAN + PCT_CROP <= 100. (Here, PCT_CROP increases and decreases at the same time as PCT_URBAN in order to exercise the simultaneous increase or decrease of two landunits, but that isn't a critical part of this test.)
! Note that the use of this file means that this testmod can only be used with the 1x1_smallvilleIA grid.
flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_map/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_dynUrban_c211206.nc'
! Feb 23, 2022: Use updated file with HASURBAN replaced by PCT_URBAN_MAX
!flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_map/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_dynUrban_c220223.nc'
flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_map/landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_dynUrban_c220223.nc'
65 changes: 65 additions & 0 deletions doc/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,4 +1,69 @@
===============================================================
Tag name: ctsm5.1.dev083
Originator(s): fang-bowen (Bowen Fang) / oleson (Keith Oleson,UCAR/TSS,303-497-1332)
/ Face2sea (Lei Zhao) / keerzhang1 (Keer Zhang) / sacks (Bill Sacks)
Date: Tue Mar 8 14:12:00 MST 2022
One-line Summary: Implement PCT_URBAN_MAX to minimize dynamic urban memory

Purpose and description of changes
----------------------------------

Read in 'PCT_URBAN_MAX' from the landuse timeseries file (maximum urban percentage throughout
timeseries) and initialize urban landunits in memory only where PCT_URBAN_MAX is greater than zero.

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
------------------------

Issues fixed (include CTSM Issue #):
- Resolves ESCOMP/CTSM#1572 (Improve mechanism for determining where to
allocate memory for urban when running with dynamic urban)

Notes of particular relevance for developers:
---------------------------------------------
NOTE: Be sure to review the steps in README.CHECKLIST.master_tags as well as the coding style in the Developers Guide

Changes to tests or testing:
ERS_Lm25.1x1_smallvilleIA.IHistClm50BgcCropQianRs.cheyenne_gnu.clm-smallville_dynurban_monthly has
been updated to accomodate PCT_URBAN_MAX

Testing summary:
----------------

regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing):

cheyenne ---- PASS
izumi ------- PASS

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/1661

===============================================================
===============================================================
Tag name: ctsm5.1.dev082
Originator(s): slevis (Samuel Levis,SLevis Consulting,303-665-1310)
Date: Mon Feb 28 10:12:16 MST 2022
Expand Down
1 change: 1 addition & 0 deletions doc/ChangeSum
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
Tag Who Date Summary
============================================================================================================================
ctsm5.1.dev083 multiple 03/08/2022 Implement PCT_URBAN_MAX to minimize dynamic urban memory
ctsm5.1.dev082 slevis 02/28/2022 Replace dom_nat_pft with dom_plant to enable crop in fsurdat_modifier tool
ctsm5.1.dev081 swensosc 02/24/2022 Do not subtract irrigation from QRUNOFF diagnostic
ctsm5.1.dev080 sacks 02/24/2022 Use avg days per year when converting param units
Expand Down
8 changes: 5 additions & 3 deletions src/main/clm_initializeMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module clm_initializeMod
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_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 clm_instur , only : irrig_method, wt_glc_mec, topo_glc_mec, haslake, pct_urban_max
use perf_mod , only : t_startf, t_stopf
use readParamsMod , only : readParameters
use ncdio_pio , only : file_desc_t
Expand Down Expand Up @@ -122,7 +122,7 @@ subroutine initialize2(ni,nj)
use clm_varctl , only : use_cn, use_fates
use clm_varctl , only : use_crop, ndep_from_cpl, fates_spitfire_mode
use clm_varorb , only : eccen, mvelpp, lambm0, obliqr
use landunit_varcon , only : landunit_varcon_init, max_lunit
use landunit_varcon , only : landunit_varcon_init, max_lunit, numurbl
use pftconMod , only : pftcon
use decompInitMod , only : decompInit_clumps, decompInit_glcp
use domainMod , only : domain_check, ldomain, domain_init
Expand Down Expand Up @@ -215,6 +215,7 @@ subroutine initialize2(ni,nj)
allocate (wt_glc_mec (begg:endg, maxpatch_glc ))
allocate (topo_glc_mec (begg:endg, maxpatch_glc ))
allocate (haslake (begg:endg ))
allocate (pct_urban_max(begg:endg, numurbl ))

! Read list of Patches and their corresponding parameter values
! Independent of model resolution, Needs to stay before surfrd_get_data
Expand Down Expand Up @@ -288,7 +289,8 @@ subroutine initialize2(ni,nj)

! Deallocate surface grid dynamic memory for variables that aren't needed elsewhere.
! Some things are kept until the end of initialize2; urban_valid is kept through the
! end of the run for error checking.
! end of the run for error checking, pct_urban_max is kept through the end of the run
! for reweighting in subgridWeights.
deallocate (wt_lunit, wt_cft, wt_glc_mec, haslake)

! Determine processor bounds and clumps for this processor
Expand Down
4 changes: 4 additions & 0 deletions src/main/clm_varsur.F90
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ module clm_instur

! whether we have lake to initialise in each grid cell
logical , pointer :: haslake(:)

! whether we have urban to initialize in each grid cell
! (second dimension goes 1:numurbl)
real(r8), pointer :: pct_urban_max(:,:)
!-----------------------------------------------------------------------

end module clm_instur
61 changes: 56 additions & 5 deletions src/main/subgridMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ module subgridMod
public :: subgrid_get_info_crop
public :: crop_patch_exists ! returns true if the given crop patch should be created in memory
public :: lake_landunit_exists ! returns true if the lake landunit should be created in memory
public :: urban_landunit_exists ! returns true if the urban landunit should be created in memory

! !PRIVATE MEMBER FUNCTIONS:
private :: subgrid_get_info_urban
Expand Down Expand Up @@ -348,6 +349,10 @@ subroutine subgrid_get_info_urban(gi, ltype, npatches, ncols, nlunits)
!
! In either case, for simplicity, we always allocate space for all columns on any
! allocated urban landunits.

! For dynamic urban: to improve efficiency, 'PCT_URBAN_MAX' is added in landuse.timeseries
! that tells if any urban landunit ever grows in a given grid cell in a transient
! run. The urban landunit is allocated only if PCT_URBAN_MAX is greater than 0. (#1572)

if (run_zero_weight_urban) then
if (urban_valid(gi)) then
Expand All @@ -356,11 +361,11 @@ subroutine subgrid_get_info_urban(gi, ltype, npatches, ncols, nlunits)
this_landunit_exists = .false.
end if
else
if (wt_lunit(gi, ltype) > 0.0_r8) then
this_landunit_exists = .true.
else
this_landunit_exists = .false.
end if
if (urban_landunit_exists(gi, ltype)) then
this_landunit_exists = .true.
else
this_landunit_exists = .false.
end if
end if

if (this_landunit_exists) then
Expand Down Expand Up @@ -599,4 +604,50 @@ function lake_landunit_exists(gi) result(exists)

end function lake_landunit_exists

!-----------------------------------------------------------------------
function urban_landunit_exists(gi, ltype) result(exists)
!
! !DESCRIPTION:
! Returns true if a landunit for urban should be created in memory
! which is defined for gridcells which will grow urban, given by pct_urban_max
!
! !USES:
use dynSubgridControlMod , only : get_do_transient_urban
use clm_instur , only : pct_urban_max
use landunit_varcon , only : isturb_MIN
!
! !ARGUMENTS:
logical :: exists ! function result
integer, intent(in) :: gi ! grid cell index
integer, intent(in) :: ltype !landunit type (isturb_tbd, etc.)
!
! !LOCAL VARIABLES:
integer :: dens_index ! urban density type index

character(len=*), parameter :: subname = 'urban_landunit_exists'
!-----------------------------------------------------------------------

if (get_do_transient_urban()) then
! To support dynamic landunits, we initialize an urban land unit in each grid cell
! in which there are urban. This is defined by the pct_urban_max variable.

dens_index = ltype - isturb_MIN + 1
if (pct_urban_max(gi,dens_index) > 0.0_r8) then
exists = .true.
else
exists = .false.
end if

else
! For a run without transient urban, only allocate memory for urban land units
! actually present in run.
if (wt_lunit(gi, ltype) > 0.0_r8) then
exists = .true.
else
exists = .false.
end if
end if

end function urban_landunit_exists

end module subgridMod
12 changes: 10 additions & 2 deletions src/main/subgridWeightsMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ logical function is_active_l(l, glc_behavior)
!
! !USES:
use landunit_varcon, only : istsoil, istice, isturb_MIN, isturb_MAX, istdlak
use clm_instur , only : pct_urban_max
!
! !ARGUMENTS:
implicit none
Expand All @@ -309,6 +310,7 @@ logical function is_active_l(l, glc_behavior)
!
! !LOCAL VARIABLES:
integer :: g ! grid cell index
integer :: dens_index ! urban density index
!------------------------------------------------------------------------

if (all_active) then
Expand All @@ -334,8 +336,14 @@ logical function is_active_l(l, glc_behavior)
is_active_l = .true.
end if

if ((lun%itype(l) >= isturb_MIN .and. lun%itype(l) <= isturb_MAX) .and. &
run_zero_weight_urban) then
! Set urban land units to active, as long as memory has been allocated for such land units, either
! through the run_zero_weight_urban setting which runs all urban landunits in each grid cell or
! through pct_urban_max which is the maximum percent urban for each density type in a transient run.
! (See subgridMod.F90 for this logic).
! By doing this, urban land units are also run virtually in grid cells which will grow
! urban during the transient run.

if ( (lun%itype(l) >= isturb_MIN .and. lun%itype(l) <= isturb_MAX) ) then
is_active_l = .true.
end if

Expand Down
Loading

0 comments on commit bf958ac

Please sign in to comment.