Skip to content

Commit

Permalink
Merge branch 'dynlakes_master_notools'
Browse files Browse the repository at this point in the history
Add capability for dynamic lakes

Adds the capability for dynamic lake areas, read from the
landuse_timeseries file. This represents reservoir construction. For
now, this capability is off by default. Turning it on requires new
fields on the landuse_timeseries file which cannot yet be produced by
mksurfdata_map; these new fields will be added in
#1073.

A substantial part of this tag involved changing the accounting of water
and energy in lakes in order to conserve water and energy across
landunit transitions while not producing too large adjustment
fluxes. This change results in roundoff-level answer changes for all
transient cases.

The core changes in this tag are from Inne Vanderkelen, in consultation
with Bill Sacks. Additional changes are from Bill Sacks, in consultation
with Inne Vanderkelen.

Resolves #200
Resolves #1140
  • Loading branch information
billsacks committed Sep 29, 2020
2 parents a7c2cea + 23568dd commit 08bc0ad
Show file tree
Hide file tree
Showing 27 changed files with 1,233 additions and 212 deletions.
64 changes: 64 additions & 0 deletions bld/CLMBuildNamelist.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2382,6 +2382,7 @@ sub setup_logic_dynamic_subgrid {

setup_logic_do_transient_pfts($opts, $nl_flags, $definition, $defaults, $nl);
setup_logic_do_transient_crops($opts, $nl_flags, $definition, $defaults, $nl);
setup_logic_do_transient_lakes($opts, $nl_flags, $definition, $defaults, $nl);
setup_logic_do_harvest($opts, $nl_flags, $definition, $defaults, $nl);

add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'reset_dynbal_baselines');
Expand Down Expand Up @@ -2547,6 +2548,69 @@ sub setup_logic_do_transient_crops {
}
}

sub setup_logic_do_transient_lakes {
#
# Set do_transient_lakes default value, and perform error checking on do_transient_lakes
#
# Assumes the following are already set in the namelist (although it's okay
# for them to be unset if that will be their final state):
# - flanduse_timeseries
#
# NOTE(wjs, 2020-08-23) I based this function on setup_logic_do_transient_crops. I'm
# not sure if all of the checks here are truly important for transient lakes (in
# particular, my guess is that collapse_urban could probably be done with transient
# lakes - as well as transient pfts and transient crops for that matter), but some of
# the checks probably are needed, and it seems best to keep transient lakes consistent
# with other transient areas in this respect.
my ($opts, $nl_flags, $definition, $defaults, $nl) = @_;

my $var = 'do_transient_lakes';

# cannot_be_true will be set to a non-empty string in any case where
# do_transient_lakes should not be true; if it turns out that
# do_transient_lakes IS true in any of these cases, a fatal error will be
# generated
my $cannot_be_true = "";

my $n_dom_pfts = $nl->get_value( 'n_dom_pfts' );
my $n_dom_landunits = $nl->get_value( 'n_dom_landunits' );
my $toosmall_soil = $nl->get_value( 'toosmall_soil' );
my $toosmall_crop = $nl->get_value( 'toosmall_crop' );
my $toosmall_glacier = $nl->get_value( 'toosmall_glacier' );
my $toosmall_lake = $nl->get_value( 'toosmall_lake' );
my $toosmall_wetland = $nl->get_value( 'toosmall_wetland' );
my $toosmall_urban = $nl->get_value( 'toosmall_urban' );

if (string_is_undef_or_empty($nl->get_value('flanduse_timeseries'))) {
$cannot_be_true = "$var can only be set to true when running a transient case (flanduse_timeseries non-blank)";
}

if (!$cannot_be_true) {
# Note that, if the variable cannot be true, we don't call add_default
# - so that we don't clutter up the namelist with variables that don't
# matter for this case
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var);
}

# Make sure the value is false when it needs to be false - i.e., that the
# user hasn't tried to set a true value at an inappropriate time.

if (&value_is_true($nl->get_value($var)) && $cannot_be_true) {
$log->fatal_error($cannot_be_true);
}

# if do_transient_lakes is .true. and any of these (n_dom_* or toosmall_*)
# are > 0 or collapse_urban = .true., then give fatal error
if (&value_is_true($nl->get_value($var))) {
if (&value_is_true($nl->get_value('collapse_urban'))) {
$log->fatal_error("$var cannot be combined with collapse_urban");
}
if ($n_dom_pfts > 0 || $n_dom_landunits > 0 || $toosmall_soil > 0 || $toosmall_crop > 0 || $toosmall_glacier > 0 || $toosmall_lake > 0 || $toosmall_wetland > 0 || $toosmall_urban > 0) {
$log->fatal_error("$var cannot be combined with any of the of the following > 0: n_dom_pfts > 0, n_dom_landunit > 0, toosmall_soil > 0._r8, toosmall_crop > 0._r8, toosmall_glacier > 0._r8, toosmall_lake > 0._r8, toosmall_wetland > 0._r8, toosmall_urban > 0._r8");
}
}
}

sub setup_logic_do_harvest {
#
# Set do_harvest default value, and perform error checking on do_harvest
Expand Down
1 change: 1 addition & 0 deletions bld/namelist_files/namelist_defaults_ctsm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3599,6 +3599,7 @@ lnd/clm2/surfdata_map/release-clm5.0.30/surfdata_ne0np4.CONUS.ne30x8_hist_78pfts
<!-- (some other defaults for dynamic subgrid -->
<!-- are set in the BuildNamelist code) -->
<!-- ========================================= -->
<do_transient_lakes>.false.</do_transient_lakes>
<reset_dynbal_baselines>.false.</reset_dynbal_baselines>

<!-- ========================================= -->
Expand Down
6 changes: 6 additions & 0 deletions bld/namelist_files/namelist_definition_ctsm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2424,6 +2424,12 @@ If TRUE, apply transient crops from flanduse_timeseries file.
(Only valid for transient runs, where there is a flanduse_timeseries file.)
</entry>

<entry id="do_transient_lakes" type="logical" category="physics"
group="dynamic_subgrid" valid_values="" >
If TRUE, apply transient lakes from flanduse_timeseries file.
(Only valid for transient runs, where there is a flanduse_timeseries file.)
</entry>

<entry id="do_harvest" type="logical" category="physics"
group="dynamic_subgrid" valid_values="" >
If TRUE, apply harvest from flanduse_timeseries file.
Expand Down
10 changes: 10 additions & 0 deletions cime_config/testdefs/testlist_clm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1622,6 +1622,16 @@ for ERS test as otherwise it won't work for a sub-day test"</option>
<option name="comment" >Want a debug test that tests a number of aspects of transient crops, including a new crop landunit and shifting PCT_CFT; move to CLM50 once we can get it fast enough (see bug 2391)</option>
</options>
</test>
<test name="ERS_Lm25" grid="1x1_smallvilleIA" compset="IHistClm50BgcCropQianRsGs" testmods="clm/smallville_dynlakes_monthly">
<machines>
<machine name="cheyenne" compiler="gnu" category="aux_clm">
<options>
<option name="wallclock">0:50:00</option>
<option name="comment">Include a test of transient lakes</option>
</options>
</machine>
</machines>
</test>
<test name="SMS_D_P48x1_Ld5" grid="f10_f10_musgs" compset="I2000Clm50BgcCrop" testmods="clm/irrig_spunup">
<machines>
<machine name="izumi" compiler="nag" category="aux_clm"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
../monthly
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
do_transient_lakes = .true.

! This file was created with the following command:
! ncap2 -s 'PCT_LAKE=array(0.0,0.0,PCT_CROP); PCT_LAKE={0.,50.,25.,25.,25.,25.}; HASLAKE=array(1.,1.,AREA); PCT_CROP=array(0.0,0.0,PCT_LAKE); PCT_CROP={0.,25.,12.,12.,12.,12.}' landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_c160127.nc landuse.timeseries_1x1_smallvilleIA_hist_78pfts_simyr1850-1855_dynLakes_c200928.nc
! Key points are that lake area starts as 0, increases after the first year, then decreases after the second year.
! PCT_CROP is also changed so that PCT_LAKE + PCT_CROP <= 100. (Here, PCT_CROP increases and decreases at the same time as PCT_LAKE 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_dynLakes_c200928.nc'

! BUG(wjs, 2020-09-25, ESCOMP/CTSM#43) Dynamic lakes don't work when methane is active,
! so for now disable methane for this test.
use_lch4 = .false.
175 changes: 175 additions & 0 deletions doc/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,4 +1,179 @@
===============================================================
Tag name: ctsm5.1.dev003
Originator(s): ivanderkelen (Inne Vanderkelen) / sacks (Bill Sacks)
Date: Tue Sep 29 10:16:00 MDT 2020
One-line Summary: Add capability for dynamic lakes

Purpose of changes
------------------

Adds the capability for dynamic lake areas, read from the
landuse_timeseries file. This represents reservoir construction. For
now, this capability is off by default. Turning it on requires new
fields on the landuse_timeseries file which cannot yet be produced by
mksurfdata_map; these new fields will be added in
https://github.com/ESCOMP/CTSM/pull/1073.

A substantial part of this tag involved changing the accounting of water
and energy in lakes in order to conserve water and energy across
landunit transitions while not producing too large adjustment
fluxes. This change results in roundoff-level answer changes for all
transient cases.

The core changes in this tag are from Inne Vanderkelen, in consultation
with Bill Sacks. Additional changes are from Bill Sacks, in consultation
with Inne Vanderkelen.

Bugs fixed or introduced
------------------------

Issues fixed (include CTSM Issue #):
- Resolves ESCOMP/CTSM#200 (Count energy of water in lakes in total
gridcell heat content)
- Resolves ESCOMP/CTSM#1140 (Add lake water to dynbal baselines)

Significant changes to scientifically-supported configurations
--------------------------------------------------------------

Does this tag change answers significantly for any of the following physics configurations?
(Details of any changes will be given in the "Answer changes" section below.)

[Put an [X] in the box for any configuration with significant answer changes.]

[ ] clm5_0

[ ] ctsm5_0-nwp

[ ] clm4_5

Notes of particular relevance for users
---------------------------------------

Caveats for users (e.g., need to interpolate initial conditions):
- Using the dynamic lakes functionality will require either the
mksurfdata_map changes in https://github.com/ESCOMP/CTSM/pull/1073 or
manually adding the necessary fields to the landuse_timeseries file.

Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables):
- New namelist variable for transient runs: do_transient_lakes

Changes made to namelist defaults (e.g., changed parameter values): none

Changes to the datasets (e.g., parameter, surface or initial files): none

Substantial timing or memory changes: none

Notes of particular relevance for developers: (including Code reviews and testing)
---------------------------------------------
NOTE: Be sure to review the steps in README.CHECKLIST.master_tags as well as the coding style in the Developers Guide

Caveats for developers (e.g., code that is duplicated that requires double maintenance):
- Using the dynamic lakes functionality will require either the
mksurfdata_map changes in https://github.com/ESCOMP/CTSM/pull/1073 or
manually adding the necessary fields to the landuse_timeseries file.
- For this reason, the new test
(ERS_Lm25.1x1_smallvilleIA.IHistClm50BgcCropQianRsGs.cheyenne_gnu.clm-smallville_dynlakes_monthly)
requires a manual step to create the necessary landuse_timeseries
file. This step is documented in the README file for the
clm-smallville_dynlakes_monthly testmod.

Changes to tests or testing:
- Added a single-point test covering dynamic lakes, using a
manually-created landuse_timeseries file:
ERS_Lm25.1x1_smallvilleIA.IHistClm50BgcCropQianRsGs.cheyenne_gnu.clm-smallville_dynlakes_monthly

CTSM testing:

[PASS means all tests PASS and OK means tests PASS other than expected fails.]

build-namelist tests:

cheyenne - ok

Tests pass, differences from baseline as expected due to new
namelist variable

tools-tests (test/tools):

cheyenne - not run

PTCLM testing (tools/shared/PTCLM/test):

cheyenne - not run

python testing (see instructions in python/README.md; document testing done):

(any machine) - not run

regular tests (aux_clm):

cheyenne ---- ok
izumi ------- ok

Tests pass, baselines differ as expected

If the tag used for baseline comparisons was NOT the previous tag, note that here:


Answer changes
--------------

Changes answers relative to baseline: YES

If a tag changes answers relative to baseline comparison the
following should be filled in (otherwise remove this section):
And always remove these three lines and parts that don't apply.

Summarize any changes to answers, i.e.,
- what code configurations: Transient cases
- what platforms/compilers: all
- nature of change (roundoff; larger than roundoff/same climate; new climate):
Mostly roundoff-level. See below for details.

- Differences in HEAT_CONTENT1, ICE_CONTENT1, LIQUID_CONTENT1, as
expected

- In transient tests (including Hist/SSP, Fates, CNDV and
transient glacier), roundoff-level diffs in EFLX_DYNBAL,
QFLX_ICE_DYNBAL and QFLX_LIQ_DYNBAL, along with related flux
terms, and river volume

- In some transient tests, roundoff-level diffs in methane terms,
presumably from downstream effects of changes in VOLR due to
roundoff-level changes in fluxes. In multi-year tests, these
methane diffs grow to bigger than roundoff-level, but I think
they originate from roundoff-level diffs. (I feel like I've seen
this high sensitivity before.)

- glcMEC_increase test
(ERP_P180x2_D_Ld5.f19_g17_gl4.I1850Clm50BgcCropG.cheyenne_intel.clm-glcMEC_increase)
shows significant differences in river-related terms, maybe due
to glacier running over lake and now lake has different states
than before; also, FILLDIFFs in h1 file because lake remains
active even when it goes to 0 area.

If bitwise differences were observed, how did you show they were no worse
than roundoff?
- Examined cprnc RMS diffs

If this tag changes climate describe the run(s) done to evaluate the new
climate (put details of the simulations in the experiment database)
- casename: N/A

URL for LMWG diagnostics output used to validate new climate: N/A


Detailed list of changes
------------------------

List any externals directories updated (cime, rtm, mosart, cism, fates, etc.): none

Pull Requests that document the changes (include PR ids):
https://github.com/ESCOMP/CTSM/pull/1109
https://github.com/billsacks/ctsm/pull/3

===============================================================
===============================================================
Tag name: ctsm5.1.dev002
Originator(s): slevis (Samuel Levis,303-665-1310)
Date: Mon Sep 25 09:39:19 MDT 2020
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.dev003 ivanderk 09/29/2020 Add capability for dynamic lakes
ctsm5.1.dev002 slevis 09/25/2020 Reduce duplication between caps
ctsm5.1.dev001 erik 09/23/2020 Start the clm5_1 physics series, with some changes to the fire model from Fang Li
ctsm1.0.dev113 negins 09/08/2020 Some bit-for-bit changes needed for the Perturbed Parameter Ensemble work
Expand Down
2 changes: 1 addition & 1 deletion src/biogeochem/ch4Mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -1251,7 +1251,7 @@ subroutine DynamicColumnAdjustments(this, bounds, clump_index, column_state_upda
character(len=*), parameter :: subname = 'DynamicColumnAdjustments'
!-----------------------------------------------------------------------

! BUG(wjs, 2016-02-16, bugz 2283) Need to do some special handling of finundated for
! BUG(wjs, 2016-02-16, ESCOMP/CTSM#43) Need to do some special handling of finundated for
! increases in lake area, since lakes are assumed to be 100% inundated. Probably it's
! most appropriate for this special handling to happen elsewhere - i.e., within this
! routine, we do the standard adjustments as they are currently done, but then in the
Expand Down
13 changes: 9 additions & 4 deletions src/biogeophys/BalanceCheckMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ module BalanceCheckMod
use SoilHydrologyType , only : soilhydrology_type
use SurfaceAlbedoType , only : surfalb_type
use WaterStateType , only : waterstate_type
use LakestateType , only : lakestate_type
use WaterDiagnosticBulkType, only : waterdiagnosticbulk_type
use WaterDiagnosticType, only : waterdiagnostic_type
use Wateratm2lndType , only : wateratm2lnd_type
Expand Down Expand Up @@ -122,7 +123,7 @@ end function GetBalanceCheckSkipSteps
!-----------------------------------------------------------------------
subroutine BeginWaterBalance(bounds, &
num_nolakec, filter_nolakec, num_lakec, filter_lakec, &
water_inst, soilhydrology_inst, &
water_inst, soilhydrology_inst, lakestate_inst, &
use_aquifer_layer)
!
! !DESCRIPTION:
Expand All @@ -136,6 +137,7 @@ subroutine BeginWaterBalance(bounds, &
integer , intent(in) :: num_lakec ! number of column lake points in column filter
integer , intent(in) :: filter_lakec(:) ! column filter for lake points
type(water_type) , intent(inout) :: water_inst
type(lakestate_type) , intent(in) :: lakestate_inst
type(soilhydrology_type) , intent(in) :: soilhydrology_inst
logical , intent(in) :: use_aquifer_layer ! whether an aquifer layer is used in this run
!
Expand All @@ -150,6 +152,7 @@ subroutine BeginWaterBalance(bounds, &
num_nolakec, filter_nolakec, &
num_lakec, filter_lakec, &
soilhydrology_inst, &
lakestate_inst, &
water_inst%bulk_and_tracers(i)%waterstate_inst, &
water_inst%bulk_and_tracers(i)%waterdiagnostic_inst, &
water_inst%bulk_and_tracers(i)%waterbalance_inst, &
Expand All @@ -161,7 +164,8 @@ end subroutine BeginWaterBalance
!-----------------------------------------------------------------------
subroutine BeginWaterBalanceSingle(bounds, &
num_nolakec, filter_nolakec, num_lakec, filter_lakec, &
soilhydrology_inst, waterstate_inst, waterdiagnostic_inst, waterbalance_inst, &
soilhydrology_inst, lakestate_inst, waterstate_inst, &
waterdiagnostic_inst, waterbalance_inst, &
use_aquifer_layer)
!
! !DESCRIPTION:
Expand All @@ -175,6 +179,7 @@ subroutine BeginWaterBalanceSingle(bounds, &
integer , intent(in) :: num_lakec ! number of column lake points in column filter
integer , intent(in) :: filter_lakec(:) ! column filter for lake points
type(soilhydrology_type) , intent(in) :: soilhydrology_inst
type(lakestate_type) , intent(in) :: lakestate_inst
class(waterstate_type) , intent(inout) :: waterstate_inst
class(waterdiagnostic_type), intent(in) :: waterdiagnostic_inst
class(waterbalance_type) , intent(inout) :: waterbalance_inst
Expand Down Expand Up @@ -210,8 +215,8 @@ subroutine BeginWaterBalanceSingle(bounds, &
water_mass = begwb(bounds%begc:bounds%endc))

call ComputeWaterMassLake(bounds, num_lakec, filter_lakec, &
waterstate_inst, &
subtract_dynbal_baselines = .false., &
waterstate_inst, lakestate_inst, &
add_lake_water_and_subtract_dynbal_baselines = .false., &
water_mass = begwb(bounds%begc:bounds%endc))

call waterstate_inst%CalculateTotalH2osno(bounds, num_nolakec, filter_nolakec, &
Expand Down
1 change: 1 addition & 0 deletions src/biogeophys/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ list(APPEND clm_sources
InfiltrationExcessRunoffMod.F90
IrrigationMod.F90
LakeCon.F90
LakeStateType.F90
QSatMod.F90
RootBiophysMod.F90
SaturatedExcessRunoffMod.F90
Expand Down
Loading

0 comments on commit 08bc0ad

Please sign in to comment.