diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index f4a225c9aa..b0bf2c5a0c 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -26,6 +26,7 @@ d866510188d26d51bcd6d37239283db690af7e82
0dcd0a3c1abcaffe5529f8d79a6bc34734b195c7
e096358c832ab292ddfd22dd5878826c7c788968
475831f0fb0e31e97f630eac4e078c886558b61c
+fd5f177131d63d39e79a13918390bdfb642d781e
# Ran SystemTests and python/ctsm through black python formatter
5364ad66eaceb55dde2d3d598fe4ce37ac83a93c
8056ae649c1b37f5e10aaaac79005d6e3a8b2380
@@ -36,6 +37,7 @@ e096358c832ab292ddfd22dd5878826c7c788968
6fccf682eaf718615407d9bacdd3903b8786a03d
2500534eb0a83cc3aff94b30fb62e915054030bf
78d05967c2b027dc9776a884716597db6ef7f57c
+47839a77229c61555e3b8932927bb54cdc511b27
a0d014fae9550dd9ffbc934abd29ef16176f8208
c7b7ca1d94ac19abb9ecea9fb5b712ddbdd6645d
b565b55ce7a9f8d812a573d716a5fd3d78cfea81
@@ -46,4 +48,6 @@ aa04d1f7d86cc2503b98b7e2b2d84dbfff6c316b
6c6f57e948bfa31e60b383536cc21663fedb8b70
9660667b1267dcd4150889f5f39db540158be74a
665cf86102e09b4c4c5a140700676dca23bc55a9
+1a49e547ba3c48fa483f9ae81a8f05adcd6b888c
045d90f1d80f713eb3ae0ac58f6c2352937f1eb0
+753fda3ff0147837231a73c9c728dd9ce47b5997
diff --git a/.gitmodules b/.gitmodules
index e437f56d61..19bc024208 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -28,7 +28,7 @@
[submodule "fates"]
path = src/fates
url = https://github.com/NGEET/fates
-fxtag = sci.1.73.0_api.35.0.0
+fxtag = sci.1.77.1_api.36.0.0
fxrequired = AlwaysRequired
# Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed
fxDONOTUSEurl = https://github.com/NCAR/fates-release
@@ -36,7 +36,7 @@ fxDONOTUSEurl = https://github.com/NCAR/fates-release
[submodule "cism"]
path = components/cism
url = https://github.com/ESCOMP/CISM-wrapper
-fxtag = cismwrap_2_2_001
+fxtag = cismwrap_2_2_002
fxrequired = ToplevelRequired
# Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed
fxDONOTUSEurl = https://github.com/ESCOMP/CISM-wrapper
@@ -44,7 +44,7 @@ fxDONOTUSEurl = https://github.com/ESCOMP/CISM-wrapper
[submodule "rtm"]
path = components/rtm
url = https://github.com/ESCOMP/RTM
-fxtag = rtm1_0_79
+fxtag = rtm1_0_80
fxrequired = ToplevelRequired
# Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed
fxDONOTUSEurl = https://github.com/ESCOMP/RTM
@@ -52,7 +52,7 @@ fxDONOTUSEurl = https://github.com/ESCOMP/RTM
[submodule "mosart"]
path = components/mosart
url = https://github.com/ESCOMP/MOSART
-fxtag = mosart1_0_49
+fxtag = mosart1.1.02
fxrequired = ToplevelRequired
# Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed
fxDONOTUSEurl = https://github.com/ESCOMP/MOSART
@@ -68,7 +68,7 @@ fxDONOTUSEurl = https://github.com/ESCOMP/mizuRoute
[submodule "ccs_config"]
path = ccs_config
url = https://github.com/ESMCI/ccs_config_cesm.git
-fxtag = ccs_config_cesm0.0.106
+fxtag = ccs_config_cesm1.0.0
fxrequired = ToplevelRequired
# Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed
fxDONOTUSEurl = https://github.com/ESMCI/ccs_config_cesm.git
@@ -84,7 +84,7 @@ fxDONOTUSEurl = https://github.com/ESMCI/cime
[submodule "cmeps"]
path = components/cmeps
url = https://github.com/ESCOMP/CMEPS.git
-fxtag = cmeps0.14.63
+fxtag = cmeps0.14.77
fxrequired = ToplevelRequired
# Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed
fxDONOTUSEurl = https://github.com/ESCOMP/CMEPS.git
diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm
index ab70d698f4..6b8342375a 100755
--- a/bld/CLMBuildNamelist.pm
+++ b/bld/CLMBuildNamelist.pm
@@ -97,22 +97,26 @@ OPTIONS
CENTURY or MIMICS decomposition
This toggles on the namelist variables:
use_fates. use_lch4 and use_nitrif_denitrif are optional
-
+
(Only for CLM4.5/CLM5.0)
-[no-]chk_res Also check [do NOT check] to make sure the resolution and
land-mask is valid.
- -clm_accelerated_spinup "on|off" Setup in a configuration to run as fast as possible for doing a throw-away
+ -clm_accelerated_spinup "on|sasu|off" Setup in a configuration to run as fast as possible for doing a throw-away
simulation in order to get the model to a spun-up state. So do things like
turn off expensive options and setup for a low level of history output.
If CLM4.5/CLM5.0 and bgc it also includes a prognostic Carbon model (cn or bgc)
, also by default turn on Accelerated Decomposition mode which
- is controlled by the namelist variable spinup_state.
+ is controlled by the namelist variable spinup_state (when soil matrix CN is off).
- Turn on given spinup mode for BGC setting of CN
+ Turn on given spinup mode for BGC setting of CN (soil matrix CN off)
on : Turn on Accelerated Decomposition (spinup_state = 1 or 2)
off : run in normal mode (spinup_state = 0)
+ To spinup using the CN soil matrix method use "sasu" SemiAnalytic Spin-Up (SASU)
+ sasu: Turn on matrix spinup (spinup_matrixcn=T)
+ Normal spinup sequence is: on, sasu, off
+
Default is set by clm_accelerated_spinup mode.
Spinup is now a two step procedure. First, run the model
@@ -517,6 +521,7 @@ sub read_namelist_defaults {
"$cfgdir/namelist_files/namelist_defaults_ctsm.xml",
"$cfgdir/namelist_files/namelist_defaults_drv.xml",
"$cfgdir/namelist_files/namelist_defaults_fire_emis.xml",
+ "$cfgdir/namelist_files/namelist_defaults_dust_emis.xml",
"$cfgdir/namelist_files/namelist_defaults_drydep.xml" );
# Add the location of the use case defaults files to the options hash
@@ -783,9 +788,10 @@ sub setup_cmdl_fates_mode {
# dis-allow fates specific namelist items with non-fates runs
my @list = ( "fates_spitfire_mode", "use_fates_planthydro", "use_fates_ed_st3", "use_fates_ed_prescribed_phys",
"use_fates_cohort_age_tracking","use_fates_inventory_init","use_fates_fixed_biogeog",
- "use_fates_nocomp","use_fates_sp","fates_inventory_ctrl_filename","use_fates_logging",
- "fates_parteh_mode","use_fates_tree_damage","fates_history_dimlevel","fates_seeddisp_cadence",
- "use_fates_luh","fluh_timeseries" );
+ "use_fates_nocomp","use_fates_sp","fates_inventory_ctrl_filename","fates_harvest_mode",
+ "fates_parteh_mode","use_fates_tree_damage","fates_seeddisp_cadence","use_fates_luh","fluh_timeseries",
+ "flandusepftdat","use_fates_potentialveg","use_fates_lupft","fates_history_dimlevel" );
+
# dis-allow fates specific namelist items with non-fates runs
foreach my $var ( @list ) {
if ( defined($nl->get_value($var)) ) {
@@ -894,6 +900,7 @@ sub setup_cmdl_bgc {
'phys'=>$nl_flags->{'phys'}, 'use_cn'=>$nl_flags->{'use_cn'}, 'use_fates'=>$nl_flags->{'use_fates'},
'use_fates_sp'=>$nl_flags->{'use_fates_sp'} );
my $soil_decomp_method = remove_leading_and_trailing_quotes( $nl->get_value( $var ) );
+ $nl_flags->{$var} = $soil_decomp_method;
if ( &value_is_true($nl_flags->{'use_cn'}) ) {
if ( $soil_decomp_method eq "None" ) {
@@ -952,6 +959,30 @@ sub setup_cmdl_bgc {
if ( (! &value_is_true($nl_flags->{'use_nitrif_denitrif'}) ) && &value_is_true($nl->get_value('use_fun')) ) {
$log->fatal_error("When FUN is on, use_nitrif_denitrif MUST also be on!");
}
+ #
+ # Make sure clm_accelerate_spinup is set correctly
+ #
+ $var = "clm_accelerated_spinup";
+ if ( $opts->{$var} ne "default" ) {
+ $val = $opts->{$var};
+ } else {
+ $val = $defaults->get_value($var);
+ }
+ $nl_flags->{$var} = $val;
+ # Set soil matrix (which is needed later for spinup)
+ $var = "use_soil_matrixcn";
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var,
+ , 'use_fates'=>$nl_flags->{'use_fates'},
+ , 'soil_decomp_method'=>$nl_flags->{'soil_decomp_method'},
+ , 'phys'=>$nl_flags->{'phys'}, clm_accelerated_spinup=>$nl_flags->{'clm_accelerated_spinup'} );
+ if ( &value_is_true($nl->get_value($var)) ) {
+ $nl_flags->{$var} = ".true.";
+ } else {
+ $nl_flags->{$var} = ".false.";
+ }
+ if ( &value_is_true($nl->get_value($var)) && $nl_flags->{'soil_decomp_method'} ne "CENTURYKoven2013" ) {
+ $log->fatal_error("$var can only be on with CENTURYKoven2013 soil decomposition");
+ }
} # end bgc
@@ -1011,7 +1042,7 @@ sub setup_cmdl_fire_light_res {
if ( ! &value_is_true($nl_flags->{'neon'}) ) {
if ( defined($opts->{'clm_usr_name'}) ) {
$log->warning("The NEON lightning dataset does NOT cover the entire globe, make sure it covers the region for your grid");
- } else {
+ } else {
$log->fatal_error("The NEON lightning dataset can NOT be used for global grids or regions or points outside of its area as it does NOT cover the entire globe.");
}
}
@@ -1156,32 +1187,40 @@ sub setup_cmdl_spinup {
my $val;
my $var;
$nl_flags->{'spinup'} = undef;
+ # clm_accelerated_spinup will already have been set in setup_cmdl_bgc
$var = "clm_accelerated_spinup";
- if ( $opts->{$var} ne "default" ) {
- $val = $opts->{$var};
- } else {
- $val = $defaults->get_value($var);
- }
- $nl_flags->{$var} = $val;
+ $val = $nl_flags->{'clm_accelerated_spinup'};
my $group = $definition->get_group_name($var);
$nl->set_variable_value($group, $var, quote_string($val) );
if ( ! $definition->is_valid_value( $var, $val , 'noquotes' => 1) ) {
my @valid_values = $definition->get_valid_values( $var );
$log->fatal_error("$var has an invalid value ($val). Valid values are: @valid_values");
}
+ if ( $nl_flags->{'clm_accelerated_spinup'} eq "sasu" ) {
+ if ( ! &value_is_true($nl_flags->{'use_cn'}) ) {
+ $log->fatal_error("If clm_accelerated_spinup is sasu, use_cn MUST be on" );
+ }
+ if ( ! &value_is_true($nl_flags->{'use_soil_matrixcn'}) ) {
+ $log->fatal_error("If clm_accelerated_spinup is sasu, use_soil_matrixcn MUST be on" );
+ }
+ }
$log->verbose_message("CLM accelerated spinup mode is $val");
if ( &value_is_true($nl_flags->{'use_cn'}) ) {
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition,
- $defaults, $nl, "spinup_state", clm_accelerated_spinup=>$nl_flags->{$var},
- use_cn=>$nl_flags->{'use_cn'}, use_fates=>$nl_flags->{'use_fates'} );
+ $defaults, $nl, "spinup_state", clm_accelerated_spinup=>$nl_flags->{'clm_accelerated_spinup'},
+ use_cn=>$nl_flags->{'use_cn'}, use_fates=>$nl_flags->{'use_fates'},
+ use_soil_matrixcn=>$nl_flags->{"use_soil_matrixcn"} );
if ( $nl->get_value("spinup_state") ne 0 ) {
$nl_flags->{'bgc_spinup'} = "on";
+ if ( &value_is_true($nl_flags->{'use_soil_matrixcn'}) ) {
+ $log->fatal_error("spinup_state is accelerated (=1 or 2), but use_soil_matrixcn is also true" .
+ ", change one or the other");
+ }
if ( $nl_flags->{'clm_accelerated_spinup'} eq "off" ) {
$log->fatal_error("spinup_state is accelerated, but clm_accelerated_spinup is off, change one or the other");
}
} else {
$nl_flags->{'bgc_spinup'} = "off";
- $val = $defaults->get_value($var);
}
# For AD spinup mode by default reseed dead plants
if ( $nl_flags->{$var} ne "off" ) {
@@ -1196,6 +1235,27 @@ sub setup_cmdl_spinup {
}
}
$nl_flags->{$var} = $val;
+ if ( &value_is_true($nl_flags->{'use_soil_matrixcn'}) ) {
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, "spinup_matrixcn",
+ , 'use_fates'=>$nl_flags->{'use_fates'}, 'bgc_mode'=>$nl_flags->{'bgc_mode'}
+ , 'phys'=>$nl_flags->{'phys'}, 'use_soil_matrixcn'=>$nl_flags->{'use_soil_matrixcn'},
+ , clm_accelerated_spinup=>$nl_flags->{'clm_accelerated_spinup'} );
+ my $spinup;
+ if ( &value_is_true($nl->get_value("spinup_matrixcn") ) ) {
+ $spinup = ".true.";
+ } else {
+ $spinup = ".false.";
+ }
+ $nl_flags->{'spinup_matrixcn'} = $spinup;
+ if ( &value_is_true($nl_flags->{'spinup_matrixcn'}) ) {
+ $nl_flags->{'bgc_spinup'} = "on";
+ if ( $nl_flags->{'clm_accelerated_spinup'} eq "off" ) {
+ $log->fatal_error("matrix spinup (spinup_matrixcn) is True, but clm_accelerated_spinup is off, change one or the other");
+ }
+ } else {
+ $nl_flags->{'bgc_spinup'} = "off";
+ }
+ }
my $group = $definition->get_group_name($var);
$nl->set_variable_value($group, $var, quote_string($val) );
if ( ! $definition->is_valid_value( $var, $val , 'noquotes' => 1) ) {
@@ -1205,11 +1265,13 @@ sub setup_cmdl_spinup {
if ( $nl_flags->{'bgc_spinup'} eq "on" && (not &value_is_true( $nl_flags->{'use_cn'} )) && (not &value_is_true($nl_flags->{'use_fates'})) ) {
$log->fatal_error("$var can not be '$nl_flags->{'bgc_spinup'}' if neither CN nor FATES is turned on (use_cn=$nl_flags->{'use_cn'}, use_fates=$nl_flags->{'use_fates'}).");
}
- if ( $nl->get_value("spinup_state") eq 0 && $nl_flags->{'bgc_spinup'} eq "on" ) {
- $log->fatal_error("Namelist spinup_state contradicts the command line option bgc_spinup" );
- }
- if ( $nl->get_value("spinup_state") eq 1 && $nl_flags->{'bgc_spinup'} eq "off" ) {
- $log->fatal_error("Namelist spinup_state contradicts the command line option bgc_spinup" );
+ if ( ! &value_is_true($nl_flags->{'use_soil_matrixcn'}) ) {
+ if ( $nl->get_value("spinup_state") eq 0 && $nl_flags->{'bgc_spinup'} eq "on" ) {
+ $log->fatal_error("Namelist spinup_state contradicts the command line option bgc_spinup" );
+ }
+ if ( $nl->get_value("spinup_state") eq 1 && $nl_flags->{'bgc_spinup'} eq "off" ) {
+ $log->fatal_error("Namelist spinup_state contradicts the command line option bgc_spinup" );
+ }
}
$val = $nl_flags->{'bgc_spinup'};
@@ -1582,7 +1644,6 @@ sub process_namelist_inline_logic {
setup_logic_hillslope($opts, $nl_flags, $definition, $defaults, $nl);
setup_logic_o3_veg_stress_method($opts, $nl_flags, $definition, $defaults, $nl,$physv);
setup_logic_hydrstress($opts, $nl_flags, $definition, $defaults, $nl);
- setup_logic_dynamic_roots($opts, $nl_flags, $definition, $defaults, $nl, $physv);
setup_logic_params_file($opts, $nl_flags, $definition, $defaults, $nl);
setup_logic_create_crop_landunit($opts, $nl_flags, $definition, $defaults, $nl);
setup_logic_subgrid($opts, $nl_flags, $definition, $defaults, $nl);
@@ -1595,6 +1656,7 @@ sub process_namelist_inline_logic {
if ( remove_leading_and_trailing_quotes($nl_flags->{'clm_start_type'}) ne "branch" ) {
setup_logic_initial_conditions($opts, $nl_flags, $definition, $defaults, $nl, $physv);
}
+ setup_logic_cnmatrix($opts, $nl_flags, $definition, $defaults, $nl, $envxml_ref);
setup_logic_spinup($opts, $nl_flags, $definition, $defaults, $nl);
setup_logic_supplemental_nitrogen($opts, $nl_flags, $definition, $defaults, $nl);
setup_logic_snowpack($opts, $nl_flags, $definition, $defaults, $nl);
@@ -1701,7 +1763,7 @@ sub process_namelist_inline_logic {
######################################
# namelist options for dust emissions
######################################
- setup_logic_dust_emis($opts, $nl_flags, $definition, $defaults, $nl);
+ setup_logic_dust_emis($opts, $nl_flags, $definition, $defaults, $nl, $envxml_ref);
#################################
# namelist group: megan_emis_nl #
@@ -1847,9 +1909,10 @@ sub setup_logic_site_specific {
$nl->set_variable_value($group, $var, $val);
}
- if ($nl_flags->{'res'} eq "1x1_smallvilleIA") {
+ my $res = $nl_flags->{'res'};
+ if ($res eq "1x1_smallvilleIA" or $res eq "1x1_cidadinhoBR") {
if (! &value_is_true($nl_flags->{'use_cn'}) || ! &value_is_true($nl_flags->{'use_crop'})) {
- $log->fatal_error("1x1_smallvilleIA grids must use a compset with CN and CROP turned on.");
+ $log->fatal_error("${res} grids must use a compset with CN and CROP turned on.");
}
}
@@ -2254,6 +2317,7 @@ sub setup_logic_urban {
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'building_temp_method');
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'urban_hac');
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'urban_explicit_ac');
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'urban_traffic');
}
@@ -2277,7 +2341,7 @@ sub setup_logic_crop_inparm {
}
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, "initial_seed_at_planting",
'use_crop'=>$nl->get_value('use_crop') );
-
+
my $crop_residue_removal_frac = $nl->get_value('crop_residue_removal_frac');
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'crop_residue_removal_frac' );
if ( $crop_residue_removal_frac < 0.0 or $crop_residue_removal_frac > 1.0 ) {
@@ -2617,8 +2681,8 @@ SIMYR: foreach my $sim_yr ( @sim_years ) {
if ( defined($use_init_interp_default) ) {
$log->fatal_error($err_msg." but can't find one without $useinitvar being set to true, change it to true in your user_nl_clm file in your case");
} else {
- my $set = "Relevent settings: use_cndv = ". $nl_flags->{'use_cndv'} . " phys = " .
- $physv->as_string() . " hgrid = " . $nl_flags->{'res'} . " sim_year = " .
+ my $set = "Relevent settings: use_cndv = ". $nl_flags->{'use_cndv'} . " phys = " .
+ $physv->as_string() . " hgrid = " . $nl_flags->{'res'} . " sim_year = " .
$settings{'sim_year'} . " lnd_tuning_mode = " . $nl_flags->{'lnd_tuning_mode'} .
"use_fates = " . $nl_flags->{'use_fates'};
$log->fatal_error($err_msg." but the default setting of $useinitvar is false, so set both $var to a startup file and $useinitvar==TRUE, or developers should modify the namelist_defaults file".$set);
@@ -3018,8 +3082,8 @@ sub setup_logic_do_harvest {
$cannot_be_true = "$var can only be set to true when running a transient case (flanduse_timeseries non-blank)";
}
- elsif (!&value_is_true($nl->get_value('use_cn')) && !&value_is_true($nl->get_value('use_fates'))) {
- $cannot_be_true = "$var can only be set to true when running with either CN or FATES";
+ elsif (!&value_is_true($nl->get_value('use_cn'))) {
+ $cannot_be_true = "$var can only be set to true when running with CN. Please set use_cn to true.";
}
if ($cannot_be_true) {
@@ -3106,7 +3170,7 @@ sub setup_logic_spinup {
if ( $nl_flags->{'bgc_mode'} eq "sp" && defined($nl->get_value('override_bgc_restart_mismatch_dump'))) {
$log->fatal_error("CN must be on if override_bgc_restart_mismatch_dump is set.");
}
- if ( $nl_flags->{'clm_accelerated_spinup'} eq "on" ) {
+ if ( $nl_flags->{'clm_accelerated_spinup'} =~ /on|sasu/ ) {
foreach my $var ( "hist_nhtfrq", "hist_fincl1", "hist_empty_htapes", "hist_mfilt" ) {
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl,
$var, use_cn=>$nl_flags->{'use_cn'}, use_fates=>$nl_flags->{'use_fates'},
@@ -3161,7 +3225,6 @@ sub setup_logic_supplemental_nitrogen {
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl,
'suplnitro', 'use_fates'=>$nl_flags->{'use_fates'});
}
-
#
# Error checking for suplnitro
#
@@ -3586,25 +3649,6 @@ sub setup_logic_grainproduct {
#-------------------------------------------------------------------------------
-sub setup_logic_dynamic_roots {
- #
- # dynamic root model
- #
- my ($opts, $nl_flags, $definition, $defaults, $nl, $physv) = @_;
-
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_dynroot', 'phys'=>$physv->as_string(), 'bgc_mode'=>$nl_flags->{'bgc_mode'});
- my $use_dynroot = $nl->get_value('use_dynroot');
- if ( &value_is_true($use_dynroot) && ($nl_flags->{'bgc_mode'} eq "sp") ) {
- $log->fatal_error("Cannot turn dynroot mode on mode bgc=sp\n" .
- "Set the bgc mode to 'bgc'.");
- }
- if ( &value_is_true( $use_dynroot ) && &value_is_true( $nl_flags->{'use_hydrstress'} ) ) {
- $log->fatal_error("Cannot turn use_dynroot on when use_hydrstress is on" );
- }
-}
-
-#-------------------------------------------------------------------------------
-
sub setup_logic_c_isotope {
#
# Error checking for C-isotope options
@@ -3687,10 +3731,10 @@ sub setup_logic_nitrogen_deposition {
'use_cn'=>$nl_flags->{'use_cn'}, 'hgrid'=>$nl_flags->{'res'},
'clm_accelerated_spinup'=>$nl_flags->{'clm_accelerated_spinup'} );
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'ndep_taxmode', 'phys'=>$nl_flags->{'phys'},
- 'use_cn'=>$nl_flags->{'use_cn'},
+ 'use_cn'=>$nl_flags->{'use_cn'},
'lnd_tuning_mode'=>$nl_flags->{'lnd_tuning_mode'} );
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'ndep_varlist', 'phys'=>$nl_flags->{'phys'},
- 'use_cn'=>$nl_flags->{'use_cn'},
+ 'use_cn'=>$nl_flags->{'use_cn'},
'lnd_tuning_mode'=>$nl_flags->{'lnd_tuning_mode'} );
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_year_first_ndep', 'phys'=>$nl_flags->{'phys'},
'use_cn'=>$nl_flags->{'use_cn'}, 'sim_year'=>$nl_flags->{'sim_year'},
@@ -3893,7 +3937,7 @@ sub setup_logic_urbantv_streams {
'sim_year_range'=>$nl_flags->{'sim_year_range'});
}
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_fldfilename_urbantv', 'phys'=>$nl_flags->{'phys'},
- 'hgrid'=>"0.9x1.25" );
+ 'hgrid'=>"0.9x1.25", 'urban_explicit_ac'=>$nl->get_value('urban_explicit_ac') );
if ($opts->{'driver'} eq "nuopc" ) {
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_meshfile_urbantv', 'phys'=>$nl_flags->{'phys'},
'hgrid'=>"0.9x1.25" );
@@ -3985,50 +4029,65 @@ sub setup_logic_fire_emis {
#-------------------------------------------------------------------------------
sub setup_logic_dust_emis {
- # Logic to handle the dust emissions
- my ($opts, $nl_flags, $definition, $defaults, $nl) = @_;
+ # Logic to handle the dust emissions namelists, both drv_flds_in and lnd_in files
+ my ($opts, $nl_flags, $definition, $defaults, $nl, $envxml_ref) = @_;
- # First get the dust emission method
- my $var = "dust_emis_method";
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var );
-
- my $dust_emis_method = remove_leading_and_trailing_quotes( $nl->get_value($var) );
-
- my @zender_files_in_lnd_opts = ( "stream_fldfilename_zendersoilerod", "stream_meshfile_zendersoilerod",
- "zendersoilerod_mapalgo" );
- if ( $dust_emis_method eq "Zender_2003" ) {
- # get the zender_soil_erod_source
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl,
- "zender_soil_erod_source", 'dust_emis_method'=>$dust_emis_method );
-
- my $zender_source = remove_leading_and_trailing_quotes( $nl->get_value('zender_soil_erod_source') );
- if ( $zender_source eq "lnd" ) {
- foreach my $option ( @zender_files_in_lnd_opts ) {
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $option,
- 'dust_emis_method'=>$dust_emis_method, 'zender_soil_erod_source'=>$zender_source,
- 'hgrid'=>$nl_flags->{'res'}, 'lnd_tuning_mod'=>$nl_flags->{'lnd_tuning_mode'} );
- }
- } else {
- foreach my $option ( @zender_files_in_lnd_opts ) {
- if ( defined($nl->get_value($option)) ) {
- $log->fatal_error("zender_soil_erod_source is NOT lnd, but the file option $option is being set" .
- " and should NOT be unless you want it handled here in the LAND model, " .
- "otherwise the equivalent option is set in CAM" );
- }
- }
- }
+ # Only set dust emission settings -- if not connected to CAM
+ my $lnd_sets_dust = logical_to_fortran($envxml_ref->{'LND_SETS_DUST_EMIS_DRV_FLDS'});
+ if ( &value_is_true( $lnd_sets_dust)) {
+
+ # First get the dust emission method
+ my $var = "dust_emis_method";
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var );
+ my $dust_emis_method = remove_leading_and_trailing_quotes( $nl->get_value($var) );
+
+ my @zender_files_in_lnd_opts = ( "stream_fldfilename_zendersoilerod", "stream_meshfile_zendersoilerod",
+ "zendersoilerod_mapalgo" );
+ if ( $dust_emis_method eq "Zender_2003" ) {
+ # get the zender_soil_erod_source
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl,
+ "zender_soil_erod_source", 'dust_emis_method'=>$dust_emis_method );
+
+ my $zender_source = remove_leading_and_trailing_quotes( $nl->get_value('zender_soil_erod_source') );
+ if ( $zender_source eq "lnd" ) {
+ foreach my $option ( @zender_files_in_lnd_opts ) {
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $option,
+ 'dust_emis_method'=>$dust_emis_method, 'zender_soil_erod_source'=>$zender_source,
+ 'hgrid'=>$nl_flags->{'res'}, 'lnd_tuning_mode'=>$nl_flags->{'lnd_tuning_mode'} );
+ }
+ } elsif ( $zender_source eq "atm" ) {
+ foreach my $option ( @zender_files_in_lnd_opts ) {
+ if ( defined($nl->get_value($option)) ) {
+ $log->fatal_error("zender_soil_erod_source is atm, and the file option $option is being set" .
+ " which should NOT be unless you want it handled here in the LAND model, " .
+ "otherwise the equivalent option is set in CAM" );
+ }
+ }
+ } elsif ( $zender_source eq "none" ) {
+ $log->fatal_error("zender_soil_erod_source is set to none and only atm or lnd should be used when $var is Zender_2002" );
+ }
+ } else {
+ # Verify that NONE of the Zender options are being set if Zender is NOT being used
+ push @zender_files_in_lnd_opts, "zender_soil_erod_source";
+ foreach my $option ( @zender_files_in_lnd_opts ) {
+ if ( defined($nl->get_value($option)) ) {
+ $log->fatal_error("dust_emis_method is NOT set to Zender_2003, but one of it's options " .
+ "$option is being set, need to change one or the other" );
+ }
+ }
+ if ( $dust_emis_method eq "Leung_2023" ) {
+ $log->warning("dust_emis_method is Leung_2023 and that option has NOT been brought into CTSM yet");
+ }
+ }
+ # Otherwise make sure dust settings are NOT being set in CLM
} else {
- # Verify that NONE of the Zender options are being set if Zender is NOT being used
- push @zender_files_in_lnd_opts, "zender_soil_erod_source";
- foreach my $option ( @zender_files_in_lnd_opts ) {
- if ( defined($nl->get_value($option)) ) {
- $log->fatal_error("dust_emis_method is NOT set to Zender_2003, but one of it's options " .
- "$option is being set, need to change one or the other" );
- }
- }
- if ( $dust_emis_method eq "Leung_2023" ) {
- $log->warning("dust_emis_method is Leung_2023 and that option has NOT been brought into CTSM yet");
- }
+ my @vars = ( "dust_emis_method", "zender_soil_erod_source" );
+ foreach my $option ( @vars ) {
+ if ( defined($nl->get_value($option)) ) {
+ $log->fatal_error("Dust emission variable is being set in CTSM, which should NOT be done when" .
+ " connected to CAM as CAM should set them");
+ }
+ }
}
}
@@ -4169,52 +4228,137 @@ sub setup_logic_lai_streams {
sub setup_logic_cropcal_streams {
my ($opts, $nl_flags, $definition, $defaults, $nl) = @_;
- # Set first and last stream years
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_year_first_cropcal',
- 'sim_year'=>$nl_flags->{'sim_year'},
- 'sim_year_range'=>$nl_flags->{'sim_year_range'});
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_year_last_cropcal',
- 'sim_year'=>$nl_flags->{'sim_year'},
- 'sim_year_range'=>$nl_flags->{'sim_year_range'});
-
- # Set align year, if first and last years are different
- if ( $nl->get_value('stream_year_first_cropcal') !=
- $nl->get_value('stream_year_last_cropcal') ) {
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl,
- 'model_year_align_cropcal', 'sim_year'=>$nl_flags->{'sim_year'},
- 'sim_year_range'=>$nl_flags->{'sim_year_range'});
- }
-
# Set up other crop calendar parameters
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'cropcals_rx');
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'cropcals_rx_adapt');
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_gdd20_seasons');
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'flush_gdd20');
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'generate_crop_gdds');
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_mxmat');
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_meshfile_cropcal');
+
+ # These can't both be true
+ my $cropcals_rx = $nl->get_value('cropcals_rx') ;
+ my $cropcals_rx_adapt = $nl->get_value('cropcals_rx_adapt') ;
+ if (&value_is_true($cropcals_rx) and &value_is_true($cropcals_rx_adapt)) {
+ $log->fatal_error("cropcals_rx and cropcals_rx_adapt may not both be true" );
+ }
+
+ # Add defaults if reading gdd20 seasons from stream files
+ my $stream_gdd20_seasons = $nl->get_value('stream_gdd20_seasons') ;
+ if ( &value_is_true($stream_gdd20_seasons)) {
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_fldFileName_gdd20_season_start');
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_fldFileName_gdd20_season_end');
+
+ # Check
+ my $gdd20_season_start_file = $nl->get_value('stream_fldFileName_gdd20_season_start') ;
+ my $gdd20_season_end_file = $nl->get_value('stream_fldFileName_gdd20_season_end') ;
+ if ( &string_is_undef_or_empty($gdd20_season_start_file) or &string_is_undef_or_empty($gdd20_season_end_file) ) {
+ $log->message($gdd20_season_start_file);
+ $log->message($gdd20_season_end_file);
+ $log->fatal_error("If stream_gdd20_seasons is true, gdd20 season start and end files must be provided." );
+ }
+ }
- # Option checks
- my $generate_crop_gdds = $nl->get_value('generate_crop_gdds') ;
- my $use_mxmat = $nl->get_value('use_mxmat') ;
+ # Add defaults if using prescribed crop calendars
+ if ( &value_is_true($cropcals_rx) or &value_is_true($cropcals_rx_adapt) ) {
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_fldFileName_swindow_start');
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_fldFileName_swindow_end');
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_fldfilename_cultivar_gdds');
+ if ( &value_is_true($cropcals_rx_adapt) ) {
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_fldFileName_gdd20_baseline', 'stream_gdd20_seasons'=>$stream_gdd20_seasons);
+ }
+ }
+
+ # Add defaults if using any crop calendar input files
my $swindow_start_file = $nl->get_value('stream_fldFileName_swindow_start') ;
my $swindow_end_file = $nl->get_value('stream_fldFileName_swindow_end') ;
my $gdd_file = $nl->get_value('stream_fldFileName_cultivar_gdds') ;
+ my $gdd20_baseline_file = $nl->get_value('stream_fldFileName_gdd20_baseline') ;
my $mesh_file = $nl->get_value('stream_meshfile_cropcal') ;
- if ( ($swindow_start_file eq '' and $swindow_start_file ne '') or ($swindow_start_file ne '' and $swindow_start_file eq '') ) {
- $log->fatal_error("When specifying sowing window dates, you must provide both swindow_start_file and swindow_end_file. To specify exact sowing dates, use the same file." );
+ if ( !&string_is_undef_or_empty($swindow_start_file) or !&string_is_undef_or_empty($swindow_end_file) or !&string_is_undef_or_empty($gdd_file) or !&string_is_undef_or_empty($gdd20_baseline_file)) {
+
+ # User gave an input file without specifying cropcals_rx or cropcals_rx_adapt = .true.
+ # Requiring this means nothing to the code, but helps namelist make more sense
+ if ( !&value_is_true($cropcals_rx) and !&value_is_true($cropcals_rx_adapt) ){
+ $log->fatal_error("If providing any crop calendar input file(s), cropcals_rx or cropcals_rx_adapt must be true" );
+ }
+
+ # User set cropcals_rx_adapt to true but set stream_fldFileName_gdd20_baseline to empty
+ if ( &value_is_true($cropcals_rx_adapt) and &string_is_undef_or_empty($gdd20_baseline_file) ) {
+ $log->fatal_error("If cropcals_rx_adapt is true, stream_fldFileName_gdd20_baseline must be provided" );
+ }
+
+ # cropcals_rx_adapt is false but user provided stream_fldFileName_gdd20_baseline
+ if ( !&value_is_true($cropcals_rx_adapt) and !&string_is_undef_or_empty($gdd20_baseline_file) ) {
+ $log->fatal_error("If stream_fldFileName_gdd20_baseline provided, cropcals_rx_adapt must be true" );
+ }
+
+ # User provided an input file but set mesh file to empty
+ if ( &string_is_undef_or_empty($mesh_file) ) {
+ $log->fatal_error("If providing any crop calendar input file(s), you must provide stream_meshfile_cropcal" );
+ }
+
+ # Set stream years
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_year_first_cropcal_swindows',
+ 'sim_year'=>$nl_flags->{'sim_year'},
+ 'sim_year_range'=>$nl_flags->{'sim_year_range'});
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_year_last_cropcal_swindows',
+ 'sim_year'=>$nl_flags->{'sim_year'},
+ 'sim_year_range'=>$nl_flags->{'sim_year_range'});
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'model_year_align_cropcal_swindows',
+ 'sim_year'=>$nl_flags->{'sim_year'},
+ 'sim_year_range'=>$nl_flags->{'sim_year_range'});
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_year_first_cropcal_cultivar_gdds',
+ 'sim_year'=>$nl_flags->{'sim_year'},
+ 'sim_year_range'=>$nl_flags->{'sim_year_range'});
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'stream_year_last_cropcal_cultivar_gdds',
+ 'sim_year'=>$nl_flags->{'sim_year'},
+ 'sim_year_range'=>$nl_flags->{'sim_year_range'});
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'model_year_align_cropcal_cultivar_gdds',
+ 'sim_year'=>$nl_flags->{'sim_year'},
+ 'sim_year_range'=>$nl_flags->{'sim_year_range'});
+
+ # Do not allow maturity requirements to change over time if stream_fldFileName_gdd20_baseline is provided. That would be nonsensical.
+ if ( $nl->get_value('stream_year_first_cropcal_cultivar_gdds') !=
+ $nl->get_value('stream_year_last_cropcal_cultivar_gdds')
+ and !&string_is_undef_or_empty($gdd20_baseline_file) ) {
+ $log->fatal_error("If cropcals_rx_adapt is true (i.e., stream_fldFileName_gdd20_baseline is provided), baseline maturity requirements are allowed to vary over time (i.e., stream_year_first_cropcal_cultivar_gdds and stream_year_last_cropcal_cultivar_gdds must be the same)." );
+ }
+ }
+
+ # If running with prescribed crop calendars, certain files must be provided
+ my $generate_crop_gdds = $nl->get_value('generate_crop_gdds') ;
+ if ( &value_is_true($cropcals_rx) or &value_is_true($cropcals_rx_adapt) ) {
+ if ( &string_is_undef_or_empty($swindow_start_file) or &string_is_undef_or_empty($swindow_end_file) ) {
+ $log->fatal_error("If cropcals_rx or cropcals_rx_adapt is true, sowing window start and end files must be provided. To specify exact sowing dates, use the same file." );
+ }
+ if ( &string_is_undef_or_empty($gdd_file) and (! &value_is_true($generate_crop_gdds)) ){
+ $log->fatal_error("If cropcals_rx or cropcals_rx_adapt is true and generate_crop_gdds is false, maturity requirement file stream_fldFileName_cultivar_gdds must be provided" );
+ }
+ }
+
+ # Option checks
+ if ( &string_is_undef_or_empty($gdd_file) and ! &string_is_undef_or_empty($gdd20_baseline_file) ) {
+ $log->fatal_error("If not providing stream_fldFileName_cultivar_gdds, don't provide stream_fldFileName_gdd20_baseline");
}
- if ( $generate_crop_gdds eq '.true.' ) {
- if ( $use_mxmat eq '.true.' ) {
+ if ( &value_is_true($generate_crop_gdds) ) {
+ my $use_mxmat = $nl->get_value('use_mxmat') ;
+ if ( &value_is_true($use_mxmat) ) {
$log->fatal_error("If generate_crop_gdds is true, you must also set use_mxmat to false" );
}
- if ( $swindow_start_file eq '' or $swindow_end_file eq '' ) {
+ if ( &string_is_undef_or_empty($swindow_start_file) or &string_is_undef_or_empty($swindow_end_file) ) {
$log->fatal_error("If generate_crop_gdds is true, you must specify stream_fldFileName_swindow_start and stream_fldFileName_swindow_end")
}
if ( $swindow_start_file ne $swindow_end_file ) {
$log->fatal_error("If generate_crop_gdds is true, you must specify exact sowing dates by setting stream_fldFileName_swindow_start and stream_fldFileName_swindow_end to the same file")
}
- if ( $gdd_file ne '' ) {
+ if ( ! &string_is_undef_or_empty($gdd_file) ) {
$log->fatal_error("If generate_crop_gdds is true, do not specify stream_fldFileName_cultivar_gdds")
}
- }
- if ( $mesh_file eq '' and ( $swindow_start_file ne '' or $gdd_file ne '' ) ) {
- $log->fatal_error("If prescribing crop sowing dates and/or maturity requirements, you must specify stream_meshfile_cropcal")
+ if ( ! &string_is_undef_or_empty($gdd20_baseline_file) ) {
+ $log->fatal_error("If generate_crop_gdds is true, do not specify stream_fldFileName_gdd20_baseline")
+ }
}
}
@@ -4512,21 +4656,35 @@ sub setup_logic_fates {
if (&value_is_true( $nl_flags->{'use_fates'}) ) {
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fates_paramfile', 'phys'=>$nl_flags->{'phys'});
my @list = ( "fates_spitfire_mode", "use_fates_planthydro", "use_fates_ed_st3", "use_fates_ed_prescribed_phys",
- "use_fates_inventory_init","use_fates_fixed_biogeog","use_fates_nocomp","fates_seeddisp_cadence",
- "use_fates_logging","fates_parteh_mode", "use_fates_cohort_age_tracking","use_fates_tree_damage",
- "use_fates_luh","fates_history_dimlevel" );
+ "use_fates_inventory_init","fates_seeddisp_cadence","fates_history_dimlevel",
+ "fates_harvest_mode","fates_parteh_mode", "use_fates_cohort_age_tracking","use_fates_tree_damage" );
+
foreach my $var ( @list ) {
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, 'use_fates'=>$nl_flags->{'use_fates'},
- 'use_fates_sp'=>$nl_flags->{'use_fates_sp'} );
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, 'use_fates'=>$nl_flags->{'use_fates'},
+ 'use_fates_sp'=>$nl_flags->{'use_fates_sp'} );
}
+
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_potentialveg', 'use_fates'=>$nl_flags->{'use_fates'});
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_lupft', 'use_fates'=>$nl_flags->{'use_fates'});
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_luh', 'use_fates'=>$nl_flags->{'use_fates'},
+ 'use_fates_lupft'=>$nl->get_value('use_fates_lupft'),
+ 'use_fates_potentialveg'=>$nl->get_value('use_fates_potentialveg'),
+ 'fates_harvest_mode'=>remove_leading_and_trailing_quotes($nl->get_value('fates_harvest_mode')) );
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_nocomp', 'use_fates'=>$nl_flags->{'use_fates'},
+ 'use_fates_lupft'=>$nl->get_value('use_fates_lupft'),
+ 'use_fates_sp'=>$nl_flags->{'use_fates_sp'} );
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_fates_fixed_biogeog', 'use_fates'=>$nl_flags->{'use_fates'},
+ 'use_fates_lupft'=>$nl->get_value('use_fates_lupft'),
+ 'use_fates_sp'=>$nl_flags->{'use_fates_sp'} );
+
my $suplnitro = $nl->get_value('suplnitro');
my $parteh_mode = $nl->get_value('fates_parteh_mode');
if ( ($parteh_mode == 1) && ($suplnitro !~ /ALL/) && not &value_is_true( $nl_flags->{'use_fates_sp'}) ) {
- $log->fatal_error("supplemental Nitrogen (suplnitro) is NOT set to ALL, FATES is on, " .
- "but and FATES-SP is not active, but fates_parteh_mode is 1, so Nitrogen is not active" .
+ $log->fatal_error("supplemental Nitrogen (suplnitro) is NOT set to ALL, FATES is on, " .
+ "but and FATES-SP is not active, but fates_parteh_mode is 1, so Nitrogen is not active" .
"Change suplnitro back to ALL");
}
- #
+
# For FATES SP mode make sure no-competetiion, and fixed-biogeography are also set
# And also check for other settings that can't be trigged on as well
#
@@ -4543,6 +4701,12 @@ sub setup_logic_fates {
if ( $nl->get_value('fates_spitfire_mode') > 0 ) {
$log->fatal_error('fates_spitfire_mode can NOT be set to greater than 0 when use_fates_sp is true');
}
+
+ # fates landuse can't be on with FATES SP mode is active
+ if ( &value_is_true($nl->get_value('use_fates_luh')) ) {
+ $log->fatal_error('use_fates_luh can NOT be true when use_fates_sp is true');
+ }
+
# hydro isn't currently supported to work when FATES SP mode is active
if (&value_is_true( $nl->get_value('use_fates_planthydro') )) {
$log->fatal_error('fates sp mode is currently not supported to work with fates hydro');
@@ -4561,22 +4725,210 @@ sub setup_logic_fates {
}
}
}
+ # make sure that fates landuse x pft mode has the necessary run mode configurations
+ my $var = "use_fates_lupft";
+ if ( defined($nl->get_value($var)) ) {
+ if ( &value_is_true($nl->get_value($var)) ) {
+ my @list = ( "use_fates_luh", "use_fates_nocomp", "use_fates_fixed_biogeog" );
+ foreach my $var ( @list ) {
+ if ( ! &value_is_true($nl->get_value($var)) ) {
+ $log->fatal_error("$var is required when use_fates_lupft is true" );
+ }
+ }
+ }
+ }
+ # check that fates landuse change mode has the necessary luh2 landuse timeseries data
+ # and add the default if not defined. Do not add default if use_fates_potentialveg is true.
+ # If fixed biogeography is on, make sure that flandusepftdat is avilable.
my $var = "use_fates_luh";
if ( defined($nl->get_value($var)) ) {
if ( &value_is_true($nl->get_value($var)) ) {
- $var = "fluh_timeseries";
- add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, 'phys'=>$nl_flags->{'phys'}, 'hgrid'=>$nl_flags->{'res'}, 'sim_year_range'=>$nl_flags->{'sim_year_range'}, nofail=>1 );
+ $var = "use_fates_potentialveg";
+ if ( defined($nl->get_value($var)) ) {
+ if ( ! &value_is_true($nl->get_value($var)) ) {
+ $var = "fluh_timeseries";
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, 'use_fates'=>$nl_flags->{'use_fates'},
+ 'hgrid'=>$nl_flags->{'res'}, 'sim_year_range'=>$nl_flags->{'sim_year_range'});
+ my $fname = remove_leading_and_trailing_quotes( $nl->get_value($var) );
+ if ( ! defined($nl->get_value($var)) ) {
+ $log->fatal_error("$var is required when use_fates_luh is set and use_fates_potentialveg is false" );
+ } elsif ( ! -f "$fname" ) {
+ $log->fatal_error("$var does NOT point to a valid filename" );
+ }
+ }
+ }
+ $var = "use_fates_fixed_biogeog";
+ if ( defined($nl->get_value($var)) ) {
+ if ( &value_is_true($nl->get_value($var)) ) {
+ $var = "flandusepftdat";
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var, 'use_fates'=>$nl_flags->{'use_fates'},
+ 'phys'=>$nl_flags->{'phys'}, 'hgrid'=>$nl_flags->{'res'}, nofail=>1 );
+ my $fname = remove_leading_and_trailing_quotes( $nl->get_value($var) );
+ if ( ! defined($nl->get_value($var)) ) {
+ $log->fatal_error("$var is required when use_fates_luh and use_fates_fixed_biogeog is set" );
+ } elsif ( ! -f "$fname" ) {
+ $log->fatal_error("$var does NOT point to a valid filename" );
+ }
+ }
+ }
+ }
+ }
+ # check that fates landuse is on and harvest mode is off when potential veg switch is true
+ my $var = "use_fates_potentialveg";
+ if ( defined($nl->get_value($var)) ) {
+ if ( &value_is_true($nl->get_value($var)) ) {
+ if ( ! &value_is_true($nl->get_value('use_fates_luh')) ) {
+ $log->fatal_error("use_fates_luh must be true when $var is true" );
+ }
+ my $var = remove_leading_and_trailing_quotes($nl->get_value('fates_harvest_mode'));
+ if ( $var ne 'no_harvest') {
+ $log->fatal_error("fates_harvest_mode set to $var. It must set to no_harvest when use_potential_veg is true." );
+ }
+ my $var = "fluh_timeseries";
+ if ( defined($nl->get_value($var)) ) {
+ $log->fatal_error("fluh_timeseries can not be defined when use_fates_potentialveg is true" );
+ }
+ }
+ }
+ # Check fates_harvest_mode compatibility
+ my $var = "fates_harvest_mode";
+ if ( defined($nl->get_value($var)) ) {
+ # using fates_harvest mode with raw luh2 harvest data
+ my $mode = remove_leading_and_trailing_quotes($nl->get_value($var));
+ if ( $mode eq 'luhdata_area' || $mode eq 'luhdata_mass' ) {
+ # Make sure that use_fates_luh is true when using raw fates luh2 harvest data
+ if ( ! &value_is_true($nl->get_value('use_fates_luh')) ) {
+ $log->fatal_error("use_fates_luh is required to be true when $var is luhdata_mass or luhdata_area" );
+ }
+ } elsif ( $mode eq 'landuse_timeseries' ) {
+ # Check to make sure that the user set the flanduse_timeseries file
+ # Since the flanduse_timeseries logic checking is upstream of the fates logic,
+ # don't add the default here. The onus is on the user to match the correct timeseries
+ # data to the correct surface dataset resolution
+ my $var = "flanduse_timeseries";
my $fname = remove_leading_and_trailing_quotes( $nl->get_value($var) );
if ( ! defined($nl->get_value($var)) ) {
- $log->fatal_error("$var is required when use_fates_luh is set" );
+ $log->fatal_error("$var is required when fates_harvest_mode is landuse_timeseries" );
} elsif ( ! -f "$fname" ) {
- $log->fatal_error("$fname does NOT point to a valid filename" );
+ $log->fatal_error("$var does NOT point to a valid filename" );
}
}
}
}
}
+
+#-------------------------------------------------------------------------------
+
+sub setup_logic_cnmatrix {
+ #
+ # Set some default options related to the CN Matrix options
+ #
+ my ($opts, $nl_flags, $definition, $defaults, $nl, $envxml_ref) = @_;
+
+ my @matrixlist = ( "use_matrixcn", "hist_wrt_matrixcn_diag" );
+ foreach my $var ( @matrixlist ) {
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var
+ , 'use_fates'=>$nl_flags->{'use_fates'}, 'bgc_mode'=>$nl_flags->{'bgc_mode'}
+ , 'phys'=>$nl_flags->{'phys'}, 'use_soil_matrixcn'=>$nl_flags->{'use_soil_matrixcn'},
+ , 'spinup_matrixcn'=>$nl_flags->{'spinup_matrixcn'}, 'clm_accelerated_spinup'=>$nl_flags->{'clm_accelerated_spinup'} );
+ }
+ @matrixlist = ( "use_matrixcn", "use_soil_matrixcn", "hist_wrt_matrixcn_diag", "spinup_matrixcn" );
+ # Matrix items can't be on for OMP_NUM_THREADS (also known as NTHRDS_LND) > 1
+ my $var_xml = "OMP_NUM_THREADS";
+ my $val_xml = $ENV{$var_xml};
+ if ( $val_xml > 1) {
+ foreach my $var ( @matrixlist ) {
+ if ( &value_is_true($nl->get_value($var)) ) {
+ $log->warning("$var and $var_xml > 1 (in this case $val_xml) causes a clm threading test to FAIL (as of 2024/7/10), so use at your own risk." );
+ }
+ }
+ }
+
+ # Matrix items can't be on for transient
+ if (not string_is_undef_or_empty($nl->get_value('flanduse_timeseries'))) {
+ foreach my $var ( @matrixlist ) {
+ if ( &value_is_true($nl->get_value($var)) ) {
+ $log->warning("$var may FAIL with balance error in transient mode" );
+ }
+ }
+ }
+ # Matrix items can't be on for SP mode
+ if ( $nl_flags->{'bgc_mode'} eq "sp" ) {
+ foreach my $var ( @matrixlist ) {
+ if ( &value_is_true($nl->get_value($var)) ) {
+ $log->fatal_error("$var can NOT be on for SP mode" );
+ }
+ }
+ # Matrix items can't be on for FATES
+ } elsif ( $nl_flags->{'bgc_mode'} eq "fates" ) {
+ foreach my $var ( @matrixlist ) {
+ if ( &value_is_true($nl->get_value($var)) ) {
+ $log->fatal_error("$var can NOT be on with FATES" );
+ }
+ }
+ # Otherwise for CN or BGC mode
+ } else {
+ # TODO (slevis 2023/12/1) The next two if statements do nothing. Erik K and Sam L found that
+ # for_testing_use_second_grain_pool and for_testing_use_repr_structure_pool
+ # are empty rather than .true. or .false., but we did not get to the bottom
+ # of why, yet. The same error-check in the code does get triggered at run-time,
+ # so we will not pursue fixing this right now.
+ # If matrixcn is on, for_testing_use_second_grain_pool and for_testing_use_repr_structure_pool must be off
+ if ( &value_is_true($nl->get_value("use_matrixcn")) && &value_is_true($nl_flags->{"for_testing_use_second_grain_pool"}) ) {
+ $log->fatal_error("for_testing_use_second_grain_pool can NOT be on when use_matrixcn is on" );
+ }
+ if ( &value_is_true($nl->get_value("use_matrixcn")) && &value_is_true($nl_flags->{"for_testing_use_repr_structure_pool"}) ) {
+ $log->fatal_error("for_testing_use_repr_structure_pool can NOT be on when use_matrixcn is on" );
+ }
+ # If both matrixcn and soil_matrix are off hist_wrt_matrixcn_diag can't be on
+ if ( ! &value_is_true($nl->get_value("use_matrixcn")) && ! &value_is_true($nl_flags->{"use_soil_matrixcn"}) ) {
+ my $var = "hist_wrt_matrixcn_diag";
+ if ( &value_is_true($nl->get_value($var)) ) {
+ $log->fatal_error("$var can NOT be on when both use_matrixcn and use_soil_matrixcn are off" );
+ }
+ }
+ # If soil_matrix is off spinup_matrixcn can't be on
+ if ( ! &value_is_true($nl_flags->{"use_soil_matrixcn"}) ) {
+ my $var = "spinup_matrixcn";
+ if ( &value_is_true($nl->get_value($var)) ) {
+ $log->fatal_error("$var can NOT be on when use_soil_matrixcn is off" );
+ }
+ }
+ }
+ # if soil matrix is on and spinup is on, set spinup specific variables
+ my @spinup_vars = ( "nyr_forcing", "nyr_sasu", "iloop_avg" );
+ foreach my $var ( @spinup_vars ) {
+ if ( &value_is_true($nl_flags->{"use_soil_matrixcn"}) && &value_is_true($nl_flags->{'spinup_matrixcn'}) ) {
+ if ( $var ne "nyr_sasu" ) {
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var,
+ , 'phys'=>$nl_flags->{'phys'}, 'spinup_matrixcn'=>$nl_flags->{'spinup_matrixcn'} );
+ } else {
+ # Set SASU spinup period to nyr_forcing (slow mode) by default
+ add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, $var,
+ , 'val'=>$nl->get_value("nyr_forcing") );
+ }
+ my $val = $nl->get_value($var);
+ if ( $val == -999 && ($var eq "iloop_avg") ) { next; } # iloop_avg can be special flag value
+ if ( $val < 1 ) {
+ $log->fatal_error("$var can NOT be negative or zero" );
+ }
+ } else {
+ my $val = $nl->get_value($var);
+ if ( defined($val) ) {
+ $log->fatal_error("$var can NOT be set when use_soil_matrixcn and isspsinup are off" );
+ }
+ }
+ }
+ if ( &value_is_true($nl_flags->{"use_soil_matrixcn"}) && &value_is_true($nl_flags->{'spinup_matrixcn'}) ) {
+ my $nyr_forcing = $nl->get_value('nyr_forcing');
+ my $nyr_sasu = $nl->get_value('nyr_sasu');
+ if ( $nyr_sasu > $nyr_forcing ) {
+ $log->fatal_error("nyr_sasu can NOT be greater than nyr_forcing" );
+ }
+ }
+}
+
#-------------------------------------------------------------------------------
sub setup_logic_exice {
#
@@ -4792,7 +5144,7 @@ sub write_output_files {
$log->verbose_message("Writing clm namelist to $outfile");
# Drydep, fire-emission or MEGAN namelist for driver
- @groups = qw(drydep_inparm megan_emis_nl fire_emis_nl carma_inparm);
+ @groups = qw(drydep_inparm megan_emis_nl fire_emis_nl carma_inparm dust_emis_inparm);
$outfile = "$opts->{'dir'}/drv_flds_in";
$nl->write($outfile, 'groups'=>\@groups, 'note'=>"$note" );
$log->verbose_message("Writing @groups namelists to $outfile");
diff --git a/bld/env_run.xml b/bld/env_run.xml
index f3b7467168..cd865ad82c 100644
--- a/bld/env_run.xml
+++ b/bld/env_run.xml
@@ -9,6 +9,7 @@ Sample env_run.xml file that allows build-namelist to be run for testing in this
-->
+
diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml
index 7ce2235a84..fc72b36942 100644
--- a/bld/namelist_files/namelist_defaults_ctsm.xml
+++ b/bld/namelist_files/namelist_defaults_ctsm.xml
@@ -47,11 +47,13 @@ attributes from the config_cache.xml file (with keys converted to upper-case).
off
-2
-1
-2
-1
-0
+2
+1
+2
+1
+0
+0
+0
.true.
@@ -66,7 +68,8 @@ attributes from the config_cache.xml file (with keys converted to upper-case).
.false.
-.true.
+.true.
+.true.
'TOTECOSYSC','TOTECOSYSN','TOTSOMC','TOTSOMN','TOTVEGC','TOTVEGN','TLAI','GPP','NPP','TWS','TSAI','HTOP','HBOT'
'TOTSOMC','TOTSOMN','TLAI','GPP','NPP','TWS'
'TLAI','TWS'
--8760
-20
+'TOTECOSYSC','TOTECOSYSN','TOTSOMC','TOTSOMN','TOTVEGC','TOTVEGN','TLAI','GPP','NPP','TWS','TSAI','HTOP','HBOT'
+'TOTECOSYSC','TOTECOSYSN','TOTSOMC','TOTSOMN','TOTVEGC','TOTVEGN','TLAI','GPP','CPOOL','NPP','TWS'
+'TOTSOMC','TOTSOMN','TLAI','GPP','NPP','TWS'
+'TLAI','TWS'
+-8760
+-8760
+20
+20
.false.
@@ -124,9 +137,10 @@ attributes from the config_cache.xml file (with keys converted to upper-case).
.false.
-1
-0
-0
+1
+0
+0
+0
NONE
@@ -146,6 +160,12 @@ attributes from the config_cache.xml file (with keys converted to upper-case).
FAST
NONE
+
+.false.
+.false.
+.false.
+.false.
+
.false.
@@ -243,18 +263,24 @@ attributes from the config_cache.xml file (with keys converted to upper-case).
>30.0d00
30.0d00
+20.0d00
20.0d00
20.0d00
20.0d00
+20.0d00
20.0d00
20.0d00
20.0d00
+20.0d00
20.0d00
0.010d00
0.010d00
+0.008d00
0.008d00
0.008d00
0.008d00
+0.008d00
0.008d00
0.008d00
0.008d00
+0.008d00
0.008d00
-lnd/clm2/paramdata/fates_params_api.35.0.0_12pft_c240326.nc
+lnd/clm2/paramdata/fates_params_api.36.0.0_12pft_c240517.nc
@@ -568,9 +600,6 @@ attributes from the config_cache.xml file (with keys converted to upper-case).
.true.
-
-.false.
-
.false.
.true.
@@ -596,13 +625,36 @@ attributes from the config_cache.xml file (with keys converted to upper-case).
Standard
Uniform
.true.
-.true.
+.false.
+.true.
.false.
.true.
.false.
+
+
+.false.
+.true.
+
+.false.
+.true.
+
+.false.
+.false.
+.false.
+.true.
+.true.
+.false.
+1
+20
+
+1
+-999
+-999
+
+
.true.
@@ -635,7 +687,66 @@ attributes from the config_cache.xml file (with keys converted to upper-case).
For an exact match for these grids
======================================== -->
+
+.true.
+.true.
+.true.
+.true.
+
+.true.
+
+
+.true.
+
+
+.true.
+.true.
+.true.
+.true.
+
+.true.
+
+
+.true.
+
+
+
+.true.
+.true.
+.true.
+.true.
+
+.true.
+
+
+.true.
+
+
.true.
.true.
.true.
+.true.
.true.
@@ -734,6 +846,10 @@ attributes from the config_cache.xml file (with keys converted to upper-case).
>hgrid=0.9x1.25 maxpft=17 mask=gx1v7 use_cn=.true. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.false. glc_nec=10 do_transient_pfts=.false.
+
+
hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.false. glc_nec=10 do_transient_pfts=.false.
@@ -755,6 +871,10 @@ attributes from the config_cache.xml file (with keys converted to upper-case).
>hgrid=0.9x1.25 maxpft=17 mask=gx1v7 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.false. glc_nec=10 do_transient_pfts=.false.
+
+
hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.false. glc_nec=10 do_transient_pfts=.false.
@@ -777,6 +897,10 @@ attributes from the config_cache.xml file (with keys converted to upper-case).
>hgrid=1.9x2.5 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+hgrid=0.9x1.25 maxpft=17 mask=gx1v7 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
hgrid=0.9x1.25 maxpft=17 mask=gx1v7 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
@@ -800,6 +924,150 @@ attributes from the config_cache.xml file (with keys converted to upper-case).
>hgrid=1.9x2.5 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+
+
+hgrid=ne120np4.pg3 maxpft=79 mask=tx0.1v3 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+
+
+hgrid=0.9x1.25 maxpft=17 mask=gx1v7 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+hgrid=1.9x2.5 maxpft=17 mask=gx1v7 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+hgrid=ne0np4.ARCTIC.ne30x4 maxpft=17 mask=tx0.1v2 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+hgrid=ne0np4.ARCTICGRIS.ne30x8 maxpft=17 mask=tx0.1v2 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+
+hgrid=1.9x2.5 maxpft=17 mask=gx1v7 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+
+hgrid=ne0np4CONUS.ne30x8 maxpft=17 mask=tx0.1v2 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
+
+
+
+
lnd/clm2/initdata_map/clmi.I1850Clm45BgcCruGs.1101-01-01.0.9x1.25_gx1v7_simyr1850_c200806.nc
+lnd/clm2/initdata_map/clmi.B1850Clm45BgcGs.0161-01-01.0.9x1.25_gx1v7_simyr1850_c200806.nc
+
+
lnd/clm2/initdata_esmf/ctsm5.2/clmi.I1850Clm50BgcCropCru-ciso.1526-01-01.0.9x1.25_gx1v7_simyr1850_c240223.nc
+lnd/clm2/initdata_map/clmi.B1850Clm50BgcCrop.0161-01-01.0.9x1.25_gx1v7_simyr1850_c200729.nc
+
lnd/clm2/initdata_esmf/ctsm5.2/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c240223.nc
+>lnd/clm2/initdata_esmf/ctsm5.2/clmi.I2000Clm52BgcCrop.2000-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c240515.nc
@@ -1066,6 +1347,14 @@ attributes from the config_cache.xml file (with keys converted to upper-case).
>lnd/clm2/initdata_esmf/ctsm5.2/clmi.I2000Clm50BgcCrop.2011-01-01.1.9x2.5_gx1v7_gl4_simyr2000_c240223.nc
+
+lnd/clm2/initdata_map/clmi.BHIST.2000-01-01.0.9x1.25_gx1v7_simyr1979_c200806.nc
+
+
-
+
+lnd/clm2/initdata_map/clmi.BHIST.2000-01-01.0.9x1.25_gx1v7_simyr1979_c200806.nc
+
+
+lnd/clm2/initdata_map/clmi.BHIST.2000-01-01.1.9x2.5_gx1v7_simyr1979_c200806.nc
+
+
+
+lnd/clm2/initdata_map/clmi.FHISTSp.1979-01-01.ARCTIC_ne30x4_mt12_simyr1979_c200806.nc
+
+
+
+lnd/clm2/initdata_map/clmi.FHISTSp.1979-01-01.ARCTICGRIS_ne30x8_mt12_simyr1979_c200806.nc
+
+
+
+lnd/clm2/initdata_map/clmi.F2000.2000-01-01.ne120pg3_mt13_simyr2000_c200728.nc
+
+
+
+lnd/clm2/initdata_map/clmi.BHIST.2000-01-01.0.9x1.25_gx1v7_simyr2000_c200728.nc
+
+
+
+
+lnd/clm2/initdata_map/clmi.BHIST.2000-01-01.0.9x1.25_gx1v7_simyr2000_c200728.nc
+
+
+
+lnd/clm2/initdata_map/clmi.BHIST.2000-01-01.0.9x1.25_gx1v7_simyr2000_c200728.nc
+
+
+
+
+lnd/clm2/initdata_map/clmi.BHISTSp.2000-01-01.1.9x2.5_gx1v7_simyr2003_c200807.nc
+
+
+
+
+lnd/clm2/initdata_map/clmi.FHISTSp.2013-01-01.ne0CONUSne30x8_mt12_simyr2013_c200806.nc
+
+
+lnd/clm2/initdata_map/clmi.BHIST.2000-01-01.0.9x1.25_gx1v7_simyr1979_c200806.nc
+
+
+lnd/clm2/initdata_map/clmi.BHIST.2000-01-01.1.9x2.5_gx1v7_simyr1979_c200806.nc
+
+
+
+lnd/clm2/initdata_map/clmi.FHISTSp.1979-01-01.ARCTIC_ne30x4_mt12_simyr1979_c200806.nc
+
+
+
+lnd/clm2/initdata_map/clmi.FHISTSp.1979-01-01.ARCTICGRIS_ne30x8_mt12_simyr1979_c200806.nc
+
+
+
+lnd/clm2/initdata_map/clmi.F2000.2000-01-01.ne120pg3_mt13_simyr2000_c200728.nc
+
+
+
+lnd/clm2/initdata_map/clmi.BHIST.2000-01-01.0.9x1.25_gx1v7_simyr2000_c200728.nc
+
+
+
+lnd/clm2/initdata_map/clmi.BHISTSp.2000-01-01.1.9x2.5_gx1v7_simyr2003_c200807.nc
+
+
+
+
+lnd/clm2/initdata_map/clmi.FHISTSp.2013-01-01.ne0CONUSne30x8_mt12_simyr2013_c200806.nc
+
+
+lnd/clm2/initdata_map/clmi.BHIST.2000-01-01.0.9x1.25_gx1v7_simyr1979_c200806.nc
+
+
+lnd/clm2/initdata_map/clmi.BHIST.2000-01-01.1.9x2.5_gx1v7_simyr1979_c200806.nc
+
+
+
+lnd/clm2/initdata_map/clmi.FHISTSp.1979-01-01.ARCTIC_ne30x4_mt12_simyr1979_c200806.nc
+
+
+
+lnd/clm2/initdata_map/clmi.FHISTSp.1979-01-01.ARCTICGRIS_ne30x8_mt12_simyr1979_c200806.nc
+
+
+
+lnd/clm2/initdata_map/clmi.F2000.2000-01-01.ne120pg3_mt13_simyr2000_c200728.nc
+
+
+
+lnd/clm2/initdata_map/clmi.BHIST.2000-01-01.0.9x1.25_gx1v7_simyr2000_c200728.nc
+
+
+
+lnd/clm2/initdata_map/clmi.BHISTSp.2000-01-01.1.9x2.5_gx1v7_simyr2003_c200807.nc
+
+
+
+
+lnd/clm2/initdata_map/clmi.FHISTSp.2013-01-01.ne0CONUSne30x8_mt12_simyr2013_c200806.nc
+
+
+
+
lnd/clm2/initdata_map/clmi.F2000.2000-01-01.ne120pg3_mt13_simyr2000_c200728.nc
-
+
lnd/clm2/initdata_map/clmi.FHISTSp.2013-01-01.ne0CONUSne30x8_mt12_simyr2013_c200806.nc
+
lnd/clm2/initdata_map/clmi.F2000.2000-01-01.ne120pg3_mt13_simyr2000_c200728.nc
-
+
lnd/clm2/initdata_map/clmi.FHISTSp.2013-01-01.ne0CONUSne30x8_mt12_simyr2013_c200806.nc
+
lnd/clm2/initdata_map/clmi.F2000.2000-01-01.ne120pg3_mt13_simyr2000_c200728.nc
-
+
lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_1850_78pfts_c240221.nc
+
+lnd/clm2/surfdata_esmf/surfdata_1x1_cidadinhoBR_hist_2000_78pfts_c240613.nc
lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_1850_78pfts_c240221.nc
@@ -1478,11 +1982,14 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c
>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_C96_SSP2-4.5_1850-2100_78pfts_c240216.nc
-
lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_SSP2-4.5_1850-1855_78pfts_c240221.nc
+
+
+
@@ -1548,14 +2055,17 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c
-
+
lnd/clm2/surfdata_map/fates-sci.1.68.3_api.31.0.0_tools.1.0.1/LUH2_states_transitions_management.timeseries_4x5_hist_simyr1850-2015_c231101.nc
+
+lnd/clm2/surfdata_map/fates-sci.1.77.0_api.36.0.0/fates_landuse_pft_map_4x5_240206.nc
+
lnd/clm2/surfdata_map/fates-sci.1.68.3_api.31.0.0_tools.1.0.1/LUH2_states_transitions_management.timeseries_4x5_hist_simyr1850-2015_c231101.nc
+ >lnd/clm2/surfdata_map/fates-sci.1.68.3_api.31.0.0_tools.1.0.1/LUH2_states_transitions_management.timeseries_4x5_hist_simyr0850-2015_c240216.nc
.false.
@@ -1687,10 +2197,34 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c
nn
nn
-
-1850
-2100
-1850
+
+.false.
+.true.
+.false.
+.false.
+.false.
+.false.
+.false.
+2000
+2000
+2000
+2000
+2000
+2000
+
+
+lnd/clm2/cropdata/calendars/processed/swindow_starts_ggcmi_crop_calendar_phase3_v1.01.2000-2000.20231005_145103.tweaked_latlons.nc
+lnd/clm2/cropdata/calendars/processed/swindow_ends_ggcmi_crop_calendar_phase3_v1.01.2000-2000.20231005_145103.tweaked_latlons.nc
+lnd/clm2/cropdata/calendars/processed/gdds_20230829_161011.tweaked_latlons.nc
+lnd/clm2/cropdata/calendars/processed/360x720_120830_ESMFmesh_c20210507_cdf5.tweaked_latlons.nc
+lnd/clm2/cropdata/calendars/processed/swindow_starts_ggcmi_crop_calendar_phase3_v1.01.2000-2000.20231005_145103.tweaked_latlons.nc
+lnd/clm2/cropdata/calendars/processed/swindow_ends_ggcmi_crop_calendar_phase3_v1.01.2000-2000.20231005_145103.tweaked_latlons.nc
+lnd/clm2/cropdata/calendars/processed/gdds_20230829_161011.tweaked_latlons.nc
+lnd/clm2/cropdata/calendars/processed/20230714_cropcals_pr2_1deg.actually2deg.1980-2009.from_GDDB20.interpd_halfdeg.tweaked_latlons.nc
+lnd/clm2/cropdata/calendars/processed/gdd20bl.copied_from.gdds_20230829_161011.v2.tweaked_latlons.nc
+lnd/clm2/cropdata/calendars/processed/sdates_ggcmi_crop_calendar_phase3_v1.01_nninterp-hcru_hcru_mt13.2000-2000.20230728_165845.tweaked_latlons.nc
+lnd/clm2/cropdata/calendars/processed/hdates_ggcmi_crop_calendar_phase3_v1.01_nninterp-hcru_hcru_mt13.2000-2000.20230728_165845.tweaked_latlons.nc
+lnd/clm2/cropdata/calendars/processed/360x720_120830_ESMFmesh_c20210507_cdf5.tweaked_latlons.nc
@@ -1863,12 +2397,18 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c
1850
2106
-lnd/clm2/urbandata/CTSM52_tbuildmax_OlesonFeddema_2020_0.9x1.25_simyr1849-2106_c200605.nc
-/glade/work/xinchang/02_Explicit_AC_Adoption/02_data_present_day/CTSM52_urbantv_Li_2024_0.9x1.25_simyr1849-2106_c20230621.nc
+lnd/clm2/urbandata/CTSM52_tbuildmax_OlesonFeddema_2020_0.9x1.25_simyr1849-2106_c200605.nc
-/glade/work/xinchang/02_Explicit_AC_Adoption/02_data_present_day/CTSM52_urbantv_Li_2024_0.9x1.25_simyr1849-2106_c20230621.nc
+lnd/clm2/urbandata/CLM50_tbuildmax_Oleson_2016_0.9x1.25_simyr1849-2106_c160923.nc
+/glade/work/xinchang/02_Explicit_AC_Adoption/02_data_present_day/CTSM52_urbantv_Li_2024_0.9x1.25_simyr1849-2106_c20230621.nc
lnd/clm2/urbandata/CLM45_tbuildmax_Oleson_2016_0.9x1.25_simyr1849-2106_c160923.nc
@@ -1948,50 +2488,78 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c
-Zender_2003
-atm
bilinear
-lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
+lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
+lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
+lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
+lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
-lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
-lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
-lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
+lnd/clm2/dustemisdata/dst_source2x2_cam5.4-forCLM_cdf5_c240202.nc
+lnd/clm2/dustemisdata/dst_source2x2_cam5.4-forCLM_cdf5_c240202.nc
-lnd/clm2/dustemisdata/dst_source2x2_cam5.4-forCLM_cdf5_c240202.nc
-lnd/clm2/dustemisdata/dst_source2x2_cam5.4-forCLM_cdf5_c240202.nc
-lnd/clm2/dustemisdata/dst_source2x2tuned-cam4-forCLM_cdf5_c240202.nc
+lnd/clm2/dustemisdata/dst_source2x2tuned-cam4-forCLM_cdf5_c240202.nc
-lnd/clm2/dustemisdata/dst_source2x2tuned-cam4-forCLM_cdf5_c240202.nc
-lnd/clm2/dustemisdata/dst_source2x2tuned-cam4-forCLM_cdf5_c240202.nc
-lnd/clm2/dustemisdata/dst_source1x1tuned-cam4-forCLM_cdf5_c240202.nc
-lnd/clm2/dustemisdata/dst_source1x1tuned-cam4-forCLM_cdf5_c240202.nc
-lnd/clm2/dustemisdata/dst_source1x1tuned-cam4-forCLM_cdf5_c240202.nc
-lnd/clm2/dustemisdata/dst_source1x1tuned-cam4-forCLM_cdf5_c240202.nc
+lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
+lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
+lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
-lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
-lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
-lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
-lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
-lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
-lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
-lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
-lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
+lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
+lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
+lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
+lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
+lnd/clm2/dustemisdata/dst_source2x2tunedcam6-2x2-forCLM_cdf5_c230312.nc
0
+no_harvest
.false.
.false.
.false.
.false.
.false.
-.false.
.false.
.false.
-.false.
+.false.
+.false.
+.true.
+.true.
+.true.
+.true.
+.false.
1
0
+.true.
+.true.
+.false.
+.true.
+.true.
+.false.
2,2
-.true.
-.false.
-.true.
-.false.
+
diff --git a/bld/namelist_files/namelist_defaults_dust_emis.xml b/bld/namelist_files/namelist_defaults_dust_emis.xml
new file mode 100644
index 0000000000..40bf3d9078
--- /dev/null
+++ b/bld/namelist_files/namelist_defaults_dust_emis.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+Zender_2003
+
+atm
+
+
diff --git a/bld/namelist_files/namelist_defaults_overall.xml b/bld/namelist_files/namelist_defaults_overall.xml
index 479b2a02b7..5b7ae1bdd9 100644
--- a/bld/namelist_files/namelist_defaults_overall.xml
+++ b/bld/namelist_files/namelist_defaults_overall.xml
@@ -62,6 +62,7 @@ determine default values for namelists.
1x1_urbanc_alpha
1x1_numaIA
1x1_smallvilleIA
+1x1_cidadinhoBR
2000
@@ -110,6 +111,7 @@ determine default values for namelists.
test
navy
test
+test
gx1v7
diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml
index a987fc1300..bd348716d8 100644
--- a/bld/namelist_files/namelist_definition_ctsm.xml
+++ b/bld/namelist_files/namelist_definition_ctsm.xml
@@ -734,10 +734,17 @@ Toggle to turn on no competition mode (only relevant if FATES is being used).
Toggle to turn on FATES satellite phenology mode (only relevant if FATES is being used).
-
-Toggle to turn on the logging module
-(Only relevant if FATES is on)
+
+Set FATES harvesting mode by setting fates_harvest_mode to a valid string option.
+Allowed values are:
+ no_harvest: no fates harvesting of any kind
+ event_code: fates logging via fates logging event codes (see fates parameter file) only
+ landuse_timeseries: fates harvest driven by CLM flanduse_timeseries file (dynHarvestMod)**
+ luhdata_area: fates harvest driven by LUH2 raw harvest data, area-based (dynFATESLandUseChangeMod)
+ luhdata_mass: fates harvest driven by LUH2 raw harvest data, mass-based (dynFATESLandUseChangeMod)
+**Note that the landuse_timeseries option is not the same as the FATES fluh_timeseries data file.
+This option is older than the luhdata options and may be depricated at some point in the future.
If TRUE, enable use of land use harmonization (LUH) state and transition data from luh_timeseries file.
+This is enabled by default if fates_harvest_mode is set to use the raw LUH2 harvest data
(Also, only valid for use_fates = true and is incompatible with transient runs currently.)
+
+If TRUE, enable use of FATES land use with no competition and fixed biogeography. This mode
+requires the use of the land use x pft association static data map file. See the
+flandusepftdat definition entry in this file for more information.
+(Only valid for use_fates = true and is incompatible with transient runs currently.)
+
+
+
+If TRUE, ignore the land-use state vector and transitions, and assert that all lands
+are primary, and that there is no harvest. This mode is only relevant for FATES
+spin-up workflows that are intending to use the spin-up restart output to start a
+FATES land use transient case using the use_fates_lupft namelist option. The option
+should be set to true for the spin-up case and false for the transient case.
+
+
@@ -806,6 +831,18 @@ types to vary over time.
(Only relevant if FATES is on).
+
+Full pathname of fates landuse x pft association static data map.
+The file associates land use types with pfts across a static global map.
+This file is necessary for running FATES with use_fates_luh,
+use_fates_nocomp, and use_fates_fixedbiogeo engaged (note that use_fates_lupft
+is provided as a namelist option to engage all necessary options). The file is output
+by the FATES land use data tool (https://github.com/NGEET/tools-fates-landusedata)
+which processes the raw land use data from the THEMIS tool data sets
+(https://doi.org/10.5065/29s7-7b41)
+
+
Toggle to turn on the LUNA model, to effect Photosynthesis by leaf Nitrogen
@@ -829,7 +866,7 @@ Toggle to turn on surface water routing in the hillslope hydrology model
+ group="clm_inparm" valid_values="" value=".false.">
If true, set fsat to zero for hillslope columns
@@ -1075,6 +1112,11 @@ Turn urban air conditioning/heating ON or OFF and add wasteheat:
ON_WASTEHEAT = Air conditioning/heating is ON and waste-heat sent to urban canyon
+
+If TRUE, use explicit, time-varying AC adoption rate for air-conditioning flux and interior building temperature calculations.
+
+
If TRUE, urban traffic flux will be activated (Currently NOT implemented).
@@ -1141,6 +1183,50 @@ e.g., because we have integrated AgSys and have tests of it that make
these software infrastructure tests obsolete.
+
+
+
+
+Turn on the Matrix solution for above ground biogeochemistry, requires CN to be on
+
+
+
+Turn on the Matrix solution for soil biogeochemistry
+
+
+
+Turn on extra output for the matrix solution
+
+
+
+Turn on semi-analytic spinup solution for the CN/Soil matrix, requires soil matrix to be on
+This will drive the solution to equilibrium
+
+
+
+Number of years to average the storage capacitance over for the soil Matrix solution during semi-analytic spinup (spinup_matrixcn=T)
+Normally should be the same as the number of years the atmospheric forcing is run over
+
+
+
+length of each semi-analytic solution. eg. nyr_SASU=5, analytic solutions will be calculated every five years.
+nyr_SASU=1: the fastest SASU, but inaccurate; nyr_SASU=nyr_forcing(eg. 20): the lowest SASU but accurate
+
+
+
+The restart file will be based on the average of all analytic solutions within the iloop_avg^th loop.
+eg. if nyr_forcing = 20, iloop_avg = 8, the restart file in yr 160 will be based on analytic solutions from yr 141 to 160.
+The number of the analytic solutions within one loop depends on ratio between nyr_forcing and nyr_SASU.
+eg. if nyr_forcing = 20, nyr_SASU = 5, number of analytic solutions is 20/5=4
+
+
@@ -1369,11 +1455,6 @@ Percentage threshold above which the model keeps the urban landunits. Selecting
Default: 0
-
-Toggle to turn on the dynamic root model
-
-
Toggle to turn on on diagnostic Snow Radiative Effect
@@ -1617,20 +1698,6 @@ Mapping method from Nitrogen deposition input file to the model resolution
-
-Which dust emission method is going to be used. Either the Zender 2003 scheme or the Leung 2023
-scheme.
-(NOTE: The Leung 2023 method is NOT currently available)
-
-
-
-Option only applying for the Zender_2003 method for whether the soil erodibility file is handled
-here in CTSM, or in the ATM model.
-(only used when dust_emis_method is Zender_2003)
-
-
Option only applying for the Zender_2003 method for whether the soil erodibility file is handled
@@ -1778,19 +1845,44 @@ Mapping method from LAI input file to the model resolution
-
+Flag to enable prescribed crop calendars (sowing window dates and maturity requirement)
+
+
+
+Flag to enable prescribed crop calendars (sowing window dates and maturity requirement), with maturity requirement adaptive based on recent climate
+
+
+
+First year to loop over for crop sowing windows
+
+
+
-First year to loop over for crop calendar data
+Last year to loop over for crop sowing windows
-
-Last year to loop over for crop calendar data
+Simulation year that aligns with stream_year_first_cropcal_swindows value
-
-Simulation year that aligns with stream_year_first_cropcal value
+First year to loop over for crop maturity requirements
+
+
+
+Last year to loop over for crop maturity requirements
+
+
+
+Simulation year that aligns with stream_year_first_cropcal_cultivar_gdds value
+
+Filename of input stream data for baseline GDD20 values
+
+
+
+Set this to true to read gdd20 accumulation season start and end dates from stream files, rather than using hard-coded hemisphere-specific "warm seasons."
+
+
+
+Set this to true to flush the accumulated GDD20 variables as soon as possible.
+
+
+
+By default, a value in stream_fldFileName_gdd20_season_start or _end outside the range [1, 365] (or 366 in leap years) will cause the run to fail. Set this to .true. to instead have such cells fall back to the hard-coded hemisphere-specific "warm seasons."
+
+
+
+Filename of input stream data for date (day of year) of start of gdd20 accumulation season.
+
+
+
+Filename of input stream data for date (day of year) of end of gdd20 accumulation season.
+
+
Filename of input stream data for crop calendar inputs
@@ -2040,10 +2162,10 @@ hist means do NOT use a future scenario, just use historical data.
Land mask description
-
+
+ valid_values="clm4_5_CRUv7,clm4_5_GSWP3v1,clm4_5_cam7.0,clm4_5_cam6.0,clm4_5_cam5.0,clm4_5_cam4.0,clm5_0_cam7.0,clm5_0_cam6.0,clm5_0_cam5.0,clm5_0_cam4.0,clm5_0_CRUv7,clm5_0_GSWP3v1,clm5_1_GSWP3v1,clm5_1_CRUv7,clm5_1_cam7.0,clm5_1_cam6.0,clm5_1_cam5.0,clm5_1_cam4.0,clm6_0_GSWP3v1,clm6_0_cam7.0,clm6_0_cam6.0,clm6_0_cam5.0,clm6_0_cam4.0">
General configuration of model version and atmospheric forcing to tune the model to run under.
This sets the model to run with constants and initial conditions that were set to run well under
the configuration of model version and atmospheric forcing. To run well constants would need to be changed
@@ -2101,21 +2223,21 @@ How close in years to use when looking for an initial condition file (finidat) i
Simulation years you can look for in initial condition files (finidat) if interpolation is turned on (use_init_interp is .true.)
-
+
Command line argument for setting up your simulation in a mode for faster
throughput. By default turns off some options, and sets up for a lower level
of output. When bgc_mode is some level of prognostic BGC (so NOT Satellite Phenology)
-it also sets up for accelerated decomposition.
+it also sets up for accelerated decomposition. The "sasu" mode sets up
+for using the CN-matrix mode with Semi-Analytic Spin Up.
NOTE: THIS CORRESPONDS DIRECTLY TO THE env_run.xml VARIABLE OF THE SAME NAME.
Set the env_run variable, rather than setting this directly.
+ group="default_settings" valid_values="sp,bgc,fates" >
Command line arguement for biogeochemistry mode for CLM4.5
sp = Satellitte Phenology
- cn = Carbon Nitrogen model
bgc = CLM4.5 BGC model with:
CENTURY model pools
Nitrification/De-nitrification
diff --git a/bld/namelist_files/namelist_definition_drv_flds.xml b/bld/namelist_files/namelist_definition_drv_flds.xml
index 088f5c5fa9..89bab07f4f 100644
--- a/bld/namelist_files/namelist_definition_drv_flds.xml
+++ b/bld/namelist_files/namelist_definition_drv_flds.xml
@@ -123,4 +123,17 @@
List of fluxes needed by the CARMA model, from CLM to CAM.
+
+ Which dust emission method is going to be used. Either the Zender 2003 scheme or the Leung 2023 scheme.
+ (NOTE: The Leung 2023 method is NOT currently available)
+
+
+
+ Option only applying for the Zender_2003 method for whether the soil erodibility file is handled
+ in the active LAND model or in the ATM model.
+ (only used when dust_emis_method is Zender_2003)
+
+
diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl
index b9d20cbba9..fe6591c16b 100755
--- a/bld/unit_testers/build-namelist_test.pl
+++ b/bld/unit_testers/build-namelist_test.pl
@@ -42,7 +42,7 @@ sub make_env_run {
my %settings = @_;
# Set default settings
- my %env_vars = ( DIN_LOC_ROOT=>"MYDINLOCROOT", GLC_TWO_WAY_COUPLING=>"FALSE", NEONSITE=>"" );
+ my %env_vars = ( DIN_LOC_ROOT=>"MYDINLOCROOT", GLC_TWO_WAY_COUPLING=>"FALSE", LND_SETS_DUST_EMIS_DRV_FLDS=>"TRUE", NEONSITE=>"" );
# Set any settings that came in from function call
foreach my $item ( keys(%settings) ) {
$env_vars{$item} = $settings{$item};
@@ -163,10 +163,10 @@ sub cat_and_create_namelistinfile {
#
# Figure out number of tests that will run
#
-my $ntests = 3263;
+my $ntests = 3338;
if ( defined($opts{'compare'}) ) {
- $ntests += 1965;
+ $ntests += 1999;
}
plan( tests=>$ntests );
@@ -326,6 +326,11 @@ sub cat_and_create_namelistinfile {
"-res 0.9x1.25 -use_case 1850_control",
"-res 1x1pt_US-UMB -clm_usr_name 1x1pt_US-UMB -namelist '&a fsurdat=\"/dev/null\"/'",
"-res 1x1_brazil",
+ "-namelist '&a use_matrixcn=F,use_soil_matrixcn=F,hist_wrt_matrixcn_diag=F,spinup_matrixcn=F/' -bgc sp",
+ "-namelist '&a use_matrixcn=T,use_soil_matrixcn=T,hist_wrt_matrixcn_diag=T,spinup_matrixcn=T/' -bgc bgc -crop -clm_accelerated_spinup on",
+ "-namelist \"&a soil_decomp_method='MIMICSWieder2015',use_matrixcn=F/\" -bgc bgc -crop",
+ "-namelist \"&a soil_decomp_method='MIMICSWieder2015',use_matrixcn=T/\" -bgc bgc -crop",
+ "-bgc bgc -crop -clm_accelerated_spinup sasu",
"-res 0.9x1.25 -clm_start_type startup", "-namelist '&a irrigate=.false./' -crop -bgc bgc",
"-res 0.9x1.25 -infile myuser_nl_clm",
"-res 0.9x1.25 -ignore_ic_date -clm_start_type branch -namelist '&a nrevsn=\"thing.nc\"/' -bgc bgc -crop",
@@ -414,17 +419,17 @@ sub cat_and_create_namelistinfile {
$mode = "-phys $phys";
&make_config_cache($phys);
foreach my $options (
- "-res ne0np4.ARCTIC.ne30x4 -bgc sp -use_case 2000_control -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam6.0",
- "-res ne0np4.ARCTICGRIS.ne30x8 -bgc sp -use_case 1850_control -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam6.0",
- "-res 1.9x2.5 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam6.0",
- "-res 0.9x1.25 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam6.0",
- "-res 0.9x1.25 -bgc bgc -crop -use_case 20thC_transient -namelist '&a start_ymd=19500101/' -lnd_tuning_mode ${phys}_cam6.0",
- "-res ne0np4CONUS.ne30x8 -bgc sp -use_case 2000_control -namelist '&a start_ymd=20130101/' -lnd_tuning_mode ${phys}_cam6.0",
- "-res 1.9x2.5 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=20030101/' -lnd_tuning_mode ${phys}_cam6.0",
- "-res 1.9x2.5 -bgc sp -use_case 2010_control -namelist '&a start_ymd=20100101/' -lnd_tuning_mode ${phys}_cam6.0",
+ "-res ne0np4.ARCTIC.ne30x4 -bgc sp -use_case 2000_control -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam7.0",
+ "-res ne0np4.ARCTICGRIS.ne30x8 -bgc sp -use_case 1850_control -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam7.0",
+ "-res 1.9x2.5 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam7.0",
+ "-res 0.9x1.25 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=19790101/' -lnd_tuning_mode ${phys}_cam7.0",
+ "-res 0.9x1.25 -bgc bgc -crop -use_case 20thC_transient -namelist '&a start_ymd=19500101/' -lnd_tuning_mode ${phys}_cam7.0",
+ "-res ne0np4CONUS.ne30x8 -bgc sp -use_case 2000_control -namelist '&a start_ymd=20130101/' -lnd_tuning_mode ${phys}_cam7.0",
+ "-res 1.9x2.5 -bgc sp -use_case 20thC_transient -namelist '&a start_ymd=20030101/' -lnd_tuning_mode ${phys}_cam7.0",
+ "-res 1.9x2.5 -bgc sp -use_case 2010_control -namelist '&a start_ymd=20100101/' -lnd_tuning_mode ${phys}_cam7.0",
"-res 1x1_brazil -no-megan -use_case 2000_control -lnd_tuning_mode ${phys}_CRUv7",
- "-res C96 -bgc sp -use_case 2010_control -namelist '&a start_ymd=20100101/' -lnd_tuning_mode ${phys}_cam6.0",
- "-res ne0np4.ARCTIC.ne30x4 -bgc sp -use_case 2000_control -namelist '&a start_ymd=20130101/' -lnd_tuning_mode ${phys}_cam6.0",
+ "-res C96 -bgc sp -use_case 2010_control -namelist '&a start_ymd=20100101/' -lnd_tuning_mode ${phys}_cam7.0",
+ "-res ne0np4.ARCTIC.ne30x4 -bgc sp -use_case 2000_control -namelist '&a start_ymd=20130101/' -lnd_tuning_mode ${phys}_cam7.0",
) {
&make_env_run();
eval{ system( "$bldnml -envxml_dir . $options > $tempfile 2>&1 " ); };
@@ -494,52 +499,42 @@ sub cat_and_create_namelistinfile {
my %failtest = (
"coldstart but with IC file"=>{ options=>"-clm_start_type cold -envxml_dir .",
namelst=>"finidat='$finidat'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"clm_demand on finidat" =>{ options=>"-clm_demand finidat -envxml_dir .",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"blank IC file, not cold" =>{ options=>"-clm_start_type startup -envxml_dir .",
namelst=>"finidat=' '",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"startup without interp" =>{ options=>"-clm_start_type startup -envxml_dir . -bgc sp -sim_year 1850",
namelst=>"use_init_interp=.false., start_ymd=19200901",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"use_crop without -crop" =>{ options=>" -envxml_dir .",
namelst=>"use_crop=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"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",
},
"coldstart exice on wo stream"=>{ options=>"-res 0.9x1.25 -envxml_dir . --clm_start_type cold",
@@ -559,377 +554,302 @@ sub cat_and_create_namelistinfile {
},
"clm50CNDVwtransient" =>{ options=>" -envxml_dir . -use_case 20thC_transient -dynamic_vegetation -res 10x15 -ignore_warnings",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"decomp_without_cn" =>{ options=>" -envxml_dir . -bgc sp",
namelst=>"soil_decomp_method='CENTURYKoven2013'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"bgc_with_no_decomp" =>{ options=>" -envxml_dir . -bgc bgc",
namelst=>"soil_decomp_method='None'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"reseed without CN" =>{ options=>" -envxml_dir . -bgc sp",
namelst=>"reseed_dead_plants=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"onset_threh w SP" =>{ options=>" -envxml_dir . -bgc sp",
namelst=>"onset_thresh_depends_on_veg=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm6_0",
},
"dribble_crphrv w/o CN" =>{ options=>" -envxml_dir . -bgc sp",
namelst=>"dribble_crophrv_xsmrpool_2atm=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"dribble_crphrv w/o crop" =>{ options=>" -envxml_dir . -bgc bgc -no-crop",
namelst=>"dribble_crophrv_xsmrpool_2atm=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"CNDV with flanduse_timeseries - clm4_5"=>{ options=>"-bgc bgc -dynamic_vegetation -envxml_dir . -ignore_warnings",
namelst=>"flanduse_timeseries='my_flanduse_timeseries_file.nc'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"use_cndv=T without bldnml op"=>{ options=>"-bgc bgc -envxml_dir . -ignore_warnings",
namelst=>"use_cndv=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"use_cndv=F with dyn_veg op"=>{ options=>"-bgc bgc -dynamic_vegetation -envxml_dir . -ignore_warnings",
namelst=>"use_cndv=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"crop with use_crop false" =>{ options=>"-crop -bgc bgc -envxml_dir .",
namelst=>"use_crop=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"crop without CN" =>{ options=>"-crop -bgc sp -envxml_dir .",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"toosmall soil w trans" =>{ options=>"-envxml_dir .",
namelst=>"toosmall_soil=10, dyn_transient_pfts=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"toosmall lake w trans" =>{ options=>"-envxml_dir .",
namelst=>"toosmall_lake=10, dyn_transient_pfts=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"toosmall crop w trans" =>{ options=>"-bgc bgc -crop -envxml_dir .",
namelst=>"toosmall_crop=10, dyn_transient_pfts=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"toosmall wetl w trans" =>{ options=>"-bgc bgc -envxml_dir .",
namelst=>"toosmall_wetland=10, dyn_transient_pfts=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"toosmall glc w trans" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"toosmall_glacier=10, dyn_transient_pfts=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"toosmall urban w trans" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"toosmall_urban=10, dyn_transient_pfts=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"collapse_urban w trans" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"collapse_urban=T, dyn_transient_crops=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"n_dom_landunits w trans" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"n_dom_landunits=2, dyn_transient_crops=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"n_dom_pfts w trans" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"n_dom_pfts=2, dyn_transient_crops=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"baset_map without crop" =>{ options=>"-bgc bgc -envxml_dir . -no-crop",
namelst=>"baset_mapping='constant'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"mapvary var w/o varymap" =>{ options=>"-crop -bgc bgc -envxml_dir . -crop",
namelst=>"baset_mapping='constant', baset_latvary_slope=1.0, baset_latvary_intercept=10.0",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"grainproductWOcrop" =>{ options=>"-bgc bgc -no-crop -envxml_dir .",
namelst=>"use_grainproduct=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"interp without finidat" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"use_init_interp=.true. finidat=' '",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"sp and c13" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"use_c13=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"sp and c14" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"use_c14=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"bombspike no c14" =>{ options=>"-bgc bgc -envxml_dir .",
namelst=>"use_c14=.false. use_c14_bombspike=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"use c13 timeseries no cn" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"use_c13_timeseries=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"use c13 timeseries no c13"=>{ options=>"-bgc bgc -envxml_dir .",
namelst=>"use_c13=.false. use_c13_timeseries=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"bombspike no cn" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"use_c14_bombspike=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"lightres no cn" =>{ options=>"-bgc sp -envxml_dir . -light_res 360x720",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"NEONlightresButGlobal" =>{ options=>"--res 4x5 --bgc bgc --envxml_dir . --light_res 106x740",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm6_0",
},
"spno-fire" =>{ options=>"-bgc sp -envxml_dir . -use_case 2000_control",
namelst=>"fire_method='nofire'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"lightres no fire" =>{ options=>"-bgc bgc -envxml_dir . -light_res 360x720",
namelst=>"fire_method='nofire'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"lightres none bgc" =>{ options=>"-bgc bgc -envxml_dir . -light_res none",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"lightresnotnone-nofire" =>{ options=>"-bgc bgc -envxml_dir . -light_res 94x192",
namelst=>"fire_method='nofire'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"lightresnonenofirelightfil"=>{ options=>"-bgc bgc -envxml_dir . -light_res none",
namelst=>"fire_method='nofire',stream_fldfilename_lightng='build-namelist_test.pl'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"lightrescontradictlightfil"=>{ options=>"-bgc bgc -envxml_dir . -light_res 360x720",
namelst=>"stream_fldfilename_lightng='build-namelist_test.pl'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"finundated and not methane"=>{ options=>"-bgc bgc -envxml_dir .",
namelst=>"use_lch4=.false.,finundation_method='h2osfc'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"use_cn=true bgc=sp" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"use_cn=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"freeliv wo fun" =>{ options=>"-bgc bgc -envxml_dir .",
namelst=>"freelivfix_intercept=9.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"use_cn=false bgc=bgc" =>{ options=>"-bgc bgc -envxml_dir .",
namelst=>"use_cn=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"lower=aqu-45 with/o Zeng" =>{ options=>"-envxml_dir .",
namelst=>"lower_boundary_condition=4,soilwater_movement_method=1,use_bedrock=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"Zeng w lower=flux" =>{ options=>"-envxml_dir .",
namelst=>"lower_boundary_condition=1,soilwater_movement_method=0,use_bedrock=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"Zeng w lower=zeroflux" =>{ options=>"-envxml_dir .",
namelst=>"lower_boundary_condition=2,soilwater_movement_method=0",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"Zeng w lower=table" =>{ options=>"-envxml_dir .",
namelst=>"lower_boundary_condition=3,soilwater_movement_method=0,use_bedrock=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"use_vic=F with -vic op" =>{ options=>"-vichydro -envxml_dir .",
namelst=>"use_vichydro=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"-vic with l_bnd=flux" =>{ options=>"-vichydro -envxml_dir .",
namelst=>"lower_boundary_condition=1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"-vic with l_bnd=zeroflux" =>{ options=>"-vichydro -envxml_dir .",
namelst=>"lower_boundary_condition=2",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"bedrock with l_bnc=flux" =>{ options=>"-envxml_dir .",
namelst=>"use_bedrock=.true., lower_boundary_condition=1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"bedrock with l_bnc=tabl" =>{ options=>"-envxml_dir .",
namelst=>"use_bedrock=.true., lower_boundary_condition=3",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"bedrock with l_bnc=aqui" =>{ options=>"-envxml_dir .",
namelst=>"use_bedrock=.true., lower_boundary_condition=4",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"zengdeck with l_bnc=flux" =>{ options=>"-envxml_dir .",
namelst=>"soilwater_movement_method=0, lower_boundary_condition=1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"zengdeck with l_bnc=z-flux"=>{ options=>"-envxml_dir .",
namelst=>"soilwater_movement_method=0, lower_boundary_condition=2",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"zengdeck with l_bnc=tabl" =>{ options=>"-envxml_dir .",
namelst=>"soilwater_movement_method=0, lower_boundary_condition=3",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"l_bnd=tabl with h2osfcfl=0"=>{ options=>"-envxml_dir .",
namelst=>"h2osfcflag=0, lower_boundary_condition=3",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"l_bnd=flux with h2osfcfl=0"=>{ options=>"-envxml_dir .",
namelst=>"h2osfcflag=0, lower_boundary_condition=1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"l_bnd=zflux with h2osfcfl=0"=>{ options=>"-envxml_dir .",
namelst=>"h2osfcflag=0, lower_boundary_condition=2",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"h2osfcfl=0 with clm5.0" =>{ options=>"-envxml_dir .",
namelst=>"h2osfcflag=0",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"45bad lnd_tuning_mode value" =>{ options=>"-lnd_tuning_mode clm5_0_GSWP3 -envxml_dir .",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"50bad lnd_tuning_mode value" =>{ options=>"-lnd_tuning_mode clm4_5_CRUNCEP -envxml_dir .",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"bgc_spinup without cn" =>{ options=>"-clm_accelerated_spinup on -bgc sp -envxml_dir .",
namelst=>"spinup_state=1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"spinup=1 without bldnml op"=>{ options=>"-clm_accelerated_spinup off -bgc bgc -envxml_dir .",
namelst=>"spinup_state=1",,
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"bgc_spinup without cn" =>{ options=>"-clm_accelerated_spinup on -bgc sp -envxml_dir .",
namelst=>"spinup_state=1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"baseflow w aquifer" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"baseflow_scalar=1.0, lower_boundary_condition=4,use_bedrock=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"baseflow w table" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"baseflow_scalar=1.0, lower_boundary_condition=3,use_bedrock=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"br_root and bgc=sp" =>{ options=>"-bgc sp -envxml_dir .",
namelst=>"br_root=1.0",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"both co2_type and on nml" =>{ options=>"-co2_type constant -envxml_dir .",
namelst=>"co2_type='prognostic'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"lnd_frac set but nuopc" =>{ options=>"-driver nuopc -lnd_frac $DOMFILE -envxml_dir .",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm6_0",
},
"lnd_frac not set but lilac"=>{ options=>"-driver nuopc -lilac -envxml_dir . -lnd_frac UNSET",
namelst=>"fsurdat='surfdata.nc'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm6_0",
},
"fatmlndfrc set but nuopc" =>{ options=>"-driver nuopc -envxml_dir .",
namelst=>"fatmlndfrc='frac.nc'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm6_0",
},
"branch but NO nrevsn" =>{ options=>"-clm_start_type branch -envxml_dir .",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"glc_nec inconsistent" =>{ options=>"-envxml_dir .",
namelst=>"maxpatch_glc=5",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"NoGLCMec" =>{ options=>"-envxml_dir . -glc_nec 0",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"UpdateGlcContradict" =>{ options=>"-envxml_dir .",
@@ -937,312 +857,356 @@ sub cat_and_create_namelistinfile {
GLC_TWO_WAY_COUPLING=>"TRUE",
phys=>"clm4_5",
},
+ "matrixWOBGC" =>{ options=>"-envxml_dir . -bgc sp",
+ namelst=>"use_matrixcn=.true.",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "soilmatrixWOBGC" =>{ options=>"-envxml_dir . -bgc sp",
+ namelst=>"use_soil_matrixcn=T",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "soilmatrixWmimics" =>{ options=>"-envxml_dir . -bgc bgc",
+ namelst=>"use_soil_matrixcn=T,soil_decomp_method='MIMICSWieder2015'",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "matrixcn_diagWOmatrix" =>{ options=>"-envxml_dir . -bgc bgc",
+ namelst=>"use_soil_matrixcn=.false.,use_matrixcn=F,hist_wrt_matrixcn_diag=T",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "spinupWOsoilmatrix" =>{ options=>"-envxml_dir . -bgc bgc",
+ namelst=>"use_soil_matrixcn=F,use_matrixcn=T,spinup_matrixcn=T",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "sasuspinupWOsoilmatx" =>{ options=>"-envxml_dir . -bgc bgc -clm_accelerated_spinup sasu",
+ namelst=>"use_soil_matrixcn=.false.,use_matrixcn=.false.",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_1",
+ },
+ "sasuspinupWOCN" =>{ options=>"-envxml_dir . -bgc sp -clm_accelerated_spinup sasu",
+ namelst=>"",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_1",
+ },
+ "nyrforceWOspinup" =>{ options=>"-envxml_dir . -bgc bgc -clm_accelerated_spinup sasu",
+ namelst=>"use_matrixcn=.false.,spinup_matrixcn=F,nyr_forcing=20",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "nyrsasuGTnyrforce" =>{ options=>"-envxml_dir . -bgc bgc -clm_accelerated_spinup sasu",
+ namelst=>"use_matrixcn=.false.,spinup_matrixcn=T,nyr_forcing=20,nyr_sasu=21",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "iloopZero" =>{ options=>"-envxml_dir . -bgc bgc -clm_accelerated_spinup sasu",
+ namelst=>"use_matrixcn=.false.,spinup_matrixcn=T,iloop_avg=0",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "matrixspinupWADmode" =>{ options=>"-envxml_dir . -bgc bgc -clm_accelerated_spinup sasu",
+ namelst=>"spinup_matrixcn=T,spinup_state=2",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "matrixspinupWclmaccell" =>{ options=>"-envxml_dir . -bgc bgc -clm_accelerated_spinup off",
+ namelst=>"use_soil_matrixcn=T,spinup_matrixcn=T",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "fatesWuse_cnmatrix" =>{ options=>"-envxml_dir . -bgc fates",
+ namelst=>"use_matrixcn=.true.",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
+ "fatesWuse_soilcnmatrix" =>{ options=>"-envxml_dir . -bgc fates",
+ namelst=>"use_soil_matrixcn=.true.",
+ GLC_TWO_WAY_COUPLING=>"TRUE",
+ phys=>"clm5_0",
+ },
"useFATESContradict" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
namelst=>"use_fates=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"useFATESContradict2" =>{ options=>"-envxml_dir . -no-megan",
namelst=>"use_fates=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"useFATESWCN" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
namelst=>"use_cn=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"useFATESWcrop" =>{ options=>"-bgc fates -envxml_dir . -no-megan -crop",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm6_0",
},
"useFATESWcreatecrop" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
namelst=>"create_crop_landunit=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"useFATESWn_dom_pft" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
namelst=>"n_dom_pfts = 1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"useFATESWbMH" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
namelst=>"use_biomass_heat_storage=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm6_0",
},
"FireNoneButFATESfireon" =>{ options=>"-bgc fates -envxml_dir . -no-megan -light_res none",
namelst=>"fates_spitfire_mode=4",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm6_0",
},
"FATESwspitfireOffLigtOn" =>{ options=>"-bgc fates -envxml_dir . -no-megan -light_res 360x720",
namelst=>"fates_spitfire_mode=0",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm6_0",
},
"useFATESWluna" =>{ options=>"--bgc fates --envxml_dir . --no-megan",
namelst=>"use_luna=TRUE",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm6_0",
},
"useFATESWfun" =>{ options=>"--bgc fates --envxml_dir . --no-megan",
namelst=>"use_fun=TRUE",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm6_0",
},
"useFATESWOsuplnitro" =>{ options=>"--bgc fates --envxml_dir . --no-megan",
namelst=>"suplnitro='NONE'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm6_0",
},
"FireNoneButBGCfireon" =>{ options=>"-bgc bgc -envxml_dir . -light_res none",
namelst=>"fire_method='li2021gswpfrc'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm6_0",
},
"createcropFalse" =>{ options=>"-bgc bgc -envxml_dir . -no-megan",
namelst=>"create_crop_landunit=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"usespitfireButNOTFATES" =>{ options=>"-envxml_dir . -no-megan",
namelst=>"fates_spitfire_mode=1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"usespitfireusefatessp" =>{ options=>"-envxml_dir . --bgc fates",
namelst=>"fates_spitfire_mode=1,use_fates_sp=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"usefatesspusefateshydro" =>{ options=>"-envxml_dir . --bgc fates",
namelst=>"use_fates_sp=.true.,use_fates_planthydro=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"useloggingButNOTFATES" =>{ options=>"-envxml_dir . -no-megan",
- namelst=>"use_fates_logging=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
+ namelst=>"fates_harvest_mode='event_code'",
phys=>"clm4_5",
},
"useinventorybutnotfile" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
namelst=>"use_fates_inventory_init=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"inventoryfileDNE" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
namelst=>"use_fates_inventory_init=.true., fates_inventory_ctrl_filename='zztop'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
- "useinventorybutnotfile" =>{ options=>"--res 0.9x1.25 --bgc fates --envxml_dir . --no-megan",
+ "useFATESLUH2butnotfile" =>{ options=>"--res 0.9x1.25 --bgc fates --envxml_dir . --no-megan",
namelst=>"use_fates_luh=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
+ phys=>"clm4_5",
+ },
+ "useFATESLUPFTbutnotfile" =>{ options=>"--res 0.9x1.25 --bgc fates --envxml_dir . --no-megan",
+ namelst=>"use_fates_lupft=.true.",
phys=>"clm4_5",
},
"inventoryfileDNE" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
namelst=>"use_fates_luh=.true., fluh_timeseries='zztop'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"useMEGANwithFATES" =>{ options=>"-bgc fates -envxml_dir . -megan",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"useFIREEMISwithFATES" =>{ options=>"-bgc fates -envxml_dir . -fire_emis --no-megan",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"useDRYDEPwithFATES" =>{ options=>"--bgc fates --envxml_dir . --no-megan --drydep",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"useFATESSPWONOCOMP" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
namelst=>"use_fates_sp=T,use_fates_nocomp=F",
- GLC_TWO_WAY_COUPLING=>"FALSE",
+ phys=>"clm5_0",
+ },
+ "useFATESSPwithLUH" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
+ namelst=>"use_fates_sp=T,use_fates_luh=T",
+ phys=>"clm5_0",
+ },
+ "useFATESPOTVEGwithHARVEST" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
+ namelst=>"use_fates_potentialveg=T,fates_harvest_mode='event_code',use_fates_luh=T",
+ phys=>"clm5_0",
+ },
+ "useFATESHARVEST3WOLUH" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
+ namelst=>"use_fates_luh=F,fates_harvest_mode='luhdata_area'",
+ phys=>"clm5_0",
+ },
+ "useFATESLUPFTWOLUH" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
+ namelst=>"use_fates_lupft=T,use_fates_luh=F",
+ phys=>"clm5_0",
+ },
+ "useFATESLUPFTWONOCOMP" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
+ namelst=>"use_fates_lupft=T,use_fates_nocomp=F",
+ phys=>"clm5_0",
+ },
+ "useFATESLUPFTWOFBG" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
+ namelst=>"use_fates_lupft=T,use_fates_fixedbiogeog=F",
phys=>"clm5_0",
},
"useFATESTRANSWdynPFT" =>{ options=>"-bgc fates -envxml_dir . -use_case 20thC_transient -no-megan",
namelst=>"do_transient_pfts=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"useHYDSTwithFATES" =>{ options=>"-bgc fates -envxml_dir . -no-megan",
namelst=>"use_hydrstress=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
- phys=>"clm5_0",
- },
- "useHYDSTwithdynroot" =>{ options=>"-bgc bgc -envxml_dir . -megan",
- namelst=>"use_hydrstress=.true., use_dynroot=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"specWOfireemis" =>{ options=>"-envxml_dir . -no-fire_emis",
namelst=>"fire_emis_specifier='bc_a1 = BC'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"elevWOfireemis" =>{ options=>"-envxml_dir . -no-fire_emis",
namelst=>"fire_emis_elevated=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"noanthro_w_crop" =>{ options=>"-envxml_dir . -res 0.9x1.25 -bgc bgc -crop -use_case 1850_noanthro_control",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"noanthro_w_irrig" =>{ options=>"-envxml_dir . -res 0.9x1.25 -bgc bgc -use_case 1850_noanthro_control",
namelst=>"irrigate=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"spdotransconflict" =>{ options=>"-envxml_dir . -bgc sp -use_case 20thC_transient",
namelst=>"do_transient_pfts=T,do_transient_crops=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"dogrossandsp" =>{ options=>"--envxml_dir . --bgc sp --use_case 20thC_transient",
namelst=>"do_grossunrep=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"dogrossandfates" =>{ options=>"--envxml_dir . --bgc fates --use_case 20thC_transient --no-megan",
namelst=>"do_grossunrep=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"dogrossandnottrans" =>{ options=>"--envxml_dir . --bgc bgc --use_case 2000_control",
namelst=>"do_grossunrep=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"nocropwfert" =>{ options=>"-envxml_dir . -bgc sp -no-crop",
namelst=>"use_fertilizer=T",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"lmr1WOcn" =>{ options=>"-envxml_dir . -bgc sp",
namelst=>"leafresp_method=1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"lmr2WOcn" =>{ options=>"-envxml_dir . -bgc sp",
namelst=>"leafresp_method=2",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"lmr0Wcn" =>{ options=>"-envxml_dir . -bgc bgc",
namelst=>"leafresp_method=0",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"nofireButSetcli_scale" =>{ options=>"-envxml_dir . -bgc bgc",
namelst=>"fire_method='nofire', cli_scale=5.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"nocnButSetrh_low" =>{ options=>"-envxml_dir . -bgc sp",
namelst=>"rh_low=5.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"funWOcn" =>{ options=>"-envxml_dir . -bgc sp",
namelst=>"use_fun=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"flexCNWOcn" =>{ options=>"-envxml_dir . -bgc sp",
namelst=>"use_flexibleCN=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"flexCNFUNwcarbonresp" =>{ options=>"-envxml_dir . -bgc bgc",
namelst=>"use_flexibleCN=.true.,use_FUN=.true.,carbon_resp_opt=1",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"funWOnitrif" =>{ options=>"-envxml_dir .",
namelst=>"use_fun=.true., use_nitrif_denitrif=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"SPModeWNitrifNMethane" =>{ options=>"-envxml_dir . -bgc sp",
namelst=>"use_lch4=.true., use_nitrif_denitrif=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"knitrmaxWOnitrif" =>{ options=>"-envxml_dir . -bgc bgc",
namelst=>"use_nitrif_denitrif=.false., k_nitr_max=1.0",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"respcoefWOnitrif" =>{ options=>"-envxml_dir . -bgc bgc",
namelst=>"use_nitrif_denitrif=.false., denitrif_respiration_coefficient=1.0",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"respexpWOnitrif" =>{ options=>"-envxml_dir . -bgc bgc",
namelst=>"use_nitrif_denitrif=.false., denitrif_respiration_exponent=1.0",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"lunaWSPandlnctrue" =>{ options=>"-envxml_dir . -bgc sp",
namelst=>"use_luna=.true., lnc_opt=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"NOlunabutsetJmaxb1" =>{ options=>"-envxml_dir . -bgc sp",
namelst=>"use_luna=.false., jmaxb1=1.0",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"envxml_not_dir" =>{ options=>"-envxml_dir myuser_nl_clm",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"envxml_emptydir" =>{ options=>"-envxml_dir xFail",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"fates_non_sp_laistreams" =>{ options=>"--envxml_dir . --bgc fates",
namelst=>"use_lai_streams=.true., use_fates_sp=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"bgc_non_sp_laistreams" =>{ options=>"--envxml_dir . -bgc bgc",
namelst=>"use_lai_streams=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"bgc_laistreams_input" =>{ options=>"--envxml_dir . --bgc bgc",
namelst=>"stream_year_first_lai=1999",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"crop_laistreams_input" =>{ options=>"--envxml_dir . --bgc sp --crop",
namelst=>"use_lai_streams=.true.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"soil_erod_wo_Zender" =>{ options=>"--envxml_dir . --ignore_warnings",
- namelst=>"dust_emis_method='Leung_2023', " .
- "stream_meshfile_zendersoilerod = '/dev/null'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
- phys=>"clm5_1",
+ namelst=>"dust_emis_method='Leung_2023', stream_meshfile_zendersoilerod = '/dev/null'",
+ phys=>"clm6_0",
},
"soil_erod_wo_lnd_source" =>{ options=>"--envxml_dir .",
- namelst=>"dust_emis_method='Zender_2003', " .
- "stream_fldfilename_zendersoilerod = '/dev/null', zender_soil_erod_source='atm'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
- phys=>"clm5_1",
+ namelst=>"dust_emis_method='Zender_2003', stream_fldfilename_zendersoilerod = '/dev/null', zender_soil_erod_source='atm'",
+ phys=>"clm6_0",
+ },
+ "soil_erod_none_w_Zender" =>{ options=>"--envxml_dir .",
+ namelst=>"dust_emis_method='Zender_2003', zender_soil_erod_source='none'",
+ phys=>"clm6_0",
+ },
+ "soil_erod_bad_w_Zender" =>{ options=>"--envxml_dir .",
+ namelst=>"dust_emis_method='Zender_2003', zender_soil_erod_source='zztop'",
+ phys=>"clm6_0",
+ },
+ "Set_Dust_When_CAM_Sets" =>{ options=>"--envxml_dir .",
+ namelst=>"dust_emis_method='Zender_2003'",
+ LND_SETS_DUST_EMIS_DRV_FLDS=>"FALSE",
+ phys=>"clm6_0",
},
);
foreach my $key ( keys(%failtest) ) {
@@ -1250,7 +1214,13 @@ sub cat_and_create_namelistinfile {
&make_config_cache($failtest{$key}{"phys"});
my $options = $failtest{$key}{"options"};
my $namelist = $failtest{$key}{"namelst"};
- &make_env_run( GLC_TWO_WAY_COUPLING=>$failtest{$key}{"GLC_TWO_WAY_COUPLING"} );
+ my %settings;
+ foreach my $xmlvar ( "GLC_TWO_WAY_COUPLING", "LND_SETS_DUST_EMIS_DRV_FLDS") {
+ if ( defined($failtest{$key}{$xmlvar}) ) {
+ $settings{$xmlvar} = $failtest{$key}{$xmlvar};
+ }
+ }
+ &make_env_run( %settings );
eval{ system( "$bldnml $options -namelist \"&clmexp $namelist /\" > $tempfile 2>&1 " ); };
isnt( $?, 0, $key );
system( "cat $tempfile" );
@@ -1267,47 +1237,38 @@ sub cat_and_create_namelistinfile {
# Warnings without the -ignore_warnings option given
"dustemisLeung" =>{ options=>"-envxml_dir .",
namelst=>"dust_emis_method = 'Leung_2023'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_1",
},
"coldwfinidat" =>{ options=>"-envxml_dir . -clm_start_type cold",
namelst=>"finidat = 'testfile.nc'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"bgcspin_w_suplnitro" =>{ options=>"-envxml_dir . -bgc bgc -clm_accelerated_spinup on",
namelst=>"suplnitro='ALL'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"bgc=bgc WO nitrif_denit" =>{ options=>"-bgc bgc -envxml_dir .",
namelst=>"use_nitrif_denitrif=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"methane off W nitrif_denit"=>{ options=>"-bgc bgc -envxml_dir .",
namelst=>"use_nitrif_denitrif=.true.,use_lch4=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm6_0",
},
"soilm_stream w transient" =>{ options=>"-res 0.9x1.25 -envxml_dir . -use_case 20thC_transient",
namelst=>"use_soil_moisture_streams=T,soilm_tintalgo='linear'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"missing_ndep_file" =>{ options=>"-envxml_dir . -bgc bgc -ssp_rcp SSP5-3.4",
namelst=>"",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm5_0",
},
"bad_megan_spec" =>{ options=>"-envxml_dir . -bgc bgc -megan",
namelst=>"megan_specifier='ZZTOP=zztop'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm4_5",
},
"FUN_wo_flexCN" =>{ options=>"-envxml_dir . -bgc bgc",
namelst=>"use_fun=.true.,use_flexiblecn=.false.",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm6_0",
},
"Set coldtemp wo coldstart" =>{ options=>"-envxml_dir . --clm_start_type startup",
@@ -1322,7 +1283,6 @@ sub cat_and_create_namelistinfile {
},
"NotNEONbutNEONlightres" =>{ options=>"--res CLM_USRDAT --clm_usr_name regional --envxml_dir . --bgc bgc --light_res 106x174",
namelst=>"fsurdat='build-namelist_test.pl'",
- GLC_TWO_WAY_COUPLING=>"FALSE",
phys=>"clm6_0",
},
);
@@ -1331,7 +1291,13 @@ sub cat_and_create_namelistinfile {
&make_config_cache($warntest{$key}{"phys"});
my $options = $warntest{$key}{"options"};
my $namelist = $warntest{$key}{"namelst"};
- &make_env_run( GLC_TWO_WAY_COUPLING=>$warntest{$key}{"GLC_TWO_WAY_COUPLING"} );
+ my %settings;
+ foreach my $xmlvar ( "GLC_TWO_WAY_COUPLING" ) {
+ if ( defined($failtest{$key}{$xmlvar}) ) {
+ $settings{$xmlvar} = $failtest{$key}{$xmlvar};
+ }
+ }
+ &make_env_run( %settings );
eval{ system( "$bldnml $options -namelist \"&clmexp $namelist /\" > $tempfile 2>&1 " ); };
isnt( $?, 0, $key );
system( "cat $tempfile" );
@@ -1589,21 +1555,27 @@ sub cat_and_create_namelistinfile {
print "==================================================\n";
# Check for crop resolutions
-my $crop1850_res = "1x1_smallvilleIA";
-$options = "-bgc bgc -crop -res $crop1850_res -use_case 1850_control -envxml_dir .";
-&make_env_run();
-eval{ system( "$bldnml $options > $tempfile 2>&1 " ); };
-is( $@, '', "$options" );
-$cfiles->checkfilesexist( "$options", $mode );
-$cfiles->shownmldiff( "default", "standard" );
-if ( defined($opts{'compare'}) ) {
- $cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode );
- $cfiles->comparefiles( "$options", $mode, $opts{'compare'} );
-}
-if ( defined($opts{'generate'}) ) {
- $cfiles->copyfiles( "$options", $mode );
+my @crop1850_res = ( "1x1_smallvilleIA", "1x1_cidadinhoBR" );
+foreach my $res ( @crop1850_res ) {
+ my $use_case = "1850_control";
+ if ( $res =~ /1x1_cidadinhoBR/ ) {
+ $use_case = "2000_control";
+ }
+ $options = "-bgc bgc -crop -res $res -use_case $use_case -envxml_dir .";
+ &make_env_run();
+ eval{ system( "$bldnml $options > $tempfile 2>&1 " ); };
+ is( $@, '', "$options" );
+ $cfiles->checkfilesexist( "$options", $mode );
+ $cfiles->shownmldiff( "default", "standard" );
+ if ( defined($opts{'compare'}) ) {
+ $cfiles->doNOTdodiffonfile( "$tempfile", "$options", $mode );
+ $cfiles->comparefiles( "$options", $mode, $opts{'compare'} );
+ }
+ if ( defined($opts{'generate'}) ) {
+ $cfiles->copyfiles( "$options", $mode );
+ }
+ &cleanup();
}
-&cleanup();
my @crop_res = ( "1x1_numaIA", "4x5", "10x15", "0.9x1.25", "1.9x2.5", "ne3np4.pg3", "ne30np4", "ne30np4.pg3", "C96", "mpasa120" );
foreach my $res ( @crop_res ) {
@@ -1638,7 +1610,7 @@ sub cat_and_create_namelistinfile {
# cases; I'm not sure if it's actually important to test this with all
# of the different use cases.
my @glc_res = ( "0.9x1.25", "1.9x2.5" );
-my @use_cases = (
+my @use_cases = (
"1850-2100_SSP2-4.5_transient",
"1850_control",
"2000_control",
@@ -1827,7 +1799,7 @@ sub cat_and_create_namelistinfile {
my $mode = "-phys $phys";
&make_config_cache($phys);
my @forclist = ();
- @forclist = ( "CRUv7", "GSWP3v1", "cam6.0", "cam5.0", "cam4.0" );
+ @forclist = ( "CRUv7", "GSWP3v1", "cam7.0", "cam6.0", "cam5.0", "cam4.0" );
foreach my $forc ( @forclist ) {
foreach my $bgc ( "sp", "bgc" ) {
my $lndtuningmode = "${phys}_${forc}";
diff --git a/ccs_config b/ccs_config
index 2ff978f92a..69a958581e 160000
--- a/ccs_config
+++ b/ccs_config
@@ -1 +1 @@
-Subproject commit 2ff978f92a5ac9a6ab243e5c14d06a7e2d2f5799
+Subproject commit 69a958581ecd2d32ee9cb1c38bcd3847b8b920bf
diff --git a/cime_config/SystemTests/lilacsmoke.py b/cime_config/SystemTests/lilacsmoke.py
index 1287301ba2..5bdbb31ec1 100644
--- a/cime_config/SystemTests/lilacsmoke.py
+++ b/cime_config/SystemTests/lilacsmoke.py
@@ -38,7 +38,7 @@
logger = logging.getLogger(__name__)
-_LILAC_RUNTIME_FILES = ["lnd_in", "lnd_modelio.nml", "lilac_in"]
+_LILAC_RUNTIME_FILES = ["lnd_in", "lnd_modelio.nml", "drv_flds_in", "lilac_in"]
class LILACSMOKE(SystemTestsCommon):
diff --git a/cime_config/SystemTests/pvt.py b/cime_config/SystemTests/pvt.py
new file mode 100644
index 0000000000..cf923dd334
--- /dev/null
+++ b/cime_config/SystemTests/pvt.py
@@ -0,0 +1,133 @@
+"""
+FATES land use potential vegetation spin up + transient test
+
+This is a FATES specific test:
+
+1) conduct a spinup with use_fates_potentialveg on
+ - write restart file
+ - use CLM_ACCELERATED_SPINUP?
+2) run a transient landuse case with use_fates_lupft
+ - start from the restart file generated in (1)
+"""
+from CIME.XML.standard_module_setup import *
+from CIME.SystemTests.system_tests_common import SystemTestsCommon
+from CIME.SystemTests.test_utils.user_nl_utils import append_to_user_nl_files
+import shutil, glob, os
+
+logger = logging.getLogger(__name__)
+
+
+class PVT(SystemTestsCommon):
+ def __init__(self, case):
+ SystemTestsCommon.__init__(self, case)
+
+ # Do not allow PVT to be run with certain testmods
+ # Should this be targeted to a specific testmod for simplicity for now?
+ # Technically this could be run with the luh fates_harvest_modes
+ error_message = None
+ casebaseid = self._case.get_value("CASEBASEID")
+ casebaseid = casebaseid.split("-")[-1]
+ if casebaseid[0:10] != "FatesLUPFT":
+ error_message = f"Only call PVT with testmod FatesLUPFT. {casebaseid} selected."
+
+ # Only allow to run if resolution is 4x5 for now
+ # Other grid resolutions will be pre-processed and included in the namelist defaults at a future date.
+ # Potentially we could generate these on the fly although doing so would result in increased build time
+ lnd_grid = self._case.get_value("LND_GRID")
+ if lnd_grid != "4x5":
+ error_message = (
+ f"PVT can currently only be run with 4x5 resolution. {lnd_grid} selected."
+ )
+
+ if error_message is not None:
+ logger.error(error_message)
+ raise RuntimeError(error_message)
+
+ def run_phase(self):
+ # -------------------------------------------------------------------
+ # (1) Run FATES spin-up case in potential vegetation mode
+ # -------------------------------------------------------------------
+ orig_case = self._case
+ orig_casevar = self._case.get_value("CASE")
+ caseroot = self._case.get_value("CASEROOT")
+
+ # Set the run start date based on the desired starting reference case year
+ refcase_year = 1700
+ stop_n_pveg = 5
+ startyear_pveg = refcase_year - stop_n_pveg
+
+ # clone the main case to create spinup case
+ logger.info("PVT log: cloning setup")
+ clone_path = "{}.potveg".format(caseroot)
+ if os.path.exists(clone_path):
+ shutil.rmtree(clone_path)
+ logger.info("PVT log: cloning")
+ clone = self._case.create_clone(clone_path, keepexe=True)
+ logger.info("PVT log: cloning complete")
+
+ # setup the clone case
+ os.chdir(clone_path)
+ self._set_active_case(clone)
+
+ # set the clone case values
+ with clone:
+ clone.set_value("CLM_ACCELERATED_SPINUP", "off")
+ clone.set_value("STOP_N", stop_n_pveg)
+ clone.set_value("STOP_OPTION", "nyears")
+ clone.set_value("RUN_STARTDATE", "{}-01-01".format(startyear_pveg))
+
+ # Modify the spin up case to use the potential vegetation mode.
+ # Checks for incompatible cases and necessary mapping files are
+ # handled in the build case.
+ # Turn off fates_harvest_mode for the spin up.
+
+ logger.info("PVT log: modify user_nl_clm file for spin up run")
+ added_content = ["use_fates_potentialveg = .true.", "fates_harvest_mode = 'no_harvest'"]
+ append_to_user_nl_files(clone_path, "clm", added_content)
+
+ # Run the spin up case
+ # As per SSP test:
+ # "No history files expected, set suffix=None to avoid compare error"
+ logger.info("PVT log: starting spin-up run")
+ dout_sr = clone.get_value("DOUT_S_ROOT")
+ self._skip_pnl = False
+ self.run_indv(suffix=None, st_archive=True)
+
+ # -------------------------------------------------------------------
+ # (2) Run FATES transient case using restart file from spin-up
+ # -------------------------------------------------------------------
+ os.chdir(caseroot)
+ self._set_active_case(orig_case)
+
+ # Copy restart files from spin up to the transient case run directory
+ # obtain rpointer files and necessary restart files from short term archiving directory
+ rundir = self._case.get_value("RUNDIR")
+
+ refdate = str(refcase_year) + "-01-01-00000"
+ rest_path = os.path.join(dout_sr, "rest", "{}".format(refdate))
+
+ for item in glob.glob("{}/*{}*".format(rest_path, refdate)):
+ link_name = os.path.join(rundir, os.path.basename(item))
+ if os.path.islink(link_name) and os.readlink(link_name) == item:
+ # Link is already set up correctly: do nothing
+ # (os.symlink raises an exception if you try to replace an
+ # existing file)
+ pass
+ else:
+ os.symlink(item, link_name)
+
+ for item in glob.glob("{}/*rpointer*".format(rest_path)):
+ shutil.copy(item, rundir)
+
+ # Update run case settings
+ self._case.set_value("CLM_ACCELERATED_SPINUP", "off")
+ self._case.set_value("RUN_TYPE", "hybrid")
+ self._case.set_value("GET_REFCASE", False)
+ self._case.set_value("RUN_REFCASE", "{}.potveg".format(orig_casevar))
+ self._case.set_value("RUN_REFDATE", "{}-01-01".format(refcase_year))
+ self._case.set_value("RUN_STARTDATE", "{}-01-01".format(refcase_year))
+ self._case.set_value("DOUT_S", False)
+ self._case.flush()
+
+ # do the restart run (short term archiving is off)
+ self.run_indv()
diff --git a/cime_config/SystemTests/rxcropmaturity.py b/cime_config/SystemTests/rxcropmaturity.py
index d25bd015ca..fb254c408f 100644
--- a/cime_config/SystemTests/rxcropmaturity.py
+++ b/cime_config/SystemTests/rxcropmaturity.py
@@ -135,6 +135,7 @@ def _run_phase(self, skip_gen=False):
logger.info("RXCROPMATURITY log: modify user_nl files: generate GDDs")
self._append_to_user_nl_clm(
[
+ "stream_fldFileName_cultivar_gdds = ''",
"generate_crop_gdds = .true.",
"use_mxmat = .false.",
" ",
@@ -400,12 +401,14 @@ def _run_check_rxboth_run(self, skip_gen):
def _modify_user_nl_allruns(self):
nl_additions = [
+ "cropcals_rx = .true.",
+ "cropcals_rx_adapt = .false.",
"stream_meshfile_cropcal = '{}'".format(self._case.get_value("LND_DOMAIN_MESH")),
"stream_fldFileName_swindow_start = '{}'".format(self._sdatefile),
"stream_fldFileName_swindow_end = '{}'".format(self._sdatefile),
- "stream_year_first_cropcal = 2000",
- "stream_year_last_cropcal = 2000",
- "model_year_align_cropcal = 2000",
+ "stream_year_first_cropcal_swindows = 2000",
+ "stream_year_last_cropcal_swindows = 2000",
+ "model_year_align_cropcal_swindows = 2000",
" ",
"! (h1) Annual outputs on sowing or harvest axis",
"hist_fincl2 = 'GRAINC_TO_FOOD_PERHARV', 'GRAINC_TO_FOOD_ANN', 'SDATES', 'SDATES_PERHARV', 'SYEARS_PERHARV', 'HDATES', 'GDDHARV_PERHARV', 'GDDACCUM_PERHARV', 'HUI_PERHARV', 'SOWING_REASON_PERHARV', 'HARVEST_REASON_PERHARV'",
@@ -442,7 +445,7 @@ def _run_generate_gdds(self, case_gddgen):
f"--sdates-file {sdates_file}",
f"--hdates-file {hdates_file}",
f"--output-dir generate_gdds_out",
- f"--skip-crops miscanthus,irrigated_miscanthus",
+ f"--skip-crops miscanthus,irrigated_miscanthus,switchgrass,irrigated_switchgrass",
]
)
stu.run_python_script(
diff --git a/cime_config/SystemTests/sspmatrixcn.py b/cime_config/SystemTests/sspmatrixcn.py
new file mode 100644
index 0000000000..f4a09a277e
--- /dev/null
+++ b/cime_config/SystemTests/sspmatrixcn.py
@@ -0,0 +1,371 @@
+"""
+
+CTSM only test to do the CN-matrix spinup procedure
+
+This is a CLM specific test:
+Verifies that spinup works correctly
+this test is only valid for CLM compsets
+
+Step 0: Run a AD cold-start with matrix and matrix spinup off
+ Fast mode and fast-mode 2-loop spinup steps are now skipped
+ These were labeled as Step 1 and Step 2.
+Step 3: Run a slow-mode spinup
+Step 4: matrix Spinup off
+"""
+import shutil, glob, os, sys
+
+if __name__ == "__main__":
+ CIMEROOT = os.environ.get("CIMEROOT")
+ if CIMEROOT is None:
+ CIMEROOT = "../../cime"
+
+ sys.path.append(os.path.join(CIMEROOT, "scripts", "lib"))
+ sys.path.append(os.path.join(CIMEROOT, "scripts"))
+else:
+ from CIME.utils import append_testlog
+
+from CIME.XML.standard_module_setup import *
+from CIME.SystemTests.system_tests_common import SystemTestsCommon
+from CIME.SystemTests.test_utils import user_nl_utils
+
+
+logger = logging.getLogger(__name__)
+
+
+class SSPMATRIXCN(SystemTestsCommon):
+
+ # Class data
+ nyr_forcing = 2
+ # Get different integer multiples of the number of forcing years
+ full = nyr_forcing
+ twice = 2 * nyr_forcing
+ thrice = 3 * nyr_forcing
+ # Define the settings that will be used for each step
+ steps = ["0-AD", "1-SASU", "2-norm"]
+ desc = [
+ "Accell-Decomp(AD)-coldstart",
+ "slow-mode Semi-Analytic SpinUp(SASU)",
+ "normal",
+ ]
+ runtyp = ["startup", "hybrid", "branch"]
+ spin = ["on", "sasu", "off"]
+ stop_n = [5, thrice, thrice]
+ cold = [True, False, False]
+ iloop = [-999, -999, -999]
+ sasu = [-999, -999, -999]
+
+ def __init__(self, case=None):
+ """
+ initialize an object interface to the SSPMATRIXCN system test
+ """
+ expect(
+ len(self.steps) == len(self.sasu),
+ "length of steps must be the same as sasu",
+ )
+ expect(
+ len(self.steps) == len(self.spin),
+ "length of steps must be the same as spin",
+ )
+ expect(
+ len(self.steps) == len(self.desc),
+ "length of steps must be the same as desc",
+ )
+ expect(
+ len(self.steps) == len(self.cold),
+ "length of steps must be the same as cold",
+ )
+ expect(
+ len(self.steps) == len(self.runtyp),
+ "length of steps must be the same as runtyp",
+ )
+ expect(
+ len(self.steps) == len(self.iloop),
+ "length of steps must be the same as iloop",
+ )
+ expect(
+ len(self.steps) == len(self.stop_n),
+ "length of steps must be the same as stop_n",
+ )
+
+ if __name__ != "__main__":
+ SystemTestsCommon.__init__(self, case)
+ ystart = int(self._case.get_value("DATM_YR_START"))
+ yend = int(self._case.get_value("DATM_YR_END"))
+ self.comp = self._case.get_value("COMP_LND")
+ else:
+ self._case = None
+ self.comp = "clm"
+ ystart = 2000
+ yend = 2001
+
+ for n in range(len(self.steps)):
+ if n == 0:
+ expect(self.cold[n] == True, "First step MUST be a cold-start")
+ expect(self.runtyp[n] == "startup", "First step MUST be a startup")
+ else:
+ expect(self.cold[n] == False, "Other steps must NOT be a cold-start")
+ expect(self.runtyp[n] != "startup", "Other steps MUST NOT be a startup")
+
+ if self.spin[n] == "sasu":
+ expect(self.cold[n] == False, "SASU step should NOT be a cold-start")
+ if self.sasu[n] != -999:
+ expect(self.sasu[n] > 0, "SASU steps must set SASU cycle")
+ expect(
+ self.sasu[n] <= self.nyr_forcing,
+ "SASU cycles can't be greater than a full forcing cycle",
+ )
+
+ expect(
+ yend - ystart + 1 == self.nyr_forcing,
+ "Number of years run over MUST correspond to nyr_forcing",
+ )
+ self._testname = "SSPMATRIX"
+
+ def check_n(self, n):
+ "Check if n is within range"
+ expect(
+ ((n >= 0) and (n < self.n_steps())),
+ "Step number is out of range = " + str(n),
+ )
+
+ def __logger__(self, n=0):
+ "Log info on this step"
+
+ self.check_n(n)
+ msg = "Step {}: {}: doing a {} run for {} years".format(
+ self.steps[n], self.runtyp[n], self.desc[n], self.stop_n[n]
+ )
+ logger.info(msg)
+ logger.info(" spinup type: {}".format(self.spin[n]))
+ if __name__ != "__main__":
+ append_testlog(msg)
+ if n + 1 < self.n_steps():
+ logger.info(" writing restarts at end of run")
+ logger.info(" short term archiving is on ")
+
+ def n_steps(self):
+ "Total number of steps"
+
+ return len(self.steps)
+
+ def total_years(self):
+ "Total number of years needed to do the full spinup"
+
+ ysum = 0
+ for nyr in self.stop_n:
+ ysum = ysum + nyr
+
+ return ysum
+
+ def append_user_nl(self, caseroot, n=0):
+ "Append needed settings to the user_nl files"
+
+ self.check_n(n)
+ # For all set output to yearly
+ contents_to_append = "hist_nhtfrq = -8760"
+ contents_to_append = contents_to_append + ", hist_mfilt = " + str(self.nyr_forcing)
+ # For all but last step turn extra matrix output to off
+ b4last = self.n_steps() - 1
+ if n < b4last:
+ contents_to_append = contents_to_append + ", hist_wrt_matrixcn_diag = .False."
+ # For matrix spinup steps, set the matrix spinup and other variables associated with it
+ if self.spin[n] == "sasu":
+ contents_to_append = contents_to_append + ", nyr_forcing = " + str(self.nyr_forcing)
+ if self.sasu[n] != -999:
+ contents_to_append = contents_to_append + ", nyr_sasu = " + str(self.sasu[n])
+ if self.iloop[n] != -999:
+ contents_to_append = contents_to_append + ", iloop_avg = " + str(self.iloop[n])
+
+ # For cold start, run with matrix off
+ if self.cold[n]:
+ contents_to_append = contents_to_append + ", use_matrixcn = .False."
+ contents_to_append = contents_to_append + ", use_soil_matrixcn = .False."
+
+ # Always append to the end
+ user_nl_utils.append_to_user_nl_files(
+ caseroot=caseroot, component=self.comp, contents=contents_to_append
+ )
+
+ def run_phase(self):
+ "Run phase"
+
+ caseroot = self._case.get_value("CASEROOT")
+ orig_case = self._case
+ orig_casevar = self._case.get_value("CASE")
+
+ # Get a clone of each step except the last one
+ b4last = self.n_steps() - 1
+ for n in range(b4last):
+ #
+ # Clone the main case, and get it setup for the next step
+ #
+ clone_path = "{}.step{}".format(caseroot, self.steps[n])
+ if os.path.exists(clone_path):
+ shutil.rmtree(clone_path)
+ if n > 0:
+ del clone
+ self._set_active_case(orig_case)
+ clone = self._case.create_clone(clone_path, keepexe=True)
+ os.chdir(clone_path)
+ self._set_active_case(clone)
+
+ self.__logger__(n)
+
+ with clone:
+ clone.set_value("RUN_TYPE", self.runtyp[n])
+ clone.set_value("STOP_N", self.stop_n[n])
+
+ clone.set_value("CLM_ACCELERATED_SPINUP", self.spin[n])
+
+ if self.cold[n]:
+ clone.set_value("CLM_FORCE_COLDSTART", "on")
+ else:
+ clone.set_value("CLM_FORCE_COLDSTART", "off")
+
+ self.append_user_nl(clone_path, n)
+
+ dout_sr = clone.get_value("DOUT_S_ROOT")
+
+ self._skip_pnl = False
+ #
+ # Start up from the previous case
+ #
+ rundir = clone.get_value("RUNDIR")
+ with clone:
+ if n > 0:
+ clone.set_value("GET_REFCASE", False)
+ expect("refcase" in locals(), "refcase was NOT previously set")
+ clone.set_value("RUN_REFCASE", refcase)
+ expect("refdate" in locals(), "refdate was NOT previously set")
+ clone.set_value("RUN_STARTDATE", refdate)
+ clone.set_value("RUN_REFDATE", refdate)
+ for item in glob.glob("{}/*{}*".format(rest_path, refdate)):
+ linkfile = os.path.join(rundir, os.path.basename(item))
+ if os.path.exists(linkfile):
+ os.remove(linkfile)
+ if not os.path.isdir(rundir):
+ os.makedirs(rundir)
+ os.symlink(item, linkfile)
+
+ for item in glob.glob("{}/*rpointer*".format(rest_path)):
+ shutil.copy(item, rundir)
+
+ #
+ # Run the case (Archiving on)
+ #
+ self._case.flush()
+ self.run_indv(suffix="step{}".format(self.steps[n]), st_archive=True)
+
+ #
+ # Get the reference case from this step for the next step
+ #
+ refcase = clone.get_value("CASE")
+ refdate = run_cmd_no_fail(
+ r'ls -1dt {}/rest/*-00000* | head -1 | sed "s/-00000.*//" | sed "s/^.*rest\///"'.format(
+ dout_sr
+ )
+ )
+ refsec = "00000"
+ rest_path = os.path.join(dout_sr, "rest", "{}-{}".format(refdate, refsec))
+
+ #
+ # Last step in original case
+ #
+ n = self.n_steps() - 1
+ #
+ # Setup the case to run from the previous clone step
+ #
+ os.chdir(caseroot)
+ self._set_active_case(orig_case)
+ self.__logger__(n)
+ self._case.set_value("DOUT_S", False)
+ self._case.set_value("RUN_TYPE", self.runtyp[n])
+ self._case.set_value("STOP_N", self.stop_n[n])
+ rundir = self._case.get_value("RUNDIR")
+ self._case.set_value("GET_REFCASE", False)
+ expect("refcase" in locals(), "refcase was NOT previously set")
+ self._case.set_value("RUN_REFCASE", refcase)
+ expect("refdate" in locals(), "refdate was NOT previously set")
+ self._case.set_value("RUN_REFDATE", refdate)
+ self._case.set_value("RUN_STARTDATE", refdate)
+ for item in glob.glob("{}/*{}*".format(rest_path, refdate)):
+ linkfile = os.path.join(rundir, os.path.basename(item))
+ if os.path.exists(linkfile):
+ os.remove(linkfile)
+ os.symlink(item, linkfile)
+
+ for item in glob.glob("{}/*rpointer*".format(rest_path)):
+ shutil.copy(item, rundir)
+
+ self.append_user_nl(clone_path, n)
+ #
+ # Don't need to set COLDSTART or ACCEL_SPINUP
+ #
+
+ #
+ # Run the case (short term archiving is off)
+ #
+ self._case.flush()
+ self.run_indv(suffix="step{}".format(self.steps[n]), st_archive=False)
+
+
+#
+# Unit testing for above
+#
+import unittest
+from CIME.case import Case
+from CIME.utils import _LessThanFilter
+from argparse import RawTextHelpFormatter
+
+
+class test_ssp_matrixcn(unittest.TestCase):
+ def setUp(self):
+ self.ssp = SSPMATRIXCN()
+
+ def test_logger(self):
+ # Test the logger
+ stream_handler = logging.StreamHandler(sys.stdout)
+ logger.addHandler(stream_handler)
+ logger.level = logging.DEBUG
+ logger.info("nyr_forcing = {}".format(self.ssp.nyr_forcing))
+ for n in range(self.ssp.n_steps()):
+ self.ssp.__logger__(n)
+ if self.ssp.spin[n] == "sasu":
+ logger.info(" SASU spinup is .true.")
+ if self.ssp.sasu[n] != -999:
+ logger.info(" nyr_sasu = {}".format(self.ssp.sasu[n]))
+ if self.ssp.iloop[n] != -999:
+ logger.info(" iloop_avg = {}".format(self.ssp.iloop[n]))
+
+ logger.info("Total number of years {}".format(self.ssp.total_years()))
+ logger.removeHandler(stream_handler)
+
+ def test_n_steps(self):
+ self.assertTrue(self.ssp.n_steps() == 3)
+
+ def test_valid_n(self):
+ for n in range(self.ssp.n_steps()):
+ self.ssp.check_n(n)
+
+ def test_negative_n(self):
+ self.assertRaises(SystemExit, self.ssp.check_n, -1)
+
+ def test_n_too_big(self):
+ self.assertRaises(SystemExit, self.ssp.check_n, self.ssp.n_steps())
+
+ def test_append_user_nl_step2(self):
+ ufile = "user_nl_clm"
+ if not os.path.exists(ufile):
+ os.mknod(ufile)
+ else:
+ expect(0, ufile + " file already exists, not overwritting it")
+
+ self.ssp.append_user_nl(caseroot=".", n=2)
+ print(ufile + " for step 2")
+ log = open(ufile, "r").read()
+ print(log)
+ os.remove(ufile)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/cime_config/SystemTests/systemtest_utils.py b/cime_config/SystemTests/systemtest_utils.py
index c5ac986abd..c252f73251 100644
--- a/cime_config/SystemTests/systemtest_utils.py
+++ b/cime_config/SystemTests/systemtest_utils.py
@@ -2,7 +2,8 @@
Reduce code duplication by putting reused functions here.
"""
-import os, subprocess
+import os, subprocess, re, glob
+from collections import OrderedDict
def cmds_to_setup_conda(caseroot):
@@ -84,3 +85,26 @@ def run_python_script(caseroot, this_conda_env, command_in, tool_path):
except:
print(f"ERROR trying to run {tool_name}.")
raise
+
+
+# Read a user_nl file and return the namelist option if found
+def find_user_nl_option(caseroot, component, namelist_option):
+
+ # This is a copy of the CIME _get_list_of_user_nl_files
+ # which could be used if this moved into the CIME project
+ file_pattern = "user_nl_" + component + "*"
+ file_list = glob.glob(os.path.join(caseroot, file_pattern))
+
+ # Check that there is at least one file
+ if len(file_list) == 0:
+ raise RuntimeError("No user_nl files found for component " + component)
+
+ # Read through the file list and look for a match and return the whole entry
+ output = OrderedDict()
+ for one_file in file_list:
+ with open(one_file, "r") as user_nl_file:
+ user_nl_text = user_nl_file.read()
+ reg = rf"{namelist_option}.*?(?=,|\n)"
+ find_out = re.findall(reg, user_nl_text)
+ output[one_file] = find_out
+ return output
diff --git a/cime_config/buildnml b/cime_config/buildnml
index 8e93b77015..3eb45dff31 100755
--- a/cime_config/buildnml
+++ b/cime_config/buildnml
@@ -50,6 +50,27 @@ def buildnml(case, caseroot, compname):
clm_force_coldstart = case.get_value("CLM_FORCE_COLDSTART")
lnd_tuning_mode = case.get_value("LND_TUNING_MODE")
clm_accelerated_spinup = case.get_value("CLM_ACCELERATED_SPINUP")
+ comp_interface = case.get_value("COMP_INTERFACE")
+ lilac_mode = case.get_value("LILAC_MODE")
+ if comp_interface == "nuopc":
+ yr_start = case.get_value("DATM_YR_START")
+ yr_end = case.get_value("DATM_YR_END")
+ else:
+ yr_start = case.get_value("DATM_CLMNCEP_YR_START")
+ yr_end = case.get_value("DATM_CLMNCEP_YR_END")
+
+ if yr_start != None and yr_start < 0:
+ yr_start = case.get_value("DATM_CPLHIST_YR_START")
+ yr_end = case.get_value("DATM_CPLHIST_YR_END")
+
+ # For LILAC
+ if yr_start == None or lilac_mode == "on":
+ yr_start = "0"
+ yr_end = "0"
+
+ yr_start = int(yr_start)
+ yr_end = int(yr_end)
+
comp_atm = case.get_value("COMP_ATM")
lnd_grid = case.get_value("LND_GRID")
ninst_lnd = case.get_value("NINST_LND")
@@ -252,7 +273,21 @@ def buildnml(case, caseroot, compname):
tuning = "-lnd_tuning_mode %s " % lnd_tuning_mode
+ #
+ # Spinup settings and specifics for SASU spinup
+ #
spinup = "-clm_accelerated_spinup %s " % clm_accelerated_spinup
+ if clm_accelerated_spinup == "sasu":
+ if (yr_start != None) and (yr_end != None):
+ nyr = yr_end - yr_start + 1
+ if (yr_end <= 0) or (yr_start <= 0):
+ logger.error("ERROR: Year start and end are both negative and should not be")
+ clm_namelist_opts = "nyr_forcing={} {}".format(nyr, clm_namelist_opts)
+ else:
+ logger.warning(
+ "WARNING: It does not make sense to do a SASU spinup with a prognostic atmosphere model"
+ )
+ logger.warning(" as it expects regular atmosphere forcing that is cycled over")
infile = os.path.join(ctsmconf, "namelist")
diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml
index d69bdbc302..3c48e16651 100644
--- a/cime_config/config_component.xml
+++ b/cime_config/config_component.xml
@@ -87,10 +87,11 @@
clm4_5_CRUv7
clm4_5_GSWP3v1
clm4_5_cam6.0
- clm4_5_cam4.0
- clm4_5_cam5.0
- clm4_5_cam7.0
- clm4_5_cam6.0
+ clm4_5_cam4.0
+ clm4_5_cam5.0
+ clm4_5_cam6.0
+ clm4_5_cam7.0
+ clm4_5_cam5.0
clm4_5_QIAN
clm4_5_QIAN
clm4_5_1PT
@@ -102,9 +103,10 @@
clm5_0_GSWP3v1
clm5_0_GSWP3v1
clm5_0_cam6.0
- clm5_0_cam4.0
- clm5_0_cam5.0
- clm5_0_cam7.0
+ clm5_0_cam4.0
+ clm5_0_cam5.0
+ clm5_0_cam6.0
+ clm5_0_cam7.0
clm5_0_cam6.0
clm5_0_QIAN
clm5_0_QIAN
@@ -112,22 +114,24 @@
clm5_0_NLDAS2
clm5_0_ERA5
- clm5_1_GSWP3v1
clm5_1_GSWP3v1
- clm5_1_cam6.0
- clm5_1_cam4.0
- clm5_1_cam5.0
- clm5_1_cam6.0
+ INVALID_USE_CLM60_NOT_CLM51
+ clm5_1_cam4.0
+ clm5_1_cam5.0
+ clm5_1_cam6.0
+ INVALID_USE_CLM60_NOT_CLM51_FOR_CAM70
+ INVALID_USE_CLM60_NOT_CLM51_FOR_CPLHIST
clm6_0_CRUv7
clm6_0_CRUv7
clm6_0_GSWP3v1
clm6_0_GSWP3v1
clm6_0_cam6.0
- clm6_0_cam4.0
- clm6_0_cam5.0
- clm6_0_cam7.0
- clm6_0_cam6.0
+ clm6_0_cam4.0
+ clm6_0_cam5.0
+ clm6_0_cam6.0
+ clm6_0_cam7.0
+ clm6_0_cam7.0
clm6_0_QIAN
clm6_0_QIAN
clm6_0_1PT
@@ -162,6 +166,20 @@
This is typically set by the compset.
+
+ logical
+ TRUE,FALSE
+ TRUE
+
+ run_component_cpl
+ env_run.xml
+ If CTSM will set the dust settings in drv_flds_in (TRUE), or if ATM (i.e. CAM) will - DO NOT EDIT (set by compset name)
+
+
char
clm,nwp
@@ -199,24 +217,24 @@
UNSET
- 2010_control
- 2000_control
- 1850_control
+ 2010_control
+ 2000_control
+ 1850_control
1850_noanthro_control
1850_noanthro_control
- 20thC_transient
- 1850-2100_SSP5-8.5_transient
- 1850-2100_SSP1-2.6_transient
- 1850-2100_SSP3-7.0_transient
- 1850-2100_SSP5-3.4_transient
- 1850-2100_SSP2-4.5_transient
- 1850-2100_SSP2-4.5_transient
- 1850-2100_SSP1-1.9_transient
- 1850-2100_SSP4-3.4_transient
- 1850-2100_SSP4-6.0_transient
- 1850-2100_SSP5-8.5_transient
- 20thC_transient
- 1850-2100_SSP5-8.5_transient
+ 20thC_transient
+ 1850-2100_SSP5-8.5_transient
+ 1850-2100_SSP1-2.6_transient
+ 1850-2100_SSP3-7.0_transient
+ 1850-2100_SSP5-3.4_transient
+ 1850-2100_SSP2-4.5_transient
+ 1850-2100_SSP2-4.5_transient
+ 1850-2100_SSP1-1.9_transient
+ 1850-2100_SSP4-3.4_transient
+ 1850-2100_SSP4-6.0_transient
+ 1850-2100_SSP5-8.5_transient
+ 20thC_transient
+ 1850-2100_SSP5-8.5_transient
run_component_ctsm
env_run.xml
@@ -293,11 +311,11 @@
char
- on,off
+ on,sasu,off
off
run_component_ctsm
env_run.xml
- Turn on any settings for accellerating the model spinup.
+ Turn on any settings for accellerating the model spinup. SASU is to run the Semi-Analytic Spin-Up with the CN soil matrix method.
diff --git a/cime_config/config_tests.xml b/cime_config/config_tests.xml
index 5c5bdc2892..12859b9131 100644
--- a/cime_config/config_tests.xml
+++ b/cime_config/config_tests.xml
@@ -123,6 +123,18 @@ This defines various CTSM-specific system tests
$STOP_N
+
+ FATES potential vegetarion spin-up + land use transient run test
+ 1
+ ndays
+ startup
+ 4
+ FALSE
+ FALSE
+ $STOP_OPTION
+ $STOP_N
+
+
Generate prescribed maturity requirements, then test with them
1
@@ -163,6 +175,19 @@ SSP smoke CLM spinup test (only valid for CLM compsets with CLM45)
$STOP_N
+
+ smoke CLM CN-Matrix spinup test
+ 1
+ nyears
+ startup
+ 2000
+ 2000
+ 2001
+ 5
+ FALSE
+ FALSE
+
+
CLM user-defined soil structure test
1
diff --git a/cime_config/testdefs/ExpectedTestFails.xml b/cime_config/testdefs/ExpectedTestFails.xml
index dad6acb63d..d5e3e4e378 100644
--- a/cime_config/testdefs/ExpectedTestFails.xml
+++ b/cime_config/testdefs/ExpectedTestFails.xml
@@ -37,6 +37,21 @@
+
+
+ FAIL
+ #2619
+ This failure relates to the following REP failure.
+
+
+
+
+ FAIL
+ #2619
+ This failure relates to the preceding ERP failure.
+
+
+
FAIL
@@ -44,7 +59,7 @@
-
+
FAIL
#2542
@@ -58,15 +73,11 @@
-
+
FAIL
#2310
-
- FAIL
- #2310
-
@@ -80,17 +91,6 @@
-
-
- FAIL
- #2310
-
-
- FAIL
- #2310
-
-
-
FAIL
@@ -163,34 +163,41 @@
+
+
+ FAIL
+ #2659
+
+
+
-
+
FAIL
- #2321
+ #2653
-
-
+
+
FAIL
- #2373
+ FATES#1216
-
+
+
+
+
FAIL
- FATES#701
+ #2321
-
-
+
+
FAIL
#2373
-
-
-
FAIL
FATES#701
@@ -259,10 +266,6 @@
FAIL
#2310
-
- FAIL
- #2310
-
diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml
index 707a310f89..951e0d8d5b 100644
--- a/cime_config/testdefs/testlist_clm.xml
+++ b/cime_config/testdefs/testlist_clm.xml
@@ -22,6 +22,15 @@
+
+
+
+
+
+
+
+
+
@@ -33,6 +42,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -63,6 +82,7 @@
+
@@ -80,22 +100,22 @@
-
+
-
+
-
+
-
+
@@ -109,7 +129,7 @@
-
+
@@ -118,7 +138,7 @@
-
+
@@ -127,7 +147,7 @@
-
+
@@ -136,7 +156,7 @@
-
+
@@ -145,7 +165,7 @@
-
+
@@ -155,7 +175,7 @@
-
+
@@ -182,7 +202,7 @@
-
+
@@ -191,7 +211,7 @@
-
+
@@ -200,7 +220,7 @@
-
+
@@ -209,7 +229,7 @@
-
+
@@ -218,7 +238,7 @@
-
+
@@ -227,7 +247,7 @@
-
+
@@ -236,7 +256,7 @@
-
+
@@ -246,7 +266,7 @@
+
+
+
@@ -3012,7 +3487,7 @@
-
+
@@ -3022,9 +3497,10 @@
-
+
+
@@ -3032,10 +3508,11 @@
-
+
+
@@ -3092,5 +3569,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cime_config/testdefs/testmods_dirs/clm/Fates/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/Fates/user_nl_clm
index 406fb598f6..91df3e2e61 100644
--- a/cime_config/testdefs/testmods_dirs/clm/Fates/user_nl_clm
+++ b/cime_config/testdefs/testmods_dirs/clm/Fates/user_nl_clm
@@ -16,7 +16,7 @@ hist_fincl1 = 'FATES_NCOHORTS', 'FATES_TRIMMING', 'FATES_AREA_PLANTS',
'FATES_SAPWOODC', 'FATES_LEAFC', 'FATES_FROOTC', 'FATES_REPROC',
'FATES_STRUCTC', 'FATES_NONSTRUCTC', 'FATES_VEGC_ABOVEGROUND',
'FATES_CANOPY_VEGC', 'FATES_USTORY_VEGC', 'FATES_PRIMARY_PATCHFUSION_ERR',
-'FATES_HARVEST_CARBON_FLUX', 'FATES_DISTURBANCE_RATE_FIRE',
+'FATES_HARVEST_WOODPROD_C_FLUX', 'FATES_DISTURBANCE_RATE_FIRE',
'FATES_DISTURBANCE_RATE_LOGGING', 'FATES_DISTURBANCE_RATE_TREEFALL',
'FATES_STOMATAL_COND', 'FATES_LBLAYER_COND', 'FATES_NPP', 'FATES_GPP',
'FATES_AUTORESP', 'FATES_GROWTH_RESP', 'FATES_MAINT_RESP', 'FATES_GPP_CANOPY',
diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2/README b/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2/README
new file mode 100644
index 0000000000..9b782cb2a7
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2/README
@@ -0,0 +1,4 @@
+Currently the FATES LUH2 category of test mods currently only supports
+4x5 grid resolutions. This is because we only have one LUH2 time series
+dataset for the 4x5 resolution. In the future we will provide more resolutions
+which will be added to the namelist defaults.
diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2/user_nl_clm
index 854c21407f..e25490ffbb 100644
--- a/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2/user_nl_clm
+++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2/user_nl_clm
@@ -1 +1,9 @@
+
+! Run a transient case, with vegetation starting from bare ground, but land use starting from LUH state vector on starting date, in a nocomp configuration.
+! From Charlie's list of valid FATES configurations:
+! https://docs.google.com/spreadsheets/d/1eE3sRMYxfocZKbT8uIQhXpjjtfM2feXPRSWXJNoo4jM/edit#gid=0
use_fates_luh = .true.
+use_fates_nocomp = .true.
+use_fates_fixed_biogeog = .true.
+use_fates_sp = .false.
+use_fates_potentialveg = .false.
diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2HarvestArea/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2HarvestArea/include_user_mods
new file mode 100644
index 0000000000..7eb8bb1579
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2HarvestArea/include_user_mods
@@ -0,0 +1 @@
+../FatesColdLUH2
diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2HarvestArea/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2HarvestArea/user_nl_clm
new file mode 100644
index 0000000000..426b41b49e
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2HarvestArea/user_nl_clm
@@ -0,0 +1 @@
+fates_harvest_mode = 'luhdata_area'
diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2HarvestMass/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2HarvestMass/include_user_mods
new file mode 100644
index 0000000000..7eb8bb1579
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2HarvestMass/include_user_mods
@@ -0,0 +1 @@
+../FatesColdLUH2
diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2HarvestMass/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2HarvestMass/user_nl_clm
new file mode 100644
index 0000000000..7b6bc24f5a
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdLUH2HarvestMass/user_nl_clm
@@ -0,0 +1 @@
+fates_harvest_mode = 'luhdata_mass'
diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdLandUse/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/FatesColdLandUse/user_nl_clm
index 668f9c861d..b27a74031c 100644
--- a/cime_config/testdefs/testmods_dirs/clm/FatesColdLandUse/user_nl_clm
+++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdLandUse/user_nl_clm
@@ -1,2 +1,2 @@
flanduse_timeseries = '$DIN_LOC_ROOT/lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_4x5_hist_16_CMIP6_1850-2015_c230620.nc'
-do_harvest = .true.
+fates_harvest_mode = 'landuse_timeseries'
diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdLogging/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/FatesColdLogging/user_nl_clm
index 3b74a4fd37..d2079d9e43 100644
--- a/cime_config/testdefs/testmods_dirs/clm/FatesColdLogging/user_nl_clm
+++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdLogging/user_nl_clm
@@ -1 +1 @@
-use_fates_logging= .true.
+fates_harvest_mode = 'event_code'
diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesLUPFT/README b/cime_config/testdefs/testmods_dirs/clm/FatesLUPFT/README
new file mode 100644
index 0000000000..88f5c2c8fb
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/FatesLUPFT/README
@@ -0,0 +1,9 @@
+This test mod does not use cold start and is intended to
+be used in conjunction with a test workflow that provides
+an initialization file. Currently this is accomplished
+by using the test mod in conjunction with the PVT
+system test. The PVT system test runs a FATES spin-up
+case using the use_fates_potentialveg mode and then
+references the restart output to run a use_fates_lupft
+transient mode case.
+
diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesLUPFT/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/FatesLUPFT/include_user_mods
new file mode 100644
index 0000000000..4c7aa0f2b4
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/FatesLUPFT/include_user_mods
@@ -0,0 +1 @@
+../Fates
diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesLUPFT/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/FatesLUPFT/user_nl_clm
new file mode 100644
index 0000000000..10044848a0
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/FatesLUPFT/user_nl_clm
@@ -0,0 +1 @@
+use_fates_lupft = .true.
diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesLUPFTAreaHarvest/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/FatesLUPFTAreaHarvest/include_user_mods
new file mode 100644
index 0000000000..1ceba4c200
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/FatesLUPFTAreaHarvest/include_user_mods
@@ -0,0 +1 @@
+../FatesLUPFT
diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesLUPFTAreaHarvest/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/FatesLUPFTAreaHarvest/user_nl_clm
new file mode 100644
index 0000000000..426b41b49e
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/FatesLUPFTAreaHarvest/user_nl_clm
@@ -0,0 +1 @@
+fates_harvest_mode = 'luhdata_area'
diff --git a/cime_config/testdefs/testmods_dirs/clm/GddGen/README b/cime_config/testdefs/testmods_dirs/clm/GddGen/README
new file mode 100644
index 0000000000..3236ca609a
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/GddGen/README
@@ -0,0 +1,5 @@
+The GddGen test is set up just like a GDD-Generating run, with two differences:
+1) It doesn't include an all-crops-everywhere surface dataset,
+2) it doesn't actually run the GDD-generating script,
+and
+3) it includes some extra outputs.
diff --git a/cime_config/testdefs/testmods_dirs/clm/GddGen/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/GddGen/include_user_mods
new file mode 100644
index 0000000000..4d75082583
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/GddGen/include_user_mods
@@ -0,0 +1,2 @@
+../cropMonthOutput
+../oldCropCals
\ No newline at end of file
diff --git a/cime_config/testdefs/testmods_dirs/clm/GddGen/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/GddGen/user_nl_clm
new file mode 100644
index 0000000000..cfde517fd9
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/GddGen/user_nl_clm
@@ -0,0 +1,13 @@
+cropcals_rx = .true.
+stream_fldFileName_swindow_start = '$DIN_LOC_ROOT/lnd/clm2/cropdata/calendars/processed/sdates_ggcmi_crop_calendar_phase3_v1.01_nninterp-hcru_hcru_mt13.2000-2000.20230728_165845.tweaked_latlons.nc'
+stream_fldFileName_swindow_end = '$DIN_LOC_ROOT/lnd/clm2/cropdata/calendars/processed/sdates_ggcmi_crop_calendar_phase3_v1.01_nninterp-hcru_hcru_mt13.2000-2000.20230728_165845.tweaked_latlons.nc'
+stream_fldFileName_cultivar_gdds = ''
+generate_crop_gdds = .true.
+use_mxmat = .false.
+
+! (h3) Daily outputs for GDD generation and figure-making
+hist_fincl4 = 'GDDACCUM', 'GDDHARV'
+hist_nhtfrq(4) = -24
+hist_mfilt(4) = 365
+hist_type1d_pertape(4) = 'PFTS'
+hist_dov2xy(4) = .false.
diff --git a/cime_config/testdefs/testmods_dirs/clm/RxCropCalsAdaptGGCMI/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/RxCropCalsAdaptGGCMI/include_user_mods
new file mode 100644
index 0000000000..23ea3745e6
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/RxCropCalsAdaptGGCMI/include_user_mods
@@ -0,0 +1 @@
+../crop
diff --git a/cime_config/testdefs/testmods_dirs/clm/RxCropCalsAdaptGGCMI/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/RxCropCalsAdaptGGCMI/user_nl_clm
new file mode 100644
index 0000000000..fdf5a86c26
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/RxCropCalsAdaptGGCMI/user_nl_clm
@@ -0,0 +1,6 @@
+cropcals_rx = .false.
+cropcals_rx_adapt = .true.
+stream_gdd20_seasons = .true.
+flush_gdd20 = .true.
+!TODO SSR: Try without this once you have half-degree inputs
+allow_invalid_gdd20_season_inputs = .true.
diff --git a/cime_config/testdefs/testmods_dirs/clm/RxCropCalsNoAdapt/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/RxCropCalsNoAdapt/include_user_mods
new file mode 100644
index 0000000000..23ea3745e6
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/RxCropCalsNoAdapt/include_user_mods
@@ -0,0 +1 @@
+../crop
diff --git a/cime_config/testdefs/testmods_dirs/clm/RxCropCalsNoAdapt/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/RxCropCalsNoAdapt/user_nl_clm
new file mode 100644
index 0000000000..625960b389
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/RxCropCalsNoAdapt/user_nl_clm
@@ -0,0 +1,2 @@
+cropcals_rx = .true.
+cropcals_rx_adapt = .false.
diff --git a/cime_config/testdefs/testmods_dirs/clm/StreamGdd20Seasons/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/StreamGdd20Seasons/user_nl_clm
new file mode 100644
index 0000000000..8b040d9d43
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/StreamGdd20Seasons/user_nl_clm
@@ -0,0 +1,2 @@
+stream_gdd20_seasons = .true.
+allow_invalid_gdd20_season_inputs = .true.
diff --git a/cime_config/testdefs/testmods_dirs/clm/ciso_monthly_matrixcn/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/ciso_monthly_matrixcn/include_user_mods
new file mode 100644
index 0000000000..2cc5720115
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/ciso_monthly_matrixcn/include_user_mods
@@ -0,0 +1 @@
+../ciso_monthly
diff --git a/cime_config/testdefs/testmods_dirs/clm/ciso_monthly_matrixcn/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/ciso_monthly_matrixcn/user_nl_clm
new file mode 100644
index 0000000000..6b7eb4347d
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/ciso_monthly_matrixcn/user_nl_clm
@@ -0,0 +1,3 @@
+ use_matrixcn = .true.
+ use_soil_matrixcn = .true.
+ hist_wrt_matrixcn_diag = .true.
diff --git a/cime_config/testdefs/testmods_dirs/clm/ciso_monthly_matrixcn_spinup/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/ciso_monthly_matrixcn_spinup/include_user_mods
new file mode 100644
index 0000000000..0634bda41e
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/ciso_monthly_matrixcn_spinup/include_user_mods
@@ -0,0 +1 @@
+../ciso_monthly_matrixcn
diff --git a/cime_config/testdefs/testmods_dirs/clm/ciso_monthly_matrixcn_spinup/shell_commands b/cime_config/testdefs/testmods_dirs/clm/ciso_monthly_matrixcn_spinup/shell_commands
new file mode 100755
index 0000000000..45fdc7e8fd
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/ciso_monthly_matrixcn_spinup/shell_commands
@@ -0,0 +1,2 @@
+./xmlchange CLM_ACCELERATED_SPINUP=sasu
+./xmlchange MOSART_MODE=NULL
diff --git a/cime_config/testdefs/testmods_dirs/clm/ciso_monthly_matrixcn_spinup/user_nl_mosart b/cime_config/testdefs/testmods_dirs/clm/ciso_monthly_matrixcn_spinup/user_nl_mosart
new file mode 100644
index 0000000000..82243d7d3d
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/ciso_monthly_matrixcn_spinup/user_nl_mosart
@@ -0,0 +1 @@
+frivinp = '/dev/null'
diff --git a/cime_config/testdefs/testmods_dirs/clm/ciso_soil_matrixcn_only/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/ciso_soil_matrixcn_only/include_user_mods
new file mode 100644
index 0000000000..ce640345c5
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/ciso_soil_matrixcn_only/include_user_mods
@@ -0,0 +1 @@
+../ciso
diff --git a/cime_config/testdefs/testmods_dirs/clm/ciso_soil_matrixcn_only/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/ciso_soil_matrixcn_only/user_nl_clm
new file mode 100644
index 0000000000..91b62c0c05
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/ciso_soil_matrixcn_only/user_nl_clm
@@ -0,0 +1,2 @@
+ use_matrixcn = .false.
+ use_soil_matrixcn = .true.
diff --git a/cime_config/testdefs/testmods_dirs/clm/clm50dynroots/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/clm50dynroots/user_nl_clm
deleted file mode 100644
index e493c3e8e7..0000000000
--- a/cime_config/testdefs/testmods_dirs/clm/clm50dynroots/user_nl_clm
+++ /dev/null
@@ -1,2 +0,0 @@
-use_dynroot = .true.
-use_hydrstress = .false.
diff --git a/cime_config/testdefs/testmods_dirs/clm/clm60_monthly_matrixcn_soilCN30/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/clm60_monthly_matrixcn_soilCN30/include_user_mods
new file mode 100644
index 0000000000..399579f425
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/clm60_monthly_matrixcn_soilCN30/include_user_mods
@@ -0,0 +1 @@
+../monthly
diff --git a/cime_config/testdefs/testmods_dirs/clm/clm60_monthly_matrixcn_soilCN30/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/clm60_monthly_matrixcn_soilCN30/user_nl_clm
new file mode 100644
index 0000000000..df20ced9e8
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/clm60_monthly_matrixcn_soilCN30/user_nl_clm
@@ -0,0 +1,2 @@
+use_soil_matrixcn = .true.
+paramfile = '$DIN_LOC_ROOT/lnd/clm2/paramdata/ctsm60_params_cn30.c240625.nc'
diff --git a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningModeCiso/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningModeCiso/include_user_mods
deleted file mode 100644
index 3dabdc9aeb..0000000000
--- a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningModeCiso/include_user_mods
+++ /dev/null
@@ -1 +0,0 @@
-../clm60cam6LndTuningMode
diff --git a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningModeCiso/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningModeCiso/user_nl_clm
deleted file mode 100644
index e7627dea50..0000000000
--- a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningModeCiso/user_nl_clm
+++ /dev/null
@@ -1,5 +0,0 @@
-! Turn on Carbon isotopes
-use_c13 = .true.
-use_c14 = .true.
-use_c13_timeseries = .true.
-use_c14_bombspike = .true.
diff --git a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningModeZDustSoilErod/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningModeZDustSoilErod/include_user_mods
deleted file mode 100644
index 3dabdc9aeb..0000000000
--- a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningModeZDustSoilErod/include_user_mods
+++ /dev/null
@@ -1 +0,0 @@
-../clm60cam6LndTuningMode
diff --git a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningModeZDustSoilErod/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningModeZDustSoilErod/user_nl_clm
deleted file mode 100644
index 93b7ee2e48..0000000000
--- a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningModeZDustSoilErod/user_nl_clm
+++ /dev/null
@@ -1,3 +0,0 @@
-! Turn on using the soil eroditability file in CTSM
-dust_emis_method = 'Zender_2003'
-zender_soil_erod_source = 'lnd'
diff --git a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode_1979Start/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode_1979Start/include_user_mods
deleted file mode 100644
index 3dabdc9aeb..0000000000
--- a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode_1979Start/include_user_mods
+++ /dev/null
@@ -1 +0,0 @@
-../clm60cam6LndTuningMode
diff --git a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode_2013Start/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode_2013Start/include_user_mods
deleted file mode 100644
index 3dabdc9aeb..0000000000
--- a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode_2013Start/include_user_mods
+++ /dev/null
@@ -1 +0,0 @@
-../clm60cam6LndTuningMode
diff --git a/cime_config/testdefs/testmods_dirs/clm/clm50dynroots/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/clm60cam7LndTuningMode/include_user_mods
similarity index 100%
rename from cime_config/testdefs/testmods_dirs/clm/clm50dynroots/include_user_mods
rename to cime_config/testdefs/testmods_dirs/clm/clm60cam7LndTuningMode/include_user_mods
diff --git a/cime_config/testdefs/testmods_dirs/clm/clm60cam7LndTuningMode/shell_commands b/cime_config/testdefs/testmods_dirs/clm/clm60cam7LndTuningMode/shell_commands
new file mode 100644
index 0000000000..7dd25a08bf
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/clm60cam7LndTuningMode/shell_commands
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+./xmlchange LND_TUNING_MODE="clm6_0_cam7.0"
+./xmlchange ROF_NCPL='$ATM_NCPL'
+
diff --git a/cime_config/testdefs/testmods_dirs/clm/clm60cam7LndTuningMode_1979Start/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/clm60cam7LndTuningMode_1979Start/include_user_mods
new file mode 100644
index 0000000000..ef8619d930
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/clm60cam7LndTuningMode_1979Start/include_user_mods
@@ -0,0 +1 @@
+../clm60cam7LndTuningMode
diff --git a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode_1979Start/shell_commands b/cime_config/testdefs/testmods_dirs/clm/clm60cam7LndTuningMode_1979Start/shell_commands
similarity index 100%
rename from cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode_1979Start/shell_commands
rename to cime_config/testdefs/testmods_dirs/clm/clm60cam7LndTuningMode_1979Start/shell_commands
diff --git a/cime_config/testdefs/testmods_dirs/clm/clm60cam7LndTuningMode_2013Start/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/clm60cam7LndTuningMode_2013Start/include_user_mods
new file mode 100644
index 0000000000..ef8619d930
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/clm60cam7LndTuningMode_2013Start/include_user_mods
@@ -0,0 +1 @@
+../clm60cam7LndTuningMode
diff --git a/cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode_2013Start/shell_commands b/cime_config/testdefs/testmods_dirs/clm/clm60cam7LndTuningMode_2013Start/shell_commands
similarity index 100%
rename from cime_config/testdefs/testmods_dirs/clm/clm60cam6LndTuningMode_2013Start/shell_commands
rename to cime_config/testdefs/testmods_dirs/clm/clm60cam7LndTuningMode_2013Start/shell_commands
diff --git a/cime_config/testdefs/testmods_dirs/clm/crop/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/crop/user_nl_clm
index 67042ea01a..aea8e39e6c 100644
--- a/cime_config/testdefs/testmods_dirs/clm/crop/user_nl_clm
+++ b/cime_config/testdefs/testmods_dirs/clm/crop/user_nl_clm
@@ -9,9 +9,12 @@
hist_fincl2 += 'DYN_COL_SOIL_ADJUSTMENTS_C'
-! Annual crop variables on per-sowing/per-harvest axes, per PFT.
-hist_fincl3 = 'SDATES', 'SDATES_PERHARV', 'SYEARS_PERHARV', 'HDATES', 'GRAINC_TO_FOOD_PERHARV', 'GRAINC_TO_FOOD_ANN', 'GRAINN_TO_FOOD_PERHARV', 'GRAINN_TO_FOOD_ANN', 'GRAINC_TO_SEED_PERHARV', 'GRAINC_TO_SEED_ANN', 'GRAINN_TO_SEED_PERHARV', 'GRAINN_TO_SEED_ANN', 'HDATES', 'GDDHARV_PERHARV', 'GDDACCUM_PERHARV', 'HUI_PERHARV', 'SOWING_REASON_PERHARV', 'HARVEST_REASON_PERHARV', 'SWINDOW_STARTS', 'SWINDOW_ENDS'
-hist_nhtfrq(3) = 17520
+! Instantaneous crop variables (including per-sowing/per-harvest axes), per PFT.
+! Note that, under normal circumstances, these should only be saved annually.
+! That's needed for the mxsowings and mxharvests axes to make sense.
+! However, for testing purposes, it makes sense to save more frequently.
+hist_fincl3 = 'SDATES', 'SDATES_PERHARV', 'SYEARS_PERHARV', 'HDATES', 'GRAINC_TO_FOOD_PERHARV', 'GRAINC_TO_FOOD_ANN', 'GRAINN_TO_FOOD_PERHARV', 'GRAINN_TO_FOOD_ANN', 'GRAINC_TO_SEED_PERHARV', 'GRAINC_TO_SEED_ANN', 'GRAINN_TO_SEED_PERHARV', 'GRAINN_TO_SEED_ANN', 'HDATES', 'GDDHARV_PERHARV', 'GDDACCUM_PERHARV', 'HUI_PERHARV', 'SOWING_REASON_PERHARV', 'HARVEST_REASON_PERHARV', 'SWINDOW_STARTS', 'SWINDOW_ENDS', 'GDD20_BASELINE', 'GDD20_SEASON_START', 'GDD20_SEASON_END'
+hist_nhtfrq(3) = -24
hist_mfilt(3) = 1
hist_type1d_pertape(3) = 'PFTS'
hist_dov2xy(3) = .false.
diff --git a/cime_config/testdefs/testmods_dirs/clm/cropMonthOutput/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/cropMonthOutput/user_nl_clm
index 8f779ed011..18220de5ef 100644
--- a/cime_config/testdefs/testmods_dirs/clm/cropMonthOutput/user_nl_clm
+++ b/cime_config/testdefs/testmods_dirs/clm/cropMonthOutput/user_nl_clm
@@ -1,4 +1,4 @@
- hist_nhtfrq = 0,-240,17520
+ hist_nhtfrq = 0,-240,0
hist_mfilt = 1,1,1
! NOTE slevis (2024/2/23) Adding option for tests to pass. In the long term
diff --git a/cime_config/testdefs/testmods_dirs/clm/decStart/README b/cime_config/testdefs/testmods_dirs/clm/decStart/README
new file mode 100644
index 0000000000..7cdab6abfd
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/decStart/README
@@ -0,0 +1 @@
+Use midDecStart instead of decStart if you want ERP/ERS/etc. tests longer than 2 days to be able to have the split in December instead of January (i.e., before rather than after new year).
\ No newline at end of file
diff --git a/cime_config/testdefs/testmods_dirs/clm/default/shell_commands b/cime_config/testdefs/testmods_dirs/clm/default/shell_commands
index 45eb822729..f1f645afd8 100644
--- a/cime_config/testdefs/testmods_dirs/clm/default/shell_commands
+++ b/cime_config/testdefs/testmods_dirs/clm/default/shell_commands
@@ -1,4 +1,3 @@
#!/bin/bash
./xmlchange CLM_BLDNML_OPTS="-fire_emis" --append
-./xmlchange BFBFLAG="TRUE"
diff --git a/cime_config/testdefs/testmods_dirs/clm/luna/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/luna/user_nl_clm
index cbfbb9f525..fb796ebfaf 100644
--- a/cime_config/testdefs/testmods_dirs/clm/luna/user_nl_clm
+++ b/cime_config/testdefs/testmods_dirs/clm/luna/user_nl_clm
@@ -1,3 +1,3 @@
use_luna = .true.
use_flexibleCN = .false.
-
+ use_matrixcn = .false.
diff --git a/cime_config/testdefs/testmods_dirs/clm/sowingWindows/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/matrixcnOn/include_user_mods
similarity index 100%
rename from cime_config/testdefs/testmods_dirs/clm/sowingWindows/include_user_mods
rename to cime_config/testdefs/testmods_dirs/clm/matrixcnOn/include_user_mods
diff --git a/cime_config/testdefs/testmods_dirs/clm/matrixcnOn/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/matrixcnOn/user_nl_clm
new file mode 100644
index 0000000000..185d6a2410
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/matrixcnOn/user_nl_clm
@@ -0,0 +1,3 @@
+hist_wrt_matrixcn_diag = .true.
+use_matrixcn = .true.
+use_soil_matrixcn = .true.
diff --git a/cime_config/testdefs/testmods_dirs/clm/matrixcnOn_ignore_warnings/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/matrixcnOn_ignore_warnings/include_user_mods
new file mode 100644
index 0000000000..a3c70cba11
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/matrixcnOn_ignore_warnings/include_user_mods
@@ -0,0 +1 @@
+../matrixcnOn
diff --git a/cime_config/testdefs/testmods_dirs/clm/matrixcnOn_ignore_warnings/shell_commands b/cime_config/testdefs/testmods_dirs/clm/matrixcnOn_ignore_warnings/shell_commands
new file mode 100644
index 0000000000..d94ef06a5c
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/matrixcnOn_ignore_warnings/shell_commands
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+./xmlchange CLM_BLDNML_OPTS="-ignore_warnings" --append
+
+# In this testmod directory we are ignoring warnings about running
+# matrixcn in transient simulations AND/OR
+# warnings about running matrixcn with threading NTHRDS_LND > 1.
diff --git a/cime_config/testdefs/testmods_dirs/clm/midDecStart/README b/cime_config/testdefs/testmods_dirs/clm/midDecStart/README
new file mode 100644
index 0000000000..7cdab6abfd
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/midDecStart/README
@@ -0,0 +1 @@
+Use midDecStart instead of decStart if you want ERP/ERS/etc. tests longer than 2 days to be able to have the split in December instead of January (i.e., before rather than after new year).
\ No newline at end of file
diff --git a/cime_config/testdefs/testmods_dirs/clm/midDecStart/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/midDecStart/include_user_mods
new file mode 100644
index 0000000000..fe0e18cf88
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/midDecStart/include_user_mods
@@ -0,0 +1 @@
+../default
diff --git a/cime_config/testdefs/testmods_dirs/clm/midDecStart/shell_commands b/cime_config/testdefs/testmods_dirs/clm/midDecStart/shell_commands
new file mode 100755
index 0000000000..d044ab8c3b
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/midDecStart/shell_commands
@@ -0,0 +1,2 @@
+./xmlchange RUN_STARTDATE=2001-12-15
+./xmlchange CLM_BLDNML_OPTS=-ignore_warnings --append
diff --git a/cime_config/testdefs/testmods_dirs/clm/mimics/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/mimics/user_nl_clm
index 152d91b21e..15b69007d8 100644
--- a/cime_config/testdefs/testmods_dirs/clm/mimics/user_nl_clm
+++ b/cime_config/testdefs/testmods_dirs/clm/mimics/user_nl_clm
@@ -1 +1,3 @@
soil_decomp_method = 'MIMICSWieder2015'
+use_matrixcn = .false.
+use_soil_matrixcn = .false.
diff --git a/cime_config/testdefs/testmods_dirs/clm/mimics_matrixcn/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/mimics_matrixcn/include_user_mods
new file mode 100644
index 0000000000..48284fffc4
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/mimics_matrixcn/include_user_mods
@@ -0,0 +1 @@
+../mimics
diff --git a/cime_config/testdefs/testmods_dirs/clm/mimics_matrixcn/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/mimics_matrixcn/user_nl_clm
new file mode 100644
index 0000000000..083717eb95
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/mimics_matrixcn/user_nl_clm
@@ -0,0 +1 @@
+use_matrixcn = .true.
diff --git a/cime_config/testdefs/testmods_dirs/clm/monthly_matrixcn_fast_spinup/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/monthly_matrixcn_fast_spinup/include_user_mods
new file mode 100644
index 0000000000..399579f425
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/monthly_matrixcn_fast_spinup/include_user_mods
@@ -0,0 +1 @@
+../monthly
diff --git a/cime_config/testdefs/testmods_dirs/clm/monthly_matrixcn_fast_spinup/shell_commands b/cime_config/testdefs/testmods_dirs/clm/monthly_matrixcn_fast_spinup/shell_commands
new file mode 100755
index 0000000000..3a435b6233
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/monthly_matrixcn_fast_spinup/shell_commands
@@ -0,0 +1,4 @@
+./xmlchange CLM_ACCELERATED_SPINUP=sasu
+./xmlchange DATM_YR_START=1901,DATM_YR_END=1902
+./xmlchange MOSART_MODE=NULL
+
diff --git a/cime_config/testdefs/testmods_dirs/clm/monthly_matrixcn_fast_spinup/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/monthly_matrixcn_fast_spinup/user_nl_clm
new file mode 100644
index 0000000000..2e232a3f40
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/monthly_matrixcn_fast_spinup/user_nl_clm
@@ -0,0 +1 @@
+nyr_sasu = 1
diff --git a/cime_config/testdefs/testmods_dirs/clm/oldCropCals/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/oldCropCals/user_nl_clm
new file mode 100644
index 0000000000..5885f6f2a0
--- /dev/null
+++ b/cime_config/testdefs/testmods_dirs/clm/oldCropCals/user_nl_clm
@@ -0,0 +1,3 @@
+cropcals_rx = .false.
+cropcals_rx_adapt = .false.
+stream_gdd20_seasons = .false.
\ No newline at end of file
diff --git a/cime_config/testdefs/testmods_dirs/clm/pts/shell_commands b/cime_config/testdefs/testmods_dirs/clm/pts/shell_commands
index 1613d28b25..ad140e45e1 100644
--- a/cime_config/testdefs/testmods_dirs/clm/pts/shell_commands
+++ b/cime_config/testdefs/testmods_dirs/clm/pts/shell_commands
@@ -22,5 +22,3 @@
./xmlchange NTASKS_ROF=1
./xmlchange NTASKS_WAV=1
./xmlchange NTASKS_ESP=1
-./xmlchange MOSART_MODE=NULL
-./xmlchange RTM_MODE=NULL
diff --git a/cime_config/testdefs/testmods_dirs/clm/rtmColdSSP/user_nl_rtm b/cime_config/testdefs/testmods_dirs/clm/rtmColdSSP/user_nl_rtm
index d1a0254a0b..e78d13a51c 100644
--- a/cime_config/testdefs/testmods_dirs/clm/rtmColdSSP/user_nl_rtm
+++ b/cime_config/testdefs/testmods_dirs/clm/rtmColdSSP/user_nl_rtm
@@ -1,4 +1,4 @@
-finidat_rtm = " "
-rtmhist_mfilt = 1
-rtmhist_ndens = 2
-rtmhist_nhtfrq = 0
+finidat = " "
+mfilt = 1
+ndens = 2
+nhtfrq = 0
diff --git a/cime_config/testdefs/testmods_dirs/clm/sowingWindows/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/sowingWindows/user_nl_clm
deleted file mode 100644
index 03165bb306..0000000000
--- a/cime_config/testdefs/testmods_dirs/clm/sowingWindows/user_nl_clm
+++ /dev/null
@@ -1,5 +0,0 @@
-stream_fldFileName_swindow_start = '$DIN_LOC_ROOT/lnd/clm2/cropdata/calendars/processed/swindow_starts_ggcmi_crop_calendar_phase3_v1.01.2000-2000.20231005_145103.nc'
-stream_fldFileName_swindow_end = '$DIN_LOC_ROOT/lnd/clm2/cropdata/calendars/processed/swindow_ends_ggcmi_crop_calendar_phase3_v1.01.2000-2000.20231005_145103.nc'
-stream_meshfile_cropcal = '$DIN_LOC_ROOT/share/meshes/360x720_120830_ESMFmesh_c20210507_cdf5.nc'
-stream_year_first_cropcal = 2000
-stream_year_last_cropcal = 2000
diff --git a/cime_config/usermods_dirs/fates_sp/user_nl_clm b/cime_config/usermods_dirs/fates_sp/user_nl_clm
index 093ecd7eda..37da8d1c67 100644
--- a/cime_config/usermods_dirs/fates_sp/user_nl_clm
+++ b/cime_config/usermods_dirs/fates_sp/user_nl_clm
@@ -22,7 +22,7 @@ hist_fexcl1 = 'FATES_TRIMMING', 'FATES_COLD_STATUS', 'FATES_GDD', 'FATES_NCHILLD
'FATES_SAPWOODC', 'FATES_FROOTC', 'FATES_REPROC', 'FATES_STRUCTC', 'FATES_NONSTRUCTC',
'FATES_VEGC_ABOVEGROUND', 'FATES_CANOPY_VEGC', 'FATES_USTORY_VEGC', 'FATES_PRIMARY_PATCHFUSION_ERR',
'FATES_DISTURBANCE_RATE_FIRE', 'FATES_DISTURBANCE_RATE_LOGGING', 'FATES_DISTURBANCE_RATE_TREEFALL',
- 'FATES_HARVEST_CARBON_FLUX', 'FATES_GPP_CANOPY', 'FATES_AUTORESP_CANOPY',
+ 'FATES_HARVEST_WOODPROD_C_FLUX', 'FATES_GPP_CANOPY', 'FATES_AUTORESP_CANOPY',
'FATES_GPP_USTORY', 'FATES_AUTORESP_USTORY', 'FATES_CROWNAREA_CL', 'FATES_DEMOTION_CARBONFLUX',
'FATES_PROMOTION_CARBONFLUX', 'FATES_MORTALITY_CFLUX_CANOPY', 'FATES_MORTALITY_CFLUX_USTORY',
'FATES_DDBH_CANOPY_SZ', 'FATES_DDBH_USTORY_SZ', 'FATES_BASALAREA_SZ',
diff --git a/components/cism b/components/cism
index c05dd5c4fc..c84cc9f5b3 160000
--- a/components/cism
+++ b/components/cism
@@ -1 +1 @@
-Subproject commit c05dd5c4fc85327e76523aaea9cfe1e388748928
+Subproject commit c84cc9f5b3103766a35d0a7ddd5e9dbd7deae762
diff --git a/components/cmeps b/components/cmeps
index 6384ff4e4a..47fb4e633a 160000
--- a/components/cmeps
+++ b/components/cmeps
@@ -1 +1 @@
-Subproject commit 6384ff4e4a6bc82a678f9419a43ffbd5d53ac209
+Subproject commit 47fb4e633a76ec6d60969b1af751f90790387246
diff --git a/components/mosart b/components/mosart
index 8c682b1b7f..e2ffe00004 160000
--- a/components/mosart
+++ b/components/mosart
@@ -1 +1 @@
-Subproject commit 8c682b1b7f15d146816de302e0d359da3e957056
+Subproject commit e2ffe00004cc416cfc8bcfae2a949474075c1d1f
diff --git a/components/rtm b/components/rtm
index 88503adbc2..b3dfcfbba5 160000
--- a/components/rtm
+++ b/components/rtm
@@ -1 +1 @@
-Subproject commit 88503adbc275fb2ccbb6b598e460deaeb140e515
+Subproject commit b3dfcfbba58c151ac5a6ab513b3515ef3deff798
diff --git a/doc/ChangeLog b/doc/ChangeLog
index 2ab7676ddc..aeb7b2972f 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,4 +1,971 @@
===============================================================
+Tag name: ctsm5.2.017
+Originator(s): erik (Erik Kluzek,UCAR/TSS,303-497-1326)
+Date: Tue 30 Jul 2024 08:39:20 AM MDT
+One-line Summary: Dust emissions control moved to cmeps
+
+Purpose and description of changes
+----------------------------------
+
+Remove the dust emissions namelist items from CTSM and use the namelist in the drv_flds_in for CMEPS.
+
+This updates CTSM to use the namelist control in CMEPS (in ESCOMP/CMEPS#429). So the CMEPS external needs to be updated, and the
+namelist control in CTSM changed to use CMEPS rather than the internal CTSM control settings and the CTSM ones removed.
+
+The new XML variable:
+
+ LND_SETS_DUST_EMIS_DRV_FLDS
+
+controls whether dust emission settings are set by CTSM or by CAM. Only one or the other can set them, and it's required so when CAM
+and CTSM are running together they need to know which one will select.
+
+This required some changes for LILAC. The drv_flds_in namelist file is now required for LILAC, and read for dust emissions
+(and dust emissions only) at the LILAC lnd_comp_esmf.F90 level.
+
+Add a unit test for the CMEPS code to make sure it's working correctly. This validates the code both for CAM and CTSM.
+
+Fix the cidinahoBR test in the build-namelist unit tester.
+
+
+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.]
+
+[ ] clm6_0
+
+[ ] clm5_1
+
+[ ] clm5_0
+
+[ ] ctsm5_0-nwp
+
+[ ] clm4_5
+
+
+Bugs fixed
+----------
+
+List of CTSM issues fixed (include CTSM Issue # and description) [one per line]:
+
+ Fixes #2376 -- Update CTSM with CMEPS that controls dust emission options
+ Fixes #2150 -- Ability to flip between different dust emission methods
+ Fixes #2524 -- Add option to NOT set dust emission settings when coupled to CAM
+ Fixes #2666 -- cidinahoBR test in build-namelist
+
+Notes of particular relevance for users
+---------------------------------------
+
+Caveats for users (e.g., need to interpolate initial conditions):
+ dust_emis_method can NOT be set to Leung_2023 -- yet.
+ See below about LND_SETS_DUST_EMIS_DRV_FLDS
+
+Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables):
+ CTSM namelist items moved to the dust_emis_inparm namelist in drv_flds_in:
+ zender_soil_erod_source and dust_emis_method
+
+ New logical XML variable:
+ LND_SETS_DUST_EMIS_DRV_FLDS
+ If TRUE CTSM sets the dust emission namelist, otherwise CAM will (when coupled to CAM)
+ If you are NOT coupled to CAM and LND_SETS_DUST_EMIS_DRV_FLDS==FALSE, the model will abort
+ trying to read the dust_emis_inparm namelist in drv_flds_in.
+
+Notes of particular relevance for developers:
+---------------------------------------------
+
+Caveats for developers (e.g., code that is duplicated that requires double maintenance):
+ Added a PF unit test for CMEPS dust emission code. This should be moved to CMEPS, but still run here.
+ Control design in DustEmisFactory, uses a Functional Programming design pattern with pure functions
+ from CMEPS for CTSM to know the drv_flds_in settings. Design notes were added in that regard.
+
+Testing summary: Regular
+----------------
+
+ [PASS means all tests PASS; OK means tests PASS other than expected fails.]
+
+ build-namelist tests (if CLMBuildNamelist.pm has changed):
+
+ derecho - PASS (1006 are different because of the namelist changes)
+
+ python testing (if python code has changed; see instructions in python/README.md; document testing done):
+
+ derecho - PASS
+
+ regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing):
+
+ derecho ----- OK
+ izumi ------- OK
+
+
+Answer changes
+--------------
+
+Changes answers relative to baseline: No bit-for-bit
+
+ The following tests compared different to baseline because of reproducability issues:
+ ERP_P64x2_Lm13.f10_f10_mg37.IHistClm60Bgc.derecho_intel.clm-monthly--clm-matrixcnOn_ignore_warnings
+ SMS_D.1x1_brazil.I2000Clm60FatesSpCruRsGs.derecho_gnu.clm-FatesColdDryDepSatPhen
+ SMS_D.1x1_brazil.I2000Clm60FatesSpCruRsGs.derecho_gnu.clm-FatesColdMeganSatPhen
+ The CN-MATRIX issue is because of #2619 and FATES because of #2656
+
+Other details
+-------------
+
+Pull Requests that document the changes (include PR ids):
+(https://github.com/ESCOMP/ctsm/pull)
+ #2545 -- Dust emission control moved to CMEPS
+
+===============================================================
+===============================================================
+Tag name: ctsm5.2.016
+Originator(s): samrabin (Sam Rabin, UCAR/TSS, samrabin@ucar.edu)
+Date: Sat 27 Jul 2024 05:13:08 PM MDT
+One-line Summary: Enable new crop calendars for clm60 compsets
+
+Purpose and description of changes
+----------------------------------
+
+This commit switches clm60 compsets (really, any compset other than clm45, clm50, and clm51) to use:
+- Per-gridcell and -crop sowing windows derived from the GGCMI phase 3b group II static growing seasons
+- Per-gridcell and -crop maturity requirements derived from those same growing seasons, over the 1980-2009 growing seasons
+- Code to adjust those prescribed maturity requirements based on recent climate
+
+
+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.)
+
+[X] clm6_0
+
+[ ] clm5_1
+
+[ ] clm5_0
+
+[?] ctsm5_0-nwp: Probably? Haven't tested, but didn't exclude that setup.
+
+[ ] clm4_5
+
+
+Bugs fixed
+----------
+
+List of CTSM issues fixed (include CTSM Issue # and description):
+- Fixes ESCOMP/CTSM#2584: Reset accumulators to initval instead of 0 (https://github.com/ESCOMP/CTSM/issues/2584)
+- Fixes ESCOMP/CTSM#2667: Change out a f19 resolution test on Izumi for f10 (https://github.com/ESCOMP/CTSM/issues/2667)
+
+Notes of particular relevance for users
+---------------------------------------
+
+Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables):
+- Add cropcals_rx, default false.
+- Add cropcals_rx_adapt, default true. This is what changes default behavior.
+- Rename stream_year_first_cropcal to stream_year_first_cropcal_swindows
+- Rename stream_year_last_cropcal to stream_year_last_cropcal_swindows
+- Rename model_year_align_cropcal to model_year_align_cropcal_swindows
+- Add stream_year_first_cropcal_cultivar_gdds
+- Add stream_year_last_cropcal_cultivar_gdds
+- Add model_year_align_cropcal_cultivar_gdds
+- Add stream_fldFileName_gdd20_baseline
+- Add stream_gdd20_seasons (experimental)
+- Add flush_gdd20 (experimental)
+- Add stream_fldFileName_gdd20_season_start (experimental)
+- Add stream_fldFileName_gdd20_season_end (experimental)
+- Add allow_invalid_gdd20_season_inputs
+
+Changes to the datasets (e.g., parameter, surface or initial files):
+- Many new default and optional stream files added.
+
+Changes to documentation:
+- None yet.
+
+Notes of particular relevance for developers:
+---------------------------------------------
+
+Caveats for developers:
+- tools/contrib/tweak_latlons.py: This is a script I made to avoid the "ambiguous nearest neighbor" issue described in the discussion at https://github.com/orgs/esmf-org/discussions/261. It's hopefully just a temporary thing as we wait for ESMF to fix that bug. If they end up deciding not to, then this should be moved into python/ctsm/ and fully tested.
+- Unit and system testing needs to be added for generate_gdd20_baseline.py.
+- RXCROPMATURITY SystemTest should be updated to also call generate_gdd20_baseline.py.
+
+Changes to tests or testing:
+- Adds testmods:
+ - midDecStart: Like decStart, except starts Dec. 15 instead of 30. Useful for ERP/ERS tests where you want the split in December.
+ - GddGen
+ - oldCropCals: To recreate previous crop calendars
+ - RxCropCalsAdaptGGCMI (experimental)
+ - RxCropCalsNoAdapt
+ - StreamGDD20Seasons (experimental)
+- Removes sowingWindows testmod
+- Adds and changes various tests related to crop calendars
+- Changes one Izumi test from f19 to 10x15 resolution:
+ - Was: ERS_D.f19_g17.I1850Clm50BgcCrop.izumi_nag.clm-ciso_monthly_matrixcn_spinup
+ - Now: ERS_D.f10_f10_mg37.I1850Clm50BgcCrop.izumi_nag.clm-ciso_monthly_matrixcn_spinup
+
+Note that testmods marked "experimental" are fine to be marked as expected failures, if needed.
+
+
+Testing summary:
+----------------
+
+ [PASS means all tests PASS; OK means tests PASS other than expected fails.]
+
+ build-namelist tests (if CLMBuildNamelist.pm has changed):
+
+ derecho - FAIL
+ 1x1_cidadinhoBR tests only. That's fine. Filed Issue #2666: 1x1_cidadinhoBR tests fail in build-namelist_test.pl (https://github.com/ESCOMP/CTSM/issues/2666).
+
+ python testing (if python code has changed; see instructions in python/README.md; document testing done):
+
+ derecho - PASS
+
+ regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing):
+
+ derecho ----- OK
+ izumi ------- OK
+
+Answer changes
+--------------
+
+Changes answers relative to baseline:
+
+ Summarize any changes to answers, i.e.,
+ - what code configurations: crop-enabled compsets with clm60 (or more specifically, other than clm45, clm50, clm51)
+ - what platforms/compilers: all
+ - nature of change (roundoff; larger than roundoff/same climate; new climate): new climate
+
+ Probably? At least, there can be large regional shifts in crop growing season. Results are similar to those for the Prescribed Calendars setup in Rabin et al. (2023; https://gmd.copernicus.org/articles/16/7253/2023/gmd-16-7253-2023.html).
+
+ If this tag changes climate describe the run(s) done to evaluate the new
+ climate (put details of the simulations in the experiment database)
+ - None
+
+
+Other details
+-------------
+
+Pull Requests that document the changes (include PR ids):
+- ESCOMP/CTSM#2560: Allow prescribed gddmaturity to vary based on recent climate (initial work, v2) (https://github.com/ESCOMP/CTSM/pull/2560)
+- ESCOMP/CTSM#2585: Allow "manual" resets of all accumulator types (https://github.com/ESCOMP/CTSM/pull/2585)
+- ESCOMP/CTSM#2593: Optionally base GDD20 on per-gridcell windows, not per-hemisphere (https://github.com/ESCOMP/CTSM/pull/2593)
+- ESCOMP/CTSM#2661: Merge ctsm5.2.015 into scale-maturity-reqs (https://github.com/ESCOMP/CTSM/pull/2661)
+- ESCOMP/CTSM#2664: Enable new crop calendars for clm60 compsets (https://github.com/ESCOMP/CTSM/pull/2664)
+- ESCOMP/CTSM#2665: Merge new crop calendars into master (https://github.com/ESCOMP/CTSM/pull/2665)
+
+===============================================================
+===============================================================
+Tag name: ctsm5.2.015
+Originator(s): multiple (Samuel Levis,UCAR/TSS,303-665-1310, @mvertens, @jedwards4b, @billsacks, @Katetc)
+Date: Mon 22 Jul 2024 12:46:17 PM MDT
+One-line Summary: Update submodule tags to pass runoff from cism to rof
+
+Purpose and description of changes
+----------------------------------
+
+ - Update MOSART, CMEPS, and CISM so CISM runoff goes to ROF rather than CTSM
+ - Update RTM with fix needed for Paleo LGM work
+
+
+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.]
+
+[ ] clm6_0
+
+[ ] clm5_1
+
+[ ] clm5_0
+
+[ ] ctsm5_0-nwp
+
+[ ] clm4_5
+
+
+Bugs fixed
+----------
+List of CTSM issues fixed (include CTSM Issue # and description) [one per line]:
+ Fixes #2590 Update CMEPS/MOSART/CISM/RTM tags
+ Fixes https://github.com/ESCOMP/RTM/issues/50 Likely wrong RTM river flux to MOM6 within cesm2_3_beta17
+
+Notes of particular relevance for users
+---------------------------------------
+
+Caveats for users (e.g., need to interpolate initial conditions):
+ Issue https://github.com/ESCOMP/RTM/issues/50
+ Likely wrong RTM river flux to MOM6 within cesm2_3_beta17 is now fixed with
+ https://github.com/ESCOMP/RTM/pull/51
+
+Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables):
+ Differences in namelist 'mosart_inparm':
+ missing variable: 'do_rtmflood'
+ missing variable: 'finidat_rtm'
+ missing variable: 'frivinp_rtm'
+ missing variable: 'rtmhist_fexcl1'
+ missing variable: 'rtmhist_fexcl2'
+ missing variable: 'rtmhist_fexcl3'
+ missing variable: 'rtmhist_fincl1'
+ missing variable: 'rtmhist_fincl2'
+ missing variable: 'rtmhist_fincl3'
+ missing variable: 'rtmhist_mfilt'
+ missing variable: 'rtmhist_ndens'
+ missing variable: 'rtmhist_nhtfrq'
+ found extra variable: 'budget_frq'
+ found extra variable: 'fexcl1'
+ found extra variable: 'fexcl2'
+ found extra variable: 'fexcl3'
+ found extra variable: 'fincl1'
+ found extra variable: 'fincl2'
+ found extra variable: 'fincl3'
+ found extra variable: 'finidat'
+ found extra variable: 'frivinp'
+ found extra variable: 'mfilt'
+ found extra variable: 'mosart_euler_calc'
+ found extra variable: 'mosart_tracers'
+ found extra variable: 'ndens'
+ found extra variable: 'nhtfrq'
+ found extra variable: 'use_halo_option'
+
+Changes to documentation:
+ Not that I am aware of
+
+
+Testing summary:
+----------------
+
+ [PASS means all tests PASS; OK means tests PASS other than expected fails.]
+
+ build-namelist tests (if CLMBuildNamelist.pm has changed):
+
+ derecho - PASS
+
+ python testing (if python code has changed; see instructions in python/README.md; document testing done):
+
+ derecho - PASS
+
+ regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing):
+
+ derecho ----- OK
+ izumi ------- OK
+
+ ctsm_sci
+ derecho ---- OK (while in tag ctsm5.2.007; I did not repeat with the latest; see checklist in #2590)
+
+
+Answer changes
+--------------
+
+Changes answers relative to baseline: Yes
+
+ Summarize any changes to answers, i.e.,
+ - what code configurations: mosart and rtm
+ - what platforms/compilers: all
+ - nature of change: mosart roundoff; rtm larger than roundoff due to bug fix
+
+ We are ignoring strange diffs from baseline in two tests in variable
+ FATES_TRANSITION_MATRIX_LULU as explained in issue #2656.
+
+Other details
+-------------
+List any git submodules updated (cime, rtm, mosart, cism, fates, etc.):
+ See .gitmodules: cism, rtm, mosart, ccs_config, cmeps
+
+Pull Requests that document the changes (include PR ids):
+ https://github.com/ESCOMP/ctsm/pull/2605
+ https://github.com/ESCOMP/RTM/pull/51
+ https://github.com/ESCOMP/MOSART/pull/94
+ https://github.com/ESCOMP/CISM-wrapper/pull/100
+ https://github.com/ESCOMP/CMEPS/pull/463
+ https://github.com/ESMCI/ccs_config_cesm/pull/174
+
+===============================================================
+===============================================================
+Tag name: ctsm5.2.014
+Originator(s): chrislxj (Xingjie Lu, Northern Arizona U., xingjie.lu@nau.edu)
+Date: Fri 19 Jul 2024 11:04:17 AM MDT
+One-line Summary: use_matrixcn, use_soil_matrixcn come in as default .false.
+
+Purpose and description of changes
+----------------------------------
+
+ Currently set as default .false.:
+ - Add matrix module for vegetation and soil C and N cycle
+ - Add diagnostic variables C and N storage capacity in history files
+ - Add Sparse matrix module to increase the code efficiency
+ - Create spin-up switch, and be ready for matrix spin up development
+
+ Additional contributors: Yuanyuan Huang, Zhenggang Du, and Yiqi Luo from
+ Professor Yiqi Luo's EcoLab at Northern Arizona University, now at Cornell U.
+
+ In TSS/CGD/NCAR/UCAR, contributors in the last year include slevis, ekluzek, wwieder.
+ I apologize if I have omitted others who may have been involved prior.
+
+
+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.]
+
+[ ] clm6_0
+
+[ ] clm5_1
+
+[ ] clm5_0
+
+[ ] ctsm5_0-nwp
+
+[ ] clm4_5
+
+
+Bugs fixed
+----------
+List of CTSM issues fixed (include CTSM Issue # and description) [one per line]:
+ Fixes #903 Bring CN-Matrix solution into CTSM
+ Fixes #2450 Cn-matrix testing in the aux_clm test-suites
+ Fixes #2621 matrixcn does not work with nrepr != 1 (number of crop reproductive pools)
+
+
+Notes of particular relevance for users
+---------------------------------------
+
+Caveats for users (e.g., need to interpolate initial conditions):
+ use_matrixcn and use_soil_matrixcn ARE NOT available for clm4_5
+ and ARE recommended for accelerating bgc
+ spin-ups (keep reading for more info) and NOT recommended for
+ - transient simulations (e.g. IHist)
+ - simulations that use threading (e.g. see tests with P64x2)
+ - NWP compsets
+
+Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables):
+ New: use_matrixcn, use_soil_matrixcn, hist_wrt_matrixcn_diag.
+ All three are default .false. at this time.
+
+Changes made to namelist defaults (e.g., changed parameter values):
+ - hillslope_fsat_equals_zero is now default .false. when
+ use_hillslope = .false. as per issue #2652
+ - clm_accelerated_spinup can be set to on, sasu, off; matrixcn spin-up
+ is performed in that order (on, sasu, off); in the "on" phase, matrixcn
+ is not active, in the "sasu" phase matrixcn is active, and in the "off"
+ phase, matrixcn may be active
+
+Changes to documentation:
+ None at this time. A description of the spinup procedure appears in
+ https://github.com/NCAR/LMWG_dev/issues/58
+
+
+Notes of particular relevance for developers:
+---------------------------------------------
+
+Caveats for developers (e.g., code that is duplicated that requires double maintenance):
+ - Future changes to the bgc will likely require changes in both
+ matrix and non-matrix parts of the code.
+ - matrixcn seems sensitive to changes in subgrid heterogeneity and
+ other subtleties. For example, matrixcn simulations have failed from
+ using a finidat file from a different simulation (#2592),
+ from running in transient mode (#2592), from running with threading (#2619),
+ and from setting hillslope_fsat_equals_zero = .true. (issue #2652).
+ - We recommend using matrixcn to accelerate bgc spin-ups and not for
+ most (any?) other purposes.
+
+Changes to tests or testing:
+ We introduced numerous new tests to the aux_clm and build-namelist_test.pl
+ test-suites that can be identified by searching "matrix"
+
+
+Testing summary:
+----------------
+
+ [PASS means all tests PASS; OK means tests PASS other than expected fails.]
+
+ build-namelist tests (if CLMBuildNamelist.pm has changed):
+
+ derecho - PASS
+
+ python testing (if python code has changed; see instructions in python/README.md; document testing done):
+
+ derecho - PASS
+
+ regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing):
+
+ derecho ----- OK
+ izumi ------- OK
+
+ ctsm_sci
+ derecho ---- OK
+
+
+Answer changes
+--------------
+
+Changes answers relative to baseline: Yes, roundoff
+
+ Summarize any changes to answers, i.e.,
+ - what code configurations: Non-matrix
+ - what platforms/compilers: All
+ - nature of change: roundoff
+ use_matrixcn and use_soil_matrixcn are default .false.. We get
+ roundoff diffs due to order-of-operation changes in a few sections
+ of code, which improve readability and streamlining of the code
+ in the presence of matrix.
+
+ Testing with the non-default use_matrixcn and use_soil_matrixcn = .true.
+ appears here: https://github.com/NCAR/LMWG_dev/issues/58
+
+ PR #640 explains how answers are expected to
+ change from non-matrix to matrix simulations.
+
+Other details
+-------------
+Pull Requests that document the changes (include PR ids):
+ https://github.com/ESCOMP/ctsm/pull/640
+
+===============================================================
+===============================================================
+Tag name: ctsm5.2.013
+Originator(s): samrabin (Sam Rabin, UCAR/TSS, samrabin@ucar.edu)
+ glemieux (Gregory Lemieux, LBNL, glemieux@lbl.gov)
+Date: Thu Jul 18 10:51:11 MDT 2024
+One-line Summary: FATES Land Use V2
+
+Purpose and description of changes
+----------------------------------
+This tag enables FATES to utilize its land use mode with fixed
+biogeography and no competition mode engaged. To facilitate
+this update, the host land model reads in a new static map data
+set that associates land use with FATES plant functional types.
+This tag also updates the pre-existing FATES dynamic land use
+module to provide access to the raw LUH2 harvest data from the
+FATES LUH2 timeseries data set (added in ctsm5.1.dev160).
+
+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.]
+
+[ ] clm6_0
+
+[ ] clm5_1
+
+[ ] clm5_0
+
+[ ] ctsm5_0-nwp
+
+[ ] clm4_5
+
+
+Notes of particular relevance for users
+---------------------------------------
+
+Caveats for users (e.g., need to interpolate initial conditions):
+ FATES satellite phenology mode and land use mode are currently incompatible
+ and trying to engage both will result in a graceful build failure message
+
+Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables):
+ New FATES namelist option: fates_harvest_mode
+ - This new option provides five harvest modes
+ - The 'event_code' mode takes over the now defunct use_fates_logging option
+ - The 'landuse_timeseries' option supersedes the use of do_harvest option
+ with FATES. Using do_harvest is no longer compatible with FATES.
+
+ New FATES namelist option: use_fates_lupft
+ - This option enables the necessary namelist options and data sets to run
+ FATES with land use, no competition, and fixed biogeography modes.
+
+ New FATES namelist option: flandusepftdat
+ - This data set is necessary for running with use_fates_lupft.
+
+ New FATES namelist option: use_potential_veg
+ - This option is only necessary for use with FATES spin-up to transient
+ workflows that will engage the use_fates_lupft mode for the transient case
+
+Changes made to namelist defaults (e.g., changed parameter values):
+ The default FATES parameter file has been updated to account for the new
+ parameters necessary for land use v2.
+
+ A new default data set has been provided for flandusepftdat. Only a 4x5 grid
+ resolution is currently provided.
+
+Changes to the datasets (e.g., parameter, surface or initial files):
+ The FATES land use timeseries data set, fluh_timeseries, has been updated to
+ provide a wider timeseries range, from 0850-2015.
+
+
+Notes of particular relevance for developers:
+---------------------------------------------
+Changes to tests or testing:
+
+ New FATES testmods have been added to account for the additional harvest mode
+ and use_fates_lupft namelist options. Additoinally a new system text prefix,
+ PVT, has been added to test the use_fates_potentialveg spin-up to use_fates_lupft
+ transient workflow. These have been added to the fates test suite.
+
+Bugs fixed
+----------
+List of CTSM issues fixed (include CTSM Issue # and description) [one per line]:
+Fixes #2444 Failing water isotope test on the ctsm5.2 branch
+
+Notes of particular relevance for users
+---------------------------------------
+Changes to documentation: None
+
+Testing summary:
+----------------
+
+ build-namelist tests (if CLMBuildNamelist.pm has changed):
+
+ derecho - PASS
+
+ regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing):
+
+ derecho ----- TBD
+ izumi ------- TBD
+
+ fates tests: (give name of baseline if different from CTSM tagname, normally fates baselines are fates--)
+ derecho ----- OK
+
+If the tag used for baseline comparisons was NOT the previous tag, note that here:
+ fates tested against fates-sci.1.76.4_api.35.1.0-ctsm5.2.008
+
+
+Answer changes
+--------------
+Changes answers relative to baseline: Only for FATES test mods, otherwise B4B
+
+Other details
+-------------
+List any git submodules updated (cime, rtm, mosart, cism, fates, etc.):
+ FATES: sci.1.73.0_api.35.0.0 -> sci.1.77.0_api.36.0.0
+
+Pull Requests that document the changes (include PR ids):
+(https://github.com/ESCOMP/ctsm/pull)
+ #2507 -- FATES land use v2 API update (CTSM-side)
+ NGEET#1116 -- V2 Land Use Change
+
+===============================================================
+===============================================================
+Tag name: ctsm5.2.012
+Originator(s): sacks (Bill Sacks, UCAR/NCAR/CGD)
+Date: Tue 16 Jul 2024 08:57:42 AM MDT
+One-line Summary: Relax tolerance for truncating small snocan values in CanopyFluxes
+
+Purpose and description of changes
+----------------------------------
+
+Details in the PR #2457.
+
+
+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.]
+
+[ ] clm6_0
+
+[ ] clm5_1
+
+[ ] clm5_0
+
+[ ] ctsm5_0-nwp
+
+[ ] clm4_5
+
+
+Bugs fixed
+----------
+List of CTSM issues fixed (include CTSM Issue # and description) [one per line]:
+Fixes #2444 Failing water isotope test on the ctsm5.2 branch
+
+Notes of particular relevance for users
+---------------------------------------
+Changes to documentation: None
+
+Testing summary:
+----------------
+
+ [PASS means all tests PASS; OK means tests PASS other than expected fails.]
+
+ regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing):
+
+ derecho ----- OK
+ izumi ------- OK
+
+Answer changes
+--------------
+
+Changes answers relative to baseline:
+ Yes, roundoff.
+
+ - what code configurations: All
+ - what platforms/compilers: All
+ - nature of change: Changes start roundoff level and grow over time.
+
+Other details
+-------------
+Pull Requests that document the changes (include PR ids):
+ https://github.com/ESCOMP/ctsm/pull/2457
+
+===============================================================
+===============================================================
+Tag name: ctsm5.2.011
+Originator(s): slevis (Samuel Levis,UCAR/TSS,303-665-1310)
+Date: Fri 12 Jul 2024 09:45:59 AM MDT
+One-line Summary: Merge b4b-dev
+
+Purpose and description of changes
+----------------------------------
+
+#2638 Remove use_dynroot and corresponding code and testing (slevis)
+#2623 Change a NIWO test to HARV and update expected failures (slevis)
+#2607 Fix py env create (wwieder)
+
+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.]
+
+[ ] clm6_0
+
+[ ] clm5_1
+
+[ ] clm5_0
+
+[ ] ctsm5_0-nwp
+
+[ ] clm4_5
+
+
+Bugs fixed
+----------
+List of CTSM issues fixed (include CTSM Issue # and description) [one per line]:
+Fixes #2451 Remove use_dynroot from clm codes and testing
+Fixes #2563 Unable to install ctsm_pylib environment for mksurfdata_esmf in CTSM5.2.005
+
+Notes of particular relevance for developers:
+---------------------------------------------
+Changes to tests or testing:
+Change a NIWO test to HARV and update expected failures
+
+Testing summary:
+----------------
+
+ [PASS means all tests PASS; OK means tests PASS other than expected fails.]
+
+ build-namelist tests (if CLMBuildNamelist.pm has changed):
+
+ derecho - OK
+
+ python testing (if python code has changed; see instructions in python/README.md; document testing done):
+
+ derecho - OK
+
+ regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing):
+
+ derecho ----- OK
+ izumi ------- OK
+
+Answer changes
+--------------
+
+Changes answers relative to baseline: NO
+
+Other details
+-------------
+[Remove any lines that don't apply. Remove entire section if nothing applies.]
+
+List any git submodules updated (cime, rtm, mosart, cism, fates, etc.):
+
+Pull Requests that document the changes (include PR ids):
+ https://github.com/ESCOMP/ctsm/pull/2638
+ https://github.com/ESCOMP/ctsm/pull/2623
+ https://github.com/ESCOMP/ctsm/pull/2607
+
+===============================================================
+===============================================================
+Tag name: ctsm5.2.010
+Originator(s): @cathyxinchangli (Cathy Xinchang Li, U of Illinois - Urbana-Champaign), @Face2sea, @olyson, @fang-bowen, @keerzhang1
+Date: Thu 11 Jul 2024 11:57:15 AM MDT
+One-line Summary: Explicit A/C adoption
+
+Purpose and description of changes
+----------------------------------
+
+ Code changes for adding an explicit air-conditioning (AC) adoption parameterization scheme in CLMU. This includes adding a new time-varying input variable (AC adoption rate, p_ac), changes to building energy calculations, and a toggle (new namelist variable urban_explicit_ac)
+
+ In this tag we keep the change off by default in order to show that answers do not change:
+ - If explicit AC adoption is off, the p_ac_[TBD/HD/MD] variables are set to 1 universally, and the building interior setpoints (tbuildmax_[TBD/HD/MD]) remain unchanged, to ensure the model reproduces previous results.
+ - If explicit AC adoption is on, the p_ac_[TBD/HD/MD] variables take on actual AC adoption rate values (present-day global data were developed together with the code change), and tbuildmax_[TBD/HD/MD] are set to 300K/27°C universally.
+
+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.]
+
+[ ] clm6_0
+
+[ ] clm5_1
+
+[ ] clm5_0
+
+[ ] ctsm5_0-nwp
+
+[ ] clm4_5
+
+
+Bugs fixed
+----------
+List of CTSM issues fixed (include CTSM Issue # and description) [one per line]:
+ Fixes #2254 Explicitly representing air-conditioning adoption in CESM
+
+Notes of particular relevance for users
+---------------------------------------
+
+Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables):
+ New namelist variable urban_explicit_ac = .false. by default
+
+Changes to the datasets (e.g., parameter, surface or initial files):
+ The default urban time-varying input data file (namelist variable stream_fldfilename_urbantv) now includes p_ac_[TBD/HD/MD] variables, whether or not the explicit-AC-adoption scheme is on and the new file has been rimported to svn: CTSM52_urbantv_Li_2024_0.9x1.25_simyr1849-2106_c20230621.nc
+
+Changes to documentation:
+
+
+Testing summary:
+----------------
+
+ [PASS means all tests PASS; OK means tests PASS other than expected fails.]
+
+ regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing):
+
+ derecho ----- OK
+ izumi ------- OK
+
+Answer changes
+--------------
+
+Changes answers relative to baseline:
+ No, because we have introduced the changes as default .false. at this time
+
+Other details
+-------------
+Pull Requests that document the changes (include PR ids):
+ https://github.com/ESCOMP/ctsm/pull/2275
+
+===============================================================
+===============================================================
+Tag name: ctsm5.2.009
+Originator(s): erik (Erik Kluzek,UCAR/TSS,303-497-1326)
+Date: Wed 10 Jul 2024 12:21:23 PM MDT
+One-line Summary: Allow for CAM7 in lnd_tuning_mode and handle C or E in long compset names
+
+Purpose and description of changes
+----------------------------------
+
+Changes so that CAM7 is allowed for the land-tuning mode. Allow "C" and "E" after period designation in long compset names. Fix an
+issue with Zender dust emission soil eroditability files.
+
+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.]
+
+[ ] clm6_0
+
+[ ] clm5_1
+
+[ ] clm5_0
+
+[ ] ctsm5_0-nwp
+
+[ ] clm4_5
+
+
+Bugs fixed
+----------
+
+List of CTSM issues fixed (include CTSM Issue # and description) [one per line]:
+ Fixes #2480 -- cam7 lnd_tuning_mode
+ Fixes #2634 -- allow period part of long-compset name to have a "C" or "E"
+ Fixes #2637 -- bad lnd_tuning_mode for Zender soil eroditability file settings
+
+Notes of particular relevance for users
+---------------------------------------
+
+Caveats for users (e.g., need to interpolate initial conditions):
+ LND_TUNING_MODE will fail with an error for CAM (that's NOT cam4/cam5/cam6), or CPLHIST with CLM51
+ use CLM60 instead
+
+Changes made to namelist defaults (e.g., changed parameter values):
+ Add lnd_tuning_mode options for cam7.0 to namelist defaults
+
+Notes of particular relevance for developers:
+---------------------------------------------
+
+Caveats for developers (e.g., code that is duplicated that requires double maintenance):
+ lnd_tuning_mode options duplicate a bunch of XML code lines and should be refactored
+
+Changes to tests or testing:
+ Add cam7.0 test mod directories
+ Change tests for clm6_0_cam6.0 lnd_tuning_mode to clm6_0_cam7.0
+
+Testing summary: regular
+----------------
+ [PASS means all tests PASS; OK means tests PASS other than expected fails.]
+
+ build-namelist tests (if CLMBuildNamelist.pm has changed):
+
+ derecho - PASS
+
+ python testing (if python code has changed; see instructions in python/README.md; document testing done):
+
+ derecho - PASS
+
+ regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing):
+
+ derecho ----- OK
+ izumi ------- OK
+
+Answer changes
+--------------
+
+Changes answers relative to baseline: Only the cam4/cam5 lnd_tuning_mode tests
+
+ Summarize any changes to answers, i.e.,
+ - what code configurations: lnd_tuning_mode ending with _cam4.0 or _cam5.0 suffix with zender_soil_erod_source='lnd'
+ - what platforms/compilers: All
+ - nature of change: new dust emissions
+
+Other details
+-------------
+
+Pull Requests that document the changes (include PR ids):
+(https://github.com/ESCOMP/ctsm/pull)
+ #2632 -- Handle CAM7
+
+===============================================================
+===============================================================
Tag name: ctsm5.2.008
Originator(s): erik (Erik Kluzek,UCAR/TSS,303-497-1326)
Date: Fri 28 Jun 2024 12:22:46 PM MDT
diff --git a/doc/ChangeSum b/doc/ChangeSum
index ea9417fe41..15a67bcf04 100644
--- a/doc/ChangeSum
+++ b/doc/ChangeSum
@@ -1,9 +1,18 @@
Tag Who Date Summary
============================================================================================================================
+ ctsm5.2.017 erik 07/30/2024 Dust emissions control moved to cmeps
+ ctsm5.2.016 samrabin 07/27/2024 Enable new crop calendars for clm60 compsets
+ ctsm5.2.015 multiple 07/22/2024 Update submodule tags to pass runoff from cism to rof
+ ctsm5.2.014 multiple 07/19/2024 use_matrixcn, use_soil_matrixcn come in as default .false.
+ ctsm5.2.013 glemieux 07/18/2024 FATES Land Use V2
+ ctsm5.2.012 sacks 07/16/2024 Relax tolerance for truncating small snocan values in CanopyFluxes
+ ctsm5.2.011 slevis 07/12/2024 Merge b4b-dev
+ ctsm5.2.010 multiple 07/11/2024 Explicit A/C adoption
+ ctsm5.2.009 erik 07/10/2024 Allow for CAM7 in lnd_tuning_mode and handle C or E in long compset names
ctsm5.2.008 erik 06/28/2024 Bring changes on temp-branch to master: b4b-dev, git-fleximod, hillslope fsat
tmp-240620.n03.ctsm5.2.007 06/27/2024 Set upland hillslope column fsat values to zero (samrabin)
tmp-240620.n02.ctsm5.2.007 06/21/2024 Another update of git-fleximod (erik)
-tmp-240620.n01.ctsm5.2.007 06/21/2024 Merge b4b-dev (full tag name is tmp-240620.n01.ctsm5.2.007) (slevis)
+tmp-240620.n01.ctsm5.2.007 06/21/2024 Merge b4b-dev (slevis)
ctsm5.2.007 multiple 05/31/2024 Rm manage_externals and update documentation accordingly
ctsm5.2.006 slevis 05/28/2024 Update externals to cesm2_3_beta17, remove mct, retire /test/tools
ctsm5.2.005 erik 05/13/2024 Fix clm6_0 defaults and CESM testing issues, add tests to detect these problems
diff --git a/doc/source/users_guide/running-special-cases/Running-with-custom-crop-calendars.rst b/doc/source/users_guide/running-special-cases/Running-with-custom-crop-calendars.rst
index b19ebcdb09..878cc0d353 100644
--- a/doc/source/users_guide/running-special-cases/Running-with-custom-crop-calendars.rst
+++ b/doc/source/users_guide/running-special-cases/Running-with-custom-crop-calendars.rst
@@ -28,8 +28,8 @@ However, geographically- and temporally-varying maps can also be used to prescri
stream_meshfile_cropcal = '/glade/p/cesmdata/cseg/inputdata/share/meshes/360x720_120830_ESMFmesh_c20210507_cdf5.nc'
! First and last years on the sowing window datasets
- stream_year_first_cropcal = 2000
- stream_year_last_cropcal = 2000
+ stream_year_first_cropcal_swindows = 2000
+ stream_year_last_cropcal_swindows = 2000
Sowing date
-----------
@@ -39,7 +39,7 @@ Specific sowing *dates* can be prescribed for any crop in any gridcell by settin
Maturity requirements
---------------------
-The heat unit accumulation required for a crop to reach maturity (and thus be harvested) is typically determined by a formula with crop-specific parameters that are specified on the parameter file. However, geographically- and temporally-varying maps of maturity requirement (in units of degree-days) can also be specified using the ``user_nl_clm`` input variable ``stream_fldFileName_cultivar_gdds``. (Note that ``stream_meshfile_cropcal``, ``stream_year_first_cropcal``, and ``stream_year_last_cropcal``---see above---are all also required.)
+The heat unit accumulation required for a crop to reach maturity (and thus be harvested) is typically determined by a formula with crop-specific parameters that are specified on the parameter file. However, geographically- and temporally-varying maps of maturity requirement (in units of degree-days) can also be specified using the ``user_nl_clm`` input variable ``stream_fldFileName_cultivar_gdds``. (Note that ``stream_meshfile_cropcal``, ``stream_year_first_cropcal_cultivar_gdds``, and ``stream_year_last_cropcal_cultivar_gdds``---see above---are all also required.)
Generating maturity requirements
--------------------------------
@@ -52,8 +52,8 @@ In a GDD-generating run, crops are planted on the specified sowing dates and are
stream_fldFileName_swindow_start = '/path/to/sowing_date_file.nc'
stream_fldFileName_swindow_end = '/path/to/sowing_date_file.nc'
stream_meshfile_cropcal = '/path/to/mesh_file.nc'
- stream_year_first_cropcal = YEAR
- stream_year_last_cropcal = YEAR
+ stream_year_first_cropcal_swindows = YEAR
+ stream_year_last_cropcal_swindows = YEAR
! Special settings for "GDD-generating" run
generate_crop_gdds = .true.
diff --git a/lilac/bld_templates/mosart_in b/lilac/bld_templates/mosart_in
index 091ec69285..0bc2242dda 100644
--- a/lilac/bld_templates/mosart_in
+++ b/lilac/bld_templates/mosart_in
@@ -4,18 +4,18 @@
delt_mosart = 1800
do_rtm = .true.
do_rtmflood = .false.
- finidat_rtm = " "
- frivinp_rtm = "/glade/campaign/cesm/cesmdata/cseg/inputdata/rof/mosart/MOSART_routing_Global_0.5x0.5_c170601.nc"
+ finidat = " "
+ frivinp = "/glade/campaign/cesm/cesmdata/cseg/inputdata/rof/mosart/MOSART_routing_Global_0.5x0.5_c170601.nc"
ice_runoff = .true.
qgwl_runoff_option = "threshold"
- rtmhist_fexcl1 = ""
- rtmhist_fexcl2 = ""
- rtmhist_fexcl3 = ""
- rtmhist_fincl1 = ""
- rtmhist_fincl2 = ""
- rtmhist_fincl3 = ""
- rtmhist_mfilt = 1
- rtmhist_ndens = 1
- rtmhist_nhtfrq = 0
+ fexcl1 = ""
+ fexcl2 = ""
+ fexcl3 = ""
+ fincl1 = ""
+ fincl2 = ""
+ fincl3 = ""
+ mfilt = 1
+ ndens = 1
+ nhtfrq = 0
smat_option = "Xonly"
/
diff --git a/py_env_create b/py_env_create
index 9a9b8d940c..ac705edb3c 100755
--- a/py_env_create
+++ b/py_env_create
@@ -122,7 +122,7 @@ if [ "$verbose" == "Yes" ]; then
verbosity="--verbose"
loglevel="INFO"
fi
-cmd="conda install --yes $verbosity --channel conda-forge --name $ctsm_python $condadir/$condafile $option"
+cmd="conda install --yes $verbosity --channel conda-forge --name $ctsm_python --file $condadir/$condafile $option"
echo "$cmd"
$cmd
if [ $? != 0 ]; then
diff --git a/python/ctsm/crop_calendars/check_rxboth_run.py b/python/ctsm/crop_calendars/check_rxboth_run.py
index a1014b5e66..fa4affd220 100644
--- a/python/ctsm/crop_calendars/check_rxboth_run.py
+++ b/python/ctsm/crop_calendars/check_rxboth_run.py
@@ -156,7 +156,16 @@ def main(argv):
any_bad = any_bad or gdds_not_obeyed
if any_bad:
- raise RuntimeError("Unexpected behavior in rxboth run")
+ msg = "\n ".join(
+ [
+ "Unexpected behavior in rxboth run:",
+ f"any_bad_import_output: {any_bad_import_output}",
+ f"any_bad_check_const_vars: {any_bad_check_const_vars}",
+ f"sdate_not_obeyed: {sdate_not_obeyed}",
+ f"gdds_not_obeyed: {gdds_not_obeyed}",
+ ]
+ )
+ raise RuntimeError(msg)
if __name__ == "__main__":
diff --git a/python/ctsm/crop_calendars/cropcal_module.py b/python/ctsm/crop_calendars/cropcal_module.py
index b87d26816f..719d352665 100644
--- a/python/ctsm/crop_calendars/cropcal_module.py
+++ b/python/ctsm/crop_calendars/cropcal_module.py
@@ -345,7 +345,7 @@ def import_output(
my_vars,
year_1=None,
year_n=None,
- my_vegtypes=utils.define_mgdcrop_list(),
+ my_vegtypes=utils.define_mgdcrop_list_withgrasses(),
sdates_rx_ds=None,
gdds_rx_ds=None,
verbose=False,
@@ -425,7 +425,7 @@ def import_output(
# Check that e.g., GDDACCUM <= HUI
for var_list in [["GDDACCUM", "HUI"], ["SYEARS", "HYEARS"]]:
if all(v in this_ds_gs for v in var_list):
- any_bad = check_v0_le_v1(
+ any_bad = any_bad or check_v0_le_v1(
this_ds_gs, var_list, both_nan_ok=True, throw_error=throw_errors
)
diff --git a/python/ctsm/crop_calendars/cropcal_utils.py b/python/ctsm/crop_calendars/cropcal_utils.py
index 00ed2413d2..584046edee 100644
--- a/python/ctsm/crop_calendars/cropcal_utils.py
+++ b/python/ctsm/crop_calendars/cropcal_utils.py
@@ -207,7 +207,24 @@ def is_each_vegtype(this_vegtypelist, this_filter, this_method):
return [is_this_vegtype(x, this_filter, this_method) for x in this_vegtypelist]
-def define_mgdcrop_list():
+def define_crop_list():
+ """
+ List (strings) of managed crops in CLM.
+ """
+ notcrop_list = [
+ "tree",
+ "c3_arctic_grass",
+ "c3_non-arctic_grass",
+ "c4_grass",
+ "shrub",
+ "not_vegetated",
+ ]
+ defined_pftlist = define_pftlist()
+ is_crop = is_each_vegtype(defined_pftlist, notcrop_list, "notok_contains")
+ return [defined_pftlist[i] for i, x in enumerate(is_crop) if x]
+
+
+def define_mgdcrop_list_nograsses():
"""
List (strings) of managed crops in CLM.
"""
@@ -217,6 +234,24 @@ def define_mgdcrop_list():
return [defined_pftlist[i] for i, x in enumerate(is_crop) if x]
+def define_mgdcrop_list_withgrasses():
+ """
+ List (strings) of managed crops in CLM.
+ """
+ notcrop_list = [
+ "tree",
+ "c3_arctic_grass",
+ "c3_non-arctic_grass",
+ "c4_grass",
+ "shrub",
+ "unmanaged",
+ "not_vegetated",
+ ]
+ defined_pftlist = define_pftlist()
+ is_crop = is_each_vegtype(defined_pftlist, notcrop_list, "notok_contains")
+ return [defined_pftlist[i] for i, x in enumerate(is_crop) if x]
+
+
def vegtype_str2int(vegtype_str, vegtype_mainlist=None):
"""
Convert list of vegtype strings to integer index equivalents.
diff --git a/python/ctsm/crop_calendars/generate_gdd20_baseline.py b/python/ctsm/crop_calendars/generate_gdd20_baseline.py
new file mode 100644
index 0000000000..13668fc850
--- /dev/null
+++ b/python/ctsm/crop_calendars/generate_gdd20_baseline.py
@@ -0,0 +1,330 @@
+"""
+Generate stream_fldFileName_gdd20_baseline file from CTSM outputs
+"""
+
+import sys
+import argparse
+import os
+import datetime as dt
+import numpy as np
+import xarray as xr
+import cftime
+
+# -- add python/ctsm to path (needed if we want to run generate_gdd20_baseline stand-alone)
+_CTSM_PYTHON = os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir, os.pardir)
+sys.path.insert(1, _CTSM_PYTHON)
+
+# pylint: disable=wrong-import-position
+from ctsm.crop_calendars.import_ds import import_ds
+import ctsm.crop_calendars.cropcal_utils as utils
+from ctsm.crop_calendars.grid_one_variable import grid_one_variable
+from ctsm.crop_calendars.cropcal_module import MISSING_RX_GDD_VAL
+
+GRIDDING_VAR_LIST = ["patches1d_ixy", "patches1d_jxy", "lat", "lon"]
+STREAM_YEAR = 2000 # The year specified for stream_yearFirst and stream_yearLast in the call of
+# shr_strdata_init_from_inline() for sdat_cropcal_gdd20_baseline
+MGDCROP_LIST = utils.define_crop_list()
+
+
+def _parse_args():
+ """
+ Set up and parse input arguments
+ """
+ parser = argparse.ArgumentParser(
+ description=(
+ "Given a list of CTSM history files, generate stream_fldFileName_gdd20_baseline input"
+ + "file from the GDD0, GDD8, and GDD10 variables."
+ )
+ )
+
+ # Required
+ parser.add_argument(
+ "-i",
+ "--input-files",
+ help="Space-separated string of CTSM history files",
+ type=str,
+ required=True,
+ )
+ parser.add_argument(
+ "-o",
+ "--output-file",
+ help="Path to which output file should be saved",
+ type=str,
+ required=True,
+ )
+ parser.add_argument(
+ "-a",
+ "--author",
+ help=(
+ "String to be saved in author attribute of output files."
+ + "E.g., 'Author Name (authorname@ucar.edu)'"
+ ),
+ type=str,
+ required=True,
+ )
+
+ # Optional
+ parser.add_argument(
+ "--overwrite",
+ help="Overwrite existing output file, if any",
+ action="store_true",
+ )
+ parser.add_argument(
+ "-y1",
+ "--first-year",
+ help=("First calendar year to include"),
+ type=int,
+ required=False,
+ )
+ parser.add_argument(
+ "-yN",
+ "--last-year",
+ help=("Last calendar year to include"),
+ type=int,
+ required=False,
+ )
+ parser.add_argument(
+ "-v",
+ "--variable",
+ help=("Which type of variable should be processed?"),
+ required=False,
+ default="GDDBX",
+ choices=["GDDBX", "GDDB20"],
+ )
+
+ # Get arguments
+ args = parser.parse_args(sys.argv[1:])
+
+ # Check arguments
+ if os.path.exists(args.output_file) and not args.overwrite:
+ raise FileExistsError("Output file exists but --overwrite is not specified")
+
+ # Get and check input files
+ args.input_files = args.input_files.split(" ")
+ for filename in args.input_files:
+ if not os.path.exists(filename):
+ raise FileNotFoundError(f"Input file not found: {filename}")
+
+ # Process time slice
+ # Assumes CESM behavior where data for e.g. 1987 is saved as 1988-01-01.
+ # It would be more robust, accounting for upcoming behavior (where timestamp for a year is the
+ # middle of that year), to do slice("YEAR1-01-03", "YEARN-01-02"), but that's not compatible
+ # with ctsm_pylib as of the version using python 3.7.9. See safer_timeslice() in cropcal_utils.
+ if args.first_year is not None:
+ date_1 = f"{args.first_year+1}-01-01"
+ else:
+ date_1 = "0000-01-01"
+ if args.last_year is not None:
+ date_n = f"{args.last_year+1}-01-01"
+ else:
+ date_n = "9999-12-31"
+ time_slice = slice(date_1, date_n)
+
+ return args, time_slice
+
+
+def _get_cft_list(crop_list):
+ """
+ Given a list of strings, return a list of CFT names that contain any of those strings.
+ Will include both irrigated and rainfed!
+
+ Args:
+ crop_list (list): List of crops to look for.
+ E.g.: ["corn", "cotton"]
+
+ Returns:
+ cft_str_list: List of CFTs containing any of the crop names in crop_list.
+ E.g.: ["tropical_corn", "irrigated_tropical_corn",
+ "temperate_corn", "irrigated_temperate_corn",
+ "cotton", "irrigated_cotton"]
+ """
+
+ cft_str_list = []
+ for crop_str in crop_list:
+ cft_str_list += [x for x in MGDCROP_LIST if crop_str in x]
+ return cft_str_list
+
+
+def _get_gddn_for_cft(cft_str, variable):
+ """
+ Given a CFT name, return the GDDN variable it uses.
+
+ Args:
+ cft_str (str): E.g., "irrigated_temperate_corn"
+
+ Returns:
+ str or None: Name of variable to use (e.g., "GDD8X"). If crop not yet handled, return None.
+ """
+
+ gddn = None
+ gddn_str = None
+
+ gdd0_list_str = ["wheat", "cotton", "rice"]
+ if cft_str in _get_cft_list(gdd0_list_str):
+ gddn = 0
+
+ gdd8_list_str = ["corn", "sugarcane", "miscanthus", "switchgrass"]
+ if cft_str in _get_cft_list(gdd8_list_str):
+ gddn = 8
+
+ gdd10_list_str = ["soybean"]
+ if cft_str in _get_cft_list(gdd10_list_str):
+ gddn = 10
+
+ if gddn is not None:
+ gddn_str = variable.replace("B", str(gddn))
+
+ return gddn, gddn_str
+
+
+def _get_output_varname(cft_str):
+ cft_int = utils.vegtype_str2int(cft_str)[0]
+ return f"gdd20bl_{cft_int}"
+
+
+def _add_time_axis(da_in):
+ """
+ Adds a size-1 time axis to a DataArray. Needed because CDEPS streams code requires a time axis,
+ even if the data in question is not supposed to vary over time.
+
+ Args:
+ da_in (DataArray): xarray DataArray which needs a time axis added
+
+ Returns:
+ DataArray: da_in with a new 1-step time axis
+ """
+ this_date = np.array(cftime.DatetimeNoLeap(STREAM_YEAR, 1, 1, 0, 0, 0, 0, has_year_zero=True))
+ this_date = np.expand_dims(this_date, axis=0)
+ da_time = xr.DataArray(
+ data=this_date,
+ dims={"time": this_date},
+ )
+ da_out = da_in.expand_dims(time=da_time)
+ return da_out
+
+
+def setup_output_dataset(input_files, author, variable, year_args, ds_in):
+ """
+ Set up output Dataset
+ """
+ data_var_dict = {}
+ for gridding_var in GRIDDING_VAR_LIST:
+ data_var_dict[gridding_var] = ds_in[gridding_var]
+ ds_out = xr.Dataset(
+ data_vars=data_var_dict,
+ attrs={
+ "author": author,
+ "created": dt.datetime.now().astimezone().isoformat(),
+ "input_year_range": f"{year_args[0]}-{year_args[1]}",
+ "input_variable": variable,
+ },
+ )
+ all_files_in_same_dir = len(np.unique([os.path.dirname(file) for file in input_files])) == 1
+ if all_files_in_same_dir:
+ ds_out.attrs["input_files_dir"] = os.path.dirname(input_files[0])
+ ds_out.attrs["input_files"] = ", ".join([os.path.basename(file) for file in input_files])
+ else:
+ ds_out.attrs["input_files"] = ", ".join(input_files)
+ return ds_out
+
+
+def generate_gdd20_baseline(input_files, output_file, author, time_slice, variable, year_args):
+ """
+ Generate stream_fldFileName_gdd20_baseline file from CTSM outputs
+ """
+
+ # Define variables to process
+ if variable == "GDDBX":
+ suffix = "X"
+ elif variable == "GDDB20":
+ suffix = "20"
+ else:
+ raise ValueError(f"-v/--variable {variable} not recoginzed")
+ var_list_in = []
+ for base_temp in [0, 8, 10]:
+ var_list_in.append(f"GDD{base_temp}{suffix}")
+
+ # Get unique values and sort
+ input_files = list(set(input_files))
+ input_files.sort()
+
+ # Import history files and ensure they have lat/lon dims
+ ds_in = import_ds(input_files, var_list_in + GRIDDING_VAR_LIST, time_slice=time_slice)
+ if not all(x in ds_in.dims for x in ["lat", "lon"]):
+ raise RuntimeError("Input files must have lat and lon dimensions")
+
+ # If needed, find mean over time
+ if "time" in ds_in.dims:
+ ds_in = ds_in.mean(dim="time", skipna=True)
+
+ # Set up a dummy DataArray to use for crops without an assigned GDDN variable
+ dummy_da = xr.DataArray(
+ data=np.full_like(ds_in[var_list_in[0]].values, MISSING_RX_GDD_VAL),
+ dims=ds_in[var_list_in[0]].dims,
+ coords=ds_in[var_list_in[0]].coords,
+ )
+ dummy_da = _add_time_axis(dummy_da)
+
+ # Set up output Dataset
+ ds_out = setup_output_dataset(input_files, author, variable, year_args, ds_in)
+
+ # Process all crops
+ encoding_dict = {}
+ for cft_str in MGDCROP_LIST:
+ cft_int = utils.vegtype_str2int(cft_str)[0]
+ print(f"{cft_str} ({cft_int})")
+
+ # Which GDDN history variable does this crop use? E.g., GDD0, GDD10
+ gddn, gddn_str = _get_gddn_for_cft(cft_str, variable)
+
+ # Fill any missing values with MISSING_RX_GDD_VAL. This will mean that gddmaturity there
+ # never changes.
+ if gddn_str is None:
+ # Crop not handled yet? It's already filled with missing value
+ this_da = dummy_da
+ print(" dummy GDD20")
+ else:
+ this_da = ds_in[gddn_str] # Already did ds_in.mean(dim="time") above
+ this_da = _add_time_axis(this_da)
+ print(f" {gddn_str}")
+ this_da = this_da.fillna(MISSING_RX_GDD_VAL)
+
+ # Add attributes of output file
+ if (gddn is None) != (gddn_str is None):
+ raise RuntimeError("gddn and gddn_str must either both be None or both be not None")
+ if gddn_str is None:
+ long_name = "Dummy GDD20"
+ else:
+ long_name = f"GDD{gddn}20"
+ this_da.attrs["long_name"] = long_name + f" baseline for {cft_str}"
+ this_da.attrs["units"] = "°C days"
+
+ # Copy that to ds_out
+ var_out = _get_output_varname(cft_str)
+ print(f" Output variable {var_out}")
+ ds_out[var_out] = this_da
+ encoding_dict[var_out] = {"dtype": "float64"}
+
+ # Grid, if needed
+ if any(x not in this_da.dims for x in ["lat", "lon"]):
+ ds_out[var_out] = grid_one_variable(ds_out, var_out)
+
+ # Save
+ ds_out.to_netcdf(output_file, format="NETCDF3_CLASSIC", encoding=encoding_dict)
+
+ print("Done!")
+
+
+def main():
+ """
+ main() function for calling generate_gdd20_baseline.py from command line.
+ """
+ args, time_slice = _parse_args()
+ generate_gdd20_baseline(
+ args.input_files,
+ args.output_file,
+ args.author,
+ time_slice,
+ args.variable,
+ [args.first_year, args.last_year],
+ )
diff --git a/python/ctsm/crop_calendars/generate_gdds.py b/python/ctsm/crop_calendars/generate_gdds.py
index 156ebfb20e..49226e6f75 100644
--- a/python/ctsm/crop_calendars/generate_gdds.py
+++ b/python/ctsm/crop_calendars/generate_gdds.py
@@ -178,6 +178,7 @@ def main(
mxmats,
cc.get_gs_len_da,
skip_crops,
+ outdir_figs,
logger,
)
diff --git a/python/ctsm/crop_calendars/generate_gdds_functions.py b/python/ctsm/crop_calendars/generate_gdds_functions.py
index 8af2fdc049..14bd6b2e40 100644
--- a/python/ctsm/crop_calendars/generate_gdds_functions.py
+++ b/python/ctsm/crop_calendars/generate_gdds_functions.py
@@ -22,6 +22,7 @@
# pylint: disable=import-error
from ctsm.crop_calendars.cropcal_figs_module import *
from matplotlib.transforms import Bbox
+ import matplotlib.pyplot as plt
warnings.filterwarnings(
"ignore",
@@ -63,7 +64,7 @@ def error(logger, string):
raise RuntimeError(string)
-def check_sdates(dates_ds, sdates_rx, logger, verbose=False):
+def check_sdates(dates_ds, sdates_rx, outdir_figs, logger, verbose=False):
"""
Checking that input and output sdates match
"""
@@ -106,8 +107,28 @@ def check_sdates(dates_ds, sdates_rx, logger, verbose=False):
log(logger, out_map_notnan[here][0:4])
log(logger, "diff:")
log(logger, diff_map_notnan[here][0:4])
+ first_diff = all_ok
all_ok = False
+ if CAN_PLOT:
+ sdate_diffs_dir = os.path.join(outdir_figs, "sdate_diffs")
+ if first_diff:
+ log(logger, f"Saving sdate difference figures to {sdate_diffs_dir}")
+ if not os.path.exists(sdate_diffs_dir):
+ os.makedirs(sdate_diffs_dir)
+ in_map.where(~np.isnan(out_map)).plot()
+ plt.title(f"{vegtype_str} sdates in (masked)")
+ plt.savefig(os.path.join(sdate_diffs_dir, f"{vegtype_str}.in.png"))
+ plt.close()
+ out_map.plot()
+ plt.title(f"{vegtype_str} sdates out")
+ plt.savefig(os.path.join(sdate_diffs_dir, f"{vegtype_str}.out.png"))
+ plt.close()
+ diff_map.plot()
+ plt.title(f"{vegtype_str} sdates diff (out - in)")
+ plt.savefig(os.path.join(sdate_diffs_dir, f"{vegtype_str}.diff.png"))
+ plt.close()
+
if not any_found:
error(logger, "No matching variables found in sdates_rx!")
@@ -234,6 +255,7 @@ def import_and_process_1yr(
mxmats,
get_gs_len_da,
skip_crops,
+ outdir_figs,
logger,
):
"""
@@ -260,9 +282,9 @@ def import_and_process_1yr(
# Get list of crops to include
if skip_crops is not None:
- crops_to_read = [c for c in utils.define_mgdcrop_list() if c not in skip_crops]
+ crops_to_read = [c for c in utils.define_mgdcrop_list_withgrasses() if c not in skip_crops]
else:
- crops_to_read = utils.define_mgdcrop_list()
+ crops_to_read = utils.define_mgdcrop_list_withgrasses()
print(h1_filelist)
dates_ds = import_ds(
@@ -272,6 +294,8 @@ def import_and_process_1yr(
time_slice=slice(f"{this_year}-01-01", f"{this_year}-12-31"),
chunks=chunks,
)
+ for timestep in dates_ds["time"].values:
+ print(timestep)
if dates_ds.dims["time"] > 1:
if dates_ds.dims["time"] == 365:
@@ -466,7 +490,7 @@ def import_and_process_1yr(
# Import expected sowing dates. This will also be used as our template output file.
imported_sdates = isinstance(sdates_rx, str)
sdates_rx = import_rx_dates("s", sdates_rx, incl_patches1d_itype_veg, mxsowings, logger)
- check_sdates(dates_incl_ds, sdates_rx, logger)
+ check_sdates(dates_incl_ds, sdates_rx, outdir_figs, logger)
# Import hdates, if needed
imported_hdates = isinstance(hdates_rx, str)
@@ -575,6 +599,7 @@ def import_and_process_1yr(
this_crop_gddaccum_da = this_crop_ds[clm_gdd_var]
if save_figs:
this_crop_gddharv_da = this_crop_ds["GDDHARV"]
+ check_gddharv = True
if not this_crop_gddaccum_da.size:
continue
log(logger, f" {vegtype_str}...")
@@ -625,11 +650,15 @@ def import_and_process_1yr(
+ "NaN after extracting GDDs accumulated at harvest",
)
if save_figs and np.any(np.isnan(gddharv_atharv_p)):
- log(
- logger,
- f" ❗ {np.sum(np.isnan(gddharv_atharv_p))}/{len(gddharv_atharv_p)} "
- + "NaN after extracting GDDHARV",
- )
+ if np.all(np.isnan(gddharv_atharv_p)):
+ log(logger, " ❗ All GDDHARV are NaN; should only affect figure")
+ check_gddharv = False
+ else:
+ log(
+ logger,
+ f" ❗ {np.sum(np.isnan(gddharv_atharv_p))}/{len(gddharv_atharv_p)} "
+ + "NaN after extracting GDDHARV",
+ )
# Assign these to growing seasons based on whether gs crossed new year
this_year_active_patch_indices = [
@@ -712,9 +741,15 @@ def import_and_process_1yr(
)
else:
error(logger, "Unexpected NaN for last season's GDD accumulation.")
- if save_figs and np.any(
- np.isnan(
- gddharv_yp_list[var][year_index - 1, active_this_year_where_gs_lastyr_indices]
+ if (
+ save_figs
+ and check_gddharv
+ and np.any(
+ np.isnan(
+ gddharv_yp_list[var][
+ year_index - 1, active_this_year_where_gs_lastyr_indices
+ ]
+ )
)
):
if incorrectly_daily:
@@ -1160,9 +1195,13 @@ def make_figures(
else:
error(logger, f"layout {layout} not recognized")
- this_min = int(np.round(np.nanmin(gddharv_map_yx)))
- this_max = int(np.round(np.nanmax(gddharv_map_yx)))
- this_title = f"{run1_name} (range {this_min}–{this_max})"
+ gddharv_all_nan = np.all(np.isnan(gddharv_map_yx.values))
+ if gddharv_all_nan:
+ this_title = f"{run1_name} (GDDHARV all NaN?)"
+ else:
+ this_min = int(np.round(np.nanmin(gddharv_map_yx)))
+ this_max = int(np.round(np.nanmax(gddharv_map_yx)))
+ this_title = f"{run1_name} (range {this_min}–{this_max})"
make_gengdd_map(
this_axis,
gddharv_map_yx,
@@ -1195,7 +1234,7 @@ def make_figures(
)
# Difference
- if layout == "3x2":
+ if not gddharv_all_nan and layout == "3x2":
this_axis = fig.add_subplot(spec[2, 0], projection=ccrs.PlateCarree())
this_min = int(np.round(np.nanmin(gdd_map_yx)))
this_max = int(np.round(np.nanmax(gdd_map_yx)))
diff --git a/python/ctsm/crop_calendars/import_ds.py b/python/ctsm/crop_calendars/import_ds.py
index 77a22b626b..486757492f 100644
--- a/python/ctsm/crop_calendars/import_ds.py
+++ b/python/ctsm/crop_calendars/import_ds.py
@@ -41,6 +41,28 @@ def compute_derived_vars(ds_in, var):
return ds_in
+def manual_mfdataset(filelist, my_vars, my_vegtypes, time_slice):
+ """
+ Opening a list of files with Xarray's open_mfdataset requires dask. This function is a
+ workaround for Python environments that don't have dask.
+ """
+ ds_out = None
+ for filename in filelist:
+ ds_in = xr.open_dataset(filename)
+ ds_in = mfdataset_preproc(ds_in, my_vars, my_vegtypes, time_slice)
+ if ds_out is None:
+ ds_out = ds_in
+ else:
+ ds_out = xr.concat(
+ [ds_out, ds_in],
+ data_vars="minimal",
+ compat="override",
+ coords="all",
+ dim="time",
+ )
+ return ds_out
+
+
def mfdataset_preproc(ds_in, vars_to_import, vegtypes_to_import, time_slice):
"""
Function to drop unwanted variables in preprocessing of open_mfdataset().
@@ -221,22 +243,20 @@ def import_ds(
if isinstance(filelist, list):
with warnings.catch_warnings():
warnings.filterwarnings(action="ignore", category=DeprecationWarning)
- if find_spec("dask") is None:
- raise ModuleNotFoundError(
- "You have asked xarray to import a list of files as a single Dataset using"
- " open_mfdataset(), but this requires dask, which is not available.\nFile"
- f" list: {filelist}"
- )
- this_ds = xr.open_mfdataset(
- sorted(filelist),
- data_vars="minimal",
- preprocess=mfdataset_preproc_closure,
- compat="override",
- coords="all",
- concat_dim="time",
- combine="nested",
- chunks=chunks,
- )
+ dask_unavailable = find_spec("dask") is None
+ if dask_unavailable:
+ this_ds = manual_mfdataset(filelist, my_vars, my_vegtypes, time_slice)
+ else:
+ this_ds = xr.open_mfdataset(
+ sorted(filelist),
+ data_vars="minimal",
+ preprocess=mfdataset_preproc_closure,
+ compat="override",
+ coords="all",
+ concat_dim="time",
+ combine="nested",
+ chunks=chunks,
+ )
elif isinstance(filelist, str):
this_ds = xr.open_dataset(filelist, chunks=chunks)
this_ds = mfdataset_preproc(this_ds, my_vars, my_vegtypes, time_slice)
diff --git a/python/ctsm/crop_calendars/interpolate_gdds.py b/python/ctsm/crop_calendars/interpolate_gdds.py
index 2aa0b79997..123d40af38 100755
--- a/python/ctsm/crop_calendars/interpolate_gdds.py
+++ b/python/ctsm/crop_calendars/interpolate_gdds.py
@@ -6,6 +6,7 @@
import sys
import argparse
import logging
+import re
import xarray as xr
# -- add python/ctsm to path (needed if we want to run this stand-alone)
@@ -64,6 +65,14 @@ def _setup_process_args():
type=str,
required=True,
)
+ parser.add_argument(
+ "-p",
+ "--variable-prefix",
+ help="Interpolate variables whose names start with this string",
+ type=str,
+ required=False,
+ default="gdd1_",
+ )
parser.add_argument(
"--overwrite",
help="If output file exists, overwrite it.",
@@ -110,8 +119,12 @@ def interpolate_gdds(args):
for var in ds_in:
# Check variable
- if "gdd1_" not in var:
- raise RuntimeError(f"Unexpected variable {var} on input file")
+ if "lat" not in ds_in[var].dims and "lon" not in ds_in[var].dims:
+ print(f"Skipping variable {var} with dimensions {ds_in[var].dims}")
+ continue
+ if not re.compile("^" + args.variable_prefix).match(var):
+ print(f"Unexpected variable {var} on input file. Skipping.")
+ continue
if args.dry_run:
continue
diff --git a/python/ctsm/lilac_make_runtime_inputs.py b/python/ctsm/lilac_make_runtime_inputs.py
index 71f3c9bbe4..e751f6c931 100644
--- a/python/ctsm/lilac_make_runtime_inputs.py
+++ b/python/ctsm/lilac_make_runtime_inputs.py
@@ -47,6 +47,12 @@
TRUE,FALSE
+
+
+ logical
+ TRUE,FALSE
+
+
"""
@@ -301,7 +307,6 @@ def buildnml(cime_path, rundir):
# remove temporary files in rundir
os.remove(os.path.join(rundir, "config_cache.xml"))
os.remove(os.path.join(rundir, "env_lilac.xml"))
- os.remove(os.path.join(rundir, "drv_flds_in"))
os.remove(infile)
diff --git a/python/ctsm/run_sys_tests.py b/python/ctsm/run_sys_tests.py
index f5a7ed04dc..6afc43cd19 100644
--- a/python/ctsm/run_sys_tests.py
+++ b/python/ctsm/run_sys_tests.py
@@ -736,13 +736,29 @@ def _check_py_env(test_attributes):
# whether import is possible.
# pylint: disable=import-error disable
- # Check requirements for FSURDATMODIFYCTSM, if needed
- if any("FSURDATMODIFYCTSM" in t for t in test_attributes):
+ # Check requirements for using modify_fsurdat Python module, if needed
+ modify_fsurdat_users = ["FSURDATMODIFYCTSM", "RXCROPMATURITY"]
+ if any(any(u in t for u in modify_fsurdat_users) for t in test_attributes):
try:
import ctsm.modify_input_files.modify_fsurdat
except ModuleNotFoundError as err:
raise ModuleNotFoundError("modify_fsurdat" + err_msg) from err
+ # Check requirements for RXCROPMATURITY, if needed
+ if any("RXCROPMATURITY" in t for t in test_attributes):
+ try:
+ import ctsm.crop_calendars.check_rxboth_run
+ except ModuleNotFoundError as err:
+ raise ModuleNotFoundError("check_rxboth_run" + err_msg) from err
+ try:
+ import ctsm.crop_calendars.generate_gdds
+ except ModuleNotFoundError as err:
+ raise ModuleNotFoundError("generate_gdds" + err_msg) from err
+ try:
+ import ctsm.crop_calendars.interpolate_gdds
+ except ModuleNotFoundError as err:
+ raise ModuleNotFoundError("interpolate_gdds" + err_msg) from err
+
# Check that list for any testmods that use modify_fates_paramfile.py
testmods_to_check = ["clm-FatesColdTwoStream", "clm-FatesColdTwoStreamNoCompFixedBioGeo"]
testmods = _get_testmod_list(test_attributes)
diff --git a/python/ctsm/site_and_regional/mesh_type.py b/python/ctsm/site_and_regional/mesh_type.py
index be785e745d..47c0295593 100644
--- a/python/ctsm/site_and_regional/mesh_type.py
+++ b/python/ctsm/site_and_regional/mesh_type.py
@@ -235,8 +235,16 @@ def create_2d_coords(self):
lons_size = self.center_lons.size
# -- convert center points from 1d to 2d
- self.center_lat2d = np.broadcast_to(self.center_lats[:], (lons_size, lats_size))
- self.center_lon2d = np.broadcast_to(self.center_lons[:], (lons_size, lats_size))
+ try:
+ self.center_lat2d = np.broadcast_to(self.center_lats[:], (lons_size, lats_size))
+ self.center_lon2d = np.broadcast_to(self.center_lons[:], (lons_size, lats_size))
+ except ValueError:
+ self.center_lat2d = np.broadcast_to(
+ np.expand_dims(self.center_lats[:], 0), (lons_size, lats_size)
+ )
+ self.center_lon2d = np.broadcast_to(
+ np.expand_dims(self.center_lons[:], 1), (lons_size, lats_size)
+ )
elif self.lat_dims == 2:
# -- 2D lats and lons
dims = self.center_lons.shape
@@ -351,7 +359,7 @@ def calculate_corners(self, unit="degrees"):
)
# Longitudes should stay within 0 to 360
if np.any(self.corner_lons > 360.0):
- abort("Corners have longitudes greater than 360")
+ abort(f"Corners have longitudes greater than 360 (max: {np.max(self.corner_lons)})")
if np.any(self.corner_lons < 0.0):
logger.warning(
"Corners have longitudes less than zero -- %s %s",
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 568b53cd15..5b0f6c9b1b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -20,9 +20,11 @@ add_subdirectory(${CLM_ROOT}/share/src csm_share)
add_subdirectory(${CLM_ROOT}/share/unit_test_stubs/util csm_share_stubs)
add_subdirectory(${CLM_ROOT}/share/src/esmf_wrf_timemgr esmf_wrf_timemgr)
-# Add the single file we need from CMEPS
-set (drv_sources_needed
- ${CLM_ROOT}/components/cmeps/cesm/nuopc_cap_share/glc_elevclass_mod.F90)
+# Add files needed from CMEPS
+list ( APPEND drv_sources_needed
+ ${CLM_ROOT}/components/cmeps/cesm/nuopc_cap_share/glc_elevclass_mod.F90
+ ${CLM_ROOT}/components/cmeps/cesm/nuopc_cap_share/shr_dust_emis_mod.F90
+ )
# Add CLM source directories
add_subdirectory(${CLM_ROOT}/src/utils clm_utils)
@@ -103,3 +105,8 @@ add_subdirectory(${CLM_ROOT}/src/dyn_subgrid/test clm_dyn_subgrid_test)
add_subdirectory(${CLM_ROOT}/src/main/test clm_main_test)
add_subdirectory(${CLM_ROOT}/src/init_interp/test clm_init_interp_test)
add_subdirectory(${CLM_ROOT}/src/self_tests/test clm_self_tests_test)
+
+# Add driver unit test directories
+# (these should be moved to the appropriate submodule)
+add_subdirectory(${CLM_ROOT}/src/drv_test drv_test)
+
diff --git a/src/biogeochem/CMakeLists.txt b/src/biogeochem/CMakeLists.txt
index 50eb64cdb7..0763be096d 100644
--- a/src/biogeochem/CMakeLists.txt
+++ b/src/biogeochem/CMakeLists.txt
@@ -14,6 +14,7 @@ list(APPEND clm_sources
CNVegStateType.F90
CNVegCarbonStateType.F90
CNVegCarbonFluxType.F90
+ CNVegMatrixMod.F90
CNVegNitrogenStateType.F90
CNVegNitrogenFluxType.F90
CNCIsoAtmTimeSeriesReadMod.F90
diff --git a/src/biogeochem/CNAllocationMod.F90 b/src/biogeochem/CNAllocationMod.F90
index 8d38ca4b87..6376279a61 100644
--- a/src/biogeochem/CNAllocationMod.F90
+++ b/src/biogeochem/CNAllocationMod.F90
@@ -86,6 +86,7 @@ subroutine calc_gpp_mr_availc(bounds, num_soilp, filter_soilp, &
!
! !USES:
use CNSharedParamsMod , only : use_matrixcn
+ !
! !ARGUMENTS:
type(bounds_type) , intent(in) :: bounds
integer , intent(in) :: num_soilp ! number of soil patches in filter
diff --git a/src/biogeochem/CNBalanceCheckMod.F90 b/src/biogeochem/CNBalanceCheckMod.F90
index 8801efdf72..7b88422843 100644
--- a/src/biogeochem/CNBalanceCheckMod.F90
+++ b/src/biogeochem/CNBalanceCheckMod.F90
@@ -64,7 +64,6 @@ module CNBalanceCheckMod
!-----------------------------------------------------------------------
subroutine Init(this, bounds)
- use CNSharedParamsMod, only : use_matrixcn
class(cn_balance_type) :: this
type(bounds_type) , intent(in) :: bounds
@@ -346,7 +345,7 @@ subroutine CBalanceCheck(this, bounds, num_soilc, filter_soilc, &
(col_endcb(c) - col_begcb(c))
! check for significant errors
- if (abs(col_errcb(c)) > this%cerror) then
+ if (abs(col_errcb(c)) > this%cerror) then
err_found = .true.
err_index = c
end if
@@ -644,8 +643,8 @@ subroutine NBalanceCheck(this, bounds, num_soilc, filter_soilc, &
! calculate the total column-level nitrogen balance error for this time step
col_errnb(c) = (col_ninputs(c) - col_noutputs(c))*dt - &
(col_endnb(c) - col_begnb(c))
-
- if (abs(col_errnb(c)) > this%nerror) then
+
+ if (abs(col_errnb(c)) > this%nerror) then
err_found = .true.
err_index = c
end if
diff --git a/src/biogeochem/CNC14DecayMod.F90 b/src/biogeochem/CNC14DecayMod.F90
index 26e938f72e..1679c602e4 100644
--- a/src/biogeochem/CNC14DecayMod.F90
+++ b/src/biogeochem/CNC14DecayMod.F90
@@ -89,7 +89,26 @@ subroutine C14Decay( bounds, num_soilc, filter_soilc, num_soilp, filter_soilp, &
livestemc => c14_cnveg_carbonstate_inst%livestemc_patch , & ! Output: [real(r8) (:) ] (gC/m2) live stem C
livestemc_storage => c14_cnveg_carbonstate_inst%livestemc_storage_patch , & ! Output: [real(r8) (:) ] (gC/m2) live stem C storage
livestemc_xfer => c14_cnveg_carbonstate_inst%livestemc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) live stem C transfer
- pft_ctrunc => c14_cnveg_carbonstate_inst%ctrunc_patch & ! Output: [real(r8) (:) ] (gC/m2) patch-level sink for C truncation
+ pft_ctrunc => c14_cnveg_carbonstate_inst%ctrunc_patch , & ! Output: [real(r8) (:) ] (gC/m2) patch-level sink for C truncation
+
+ ileaf_to_iout_fic => c14_cnveg_carbonflux_inst%ileaf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_fic => c14_cnveg_carbonflux_inst%ileafst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_fic => c14_cnveg_carbonflux_inst%ileafxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_fic => c14_cnveg_carbonflux_inst%ifroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_fic => c14_cnveg_carbonflux_inst%ifrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_fic => c14_cnveg_carbonflux_inst%ifrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from fine root transfer pool to outside of vegetation pools
+ ilivestem_to_iout_fic => c14_cnveg_carbonflux_inst%ilivestem_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_fic => c14_cnveg_carbonflux_inst%ilivestemst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem storage pool to outside of vegetation pools
+ ilivestemxf_to_iout_fic => c14_cnveg_carbonflux_inst%ilivestemxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_fic => c14_cnveg_carbonflux_inst%ideadstem_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_fic => c14_cnveg_carbonflux_inst%ideadstemst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_fic => c14_cnveg_carbonflux_inst%ideadstemxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_fic => c14_cnveg_carbonflux_inst%ilivecroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_fic => c14_cnveg_carbonflux_inst%ilivecrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_fic => c14_cnveg_carbonflux_inst%ilivecrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_fic => c14_cnveg_carbonflux_inst%ideadcroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_fic => c14_cnveg_carbonflux_inst%ideadcrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_fic => c14_cnveg_carbonflux_inst%ideadcrootxf_to_iout_fi & ! Input: [integer (:)] Index of fire related C transfer from dead coarse root transfer pool to outside of vegetation pools
)
! set time steps
@@ -116,12 +135,15 @@ subroutine C14Decay( bounds, num_soilc, filter_soilc, num_soilp, filter_soilp, &
else
spinup_term = 1._r8
endif
- ! Without matrix solution
if(.not. use_soil_matrixcn)then
decomp_cpools_vr(c,j,l) = decomp_cpools_vr(c,j,l) * (1._r8 - decay_const * spinup_term * dt)
else
- ! Matrix solution equivalent to above
- ! This will be added when the full matrix solution is brought in
+ associate( &
+ matrix_decomp_fire_k => c14_soilbiogeochem_carbonflux_inst%matrix_decomp_fire_k_col & ! Output: [real(r8) (:,:) ] (gC/m3/step) VR deomp. C fire loss in matrix representation
+ )
+ matrix_decomp_fire_k(c,j+nlevdecomp*(l-1)) = matrix_decomp_fire_k(c,j+nlevdecomp*(l-1)) &
+ - spinup_term * decay_const * dt
+ end associate
end if
end do
end do
@@ -133,8 +155,6 @@ subroutine C14Decay( bounds, num_soilc, filter_soilc, num_soilp, filter_soilp, &
cpool(p) = cpool(p) * (1._r8 - decay_const * dt)
xsmrpool(p) = xsmrpool(p) * (1._r8 - decay_const * dt)
-
- ! Without Matrix solution
if(.not. use_matrixcn)then
! NOTE: Any changes here need to be applied below
deadcrootc(p) = deadcrootc(p) * (1._r8 - decay_const * dt)
@@ -156,11 +176,31 @@ subroutine C14Decay( bounds, num_soilc, filter_soilc, num_soilp, filter_soilp, &
livestemc_storage(p) = livestemc_storage(p) * (1._r8 - decay_const * dt)
livestemc_xfer(p) = livestemc_xfer(p) * (1._r8 - decay_const * dt)
else
+ associate( &
+ matrix_fitransfer => c14_cnveg_carbonflux_inst%matrix_fitransfer_patch & ! Output: [real(r8) (:,:) ] (gC/m2/s) C transfer rate from fire processes
+ )
! Each of these MUST correspond to the code above. Any changes in
! code above need to apply here as well
+ matrix_fitransfer(p,ideadcroot_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ideadcrootst_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ideadcrootxf_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ideadstem_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ideadstemst_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ideadstemxf_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ifroot_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ifrootst_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ifrootxf_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ileaf_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ileafst_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ileafxf_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ilivecroot_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ilivecrootst_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ilivecrootxf_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ilivestem_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ilivestemst_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ilivestemxf_to_iout_fic) = decay_const
+ end associate
end if
- ! Some fields like cpool, and xsmrpool above, and the gresp and
- ! pft_ctrunc fields are handled the same for both matrix on and off
gresp_storage(p) = gresp_storage(p) * (1._r8 - decay_const * dt)
gresp_xfer(p) = gresp_xfer(p) * (1._r8 - decay_const * dt)
pft_ctrunc(p) = pft_ctrunc(p) * (1._r8 - decay_const * dt)
diff --git a/src/biogeochem/CNCStateUpdate1Mod.F90 b/src/biogeochem/CNCStateUpdate1Mod.F90
index 5e38de2676..093e83172a 100644
--- a/src/biogeochem/CNCStateUpdate1Mod.F90
+++ b/src/biogeochem/CNCStateUpdate1Mod.F90
@@ -2,9 +2,6 @@ module CNCStateUpdate1Mod
!-----------------------------------------------------------------------
! Module for carbon state variable update, non-mortality fluxes.
- ! When the matrix solution is being used (use_matrixcn and use_soil_matrixcn)
- ! only some state updates are done here, the other state updates happen
- ! after the matrix is solved in VegMatrix and SoilMatrix.
!
! !USES:
use shr_kind_mod , only : r8 => shr_kind_r8
@@ -147,6 +144,7 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
! variables (except for gap-phase mortality and fire fluxes)
!
use clm_varctl , only : carbon_resp_opt
+ use CNVegMatrixMod, only : matrix_update_phc
! !ARGUMENTS:
integer , intent(in) :: num_soilc ! number of soil columns filter
integer , intent(in) :: filter_soilc(:) ! filter for soil columns
@@ -188,7 +186,7 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
dt = get_step_size_real()
! Below is the input into the soil biogeochemistry model
-
+
fc_loop: do fc = 1,num_soilc
c = filter_soilc(fc)
@@ -202,9 +200,7 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
call clm_fates%UpdateCLitterfluxes(cf_soil,clump_index,c)
else
-
do j = 1,nlevdecomp
-
!
! State update without the matrix solution
!
@@ -219,66 +215,52 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
! terms have been moved to CStateUpdateDynPatch. I think this is zeroed every
! time step, but to be safe, I'm explicitly setting it to zero here.
cf_soil%decomp_cpools_sourcesink_col(c,j,i_cwd) = 0._r8
+
+ else
!
! For the matrix solution the actual state update comes after the matrix
! multiply in SoilMatrix, but the matrix needs to be setup with
! the equivalent of above. Those changes can be here or in the
! native subroutines dealing with that field
!
- else
! phenology and dynamic land cover fluxes
+ do i = i_litr_min, i_litr_max
+ cf_soil%matrix_Cinput%V(c,j+(i-1)*nlevdecomp) = &
+ cf_soil%matrix_Cinput%V(c,j+(i-1)*nlevdecomp) + cf_veg%phenology_c_to_litr_c_col(c,j,i) *dt
+ end do
end if
end do
end if fates_if
-
- end do fc_loop
-
- ! litter and SOM HR fluxes
- do k = 1, ndecomp_cascade_transitions
do j = 1,nlevdecomp
- do fc = 1,num_soilc
- c = filter_soilc(fc)
- !
- ! State update without the matrix solution
- !
- if (.not. use_soil_matrixcn) then
+ !
+ ! State update without the matrix solution
+ !
+ if (.not. use_soil_matrixcn) then
+ ! litter and SOM HR fluxes
+ do k = 1, ndecomp_cascade_transitions
cf_soil%decomp_cpools_sourcesink_col(c,j,cascade_donor_pool(k)) = &
cf_soil%decomp_cpools_sourcesink_col(c,j,cascade_donor_pool(k)) &
- - ( cf_soil%decomp_cascade_hr_vr_col(c,j,k) + cf_soil%decomp_cascade_ctransfer_vr_col(c,j,k)) *dt
- end if !not use_soil_matrixcn
- end do
- end do
- end do
- do k = 1, ndecomp_cascade_transitions
- if ( cascade_receiver_pool(k) /= 0 ) then ! skip terminal transitions
- do j = 1,nlevdecomp
- do fc = 1,num_soilc
- c = filter_soilc(fc)
- !
- ! State update without the matrix solution
- !
- if (.not. use_soil_matrixcn) then
+ - ( cf_soil%decomp_cascade_hr_vr_col(c,j,k) + cf_soil%decomp_cascade_ctransfer_vr_col(c,j,k)) * dt
+ if ( cascade_receiver_pool(k) /= 0 ) then ! skip terminal transitions
cf_soil%decomp_cpools_sourcesink_col(c,j,cascade_receiver_pool(k)) = &
cf_soil%decomp_cpools_sourcesink_col(c,j,cascade_receiver_pool(k)) &
- + cf_soil%decomp_cascade_ctransfer_vr_col(c,j,k)*dt
- end if !not use_soil_matrixcn
+ + cf_soil%decomp_cascade_ctransfer_vr_col(c,j,k) * dt
+ end if
end do
- end do
- end if
- end do
+ end if
+ end do
+
+ end do fc_loop
soilpatch_loop: do fp = 1,num_soilp
p = filter_soilp(fp)
c = patch%column(p)
! phenology: transfer growth fluxes
-
- !
- ! State update without the matrix solution
- !
- if(.not. use_matrixcn)then
+ ! TODO slevis: improve indentation
+ if(.not. use_matrixcn)then
! NOTE: Any changes that go here MUST be applied to the matrix
! version as well
cs_veg%leafc_patch(p) = cs_veg%leafc_patch(p) + cf_veg%leafc_xfer_to_leafc_patch(p)*dt
@@ -307,11 +289,11 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
end do
end if
- ! phenology: litterfall fluxes
+ ! phenology: litterfall fluxes
cs_veg%leafc_patch(p) = cs_veg%leafc_patch(p) - cf_veg%leafc_to_litter_patch(p)*dt
cs_veg%frootc_patch(p) = cs_veg%frootc_patch(p) - cf_veg%frootc_to_litter_patch(p)*dt
- ! livewood turnover fluxes
+ ! livewood turnover fluxes
if (woody(ivt(p)) == 1._r8) then
cs_veg%livestemc_patch(p) = cs_veg%livestemc_patch(p) - cf_veg%livestemc_to_deadstemc_patch(p)*dt
cs_veg%deadstemc_patch(p) = cs_veg%deadstemc_patch(p) + cf_veg%livestemc_to_deadstemc_patch(p)*dt
@@ -337,55 +319,57 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
- (cf_veg%repr_structurec_to_cropprod_patch(p,k) + cf_veg%repr_structurec_to_litter_patch(p,k))*dt
end do
end if
- !
- ! For the matrix solution the actual state update comes after the matrix
- ! multiply in VegMatrix, but the matrix needs to be setup with
- ! the equivalent of above. Those changes can be here or in the
- ! native subroutines dealing with that field
- !
- else
- ! NOTE: Changes for above that apply for matrix code are in CNPhenology EBK (11/26/2019)
-
- ! This part below MUST match exactly the code for the non-matrix part
- ! above!
- end if !not use_matrixcn
+ else
+ ! NOTE: Changes for above that apply for matrix code are in CNPhenology EBK (11/26/2019)
+
+ ! This part below MUST match exactly the code for the non-matrix part
+ ! above!
+ if (ivt(p) >= npcropmin) then
+ cs_veg%cropseedc_deficit_patch(p) = cs_veg%cropseedc_deficit_patch(p) &
+ - cf_veg%crop_seedc_to_leaf_patch(p) * dt
+ do k = repr_grain_min, repr_grain_max
+ cs_veg%cropseedc_deficit_patch(p) = cs_veg%cropseedc_deficit_patch(p) &
+ + cf_veg%repr_grainc_to_seed_patch(p,k) * dt
+ end do
+ end if
+ end if !not use_matrixcn
- check_cpool = cs_veg%cpool_patch(p)- cf_veg%psnsun_to_cpool_patch(p)*dt-cf_veg%psnshade_to_cpool_patch(p)*dt
- cpool_delta = cs_veg%cpool_patch(p)
+ check_cpool = cs_veg%cpool_patch(p)- cf_veg%psnsun_to_cpool_patch(p)*dt-cf_veg%psnshade_to_cpool_patch(p)*dt
+ cpool_delta = cs_veg%cpool_patch(p)
- ! maintenance respiration fluxes from cpool
+ ! maintenance respiration fluxes from cpool
- cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_xsmrpool_patch(p)*dt
- cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%leaf_curmr_patch(p)*dt
- cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%froot_curmr_patch(p)*dt
- If (woody(ivt(p)) == 1._r8) then
+ cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_xsmrpool_patch(p)*dt
+ cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%leaf_curmr_patch(p)*dt
+ cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%froot_curmr_patch(p)*dt
+ If (woody(ivt(p)) == 1._r8) then
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%livestem_curmr_patch(p)*dt
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%livecroot_curmr_patch(p)*dt
- end if
- if (ivt(p) >= npcropmin) then ! skip 2 generic crops
+ end if
+ if (ivt(p) >= npcropmin) then ! skip 2 generic crops
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%livestem_curmr_patch(p)*dt
do k = 1, nrepr
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%reproductive_curmr_patch(p,k)*dt
end do
- end if
+ end if
- cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_resp_patch(p)*dt
+ cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_resp_patch(p)*dt
- !RF Add in the carbon spent on uptake respiration.
- cs_veg%cpool_patch(p)= cs_veg%cpool_patch(p) - cf_veg%soilc_change_patch(p)*dt
+ !RF Add in the carbon spent on uptake respiration.
+ cs_veg%cpool_patch(p)= cs_veg%cpool_patch(p) - cf_veg%soilc_change_patch(p)*dt
- ! maintenance respiration fluxes from xsmrpool
- cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) + cf_veg%cpool_to_xsmrpool_patch(p)*dt
- cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) - cf_veg%leaf_xsmr_patch(p)*dt
- cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) - cf_veg%froot_xsmr_patch(p)*dt
- if (woody(ivt(p)) == 1._r8) then
+ ! maintenance respiration fluxes from xsmrpool
+ cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) + cf_veg%cpool_to_xsmrpool_patch(p)*dt
+ cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) - cf_veg%leaf_xsmr_patch(p)*dt
+ cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) - cf_veg%froot_xsmr_patch(p)*dt
+ if (woody(ivt(p)) == 1._r8) then
cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) - cf_veg%livestem_xsmr_patch(p)*dt
cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) - cf_veg%livecroot_xsmr_patch(p)*dt
- end if
+ end if
- ! allocation fluxes
- if (carbon_resp_opt == 1) then
+ ! allocation fluxes
+ if (carbon_resp_opt == 1) then
cf_veg%cpool_to_leafc_patch(p) = cf_veg%cpool_to_leafc_patch(p) - cf_veg%cpool_to_leafc_resp_patch(p)
cf_veg%cpool_to_leafc_storage_patch(p) = cf_veg%cpool_to_leafc_storage_patch(p) - &
cf_veg%cpool_to_leafc_storage_resp_patch(p)
@@ -397,20 +381,11 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_leafc_storage_patch(p)*dt
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_frootc_patch(p)*dt
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_frootc_storage_patch(p)*dt
- !
- ! State update without the matrix solution
- !
- if(.not. use_matrixcn) then
+ if(.not. use_matrixcn) then
cs_veg%leafc_patch(p) = cs_veg%leafc_patch(p) + cf_veg%cpool_to_leafc_patch(p)*dt
cs_veg%leafc_storage_patch(p) = cs_veg%leafc_storage_patch(p) + cf_veg%cpool_to_leafc_storage_patch(p)*dt
cs_veg%frootc_patch(p) = cs_veg%frootc_patch(p) + cf_veg%cpool_to_frootc_patch(p)*dt
cs_veg%frootc_storage_patch(p) = cs_veg%frootc_storage_patch(p) + cf_veg%cpool_to_frootc_storage_patch(p)*dt
- !
- ! For the matrix solution the actual state update comes after the matrix
- ! multiply in VegMatrix, but the matrix needs to be setup with
- ! the equivalent of above. Those changes can be here or in the
- ! native subroutines dealing with that field
- !
else
! NOTE: The equivalent changes for matrix code are in CNPhenology EBK (11/26/2019)
end if !not use_matrixcn
@@ -431,9 +406,6 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_livecrootc_storage_patch(p)*dt
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_deadcrootc_patch(p)*dt
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_deadcrootc_storage_patch(p)*dt
- !
- ! State update without the matrix solution
- !
if(.not. use_matrixcn)then
cs_veg%livestemc_patch(p) = cs_veg%livestemc_patch(p) + cf_veg%cpool_to_livestemc_patch(p)*dt
cs_veg%livestemc_storage_patch(p) = cs_veg%livestemc_storage_patch(p) + cf_veg%cpool_to_livestemc_storage_patch(p)*dt
@@ -443,12 +415,6 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
cs_veg%livecrootc_storage_patch(p) = cs_veg%livecrootc_storage_patch(p) + cf_veg%cpool_to_livecrootc_storage_patch(p)*dt
cs_veg%deadcrootc_patch(p) = cs_veg%deadcrootc_patch(p) + cf_veg%cpool_to_deadcrootc_patch(p)*dt
cs_veg%deadcrootc_storage_patch(p) = cs_veg%deadcrootc_storage_patch(p) + cf_veg%cpool_to_deadcrootc_storage_patch(p)*dt
- !
- ! For the matrix solution the actual state update comes after the matrix
- ! multiply in VegMatrix, but the matrix needs to be setup with
- ! the equivalent of above. Those changes can be here or in the
- ! native subroutines dealing with that field
- !
else
! NOTE: The equivalent changes for matrix code are in CNPhenology EBK (11/26/2019)
end if !not use_matrixcn
@@ -465,9 +431,6 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_reproductivec_patch(p,k)*dt
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_reproductivec_storage_patch(p,k)*dt
end do
- !
- ! State update without the matrix solution
- !
if(.not. use_matrixcn)then
cs_veg%livestemc_patch(p) = cs_veg%livestemc_patch(p) + cf_veg%cpool_to_livestemc_patch(p)*dt
cs_veg%livestemc_storage_patch(p) = cs_veg%livestemc_storage_patch(p) + cf_veg%cpool_to_livestemc_storage_patch(p)*dt
@@ -477,12 +440,6 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
cs_veg%reproductivec_storage_patch(p,k) = cs_veg%reproductivec_storage_patch(p,k) &
+ cf_veg%cpool_to_reproductivec_storage_patch(p,k)*dt
end do
- !
- ! For the matrix solution the actual state update comes after the matrix
- ! multiply in VegMatrix, but the matrix needs to be setup with
- ! the equivalent of above. Those changes can be here or in the
- ! native subroutines dealing with that field
- !
else
! NOTE: The equivalent changes for matrix code are in CNPhenology EBK (11/26/2019)
end if !not use_matrixcn
@@ -545,30 +502,17 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
cs_veg%gresp_storage_patch(p) = cs_veg%gresp_storage_patch(p) + cf_veg%cpool_to_gresp_storage_patch(p)*dt
! move storage pools into transfer pools
-
- !
- ! State update without the matrix solution
- !
- if(.not. use_matrixcn)then
- cs_veg%leafc_storage_patch(p) = cs_veg%leafc_storage_patch(p) - cf_veg%leafc_storage_to_xfer_patch(p)*dt
- cs_veg%leafc_xfer_patch(p) = cs_veg%leafc_xfer_patch(p) + cf_veg%leafc_storage_to_xfer_patch(p)*dt
- cs_veg%frootc_storage_patch(p) = cs_veg%frootc_storage_patch(p) - cf_veg%frootc_storage_to_xfer_patch(p)*dt
- cs_veg%frootc_xfer_patch(p) = cs_veg%frootc_xfer_patch(p) + cf_veg%frootc_storage_to_xfer_patch(p)*dt
- !
- ! For the matrix solution the actual state update comes after the matrix
- ! multiply in VegMatrix, but the matrix needs to be setup with
- ! the equivalent of above. Those changes can be here or in the
- ! native subroutines dealing with that field
- !
+ if(.not. use_matrixcn)then
+ cs_veg%leafc_storage_patch(p) = cs_veg%leafc_storage_patch(p) - cf_veg%leafc_storage_to_xfer_patch(p)*dt
+ cs_veg%leafc_xfer_patch(p) = cs_veg%leafc_xfer_patch(p) + cf_veg%leafc_storage_to_xfer_patch(p)*dt
+ cs_veg%frootc_storage_patch(p) = cs_veg%frootc_storage_patch(p) - cf_veg%frootc_storage_to_xfer_patch(p)*dt
+ cs_veg%frootc_xfer_patch(p) = cs_veg%frootc_xfer_patch(p) + cf_veg%frootc_storage_to_xfer_patch(p)*dt
else
- ! NOTE: The equivalent changes for matrix code are in CNPhenology EBK (11/26/2019)
+ ! NOTE: The equivalent changes for matrix code are in CNPhenology EBK (11/26/2019)
end if !not use_matrixcn
if (woody(ivt(p)) == 1._r8) then
cs_veg%gresp_storage_patch(p) = cs_veg%gresp_storage_patch(p) - cf_veg%gresp_storage_to_xfer_patch(p)*dt
cs_veg%gresp_xfer_patch(p) = cs_veg%gresp_xfer_patch(p) + cf_veg%gresp_storage_to_xfer_patch(p)*dt
- !
- ! State update without the matrix solution
- !
if(.not. use_matrixcn)then
cs_veg%livestemc_storage_patch(p) = cs_veg%livestemc_storage_patch(p) - cf_veg%livestemc_storage_to_xfer_patch(p)*dt
cs_veg%livestemc_xfer_patch(p) = cs_veg%livestemc_xfer_patch(p) + cf_veg%livestemc_storage_to_xfer_patch(p)*dt
@@ -578,21 +522,12 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
cs_veg%livecrootc_xfer_patch(p) = cs_veg%livecrootc_xfer_patch(p) + cf_veg%livecrootc_storage_to_xfer_patch(p)*dt
cs_veg%deadcrootc_storage_patch(p) = cs_veg%deadcrootc_storage_patch(p)- cf_veg%deadcrootc_storage_to_xfer_patch(p)*dt
cs_veg%deadcrootc_xfer_patch(p) = cs_veg%deadcrootc_xfer_patch(p) + cf_veg%deadcrootc_storage_to_xfer_patch(p)*dt
- !
- ! For the matrix solution the actual state update comes after the matrix
- ! multiply in VegMatrix, but the matrix needs to be setup with
- ! the equivalent of above. Those changes can be here or in the
- ! native subroutines dealing with that field
- !
else
! NOTE: The equivalent changes for matrix code are in CNPhenology EBK (11/26/2019)
end if !not use_matrixcn
end if
if (ivt(p) >= npcropmin) then ! skip 2 generic crops
! lines here for consistency; the transfer terms are zero
- !
- ! State update without the matrix solution
- !
if(.not. use_matrixcn)then
! lines here for consistency; the transfer terms are zero
cs_veg%livestemc_storage_patch(p) = cs_veg%livestemc_storage_patch(p) - cf_veg%livestemc_storage_to_xfer_patch(p)*dt
@@ -603,12 +538,6 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
cs_veg%reproductivec_xfer_patch(p,k) = cs_veg%reproductivec_xfer_patch(p,k) &
+ cf_veg%reproductivec_storage_to_xfer_patch(p,k)*dt
end do
- !
- ! For the matrix solution the actual state update comes after the matrix
- ! multiply in VegMatrix, but the matrix needs to be setup with
- ! the equivalent of above. Those changes can be here or in the
- ! native subroutines dealing with that field
- !
else
! NOTE: The equivalent changes for matrix code are in CNPhenology EBK (11/26/2019)
end if !not use_matrixcn
@@ -631,15 +560,14 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
! bounds. Zeroing out these small pools and putting them into the flux to the
! atmosphere solved many of the crop isotope problems
- ! Instantly release XSMRPOOL to atmosphere
if ( .not. dribble_crophrv_xsmrpool_2atm ) then
cf_veg%xsmrpool_to_atm_patch(p) = cf_veg%xsmrpool_to_atm_patch(p) + cs_veg%xsmrpool_patch(p)/dt
cf_veg%xsmrpool_to_atm_patch(p) = cf_veg%xsmrpool_to_atm_patch(p) + cs_veg%cpool_patch(p)/dt
- !
- ! State update without the matrix solution
- !
if(.not. use_matrixcn)then
cf_veg%xsmrpool_to_atm_patch(p) = cf_veg%xsmrpool_to_atm_patch(p) + cs_veg%frootc_patch(p)/dt
+ else
+ cf_veg%xsmrpool_to_atm_patch(p) = cf_veg%xsmrpool_to_atm_patch(p) &
+ + cs_veg%frootc_patch(p) * matrix_update_phc(p,cf_veg%ifroot_to_iout_ph,1._r8/dt,dt,cnveg_carbonflux_inst,.true.,.true.)
end if
! Save xsmrpool, cpool, frootc to loss state variable for
! dribbling
@@ -650,16 +578,13 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
cs_veg%xsmrpool_loss_patch(p) = cs_veg%xsmrpool_loss_patch(p) + &
cs_veg%xsmrpool_patch(p) + &
cs_veg%cpool_patch(p)
- !
- ! State update without the matrix solution
- !
if(.not. use_matrixcn)then
cs_veg%xsmrpool_loss_patch(p) = cs_veg%xsmrpool_loss_patch(p) + cs_veg%frootc_patch(p)
+ else
+ cs_veg%xsmrpool_loss_patch(p) = cs_veg%xsmrpool_loss_patch(p) &
+ + cs_veg%frootc_patch(p) * matrix_update_phc(p,cf_veg%ifroot_to_iout_ph,1._r8/dt,dt,cnveg_carbonflux_inst,.true.,.true.)
end if
end if
- !
- ! State update without the matrix solution
- !
if (.not. use_matrixcn) then
cs_veg%frootc_patch(p) = 0._r8
end if
@@ -675,7 +600,6 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
cs_veg%xsmrpool_loss_patch(p) = cs_veg%xsmrpool_loss_patch(p) - cf_veg%xsmrpool_to_atm_patch(p) * dt
end if
end if
-
end do soilpatch_loop ! end of patch loop
end associate
diff --git a/src/biogeochem/CNCStateUpdate2Mod.F90 b/src/biogeochem/CNCStateUpdate2Mod.F90
index 6ecc4893e3..5fb7a283e9 100644
--- a/src/biogeochem/CNCStateUpdate2Mod.F90
+++ b/src/biogeochem/CNCStateUpdate2Mod.F90
@@ -97,9 +97,13 @@ subroutine CStateUpdate2(num_soilc, filter_soilc, num_soilp, filter_soilp, &
else
! Match above for soil-matrix
do i = i_litr_min, i_litr_max
+ cf_soil%matrix_Cinput%V(c,j+(i-1)*nlevdecomp) = &
+ cf_soil%matrix_Cinput%V(c,j+(i-1)*nlevdecomp) + cf_veg%gap_mortality_c_to_litr_c_col(c,j,i) * dt
end do
! Currently i_cwd .ne. i_litr_max + 1 if .not. fates and
! i_cwd = 0 if fates, so not including in the i-loop
+ cf_soil%matrix_Cinput%V(c,j+(i_cwd-1)*nlevdecomp) = &
+ cf_soil%matrix_Cinput%V(c,j+(i_cwd-1)*nlevdecomp) + cf_veg%gap_mortality_c_to_cwdc_col(c,j) * dt
end if !soil_matrix
end do
end do
@@ -237,9 +241,13 @@ subroutine CStateUpdate2h(num_soilc, filter_soilc, num_soilp, filter_soilp, &
else
! Match above for matrix method
do i = i_litr_min, i_litr_max
+ cf_soil%matrix_Cinput%V(c,j+(i-1)*nlevdecomp) = &
+ cf_soil%matrix_Cinput%V(c,j+(i-1)*nlevdecomp) + cf_veg%harvest_c_to_litr_c_col(c,j,i) * dt
end do
! Currently i_cwd .ne. i_litr_max + 1 if .not. fates and
! i_cwd = 0 if fates, so not including in the i-loop
+ cf_soil%matrix_Cinput%V(c,j+(i_cwd-1)*nlevdecomp) = &
+ cf_soil%matrix_Cinput%V(c,j+(i_cwd-1)*nlevdecomp) + cf_veg%harvest_c_to_cwdc_col(c,j) * dt
end if
! wood to product pools - states updated in CNProducts
@@ -327,7 +335,8 @@ end subroutine CStateUpdate2h
!-----------------------------------------------------------------------
subroutine CStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, &
- cnveg_carbonflux_inst, cnveg_carbonstate_inst, soilbiogeochem_carbonstate_inst)
+ cnveg_carbonflux_inst, cnveg_carbonstate_inst, &
+ soilbiogeochem_carbonstate_inst, soilbiogeochem_carbonflux_inst)
!
! !DESCRIPTION:
! Update all the prognostic carbon state
@@ -340,6 +349,7 @@ subroutine CStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, &
integer , intent(in) :: filter_soilp(:) ! filter for soil patches
type(cnveg_carbonflux_type) , intent(in) :: cnveg_carbonflux_inst
type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst
+ type(soilbiogeochem_carbonflux_type) , intent(inout) :: soilbiogeochem_carbonflux_inst
type(soilbiogeochem_carbonstate_type) , intent(inout) :: soilbiogeochem_carbonstate_inst
!
! !LOCAL VARIABLES:
@@ -351,6 +361,7 @@ subroutine CStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, &
associate( &
cf_veg => cnveg_carbonflux_inst , &
cs_veg => cnveg_carbonstate_inst , &
+ cf_soil => soilbiogeochem_carbonflux_inst, &
cs_soil => soilbiogeochem_carbonstate_inst &
)
@@ -362,15 +373,27 @@ subroutine CStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, &
do fc = 1,num_soilc
c = filter_soilc(fc)
- ! column gross unrepresented landcover change fluxes
- do i = i_litr_min, i_litr_max
- cs_soil%decomp_cpools_vr_col(c,j,i) = &
- cs_soil%decomp_cpools_vr_col(c,j,i) + cf_veg%gru_c_to_litr_c_col(c,j,i) * dt
- end do
- cs_soil%decomp_cpools_vr_col(c,j,i_cwd) = &
- cs_soil%decomp_cpools_vr_col(c,j,i_cwd) + cf_veg%gru_c_to_cwdc_col(c,j) * dt
+ if (.not. use_soil_matrixcn)then
+ ! column gross unrepresented landcover change fluxes
+ do i = i_litr_min, i_litr_max
+ cs_soil%decomp_cpools_vr_col(c,j,i) = &
+ cs_soil%decomp_cpools_vr_col(c,j,i) + cf_veg%gru_c_to_litr_c_col(c,j,i) * dt
+ end do
+ cs_soil%decomp_cpools_vr_col(c,j,i_cwd) = &
+ cs_soil%decomp_cpools_vr_col(c,j,i_cwd) + cf_veg%gru_c_to_cwdc_col(c,j) * dt
- ! wood to product pools - states updated in CNProducts
+ ! wood to product pools - states updated in CNProducts
+ else
+ ! Match above for soil-matrix
+ do i = i_litr_min, i_litr_max
+ cf_soil%matrix_Cinput%V(c,j+(i-1)*nlevdecomp) = &
+ cf_soil%matrix_Cinput%V(c,j+(i-1)*nlevdecomp) + cf_veg%gru_c_to_litr_c_col(c,j,i) * dt
+ end do
+ ! Currently i_cwd .ne. i_litr_max + 1 if .not. fates and
+ ! i_cwd = 0 if fates, so not including in the i-loop
+ cf_soil%matrix_Cinput%V(c,j+(i_cwd-1)*nlevdecomp) = &
+ cf_soil%matrix_Cinput%V(c,j+(i_cwd-1)*nlevdecomp) + cf_veg%gru_c_to_cwdc_col(c,j) * dt
+ end if !soil_matrix
end do
end do
@@ -378,59 +401,69 @@ subroutine CStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, &
do fp = 1,num_soilp
p = filter_soilp(fp)
- ! patch-level carbon fluxes from gross unrepresented landcover change mortality
- ! displayed pools
- cs_veg%leafc_patch(p) = cs_veg%leafc_patch(p) &
- - cf_veg%gru_leafc_to_litter_patch(p) * dt
- cs_veg%frootc_patch(p) = cs_veg%frootc_patch(p) &
- - cf_veg%gru_frootc_to_litter_patch(p) * dt
- cs_veg%livestemc_patch(p) = cs_veg%livestemc_patch(p) &
- - cf_veg%gru_livestemc_to_atm_patch(p) * dt
- cs_veg%deadstemc_patch(p) = cs_veg%deadstemc_patch(p) &
- - cf_veg%gru_deadstemc_to_atm_patch(p) * dt
- cs_veg%deadstemc_patch(p) = cs_veg%deadstemc_patch(p) &
- - cf_veg%gru_wood_productc_gain_patch(p) * dt
- cs_veg%livecrootc_patch(p) = cs_veg%livecrootc_patch(p) &
- - cf_veg%gru_livecrootc_to_litter_patch(p) * dt
- cs_veg%deadcrootc_patch(p) = cs_veg%deadcrootc_patch(p) &
- - cf_veg%gru_deadcrootc_to_litter_patch(p) * dt
-
! xsmrpool
- cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) &
+ cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) &
- cf_veg%gru_xsmrpool_to_atm_patch(p) * dt
-
- ! storage pools
- cs_veg%leafc_storage_patch(p) = cs_veg%leafc_storage_patch(p) &
- - cf_veg%gru_leafc_storage_to_atm_patch(p) * dt
- cs_veg%frootc_storage_patch(p) = cs_veg%frootc_storage_patch(p) &
- - cf_veg%gru_frootc_storage_to_atm_patch(p) * dt
- cs_veg%livestemc_storage_patch(p) = cs_veg%livestemc_storage_patch(p) &
- - cf_veg%gru_livestemc_storage_to_atm_patch(p) * dt
- cs_veg%deadstemc_storage_patch(p) = cs_veg%deadstemc_storage_patch(p) &
- - cf_veg%gru_deadstemc_storage_to_atm_patch(p) * dt
- cs_veg%livecrootc_storage_patch(p) = cs_veg%livecrootc_storage_patch(p) &
- - cf_veg%gru_livecrootc_storage_to_atm_patch(p) * dt
- cs_veg%deadcrootc_storage_patch(p) = cs_veg%deadcrootc_storage_patch(p) &
- - cf_veg%gru_deadcrootc_storage_to_atm_patch(p) * dt
- cs_veg%gresp_storage_patch(p) = cs_veg%gresp_storage_patch(p) &
+ ! gresp storage pool
+ cs_veg%gresp_storage_patch(p) = cs_veg%gresp_storage_patch(p) &
- cf_veg%gru_gresp_storage_to_atm_patch(p) * dt
-
- ! transfer pools
- cs_veg%leafc_xfer_patch(p) = cs_veg%leafc_xfer_patch(p) &
- - cf_veg%gru_leafc_xfer_to_atm_patch(p) * dt
- cs_veg%frootc_xfer_patch(p) = cs_veg%frootc_xfer_patch(p) &
- - cf_veg%gru_frootc_xfer_to_atm_patch(p) * dt
- cs_veg%livestemc_xfer_patch(p) = cs_veg%livestemc_xfer_patch(p) &
- - cf_veg%gru_livestemc_xfer_to_atm_patch(p) * dt
- cs_veg%deadstemc_xfer_patch(p) = cs_veg%deadstemc_xfer_patch(p) &
- - cf_veg%gru_deadstemc_xfer_to_atm_patch(p) * dt
- cs_veg%livecrootc_xfer_patch(p) = cs_veg%livecrootc_xfer_patch(p) &
- - cf_veg%gru_livecrootc_xfer_to_atm_patch(p) * dt
- cs_veg%deadcrootc_xfer_patch(p) = cs_veg%deadcrootc_xfer_patch(p) &
- - cf_veg%gru_deadcrootc_xfer_to_atm_patch(p) * dt
- cs_veg%gresp_xfer_patch(p) = cs_veg%gresp_xfer_patch(p) &
+ ! gresp transfer pool
+ cs_veg%gresp_xfer_patch(p) = cs_veg%gresp_xfer_patch(p) &
- cf_veg%gru_gresp_xfer_to_atm_patch(p) * dt
+ ! patch-level carbon fluxes from gross unrepresented landcover change mortality
+ !
+ ! State update without the matrix solution
+ !
+ if(.not. use_matrixcn)then
+ ! displayed pools
+ cs_veg%leafc_patch(p) = cs_veg%leafc_patch(p) &
+ - cf_veg%gru_leafc_to_litter_patch(p) * dt
+ cs_veg%frootc_patch(p) = cs_veg%frootc_patch(p) &
+ - cf_veg%gru_frootc_to_litter_patch(p) * dt
+ cs_veg%livestemc_patch(p) = cs_veg%livestemc_patch(p) &
+ - cf_veg%gru_livestemc_to_atm_patch(p) * dt
+ cs_veg%deadstemc_patch(p) = cs_veg%deadstemc_patch(p) &
+ - cf_veg%gru_deadstemc_to_atm_patch(p) * dt
+ cs_veg%deadstemc_patch(p) = cs_veg%deadstemc_patch(p) &
+ - cf_veg%gru_wood_productc_gain_patch(p) * dt
+ cs_veg%livecrootc_patch(p) = cs_veg%livecrootc_patch(p) &
+ - cf_veg%gru_livecrootc_to_litter_patch(p) * dt
+ cs_veg%deadcrootc_patch(p) = cs_veg%deadcrootc_patch(p) &
+ - cf_veg%gru_deadcrootc_to_litter_patch(p) * dt
+
+ ! storage pools
+ cs_veg%leafc_storage_patch(p) = cs_veg%leafc_storage_patch(p) &
+ - cf_veg%gru_leafc_storage_to_atm_patch(p) * dt
+ cs_veg%frootc_storage_patch(p) = cs_veg%frootc_storage_patch(p) &
+ - cf_veg%gru_frootc_storage_to_atm_patch(p) * dt
+ cs_veg%livestemc_storage_patch(p) = cs_veg%livestemc_storage_patch(p) &
+ - cf_veg%gru_livestemc_storage_to_atm_patch(p) * dt
+ cs_veg%deadstemc_storage_patch(p) = cs_veg%deadstemc_storage_patch(p) &
+ - cf_veg%gru_deadstemc_storage_to_atm_patch(p) * dt
+ cs_veg%livecrootc_storage_patch(p) = cs_veg%livecrootc_storage_patch(p) &
+ - cf_veg%gru_livecrootc_storage_to_atm_patch(p) * dt
+ cs_veg%deadcrootc_storage_patch(p) = cs_veg%deadcrootc_storage_patch(p) &
+ - cf_veg%gru_deadcrootc_storage_to_atm_patch(p) * dt
+
+ ! transfer pools
+ cs_veg%leafc_xfer_patch(p) = cs_veg%leafc_xfer_patch(p) &
+ - cf_veg%gru_leafc_xfer_to_atm_patch(p) * dt
+ cs_veg%frootc_xfer_patch(p) = cs_veg%frootc_xfer_patch(p) &
+ - cf_veg%gru_frootc_xfer_to_atm_patch(p) * dt
+ cs_veg%livestemc_xfer_patch(p) = cs_veg%livestemc_xfer_patch(p) &
+ - cf_veg%gru_livestemc_xfer_to_atm_patch(p) * dt
+ cs_veg%deadstemc_xfer_patch(p) = cs_veg%deadstemc_xfer_patch(p) &
+ - cf_veg%gru_deadstemc_xfer_to_atm_patch(p) * dt
+ cs_veg%livecrootc_xfer_patch(p) = cs_veg%livecrootc_xfer_patch(p) &
+ - cf_veg%gru_livecrootc_xfer_to_atm_patch(p) * dt
+ cs_veg%deadcrootc_xfer_patch(p) = cs_veg%deadcrootc_xfer_patch(p) &
+ - cf_veg%gru_deadcrootc_xfer_to_atm_patch(p) * dt
+
+ else
+ ! NB (slevis) The matrix equivalent of the above is in
+ ! dynGrossUnrepMod::CNGrossUnrep*
+ end if
end do ! end of patch loop
end associate
diff --git a/src/biogeochem/CNCStateUpdate3Mod.F90 b/src/biogeochem/CNCStateUpdate3Mod.F90
index 55d647866f..4b4d41fbe3 100644
--- a/src/biogeochem/CNCStateUpdate3Mod.F90
+++ b/src/biogeochem/CNCStateUpdate3Mod.F90
@@ -92,9 +92,12 @@ subroutine CStateUpdate3( num_soilc, filter_soilc, num_soilp, filter_soilp, &
else
! Match above for matrix terms
! patch-level wood to column-level CWD (uncombusted wood)
-
+ cf_soil%matrix_Cinput%V(c,j+(i_cwd-1)*nlevdecomp) = cf_soil%matrix_Cinput%V(c,j+(i_cwd-1)*nlevdecomp) + &
+ cf_veg%fire_mortality_c_to_cwdc_col(c,j) * dt
! patch-level wood to column-level litter (uncombusted wood)
do i = i_litr_min, i_litr_max
+ cf_soil%matrix_Cinput%V(c,j+(i-1)*nlevdecomp) = cf_soil%matrix_Cinput%V(c,j+(i-1)*nlevdecomp) + &
+ cf_veg%m_c_to_litr_fire_col(c,j,i)* dt
end do
end if
end do
diff --git a/src/biogeochem/CNDVType.F90 b/src/biogeochem/CNDVType.F90
index 19a0f64f7d..fb6b3d9753 100644
--- a/src/biogeochem/CNDVType.F90
+++ b/src/biogeochem/CNDVType.F90
@@ -439,7 +439,7 @@ subroutine UpdateAccVars(this, bounds, t_a10_patch, t_ref2m_patch)
use shr_const_mod , only : SHR_CONST_CDAY, SHR_CONST_TKFRZ
use clm_time_manager , only : get_step_size, get_nstep, get_curr_date
use pftconMod , only : ndllf_dcd_brl_tree
- use accumulMod , only : update_accum_field, extract_accum_field, accumResetVal
+ use accumulMod , only : update_accum_field, extract_accum_field, markreset_accum_field
!
! !ARGUMENTS:
class(dgvs_type) , intent(inout) :: this
@@ -489,25 +489,34 @@ subroutine UpdateAccVars(this, bounds, t_a10_patch, t_ref2m_patch)
! Accumulate and extract AGDDTW (gdd base twmax, which is 23 deg C
! for boreal woody patches)
+ ! SSR 2024-06-07: Don't wrap this do-loop in an "if it's not time to reset." Behavior would
+ ! be identical for now, but if "missed update" behavior is fixed (see ESCOMP/CTSM#2585), you
+ ! would end up updating AGDDTW with uninitialized values.
do p = begp,endp
rbufslp(p) = max(0._r8, &
(t_a10_patch(p) - SHR_CONST_TKFRZ - dgv_ecophyscon%twmax(ndllf_dcd_brl_tree)) &
* dtime/SHR_CONST_CDAY)
- if (month==1 .and. day==1 .and. secs==int(dtime)) rbufslp(p) = accumResetVal
end do
+ if (month==1 .and. day==1 .and. secs==int(dtime)) then
+ ! Reset annually
+ call markreset_accum_field('AGDDTW')
+ end if
call update_accum_field ('AGDDTW', rbufslp, nstep)
call extract_accum_field ('AGDDTW', this%agddtw_patch, nstep)
! Accumulate and extract AGDD
+ ! SSR 2024-06-07: Don't wrap this do-loop in an "if it's not time to reset." Behavior would
+ ! be identical for now, but if "missed update" behavior is fixed (see ESCOMP/CTSM#2585), you
+ ! would end up updating AGDD with uninitialized values.
do p = begp,endp
rbufslp(p) = max(0.0_r8, &
(t_ref2m_patch(p) - (SHR_CONST_TKFRZ + 5.0_r8)) * dtime/SHR_CONST_CDAY)
- !
- ! Fix (for bug 1858) from Sam Levis to reset the annual AGDD variable
- !
- if (month==1 .and. day==1 .and. secs==int(dtime)) rbufslp(p) = accumResetVal
end do
+ if (month==1 .and. day==1 .and. secs==int(dtime)) then
+ ! Reset annually
+ call markreset_accum_field('AGDD')
+ end if
call update_accum_field ('AGDD', rbufslp, nstep)
call extract_accum_field ('AGDD', this%agdd_patch, nstep)
diff --git a/src/biogeochem/CNDriverMod.F90 b/src/biogeochem/CNDriverMod.F90
index b23019eb23..c5deb1e86a 100644
--- a/src/biogeochem/CNDriverMod.F90
+++ b/src/biogeochem/CNDriverMod.F90
@@ -6,12 +6,12 @@ module CNDriverMod
!
! !USES:
use shr_kind_mod , only : r8 => shr_kind_r8
- use clm_varctl , only : use_c13, use_c14, use_fates, use_fates_bgc, use_dynroot
+ use clm_varctl , only : use_c13, use_c14, use_fates, use_fates_bgc
use dynSubgridControlMod , only : get_do_harvest, get_do_grossunrep
use decompMod , only : bounds_type
use perf_mod , only : t_startf, t_stopf
use clm_varctl , only : use_nitrif_denitrif, use_nguardrail
- use clm_varctl , only : iulog, use_crop, use_crop_agsys, use_cn
+ use clm_varctl , only : use_crop, use_crop_agsys, use_cn
use SoilBiogeochemDecompCascadeConType, only : mimics_decomp, century_decomp, decomp_method
use CNSharedParamsMod , only : use_fun
use CNVegStateType , only : cnveg_state_type
@@ -85,7 +85,7 @@ end subroutine CNDriverInit
!-----------------------------------------------------------------------
subroutine CNDriverNoLeaching(bounds, &
- num_bgc_soilc, filter_bgc_soilc, num_bgc_vegp, filter_bgc_vegp, &
+ num_bgc_soilc, filter_bgc_soilc, num_bgc_vegp, filter_bgc_vegp, &
num_pcropp, filter_pcropp, num_soilnopcropp, filter_soilnopcropp, &
num_actfirec, filter_actfirec, num_actfirep, filter_actfirep, &
num_exposedvegp, filter_exposedvegp, num_noexposedvegp, filter_noexposedvegp, &
@@ -103,8 +103,8 @@ subroutine CNDriverNoLeaching(bounds,
active_layer_inst, clm_fates, &
atm2lnd_inst, waterstatebulk_inst, waterdiagnosticbulk_inst, waterfluxbulk_inst, &
wateratm2lndbulk_inst, canopystate_inst, soilstate_inst, temperature_inst, &
- soil_water_retention_curve, crop_inst, ch4_inst, &
- dgvs_inst, photosyns_inst, saturated_excess_runoff_inst, energyflux_inst, &
+ soil_water_retention_curve, crop_inst, ch4_inst, &
+ dgvs_inst, photosyns_inst, saturated_excess_runoff_inst, energyflux_inst, &
nutrient_competition_method, cnfire_method, dribble_crophrv_xsmrpool_2atm)
!
! !DESCRIPTION:
@@ -147,7 +147,6 @@ subroutine CNDriverNoLeaching(bounds,
use SoilBiogeochemNitrifDenitrifMod , only: SoilBiogeochemNitrifDenitrif
use SoilBiogeochemNStateUpdate1Mod , only: SoilBiogeochemNStateUpdate1
use NutrientCompetitionMethodMod , only: nutrient_competition_method_type
- use CNRootDynMod , only: CNRootDyn
use CNPrecisionControlMod , only: CNPrecisionControl
!
! !ARGUMENTS:
@@ -564,20 +563,6 @@ subroutine CNDriverNoLeaching(bounds,
call t_stopf('CNGResp')
- !--------------------------------------------
- ! Dynamic Roots
- !--------------------------------------------
-
- if( use_dynroot ) then
- call t_startf('CNRootDyn')
-
- call CNRootDyn(bounds, num_bgc_soilc, filter_bgc_soilc, num_bgc_vegp, filter_bgc_vegp, &
- cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, &
- cnveg_state_inst, crop_inst, soilstate_inst, soilbiogeochem_nitrogenstate_inst)
-
- call t_stopf('CNRootDyn')
- end if
-
!--------------------------------------------------------------------------
! CNUpdate0
! The state updates are still called for the matrix solution (use_matrixn
@@ -609,12 +594,9 @@ subroutine CNDriverNoLeaching(bounds,
c14_cnveg_carbonstate_inst, cnveg_nitrogenstate_inst)
call t_stopf('CNPrecisionControl')
end if
- !--------------------------------------------------------------------------
+ !--------------------------------------------
! Update1
- ! The state updates are still called for the matrix solution (use_matrixn
- ! and use_soil_matrixcn) but most of the state updates are done after
- ! the matrix multiply in VegMatrix and SoilMatrix.
- !--------------------------------------------------------------------------
+ !--------------------------------------------
call t_startf('CNUpdate1')
@@ -830,18 +812,22 @@ subroutine CNDriverNoLeaching(bounds,
end if
call CStateUpdate2g( num_bgc_soilc, filter_bgc_soilc, num_bgc_vegp, filter_bgc_vegp, &
- cnveg_carbonflux_inst, cnveg_carbonstate_inst, soilbiogeochem_carbonstate_inst)
+ cnveg_carbonflux_inst, cnveg_carbonstate_inst, &
+ soilbiogeochem_carbonstate_inst, soilbiogeochem_carbonflux_inst)
if ( use_c13 ) then
call CStateUpdate2g(num_bgc_soilc, filter_bgc_soilc, num_bgc_vegp, filter_bgc_vegp, &
- c13_cnveg_carbonflux_inst, c13_cnveg_carbonstate_inst, c13_soilbiogeochem_carbonstate_inst)
+ c13_cnveg_carbonflux_inst, c13_cnveg_carbonstate_inst, &
+ c13_soilbiogeochem_carbonstate_inst, c13_soilbiogeochem_carbonflux_inst)
end if
if ( use_c14 ) then
call CStateUpdate2g(num_bgc_soilc, filter_bgc_soilc, num_bgc_vegp, filter_bgc_vegp, &
- c14_cnveg_carbonflux_inst, c14_cnveg_carbonstate_inst, c14_soilbiogeochem_carbonstate_inst)
+ c14_cnveg_carbonflux_inst, c14_cnveg_carbonstate_inst, &
+ c14_soilbiogeochem_carbonstate_inst, c14_soilbiogeochem_carbonflux_inst)
end if
call NStateUpdate2g(num_bgc_soilc, filter_bgc_soilc, num_bgc_vegp, filter_bgc_vegp, &
- cnveg_nitrogenflux_inst, cnveg_nitrogenstate_inst, soilbiogeochem_nitrogenstate_inst)
+ cnveg_nitrogenflux_inst, cnveg_nitrogenstate_inst, &
+ soilbiogeochem_nitrogenstate_inst, soilbiogeochem_nitrogenflux_inst)
call t_stopf('CNUpdate2')
@@ -1040,9 +1026,11 @@ subroutine CNDriverLeaching(bounds, &
use SoilBiogeochemNLeachingMod, only: SoilBiogeochemNLeaching
use CNNStateUpdate3Mod , only: NStateUpdate3
use CNNStateUpdate3Mod , only: NStateUpdateLeaching
+ use CNVegMatrixMod , only: CNVegMatrix
+ use CNSoilMatrixMod , only: CNSoilMatrix
use clm_time_manager , only: is_first_step_of_this_run_segment,is_beg_curr_year,is_end_curr_year,get_curr_date
use CNSharedParamsMod , only: use_matrixcn
- use SoilBiogeochemDecompCascadeConType , only : use_soil_matrixcn
+ use SoilBiogeochemDecompCascadeConType, only: use_soil_matrixcn
!
! !ARGUMENTS:
type(bounds_type) , intent(in) :: bounds
@@ -1088,10 +1076,6 @@ subroutine CNDriverLeaching(bounds, &
soilbiogeochem_nitrogenflux_inst, soilbiogeochem_nitrogenstate_inst)
call t_stopf('SoilBiogeochemNLeaching')
-
-
-
-
! Nitrogen state variable update, mortality fluxes.
if(num_bgc_vegp>0)then
call t_startf('NUpdate3')
@@ -1108,14 +1092,23 @@ subroutine CNDriverLeaching(bounds, &
if ( use_matrixcn ) then
call t_startf('CNVMatrix')
- ! Matrix cn code will go here:
- call t_stopf( 'CNVMatrix')
+ call CNVegMatrix(bounds, num_bgc_vegp, filter_bgc_vegp(1:num_bgc_vegp), &
+ num_actfirep, filter_actfirep, cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, &
+ cnveg_carbonflux_inst, cnveg_nitrogenflux_inst, cnveg_state_inst,soilbiogeochem_nitrogenflux_inst, &
+ c13_cnveg_carbonstate_inst, c14_cnveg_carbonstate_inst, c13_cnveg_carbonflux_inst, c14_cnveg_carbonflux_inst)
+ call t_stopf('CNVMatrix')
end if
- if ( use_soil_matrixcn ) then
+ if(use_soil_matrixcn)then
call t_startf('CNSoilMatrix')
- ! Soil Matrix cn code will go here:
- call t_stopf( 'CNSoilMatrix')
+ call CNSoilMatrix(bounds,num_bgc_soilc, filter_bgc_soilc(1:num_bgc_soilc), num_actfirec, filter_actfirec, &
+ cnveg_carbonflux_inst,soilbiogeochem_carbonstate_inst, &
+ soilbiogeochem_carbonflux_inst,soilbiogeochem_state_inst, &
+ cnveg_nitrogenflux_inst, soilbiogeochem_nitrogenflux_inst, &
+ soilbiogeochem_nitrogenstate_inst,c13_soilbiogeochem_carbonstate_inst,&
+ c13_soilbiogeochem_carbonflux_inst,c14_soilbiogeochem_carbonstate_inst,&
+ c14_soilbiogeochem_carbonflux_inst)
+ call t_stopf('CNSoilMatrix')
end if
end subroutine CNDriverLeaching
diff --git a/src/biogeochem/CNFUNMod.F90 b/src/biogeochem/CNFUNMod.F90
index bb750af2fd..dde666c1f7 100644
--- a/src/biogeochem/CNFUNMod.F90
+++ b/src/biogeochem/CNFUNMod.F90
@@ -26,7 +26,7 @@ module CNFUNMod
use pftconMod , only : pftcon, npcropmin
use decompMod , only : bounds_type
use clm_varctl , only : use_nitrif_denitrif,use_flexiblecn
- use CNSharedParamsMod , only : use_matrixcn
+ use CNSharedParamsMod , only : use_matrixcn
use abortutils , only : endrun
use CNVegstateType , only : cnveg_state_type
use CNVegCarbonStateType , only : cnveg_carbonstate_type
@@ -218,6 +218,7 @@ subroutine CNFUN(bounds,num_soilc, filter_soilc,num_soilp&
use PatchType , only : patch
use subgridAveMod , only : p2c
use pftconMod , only : npcropmin
+ use CNVegMatrixMod , only : matrix_update_phn
!
! !ARGUMENTS:
type(bounds_type) , intent(in) :: bounds
@@ -621,6 +622,7 @@ subroutine CNFUN(bounds,num_soilc, filter_soilc,num_soilp&
leafc_change => cnveg_carbonflux_inst%leafc_change_patch , & ! Output: [real(r8)
! (:) ] Used C from the leaf (gC/m2/s)
leafn_storage_to_xfer => cnveg_nitrogenflux_inst%leafn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ]
+ iretransn_to_iout => cnveg_nitrogenflux_inst%iretransn_to_iout_ph , & ! Input: [integer]
plant_ndemand => cnveg_nitrogenflux_inst%plant_ndemand_patch , & ! Iutput: [real(r8) (:)
! ] N flux required to support initial GPP (gN/m2/s)
plant_ndemand_retrans => cnveg_nitrogenflux_inst%plant_ndemand_retrans_patch , & ! Output: [real(r8) (:)
@@ -1451,11 +1453,14 @@ subroutine CNFUN(bounds,num_soilc, filter_soilc,num_soilp&
Npassive(p) = n_passive_acc(p)/dt
Nfix(p) = n_fix_acc_total(p)/dt
retransn_to_npool(p) = n_retrans_acc_total(p)/dt
- ! Without matrix solution
if(.not. use_matrixcn)then
free_retransn_to_npool(p) = free_nretrans(p)/dt
- ! With matrix solution (when it comes in)
else
+ if(retransn(p) .gt. 0)then
+ free_retransn_to_npool(p) = retransn(p) * matrix_update_phn(p,iretransn_to_iout,free_nretrans(p)/dt/retransn(p),dt,cnveg_nitrogenflux_inst,.true.,.true.)
+ else
+ free_retransn_to_npool(p) = 0._r8
+ end if
end if
! this is the N that comes off leaves.
Nretrans(p) = retransn_to_npool(p) + free_retransn_to_npool(p)
diff --git a/src/biogeochem/CNFireBaseMod.F90 b/src/biogeochem/CNFireBaseMod.F90
index f1d488eb22..7cc7750809 100644
--- a/src/biogeochem/CNFireBaseMod.F90
+++ b/src/biogeochem/CNFireBaseMod.F90
@@ -451,6 +451,13 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
use pftconMod , only: nc3crop
use dynSubgridControlMod , only: run_has_transient_landcover
use clm_varpar , only: nlevdecomp_full, ndecomp_pools, nlevdecomp, i_litr_max, i_met_lit
+ use clm_varpar , only: ileaf,ileaf_st,ileaf_xf,ifroot,ifroot_st,ifroot_xf,&
+ ilivestem,ilivestem_st,ilivestem_xf,&
+ ideadstem,ideadstem_st,ideadstem_xf,&
+ ilivecroot,ilivecroot_st,ilivecroot_xf,&
+ ideadcroot,ideadcroot_st,ideadcroot_xf,iretransn,ioutc,ioutn
+ use CNVegMatrixMod , only: matrix_update_fic, matrix_update_fin
+ !
! !ARGUMENTS:
class(cnfire_base_type) :: this
type(bounds_type) , intent(in) :: bounds
@@ -683,7 +690,48 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
m_deadcrootn_xfer_to_litter_fire => cnveg_nitrogenflux_inst%m_deadcrootn_xfer_to_litter_fire_patch , & ! Output: [real(r8) (:) ]
m_retransn_to_litter_fire => cnveg_nitrogenflux_inst%m_retransn_to_litter_fire_patch , & ! Output: [real(r8) (:) ]
m_decomp_npools_to_fire_vr => cnveg_nitrogenflux_inst%m_decomp_npools_to_fire_vr_col , & ! Output: [real(r8) (:,:,:) ] VR decomp. N fire loss (gN/m3/s)
- m_n_to_litr_fire => cnveg_nitrogenflux_inst%m_n_to_litr_fire_col & ! Output: [real(r8) (:,:,:) ]
+ m_n_to_litr_fire => cnveg_nitrogenflux_inst%m_n_to_litr_fire_col , & ! Output: [real(r8) (:,:) ]
+ ileaf_to_iout_fic => cnveg_carbonflux_inst%ileaf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_fic => cnveg_carbonflux_inst%ileafst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_fic => cnveg_carbonflux_inst%ileafxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_fic => cnveg_carbonflux_inst%ifroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_fic => cnveg_carbonflux_inst%ifrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_fic => cnveg_carbonflux_inst%ifrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from fine root transfer pool to outside of vegetation pools
+ ilivestem_to_iout_fic => cnveg_carbonflux_inst%ilivestem_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_fic => cnveg_carbonflux_inst%ilivestemst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem storage pool to outside of vegetation pools
+ ilivestemxf_to_iout_fic => cnveg_carbonflux_inst%ilivestemxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_fic => cnveg_carbonflux_inst%ideadstem_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_fic => cnveg_carbonflux_inst%ideadstemst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_fic => cnveg_carbonflux_inst%ideadstemxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_fic => cnveg_carbonflux_inst%ilivecroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_fic => cnveg_carbonflux_inst%ilivecrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_fic => cnveg_carbonflux_inst%ilivecrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_fic => cnveg_carbonflux_inst%ideadcroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_fic => cnveg_carbonflux_inst%ideadcrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_fic => cnveg_carbonflux_inst%ideadcrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead coarse root transfer pool to outside of vegetation pools
+ ilivestem_to_ideadstem_fic => cnveg_carbonflux_inst%ilivestem_to_ideadstem_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_fic => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root pool to dead coarse root pool
+ ileaf_to_iout_fin => cnveg_nitrogenflux_inst%ileaf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_fin => cnveg_nitrogenflux_inst%ileafst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_fin => cnveg_nitrogenflux_inst%ileafxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_fin => cnveg_nitrogenflux_inst%ifroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_fin => cnveg_nitrogenflux_inst%ifrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_fin => cnveg_nitrogenflux_inst%ifrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from fine transfer pool to outside of vegetation pools
+ ilivestem_to_iout_fin => cnveg_nitrogenflux_inst%ilivestem_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_fin => cnveg_nitrogenflux_inst%ilivestemst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live stem storage pool to outside of vegetation pools
+ ilivestemxf_to_iout_fin => cnveg_nitrogenflux_inst%ilivestemxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_fin => cnveg_nitrogenflux_inst%ideadstem_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_fin => cnveg_nitrogenflux_inst%ideadstemst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_fin => cnveg_nitrogenflux_inst%ideadstemxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_fin => cnveg_nitrogenflux_inst%ilivecroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_fin => cnveg_nitrogenflux_inst%ilivecrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_fin => cnveg_nitrogenflux_inst%ilivecrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_fin => cnveg_nitrogenflux_inst%ideadcroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_fin => cnveg_nitrogenflux_inst%ideadcrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_fin => cnveg_nitrogenflux_inst%ideadcrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead coarse root transfer pool to outside of vegetation pools
+ ilivestem_to_ideadstem_fin => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_fi , & ! Input: [integer (:)] Index of fire related N transfer from live stem to dead stem pool
+ ilivecroot_to_ideadcroot_fin => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_fi , & ! Input: [integer (:)] Index of fire related N transfer from live coarse root pool to dead coarse root pool
+ iretransn_to_iout_fin => cnveg_nitrogenflux_inst%iretransn_to_iout_fi & ! Input: [integer (:)] Index of fire related N transfer from retranslocated N pool to outside of vegetation pools
)
transient_landcover = run_has_transient_landcover()
@@ -696,7 +744,7 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
!
! patch loop
!
- num_actfirep = 0 ! Initialize active fire patch filter to zero
+ num_actfirep = 0
do fp = 1,num_soilp
p = filter_soilp(fp)
c = patch%column(p)
@@ -722,7 +770,6 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
! carbon fluxes
m = spinup_factor_deadwood
- ! For patches with active fire add to active fire filter
if(f /= 0)then
num_actfirep = num_actfirep + 1
filter_actfirep(num_actfirep) = p
@@ -773,6 +820,45 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
m_deadcrootn_storage_to_fire(p) = deadcrootn_storage(p) * f * cc_other(patch%itype(p))
m_retransn_to_fire(p) = retransn(p) * f * cc_other(patch%itype(p))
+ else
+ m_leafc_to_fire(p) = leafc(p) * matrix_update_fic(p,ileaf_to_iout_fic ,f * cc_leaf(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_leafc_storage_to_fire(p) = leafc_storage(p) * matrix_update_fic(p,ileafst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_leafc_xfer_to_fire(p) = leafc_xfer(p) * matrix_update_fic(p,ileafxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_to_fire(p) = livestemc(p) * matrix_update_fic(p,ilivestem_to_iout_fic ,f * cc_lstem(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_storage_to_fire(p) = livestemc_storage(p) * matrix_update_fic(p,ilivestemst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_xfer_to_fire(p) = livestemc_xfer(p) * matrix_update_fic(p,ilivestemxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_to_fire(p) = deadstemc(p) * matrix_update_fic(p,ideadstem_to_iout_fic ,f * cc_dstem(patch%itype(p))*m,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_storage_to_fire(p) = deadstemc_storage(p) * matrix_update_fic(p,ideadstemst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_xfer_to_fire(p) = deadstemc_xfer(p) * matrix_update_fic(p,ideadstemxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_to_fire(p) = frootc(p) * matrix_update_fic(p,ifroot_to_iout_fic ,f * 0._r8 ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_storage_to_fire(p) = frootc_storage(p) * matrix_update_fic(p,ifrootst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_xfer_to_fire(p) = frootc_xfer(p) * matrix_update_fic(p,ifrootxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_to_fire(p) = livecrootc(p) * matrix_update_fic(p,ilivecroot_to_iout_fic ,f * 0._r8 ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_storage_to_fire(p) = livecrootc_storage(p) * matrix_update_fic(p,ilivecrootst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_xfer_to_fire(p) = livecrootc_xfer(p) * matrix_update_fic(p,ilivecrootxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_to_fire(p) = deadcrootc(p) * matrix_update_fic(p,ideadcroot_to_iout_fic ,f * 0._r8 ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_storage_to_fire(p) = deadcrootc_storage(p) * matrix_update_fic(p,ideadcrootst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_xfer_to_fire(p) = deadcrootc_xfer(p) * matrix_update_fic(p,ideadcrootxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+
+ m_leafn_to_fire(p) = leafn(p) * matrix_update_fin(p,ileaf_to_iout_fin ,f * cc_leaf(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_leafn_storage_to_fire(p) = leafn_storage(p) * matrix_update_fin(p,ileafst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_leafn_xfer_to_fire(p) = leafn_xfer(p) * matrix_update_fin(p,ileafxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_to_fire(p) = livestemn(p) * matrix_update_fin(p,ilivestem_to_iout_fin ,f * cc_lstem(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_storage_to_fire(p) = livestemn_storage(p) * matrix_update_fin(p,ilivestemst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_xfer_to_fire(p) = livestemn_xfer(p) * matrix_update_fin(p,ilivestemxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_to_fire(p) = deadstemn(p) * matrix_update_fin(p,ideadstem_to_iout_fin ,f * cc_dstem(patch%itype(p))*m,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_storage_to_fire(p) = deadstemn_storage(p) * matrix_update_fin(p,ideadstemst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_xfer_to_fire(p) = deadstemn_xfer(p) * matrix_update_fin(p,ideadstemxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_to_fire(p) = frootn(p) * matrix_update_fin(p,ifroot_to_iout_fin ,f * 0._r8 ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_storage_to_fire(p) = frootn_storage(p) * matrix_update_fin(p,ifrootst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_xfer_to_fire(p) = frootn_xfer(p) * matrix_update_fin(p,ifrootxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_to_fire(p) = livecrootn(p) * matrix_update_fin(p,ilivecroot_to_iout_fin ,f * 0._r8 ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_storage_to_fire(p) = livecrootn_storage(p) * matrix_update_fin(p,ilivecrootst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_xfer_to_fire(p) = livecrootn_xfer(p) * matrix_update_fin(p,ilivecrootxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_to_fire(p) = deadcrootn(p) * matrix_update_fin(p,ideadcroot_to_iout_fin ,f * 0._r8 ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_storage_to_fire(p) = deadcrootn_storage(p) * matrix_update_fin(p,ideadcrootst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_xfer_to_fire(p) = deadcrootn_xfer(p) * matrix_update_fin(p,ideadcrootxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_retransn_to_fire(p) = retransn(p) * matrix_update_fin(p,iretransn_to_iout_fin ,f * 0._r8 ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
end if
! mortality due to fire
! carbon pools
@@ -920,6 +1006,88 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
(1._r8 - cc_other(patch%itype(p))) * &
fm_other(patch%itype(p))
+ else
+ m_leafc_to_litter_fire(p) = leafc(p) * matrix_update_fic(p,ileaf_to_iout_fic, &
+ f * (1._r8 - cc_leaf(patch%itype(p))) * fm_leaf(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_leafc_storage_to_litter_fire(p) = leafc_storage(p) * matrix_update_fic(p,ileafst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_leafc_xfer_to_litter_fire(p) = leafc_xfer(p) * matrix_update_fic(p,ileafxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_to_litter_fire(p) = livestemc(p) * matrix_update_fic(p,ilivestem_to_iout_fic, &
+ f * (1._r8 - cc_lstem(patch%itype(p))) * fm_droot(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_storage_to_litter_fire(p) = livestemc_storage(p) * matrix_update_fic(p,ilivestemst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_xfer_to_litter_fire(p) = livestemc_xfer(p) * matrix_update_fic(p,ilivestemxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_to_deadstemc_fire(p) = livestemc(p) * matrix_update_fic(p,ilivestem_to_ideadstem_fic,&
+ f * (1._r8 - cc_lstem(patch%itype(p))) * (fm_lstem(patch%itype(p))-fm_droot(patch%itype(p))),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_to_litter_fire(p) = deadstemc(p) * matrix_update_fic(p,ideadstem_to_iout_fic, &
+ f * (1._r8 - cc_dstem(patch%itype(p))) * fm_droot(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_storage_to_litter_fire(p) = deadstemc_storage(p) * matrix_update_fic(p,ideadstemst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_xfer_to_litter_fire(p) = deadstemc_xfer(p) * matrix_update_fic(p,ideadstemxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_to_litter_fire(p) = frootc(p) * matrix_update_fic(p,ifroot_to_iout_fic, &
+ f * fm_root(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_storage_to_litter_fire(p) = frootc_storage(p) * matrix_update_fic(p,ifrootst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_xfer_to_litter_fire(p) = frootc_xfer(p) * matrix_update_fic(p,ifrootxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_to_litter_fire(p) = livecrootc(p) * matrix_update_fic(p,ilivecroot_to_iout_fic, &
+ f * fm_droot(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_storage_to_litter_fire(p) = livecrootc_storage(p) * matrix_update_fic(p,ilivecrootst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_xfer_to_litter_fire(p) = livecrootc_xfer(p) * matrix_update_fic(p,ilivecrootxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_to_deadcrootc_fire(p) = livecrootc(p) * matrix_update_fic(p,ilivecroot_to_ideadcroot_fic,&
+ f * (fm_lroot(patch%itype(p))-fm_droot(patch%itype(p))),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_to_litter_fire(p) = deadcrootc(p) * matrix_update_fic(p,ideadcroot_to_iout_fic, &
+ f * m * fm_droot(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_storage_to_litter_fire(p) = deadcrootc_storage(p) * matrix_update_fic(p,ideadcrootst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_xfer_to_litter_fire(p) = deadcrootc_xfer(p) * matrix_update_fic(p,ideadcrootxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+
+ m_leafn_to_litter_fire(p) = leafn(p) * matrix_update_fin(p,ileaf_to_iout_fin, &
+ f * (1._r8 - cc_leaf(patch%itype(p))) * fm_leaf(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_leafn_storage_to_litter_fire(p) = leafn_storage(p) * matrix_update_fin(p,ileafst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_leafn_xfer_to_litter_fire(p) = leafn_xfer(p) * matrix_update_fin(p,ileafxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_to_litter_fire(p) = livestemn(p) * matrix_update_fin(p,ilivestem_to_iout_fin, &
+ f * (1._r8 - cc_lstem(patch%itype(p))) * fm_droot(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_storage_to_litter_fire(p) = livestemn_storage(p) * matrix_update_fin(p,ilivestemst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_xfer_to_litter_fire(p) = livestemn_xfer(p) * matrix_update_fin(p,ilivestemxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_to_deadstemn_fire(p) = livestemn(p) * matrix_update_fin(p,ilivestem_to_ideadstem_fin,&
+ f * (1._r8 - cc_lstem(patch%itype(p))) * (fm_lstem(patch%itype(p))-fm_droot(patch%itype(p))),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_to_litter_fire(p) = deadstemn(p) * matrix_update_fin(p,ideadstem_to_iout_fin, &
+ f * (1._r8 - cc_dstem(patch%itype(p))) * fm_droot(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_storage_to_litter_fire(p) = deadstemn_storage(p) * matrix_update_fin(p,ideadstemst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_xfer_to_litter_fire(p) = deadstemn_xfer(p) * matrix_update_fin(p,ideadstemxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_to_litter_fire(p) = frootn(p) * matrix_update_fin(p,ifroot_to_iout_fin, &
+ f * fm_root(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_storage_to_litter_fire(p) = frootn_storage(p) * matrix_update_fin(p,ifrootst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_xfer_to_litter_fire(p) = frootn_xfer(p) * matrix_update_fin(p,ifrootxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_to_litter_fire(p) = livecrootn(p) * matrix_update_fin(p,ilivecroot_to_iout_fin, &
+ f * fm_droot(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_storage_to_litter_fire(p) = livecrootn_storage(p) * matrix_update_fin(p,ilivecrootst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_xfer_to_litter_fire(p) = livecrootn_xfer(p) * matrix_update_fin(p,ilivecrootxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_to_deadcrootn_fire(p) = livecrootn(p) * matrix_update_fin(p,ilivecroot_to_ideadcroot_fin,&
+ f * (fm_lroot(patch%itype(p))-fm_droot(patch%itype(p))),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_to_litter_fire(p) = deadcrootn(p) * matrix_update_fin(p,ideadcroot_to_iout_fin, &
+ f * m * fm_droot(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_storage_to_litter_fire(p) = deadcrootn_storage(p) * matrix_update_fin(p,ideadcrootst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_xfer_to_litter_fire(p) = deadcrootn_xfer(p) * matrix_update_fin(p,ideadcrootxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
end if
if (use_cndv) then
@@ -1022,13 +1190,12 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
! vertically-resolved decomposing C/N fire loss
! column loop
!
- num_actfirec = 0 ! Initialize active fire column filter to zero
+ num_actfirec = 0
do fc = 1,num_soilc
c = filter_soilc(fc)
f = farea_burned(c)
- ! If fire is active add to active fire filter
if(f /= 0 .or. f /= baf_crop(c))then
num_actfirec = num_actfirec + 1
filter_actfirec(num_actfirec) = c
@@ -1040,14 +1207,24 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
m_decomp_cpools_to_fire_vr(c,j,l) = decomp_cpools_vr(c,j,l) * f * &
cmb_cmplt_fact_litter
if(use_soil_matrixcn)then! matrix is the same for C and N in the fire.
- ! Apply above for matrix solution
+ associate( &
+ matrix_decomp_fire_k => soilbiogeochem_carbonflux_inst%matrix_decomp_fire_k_col & ! Output: [real(r8) (:,:) ] (gC/m3/step) VR deomp. C fire loss in matrix representation
+ )
+ matrix_decomp_fire_k(c,j+nlevdecomp*(l-1)) = matrix_decomp_fire_k(c,j+nlevdecomp*(l-1)) &
+ - f * cmb_cmplt_fact_litter * dt
+ end associate
end if
end if
if ( is_cwd(l) ) then
m_decomp_cpools_to_fire_vr(c,j,l) = decomp_cpools_vr(c,j,l) * &
(f-baf_crop(c)) * cmb_cmplt_fact_cwd
if(use_soil_matrixcn)then
- ! Apply above for matrix solution
+ associate( &
+ matrix_decomp_fire_k => soilbiogeochem_carbonflux_inst%matrix_decomp_fire_k_col & ! Output: [real(r8) (:,:) ] (gC/m3/step) VR deomp. C fire loss in matrix representation
+ )
+ matrix_decomp_fire_k(c,j+nlevdecomp*(l-1)) = matrix_decomp_fire_k(c,j+nlevdecomp*(l-1)) &
+ - (f-baf_crop(c)) * cmb_cmplt_fact_cwd * dt
+ end associate
end if
end if
end do
diff --git a/src/biogeochem/CNFireLi2014Mod.F90 b/src/biogeochem/CNFireLi2014Mod.F90
index 6ea21a530b..6bfa17a143 100644
--- a/src/biogeochem/CNFireLi2014Mod.F90
+++ b/src/biogeochem/CNFireLi2014Mod.F90
@@ -46,6 +46,7 @@ module CNFireLi2014Mod
use PatchType , only : patch
use FireMethodType , only : fire_method_type
use CNFireBaseMod , only : cnfire_base_type, cnfire_const, cnfire_params
+ use CNVegMatrixMod , only : matrix_update_fic, matrix_update_fin
!
implicit none
private
@@ -654,6 +655,11 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
use clm_varpar , only: i_met_lit, i_litr_max
use pftconMod , only: nc3crop
use dynSubgridControlMod , only: run_has_transient_landcover
+ use clm_varpar , only: ileaf,ileaf_st,ileaf_xf,ifroot,ifroot_st,ifroot_xf,&
+ ilivestem,ilivestem_st,ilivestem_xf,&
+ ideadstem,ideadstem_st,ideadstem_xf,&
+ ilivecroot,ilivecroot_st,ilivecroot_xf,&
+ ideadcroot,ideadcroot_st,ideadcroot_xf,iretransn,ioutc,ioutn
!
! !ARGUMENTS:
class(cnfire_li2014_type) :: this
@@ -884,7 +890,48 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
m_deadcrootn_xfer_to_litter_fire => cnveg_nitrogenflux_inst%m_deadcrootn_xfer_to_litter_fire_patch , & ! Output: [real(r8) (:) ]
m_retransn_to_litter_fire => cnveg_nitrogenflux_inst%m_retransn_to_litter_fire_patch , & ! Output: [real(r8) (:) ]
m_decomp_npools_to_fire_vr => cnveg_nitrogenflux_inst%m_decomp_npools_to_fire_vr_col , & ! Output: [real(r8) (:,:,:) ] VR decomp. N fire loss (gN/m3/s)
- m_n_to_litr_fire => cnveg_nitrogenflux_inst%m_n_to_litr_fire_col & ! Output: [real(r8) (:,:,:) ]
+ m_n_to_litr_fire => cnveg_nitrogenflux_inst%m_n_to_litr_fire_col , & ! Output: [real(r8) (:,:) ]
+ ileaf_to_iout_fic => cnveg_carbonflux_inst%ileaf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_fic => cnveg_carbonflux_inst%ileafst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_fic => cnveg_carbonflux_inst%ileafxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_fic => cnveg_carbonflux_inst%ifroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_fic => cnveg_carbonflux_inst%ifrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_fic => cnveg_carbonflux_inst%ifrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from fine root transfer pool to outside of vegetation pools
+ ilivestem_to_iout_fic => cnveg_carbonflux_inst%ilivestem_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_fic => cnveg_carbonflux_inst%ilivestemst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem storage pool to outside of vegetation pools
+ ilivestemxf_to_iout_fic => cnveg_carbonflux_inst%ilivestemxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_fic => cnveg_carbonflux_inst%ideadstem_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_fic => cnveg_carbonflux_inst%ideadstemst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_fic => cnveg_carbonflux_inst%ideadstemxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_fic => cnveg_carbonflux_inst%ilivecroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_fic => cnveg_carbonflux_inst%ilivecrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_fic => cnveg_carbonflux_inst%ilivecrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_fic => cnveg_carbonflux_inst%ideadcroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_fic => cnveg_carbonflux_inst%ideadcrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_fic => cnveg_carbonflux_inst%ideadcrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead coarse root transfer pool to outside of vegetation pools
+ ilivestem_to_ideadstem_fic => cnveg_carbonflux_inst%ilivestem_to_ideadstem_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_fic => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root pool to dead coarse root pool
+ ileaf_to_iout_fin => cnveg_nitrogenflux_inst%ileaf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_fin => cnveg_nitrogenflux_inst%ileafst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_fin => cnveg_nitrogenflux_inst%ileafxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_fin => cnveg_nitrogenflux_inst%ifroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_fin => cnveg_nitrogenflux_inst%ifrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_fin => cnveg_nitrogenflux_inst%ifrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from fine transfer pool to outside of vegetation pools
+ ilivestem_to_iout_fin => cnveg_nitrogenflux_inst%ilivestem_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_fin => cnveg_nitrogenflux_inst%ilivestemst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live stem storage pool to outside of vegetation pool
+ ilivestemxf_to_iout_fin => cnveg_nitrogenflux_inst%ilivestemxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_fin => cnveg_nitrogenflux_inst%ideadstem_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_fin => cnveg_nitrogenflux_inst%ideadstemst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_fin => cnveg_nitrogenflux_inst%ideadstemxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_fin => cnveg_nitrogenflux_inst%ilivecroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_fin => cnveg_nitrogenflux_inst%ilivecrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_fin => cnveg_nitrogenflux_inst%ilivecrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_fin => cnveg_nitrogenflux_inst%ideadcroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_fin => cnveg_nitrogenflux_inst%ideadcrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_fin => cnveg_nitrogenflux_inst%ideadcrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead coarse root transfer pool to outside of vegetation pools
+ ilivestem_to_ideadstem_fin => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_fi , & ! Input: [integer (:)] Index of fire related N transfer from live stem to dead stem pool
+ ilivecroot_to_ideadcroot_fin => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_fi , & ! Input: [integer (:)] Index of fire related N transfer from live coarse root pool to dead coarse root pool
+ iretransn_to_iout_fin => cnveg_nitrogenflux_inst%iretransn_to_iout_fi & ! Input: [integer (:)] Index of fire related N transfer from retranslocated N pool to outside of vegetation pools
)
transient_landcover = run_has_transient_landcover()
@@ -897,7 +944,7 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
!
! patch loop
!
- num_actfirep = 0 ! Initialize active fire patch filter to zero
+ num_actfirep = 0
do fp = 1,num_soilp
p = filter_soilp(fp)
c = patch%column(p)
@@ -923,7 +970,6 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
! carbon fluxes
m = spinup_factor_deadwood
- ! For patches with active fire add to active fire filter
if(f /= 0)then
num_actfirep = num_actfirep + 1
filter_actfirep(num_actfirep) = p
@@ -975,6 +1021,45 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
m_deadcrootn_storage_to_fire(p) = deadcrootn_storage(p) * f * cc_other(patch%itype(p))
m_retransn_to_fire(p) = retransn(p) * f * cc_other(patch%itype(p))
+ else
+ m_leafc_to_fire(p) = leafc(p) * matrix_update_fic(p,ileaf_to_iout_fic ,f * cc_leaf(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_leafc_storage_to_fire(p) = leafc_storage(p) * matrix_update_fic(p,ileafst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_leafc_xfer_to_fire(p) = leafc_xfer(p) * matrix_update_fic(p,ileafxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_to_fire(p) = livestemc(p) * matrix_update_fic(p,ilivestem_to_iout_fic ,f * cc_lstem(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_storage_to_fire(p) = livestemc_storage(p) * matrix_update_fic(p,ilivestemst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_xfer_to_fire(p) = livestemc_xfer(p) * matrix_update_fic(p,ilivestemxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_to_fire(p) = deadstemc(p) * matrix_update_fic(p,ideadstem_to_iout_fic ,f * cc_dstem(patch%itype(p))*m,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_storage_to_fire(p) = deadstemc_storage(p) * matrix_update_fic(p,ideadstemst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_xfer_to_fire(p) = deadstemc_xfer(p) * matrix_update_fic(p,ideadstemxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_to_fire(p) = frootc(p) * matrix_update_fic(p,ifroot_to_iout_fic ,f * 0._r8 ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_storage_to_fire(p) = frootc_storage(p) * matrix_update_fic(p,ifrootst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_xfer_to_fire(p) = frootc_xfer(p) * matrix_update_fic(p,ifrootxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_to_fire(p) = livecrootc(p) * matrix_update_fic(p,ilivecroot_to_iout_fic ,f * 0._r8 ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_storage_to_fire(p) = livecrootc_storage(p) * matrix_update_fic(p,ilivecrootst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_xfer_to_fire(p) = livecrootc_xfer(p) * matrix_update_fic(p,ilivecrootxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_to_fire(p) = deadcrootc(p) * matrix_update_fic(p,ideadcroot_to_iout_fic ,f * 0._r8 ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_storage_to_fire(p) = deadcrootc_storage(p) * matrix_update_fic(p,ideadcrootst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_xfer_to_fire(p) = deadcrootc_xfer(p) * matrix_update_fic(p,ideadcrootxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+
+ m_leafn_to_fire(p) = leafn(p) * matrix_update_fin(p,ileaf_to_iout_fin ,f * cc_leaf(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_leafn_storage_to_fire(p) = leafn_storage(p) * matrix_update_fin(p,ileafst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_leafn_xfer_to_fire(p) = leafn_xfer(p) * matrix_update_fin(p,ileafxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_to_fire(p) = livestemn(p) * matrix_update_fin(p,ilivestem_to_iout_fin ,f * cc_lstem(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_storage_to_fire(p) = livestemn_storage(p) * matrix_update_fin(p,ilivestemst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_xfer_to_fire(p) = livestemn_xfer(p) * matrix_update_fin(p,ilivestemxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_to_fire(p) = deadstemn(p) * matrix_update_fin(p,ideadstem_to_iout_fin ,f * cc_dstem(patch%itype(p))*m,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_storage_to_fire(p) = deadstemn_storage(p) * matrix_update_fin(p,ideadstemst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_xfer_to_fire(p) = deadstemn_xfer(p) * matrix_update_fin(p,ideadstemxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_to_fire(p) = frootn(p) * matrix_update_fin(p,ifroot_to_iout_fin ,f * 0._r8 ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_storage_to_fire(p) = frootn_storage(p) * matrix_update_fin(p,ifrootst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_xfer_to_fire(p) = frootn_xfer(p) * matrix_update_fin(p,ifrootxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_to_fire(p) = livecrootn(p) * matrix_update_fin(p,ilivecroot_to_iout_fin ,f * 0._r8 ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_storage_to_fire(p) = livecrootn_storage(p) * matrix_update_fin(p,ilivecrootst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_xfer_to_fire(p) = livecrootn_xfer(p) * matrix_update_fin(p,ilivecrootxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_to_fire(p) = deadcrootn(p) * matrix_update_fin(p,ideadcroot_to_iout_fin ,f * 0._r8 ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_storage_to_fire(p) = deadcrootn_storage(p) * matrix_update_fin(p,ideadcrootst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_xfer_to_fire(p) = deadcrootn_xfer(p) * matrix_update_fin(p,ideadcrootxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_retransn_to_fire(p) = retransn(p) * matrix_update_fin(p,iretransn_to_iout_fin ,f * 0._r8 ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
end if
! mortality due to fire
! carbon pools
@@ -1122,6 +1207,94 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
(1._r8 - cc_other(patch%itype(p))) * &
fm_other(patch%itype(p))
+ else
+ m_leafc_to_litter_fire(p) = leafc(p) * matrix_update_fic(p,ileaf_to_iout_fic, &
+ f * (1._r8 - cc_leaf(patch%itype(p))) * fm_leaf(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_leafc_storage_to_litter_fire(p) = leafc_storage(p) * matrix_update_fic(p,ileafst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_leafc_xfer_to_litter_fire(p) = leafc_xfer(p) * matrix_update_fic(p,ileafxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_to_litter_fire(p) = livestemc(p) * matrix_update_fic(p,ilivestem_to_iout_fic, &
+ f * (1._r8 - cc_lstem(patch%itype(p))) * fm_droot(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_storage_to_litter_fire(p) = livestemc_storage(p) * matrix_update_fic(p,ilivestemst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_xfer_to_litter_fire(p) = livestemc_xfer(p) * matrix_update_fic(p,ilivestemxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_to_deadstemc_fire(p) = livestemc(p) * matrix_update_fic(p,ilivestem_to_ideadstem_fic,&
+ f * (1._r8 - cc_lstem(patch%itype(p))) * (fm_lstem(patch%itype(p))-fm_droot(patch%itype(p))),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_to_litter_fire(p) = deadstemc(p) * matrix_update_fic(p,ideadstem_to_iout_fic, &
+ f * (1._r8 - cc_dstem(patch%itype(p))) * fm_droot(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_storage_to_litter_fire(p) = deadstemc_storage(p) * matrix_update_fic(p,ideadstemst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_xfer_to_litter_fire(p) = deadstemc_xfer(p) * matrix_update_fic(p,ideadstemxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_to_litter_fire(p) = frootc(p) * matrix_update_fic(p,ifroot_to_iout_fic, &
+ f * fm_root(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_storage_to_litter_fire(p) = frootc_storage(p) * matrix_update_fic(p,ifrootst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_xfer_to_litter_fire(p) = frootc_xfer(p) * matrix_update_fic(p,ifrootxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_to_litter_fire(p) = livecrootc(p) * matrix_update_fic(p,ilivecroot_to_iout_fic, &
+ f * fm_droot(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_storage_to_litter_fire(p) = livecrootc_storage(p) * matrix_update_fic(p,ilivecrootst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_xfer_to_litter_fire(p) = livecrootc_xfer(p) * matrix_update_fic(p,ilivecrootxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_to_deadcrootc_fire(p) = livecrootc(p) * matrix_update_fic(p,ilivecroot_to_ideadcroot_fic,&
+ f * (fm_lroot(patch%itype(p))-fm_droot(patch%itype(p))),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_to_litter_fire(p) = deadcrootc(p) * matrix_update_fic(p,ideadcroot_to_iout_fic, &
+ f * m * fm_droot(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_storage_to_litter_fire(p) = deadcrootc_storage(p) * matrix_update_fic(p,ideadcrootst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_xfer_to_litter_fire(p) = deadcrootc_xfer(p) * matrix_update_fic(p,ideadcrootxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+
+ m_leafn_to_litter_fire(p) = leafn(p) * matrix_update_fin(p,ileaf_to_iout_fin, &
+ f * (1._r8 - cc_leaf(patch%itype(p))) * fm_leaf(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_leafn_storage_to_litter_fire(p) = leafn_storage(p) * matrix_update_fin(p,ileafst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_leafn_xfer_to_litter_fire(p) = leafn_xfer(p) * matrix_update_fin(p,ileafxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_to_litter_fire(p) = livestemn(p) * matrix_update_fin(p,ilivestem_to_iout_fin, &
+ f * (1._r8 - cc_lstem(patch%itype(p))) * fm_droot(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_storage_to_litter_fire(p) = livestemn_storage(p) * matrix_update_fin(p,ilivestemst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_xfer_to_litter_fire(p) = livestemn_xfer(p) * matrix_update_fin(p,ilivestemxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_to_deadstemn_fire(p) = livestemn(p) * matrix_update_fin(p,ilivestem_to_ideadstem_fin,&
+ f * (1._r8 - cc_lstem(patch%itype(p))) * (fm_lstem(patch%itype(p))-fm_droot(patch%itype(p))),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_to_litter_fire(p) = deadstemn(p) * matrix_update_fin(p,ideadstem_to_iout_fin, &
+ f * (1._r8 - cc_dstem(patch%itype(p))) * fm_droot(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_storage_to_litter_fire(p) = deadstemn_storage(p) * matrix_update_fin(p,ideadstemst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_xfer_to_litter_fire(p) = deadstemn_xfer(p) * matrix_update_fin(p,ideadstemxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_to_litter_fire(p) = frootn(p) * matrix_update_fin(p,ifroot_to_iout_fin, &
+ f * fm_root(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_storage_to_litter_fire(p) = frootn_storage(p) * matrix_update_fin(p,ifrootst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_xfer_to_litter_fire(p) = frootn_xfer(p) * matrix_update_fin(p,ifrootxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_to_litter_fire(p) = livecrootn(p) * matrix_update_fin(p,ilivecroot_to_iout_fin, &
+ f * fm_droot(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_storage_to_litter_fire(p) = livecrootn_storage(p) * matrix_update_fin(p,ilivecrootst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_xfer_to_litter_fire(p) = livecrootn_xfer(p) * matrix_update_fin(p,ilivecrootxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_to_deadcrootn_fire(p) = livecrootn(p) * matrix_update_fin(p,ilivecroot_to_ideadcroot_fin,&
+ f * (fm_lroot(patch%itype(p))-fm_droot(patch%itype(p))),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_to_litter_fire(p) = deadcrootn(p) * matrix_update_fin(p,ideadcroot_to_iout_fin, &
+ f * m * fm_droot(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_storage_to_litter_fire(p) = deadcrootn_storage(p) * matrix_update_fin(p,ideadcrootst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_xfer_to_litter_fire(p) = deadcrootn_xfer(p) * matrix_update_fin(p,ideadcrootxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+!KO
+ ! This term is not currently in the matrix code version of CNFireBaseMod, but there are non-matrix terms for this
+ ! in CNFireLi2014Mod and in CNFireBaseMod in ctsm5.1.dev012. I'm not adding it here because tests are passing without it.
+!KO m_retransn_to_litter_fire(p) = retransn(p) * matrix_update_fin(p,iretransn_to_iout_fin, &
+!KO f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+!KO
end if
if (use_cndv) then
@@ -1218,13 +1391,12 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
! vertically-resolved decomposing C/N fire loss
! column loop
!
- num_actfirec = 0 ! Initialize active fire column filter to zero
+ num_actfirec = 0
do fc = 1,num_soilc
c = filter_soilc(fc)
f = farea_burned(c)
- ! If fire is active add to active fire filter
if(f .ne. 0 .or. f .ne. baf_crop(c))then
num_actfirec = num_actfirec + 1
filter_actfirec(num_actfirec) = c
@@ -1237,15 +1409,23 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
do l = 1, ndecomp_pools
if ( is_litter(l) ) then
m_decomp_cpools_to_fire_vr(c,j,l) = decomp_cpools_vr(c,j,l) * f * 0.5_r8
- ! Apply the above for the matrix solution
if(use_soil_matrixcn)then
+ associate( &
+ matrix_decomp_fire_k => soilbiogeochem_carbonflux_inst%matrix_decomp_fire_k_col & ! Output: [real(r8) (:,:) ]
+ )
+ matrix_decomp_fire_k(c,j+nlevdecomp*(l-1)) = matrix_decomp_fire_k(c,j+nlevdecomp*(l-1)) - f * 0.5_r8 * dt
+ end associate
end if
end if
if ( is_cwd(l) ) then
m_decomp_cpools_to_fire_vr(c,j,l) = decomp_cpools_vr(c,j,l) * &
(f-baf_crop(c)) * 0.25_r8
- ! Apply the above for the matrix solution
if(use_soil_matrixcn)then
+ associate( &
+ matrix_decomp_fire_k => soilbiogeochem_carbonflux_inst%matrix_decomp_fire_k_col & ! Output: [real(r8) (:,:) ]
+ )
+ matrix_decomp_fire_k(c,j+nlevdecomp*(l-1)) = matrix_decomp_fire_k(c,j+nlevdecomp*(l-1)) - (f-baf_crop(c)) * 0.25_r8 * dt
+ end associate
end if
end if
end do
diff --git a/src/biogeochem/CNGapMortalityMod.F90 b/src/biogeochem/CNGapMortalityMod.F90
index aa53317fb3..8979b1eebd 100644
--- a/src/biogeochem/CNGapMortalityMod.F90
+++ b/src/biogeochem/CNGapMortalityMod.F90
@@ -24,7 +24,8 @@ module CNGapMortalityMod
use PatchType , only : patch
use GridcellType , only : grc
use CNSharedParamsMod , only : use_matrixcn
-
+ use CNVegMatrixMod , only : matrix_update_gmc, matrix_update_gmn
+ !
implicit none
private
!
@@ -141,7 +142,44 @@ subroutine CNGapMortality (bounds, num_soilp, filter_soilp, &
livewdcn => pftcon%livewdcn , & ! Input: [real(r8) (:)] live wood (phloem and ray parenchyma) C:N (gC/gN)
laisun => canopystate_inst%laisun_patch , & ! Input: [real(r8) (:) ] sunlit projected leaf area index
laisha => canopystate_inst%laisha_patch , & ! Input: [real(r8) (:) ] shaded projected leaf area index
- nind => dgvs_inst%nind_patch & ! Output:[real(r8)(:)] number of individuals (#/m2) added by F. Li and S. Levis
+ nind => dgvs_inst%nind_patch , & ! Output:[real(r8)(:)] number of individuals (#/m2) added by F. Li and S. Levis
+ ileaf_to_iout_gmc => cnveg_carbonflux_inst%ileaf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_gmc => cnveg_carbonflux_inst%ileafst_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_gmc => cnveg_carbonflux_inst%ileafxf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_gmc => cnveg_carbonflux_inst%ifroot_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_gmc => cnveg_carbonflux_inst%ifrootst_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_gmc => cnveg_carbonflux_inst%ifrootxf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from fine root transfer pool to outside of vegetation pools
+ ilivestem_to_iout_gmc => cnveg_carbonflux_inst%ilivestem_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_gmc => cnveg_carbonflux_inst%ilivestemst_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from live stem storage pool to outside of vegetation pools
+ ilivestemxf_to_iout_gmc => cnveg_carbonflux_inst%ilivestemxf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_gmc => cnveg_carbonflux_inst%ideadstem_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_gmc => cnveg_carbonflux_inst%ideadstemst_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_gmc => cnveg_carbonflux_inst%ideadstemxf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_gmc => cnveg_carbonflux_inst%ilivecroot_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_gmc => cnveg_carbonflux_inst%ilivecrootst_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_gmc => cnveg_carbonflux_inst%ilivecrootxf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_gmc => cnveg_carbonflux_inst%ideadcroot_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_gmc => cnveg_carbonflux_inst%ideadcrootst_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_gmc => cnveg_carbonflux_inst%ideadcrootxf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from dead coarse root transfer pool to outside of vegetation pools
+ ileaf_to_iout_gmn => cnveg_nitrogenflux_inst%ileaf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_gmn => cnveg_nitrogenflux_inst%ileafst_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_gmn => cnveg_nitrogenflux_inst%ileafxf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_gmn => cnveg_nitrogenflux_inst%ifroot_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ifrootst_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ifrootxf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from fine root transfer pool to outside of vegetation pools
+ ilivestem_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestem_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestemst_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from live stem storage pool to outside of vegetation pools
+ ilivestemxf_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestemxf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstem_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstemst_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstemxf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecroot_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecrootst_to_iout_gm, & ! Input: [integer (:)] Index of gap mortality related N transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecrootxf_to_iout_gm, & ! Input: [integer (:)] Index of gap mortality related N transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcroot_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcrootst_to_iout_gm, & ! Input: [integer (:)] Index of gap mortality related N transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcrootxf_to_iout_gm, & ! Input: [integer (:)] Index of gap mortality related N transfer from dead coarse root transfer pool to outside of vegetation pools
+ iretransn_to_iout_gmn => cnveg_nitrogenflux_inst%iretransn_to_iout_gm & ! Input: [integer (:)] Index of gap mortality related N transfer from retranslocation pool to outside of vegetation pools
)
dt = real( get_step_size(), r8 )
@@ -195,9 +233,23 @@ subroutine CNGapMortality (bounds, num_soilp, filter_soilp, &
cnveg_carbonflux_inst%m_frootc_to_litter_patch(p) = cnveg_carbonstate_inst%frootc_patch(p) * m
cnveg_carbonflux_inst%m_livestemc_to_litter_patch(p) = cnveg_carbonstate_inst%livestemc_patch(p) * m
cnveg_carbonflux_inst%m_livecrootc_to_litter_patch(p) = cnveg_carbonstate_inst%livecrootc_patch(p) * m
- cnveg_carbonflux_inst%m_deadstemc_to_litter_patch(p) = cnveg_carbonstate_inst%deadstemc_patch(p) * m * spinup_factor_deadwood
- cnveg_carbonflux_inst%m_deadcrootc_to_litter_patch(p) = cnveg_carbonstate_inst%deadcrootc_patch(p) * m * spinup_factor_deadwood
+ else
+ cnveg_carbonflux_inst%m_leafc_to_litter_patch(p) = cnveg_carbonstate_inst%leafc_patch(p) * matrix_update_gmc(p,ileaf_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_frootc_to_litter_patch(p) = cnveg_carbonstate_inst%frootc_patch(p) * matrix_update_gmc(p,ifroot_to_iout_gmc,m,dt,cnveg_carbonflux_inst,.true.,.True.)
+ cnveg_carbonflux_inst%m_livestemc_to_litter_patch(p) = cnveg_carbonstate_inst%livestemc_patch(p) * matrix_update_gmc(p,ilivestem_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_livecrootc_to_litter_patch(p) = cnveg_carbonstate_inst%livecrootc_patch(p) * matrix_update_gmc(p,ilivecroot_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ end if
+ if(.not. use_matrixcn)then
+ cnveg_carbonflux_inst%m_deadstemc_to_litter_patch(p) = cnveg_carbonstate_inst%deadstemc_patch(p) * m * spinup_factor_deadwood
+ cnveg_carbonflux_inst%m_deadcrootc_to_litter_patch(p) = cnveg_carbonstate_inst%deadcrootc_patch(p) * m * spinup_factor_deadwood
+ else
+ cnveg_carbonflux_inst%m_deadstemc_to_litter_patch(p) = cnveg_carbonstate_inst%deadstemc_patch(p) * matrix_update_gmc(p,ideadstem_to_iout_gmc, &
+ m*spinup_factor_deadwood,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_deadcrootc_to_litter_patch(p) = cnveg_carbonstate_inst%deadcrootc_patch(p) * matrix_update_gmc(p,ideadcroot_to_iout_gmc, &
+ m*spinup_factor_deadwood,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ end if !use_matrixcn
+ if(.not. use_matrixcn)then
! storage pools
cnveg_carbonflux_inst%m_leafc_storage_to_litter_patch(p) = cnveg_carbonstate_inst%leafc_storage_patch(p) * m
cnveg_carbonflux_inst%m_frootc_storage_to_litter_patch(p) = cnveg_carbonstate_inst%frootc_storage_patch(p) * m
@@ -216,11 +268,23 @@ subroutine CNGapMortality (bounds, num_soilp, filter_soilp, &
cnveg_carbonflux_inst%m_deadcrootc_xfer_to_litter_patch(p) = cnveg_carbonstate_inst%deadcrootc_xfer_patch(p) * m
cnveg_carbonflux_inst%m_gresp_xfer_to_litter_patch(p) = cnveg_carbonstate_inst%gresp_xfer_patch(p) * m
else
- ! For the matrix solution the same mortality gets applied, but it may be limited by the matrix solution
- ! This could be unified, by not limiting matrix_update_gmc when use_matrixcn is true
- ! displayed pools
- ! storage pools
- ! transfer pools
+ ! NOTE: The non-matrix version of this is in CNCStateUpdate2Mod CStateUpdate2 (EBK 11/25/2019)
+
+ ! storage pools
+ cnveg_carbonflux_inst%m_leafc_storage_to_litter_patch(p) = cnveg_carbonstate_inst%leafc_storage_patch(p) * matrix_update_gmc(p,ileafst_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_frootc_storage_to_litter_patch(p) = cnveg_carbonstate_inst%frootc_storage_patch(p) * matrix_update_gmc(p,ifrootst_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_livestemc_storage_to_litter_patch(p) = cnveg_carbonstate_inst%livestemc_storage_patch(p) * matrix_update_gmc(p,ilivestemst_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_deadstemc_storage_to_litter_patch(p) = cnveg_carbonstate_inst%deadstemc_storage_patch(p) * matrix_update_gmc(p,ideadstemst_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_livecrootc_storage_to_litter_patch(p) = cnveg_carbonstate_inst%livecrootc_storage_patch(p) * matrix_update_gmc(p,ilivecrootst_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_deadcrootc_storage_to_litter_patch(p) = cnveg_carbonstate_inst%deadcrootc_storage_patch(p) * matrix_update_gmc(p,ideadcrootst_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+
+ ! transfer pools
+ cnveg_carbonflux_inst%m_leafc_xfer_to_litter_patch(p) = cnveg_carbonstate_inst%leafc_xfer_patch(p) * matrix_update_gmc(p,ileafxf_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_frootc_xfer_to_litter_patch(p) = cnveg_carbonstate_inst%frootc_xfer_patch(p) * matrix_update_gmc(p,ifrootxf_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_livestemc_xfer_to_litter_patch(p) = cnveg_carbonstate_inst%livestemc_xfer_patch(p) * matrix_update_gmc(p,ilivestemxf_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_deadstemc_xfer_to_litter_patch(p) = cnveg_carbonstate_inst%deadstemc_xfer_patch(p) * matrix_update_gmc(p,ideadstemxf_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_livecrootc_xfer_to_litter_patch(p) = cnveg_carbonstate_inst%livecrootc_xfer_patch(p) * matrix_update_gmc(p,ilivecrootxf_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_deadcrootc_xfer_to_litter_patch(p) = cnveg_carbonstate_inst%deadcrootc_xfer_patch(p) * matrix_update_gmc(p,ideadcrootxf_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
end if !use_matrixcn
!------------------------------------------------------
@@ -234,8 +298,10 @@ subroutine CNGapMortality (bounds, num_soilp, filter_soilp, &
cnveg_nitrogenflux_inst%m_livestemn_to_litter_patch(p) = cnveg_nitrogenstate_inst%livestemn_patch(p) * m
cnveg_nitrogenflux_inst%m_livecrootn_to_litter_patch(p) = cnveg_nitrogenstate_inst%livecrootn_patch(p) * m
else
- ! For the matrix solution the same mortality gets applied, but it may be limited by the matrix solution
- ! This could be unified, by not limiting matrix_update_gmn when use_matrixcn is true
+ cnveg_nitrogenflux_inst%m_leafn_to_litter_patch(p) = cnveg_nitrogenstate_inst%leafn_patch(p) * matrix_update_gmn(p,ileaf_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_frootn_to_litter_patch(p) = cnveg_nitrogenstate_inst%frootn_patch(p) * matrix_update_gmn(p,ifroot_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,.true.,.True.)
+ cnveg_nitrogenflux_inst%m_livestemn_to_litter_patch(p) = cnveg_nitrogenstate_inst%livestemn_patch(p) * matrix_update_gmn(p,ilivestem_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_livecrootn_to_litter_patch(p) = cnveg_nitrogenstate_inst%livecrootn_patch(p) * matrix_update_gmn(p,ilivecroot_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
end if
if (spinup_state == 2 .and. .not. use_cndv) then !accelerate mortality of dead woody pools
@@ -243,16 +309,18 @@ subroutine CNGapMortality (bounds, num_soilp, filter_soilp, &
cnveg_nitrogenflux_inst%m_deadstemn_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadstemn_patch(p) * m * spinup_factor_deadwood
cnveg_nitrogenflux_inst%m_deadcrootn_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadcrootn_patch(p) * m * spinup_factor_deadwood
else
- ! For the matrix solution the same mortality gets applied, but it may be limited by the matrix solution
- ! This could be unified, by not limiting matrix_update_gmn when use_matrixcn is true
+ cnveg_nitrogenflux_inst%m_deadstemn_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadstemn_patch(p) * matrix_update_gmn(p,ideadstem_to_iout_gmn , &
+ m*spinup_factor_deadwood,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_deadcrootn_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadcrootn_patch(p) * matrix_update_gmn(p,ideadcroot_to_iout_gmn, &
+ m*spinup_factor_deadwood,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
end if !.not. use_matrixcn
else
if (.not. use_matrixcn) then
cnveg_nitrogenflux_inst%m_deadstemn_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadstemn_patch(p) * m
cnveg_nitrogenflux_inst%m_deadcrootn_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadcrootn_patch(p) * m
else
- ! For the matrix solution the same mortality gets applied, but it may be limited by the matrix solution
- ! This could be unified, by not limiting matrix_update_gmn when use_matrixcn is true
+ cnveg_nitrogenflux_inst%m_deadstemn_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadstemn_patch(p) * matrix_update_gmn(p,ideadstem_to_iout_gmn ,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_deadcrootn_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadcrootn_patch(p) * matrix_update_gmn(p,ideadcroot_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
end if !use_matrixcn
end if
@@ -260,8 +328,7 @@ subroutine CNGapMortality (bounds, num_soilp, filter_soilp, &
if(.not. use_matrixcn)then
cnveg_nitrogenflux_inst%m_retransn_to_litter_patch(p) = cnveg_nitrogenstate_inst%retransn_patch(p) * m
else
- ! For the matrix solution the same mortality gets applied, but it may be limited by the matrix solution
- ! This could be unified, by not limiting matrix_update_gmn when use_matrixcn is true
+ cnveg_nitrogenflux_inst%m_retransn_to_litter_patch(p) = cnveg_nitrogenstate_inst%retransn_patch(p) * matrix_update_gmn(p,iretransn_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
end if
end if
@@ -282,10 +349,21 @@ subroutine CNGapMortality (bounds, num_soilp, filter_soilp, &
cnveg_nitrogenflux_inst%m_livecrootn_xfer_to_litter_patch(p) = cnveg_nitrogenstate_inst%livecrootn_xfer_patch(p) * m
cnveg_nitrogenflux_inst%m_deadcrootn_xfer_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadcrootn_xfer_patch(p) * m
else
- ! For the matrix solution the same mortality gets applied, but it may be limited by the matrix solution
- ! This could be unified, by not limiting matrix_update_gmn when use_matrixcn is true
- ! storage pools
- ! transfer pools
+ ! storage pools
+ cnveg_nitrogenflux_inst%m_leafn_storage_to_litter_patch(p) = cnveg_nitrogenstate_inst%leafn_storage_patch(p) * matrix_update_gmn(p,ileafst_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_frootn_storage_to_litter_patch(p) = cnveg_nitrogenstate_inst%frootn_storage_patch(p) * matrix_update_gmn(p,ifrootst_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_livestemn_storage_to_litter_patch(p) = cnveg_nitrogenstate_inst%livestemn_storage_patch(p) * matrix_update_gmn(p,ilivestemst_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_deadstemn_storage_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadstemn_storage_patch(p) * matrix_update_gmn(p,ideadstemst_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_livecrootn_storage_to_litter_patch(p) = cnveg_nitrogenstate_inst%livecrootn_storage_patch(p) * matrix_update_gmn(p,ilivecrootst_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_deadcrootn_storage_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadcrootn_storage_patch(p) * matrix_update_gmn(p,ideadcrootst_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+
+ ! transfer pools
+ cnveg_nitrogenflux_inst%m_leafn_xfer_to_litter_patch(p) = cnveg_nitrogenstate_inst%leafn_xfer_patch(p) * matrix_update_gmn(p,ileafxf_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_frootn_xfer_to_litter_patch(p) = cnveg_nitrogenstate_inst%frootn_xfer_patch(p) * matrix_update_gmn(p,ifrootxf_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_livestemn_xfer_to_litter_patch(p) = cnveg_nitrogenstate_inst%livestemn_xfer_patch(p) * matrix_update_gmn(p,ilivestemxf_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_deadstemn_xfer_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadstemn_xfer_patch(p) * matrix_update_gmn(p,ideadstemxf_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_livecrootn_xfer_to_litter_patch(p) = cnveg_nitrogenstate_inst%livecrootn_xfer_patch(p) * matrix_update_gmn(p,ilivecrootxf_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_deadcrootn_xfer_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadcrootn_xfer_patch(p) * matrix_update_gmn(p,ideadcrootxf_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
end if !use_matrixcn
! added by F. Li and S. Levis
diff --git a/src/biogeochem/CNNStateUpdate1Mod.F90 b/src/biogeochem/CNNStateUpdate1Mod.F90
index 833a65cbc3..21b5d335b7 100644
--- a/src/biogeochem/CNNStateUpdate1Mod.F90
+++ b/src/biogeochem/CNNStateUpdate1Mod.F90
@@ -182,6 +182,8 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, &
else
! Do the above to the matrix solution
do i = i_litr_min, i_litr_max
+ nf_soil%matrix_Ninput%V(c,j+(i-1)*nlevdecomp) = &
+ nf_soil%matrix_Ninput%V(c,j+(i-1)*nlevdecomp) + nf_veg%phenology_n_to_litr_n_col(c,j,i) *dt
end do
end if
end do
@@ -286,6 +288,14 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, &
(nf_veg%leafn_to_biofueln_patch(p) + nf_veg%leafn_to_removedresiduen_patch(p))*dt
ns_veg%livestemn_patch(p) = ns_veg%livestemn_patch(p) - nf_veg%livestemn_to_retransn_patch(p)*dt
ns_veg%retransn_patch(p) = ns_veg%retransn_patch(p) + nf_veg%livestemn_to_retransn_patch(p)*dt
+ do k = repr_grain_min, repr_grain_max
+ ns_veg%reproductiven_patch(p,k) = ns_veg%reproductiven_patch(p,k) &
+ - (nf_veg%repr_grainn_to_food_patch(p,k) + nf_veg%repr_grainn_to_seed_patch(p,k))*dt
+ end do
+ do k = repr_structure_min, repr_structure_max
+ ns_veg%reproductiven_patch(p,k) = ns_veg%reproductiven_patch(p,k) &
+ - (nf_veg%repr_structuren_to_cropprod_patch(p,k) + nf_veg%repr_structuren_to_litter_patch(p,k))*dt
+ end do
!
! For the matrix solution the actual state update comes after the matrix
! multiply in VegMatrix, but the matrix needs to be setup with
@@ -298,15 +308,9 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, &
ns_veg%cropseedn_deficit_patch(p) = ns_veg%cropseedn_deficit_patch(p) &
- nf_veg%crop_seedn_to_leaf_patch(p) * dt
do k = repr_grain_min, repr_grain_max
- ns_veg%reproductiven_patch(p,k) = ns_veg%reproductiven_patch(p,k) &
- - (nf_veg%repr_grainn_to_food_patch(p,k) + nf_veg%repr_grainn_to_seed_patch(p,k))*dt
ns_veg%cropseedn_deficit_patch(p) = ns_veg%cropseedn_deficit_patch(p) &
+ nf_veg%repr_grainn_to_seed_patch(p,k) * dt
end do
- do k = repr_structure_min, repr_structure_max
- ns_veg%reproductiven_patch(p,k) = ns_veg%reproductiven_patch(p,k) &
- - (nf_veg%repr_structuren_to_cropprod_patch(p,k) + nf_veg%repr_structuren_to_litter_patch(p,k))*dt
- end do
end if
! uptake from soil mineral N pool
diff --git a/src/biogeochem/CNNStateUpdate2Mod.F90 b/src/biogeochem/CNNStateUpdate2Mod.F90
index 678bdf05d3..4b6174195e 100644
--- a/src/biogeochem/CNNStateUpdate2Mod.F90
+++ b/src/biogeochem/CNNStateUpdate2Mod.F90
@@ -96,9 +96,13 @@ subroutine NStateUpdate2(num_soilc, filter_soilc, num_soilp, filter_soilp, &
else
! Do above for the matrix solution
do i = i_litr_min, i_litr_max
+ nf_soil%matrix_Ninput%V(c,j+(i-1)*nlevdecomp) = &
+ nf_soil%matrix_Ninput%V(c,j+(i-1)*nlevdecomp) + nf_veg%gap_mortality_n_to_litr_n_col(c,j,i) * dt
end do
! Currently i_cwd .ne. i_litr_max + 1 if .not. fates and
! i_cwd = 0 if fates, so not including in the i-loop
+ nf_soil%matrix_Ninput%V(c,j+(i_cwd-1)*nlevdecomp) = &
+ nf_soil%matrix_Ninput%V(c,j+(i_cwd-1)*nlevdecomp) + nf_veg%gap_mortality_n_to_cwdn_col(c,j) * dt
end if !not use_soil_matrix
end do
end do
@@ -235,9 +239,13 @@ subroutine NStateUpdate2h(num_soilc, filter_soilc, num_soilp, filter_soilp, &
else
! Do above for the matrix solution
do i = i_litr_min, i_litr_max
+ nf_soil%matrix_Ninput%V(c,j+(i-1)*nlevdecomp) = &
+ nf_soil%matrix_Ninput%V(c,j+(i-1)*nlevdecomp) + nf_veg%harvest_n_to_litr_n_col(c,j,i) * dt
end do
! Currently i_cwd .ne. i_litr_max + 1 if .not. fates and
! i_cwd = 0 if fates, so not including in the i-loop
+ nf_soil%matrix_Ninput%V(c,j+(i_cwd-1)*nlevdecomp) = &
+ nf_soil%matrix_Ninput%V(c,j+(i_cwd-1)*nlevdecomp) + nf_veg%harvest_n_to_cwdn_col(c,j) * dt
end if !not use_soil_matrixcn
end do
end do
@@ -313,7 +321,8 @@ end subroutine NStateUpdate2h
!-----------------------------------------------------------------------
subroutine NStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, &
- cnveg_nitrogenflux_inst, cnveg_nitrogenstate_inst, soilbiogeochem_nitrogenstate_inst)
+ cnveg_nitrogenflux_inst, cnveg_nitrogenstate_inst, &
+ soilbiogeochem_nitrogenstate_inst, soilbiogeochem_nitrogenflux_inst)
!
! !DESCRIPTION:
! Update all the prognostic nitrogen state
@@ -329,6 +338,7 @@ subroutine NStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, &
type(cnveg_nitrogenflux_type) , intent(in) :: cnveg_nitrogenflux_inst
type(cnveg_nitrogenstate_type) , intent(inout) :: cnveg_nitrogenstate_inst
type(soilbiogeochem_nitrogenstate_type) , intent(inout) :: soilbiogeochem_nitrogenstate_inst
+ type(soilbiogeochem_nitrogenflux_type) , intent(inout) :: soilbiogeochem_nitrogenflux_inst
!
! !LOCAL VARIABLES:
integer :: c,p,j,l,i ! indices
@@ -339,6 +349,7 @@ subroutine NStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, &
associate( &
nf_veg => cnveg_nitrogenflux_inst , &
ns_veg => cnveg_nitrogenstate_inst , &
+ nf_soil => soilbiogeochem_nitrogenflux_inst, &
ns_soil => soilbiogeochem_nitrogenstate_inst &
)
@@ -350,14 +361,29 @@ subroutine NStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, &
do j = 1,nlevdecomp
do fc = 1,num_soilc
c = filter_soilc(fc)
- do i = i_litr_min, i_litr_max
- ns_soil%decomp_npools_vr_col(c,j,i) = &
- ns_soil%decomp_npools_vr_col(c,j,i) + nf_veg%gru_n_to_litr_n_col(c,j,i) * dt
- end do
- ! Currently i_cwd .ne. i_litr_max + 1 if .not. fates and
- ! i_cwd = 0 if fates, so not including in the i-loop
- ns_soil%decomp_npools_vr_col(c,j,i_cwd) = &
- ns_soil%decomp_npools_vr_col(c,j,i_cwd) + nf_veg%gru_n_to_cwdn_col(c,j) * dt
+ !
+ ! State update without the matrix solution
+ !
+ if (.not. use_soil_matrixcn)then
+ do i = i_litr_min, i_litr_max
+ ns_soil%decomp_npools_vr_col(c,j,i) = &
+ ns_soil%decomp_npools_vr_col(c,j,i) + nf_veg%gru_n_to_litr_n_col(c,j,i) * dt
+ end do
+ ! Currently i_cwd .ne. i_litr_max + 1 if .not. fates and
+ ! i_cwd = 0 if fates, so not including in the i-loop
+ ns_soil%decomp_npools_vr_col(c,j,i_cwd) = &
+ ns_soil%decomp_npools_vr_col(c,j,i_cwd) + nf_veg%gru_n_to_cwdn_col(c,j) * dt
+ else
+ ! Do above for the matrix solution
+ do i = i_litr_min, i_litr_max
+ nf_soil%matrix_Ninput%V(c,j+(i-1)*nlevdecomp) = &
+ nf_soil%matrix_Ninput%V(c,j+(i-1)*nlevdecomp) + nf_veg%gru_n_to_litr_n_col(c,j,i) * dt
+ end do
+ ! Currently i_cwd .ne. i_litr_max + 1 if .not. fates and
+ ! i_cwd = 0 if fates, so not including in the i-loop
+ nf_soil%matrix_Ninput%V(c,j+(i_cwd-1)*nlevdecomp) = &
+ nf_soil%matrix_Ninput%V(c,j+(i_cwd-1)*nlevdecomp) + nf_veg%gru_n_to_cwdn_col(c,j) * dt
+ end if !not use_soil_matrixcn
end do
end do
@@ -366,51 +392,59 @@ subroutine NStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, &
do fp = 1,num_soilp
p = filter_soilp(fp)
- ! displayed pools
- ns_veg%leafn_patch(p) = ns_veg%leafn_patch(p) &
- - nf_veg%gru_leafn_to_litter_patch(p) * dt
- ns_veg%frootn_patch(p) = ns_veg%frootn_patch(p) &
- - nf_veg%gru_frootn_to_litter_patch(p) * dt
- ns_veg%livestemn_patch(p) = ns_veg%livestemn_patch(p) &
- - nf_veg%gru_livestemn_to_atm_patch(p) * dt
- ns_veg%deadstemn_patch(p) = ns_veg%deadstemn_patch(p) &
- - nf_veg%gru_deadstemn_to_atm_patch(p) * dt
- ns_veg%deadstemn_patch(p) = ns_veg%deadstemn_patch(p) &
- - nf_veg%gru_wood_productn_gain_patch(p) * dt
- ns_veg%livecrootn_patch(p) = ns_veg%livecrootn_patch(p) &
- - nf_veg%gru_livecrootn_to_litter_patch(p) * dt
- ns_veg%deadcrootn_patch(p) = ns_veg%deadcrootn_patch(p) &
- - nf_veg%gru_deadcrootn_to_litter_patch(p) * dt
- ns_veg%retransn_patch(p) = ns_veg%retransn_patch(p) &
- - nf_veg%gru_retransn_to_litter_patch(p) * dt
-
- ! storage pools
- ns_veg%leafn_storage_patch(p) = ns_veg%leafn_storage_patch(p) &
- - nf_veg%gru_leafn_storage_to_atm_patch(p) * dt
- ns_veg%frootn_storage_patch(p) = ns_veg%frootn_storage_patch(p) &
- - nf_veg%gru_frootn_storage_to_atm_patch(p) * dt
- ns_veg%livestemn_storage_patch(p) = ns_veg%livestemn_storage_patch(p) &
- - nf_veg%gru_livestemn_storage_to_atm_patch(p) * dt
- ns_veg%deadstemn_storage_patch(p) = ns_veg%deadstemn_storage_patch(p) &
- - nf_veg%gru_deadstemn_storage_to_atm_patch(p) * dt
- ns_veg%livecrootn_storage_patch(p) = ns_veg%livecrootn_storage_patch(p) &
- - nf_veg%gru_livecrootn_storage_to_atm_patch(p) * dt
- ns_veg%deadcrootn_storage_patch(p) = ns_veg%deadcrootn_storage_patch(p) &
- - nf_veg%gru_deadcrootn_storage_to_atm_patch(p) * dt
-
- ! transfer pools
- ns_veg%leafn_xfer_patch(p) = ns_veg%leafn_xfer_patch(p) &
- - nf_veg%gru_leafn_xfer_to_atm_patch(p) *dt
- ns_veg%frootn_xfer_patch(p) = ns_veg%frootn_xfer_patch(p) &
- - nf_veg%gru_frootn_xfer_to_atm_patch(p) *dt
- ns_veg%livestemn_xfer_patch(p) = ns_veg%livestemn_xfer_patch(p) &
- - nf_veg%gru_livestemn_xfer_to_atm_patch(p) *dt
- ns_veg%deadstemn_xfer_patch(p) = ns_veg%deadstemn_xfer_patch(p) &
- - nf_veg%gru_deadstemn_xfer_to_atm_patch(p) *dt
- ns_veg%livecrootn_xfer_patch(p) = ns_veg%livecrootn_xfer_patch(p) &
- - nf_veg%gru_livecrootn_xfer_to_atm_patch(p) *dt
- ns_veg%deadcrootn_xfer_patch(p) = ns_veg%deadcrootn_xfer_patch(p) &
- - nf_veg%gru_deadcrootn_xfer_to_atm_patch(p) *dt
+ !
+ ! State update without the matrix solution
+ !
+ if(.not. use_matrixcn)then
+ ! displayed pools
+ ns_veg%leafn_patch(p) = ns_veg%leafn_patch(p) &
+ - nf_veg%gru_leafn_to_litter_patch(p) * dt
+ ns_veg%frootn_patch(p) = ns_veg%frootn_patch(p) &
+ - nf_veg%gru_frootn_to_litter_patch(p) * dt
+ ns_veg%livestemn_patch(p) = ns_veg%livestemn_patch(p) &
+ - nf_veg%gru_livestemn_to_atm_patch(p) * dt
+ ns_veg%deadstemn_patch(p) = ns_veg%deadstemn_patch(p) &
+ - nf_veg%gru_deadstemn_to_atm_patch(p) * dt
+ ns_veg%deadstemn_patch(p) = ns_veg%deadstemn_patch(p) &
+ - nf_veg%gru_wood_productn_gain_patch(p) * dt
+ ns_veg%livecrootn_patch(p) = ns_veg%livecrootn_patch(p) &
+ - nf_veg%gru_livecrootn_to_litter_patch(p) * dt
+ ns_veg%deadcrootn_patch(p) = ns_veg%deadcrootn_patch(p) &
+ - nf_veg%gru_deadcrootn_to_litter_patch(p) * dt
+ ns_veg%retransn_patch(p) = ns_veg%retransn_patch(p) &
+ - nf_veg%gru_retransn_to_litter_patch(p) * dt
+
+ ! storage pools
+ ns_veg%leafn_storage_patch(p) = ns_veg%leafn_storage_patch(p) &
+ - nf_veg%gru_leafn_storage_to_atm_patch(p) * dt
+ ns_veg%frootn_storage_patch(p) = ns_veg%frootn_storage_patch(p) &
+ - nf_veg%gru_frootn_storage_to_atm_patch(p) * dt
+ ns_veg%livestemn_storage_patch(p) = ns_veg%livestemn_storage_patch(p) &
+ - nf_veg%gru_livestemn_storage_to_atm_patch(p) * dt
+ ns_veg%deadstemn_storage_patch(p) = ns_veg%deadstemn_storage_patch(p) &
+ - nf_veg%gru_deadstemn_storage_to_atm_patch(p) * dt
+ ns_veg%livecrootn_storage_patch(p) = ns_veg%livecrootn_storage_patch(p) &
+ - nf_veg%gru_livecrootn_storage_to_atm_patch(p) * dt
+ ns_veg%deadcrootn_storage_patch(p) = ns_veg%deadcrootn_storage_patch(p) &
+ - nf_veg%gru_deadcrootn_storage_to_atm_patch(p) * dt
+
+ ! transfer pools
+ ns_veg%leafn_xfer_patch(p) = ns_veg%leafn_xfer_patch(p) &
+ - nf_veg%gru_leafn_xfer_to_atm_patch(p) *dt
+ ns_veg%frootn_xfer_patch(p) = ns_veg%frootn_xfer_patch(p) &
+ - nf_veg%gru_frootn_xfer_to_atm_patch(p) *dt
+ ns_veg%livestemn_xfer_patch(p) = ns_veg%livestemn_xfer_patch(p) &
+ - nf_veg%gru_livestemn_xfer_to_atm_patch(p) *dt
+ ns_veg%deadstemn_xfer_patch(p) = ns_veg%deadstemn_xfer_patch(p) &
+ - nf_veg%gru_deadstemn_xfer_to_atm_patch(p) *dt
+ ns_veg%livecrootn_xfer_patch(p) = ns_veg%livecrootn_xfer_patch(p) &
+ - nf_veg%gru_livecrootn_xfer_to_atm_patch(p) *dt
+ ns_veg%deadcrootn_xfer_patch(p) = ns_veg%deadcrootn_xfer_patch(p) &
+ - nf_veg%gru_deadcrootn_xfer_to_atm_patch(p) *dt
+ else
+ ! NB (slevis) The equivalent changes for matrix code are in
+ ! dynGrossUnrepMod::CNGrossUnrep*
+ end if !not use_matrixcn
end do
diff --git a/src/biogeochem/CNNStateUpdate3Mod.F90 b/src/biogeochem/CNNStateUpdate3Mod.F90
index 26902cef22..fb8f57b38f 100644
--- a/src/biogeochem/CNNStateUpdate3Mod.F90
+++ b/src/biogeochem/CNNStateUpdate3Mod.F90
@@ -146,10 +146,14 @@ subroutine NStateUpdate3(num_soilc, filter_soilc, num_soilp, filter_soilp, &
! native subroutines dealing with that field
!
else
+ nf_soil%matrix_Ninput%V(c,j+(i_cwd-1)*nlevdecomp) = nf_soil%matrix_Ninput%V(c,j+(i_cwd-1)*nlevdecomp) + &
+ nf_veg%fire_mortality_n_to_cwdn_col(c,j) * dt
! Do above for the matrix solution
! patch-level wood to column-level litter (uncombusted wood)
do k = i_litr_min, i_litr_max
+ nf_soil%matrix_Ninput%V(c,j+(k-1)*nlevdecomp) = nf_soil%matrix_Ninput%V(c,j+(k-1)*nlevdecomp) + &
+ nf_veg%m_n_to_litr_fire_col(c,j,k)* dt
end do
end if ! not use_soil_matrix
end do ! end of column loop
diff --git a/src/biogeochem/CNPhenologyMod.F90 b/src/biogeochem/CNPhenologyMod.F90
index fffb19bc46..2ce7f029da 100644
--- a/src/biogeochem/CNPhenologyMod.F90
+++ b/src/biogeochem/CNPhenologyMod.F90
@@ -14,6 +14,12 @@ module CNPhenologyMod
use shr_log_mod , only : errMsg => shr_log_errMsg
use shr_sys_mod , only : shr_sys_flush
use decompMod , only : bounds_type
+ use clm_varpar , only : ileaf,ileaf_st,ileaf_xf,ifroot,ifroot_st,ifroot_xf,&
+ ilivestem,ilivestem_st,ilivestem_xf,&
+ ideadstem,ideadstem_st,ideadstem_xf,&
+ ilivecroot,ilivecroot_st,ilivecroot_xf,&
+ ideadcroot,ideadcroot_st,ideadcroot_xf,&
+ igrain,igrain_st,igrain_xf,iretransn,ioutc,ioutn
use clm_varpar , only : maxveg, nlevdecomp_full, mxsowings, mxharvests
use clm_varpar , only : i_litr_min, i_litr_max
use clm_varctl , only : iulog, use_cndv
@@ -42,6 +48,8 @@ module CNPhenologyMod
use GridcellType , only : grc
use PatchType , only : patch
use atm2lndType , only : atm2lnd_type
+ use CNVegMatrixMod , only : matrix_update_phc, matrix_update_phn
+ use CNVegMatrixMod , only : matrix_update_gmc, matrix_update_gmn
!
implicit none
private
@@ -132,10 +140,8 @@ module CNPhenologyMod
integer, allocatable :: maxplantjday(:,:) ! maximum planting julian day
integer :: jdayyrstart(inSH) ! julian day of start of year
- ! Two matrix check parameters that will be invoked when the matrix solution
- ! comes in (use_matrixcn)
- logical,parameter :: matrixcheck_ph = .True. ! Matrix solution check
- logical,parameter :: acc_ph = .False. ! Another matrix solution check
+ logical,parameter :: matrixcheck_ph = .True. ! Matrix check
+ logical,parameter :: acc_ph = .False. ! Another matrix check
real(r8), private :: initial_seed_at_planting = 3._r8 ! Initial seed at planting
@@ -143,6 +149,9 @@ module CNPhenologyMod
logical, public :: generate_crop_gdds = .false. ! If true, harvest the day before next sowing
logical, public :: use_mxmat = .true. ! If true, ignore crop maximum growing season length
+ ! For use with adapt_cropcal_rx_cultivar_gdds .true.
+ real(r8), parameter :: min_gdd20_baseline = 0._r8 ! If gdd20_baseline_patch is ≤ this, do not consider baseline.
+
! Constants for seasonal decidious leaf onset and offset
logical, private :: onset_thresh_depends_on_veg = .false. ! If onset threshold depends on vegetation type
integer, public, parameter :: critical_daylight_constant = 1
@@ -674,8 +683,47 @@ subroutine CNEvergreenPhenology (num_soilp, filter_soilp , &
bglfr => cnveg_state_inst%bglfr_patch , & ! Output: [real(r8) (:) ] background litterfall rate (1/s)
bgtr => cnveg_state_inst%bgtr_patch , & ! Output: [real(r8) (:) ] background transfer growth rate (1/s)
- lgsf => cnveg_state_inst%lgsf_patch & ! Output: [real(r8) (:) ] long growing season factor [0-1]
-
+ lgsf => cnveg_state_inst%lgsf_patch , & ! Output: [real(r8) (:) ] long growing season factor [0-1]
+
+ ileafst_to_ileafxf_phc => cnveg_carbonflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phc => cnveg_carbonflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phc => cnveg_carbonflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phc => cnveg_carbonflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phc => cnveg_carbonflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phc => cnveg_carbonflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phc => cnveg_carbonflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phc => cnveg_carbonflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phc => cnveg_carbonflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phc => cnveg_carbonflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phc => cnveg_carbonflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phc => cnveg_carbonflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phc => cnveg_carbonflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phc => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phc => cnveg_carbonflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phc => cnveg_carbonflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phc => cnveg_carbonflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ igrain_to_iout_phc => cnveg_carbonflux_inst%igrain_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
+ ileafst_to_ileafxf_phn => cnveg_nitrogenflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phn => cnveg_nitrogenflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phn => cnveg_nitrogenflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phn => cnveg_nitrogenflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phn => cnveg_nitrogenflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phn => cnveg_nitrogenflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phn => cnveg_nitrogenflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phn => cnveg_nitrogenflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phn => cnveg_nitrogenflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phn => cnveg_nitrogenflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phn => cnveg_nitrogenflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phn => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phn => cnveg_nitrogenflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phn => cnveg_nitrogenflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phn => cnveg_nitrogenflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ ileaf_to_iretransn_phn => cnveg_nitrogenflux_inst%ileaf_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to retranslocation pool
+ ilivestem_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivestem_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to retranslocation pool
+ ilivecroot_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivecroot_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root pool to retranslocation pool
+ igrain_to_iout_phn => cnveg_nitrogenflux_inst%igrain_to_iout_ph & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
)
avg_dayspyr = get_average_days_per_year()
@@ -697,22 +745,38 @@ subroutine CNEvergreenPhenology (num_soilp, filter_soilp , &
tranr=0.0002_r8
! set carbon fluxes for shifting storage pools to transfer pools
- if (.not. use_matrixcn) then
- leafc_storage_to_xfer(p) = tranr * leafc_storage(p)/dt
- frootc_storage_to_xfer(p) = tranr * frootc_storage(p)/dt
- if (woody(ivt(p)) == 1.0_r8) then
- livestemc_storage_to_xfer(p) = tranr * livestemc_storage(p)/dt
- deadstemc_storage_to_xfer(p) = tranr * deadstemc_storage(p)/dt
- livecrootc_storage_to_xfer(p) = tranr * livecrootc_storage(p)/dt
- deadcrootc_storage_to_xfer(p) = tranr * deadcrootc_storage(p)/dt
- gresp_storage_to_xfer(p) = tranr * gresp_storage(p)/dt
+ if (use_matrixcn) then
+ leafc_storage_to_xfer(p) = leafc_storage(p) * matrix_update_phc(p,ileafst_to_ileafxf_phc,tranr/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ frootc_storage_to_xfer(p) = frootc_storage(p) * matrix_update_phc(p,ifrootst_to_ifrootxf_phc,tranr/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ if (woody(ivt(p)) == 1.0_r8) then
+ livestemc_storage_to_xfer(p) = livestemc_storage(p) * matrix_update_phc(p,ilivestemst_to_ilivestemxf_phc,tranr/dt ,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadstemc_storage_to_xfer(p) = deadstemc_storage(p) * matrix_update_phc(p,ideadstemst_to_ideadstemxf_phc,tranr/dt ,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ livecrootc_storage_to_xfer(p) = livecrootc_storage(p) * matrix_update_phc(p,ilivecrootst_to_ilivecrootxf_phc,tranr/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootc_storage_to_xfer(p) = deadcrootc_storage(p) * matrix_update_phc(p,ideadcrootst_to_ideadcrootxf_phc,tranr/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
- end if !not use_matrixcn
+ leafc_storage_to_xfer(p) = tranr * leafc_storage(p)/dt
+ frootc_storage_to_xfer(p) = tranr * frootc_storage(p)/dt
+ if (woody(ivt(p)) == 1.0_r8) then
+ livestemc_storage_to_xfer(p) = tranr * livestemc_storage(p)/dt
+ deadstemc_storage_to_xfer(p) = tranr * deadstemc_storage(p)/dt
+ livecrootc_storage_to_xfer(p) = tranr * livecrootc_storage(p)/dt
+ deadcrootc_storage_to_xfer(p) = tranr * deadcrootc_storage(p)/dt
+ gresp_storage_to_xfer(p) = tranr * gresp_storage(p)/dt
+ end if
+ end if !use_matrixcn
! set nitrogen fluxes for shifting storage pools to transfer pools
if (use_matrixcn) then
+ leafn_storage_to_xfer(p) = leafn_storage(p) * matrix_update_phn(p,ileafst_to_ileafxf_phn,tranr/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ frootn_storage_to_xfer(p) = frootn_storage(p) * matrix_update_phn(p,ifrootst_to_ifrootxf_phn,tranr/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ if (woody(ivt(p)) == 1.0_r8) then
+ livestemn_storage_to_xfer(p) = livestemn_storage(p) * matrix_update_phn(p,ilivestemst_to_ilivestemxf_phn,tranr/dt ,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadstemn_storage_to_xfer(p) = deadstemn_storage(p) * matrix_update_phn(p,ideadstemst_to_ideadstemxf_phn,tranr/dt ,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ livecrootn_storage_to_xfer(p) = livecrootn_storage(p) * matrix_update_phn(p,ilivecrootst_to_ilivecrootxf_phn,tranr/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootn_storage_to_xfer(p) = deadcrootn_storage(p) * matrix_update_phn(p,ideadcrootst_to_ideadcrootxf_phn,tranr/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ end if
else
! NOTE: The non matrix version of this is in CNNStateUpdate1::NStateUpdate1 EBK (11/26/2019)
leafn_storage_to_xfer(p) = tranr * leafn_storage(p)/dt
@@ -728,6 +792,22 @@ subroutine CNEvergreenPhenology (num_soilp, filter_soilp , &
t1 = 1.0_r8 / dt
if (use_matrixcn) then
+ leafc_xfer_to_leafc(p) = leafc_xfer(p) * matrix_update_phc(p,ileafxf_to_ileaf_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ frootc_xfer_to_frootc(p) = frootc_xfer(p) * matrix_update_phc(p,ifrootxf_to_ifroot_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+
+ leafn_xfer_to_leafn(p) = leafn_xfer(p) * matrix_update_phn(p,ileafxf_to_ileaf_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ frootn_xfer_to_frootn(p) = frootn_xfer(p) * matrix_update_phn(p,ifrootxf_to_ifroot_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ if (woody(ivt(p)) == 1.0_r8) then
+ livestemc_xfer_to_livestemc(p) = livestemc_xfer(p) * matrix_update_phc(p,ilivestemxf_to_ilivestem_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadstemc_xfer_to_deadstemc(p) = deadstemc_xfer(p) * matrix_update_phc(p,ideadstemxf_to_ideadstem_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ livecrootc_xfer_to_livecrootc(p) = livecrootc_xfer(p) * matrix_update_phc(p,ilivecrootxf_to_ilivecroot_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootc_xfer_to_deadcrootc(p) = deadcrootc_xfer(p) * matrix_update_phc(p,ideadcrootxf_to_ideadcroot_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+
+ livestemn_xfer_to_livestemn(p) = livestemn_xfer(p) * matrix_update_phn(p,ilivestemxf_to_ilivestem_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadstemn_xfer_to_deadstemn(p) = deadstemn_xfer(p) * matrix_update_phn(p,ideadstemxf_to_ideadstem_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ livecrootn_xfer_to_livecrootn(p) = livecrootn_xfer(p) * matrix_update_phn(p,ilivecrootxf_to_ilivecroot_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootn_xfer_to_deadcrootn(p) = deadcrootn_xfer(p) * matrix_update_phn(p,ideadcrootxf_to_ideadcroot_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
@@ -880,7 +960,46 @@ subroutine CNSeasonDecidPhenology (num_soilp, filter_soilp , &
livestemn_storage_to_xfer => cnveg_nitrogenflux_inst%livestemn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ]
deadstemn_storage_to_xfer => cnveg_nitrogenflux_inst%deadstemn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ]
livecrootn_storage_to_xfer => cnveg_nitrogenflux_inst%livecrootn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ]
- deadcrootn_storage_to_xfer => cnveg_nitrogenflux_inst%deadcrootn_storage_to_xfer_patch & ! Output: [real(r8) (:) ]
+ deadcrootn_storage_to_xfer => cnveg_nitrogenflux_inst%deadcrootn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ]
+ ileafst_to_ileafxf_phc => cnveg_carbonflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phc => cnveg_carbonflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phc => cnveg_carbonflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phc => cnveg_carbonflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phc => cnveg_carbonflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phc => cnveg_carbonflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phc => cnveg_carbonflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phc => cnveg_carbonflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phc => cnveg_carbonflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phc => cnveg_carbonflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phc => cnveg_carbonflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phc => cnveg_carbonflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phc => cnveg_carbonflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phc => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phc => cnveg_carbonflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phc => cnveg_carbonflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phc => cnveg_carbonflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ igrain_to_iout_phc => cnveg_carbonflux_inst%igrain_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
+ ileafst_to_ileafxf_phn => cnveg_nitrogenflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phn => cnveg_nitrogenflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phn => cnveg_nitrogenflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phn => cnveg_nitrogenflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phn => cnveg_nitrogenflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phn => cnveg_nitrogenflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phn => cnveg_nitrogenflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phn => cnveg_nitrogenflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phn => cnveg_nitrogenflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phn => cnveg_nitrogenflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phn => cnveg_nitrogenflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phn => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phn => cnveg_nitrogenflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phn => cnveg_nitrogenflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phn => cnveg_nitrogenflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ ileaf_to_iretransn_phn => cnveg_nitrogenflux_inst%ileaf_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to retranslocation pool
+ ilivestem_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivestem_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to retranslocation pool
+ ilivecroot_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivecroot_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root pool to retranslocation pool
+ igrain_to_iout_phn => cnveg_nitrogenflux_inst%igrain_to_iout_ph & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
)
! start patch loop
@@ -1002,6 +1121,25 @@ subroutine CNSeasonDecidPhenology (num_soilp, filter_soilp , &
! set carbon fluxes for shifting storage pools to transfer pools
if(use_matrixcn)then
+ leafc_storage_to_xfer(p) = leafc_storage(p) * matrix_update_phc(p,ileafst_to_ileafxf_phc,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ frootc_storage_to_xfer(p) = frootc_storage(p) * matrix_update_phc(p,ifrootst_to_ifrootxf_phc,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+
+ if (woody(ivt(p)) == 1.0_r8) then
+ livestemc_storage_to_xfer(p) = livestemc_storage(p) * matrix_update_phc(p,ilivestemst_to_ilivestemxf_phc ,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadstemc_storage_to_xfer(p) = deadstemc_storage(p) * matrix_update_phc(p,ideadstemst_to_ideadstemxf_phc ,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ livecrootc_storage_to_xfer(p) = livecrootc_storage(p) * matrix_update_phc(p,ilivecrootst_to_ilivecrootxf_phc,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootc_storage_to_xfer(p) = deadcrootc_storage(p) * matrix_update_phc(p,ideadcrootst_to_ideadcrootxf_phc,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ gresp_storage_to_xfer(p) = fstor2tran * gresp_storage(p)/dt
+ end if
+ leafn_storage_to_xfer(p) = leafn_storage(p) * matrix_update_phn(p,ileafst_to_ileafxf_phn,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ frootn_storage_to_xfer(p) = frootn_storage(p) * matrix_update_phn(p,ifrootst_to_ifrootxf_phn,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+
+ if (woody(ivt(p)) == 1.0_r8) then
+ livestemn_storage_to_xfer(p) = livestemn_storage(p) * matrix_update_phn(p,ilivestemst_to_ilivestemxf_phn ,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadstemn_storage_to_xfer(p) = deadstemn_storage(p) * matrix_update_phn(p,ideadstemst_to_ideadstemxf_phn ,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ livecrootn_storage_to_xfer(p) = livecrootn_storage(p) * matrix_update_phn(p,ilivecrootst_to_ilivecrootxf_phn,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootn_storage_to_xfer(p) = deadcrootn_storage(p) * matrix_update_phn(p,ideadcrootst_to_ideadcrootxf_phn,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
@@ -1340,7 +1478,46 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , &
livestemn_storage_to_xfer => cnveg_nitrogenflux_inst%livestemn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ]
deadstemn_storage_to_xfer => cnveg_nitrogenflux_inst%deadstemn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ]
livecrootn_storage_to_xfer => cnveg_nitrogenflux_inst%livecrootn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ]
- deadcrootn_storage_to_xfer => cnveg_nitrogenflux_inst%deadcrootn_storage_to_xfer_patch & ! Output: [real(r8) (:) ]
+ deadcrootn_storage_to_xfer => cnveg_nitrogenflux_inst%deadcrootn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ]
+ ileafst_to_ileafxf_phc => cnveg_carbonflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phc => cnveg_carbonflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phc => cnveg_carbonflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phc => cnveg_carbonflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phc => cnveg_carbonflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phc => cnveg_carbonflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phc => cnveg_carbonflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phc => cnveg_carbonflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phc => cnveg_carbonflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phc => cnveg_carbonflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phc => cnveg_carbonflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phc => cnveg_carbonflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phc => cnveg_carbonflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phc => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phc => cnveg_carbonflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phc => cnveg_carbonflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phc => cnveg_carbonflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ igrain_to_iout_phc => cnveg_carbonflux_inst%igrain_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
+ ileafst_to_ileafxf_phn => cnveg_nitrogenflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phn => cnveg_nitrogenflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phn => cnveg_nitrogenflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phn => cnveg_nitrogenflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phn => cnveg_nitrogenflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phn => cnveg_nitrogenflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phn => cnveg_nitrogenflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phn => cnveg_nitrogenflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phn => cnveg_nitrogenflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phn => cnveg_nitrogenflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phn => cnveg_nitrogenflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phn => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phn => cnveg_nitrogenflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phn => cnveg_nitrogenflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phn => cnveg_nitrogenflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ ileaf_to_iretransn_phn => cnveg_nitrogenflux_inst%ileaf_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to retranslocation pool
+ ilivestem_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivestem_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to retranslocation pool
+ ilivecroot_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivecroot_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root pool to retranslocation pool
+ igrain_to_iout_phn => cnveg_nitrogenflux_inst%igrain_to_iout_ph & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
)
avg_dayspyr = get_average_days_per_year()
@@ -1508,6 +1685,23 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , &
! set carbon fluxes for shifting storage pools to transfer pools
if (use_matrixcn) then
+ leafc_storage_to_xfer(p) = leafc_storage(p) * matrix_update_phc(p,ileafst_to_ileafxf_phc,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ frootc_storage_to_xfer(p) = frootc_storage(p) * matrix_update_phc(p,ifrootst_to_ifrootxf_phc,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ if (woody(ivt(p)) == 1.0_r8) then
+ livestemc_storage_to_xfer(p) = livestemc_storage(p) * matrix_update_phc(p,ilivestemst_to_ilivestemxf_phc,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadstemc_storage_to_xfer(p) = deadstemc_storage(p) * matrix_update_phc(p,ideadstemst_to_ideadstemxf_phc,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ livecrootc_storage_to_xfer(p) = livecrootc_storage(p) * matrix_update_phc(p,ilivecrootst_to_ilivecrootxf_phc,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootc_storage_to_xfer(p) = deadcrootc_storage(p) * matrix_update_phc(p,ideadcrootst_to_ideadcrootxf_phc,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ end if
+
+ leafn_storage_to_xfer(p) = leafn_storage(p) * matrix_update_phn(p,ileafst_to_ileafxf_phn,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ frootn_storage_to_xfer(p) = frootn_storage(p) * matrix_update_phn(p,ifrootst_to_ifrootxf_phn,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ if (woody(ivt(p)) == 1.0_r8) then
+ livestemn_storage_to_xfer(p) = livestemn_storage(p) * matrix_update_phn(p,ilivestemst_to_ilivestemxf_phn,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadstemn_storage_to_xfer(p) = deadstemn_storage(p) * matrix_update_phn(p,ideadstemst_to_ideadstemxf_phn,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ livecrootn_storage_to_xfer(p) = livecrootn_storage(p) * matrix_update_phn(p,ilivecrootst_to_ilivecrootxf_phn,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootn_storage_to_xfer(p) = deadcrootn_storage(p) * matrix_update_phn(p,ideadcrootst_to_ideadcrootxf_phn,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
@@ -1631,9 +1825,26 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , &
! between leafc and leafc_store in the flux. RosieF, Nov5 2015.
leafc_storage_to_xfer(p) = max(0.0_r8,(leafc_storage(p)-leafc(p))) * bgtr(p)
frootc_storage_to_xfer(p) = max(0.0_r8,(frootc_storage(p)-frootc(p))) * bgtr(p)
-
if (use_matrixcn) then
- else
+ if(leafc_storage(p) .gt. 0)then
+ leafc_storage_to_xfer(p) = leafc_storage(p) * matrix_update_phc(p,ileafst_to_ileafxf_phc,&
+ leafc_storage_to_xfer(p) / leafc_storage(p), dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ else
+ leafc_storage_to_xfer(p) = 0
+ end if
+ if(frootc_storage(p) .gt. 0)then
+ frootc_storage_to_xfer(p) = frootc_storage(p) * matrix_update_phc(p,ifrootst_to_ifrootxf_phc,&
+ frootc_storage_to_xfer(p) / frootc_storage(p), dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ else
+ frootc_storage_to_xfer(p) = 0
+ end if
+ if (woody(ivt(p)) == 1.0_r8) then
+ livestemc_storage_to_xfer(p) = livestemc_storage(p) * matrix_update_phc(p,ilivestemst_to_ilivestemxf_phc ,bgtr(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadstemc_storage_to_xfer(p) = deadstemc_storage(p) * matrix_update_phc(p,ideadstemst_to_ideadstemxf_phc ,bgtr(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ livecrootc_storage_to_xfer(p) = livecrootc_storage(p) * matrix_update_phc(p,ilivecrootst_to_ilivecrootxf_phc,bgtr(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootc_storage_to_xfer(p) = deadcrootc_storage(p) * matrix_update_phc(p,ideadcrootst_to_ideadcrootxf_phc,bgtr(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ end if
+ else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
if (woody(ivt(p)) == 1.0_r8) then
@@ -1647,9 +1858,17 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , &
! set nitrogen fluxes for shifting storage pools to transfer pools
if (use_matrixcn) then
+ leafn_storage_to_xfer(p) = leafn_storage(p) * matrix_update_phn(p,ileafst_to_ileafxf_phn,bgtr(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ frootn_storage_to_xfer(p) = frootn_storage(p) * matrix_update_phn(p,ifrootst_to_ifrootxf_phn,bgtr(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ if (woody(ivt(p)) == 1.0_r8) then
+ livestemn_storage_to_xfer(p) = livestemn_storage(p) * matrix_update_phn(p,ilivestemst_to_ilivestemxf_phn,bgtr(p) ,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadstemn_storage_to_xfer(p) = deadstemn_storage(p) * matrix_update_phn(p,ideadstemst_to_ideadstemxf_phn,bgtr(p) ,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ livecrootn_storage_to_xfer(p) = livecrootn_storage(p) * matrix_update_phn(p,ilivecrootst_to_ilivecrootxf_phn,bgtr(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootn_storage_to_xfer(p) = deadcrootn_storage(p) * matrix_update_phn(p,ideadcrootst_to_ideadcrootxf_phn,bgtr(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
- ! and CNNStateUpdate1::NStateUpdate11
+ ! and CNNStateUpdate1::NStateUpdate1
leafn_storage_to_xfer(p) = leafn_storage(p) * bgtr(p)
frootn_storage_to_xfer(p) = frootn_storage(p) * bgtr(p)
if (woody(ivt(p)) == 1.0_r8) then
@@ -1808,7 +2027,7 @@ subroutine CropPhenology(num_pcropp, filter_pcropp , &
use clm_varctl , only : use_fertilizer
use clm_varctl , only : use_c13, use_c14
use clm_varcon , only : c13ratio, c14ratio
- use clm_varctl , only : use_cropcal_rx_swindows, use_cropcal_rx_cultivar_gdds, use_cropcal_streams
+ use clm_varctl , only : use_cropcal_rx_swindows
!
! !ARGUMENTS:
integer , intent(in) :: num_pcropp ! number of prog crop patches in filter
@@ -1973,7 +2192,7 @@ subroutine CropPhenology(num_pcropp, filter_pcropp , &
cnveg_state_inst%gddmaturity_thisyr(p,s) = -1._r8
crop_inst%gddaccum_thisyr_patch(p,s) = -1._r8
crop_inst%hui_thisyr_patch(p,s) = -1._r8
- crop_inst%sowing_reason_perharv_patch = -1._r8
+ crop_inst%sowing_reason_perharv_patch(p,s) = -1._r8
crop_inst%harvest_reason_thisyr_patch(p,s) = -1._r8
do k = repr_grain_min, repr_grain_max
cnveg_carbonflux_inst%repr_grainc_to_food_perharv_patch(p,s,k) = 0._r8
@@ -2242,7 +2461,7 @@ subroutine CropPhenology(num_pcropp, filter_pcropp , &
do_harvest = .true.
fake_harvest = .true.
harvest_reason = HARVEST_REASON_SOWNBADDEC31
- else if (use_cropcal_streams .and. do_plant .and. .not. did_plant) then
+ else if (use_cropcal_rx_swindows .and. do_plant .and. .not. did_plant) then
! Today was supposed to be the planting day, but the previous crop still hasn't been harvested.
do_harvest = .true.
harvest_reason = HARVEST_REASON_SOWTODAY
@@ -2559,7 +2778,7 @@ subroutine PlantCrop(p, leafcn_in, jday, kyr, do_plant_normal, &
! !USES:
use clm_varctl , only : use_c13, use_c14
- use clm_varctl , only : use_cropcal_rx_cultivar_gdds, use_cropcal_streams
+ use clm_varctl , only : use_cropcal_rx_cultivar_gdds, adapt_cropcal_rx_cultivar_gdds
use clm_varcon , only : c13ratio, c14ratio
use clm_varpar , only : mxsowings
use pftconMod , only : ntmp_corn, nswheat, nwwheat, ntmp_soybean
@@ -2590,6 +2809,7 @@ subroutine PlantCrop(p, leafcn_in, jday, kyr, do_plant_normal, &
! LOCAL VARAIBLES:
integer s ! growing season index
integer k ! grain pool index
+ real(r8) gdd20 ! GDD*20 value for this crop type
real(r8) gdd_target ! cultivar GDD target this growing season
real(r8) this_sowing_reason ! number representing sowing reason(s)
logical did_rx_gdds ! did this patch use a prescribed harvest requirement?
@@ -2668,42 +2888,71 @@ subroutine PlantCrop(p, leafcn_in, jday, kyr, do_plant_normal, &
endif
endif
+ ! which GDD*20 variable does this crop use?
+ if (ivt(p) == ntmp_soybean .or. ivt(p) == nirrig_tmp_soybean .or. &
+ ivt(p) == ntrp_soybean .or. ivt(p) == nirrig_trp_soybean) then
+ gdd20 = gdd1020(p)
+ else if (ivt(p) == ntmp_corn .or. ivt(p) == nirrig_tmp_corn .or. &
+ ivt(p) == ntrp_corn .or. ivt(p) == nirrig_trp_corn .or. &
+ ivt(p) == nsugarcane .or. ivt(p) == nirrig_sugarcane .or. &
+ ivt(p) == nmiscanthus .or. ivt(p) == nirrig_miscanthus .or. &
+ ivt(p) == nswitchgrass .or. ivt(p) == nirrig_switchgrass) then
+ gdd20 = gdd820(p)
+ else if (ivt(p) == nswheat .or. ivt(p) == nirrig_swheat .or. &
+ ivt(p) == nwwheat .or. ivt(p) == nirrig_wwheat .or. &
+ ivt(p) == ncotton .or. ivt(p) == nirrig_cotton .or. &
+ ivt(p) == nrice .or. ivt(p) == nirrig_rice) then
+ gdd20 = gdd020(p)
+ else
+ write(iulog, *) 'ERROR: PlantCrop(): unrecognized ivt for gdd20: ',ivt(p)
+ call endrun(msg="Stopping")
+ end if
+
! set GDD target
did_rx_gdds = .false.
if (use_cropcal_rx_cultivar_gdds .and. crop_inst%rx_cultivar_gdds_thisyr_patch(p,sowing_count(p)) .ge. 0._r8) then
gddmaturity(p) = crop_inst%rx_cultivar_gdds_thisyr_patch(p,sowing_count(p))
did_rx_gdds = .true.
+ if (adapt_cropcal_rx_cultivar_gdds .and. crop_inst%gdd20_baseline_patch(p) > min_gdd20_baseline) then
+ gddmaturity(p) = gddmaturity(p) * gdd20 / crop_inst%gdd20_baseline_patch(p)
+ !TODO Sam Rabin: Set maximum and minimum gddmaturity
+ end if
else if (ivt(p) == nwwheat .or. ivt(p) == nirrig_wwheat) then
gddmaturity(p) = hybgdd(ivt(p))
else
if (ivt(p) == ntmp_soybean .or. ivt(p) == nirrig_tmp_soybean .or. &
- ivt(p) == ntrp_soybean .or. ivt(p) == nirrig_trp_soybean) then
- gddmaturity(p) = min(gdd1020(p), hybgdd(ivt(p)))
- end if
- if (ivt(p) == ntmp_corn .or. ivt(p) == nirrig_tmp_corn .or. &
+ ivt(p) == ntrp_soybean .or. ivt(p) == nirrig_trp_soybean .or. &
+ ivt(p) == nswheat .or. ivt(p) == nirrig_swheat .or. &
+ ivt(p) == ncotton .or. ivt(p) == nirrig_cotton .or. &
+ ivt(p) == nrice .or. ivt(p) == nirrig_rice) then
+ gddmaturity(p) = min(gdd20, hybgdd(ivt(p)))
+ else if (ivt(p) == ntmp_corn .or. ivt(p) == nirrig_tmp_corn .or. &
ivt(p) == ntrp_corn .or. ivt(p) == nirrig_trp_corn .or. &
ivt(p) == nsugarcane .or. ivt(p) == nirrig_sugarcane .or. &
ivt(p) == nmiscanthus .or. ivt(p) == nirrig_miscanthus .or. &
ivt(p) == nswitchgrass .or. ivt(p) == nirrig_switchgrass) then
- gddmaturity(p) = max(950._r8, min(gdd820(p)*0.85_r8, hybgdd(ivt(p))))
+ gddmaturity(p) = max(950._r8, min(gdd20*0.85_r8, hybgdd(ivt(p))))
if (do_plant_normal) then
gddmaturity(p) = max(950._r8, min(gddmaturity(p)+150._r8, 1850._r8))
end if
- end if
- if (ivt(p) == nswheat .or. ivt(p) == nirrig_swheat .or. &
- ivt(p) == ncotton .or. ivt(p) == nirrig_cotton .or. &
- ivt(p) == nrice .or. ivt(p) == nirrig_rice) then
- gddmaturity(p) = min(gdd020(p), hybgdd(ivt(p)))
+ else
+ write(iulog, *) 'ERROR: PlantCrop(): unrecognized ivt for GDD target: ',ivt(p)
+ call endrun(msg="Stopping")
end if
endif
- if (use_cropcal_streams .and. gddmaturity(p) < min_gddmaturity) then
- if (did_rx_gdds) then
- write(iulog,*) 'Some patch with ivt ',ivt(p),' has rx gddmaturity',gddmaturity(p),'; using min_gddmaturity instead (',min_gddmaturity,')'
- endif
- gddmaturity(p) = min_gddmaturity
- endif
+ if (gddmaturity(p) < min_gddmaturity) then
+ if (use_cropcal_rx_cultivar_gdds .or. generate_crop_gdds) then
+ if (did_rx_gdds) then
+ write(iulog,*) 'Some patch with ivt ',ivt(p),' has rx gddmaturity ',gddmaturity(p),'; using min_gddmaturity instead (',min_gddmaturity,')'
+ end if
+ gddmaturity(p) = min_gddmaturity
+ else
+ write(iulog, *) 'ERROR: PlantCrop(): gddmaturity < minimum for ivt ',ivt(p)
+ call endrun(msg="Stopping")
+ end if
+ end if
! Initialize allocation coefficients.
! Because crops have no live carbon pools when planted but not emerged, this shouldn't
@@ -2961,7 +3210,46 @@ subroutine CNOnsetGrowth (num_soilp, filter_soilp, &
livestemn_xfer_to_livestemn => cnveg_nitrogenflux_inst%livestemn_xfer_to_livestemn_patch , & ! Output: [real(r8) (:) ]
deadstemn_xfer_to_deadstemn => cnveg_nitrogenflux_inst%deadstemn_xfer_to_deadstemn_patch , & ! Output: [real(r8) (:) ]
livecrootn_xfer_to_livecrootn => cnveg_nitrogenflux_inst%livecrootn_xfer_to_livecrootn_patch , & ! Output: [real(r8) (:) ]
- deadcrootn_xfer_to_deadcrootn => cnveg_nitrogenflux_inst%deadcrootn_xfer_to_deadcrootn_patch & ! Output: [real(r8) (:) ]
+ deadcrootn_xfer_to_deadcrootn => cnveg_nitrogenflux_inst%deadcrootn_xfer_to_deadcrootn_patch , & ! Output: [real(r8) (:) ]
+ ileafst_to_ileafxf_phc => cnveg_carbonflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phc => cnveg_carbonflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phc => cnveg_carbonflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phc => cnveg_carbonflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phc => cnveg_carbonflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phc => cnveg_carbonflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phc => cnveg_carbonflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phc => cnveg_carbonflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phc => cnveg_carbonflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phc => cnveg_carbonflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phc => cnveg_carbonflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phc => cnveg_carbonflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phc => cnveg_carbonflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phc => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phc => cnveg_carbonflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phc => cnveg_carbonflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phc => cnveg_carbonflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ igrain_to_iout_phc => cnveg_carbonflux_inst%igrain_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
+ ileafst_to_ileafxf_phn => cnveg_nitrogenflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phn => cnveg_nitrogenflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phn => cnveg_nitrogenflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phn => cnveg_nitrogenflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phn => cnveg_nitrogenflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phn => cnveg_nitrogenflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phn => cnveg_nitrogenflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phn => cnveg_nitrogenflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phn => cnveg_nitrogenflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phn => cnveg_nitrogenflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phn => cnveg_nitrogenflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phn => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phn => cnveg_nitrogenflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phn => cnveg_nitrogenflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phn => cnveg_nitrogenflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ ileaf_to_iretransn_phn => cnveg_nitrogenflux_inst%ileaf_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to retranslocation pool
+ ilivestem_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivestem_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to retranslocation pool
+ ilivecroot_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivecroot_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root pool to retranslocation pool
+ igrain_to_iout_phn => cnveg_nitrogenflux_inst%igrain_to_iout_ph & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
)
! patch loop
@@ -2980,6 +3268,22 @@ subroutine CNOnsetGrowth (num_soilp, filter_soilp, &
t1 = 2.0_r8 / (onset_counter(p))
end if
if (use_matrixcn)then
+ leafc_xfer_to_leafc(p) = leafc_xfer(p) * matrix_update_phc(p,ileafxf_to_ileaf_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ frootc_xfer_to_frootc(p) = frootc_xfer(p) * matrix_update_phc(p,ifrootxf_to_ifroot_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ leafn_xfer_to_leafn(p) = leafn_xfer(p) * matrix_update_phn(p,ileafxf_to_ileaf_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ frootn_xfer_to_frootn(p) = frootn_xfer(p) * matrix_update_phn(p,ifrootxf_to_ifroot_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ if (woody(ivt(p)) == 1.0_r8) then
+
+ livestemc_xfer_to_livestemc(p) = livestemc_xfer(p) * matrix_update_phc(p,ilivestemxf_to_ilivestem_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadstemc_xfer_to_deadstemc(p) = deadstemc_xfer(p) * matrix_update_phc(p,ideadstemxf_to_ideadstem_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ livecrootc_xfer_to_livecrootc(p) = livecrootc_xfer(p) * matrix_update_phc(p,ilivecrootxf_to_ilivecroot_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootc_xfer_to_deadcrootc(p) = deadcrootc_xfer(p) * matrix_update_phc(p,ideadcrootxf_to_ideadcroot_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+
+ livestemn_xfer_to_livestemn(p) = livestemn_xfer(p) * matrix_update_phn(p,ilivestemxf_to_ilivestem_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadstemn_xfer_to_deadstemn(p) = deadstemn_xfer(p) * matrix_update_phn(p,ideadstemxf_to_ideadstem_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ livecrootn_xfer_to_livecrootn(p) = livecrootn_xfer(p) * matrix_update_phn(p,ilivecrootxf_to_ilivecroot_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootn_xfer_to_deadcrootn(p) = deadcrootn_xfer(p) * matrix_update_phn(p,ideadcrootxf_to_ideadcroot_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
@@ -3006,7 +3310,26 @@ subroutine CNOnsetGrowth (num_soilp, filter_soilp, &
! pools should be moved to displayed growth in each timestep.
if (bgtr(p) > 0._r8) then
- if(.not. use_matrixcn)then
+ if(use_matrixcn)then
+ leafc_xfer_to_leafc(p) = leafc_xfer(p) * matrix_update_phc(p,ileafxf_to_ileaf_phc,1._r8 / dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ frootc_xfer_to_frootc(p) = frootc_xfer(p) * matrix_update_phc(p,ifrootxf_to_ifroot_phc,1._r8 / dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ leafn_xfer_to_leafn(p) = leafn_xfer(p) * matrix_update_phn(p,ileafxf_to_ileaf_phn,1._r8 / dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ frootn_xfer_to_frootn(p) = frootn_xfer(p) * matrix_update_phn(p,ifrootxf_to_ifroot_phn,1._r8 / dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ if (woody(ivt(p)) == 1.0_r8) then
+
+ livestemc_xfer_to_livestemc(p) = livestemc_xfer(p) * matrix_update_phc(p,ilivestemxf_to_ilivestem_phc,1._r8 / dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadstemc_xfer_to_deadstemc(p) = deadstemc_xfer(p) * matrix_update_phc(p,ideadstemxf_to_ideadstem_phc,1._r8 / dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ livecrootc_xfer_to_livecrootc(p) = livecrootc_xfer(p) * matrix_update_phc(p,ilivecrootxf_to_ilivecroot_phc,1._r8 / dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootc_xfer_to_deadcrootc(p) = deadcrootc_xfer(p) * matrix_update_phc(p,ideadcrootxf_to_ideadcroot_phc,1._r8 / dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+
+ livestemn_xfer_to_livestemn(p) = livestemn_xfer(p) * matrix_update_phn(p,ilivestemxf_to_ilivestem_phn,1._r8 / dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadstemn_xfer_to_deadstemn(p) = deadstemn_xfer(p) * matrix_update_phn(p,ideadstemxf_to_ideadstem_phn,1._r8 / dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ livecrootn_xfer_to_livecrootn(p) = livecrootn_xfer(p) * matrix_update_phn(p,ilivecrootxf_to_ilivecroot_phn,1._r8 / dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootn_xfer_to_deadcrootn(p) = deadcrootn_xfer(p) * matrix_update_phn(p,ideadcrootxf_to_ideadcroot_phn,1._r8 / dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ end if
+ else
+ ! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
+ ! and CNNStateUpdate1::NStateUpdate1
leafc_xfer_to_leafc(p) = leafc_xfer(p) / dt
frootc_xfer_to_frootc(p) = frootc_xfer(p) / dt
leafn_xfer_to_leafn(p) = leafn_xfer(p) / dt
@@ -3021,7 +3344,7 @@ subroutine CNOnsetGrowth (num_soilp, filter_soilp, &
livecrootn_xfer_to_livecrootn(p) = livecrootn_xfer(p) / dt
deadcrootn_xfer_to_deadcrootn(p) = deadcrootn_xfer(p) / dt
end if
- end if !not use_matrixcn
+ end if !use_matrixcn
end if ! end if bgtr
end do ! end patch loop
@@ -3143,8 +3466,51 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
paid_retransn_to_npool=> cnveg_nitrogenflux_inst%retransn_to_npool_patch, & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s)
frootn_to_litter => cnveg_nitrogenflux_inst%frootn_to_litter_patch , & ! Output: [real(r8) (:) ] fine root N litterfall (gN/m2/s)
leafc_to_litter_fun => cnveg_carbonflux_inst%leafc_to_litter_fun_patch , & ! Output: [real(r8) (:) ] leaf C litterfall used by FUN (gC/m2/s)
- leafcn_offset => cnveg_state_inst%leafcn_offset_patch & ! Output: [real(r8) (:) ] Leaf C:N used by FUN
-
+ leafcn_offset => cnveg_state_inst%leafcn_offset_patch , & ! Output: [real(r8) (:) ] Leaf C:N used by FUN
+
+ ileafst_to_ileafxf_phc => cnveg_carbonflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phc => cnveg_carbonflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phc => cnveg_carbonflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phc => cnveg_carbonflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phc => cnveg_carbonflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phc => cnveg_carbonflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phc => cnveg_carbonflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phc => cnveg_carbonflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phc => cnveg_carbonflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phc => cnveg_carbonflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phc => cnveg_carbonflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phc => cnveg_carbonflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phc => cnveg_carbonflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phc => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phc => cnveg_carbonflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ileaf_to_iout_gmc => cnveg_carbonflux_inst%ileaf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from leaf pool to outside of vegetation pools
+ ileaf_to_iout_gmn => cnveg_nitrogenflux_inst%ileaf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phc => cnveg_carbonflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phc => cnveg_carbonflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ igrain_to_iout_phc => cnveg_carbonflux_inst%igrain_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
+ ileafst_to_ileafxf_phn => cnveg_nitrogenflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phn => cnveg_nitrogenflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phn => cnveg_nitrogenflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phn => cnveg_nitrogenflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phn => cnveg_nitrogenflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phn => cnveg_nitrogenflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phn => cnveg_nitrogenflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phn => cnveg_nitrogenflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phn => cnveg_nitrogenflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phn => cnveg_nitrogenflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phn => cnveg_nitrogenflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phn => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phn => cnveg_nitrogenflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phn => cnveg_nitrogenflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phn => cnveg_nitrogenflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ ilivestem_to_iout_gmc => cnveg_carbonflux_inst%ilivestem_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from live stem pool to outside of vegetation pools
+ ilivestem_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestem_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from live stem pool to outside of vegetation pools
+ ileaf_to_iretransn_phn => cnveg_nitrogenflux_inst%ileaf_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to retranslocation pool
+ ilivestem_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivestem_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to retranslocation pool
+ ilivecroot_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivecroot_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root pool to retranslocation pool
+ igrain_to_iout_phn => cnveg_nitrogenflux_inst%igrain_to_iout_ph & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
)
! The litterfall transfer rate starts at 0.0 and increases linearly
@@ -3159,14 +3525,18 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
if (abs(offset_counter(p) - dt) <= dt/2._r8) then
t1 = 1.0_r8 / dt
frootc_to_litter(p) = t1 * frootc(p) + cpool_to_frootc(p)
-
- ! leafc_litter and frootc_to_litter for matrix
+
+ ! frootc_to_litter for matrix
if (use_matrixcn) then
+ if(frootc(p) .gt. 0)then
+ frootc_to_litter(p) = frootc(p) * matrix_update_phc(p,ifroot_to_iout_phc,frootc_to_litter(p) / frootc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ else
+ frootc_to_litter(p) = 0
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
end if ! use_matrixcn
-
! this assumes that offset_counter == dt for crops
! if this were ever changed, we'd need to add code to the "else"
if (ivt(p) >= npcropmin) then
@@ -3269,8 +3639,55 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
! as well as leaf C:N ratio (unaffected by biofuel harvest). It thus does not
! need to be updated here.
- ! Matrix for grain, livestem to litter and biofuel
+ ! Matrix for grain
+ ! Matrix for livestem/leaf to litter, biofuel, and removed residue
if(use_matrixcn)then
+ if(reproductivec(p,1) > 0._r8)then
+ grainc_to_out = reproductivec(p,1) * matrix_update_phc(p,igrain_to_iout_phc,(repr_grainc_to_seed(p,1) + repr_grainc_to_food(p,1)) / reproductivec(p,1),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ else
+ repr_grainc_to_seed(p,1) = 0._r8
+ repr_grainc_to_food(p,1) = 0._r8
+ end if
+ if(reproductiven(p,1) > 0._r8)then
+ grainn_to_out = reproductiven(p,1) * matrix_update_phn(p,igrain_to_iout_phn,(repr_grainn_to_seed(p,1) + repr_grainn_to_food(p,1)) / reproductiven(p,1),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ else
+ repr_grainn_to_seed(p,1) = 0._r8
+ repr_grainn_to_food(p,1) = 0._r8
+ end if
+ if(livestemc(p) > 0._r8)then
+ livestemc_to_litter(p) = livestemc(p) * matrix_update_phc(p,ilivestem_to_iout_phc,livestemc_to_litter(p) / livestemc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ livestemc_to_removedresiduec(p) = livestemc(p) * matrix_update_gmc(p,ilivestem_to_iout_gmc,livestemc_to_removedresiduec(p) / livestemc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,.True.)
+ livestemc_to_biofuelc(p) = livestemc(p) * matrix_update_gmc(p,ilivestem_to_iout_gmc,livestemc_to_biofuelc(p) / livestemc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,.True.)
+ else
+ livestemc_to_litter(p) = 0._r8
+ livestemc_to_removedresiduec(p) = 0._r8
+ livestemc_to_biofuelc(p) = 0._r8
+ end if
+ if(livestemn(p) > 0._r8)then
+ livestemn_to_biofueln(p) = livestemn(p) * matrix_update_gmn(p,ilivestem_to_iout_gmn,livestemn_to_biofueln(p) / livestemn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ livestemn_to_removedresiduen(p) = livestemn(p) * matrix_update_gmn(p,ilivestem_to_iout_gmn,livestemn_to_removedresiduen(p) / livestemn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ livestemn_to_litter(p) = livestemn(p) * matrix_update_phn(p,ilivestem_to_iout_phn, (1._r8- biofuel_harvfrac(ivt(p)))/dt, dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ else
+ livestemn_to_biofueln(p) = 0._r8
+ livestemn_to_removedresiduen(p) = 0._r8
+ livestemn_to_litter(p) = 0._r8
+ end if
+ if(leafn(p) > 0._r8)then
+ leafn_to_biofueln(p) = leafn(p) * matrix_update_gmn(p,ileaf_to_iout_gmn,leafn_to_biofueln(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ leafn_to_removedresiduen(p) = leafn(p) * matrix_update_gmn(p,ileaf_to_iout_gmn,leafn_to_removedresiduen(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ else
+ leafn_to_biofueln(p) = 0._r8
+ leafn_to_removedresiduen(p) = 0._r8
+ end if
+ if (leafc(p) > 0._r8)then
+ leafc_to_biofuelc(p) = leafc(p) * matrix_update_gmc(p,ileaf_to_iout_gmc,leafc_to_biofuelc(p) / leafc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,.True.)
+ leafc_to_removedresiduec(p) = leafc(p) * matrix_update_gmc(p,ileaf_to_iout_gmc,leafc_to_removedresiduec(p) / leafc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,.True.)
+ leafc_to_litter(p) = leafc(p) * matrix_update_phc(p,ileaf_to_iout_phc,leafc_to_litter(p) / leafc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ else
+ leafc_to_biofuelc(p) = 0._r8
+ leafc_to_removedresiduec(p) = 0._r8
+ leafc_to_litter(p) = 0._r8
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
@@ -3281,8 +3698,17 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
leafc_to_litter(p) = prev_leafc_to_litter(p) + t1*(leafc(p) - prev_leafc_to_litter(p)*offset_counter(p))
frootc_to_litter(p) = prev_frootc_to_litter(p) + t1*(frootc(p) - prev_frootc_to_litter(p)*offset_counter(p))
- ! Matrix for leafc and frootc to litter
if (use_matrixcn) then
+ if(leafc(p) .gt. 0)then
+ leafc_to_litter(p) = leafc(p) * matrix_update_phc(p,ileaf_to_iout_phc,leafc_to_litter(p) / leafc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ else
+ leafc_to_litter(p) = 0
+ end if
+ if(frootc(p) .gt. 0)then
+ frootc_to_litter(p) = frootc(p) * matrix_update_phc(p,ifroot_to_iout_phc,frootc_to_litter(p) / frootc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ else
+ frootc_to_litter(p) = 0 ! TODO slevis here and elsewhere
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
@@ -3292,18 +3718,24 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
if ( use_fun ) then
if(leafc_to_litter(p)*dt.gt.leafc(p))then
leafc_to_litter(p) = leafc(p)/dt + cpool_to_leafc(p)
-
- ! Matrix for leafc to litter
- if (use_matrixcn) then
- else
- ! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
- end if !use_matrixcn
+ if (use_matrixcn) then
+ if(leafc(p) .gt. 0)then
+ leafc_to_litter(p) = leafc(p) * matrix_update_phc(p,ileaf_to_iout_phc,leafc_to_litter(p) / leafc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ else
+ leafc_to_litter(p) = 0
+ end if
+ else
+ ! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
+ end if !use_matrixcn
endif
if(frootc_to_litter(p)*dt.gt.frootc(p))then
frootc_to_litter(p) = frootc(p)/dt + cpool_to_frootc(p)
-
- ! Matrix update for frootc to litter
if (use_matrixcn) then
+ if(frootc(p) .gt. 0)then
+ frootc_to_litter(p) = frootc(p) * matrix_update_phc(p,ifroot_to_iout_phc,frootc_to_litter(p) / frootc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ else
+ frootc_to_litter(p) = 0
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
end if !use_matrixcn
@@ -3325,9 +3757,14 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
end if
leafn_to_litter(p) = leafc_to_litter(p)/leafcn_offset(p) - leafn_to_retransn(p)
leafn_to_litter(p) = max(leafn_to_litter(p),0._r8)
-
- ! Matrix update for leafn to litter and retrans
if (use_matrixcn) then
+ if(leafn(p) .gt. 0)then
+ leafn_to_litter(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iout_phn,leafn_to_litter(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ leafn_to_retransn(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iretransn_phn,leafn_to_retransn(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ else
+ leafn_to_litter(p) = 0
+ leafn_to_retransn(p) = 0
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
@@ -3350,8 +3787,14 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
leafn_to_litter(p) = leafc_to_litter(p) / lflitcn(ivt(p))
leafn_to_retransn(p) = (leafc_to_litter(p) / leafcn(ivt(p))) - leafn_to_litter(p)
- ! Matrix update for leafn to litter and retrans
if (use_matrixcn) then
+ if(leafn(p) .gt. 0)then
+ leafn_to_litter(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iout_phn,leafn_to_litter(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ leafn_to_retransn(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iretransn_phn,leafn_to_retransn(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ else
+ leafn_to_litter(p) = 0
+ leafn_to_retransn(p) = 0
+ end if
else
! NOTE: The non matrix version of this is in CNNStateUpdate1::NStateUpdate1 EBK (11/26/2019)
end if !use_matrixcn
@@ -3359,9 +3802,12 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
! calculate fine root N litterfall (no retranslocation of fine root N)
frootn_to_litter(p) = frootc_to_litter(p) / frootcn(ivt(p))
-
- ! Matrix update for frootn to litter
if (use_matrixcn) then
+ if(frootn(p) .gt. 0)then
+ frootn_to_litter(p) = frootn(p) * matrix_update_phn(p,ifroot_to_iout_phn,frootn_to_litter(p) / frootn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ else
+ frootn_to_litter(p) = 0
+ end if
else
! NOTE: The non matrix version of this is in CNNStateUpdate1::NStateUpdate1 EBK (11/26/2019)
end if !use_matrixcn
@@ -3375,19 +3821,26 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
leafn_to_litter(p) = fr_leafn_to_litter * ntovr_leaf
leafn_to_retransn(p) = ntovr_leaf - leafn_to_litter(p)
-
- ! Matrix update for leafn to litter and retrans
if (use_matrixcn) then
- else
+ if(leafn(p) .gt. 0)then
+ leafn_to_litter(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iout_phn,leafn_to_litter(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ leafn_to_retransn(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iretransn_phn,leafn_to_retransn(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ else
+ leafn_to_litter(p) = 0
+ leafn_to_retransn(p) = 0
+ end if
end if !use_matrixcn
if (frootc(p) == 0.0_r8) then
frootn_to_litter(p) = 0.0_r8
- else
+ else
frootn_to_litter(p) = frootc_to_litter(p) * (frootn(p) / frootc(p))
- end if
-
- ! Matrix update for frootn to litter
+ end if
if (use_matrixcn) then
+ if(frootn(p) .gt. 0)then
+ frootn_to_litter(p) = frootn(p) * matrix_update_phn(p,ifroot_to_iout_phn,frootn_to_litter(p) / frootn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ else
+ frootn_to_litter(p) = 0
+ end if
else
! NOTE: The non matrix version of this is in CNNStateUpdate1::NStateUpdate1 EBK (11/26/2019)
end if !use_matrixcn
@@ -3395,12 +3848,10 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
if ( use_fun ) then
if(frootn_to_litter(p)*dt.gt.frootn(p))then
-
- ! Send all frootn to litter
if (.not. use_matrixcn) then
frootn_to_litter(p) = frootn(p)/dt
else
- ! Matrix update for frootn to litter
+ frootn_to_litter(p) = frootn(p) * matrix_update_phn(p,ifroot_to_iout_phn,1._r8/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
end if
endif
end if
@@ -3470,8 +3921,47 @@ subroutine CNBackgroundLitterfall (num_soilp, filter_soilp, &
leafc_to_litter_fun => cnveg_carbonflux_inst%leafc_to_litter_fun_patch, & ! Output: [real(r8) (:) ] leaf C litterfall used by FUN (gC/m2/s)
leafcn_offset => cnveg_state_inst%leafcn_offset_patch , & ! Output: [real(r8) (:) ] Leaf C:N used by FUN
free_retransn_to_npool=> cnveg_nitrogenflux_inst%free_retransn_to_npool_patch , & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s)
- paid_retransn_to_npool=> cnveg_nitrogenflux_inst%retransn_to_npool_patch & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s)
-
+ paid_retransn_to_npool=> cnveg_nitrogenflux_inst%retransn_to_npool_patch , & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s)
+
+ ileafst_to_ileafxf_phc => cnveg_carbonflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phc => cnveg_carbonflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phc => cnveg_carbonflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phc => cnveg_carbonflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phc => cnveg_carbonflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phc => cnveg_carbonflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phc => cnveg_carbonflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phc => cnveg_carbonflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phc => cnveg_carbonflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phc => cnveg_carbonflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phc => cnveg_carbonflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phc => cnveg_carbonflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phc => cnveg_carbonflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phc => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phc => cnveg_carbonflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phc => cnveg_carbonflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phc => cnveg_carbonflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ igrain_to_iout_phc => cnveg_carbonflux_inst%igrain_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
+ ileafst_to_ileafxf_phn => cnveg_nitrogenflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phn => cnveg_nitrogenflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phn => cnveg_nitrogenflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phn => cnveg_nitrogenflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phn => cnveg_nitrogenflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phn => cnveg_nitrogenflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phn => cnveg_nitrogenflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phn => cnveg_nitrogenflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phn => cnveg_nitrogenflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phn => cnveg_nitrogenflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phn => cnveg_nitrogenflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phn => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phn => cnveg_nitrogenflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phn => cnveg_nitrogenflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phn => cnveg_nitrogenflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ ileaf_to_iretransn_phn => cnveg_nitrogenflux_inst%ileaf_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to retranslocation pool
+ ilivestem_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivestem_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to retranslocation pool
+ ilivecroot_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivecroot_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root pool to retranslocation pool
+ igrain_to_iout_phn => cnveg_nitrogenflux_inst%igrain_to_iout_ph & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
)
! patch loop
@@ -3483,10 +3973,9 @@ subroutine CNBackgroundLitterfall (num_soilp, filter_soilp, &
! units for bglfr are already 1/s
leafc_to_litter(p) = bglfr(p) * leafc(p)
frootc_to_litter(p) = bglfr(p) * frootc(p)
-
- ! Matrix update for leafc and frootc to litter
if (use_matrixcn) then
- else
+ leafc_to_litter(p) = leafc(p) * matrix_update_phc(p,ileaf_to_iout_phc,bglfr(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ frootc_to_litter(p) = frootc(p) * matrix_update_phc(p,ifroot_to_iout_phc,bglfr(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
end if
if ( use_fun ) then
leafc_to_litter_fun(p) = leafc_to_litter(p)
@@ -3502,9 +3991,11 @@ subroutine CNBackgroundLitterfall (num_soilp, filter_soilp, &
end if
leafn_to_litter(p) = leafc_to_litter(p)/leafcn_offset(p) - leafn_to_retransn(p)
leafn_to_litter(p) = max(leafn_to_litter(p),0._r8)
-
- ! Matrix update for leafn to litter and retrans
if(use_matrixcn)then
+ if(leafn(p) .ne. 0._r8)then
+ leafn_to_litter(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iout_phn,leafn_to_litter(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ leafn_to_retransn(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iretransn_phn,leafn_to_retransn(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ end if
else
! NOTE: The non matrix version of this is in CNNStateUpdate1::NStateUpdate1 EBK (11/26/2019)
end if !use_matrixcn
@@ -3527,8 +4018,11 @@ subroutine CNBackgroundLitterfall (num_soilp, filter_soilp, &
leafn_to_litter(p) = leafc_to_litter(p) / lflitcn(ivt(p))
leafn_to_retransn(p) = (leafc_to_litter(p) / leafcn(ivt(p))) - leafn_to_litter(p)
- ! Matrix update for leafn to litter and retrans
if (use_matrixcn) then
+ if(leafn(p) .ne. 0)then
+ leafn_to_litter(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iout_phn,leafn_to_litter(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ leafn_to_retransn(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iretransn_phn,leafn_to_retransn(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ end if
else
! NOTE: The non matrix version of this is in CNNStateUpdate1::NStateUpdate1 EBK (11/26/2019)
end if !use_matrixcn
@@ -3546,9 +4040,14 @@ subroutine CNBackgroundLitterfall (num_soilp, filter_soilp, &
leafn_to_litter(p) = fr_leafn_to_litter * ntovr_leaf
leafn_to_retransn(p) = ntovr_leaf - leafn_to_litter(p)
-
- ! Matrix update for leafn to litter and retrans
if (use_matrixcn) then
+ if(leafn(p) .gt. 0)then
+ leafn_to_litter(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iout_phn,leafn_to_litter(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ leafn_to_retransn(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iretransn_phn,leafn_to_retransn(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ else
+ leafn_to_litter(p) = 0
+ leafn_to_retransn(p) = 0
+ end if
else
! NOTE: The non matrix version of this is in CNNStateUpdate1::NStateUpdate1 EBK (11/26/2019)
end if !use_matrixcn
@@ -3565,8 +4064,10 @@ subroutine CNBackgroundLitterfall (num_soilp, filter_soilp, &
endif
end if
- ! Matrix update for frootn to litter
if (use_matrixcn) then
+ if(frootn(p) .ne. 0)then
+ frootn_to_litter(p) = frootn(p) * matrix_update_phn(p,ifroot_to_iout_phn,frootn_to_litter(p) / frootn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ end if
else
! NOTE: The non matrix version of this is in CNNStateUpdate1::NStateUpdate1 EBK (11/26/2019)
end if !use_matrixcn
@@ -3624,7 +4125,47 @@ subroutine CNLivewoodTurnover (num_soilp, filter_soilp, &
livestemn_to_retransn => cnveg_nitrogenflux_inst%livestemn_to_retransn_patch , & ! Output: [real(r8) (:) ]
livecrootn_to_deadcrootn => cnveg_nitrogenflux_inst%livecrootn_to_deadcrootn_patch , & ! Output: [real(r8) (:) ]
livecrootn_to_retransn => cnveg_nitrogenflux_inst%livecrootn_to_retransn_patch , & ! Output: [real(r8) (:) ]
- free_retransn_to_npool => cnveg_nitrogenflux_inst%free_retransn_to_npool_patch & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s)
+ free_retransn_to_npool => cnveg_nitrogenflux_inst%free_retransn_to_npool_patch , & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s)
+ ileafst_to_ileafxf_phc => cnveg_carbonflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phc => cnveg_carbonflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phc => cnveg_carbonflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phc => cnveg_carbonflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phc => cnveg_carbonflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phc => cnveg_carbonflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phc => cnveg_carbonflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phc => cnveg_carbonflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phc => cnveg_carbonflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phc => cnveg_carbonflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phc => cnveg_carbonflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phc => cnveg_carbonflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phc => cnveg_carbonflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phc => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phc => cnveg_carbonflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phc => cnveg_carbonflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phc => cnveg_carbonflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ igrain_to_iout_phc => cnveg_carbonflux_inst%igrain_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
+ ileafst_to_ileafxf_phn => cnveg_nitrogenflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phn => cnveg_nitrogenflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phn => cnveg_nitrogenflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phn => cnveg_nitrogenflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phn => cnveg_nitrogenflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phn => cnveg_nitrogenflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phn => cnveg_nitrogenflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phn => cnveg_nitrogenflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phn => cnveg_nitrogenflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phn => cnveg_nitrogenflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phn => cnveg_nitrogenflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phn => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phn => cnveg_nitrogenflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phn => cnveg_nitrogenflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phn => cnveg_nitrogenflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ ileaf_to_iretransn_phn => cnveg_nitrogenflux_inst%ileaf_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to retranslocation pool
+ ilivestem_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivestem_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to retranslocation pool
+ ilivecroot_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivecroot_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root pool to retranslocation pool
+ iretransn_to_iout => cnveg_nitrogenflux_inst%iretransn_to_iout_ph , & ! Input: [integer ]
+ igrain_to_iout_phn => cnveg_nitrogenflux_inst%igrain_to_iout_ph & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
)
@@ -3642,9 +4183,13 @@ subroutine CNLivewoodTurnover (num_soilp, filter_soilp, &
ntovr = ctovr / livewdcn(ivt(p))
livestemc_to_deadstemc(p) = ctovr
livestemn_to_deadstemn(p) = ctovr / deadwdcn(ivt(p))
-
- ! Matrix update for livestemc to deadstem
if( use_matrixcn)then
+ livestemc_to_deadstemc(p) = livestemc(p) * matrix_update_phc(p,ilivestem_to_ideadstem_phc,lwtop,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ if (livestemn(p) .gt. 0.0_r8) then
+ livestemn_to_deadstemn(p) = livestemn(p) * matrix_update_phn(p,ilivestem_to_ideadstem_phn,livestemn_to_deadstemn(p)/livestemn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ else
+ livestemn_to_deadstemn(p) = 0
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
@@ -3653,13 +4198,18 @@ subroutine CNLivewoodTurnover (num_soilp, filter_soilp, &
if (livestemc(p) == 0.0_r8) then
ntovr = 0.0_r8
livestemn_to_deadstemn(p) = 0.0_r8
- else
+ else
ntovr = ctovr * (livestemn(p) / livestemc(p))
livestemn_to_deadstemn(p) = ctovr / deadwdcn(ivt(p))
- end if
+ end if
- ! Matrix update for livestemn to deadstem
if (use_matrixcn)then
+ if (livestemn(p) .gt. 0.0_r8) then
+ livestemn_to_deadstemn(p) = livestemn(p) * matrix_update_phn(p,ilivestem_to_ideadstem_phn,&
+ livestemn_to_deadstemn(p) / livestemn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ else
+ livestemn_to_deadstemn(p) = 0
+ end if
else
! NOTE: The non matrix version of this is in CNNStateUpdate1::NStateUpdate1 EBK (11/26/2019)
end if
@@ -3672,14 +4222,14 @@ subroutine CNLivewoodTurnover (num_soilp, filter_soilp, &
ctovr = livecrootc(p) * lwtop
ntovr = ctovr / livewdcn(ivt(p))
-
if(.not. use_matrixcn)then
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
livecrootc_to_deadcrootc(p) = ctovr
livecrootn_to_deadcrootn(p) = ctovr / deadwdcn(ivt(p))
else
- ! Matrix update for livecroot to deadcroot
+ livecrootc_to_deadcrootc(p) = livecrootc(p) * matrix_update_phc(p,ilivecroot_to_ideadcroot_phc,lwtop,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ livecrootn_to_deadcrootn(p) = livecrootn(p) * matrix_update_phn(p,ilivecroot_to_ideadcroot_phn,lwtop/deadwdcn(ivt(p)),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
end if !use_matrixcn
if (CNratio_floating .eqv. .true.) then
@@ -3691,20 +4241,48 @@ subroutine CNLivewoodTurnover (num_soilp, filter_soilp, &
livecrootn_to_deadcrootn(p) = ctovr / deadwdcn(ivt(p))
end if
- ! Matrix update for livecroot to deadcroot
if (use_matrixcn)then
+ if (livecrootn(p) .ne.0.0_r8 )then
+ livecrootn_to_deadcrootn(p) = matrix_update_phn(p,ilivecroot_to_ideadcroot_phn,&
+ livecrootn_to_deadcrootn(p) / livecrootn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph) * livecrootn(p)
+ end if
else
! NOTE: The non matrix version of this is in CNNStateUpdate1::NStateUpdate1 EBK (11/26/2019)
end if !use_matrixcn
end if
livecrootn_to_retransn(p) = ntovr - livecrootn_to_deadcrootn(p)
-
- ! Matrix update for livecrootn and livestemn to retrans as well as free retransn to npool with FUN
- if(use_matrixcn)then
- else
- ! The non-matrix version of this is in NStateUpdate1
- end if !use_matrixcn
+ if(use_matrixcn)then
+ if(livecrootn(p) .gt. 0.0_r8) then
+ livecrootn_to_retransn(p) = matrix_update_phn(p,ilivecroot_to_iretransn_phn,&
+ livecrootn_to_retransn(p) / livecrootn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph) * livecrootn(p)
+ else
+ livecrootn_to_retransn(p) = 0
+ end if
+ if(livestemn(p) .gt. 0.0_r8) then
+ livestemn_to_retransn(p) = matrix_update_phn(p,ilivestem_to_iretransn_phn,&
+ livestemn_to_retransn(p) / livestemn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph) * livestemn(p)
+ else
+ livestemn_to_retransn(p) = 0
+ end if
+ ! WW change logic so livestem_retrans goes to npool (via
+ ! free_retrans flux)
+ ! this should likely be done more cleanly if it works, i.e. not
+ ! update fluxes w/ states
+ ! additional considerations for crop?
+ ! The non-matrix version of this is in NStateUpdate1
+ if (use_fun) then
+ if (retransn(p) .gt. 0._r8) then
+ ! The acc matrix check MUST be turned on, or this will
+ ! fail with Nitrogen balance error EBK 03/11/2021
+ free_retransn_to_npool(p) = free_retransn_to_npool(p) + retransn(p) * matrix_update_phn(p,iretransn_to_iout, &
+ (livestemn_to_retransn(p) + livecrootn_to_retransn(p)) / retransn(p),dt, &
+ cnveg_nitrogenflux_inst, matrixcheck_ph, acc=.true.)
+ else
+ free_retransn_to_npool(p) = 0._r8
+ end if
+ end if
+ end if !use_matrixcn
end if
diff --git a/src/biogeochem/CNRootDynMod.F90 b/src/biogeochem/CNRootDynMod.F90
deleted file mode 100644
index 3f43424cfa..0000000000
--- a/src/biogeochem/CNRootDynMod.F90
+++ /dev/null
@@ -1,271 +0,0 @@
-module CNRootDynMod
-
-!-----------------------------------------------------------------------
-! !DESCRIPTION:
-! Module holding routines used for determining fine root distribution for all pfts.
-! Includes dynamic root depth for crops
-!
-! !USES:
- use shr_kind_mod , only : r8 => shr_kind_r8
- use clm_time_manager , only : get_step_size_real
- use abortutils , only : endrun
- use clm_varpar , only : nlevsoi, nlevgrnd
- use clm_varctl , only : use_bedrock
- use decompMod , only : bounds_type
- use pftconMod , only : noveg, npcropmin, pftcon
- use ColumnType , only : col
- use PatchType , only : patch
- use CNVegStateType , only : cnveg_state_type
- use CNVegCarbonStateType , only : cnveg_carbonstate_type
- use CNVegCarbonFluxType , only : cnveg_carbonflux_type
- use CNVegnitrogenstateType , only : cnveg_nitrogenstate_type
- use SoilStateType , only : soilstate_type
- use SoilBiogeochemNitrogenStateType , only : soilbiogeochem_nitrogenstate_type
- use CropType , only : crop_type
-
-! !PUBLIC TYPES:
- implicit none
- save
- private
- public :: CNRootDyn
-!-----------------------------------------------------------------------
-
-contains
-
-!-----------------------------------------------------------------------
-!
-subroutine CNRootDyn(bounds, num_soilc, filter_soilc, num_soilp, filter_soilp, &
- cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, &
- cnveg_state_inst, crop_inst, soilstate_inst, soilbiogeochem_nitrogenstate_inst)
-!
-! !DESCRIPTION:
-! This routine determine the fine root distribution
-! Needs to be called after the photosynthesis calculation
-! May need to update other subroutines that use the fixed root profile for calculations
-! i.e. CNVerticalProfileMod
-!
-! !USES:
-
-
-! !ARGUMENTS:
- type(bounds_type), intent(in) :: bounds ! bounds
- integer, intent(in) :: num_soilc
- integer, intent(in) :: filter_soilc(:)
- integer, intent(in) :: num_soilp ! number of soil pfts in filter
- integer, intent(in) :: filter_soilp(:) ! filter for soil pfts
- type(cnveg_state_type) , intent(in) :: cnveg_state_inst
- type(cnveg_carbonstate_type) , intent(in) :: cnveg_carbonstate_inst
- type(cnveg_carbonflux_type) , intent(in) :: cnveg_carbonflux_inst
- type(cnveg_nitrogenstate_type) , intent(in) :: cnveg_nitrogenstate_inst
- type(crop_type) , intent(in) :: crop_inst
- type(soilbiogeochem_nitrogenstate_type) , intent(in) :: soilbiogeochem_nitrogenstate_inst
- type(soilstate_type) , intent(inout) :: soilstate_inst
-
-!
-! !LOCAL VARIABLES:
-
- integer :: f,c,p,lev,j ! indices
- real(r8):: dt ! radiation time step delta t (seconds)
- real(r8), allocatable :: w_limit(:)
- real(r8), allocatable :: rswa(:,:) ! soil water availability in each soil layer
- real(r8), allocatable :: rsmn(:,:) ! soil nitrogen availability in each soil layer
- real(r8), allocatable :: sumrswa(:) ! scaling soil water availability in each soil layer
- real(r8), allocatable :: sumrsmn(:) ! scaling soil mineral N availability in each soil layer
- real(r8) :: frootc_dz(bounds%begp:bounds%endp, 1:nlevgrnd)
- real(r8), allocatable :: sumfrootc(:) ! fine root carbon total before turnover in each step
- real(r8):: minpsi ! minimum soil moisture potential
- real(r8):: psi
- real(r8):: maxpsi
- real(r8):: new_growth
-
-!-----------------------------------------------------------------------
- ! Assign local pointers to derived type arrays (in)
- associate(&
- ivt => patch%itype , & ! Input: [integer (:)] pft vegetation type
- pcolumn => patch%column , & ! Input: [integer (:)] pft's column index
- roota_par => pftcon%roota_par , & ! Input: [real(r8) (:)] pft's roota index
- rootb_par => pftcon%rootb_par , & ! Input: [real(r8) (:)] pft's rootb index
- root_dmx => pftcon%root_dmx , & ! Input: [real(r8) (:)] crop maximum root depth
- cpool_to_frootc => cnveg_carbonflux_inst%cpool_to_frootc_patch , & ! Input: [real(r8) (:)] allocation to fine root C (gC/m2/s)
- frootc_xfer_to_frootc => cnveg_carbonflux_inst%frootc_xfer_to_frootc_patch , & ! Input: [real(r8) (:)] fine root C growth from storage (gC/m2/s)
- dormant_flag => cnveg_state_inst%dormant_flag_patch , & ! Input: [real(r8) (:)] dormancy flag
- root_depth => soilstate_inst%root_depth_patch , & ! InOut: [real(r8) (:)] current root depth
- dz => col%dz , & ! Input: layer thickness (m) (-nlevsno+1:nlevgrnd)
- zi => col%zi , & ! Input: interface level below a "z" level (m) (-nlevsno+0:nlevgrnd)
- rootfr => soilstate_inst%rootfr_patch , & ! Output: [real(r8) (:,:)] fraction of roots in each soil layer
- sucsat => soilstate_inst%sucsat_col , & ! Input: minimum soil suction (mm)
- soilpsi => soilstate_inst%soilpsi_col , & ! Input: soil water potential in each soil layer (MPa)
- sminn_vr => soilbiogeochem_nitrogenstate_inst%sminn_vr_col , & ! Iniput: [real(r8) (:,:)] (gN/m3) soil mineral N
- frootc => cnveg_carbonstate_inst%frootc_patch , & ! Input: [real(r8) (:)] (gC/m2) fine root C
- hui => crop_inst%hui_patch , & ! Input: [real(r8) (:)] crop patch heat unit index (growing degree-days); set to 0 at sowing and accumulated until harvest
- croplive => crop_inst%croplive_patch , & ! Input: [logical (:)] flag, true if planted, not harvested
- huigrain => cnveg_state_inst%huigrain_patch & ! Input: [real(r8) (:)] same to reach vegetative maturity
- )
-
-! set time steps
- dt = get_step_size_real()
-
-! set minpsi to permanent wilting point
- minpsi = -1.5_r8
-
- allocate(sumrswa(bounds%begp:bounds%endp))
- allocate(sumrsmn(bounds%begp:bounds%endp))
- allocate(sumfrootc(bounds%begp:bounds%endp))
- allocate(rswa(bounds%begp:bounds%endp,nlevgrnd))
- allocate(rsmn(bounds%begp:bounds%endp,nlevgrnd))
- allocate(w_limit(bounds%begp:bounds%endp))
-
-!initialize to 0
- w_limit(bounds%begp:bounds%endp) = 0._r8
- sumrswa(bounds%begp:bounds%endp) = 0._r8
- sumrsmn(bounds%begp:bounds%endp) = 0._r8
- sumfrootc(bounds%begp:bounds%endp) = 0._r8
- rswa(bounds%begp:bounds%endp,:) = 0._r8
- rsmn(bounds%begp:bounds%endp,:) = 0._r8
-
- frootc_dz(bounds%begp:bounds%endp,1:nlevgrnd) = 0._r8
-
-
-!---------------------------------------------------------------
-! Set root depth, dynamic for crops, fixed for other vegetation
-!---------------------------------------------------------------
-
- do f = 1, num_soilp
- p = filter_soilp(f)
- c = pcolumn(p)
- if (ivt(p) /= noveg) then
- if((ivt(p)) >= npcropmin)then !skip generic crop types
- if (.not. croplive(p)) then
- root_depth(p) = 0._r8
- else if(huigrain(p) > 0._r8)then
- root_depth(p) = max(zi(c,2), min(hui(p)/huigrain(p)* root_dmx(ivt(p)), root_dmx(ivt(p))))
- end if
- else
- ! this can be changed to any depth (i.e. the maximum soil depth)
- root_depth(p) = zi(c,nlevsoi)
- end if
- if (use_bedrock) then
- root_depth(p) = min(root_depth(p),zi(c,col%nbedrock(c)))
- end if
- else
- root_depth(p) = 0._r8
- end if
- end do
-
-!----------------------------------------------------------------
-! ! calculate a weighting function by soil depth that depends on the
- ! fine root distribution per pft and depth and the pft weight on the column.
- ! This will be used to weight the temperature and water potential scalars
- ! for decomposition control.
-
- ! calculate the rate constant scalar for soil water content.
- ! Uses the log relationship with water potential given in
- ! Andren, O., and K. Paustian, 1987. Barley straw decomposition in the field:
- ! a comparison of models. Ecology, 68(5):1190-1200.
- ! and supported by data in
- ! Orchard, V.A., and F.J. Cook, 1983. Relationship between soil respiration
- ! and soil moisture. Soil Biol. Biochem., 15(4):447-453.
-
- do j = 1,nlevsoi
- do f = 1,num_soilp
- p = filter_soilp(f)
- c = pcolumn(p)
- maxpsi = sucsat(c,j) * (-9.8e-6_r8)
- psi = min(soilpsi(c,j),maxpsi)
- if (psi > minpsi) then
-! First calculate water in the root zone
- if(root_depth(p) > 0.15_r8 .and. (zi(c,j) <= root_depth(p) .or. &
- (zi(c,j-1) < root_depth(p) .and. zi(c,j) > root_depth(p)))) then
- w_limit(p) = w_limit(p) + max(0._r8,log(minpsi/psi)/log(minpsi/maxpsi))*rootfr(p,j)
- end if
-! Calculate the water in each soil layer
- if (root_depth(p) >= zi(c,j) .or. &
- (zi(c,j-1) < root_depth(p) .and. zi(c,j) > root_depth(p))) then
- rswa(p,j) = max(0._r8, (log(minpsi/psi)/log(minpsi/maxpsi)))
- end if
- end if
- sumrswa(p) = sumrswa(p) + rswa(p,j)
-
-! Calculate the nitrogen profile in each layer
-! For now, the profile for each PFT is equivilent to the
-! column profile, in the future, this could be changed to a weighted profile
- rsmn(p,j) = sminn_vr(c,j)
- if (root_depth(p) >= zi(c,j).or. &
- (zi(c,j-1) < root_depth(p) .and. zi(c,j) > root_depth(p))) then
- sumrsmn(p) = sumrsmn(p) + rsmn(p,j)
- end if
- end do
- end do
-
-
-!--------------------------------------------------------------------
-! Now calculate the density of roots in each soil layer for each pft
-! based on this timesteps growth
-!--------------------------------------------------------------------
- do lev = 1, nlevgrnd
-
- do f = 1, num_soilp
- p = filter_soilp(f)
- c = pcolumn(p)
-
- new_growth = (cpool_to_frootc(p) + frootc_xfer_to_frootc(p))*dt
- if(zi(c,lev) <= root_depth(p) .or. &
- (zi(c,lev-1) < root_depth(p) .and. zi(c,lev) > root_depth(p))) then
- if(sumrswa(p) <= 0._r8 .or. sumrsmn(p) <= 0._r8) then
-! when sumrswa or sumrsmn are less than or equal to 0 rootfr will not be updated
- else
- frootc_dz(p,lev) = (frootc(p))*rootfr(p,lev) &
- + new_growth * ((1._r8 - w_limit(p)) * rswa(p,lev) / sumrswa(p) &
- + w_limit(p) * rsmn(p,lev) / sumrsmn(p))
- end if
- else
- frootc_dz(p,lev) = 0._r8
- end if
-
- sumfrootc(p) = sumfrootc(p) + frootc_dz(p,lev)
-
- end do
- end do
-!----------------------------------
-!Calculate root fraction
-!----------------------------------
-
- do lev = 1, nlevgrnd
- do f = 1, num_soilp
- p = filter_soilp(f)
- c = pcolumn(p)
- if(sumfrootc(p) > 0._r8)then
- rootfr(p,lev) = frootc_dz(p,lev)/sumfrootc(p)
- end if
- if(ivt(p) >= npcropmin .and. .not. croplive(p))then
-! CROPS are dormant, there are no roots!
-! but, need an initial frootr so crops can start root production
- if (lev < 2)then
- rootfr(p,lev) = .5_r8*( exp(-roota_par(patch%itype(p)) * zi(c,lev-1)) &
- + exp(-rootb_par(patch%itype(p)) * zi(c,lev-1)) &
- - exp(-roota_par(patch%itype(p)) * zi(c,lev )) &
- - exp(-rootb_par(patch%itype(p)) * zi(c,lev )) )
- elseif (lev == 2) then
- rootfr(p,lev) = .5_r8*( exp(-roota_par(patch%itype(p)) * zi(c,lev-1)) &
- + exp(-rootb_par(patch%itype(p)) * zi(c,lev-1)) )
- else
- rootfr(p,lev) = 0.0_r8
- end if
-
- end if
- end do
- end do
-
-!**********************
- deallocate(sumrswa)
- deallocate(sumrsmn)
- deallocate(sumfrootc)
- deallocate(rsmn)
- deallocate(rswa)
- deallocate(w_limit)
-
- end associate
-
- end subroutine CNRootDyn
-
-end module CNRootDynMod
diff --git a/src/biogeochem/CNSharedParamsMod.F90 b/src/biogeochem/CNSharedParamsMod.F90
index f4f5eb3bac..a178a0f7f0 100644
--- a/src/biogeochem/CNSharedParamsMod.F90
+++ b/src/biogeochem/CNSharedParamsMod.F90
@@ -35,7 +35,7 @@ module CNSharedParamsMod
! Public data
- logical, public, parameter :: use_matrixcn = .false. ! true => use cn matrix solution
+ logical, public :: use_matrixcn = .false. ! true => use cn matrix solution
logical, public :: use_fun = .false. ! Use the FUN2.0 model
integer, public :: nlev_soildecomp_standard = 5
integer, public :: upper_soil_layer = -1 ! Upper soil layer to use for 10-day average in CNPhenology
diff --git a/src/biogeochem/CNVegCarbonFluxType.F90 b/src/biogeochem/CNVegCarbonFluxType.F90
index 8210bafc97..b4c581c081 100644
--- a/src/biogeochem/CNVegCarbonFluxType.F90
+++ b/src/biogeochem/CNVegCarbonFluxType.F90
@@ -9,10 +9,17 @@ module CNVegCarbonFluxType
use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
use shr_log_mod , only : errMsg => shr_log_errMsg
use decompMod , only : bounds_type
- use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con, use_soil_matrixcn
- use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_pools
- use clm_varpar , only : nvegcpool
+ use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con
+ use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_pools,&
+ nvegcpool,ncphtrans,ncgmtrans,ncfitrans,&
+ ncphouttrans,ncgmouttrans,ncfiouttrans
use clm_varpar , only : nlevdecomp_full, nlevdecomp, i_litr_min, i_litr_max
+ use clm_varpar , only : ileaf,ileaf_st,ileaf_xf,ifroot,ifroot_st,ifroot_xf,&
+ ilivestem,ilivestem_st,ilivestem_xf,&
+ ideadstem,ideadstem_st,ideadstem_xf,&
+ ilivecroot,ilivecroot_st,ilivecroot_xf,&
+ ideadcroot,ideadcroot_st,ideadcroot_xf,&
+ igrain,ioutc
use clm_varpar , only : mxharvests
use clm_varcon , only : spval, dzsoi_decomp
use clm_varctl , only : use_cndv, use_c13, use_c14, use_nitrif_denitrif, use_crop
@@ -402,11 +409,112 @@ module CNVegCarbonFluxType
real(r8), pointer :: npp_growth_patch (:) ! Total C u for growth in FUN (gC/m2/s)
real(r8), pointer :: leafc_change_patch (:) ! Total used C from leaves (gC/m2/s)
real(r8), pointer :: soilc_change_patch (:) ! Total used C from soil (gC/m2/s)
- integer, pointer :: actpatch_fire (:) ! Patch indices with fire in current time step
- integer :: num_actpatch_fire ! Number of patches with fire in current time step
! Matrix solution arrays for C flux index
+ real(r8), pointer :: matrix_Cinput_patch (:) ! I-matrix for carbon input
+ real(r8), pointer :: matrix_C13input_patch (:) ! I-matrix for C13 input
+ real(r8), pointer :: matrix_C14input_patch (:) ! I-matrix for C14 input
+ real(r8), pointer :: matrix_alloc_patch (:,:) ! B-matrix for carbon allocation
+
+ real(r8), pointer :: matrix_phtransfer_patch (:,:) ! A-matrix_phenology
+ real(r8), pointer :: matrix_phturnover_patch (:,:) ! K-matrix_phenology
+ integer, pointer :: matrix_phtransfer_doner_patch (:) ! A-matrix_phenology non-zero indices (column indices)
+ integer, pointer :: matrix_phtransfer_receiver_patch (:) ! A-matrix_phenology non-zero indices (row indices)
+
+ real(r8), pointer :: matrix_gmtransfer_patch (:,:) ! A-matrix_gap mortality
+ real(r8), pointer :: matrix_gmturnover_patch (:,:) ! K-matrix_gap mortality
+ integer, pointer :: matrix_gmtransfer_doner_patch (:) ! A-matrix_gap mortality non-zero indices (column indices)
+ integer, pointer :: matrix_gmtransfer_receiver_patch (:) ! A-matrix_gap mortality non-zero indices (row indices)
+
+ real(r8), pointer :: matrix_fitransfer_patch (:,:) ! A-matrix_fire
+ real(r8), pointer :: matrix_fiturnover_patch (:,:) ! K-matrix_fire
+ integer, pointer :: matrix_fitransfer_doner_patch (:) ! A-matrix_fire non-zero indices (column indices)
+ integer, pointer :: matrix_fitransfer_receiver_patch (:) ! A-matrix_fire non-zero indices (row indices)
+
! Matrix variables
+ integer ileafst_to_ileafxf_ph ! Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ integer ileafxf_to_ileaf_ph ! Index of phenology related C transfer from leaf transfer pool to leaf pool
+ integer ifrootst_to_ifrootxf_ph ! Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ integer ifrootxf_to_ifroot_ph ! Index of phenology related C transfer from fine root transfer pool to fine root pool
+ integer ilivestemst_to_ilivestemxf_ph ! Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ integer ilivestemxf_to_ilivestem_ph ! Index of phenology related C transfer from live stem transfer pool to live stem pool
+ integer ideadstemst_to_ideadstemxf_ph ! Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ integer ideadstemxf_to_ideadstem_ph ! Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ integer ilivecrootst_to_ilivecrootxf_ph ! Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ integer ilivecrootxf_to_ilivecroot_ph ! Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ integer ideadcrootst_to_ideadcrootxf_ph ! Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ integer ideadcrootxf_to_ideadcroot_ph ! Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ integer ilivestem_to_ideadstem_ph ! Index of phenology related C transfer from live stem pool to dead stem pool
+ integer ilivecroot_to_ideadcroot_ph ! Index of phenology related C transfer from live coarse root pool to dead coarse root pool
+ integer ileaf_to_iout_ph ! Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ integer ifroot_to_iout_ph ! Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ integer ilivestem_to_iout_ph ! Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ integer igrain_to_iout_ph ! Index of phenology related C transfer from grain pool to outside of vegetation pools
+ integer ileaf_to_iout_gm ! Index of gap mortality related C transfer from leaf pool to outside of vegetation pools
+ integer ileafst_to_iout_gm ! Index of gap mortality related C transfer from leaf storage pool to outside of vegetation pools
+ integer ileafxf_to_iout_gm ! Index of gap mortality related C transfer from leaf transfer pool to outside of vegetation pools
+ integer ifroot_to_iout_gm ! Index of gap mortality related C transfer from fine root pool to outside of vegetation pools
+ integer ifrootst_to_iout_gm ! Index of gap mortality related C transfer from fine root storage pool to outside of vegetation pools
+ integer ifrootxf_to_iout_gm ! Index of gap mortality related C transfer from fine root transfer pool to outside of vegetation pools
+ integer ilivestem_to_iout_gm ! Index of gap mortality related C transfer from live stem pool to outside of vegetation pools
+ integer ilivestemst_to_iout_gm ! Index of gap mortality related C transfer from live stem storage pool to outside of vegetation pools
+ integer ilivestemxf_to_iout_gm ! Index of gap mortality related C transfer from live stem transfer pool to outside of vegetation pools
+ integer ideadstem_to_iout_gm ! Index of gap mortality related C transfer from dead stem pool to outside of vegetation pools
+ integer ideadstemst_to_iout_gm ! Index of gap mortality related C transfer from dead stem storage pool to outside of vegetation pools
+ integer ideadstemxf_to_iout_gm ! Index of gap mortality related C transfer from dead stem transfer pool to outside of vegetation pools
+ integer ilivecroot_to_iout_gm ! Index of gap mortality related C transfer from live coarse root pool to outside of vegetation pools
+ integer ilivecrootst_to_iout_gm ! Index of gap mortality related C transfer from live coarse root storage pool to outside of vegetation pools
+ integer ilivecrootxf_to_iout_gm ! Index of gap mortality related C transfer from live coarse root transfer pool to outside of vegetation pools
+ integer ideadcroot_to_iout_gm ! Index of gap mortality related C transfer from dead coarse root pool to outside of vegetation pools
+ integer ideadcrootst_to_iout_gm ! Index of gap mortality related C transfer from dead coarse root storage pool to outside of vegetation pools
+ integer ideadcrootxf_to_iout_gm ! Index of gap mortality related C transfer from dead coarse root transfer pool to outside of vegetation pools
+ integer ileaf_to_iout_fi ! Index of fire related C transfer from leaf pool to outside of vegetation pools
+ integer ileafst_to_iout_fi ! Index of fire related C transfer from leaf storage pool to outside of vegetation pools
+ integer ileafxf_to_iout_fi ! Index of fire related C transfer from leaf transfer pool to outside of vegetation pools
+ integer ifroot_to_iout_fi ! Index of fire related C transfer from fine root pool to outside of vegetation pools
+ integer ifrootst_to_iout_fi ! Index of fire related C transfer from fine root storage pool to outside of vegetation pools
+ integer ifrootxf_to_iout_fi ! Index of fire related C transfer from fine root transfer pool to outside of vegetation pools
+ integer ilivestem_to_iout_fi ! Index of fire related C transfer from live stem pool to outside of vegetation pools
+ integer ilivestemst_to_iout_fi ! Index of fire related C transfer from live stem storage pool to outside of vegetation pools
+ integer ilivestemxf_to_iout_fi ! Index of fire related C transfer from live stem transfer pool to outside of vegetation pools
+ integer ideadstem_to_iout_fi ! Index of fire related C transfer from dead stem pool to outside of vegetation pools
+ integer ideadstemst_to_iout_fi ! Index of fire related C transfer from dead stem storage pool to outside of vegetation pools
+ integer ideadstemxf_to_iout_fi ! Index of fire related C transfer from dead stem transfer pool to outside of vegetation pools
+ integer ilivecroot_to_iout_fi ! Index of fire related C transfer from live coarse root pool to outside of vegetation pools
+ integer ilivecrootst_to_iout_fi ! Index of fire related C transfer from live coarse root storage pool to outside of vegetation pools
+ integer ilivecrootxf_to_iout_fi ! Index of fire related C transfer from live coarse root transfer pool to outside of vegetation pools
+ integer ideadcroot_to_iout_fi ! Index of fire related C transfer from dead coarse root pool to outside of vegetation pools
+ integer ideadcrootst_to_iout_fi ! Index of fire related C transfer from dead coarse root storage pool to outside of vegetation pools
+ integer ideadcrootxf_to_iout_fi ! Index of fire related C transfer from dead coarse root transfer pool to outside of vegetation pools
+ integer ilivestem_to_ideadstem_fi ! Index of fire related C transfer from live stem pool to dead stem pools
+ integer ilivecroot_to_ideadcroot_fi ! Index of fire related C transfer from live coarse root pool to dead coarse root pools
+
+ integer,pointer :: list_phc_phgmc (:) ! Index mapping for sparse matrix addition (save to reduce computational cost): from AKphc to AKphc+AKgmc
+ integer,pointer :: list_gmc_phgmc (:) ! Index mapping for sparse matrix addition (save to reduce computational cost): from AKgmc to AKphc+AKgmc
+ integer,pointer :: list_phc_phgmfic (:) ! Index mapping for sparse matrix addition (save to reduce computational cost): from AKphc to AKphc+AKgmc+AKfic
+ integer,pointer :: list_gmc_phgmfic (:) ! Index mapping for sparse matrix addition (save to reduce computational cost): from AKgmc to AKphc+AKgmc+AKfic
+ integer,pointer :: list_fic_phgmfic (:) ! Index mapping for sparse matrix addition (save to reduce computational cost): from AKfic to AKphc+AKgmc+AKfic
+ integer,pointer :: list_aphc (:) ! Indices of non-diagnoal entries in full sparse matrix Aph for C cycle
+ integer,pointer :: list_agmc (:) ! Indices of non-diagnoal entries in full sparse matrix Agm for C cycle
+ integer,pointer :: list_afic (:) ! Indices of non-diagnoal entries in full sparse matrix Afi for C cycle
+
+ type(sparse_matrix_type) :: AKphvegc ! Aph*Kph for C cycle in sparse matrix format
+ type(sparse_matrix_type) :: AKgmvegc ! Agm*Kgm for C cycle in sparse matrix format
+ type(sparse_matrix_type) :: AKfivegc ! Afi*Kfi for C cycle in sparse matrix format
+ type(sparse_matrix_type) :: AKallvegc ! Aph*Kph + Agm*Kgm + Afi*Kfi for C cycle in sparse matrix format
+ integer :: NE_AKallvegc ! Number of entries in AKallvegc
+ integer,pointer,dimension(:) :: RI_AKallvegc ! Row indices in Akallvegc
+ integer,pointer,dimension(:) :: CI_AKallvegc ! Column indices in AKallvegc
+ integer,pointer,dimension(:) :: RI_phc ! Row indices of non-diagonal entires in Aph for C cycle
+ integer,pointer,dimension(:) :: CI_phc ! Column indices of non-diagonal entries in Aph for C cycle
+ integer,pointer,dimension(:) :: RI_gmc ! Row indices of non-diagonal entires in Agm for C cycle
+ integer,pointer,dimension(:) :: CI_gmc ! Column indices of non-diagonal entries in Agm for C cycle
+ integer,pointer,dimension(:) :: RI_fic ! Row indices of non-diagonal entires in Afi for C cycle
+ integer,pointer,dimension(:) :: CI_fic ! Column indices of non-diagonal entries in Afi for C cycle
+ type(diag_matrix_type) :: Kvegc ! Temporary variable of Kph, Kgm or Kfi for C cycle in diagonal matrix format
+ type(vector_type) :: Xvegc ! Vegetation C of each compartment in a vector format
+ type(vector_type) :: Xveg13c ! Vegetation C13 of each compartment in a vector format
+ type(vector_type) :: Xveg14c ! Vegetation C14 of each compartment in a vector format
! Objects that help convert once-per-year dynamic land cover changes into fluxes
! that are dribbled throughout the year
@@ -463,7 +571,233 @@ subroutine InitTransfer (this)
!
! !AGRUMENTS:
class (cnveg_carbonflux_type) :: this
-
+
+ this%ileafst_to_ileafxf_ph = 1
+ this%matrix_phtransfer_doner_patch(this%ileafst_to_ileafxf_ph) = ileaf_st
+ this%matrix_phtransfer_receiver_patch(this%ileafst_to_ileafxf_ph) = ileaf_xf
+
+ this%ileafxf_to_ileaf_ph = 2
+ this%matrix_phtransfer_doner_patch(this%ileafxf_to_ileaf_ph) = ileaf_xf
+ this%matrix_phtransfer_receiver_patch(this%ileafxf_to_ileaf_ph) = ileaf
+
+ this%ifrootst_to_ifrootxf_ph = 3
+ this%matrix_phtransfer_doner_patch(this%ifrootst_to_ifrootxf_ph) = ifroot_st
+ this%matrix_phtransfer_receiver_patch(this%ifrootst_to_ifrootxf_ph) = ifroot_xf
+
+ this%ifrootxf_to_ifroot_ph = 4
+ this%matrix_phtransfer_doner_patch(this%ifrootxf_to_ifroot_ph) = ifroot_xf
+ this%matrix_phtransfer_receiver_patch(this%ifrootxf_to_ifroot_ph) = ifroot
+
+ this%ilivestem_to_ideadstem_ph = 5
+ this%matrix_phtransfer_doner_patch(this%ilivestem_to_ideadstem_ph) = ilivestem
+ this%matrix_phtransfer_receiver_patch(this%ilivestem_to_ideadstem_ph) = ideadstem
+
+ this%ilivestemst_to_ilivestemxf_ph = 6
+ this%matrix_phtransfer_doner_patch(this%ilivestemst_to_ilivestemxf_ph) = ilivestem_st
+ this%matrix_phtransfer_receiver_patch(this%ilivestemst_to_ilivestemxf_ph) = ilivestem_xf
+
+ this%ilivestemxf_to_ilivestem_ph = 7
+ this%matrix_phtransfer_doner_patch(this%ilivestemxf_to_ilivestem_ph) = ilivestem_xf
+ this%matrix_phtransfer_receiver_patch(this%ilivestemxf_to_ilivestem_ph) = ilivestem
+
+ this%ideadstemst_to_ideadstemxf_ph = 8
+ this%matrix_phtransfer_doner_patch(this%ideadstemst_to_ideadstemxf_ph) = ideadstem_st
+ this%matrix_phtransfer_receiver_patch(this%ideadstemst_to_ideadstemxf_ph) = ideadstem_xf
+
+ this%ideadstemxf_to_ideadstem_ph = 9
+ this%matrix_phtransfer_doner_patch(this%ideadstemxf_to_ideadstem_ph) = ideadstem_xf
+ this%matrix_phtransfer_receiver_patch(this%ideadstemxf_to_ideadstem_ph) = ideadstem
+
+ this%ilivecroot_to_ideadcroot_ph = 10
+ this%matrix_phtransfer_doner_patch(this%ilivecroot_to_ideadcroot_ph) = ilivecroot
+ this%matrix_phtransfer_receiver_patch(this%ilivecroot_to_ideadcroot_ph) = ideadcroot
+
+ this%ilivecrootst_to_ilivecrootxf_ph = 11
+ this%matrix_phtransfer_doner_patch(this%ilivecrootst_to_ilivecrootxf_ph) = ilivecroot_st
+ this%matrix_phtransfer_receiver_patch(this%ilivecrootst_to_ilivecrootxf_ph) = ilivecroot_xf
+
+ this%ilivecrootxf_to_ilivecroot_ph = 12
+ this%matrix_phtransfer_doner_patch(this%ilivecrootxf_to_ilivecroot_ph) = ilivecroot_xf
+ this%matrix_phtransfer_receiver_patch(this%ilivecrootxf_to_ilivecroot_ph) = ilivecroot
+
+ this%ideadcrootst_to_ideadcrootxf_ph = 13
+ this%matrix_phtransfer_doner_patch(this%ideadcrootst_to_ideadcrootxf_ph) = ideadcroot_st
+ this%matrix_phtransfer_receiver_patch(this%ideadcrootst_to_ideadcrootxf_ph) = ideadcroot_xf
+
+ this%ideadcrootxf_to_ideadcroot_ph = 14
+ this%matrix_phtransfer_doner_patch(this%ideadcrootxf_to_ideadcroot_ph) = ideadcroot_xf
+ this%matrix_phtransfer_receiver_patch(this%ideadcrootxf_to_ideadcroot_ph) = ideadcroot
+
+ this%ileaf_to_iout_ph = 15
+ this%matrix_phtransfer_doner_patch(this%ileaf_to_iout_ph) = ileaf
+ this%matrix_phtransfer_receiver_patch(this%ileaf_to_iout_ph) = ioutc
+
+ this%ifroot_to_iout_ph = 16
+ this%matrix_phtransfer_doner_patch(this%ifroot_to_iout_ph) = ifroot
+ this%matrix_phtransfer_receiver_patch(this%ifroot_to_iout_ph) = ioutc
+
+ this%ilivestem_to_iout_ph = 17
+ this%matrix_phtransfer_doner_patch(this%ilivestem_to_iout_ph) = ilivestem
+ this%matrix_phtransfer_receiver_patch(this%ilivestem_to_iout_ph) = ioutc
+
+ if(use_crop)then
+ this%igrain_to_iout_ph = 18
+ this%matrix_phtransfer_doner_patch(this%igrain_to_iout_ph) = igrain
+ this%matrix_phtransfer_receiver_patch(this%igrain_to_iout_ph) = ioutc
+ end if
+
+ this%ileaf_to_iout_gm = 1
+ this%matrix_gmtransfer_doner_patch(this%ileaf_to_iout_gm) = ileaf
+ this%matrix_gmtransfer_receiver_patch(this%ileaf_to_iout_gm) = ioutc
+
+ this%ileafst_to_iout_gm = 2
+ this%matrix_gmtransfer_doner_patch(this%ileafst_to_iout_gm) = ileaf_st
+ this%matrix_gmtransfer_receiver_patch(this%ileafst_to_iout_gm) = ioutc
+
+ this%ileafxf_to_iout_gm = 3
+ this%matrix_gmtransfer_doner_patch(this%ileafxf_to_iout_gm) = ileaf_xf
+ this%matrix_gmtransfer_receiver_patch(this%ileafxf_to_iout_gm) = ioutc
+
+ this%ifroot_to_iout_gm = 4
+ this%matrix_gmtransfer_doner_patch(this%ifroot_to_iout_gm) = ifroot
+ this%matrix_gmtransfer_receiver_patch(this%ifroot_to_iout_gm) = ioutc
+
+ this%ifrootst_to_iout_gm = 5
+ this%matrix_gmtransfer_doner_patch(this%ifrootst_to_iout_gm) = ifroot_st
+ this%matrix_gmtransfer_receiver_patch(this%ifrootst_to_iout_gm) = ioutc
+
+ this%ifrootxf_to_iout_gm = 6
+ this%matrix_gmtransfer_doner_patch(this%ifrootxf_to_iout_gm) = ifroot_xf
+ this%matrix_gmtransfer_receiver_patch(this%ifrootxf_to_iout_gm) = ioutc
+
+ this%ilivestem_to_iout_gm = 7
+ this%matrix_gmtransfer_doner_patch(this%ilivestem_to_iout_gm) = ilivestem
+ this%matrix_gmtransfer_receiver_patch(this%ilivestem_to_iout_gm) = ioutc
+
+ this%ilivestemst_to_iout_gm = 8
+ this%matrix_gmtransfer_doner_patch(this%ilivestemst_to_iout_gm) = ilivestem_st
+ this%matrix_gmtransfer_receiver_patch(this%ilivestemst_to_iout_gm) = ioutc
+
+ this%ilivestemxf_to_iout_gm = 9
+ this%matrix_gmtransfer_doner_patch(this%ilivestemxf_to_iout_gm) = ilivestem_xf
+ this%matrix_gmtransfer_receiver_patch(this%ilivestemxf_to_iout_gm) = ioutc
+
+ this%ideadstem_to_iout_gm = 10
+ this%matrix_gmtransfer_doner_patch(this%ideadstem_to_iout_gm) = ideadstem
+ this%matrix_gmtransfer_receiver_patch(this%ideadstem_to_iout_gm) = ioutc
+
+ this%ideadstemst_to_iout_gm = 11
+ this%matrix_gmtransfer_doner_patch(this%ideadstemst_to_iout_gm) = ideadstem_st
+ this%matrix_gmtransfer_receiver_patch(this%ideadstemst_to_iout_gm) = ioutc
+
+ this%ideadstemxf_to_iout_gm = 12
+ this%matrix_gmtransfer_doner_patch(this%ideadstemxf_to_iout_gm) = ideadstem_xf
+ this%matrix_gmtransfer_receiver_patch(this%ideadstemxf_to_iout_gm) = ioutc
+
+ this%ilivecroot_to_iout_gm = 13
+ this%matrix_gmtransfer_doner_patch(this%ilivecroot_to_iout_gm) = ilivecroot
+ this%matrix_gmtransfer_receiver_patch(this%ilivecroot_to_iout_gm) = ioutc
+
+ this%ilivecrootst_to_iout_gm = 14
+ this%matrix_gmtransfer_doner_patch(this%ilivecrootst_to_iout_gm) = ilivecroot_st
+ this%matrix_gmtransfer_receiver_patch(this%ilivecrootst_to_iout_gm) = ioutc
+
+ this%ilivecrootxf_to_iout_gm = 15
+ this%matrix_gmtransfer_doner_patch(this%ilivecrootxf_to_iout_gm) = ilivecroot_xf
+ this%matrix_gmtransfer_receiver_patch(this%ilivecrootxf_to_iout_gm) = ioutc
+
+ this%ideadcroot_to_iout_gm = 16
+ this%matrix_gmtransfer_doner_patch(this%ideadcroot_to_iout_gm) = ideadcroot
+ this%matrix_gmtransfer_receiver_patch(this%ideadcroot_to_iout_gm) = ioutc
+
+ this%ideadcrootst_to_iout_gm = 17
+ this%matrix_gmtransfer_doner_patch(this%ideadcrootst_to_iout_gm) = ideadcroot_st
+ this%matrix_gmtransfer_receiver_patch(this%ideadcrootst_to_iout_gm) = ioutc
+
+ this%ideadcrootxf_to_iout_gm = 18
+ this%matrix_gmtransfer_doner_patch(this%ideadcrootxf_to_iout_gm) = ideadcroot_xf
+ this%matrix_gmtransfer_receiver_patch(this%ideadcrootxf_to_iout_gm) = ioutc
+
+ this%ilivestem_to_ideadstem_fi = 1
+ this%matrix_fitransfer_doner_patch(this%ilivestem_to_ideadstem_fi) = ilivestem
+ this%matrix_fitransfer_receiver_patch(this%ilivestem_to_ideadstem_fi) = ideadstem
+
+ this%ilivecroot_to_ideadcroot_fi = 2
+ this%matrix_fitransfer_doner_patch(this%ilivecroot_to_ideadcroot_fi) = ilivecroot
+ this%matrix_fitransfer_receiver_patch(this%ilivecroot_to_ideadcroot_fi) = ideadcroot
+
+ this%ileaf_to_iout_fi = 3
+ this%matrix_fitransfer_doner_patch(this%ileaf_to_iout_fi) = ileaf
+ this%matrix_fitransfer_receiver_patch(this%ileaf_to_iout_fi) = ioutc
+
+ this%ileafst_to_iout_fi = 4
+ this%matrix_fitransfer_doner_patch(this%ileafst_to_iout_fi) = ileaf_st
+ this%matrix_fitransfer_receiver_patch(this%ileafst_to_iout_fi) = ioutc
+
+ this%ileafxf_to_iout_fi = 5
+ this%matrix_fitransfer_doner_patch(this%ileafxf_to_iout_fi) = ileaf_xf
+ this%matrix_fitransfer_receiver_patch(this%ileafxf_to_iout_fi) = ioutc
+
+ this%ifroot_to_iout_fi = 6
+ this%matrix_fitransfer_doner_patch(this%ifroot_to_iout_fi) = ifroot
+ this%matrix_fitransfer_receiver_patch(this%ifroot_to_iout_fi) = ioutc
+
+ this%ifrootst_to_iout_fi = 7
+ this%matrix_fitransfer_doner_patch(this%ifrootst_to_iout_fi) = ifroot_st
+ this%matrix_fitransfer_receiver_patch(this%ifrootst_to_iout_fi) = ioutc
+
+ this%ifrootxf_to_iout_fi = 8
+ this%matrix_fitransfer_doner_patch(this%ifrootxf_to_iout_fi) = ifroot_xf
+ this%matrix_fitransfer_receiver_patch(this%ifrootxf_to_iout_fi) = ioutc
+
+ this%ilivestem_to_iout_fi = 9
+ this%matrix_fitransfer_doner_patch(this%ilivestem_to_iout_fi) = ilivestem
+ this%matrix_fitransfer_receiver_patch(this%ilivestem_to_iout_fi) = ioutc
+
+ this%ilivestemst_to_iout_fi = 10
+ this%matrix_fitransfer_doner_patch(this%ilivestemst_to_iout_fi) = ilivestem_st
+ this%matrix_fitransfer_receiver_patch(this%ilivestemst_to_iout_fi) = ioutc
+
+ this%ilivestemxf_to_iout_fi = 11
+ this%matrix_fitransfer_doner_patch(this%ilivestemxf_to_iout_fi) = ilivestem_xf
+ this%matrix_fitransfer_receiver_patch(this%ilivestemxf_to_iout_fi) = ioutc
+
+ this%ideadstem_to_iout_fi = 12
+ this%matrix_fitransfer_doner_patch(this%ideadstem_to_iout_fi) = ideadstem
+ this%matrix_fitransfer_receiver_patch(this%ideadstem_to_iout_fi) = ioutc
+
+ this%ideadstemst_to_iout_fi = 13
+ this%matrix_fitransfer_doner_patch(this%ideadstemst_to_iout_fi) = ideadstem_st
+ this%matrix_fitransfer_receiver_patch(this%ideadstemst_to_iout_fi) = ioutc
+
+ this%ideadstemxf_to_iout_fi = 14
+ this%matrix_fitransfer_doner_patch(this%ideadstemxf_to_iout_fi) = ideadstem_xf
+ this%matrix_fitransfer_receiver_patch(this%ideadstemxf_to_iout_fi) = ioutc
+
+ this%ilivecroot_to_iout_fi = 15
+ this%matrix_fitransfer_doner_patch(this%ilivecroot_to_iout_fi) = ilivecroot
+ this%matrix_fitransfer_receiver_patch(this%ilivecroot_to_iout_fi) = ioutc
+
+ this%ilivecrootst_to_iout_fi = 16
+ this%matrix_fitransfer_doner_patch(this%ilivecrootst_to_iout_fi) = ilivecroot_st
+ this%matrix_fitransfer_receiver_patch(this%ilivecrootst_to_iout_fi) = ioutc
+
+ this%ilivecrootxf_to_iout_fi = 17
+ this%matrix_fitransfer_doner_patch(this%ilivecrootxf_to_iout_fi) = ilivecroot_xf
+ this%matrix_fitransfer_receiver_patch(this%ilivecrootxf_to_iout_fi) = ioutc
+
+ this%ideadcroot_to_iout_fi = 18
+ this%matrix_fitransfer_doner_patch(this%ideadcroot_to_iout_fi) = ideadcroot
+ this%matrix_fitransfer_receiver_patch(this%ideadcroot_to_iout_fi) = ioutc
+
+ this%ideadcrootst_to_iout_fi = 19
+ this%matrix_fitransfer_doner_patch(this%ideadcrootst_to_iout_fi) = ideadcroot_st
+ this%matrix_fitransfer_receiver_patch(this%ideadcrootst_to_iout_fi) = ioutc
+
+ this%ideadcrootxf_to_iout_fi = 20
+ this%matrix_fitransfer_doner_patch(this%ideadcrootxf_to_iout_fi) = ideadcroot_xf
+ this%matrix_fitransfer_receiver_patch(this%ideadcrootxf_to_iout_fi) = ioutc
+
end subroutine InitTransfer
!------------------------------------------------------------------------
@@ -839,6 +1173,58 @@ subroutine InitAllocate(this, bounds, carbon_type, alloc_full_veg)
allocate(this%soilc_change_patch (begp:endp)) ; this%soilc_change_patch (:) = nan
! Allocate Matrix data
if(use_matrixcn)then
+ allocate(this%matrix_Cinput_patch (begp:endp)) ; this%matrix_Cinput_patch (:) = nan
+ allocate(this%matrix_C13input_patch (begp:endp)) ; this%matrix_C13input_patch (:) = nan !for isotop
+ allocate(this%matrix_C14input_patch (begp:endp)) ; this%matrix_C14input_patch (:) = nan
+ allocate(this%matrix_alloc_patch (begp:endp,1:nvegcpool)) ; this%matrix_alloc_patch (:,:) = nan
+
+ allocate(this%matrix_phtransfer_patch (begp:endp,1:ncphtrans)) ; this%matrix_phtransfer_patch (:,:) = nan
+ allocate(this%matrix_phturnover_patch (begp:endp,1:nvegcpool)) ; this%matrix_phturnover_patch (:,:) = nan
+ allocate(this%matrix_phtransfer_doner_patch (1:ncphtrans)) ; this%matrix_phtransfer_doner_patch(:) = -9999
+ allocate(this%matrix_phtransfer_receiver_patch (1:ncphtrans)) ; this%matrix_phtransfer_receiver_patch(:) = -9999
+
+ allocate(this%matrix_gmtransfer_patch (begp:endp,1:ncgmtrans)) ; this%matrix_gmtransfer_patch (:,:) = nan
+ allocate(this%matrix_gmturnover_patch (begp:endp,1:nvegcpool)) ; this%matrix_gmturnover_patch (:,:) = nan
+ allocate(this%matrix_gmtransfer_doner_patch (1:ncgmtrans)) ; this%matrix_gmtransfer_doner_patch(:) = -9999
+ allocate(this%matrix_gmtransfer_receiver_patch (1:ncgmtrans)) ; this%matrix_gmtransfer_receiver_patch(:) = -9999
+
+ allocate(this%matrix_fitransfer_patch (begp:endp,1:ncfitrans)) ; this%matrix_fitransfer_patch (:,:) = nan
+ allocate(this%matrix_fiturnover_patch (begp:endp,1:nvegcpool)) ; this%matrix_fiturnover_patch (:,:) = nan
+ allocate(this%matrix_fitransfer_doner_patch (1:ncfitrans)) ; this%matrix_fitransfer_doner_patch(:) = -9999
+ allocate(this%matrix_fitransfer_receiver_patch (1:ncfitrans)) ; this%matrix_fitransfer_receiver_patch(:) = -9999
+
+ allocate(this%list_phc_phgmc (1:ncphtrans+nvegcpool)) ; this%list_phc_phgmc(:) = -9999
+ allocate(this%list_gmc_phgmc (1:nvegcpool)) ; this%list_gmc_phgmc(:) = -9999
+ allocate(this%list_phc_phgmfic (1:ncphtrans+nvegcpool)); this%list_phc_phgmfic(:) = -9999
+ allocate(this%list_gmc_phgmfic (1:nvegcpool)) ; this%list_gmc_phgmfic(:) = -9999
+ allocate(this%list_fic_phgmfic (1:ncfitrans+nvegcpool)); this%list_fic_phgmfic(:) = -9999
+
+ allocate(this%list_aphc(1:ncphtrans-ncphouttrans)); this%list_aphc = -9999
+ allocate(this%list_agmc(1:ncgmtrans-ncgmouttrans)); this%list_agmc = -9999
+ allocate(this%list_afic(1:ncfitrans-ncfiouttrans)); this%list_afic = -9999
+
+ call this%AKphvegc%InitSM(nvegcpool,begp,endp,ncphtrans-ncphouttrans+nvegcpool)
+ call this%AKgmvegc%InitSM(nvegcpool,begp,endp,ncgmtrans-ncgmouttrans+nvegcpool)
+ call this%AKfivegc%InitSM(nvegcpool,begp,endp,ncfitrans-ncfiouttrans+nvegcpool)
+ call this%AKallvegc%InitSM(nvegcpool,begp,endp,ncphtrans-ncphouttrans+ncfitrans-ncfiouttrans+nvegcpool)
+ this%NE_AKallvegc = (ncphtrans-ncphouttrans+nvegcpool) + (ncgmtrans-ncgmouttrans+nvegcpool) + &
+ ncfitrans-ncfiouttrans+nvegcpool
+ allocate(this%RI_AKallvegc(1:this%NE_AKallvegc));this%RI_AKallvegc(:) = -9999
+ allocate(this%CI_AKallvegc(1:this%NE_AKallvegc));this%CI_AKallvegc(:) = -9999
+ allocate(this%RI_phc(1:ncphtrans-ncphouttrans+nvegcpool));this%RI_phc(:) = -9999
+ allocate(this%CI_phc(1:ncphtrans-ncphouttrans+nvegcpool));this%CI_phc(:) = -9999
+ allocate(this%RI_gmc(1:ncgmtrans-ncgmouttrans+nvegcpool));this%RI_gmc(:) = -9999
+ allocate(this%CI_gmc(1:ncgmtrans-ncgmouttrans+nvegcpool));this%CI_gmc(:) = -9999
+ allocate(this%RI_fic(1:ncfitrans-ncfiouttrans+nvegcpool));this%RI_fic(:) = -9999
+ allocate(this%CI_fic(1:ncfitrans-ncfiouttrans+nvegcpool));this%CI_fic(:) = -9999
+ call this%Kvegc%InitDM(nvegcpool,begp,endp)
+ call this%Xvegc%InitV(nvegcpool,begp,endp)
+ if(use_c13)then
+ call this%Xveg13c%InitV(nvegcpool,begp,endp)
+ end if
+ if(use_c14)then
+ call this%Xveg14c%InitV(nvegcpool,begp,endp)
+ end if
end if
! Construct restart field names consistently to what is done in SpeciesNonIsotope &
@@ -3574,6 +3960,9 @@ subroutine InitCold(this, bounds)
if (lun%ifspecial(l)) then
this%availc_patch(p) = spval
if(use_matrixcn)then
+ this%matrix_Cinput_patch(p) = spval
+ this%matrix_C13input_patch(p) = spval
+ this%matrix_C14input_patch(p) = spval
end if
this%xsmrpool_recover_patch(p) = spval
this%excess_cflux_patch(p) = spval
@@ -3588,6 +3977,9 @@ subroutine InitCold(this, bounds)
if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then
this%availc_patch(p) = 0._r8
if(use_matrixcn)then
+ this%matrix_Cinput_patch(p) = 0._r8
+ this%matrix_C13input_patch(p) = 0._r8
+ this%matrix_C14input_patch(p) = 0._r8
end if
this%xsmrpool_recover_patch(p) = 0._r8
this%excess_cflux_patch(p) = 0._r8
@@ -4194,6 +4586,9 @@ subroutine SetValues ( this, nvegcpool, &
this%crop_harvestc_to_cropprodc_patch(i) = value_patch
! Matrix
if(use_matrixcn)then
+ this%matrix_Cinput_patch(i) = value_patch
+ this%matrix_C13input_patch(i) = value_patch
+ this%matrix_C14input_patch(i) = value_patch
end if
end do
@@ -4208,6 +4603,36 @@ subroutine SetValues ( this, nvegcpool, &
! Set Matrix elements
if(use_matrixcn)then
+ do j = 1, nvegcpool
+ do fi = 1,num_patch
+ i = filter_patch(fi)
+ this%matrix_alloc_patch(i,j) = value_patch
+ this%matrix_phturnover_patch (i,j) = value_patch
+ this%matrix_gmturnover_patch (i,j) = value_patch
+ this%matrix_fiturnover_patch (i,j) = value_patch
+ end do
+ end do
+
+ do j = 1, ncphtrans
+ do fi = 1,num_patch
+ i = filter_patch(fi)
+ this%matrix_phtransfer_patch (i,j) = value_patch
+ end do
+ end do
+
+ do j = 1, ncgmtrans
+ do fi = 1,num_patch
+ i = filter_patch(fi)
+ this%matrix_gmtransfer_patch (i,j) = value_patch
+ end do
+ end do
+
+ do j = 1, ncfitrans
+ do fi = 1,num_patch
+ i = filter_patch(fi)
+ this%matrix_fitransfer_patch (i,j) = value_patch
+ end do
+ end do
end if
if ( use_crop )then
diff --git a/src/biogeochem/CNVegCarbonStateType.F90 b/src/biogeochem/CNVegCarbonStateType.F90
index c7e21da1d6..aee328a45e 100644
--- a/src/biogeochem/CNVegCarbonStateType.F90
+++ b/src/biogeochem/CNVegCarbonStateType.F90
@@ -9,7 +9,7 @@ module CNVegCarbonStateType
use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
use shr_const_mod , only : SHR_CONST_PDB
use shr_log_mod , only : errMsg => shr_log_errMsg
- use pftconMod , only : noveg, npcropmin, pftcon, nc3crop, nc3irrig
+ use pftconMod , only : noveg, npcropmin, pftcon, nc3crop, nc3irrig
use clm_varcon , only : spval, c3_r2, c4_r2, c14ratio
use clm_varctl , only : iulog, use_cndv, use_crop
use CNSharedParamsMod, only : use_matrixcn
@@ -36,33 +36,50 @@ module CNVegCarbonStateType
real(r8), pointer :: reproductivec_patch (:,:) ! (gC/m2) reproductive (e.g., grain) C (crop model)
real(r8), pointer :: reproductivec_storage_patch (:,:) ! (gC/m2) reproductive (e.g., grain) C storage (crop model)
real(r8), pointer :: reproductivec_xfer_patch (:,:) ! (gC/m2) reproductive (e.g., grain) C transfer (crop model)
+ real(r8), pointer :: matrix_cap_reproc_patch (:) ! (gC/m2) Capacity of grain C
+ real(r8), pointer :: matrix_cap_reproc_storage_patch (:) ! (gC/m2) Capacity of grain storage C
+ real(r8), pointer :: matrix_cap_reproc_xfer_patch (:) ! (gC/m2) Capacity of grain transfer C
real(r8), pointer :: leafc_patch (:) ! (gC/m2) leaf C
real(r8), pointer :: leafc_storage_patch (:) ! (gC/m2) leaf C storage
real(r8), pointer :: leafc_xfer_patch (:) ! (gC/m2) leaf C transfer
+ real(r8), pointer :: matrix_cap_leafc_patch (:) ! (gC/m2) Capacity of leaf C
+ real(r8), pointer :: matrix_cap_leafc_storage_patch (:) ! (gC/m2) Capacity of leaf C storage
+ real(r8), pointer :: matrix_cap_leafc_xfer_patch (:) ! (gC/m2) Capacity of leaf C transfer
real(r8), pointer :: leafc_storage_xfer_acc_patch (:) ! (gC/m2) Accmulated leaf C transfer
real(r8), pointer :: storage_cdemand_patch (:) ! (gC/m2) C use from the C storage pool
real(r8), pointer :: frootc_patch (:) ! (gC/m2) fine root C
real(r8), pointer :: frootc_storage_patch (:) ! (gC/m2) fine root C storage
real(r8), pointer :: frootc_xfer_patch (:) ! (gC/m2) fine root C transfer
+ real(r8), pointer :: matrix_cap_frootc_patch (:) ! (gC/m2) Capacity of fine root C
+ real(r8), pointer :: matrix_cap_frootc_storage_patch (:) ! (gC/m2) Capacity of fine root C storage
+ real(r8), pointer :: matrix_cap_frootc_xfer_patch (:) ! (gC/m2) Capacity of fine root C transfer
real(r8), pointer :: livestemc_patch (:) ! (gC/m2) live stem C
real(r8), pointer :: livestemc_storage_patch (:) ! (gC/m2) live stem C storage
real(r8), pointer :: livestemc_xfer_patch (:) ! (gC/m2) live stem C transfer
+ real(r8), pointer :: matrix_cap_livestemc_patch (:) ! (gC/m2) Capacity of live stem C
+ real(r8), pointer :: matrix_cap_livestemc_storage_patch (:) ! (gC/m2) Capacity of live stem C storage
+ real(r8), pointer :: matrix_cap_livestemc_xfer_patch (:) ! (gC/m2) Capacity of live stem C transfer
real(r8), pointer :: deadstemc_patch (:) ! (gC/m2) dead stem C
real(r8), pointer :: deadstemc_storage_patch (:) ! (gC/m2) dead stem C storage
real(r8), pointer :: deadstemc_xfer_patch (:) ! (gC/m2) dead stem C transfer
+ real(r8), pointer :: matrix_cap_deadstemc_patch (:) ! (gC/m2) Capacity of dead stem C
+ real(r8), pointer :: matrix_cap_deadstemc_storage_patch (:) ! (gC/m2) Capacity of dead stem C storage
+ real(r8), pointer :: matrix_cap_deadstemc_xfer_patch (:) ! (gC/m2) Capacity of dead stem C transfer
real(r8), pointer :: livecrootc_patch (:) ! (gC/m2) live coarse root C
real(r8), pointer :: livecrootc_storage_patch (:) ! (gC/m2) live coarse root C storage
real(r8), pointer :: livecrootc_xfer_patch (:) ! (gC/m2) live coarse root C transfer
+ real(r8), pointer :: matrix_cap_livecrootc_patch (:) ! (gC/m2) Capacity of live coarse root C
+ real(r8), pointer :: matrix_cap_livecrootc_storage_patch (:) ! (gC/m2) Capacity of live coarse root C storage
+ real(r8), pointer :: matrix_cap_livecrootc_xfer_patch (:) ! (gC/m2) Capacity of live coarse root C transfer
real(r8), pointer :: deadcrootc_patch (:) ! (gC/m2) dead coarse root C
real(r8), pointer :: deadcrootc_storage_patch (:) ! (gC/m2) dead coarse root C storage
real(r8), pointer :: deadcrootc_xfer_patch (:) ! (gC/m2) dead coarse root C transfer
+ real(r8), pointer :: matrix_cap_deadcrootc_patch (:) ! (gC/m2) Capacity of dead coarse root C
+ real(r8), pointer :: matrix_cap_deadcrootc_storage_patch (:) ! (gC/m2) Capacity of dead coarse root C storage
+ real(r8), pointer :: matrix_cap_deadcrootc_xfer_patch (:) ! (gC/m2) Capacity of dead coarse root C transfer
real(r8), pointer :: gresp_storage_patch (:) ! (gC/m2) growth respiration storage
real(r8), pointer :: gresp_xfer_patch (:) ! (gC/m2) growth respiration transfer
real(r8), pointer :: cpool_patch (:) ! (gC/m2) temporary photosynthate C pool
- ! Matrix data
- ! Initial pool size for matrix spinup
- ! Assumulation variables for matrix spinup as well as calculation of diagnostic variables
- ! Transfer pools
real(r8), pointer :: xsmrpool_patch (:) ! (gC/m2) abstract C pool to meet excess MR demand
real(r8), pointer :: xsmrpool_loss_patch (:) ! (gC/m2) abstract C pool to meet excess MR demand loss
real(r8), pointer :: ctrunc_patch (:) ! (gC/m2) patch-level sink for C truncation
@@ -74,6 +91,28 @@ module CNVegCarbonStateType
real(r8), pointer :: fuelc_col (:) ! fuel load outside cropland
real(r8), pointer :: fuelc_crop_col (:) ! fuel load for cropland
real(r8), pointer :: cropseedc_deficit_patch (:) ! (gC/m2) pool for seeding new crop growth; this is a NEGATIVE term, indicating the amount of seed usage that needs to be repaid
+! initial pool size of year for matrix
+ real(r8), pointer :: leafc0_patch (:) ! (gC/m2) Initial value of leaf C for SASU
+ real(r8), pointer :: leafc0_storage_patch (:) ! (gC/m2) Initial value of leaf C storage for SASU
+ real(r8), pointer :: leafc0_xfer_patch (:) ! (gC/m2) Initial value of leaf C transfer for SASU
+ real(r8), pointer :: frootc0_patch (:) ! (gC/m2) Initial value of fine root C for SASU
+ real(r8), pointer :: frootc0_storage_patch (:) ! (gC/m2) Initial value of fine root C storage for SASU
+ real(r8), pointer :: frootc0_xfer_patch (:) ! (gC/m2) Initial value of fine root C transfer for SASU
+ real(r8), pointer :: livestemc0_patch (:) ! (gC/m2) Initial value of live stem C for SASU
+ real(r8), pointer :: livestemc0_storage_patch (:) ! (gC/m2) Initial value of live stem C storage for SASU
+ real(r8), pointer :: livestemc0_xfer_patch (:) ! (gC/m2) Initial value of live stem C transfer for SASU
+ real(r8), pointer :: deadstemc0_patch (:) ! (gC/m2) Initial value of dead stem C for SASU
+ real(r8), pointer :: deadstemc0_storage_patch (:) ! (gC/m2) Initial value of dead stem C storage for SASU
+ real(r8), pointer :: deadstemc0_xfer_patch (:) ! (gC/m2) Initial value of dead stem C transfer for SASU
+ real(r8), pointer :: livecrootc0_patch (:) ! (gC/m2) Initial value of live coarse root C for SASU
+ real(r8), pointer :: livecrootc0_storage_patch (:) ! (gC/m2) Initial value of live coarse root C storage for SASU
+ real(r8), pointer :: livecrootc0_xfer_patch (:) ! (gC/m2) Initial value of live coarse root C transfer for SASU
+ real(r8), pointer :: deadcrootc0_patch (:) ! (gC/m2) Initial value of dead coarse root C for SASU
+ real(r8), pointer :: deadcrootc0_storage_patch (:) ! (gC/m2) Initial value of dead coarse root C storage for SASU
+ real(r8), pointer :: deadcrootc0_xfer_patch (:) ! (gC/m2) Initial value of dead coarse root C transfer for SASU
+ real(r8), pointer :: reproc0_patch (:) ! (gC/m2) Initial value of fine grain C for SASU
+ real(r8), pointer :: reproc0_storage_patch (:) ! (gC/m2) Initial value of fine grain C storage for SASU
+ real(r8), pointer :: reproc0_xfer_patch (:) ! (gC/m2) Initial value of fine grain C transfer for SASU
! pools for dynamic landcover
real(r8), pointer :: seedc_grc (:) ! (gC/m2) gridcell-level pool for seeding new PFTs via dynamic landcover
@@ -90,7 +129,83 @@ module CNVegCarbonStateType
real(r8), pointer :: totvegc_patch (:) ! (gC/m2) total vegetation carbon, excluding cpool
real(r8), pointer :: totvegc_col (:) ! (gC/m2) total vegetation carbon, excluding cpool averaged to column (p2c)
real(r8), pointer :: totc_p2c_col (:) ! (gC/m2) totc_patch averaged to col
-
+
+! Accumulation variables are accumulated for a whole year. They are used for matrix spinup and calculation of diagnostic variables
+ real(r8), pointer :: matrix_calloc_leaf_acc_patch (:) ! (gC/m2/year) Input C allocated to leaf during this year
+ real(r8), pointer :: matrix_calloc_leafst_acc_patch (:) ! (gC/m2/year) Input C allocated to leaf storage during this year
+ real(r8), pointer :: matrix_calloc_froot_acc_patch (:) ! (gC/m2/year) Input C allocated to fine root during this year
+ real(r8), pointer :: matrix_calloc_frootst_acc_patch (:) ! (gC/m2/year) Input C allocated to fine root storage during this year
+ real(r8), pointer :: matrix_calloc_livestem_acc_patch (:) ! (gC/m2/year) Input C allocated to live stem during this year
+ real(r8), pointer :: matrix_calloc_livestemst_acc_patch (:) ! (gC/m2/year) Input C allocated to live stem storage during this year
+ real(r8), pointer :: matrix_calloc_deadstem_acc_patch (:) ! (gC/m2/year) Input C allocated to dead stem during this year
+ real(r8), pointer :: matrix_calloc_deadstemst_acc_patch (:) ! (gC/m2/year) Input C allocated to dead stem storage during this year
+ real(r8), pointer :: matrix_calloc_livecroot_acc_patch (:) ! (gC/m2/year) Input C allocated to live coarse root during this year
+ real(r8), pointer :: matrix_calloc_livecrootst_acc_patch (:) ! (gC/m2/year) Input C allocated to live coarse root storage during this year
+ real(r8), pointer :: matrix_calloc_deadcroot_acc_patch (:) ! (gC/m2/year) Input C allocated to dead coarse root during this year
+ real(r8), pointer :: matrix_calloc_deadcrootst_acc_patch (:) ! (gC/m2/year) Input C allocated to dead coarse root storage during this year
+ real(r8), pointer :: matrix_calloc_grain_acc_patch (:) ! (gC/m2/year) Input C allocated to grain during this year
+ real(r8), pointer :: matrix_calloc_grainst_acc_patch (:) ! (gC/m2/year) Input C allocated to grain storage during this year
+
+ real(r8), pointer :: matrix_ctransfer_leafst_to_leafxf_acc_patch (:) ! (gC/m2/year) C transfer from leaf storage to leaf transfer pool during this year
+ real(r8), pointer :: matrix_ctransfer_leafxf_to_leaf_acc_patch (:) ! (gC/m2/year) C transfer from leaf transfer to leaf pool during this year
+ real(r8), pointer :: matrix_ctransfer_frootst_to_frootxf_acc_patch (:) ! (gC/m2/year) C transfer from fine root storage to fine root transfer pool during this year
+ real(r8), pointer :: matrix_ctransfer_frootxf_to_froot_acc_patch (:) ! (gC/m2/year) C transfer from fine root transfer to fine root pool during this year
+ real(r8), pointer :: matrix_ctransfer_livestemst_to_livestemxf_acc_patch (:) ! (gC/m2/year) C transfer from live stem storage to live stem transfer pool during this year
+ real(r8), pointer :: matrix_ctransfer_livestemxf_to_livestem_acc_patch (:) ! (gC/m2/year) C transfer from live stem transfer to live stem pool during this year
+ real(r8), pointer :: matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch (:) ! (gC/m2/year) C transfer from dead stem storage to dead stem transfer pool during this year
+ real(r8), pointer :: matrix_ctransfer_deadstemxf_to_deadstem_acc_patch (:) ! (gC/m2/year) C transfer from dead stem transfer to dead stem pool during this year
+ real(r8), pointer :: matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch (:) ! (gC/m2/year) C transfer from live coarse root storage to live coarse root transfer pool during this year
+ real(r8), pointer :: matrix_ctransfer_livecrootxf_to_livecroot_acc_patch (:) ! (gC/m2/year) C transfer from live coarse root transfer to live coarse root pool during this year
+ real(r8), pointer :: matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch (:) ! (gC/m2/year) C transfer from dead coarse root storage to dead coarse root transfer pool during this year
+ real(r8), pointer :: matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch (:) ! (gC/m2/year) C transfer from dead coarse root transfer to dead coarse root pool during this year
+ real(r8), pointer :: matrix_ctransfer_grainst_to_grainxf_acc_patch (:) ! (gC/m2/year) C transfer from grain storage to grain transfer pool during this year
+ real(r8), pointer :: matrix_ctransfer_grainxf_to_grain_acc_patch (:) ! (gC/m2/year) C transfer from grain transfer to grain pool during this year
+ real(r8), pointer :: matrix_ctransfer_livestem_to_deadstem_acc_patch (:) ! (gC/m2/year) C transfer from live stem to dead stem pool during this year
+ real(r8), pointer :: matrix_ctransfer_livecroot_to_deadcroot_acc_patch (:) ! (gC/m2/year) C transfer from live coarse root to dead coarse root pool during this year
+
+ real(r8), pointer :: matrix_cturnover_leaf_acc_patch (:) ! (gC/m2/year) C turnover from leaf
+ real(r8), pointer :: matrix_cturnover_leafst_acc_patch (:) ! (gC/m2/year) C turnover from leaf storage
+ real(r8), pointer :: matrix_cturnover_leafxf_acc_patch (:) ! (gC/m2/year) C turnover from leaf transfer
+ real(r8), pointer :: matrix_cturnover_froot_acc_patch (:) ! (gC/m2/year) C turnover from fine root
+ real(r8), pointer :: matrix_cturnover_frootst_acc_patch (:) ! (gC/m2/year) C turnover from fine root storage
+ real(r8), pointer :: matrix_cturnover_frootxf_acc_patch (:) ! (gC/m2/year) C turnover from fine root transfer
+ real(r8), pointer :: matrix_cturnover_livestem_acc_patch (:) ! (gC/m2/year) C turnover from live stem
+ real(r8), pointer :: matrix_cturnover_livestemst_acc_patch (:) ! (gC/m2/year) C turnover from live stem storage
+ real(r8), pointer :: matrix_cturnover_livestemxf_acc_patch (:) ! (gC/m2/year) C turnover from live stem transfer
+ real(r8), pointer :: matrix_cturnover_deadstem_acc_patch (:) ! (gC/m2/year) C turnover from dead stem
+ real(r8), pointer :: matrix_cturnover_deadstemst_acc_patch (:) ! (gC/m2/year) C turnover from dead stem storage
+ real(r8), pointer :: matrix_cturnover_deadstemxf_acc_patch (:) ! (gC/m2/year) C turnover from dead stem transfer
+ real(r8), pointer :: matrix_cturnover_livecroot_acc_patch (:) ! (gC/m2/year) C turnover from live coarse root
+ real(r8), pointer :: matrix_cturnover_livecrootst_acc_patch (:) ! (gC/m2/year) C turnover from live coarse root storage
+ real(r8), pointer :: matrix_cturnover_livecrootxf_acc_patch (:) ! (gC/m2/year) C turnover from live coarse root transfer
+ real(r8), pointer :: matrix_cturnover_deadcroot_acc_patch (:) ! (gC/m2/year) C turnover from dead coarse root
+ real(r8), pointer :: matrix_cturnover_deadcrootst_acc_patch (:) ! (gC/m2/year) C turnover from dead coarse root storage
+ real(r8), pointer :: matrix_cturnover_deadcrootxf_acc_patch (:) ! (gC/m2/year) C turnover from dead coarse root transfer
+ real(r8), pointer :: matrix_cturnover_grain_acc_patch (:) ! (gC/m2/year) C turnover from grain
+ real(r8), pointer :: matrix_cturnover_grainst_acc_patch (:) ! (gC/m2/year) C turnover from grain storage
+ real(r8), pointer :: matrix_cturnover_grainxf_acc_patch (:) ! (gC/m2/year) C turnover from grain transfer
+
+ real(r8), pointer :: grainc_SASUsave_patch (:) ! (gC/m2) grain C (crop model)
+ real(r8), pointer :: grainc_storage_SASUsave_patch (:) ! (gC/m2) grain C storage (crop model)
+ real(r8), pointer :: leafc_SASUsave_patch (:) ! (gC/m2) leaf C
+ real(r8), pointer :: leafc_storage_SASUsave_patch (:) ! (gC/m2) leaf C storage
+ real(r8), pointer :: leafc_xfer_SASUsave_patch (:) ! (gC/m2) leaf C transfer
+ real(r8), pointer :: frootc_SASUsave_patch (:) ! (gC/m2) fine root C
+ real(r8), pointer :: frootc_storage_SASUsave_patch (:) ! (gC/m2) fine root C storage
+ real(r8), pointer :: frootc_xfer_SASUsave_patch (:) ! (gC/m2) fine root C transfer
+ real(r8), pointer :: livestemc_SASUsave_patch (:) ! (gC/m2) live stem C
+ real(r8), pointer :: livestemc_storage_SASUsave_patch (:) ! (gC/m2) live stem C storage
+ real(r8), pointer :: livestemc_xfer_SASUsave_patch (:) ! (gC/m2) live stem C transfer
+ real(r8), pointer :: deadstemc_SASUsave_patch (:) ! (gC/m2) dead stem C
+ real(r8), pointer :: deadstemc_storage_SASUsave_patch (:) ! (gC/m2) dead stem C storage
+ real(r8), pointer :: deadstemc_xfer_SASUsave_patch (:) ! (gC/m2) dead stem C transfer
+ real(r8), pointer :: livecrootc_SASUsave_patch (:) ! (gC/m2) live coarse root C
+ real(r8), pointer :: livecrootc_storage_SASUsave_patch (:) ! (gC/m2) live coarse root C storage
+ real(r8), pointer :: livecrootc_xfer_SASUsave_patch (:) ! (gC/m2) live coarse root C transfer
+ real(r8), pointer :: deadcrootc_SASUsave_patch (:) ! (gC/m2) dead coarse root C
+ real(r8), pointer :: deadcrootc_storage_SASUsave_patch (:) ! (gC/m2) dead coarse root C storage
+ real(r8), pointer :: deadcrootc_xfer_SASUsave_patch (:) ! (gC/m2) dead coarse root C transfer
+
contains
procedure , public :: Init
@@ -242,23 +357,53 @@ subroutine InitAllocate(this, bounds, alloc_full_veg)
allocate(this%leafc_patch (begp:endp)) ; this%leafc_patch (:) = nan
allocate(this%leafc_storage_patch (begp:endp)) ; this%leafc_storage_patch (:) = nan
allocate(this%leafc_xfer_patch (begp:endp)) ; this%leafc_xfer_patch (:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_leafc_patch (begp:endp)) ; this%matrix_cap_leafc_patch (:) = nan
+ allocate(this%matrix_cap_leafc_storage_patch (begp:endp)) ; this%matrix_cap_leafc_storage_patch (:) = nan
+ allocate(this%matrix_cap_leafc_xfer_patch (begp:endp)) ; this%matrix_cap_leafc_xfer_patch (:) = nan
+ end if
allocate(this%leafc_storage_xfer_acc_patch (begp:endp)) ; this%leafc_storage_xfer_acc_patch (:) = nan
allocate(this%storage_cdemand_patch (begp:endp)) ; this%storage_cdemand_patch (:) = nan
allocate(this%frootc_patch (begp:endp)) ; this%frootc_patch (:) = nan
allocate(this%frootc_storage_patch (begp:endp)) ; this%frootc_storage_patch (:) = nan
allocate(this%frootc_xfer_patch (begp:endp)) ; this%frootc_xfer_patch (:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_frootc_patch (begp:endp)) ; this%matrix_cap_frootc_patch (:) = nan
+ allocate(this%matrix_cap_frootc_storage_patch (begp:endp)) ; this%matrix_cap_frootc_storage_patch (:) = nan
+ allocate(this%matrix_cap_frootc_xfer_patch (begp:endp)) ; this%matrix_cap_frootc_xfer_patch (:) = nan
+ end if
allocate(this%livestemc_patch (begp:endp)) ; this%livestemc_patch (:) = nan
allocate(this%livestemc_storage_patch (begp:endp)) ; this%livestemc_storage_patch (:) = nan
allocate(this%livestemc_xfer_patch (begp:endp)) ; this%livestemc_xfer_patch (:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_livestemc_patch (begp:endp)) ; this%matrix_cap_livestemc_patch (:) = nan
+ allocate(this%matrix_cap_livestemc_storage_patch (begp:endp)) ; this%matrix_cap_livestemc_storage_patch (:) = nan
+ allocate(this%matrix_cap_livestemc_xfer_patch (begp:endp)) ; this%matrix_cap_livestemc_xfer_patch (:) = nan
+ end if
allocate(this%deadstemc_patch (begp:endp)) ; this%deadstemc_patch (:) = nan
allocate(this%deadstemc_storage_patch (begp:endp)) ; this%deadstemc_storage_patch (:) = nan
allocate(this%deadstemc_xfer_patch (begp:endp)) ; this%deadstemc_xfer_patch (:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_deadstemc_patch (begp:endp)) ; this%matrix_cap_deadstemc_patch (:) = nan
+ allocate(this%matrix_cap_deadstemc_storage_patch (begp:endp)) ; this%matrix_cap_deadstemc_storage_patch (:) = nan
+ allocate(this%matrix_cap_deadstemc_xfer_patch (begp:endp)) ; this%matrix_cap_deadstemc_xfer_patch (:) = nan
+ end if
allocate(this%livecrootc_patch (begp:endp)) ; this%livecrootc_patch (:) = nan
allocate(this%livecrootc_storage_patch (begp:endp)) ; this%livecrootc_storage_patch (:) = nan
allocate(this%livecrootc_xfer_patch (begp:endp)) ; this%livecrootc_xfer_patch (:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_livecrootc_patch (begp:endp)) ; this%matrix_cap_livecrootc_patch (:) = nan
+ allocate(this%matrix_cap_livecrootc_storage_patch (begp:endp)) ; this%matrix_cap_livecrootc_storage_patch(:) = nan
+ allocate(this%matrix_cap_livecrootc_xfer_patch (begp:endp)) ; this%matrix_cap_livecrootc_xfer_patch (:) = nan
+ end if
allocate(this%deadcrootc_patch (begp:endp)) ; this%deadcrootc_patch (:) = nan
allocate(this%deadcrootc_storage_patch (begp:endp)) ; this%deadcrootc_storage_patch (:) = nan
allocate(this%deadcrootc_xfer_patch (begp:endp)) ; this%deadcrootc_xfer_patch (:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_deadcrootc_patch (begp:endp)) ; this%matrix_cap_deadcrootc_patch (:) = nan
+ allocate(this%matrix_cap_deadcrootc_storage_patch (begp:endp)) ; this%matrix_cap_deadcrootc_storage_patch(:) = nan
+ allocate(this%matrix_cap_deadcrootc_xfer_patch (begp:endp)) ; this%matrix_cap_deadcrootc_xfer_patch (:) = nan
+ end if
allocate(this%gresp_storage_patch (begp:endp)) ; this%gresp_storage_patch (:) = nan
allocate(this%gresp_xfer_patch (begp:endp)) ; this%gresp_xfer_patch (:) = nan
allocate(this%cpool_patch (begp:endp)) ; this%cpool_patch (:) = nan
@@ -272,7 +417,127 @@ subroutine InitAllocate(this, bounds, alloc_full_veg)
allocate(this%reproductivec_patch (begp:endp, nrepr)) ; this%reproductivec_patch (:,:) = nan
allocate(this%reproductivec_storage_patch (begp:endp, nrepr)) ; this%reproductivec_storage_patch (:,:) = nan
allocate(this%reproductivec_xfer_patch (begp:endp, nrepr)) ; this%reproductivec_xfer_patch (:,:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_reproc_patch (begp:endp)) ; this%matrix_cap_reproc_patch (:) = nan
+ allocate(this%matrix_cap_reproc_storage_patch (begp:endp)) ; this%matrix_cap_reproc_storage_patch (:) = nan
+ allocate(this%matrix_cap_reproc_xfer_patch (begp:endp)) ; this%matrix_cap_reproc_xfer_patch (:) = nan
+ end if
allocate(this%woodc_patch (begp:endp)) ; this%woodc_patch (:) = nan
+!initial pool size of year for matrix
+ if(use_matrixcn)then
+ allocate(this%leafc0_patch (begp:endp)) ; this%leafc0_patch (:) = nan
+ allocate(this%leafc0_storage_patch (begp:endp)) ; this%leafc0_storage_patch (:) = nan
+ allocate(this%leafc0_xfer_patch (begp:endp)) ; this%leafc0_xfer_patch (:) = nan
+ allocate(this%frootc0_patch (begp:endp)) ; this%frootc0_patch (:) = nan
+ allocate(this%frootc0_storage_patch (begp:endp)) ; this%frootc0_storage_patch (:) = nan
+ allocate(this%frootc0_xfer_patch (begp:endp)) ; this%frootc0_xfer_patch (:) = nan
+ allocate(this%livestemc0_patch (begp:endp)) ; this%livestemc0_patch (:) = nan
+ allocate(this%livestemc0_storage_patch (begp:endp)) ; this%livestemc0_storage_patch (:) = nan
+ allocate(this%livestemc0_xfer_patch (begp:endp)) ; this%livestemc0_xfer_patch (:) = nan
+ allocate(this%deadstemc0_patch (begp:endp)) ; this%deadstemc0_patch (:) = nan
+ allocate(this%deadstemc0_storage_patch (begp:endp)) ; this%deadstemc0_storage_patch (:) = nan
+ allocate(this%deadstemc0_xfer_patch (begp:endp)) ; this%deadstemc0_xfer_patch (:) = nan
+ allocate(this%livecrootc0_patch (begp:endp)) ; this%livecrootc0_patch (:) = nan
+ allocate(this%livecrootc0_storage_patch (begp:endp)) ; this%livecrootc0_storage_patch (:) = nan
+ allocate(this%livecrootc0_xfer_patch (begp:endp)) ; this%livecrootc0_xfer_patch (:) = nan
+ allocate(this%deadcrootc0_patch (begp:endp)) ; this%deadcrootc0_patch (:) = nan
+ allocate(this%deadcrootc0_storage_patch (begp:endp)) ; this%deadcrootc0_storage_patch (:) = nan
+ allocate(this%deadcrootc0_xfer_patch (begp:endp)) ; this%deadcrootc0_xfer_patch (:) = nan
+ allocate(this%reproc0_patch (begp:endp)) ; this%reproc0_patch (:) = nan
+ allocate(this%reproc0_storage_patch (begp:endp)) ; this%reproc0_storage_patch (:) = nan
+ allocate(this%reproc0_xfer_patch (begp:endp)) ; this%reproc0_xfer_patch (:) = nan
+
+ allocate(this%leafc_SASUsave_patch (begp:endp)) ; this%leafc_SASUsave_patch (:) = nan
+ allocate(this%leafc_storage_SASUsave_patch (begp:endp)) ; this%leafc_storage_SASUsave_patch (:) = nan
+ allocate(this%leafc_xfer_SASUsave_patch (begp:endp)) ; this%leafc_xfer_SASUsave_patch (:) = nan
+ allocate(this%frootc_SASUsave_patch (begp:endp)) ; this%frootc_SASUsave_patch (:) = nan
+ allocate(this%frootc_storage_SASUsave_patch (begp:endp)) ; this%frootc_storage_SASUsave_patch (:) = nan
+ allocate(this%frootc_xfer_SASUsave_patch (begp:endp)) ; this%frootc_xfer_SASUsave_patch (:) = nan
+ allocate(this%livestemc_SASUsave_patch (begp:endp)) ; this%livestemc_SASUsave_patch (:) = nan
+ allocate(this%livestemc_storage_SASUsave_patch (begp:endp)) ; this%livestemc_storage_SASUsave_patch (:) = nan
+ allocate(this%livestemc_xfer_SASUsave_patch (begp:endp)) ; this%livestemc_xfer_SASUsave_patch (:) = nan
+ allocate(this%deadstemc_SASUsave_patch (begp:endp)) ; this%deadstemc_SASUsave_patch (:) = nan
+ allocate(this%deadstemc_storage_SASUsave_patch (begp:endp)) ; this%deadstemc_storage_SASUsave_patch (:) = nan
+ allocate(this%deadstemc_xfer_SASUsave_patch (begp:endp)) ; this%deadstemc_xfer_SASUsave_patch (:) = nan
+ allocate(this%livecrootc_SASUsave_patch (begp:endp)) ; this%livecrootc_SASUsave_patch (:) = nan
+ allocate(this%livecrootc_storage_SASUsave_patch (begp:endp)) ; this%livecrootc_storage_SASUsave_patch (:) = nan
+ allocate(this%livecrootc_xfer_SASUsave_patch (begp:endp)) ; this%livecrootc_xfer_SASUsave_patch (:) = nan
+ allocate(this%deadcrootc_SASUsave_patch (begp:endp)) ; this%deadcrootc_SASUsave_patch (:) = nan
+ allocate(this%deadcrootc_storage_SASUsave_patch (begp:endp)) ; this%deadcrootc_storage_SASUsave_patch (:) = nan
+ allocate(this%deadcrootc_xfer_SASUsave_patch (begp:endp)) ; this%deadcrootc_xfer_SASUsave_patch (:) = nan
+ allocate(this%grainc_SASUsave_patch (begp:endp)) ; this%grainc_SASUsave_patch (:) = nan
+ allocate(this%grainc_storage_SASUsave_patch (begp:endp)) ; this%grainc_storage_SASUsave_patch (:) = nan
+
+ allocate(this%matrix_calloc_leaf_acc_patch (begp:endp)); this%matrix_calloc_leaf_acc_patch (:) = nan
+ allocate(this%matrix_calloc_leafst_acc_patch (begp:endp)); this%matrix_calloc_leafst_acc_patch (:) = nan
+ allocate(this%matrix_calloc_froot_acc_patch (begp:endp)); this%matrix_calloc_froot_acc_patch (:) = nan
+ allocate(this%matrix_calloc_frootst_acc_patch (begp:endp)); this%matrix_calloc_frootst_acc_patch (:) = nan
+ allocate(this%matrix_calloc_livestem_acc_patch (begp:endp)); this%matrix_calloc_livestem_acc_patch (:) = nan
+ allocate(this%matrix_calloc_livestemst_acc_patch (begp:endp)); this%matrix_calloc_livestemst_acc_patch (:) = nan
+ allocate(this%matrix_calloc_deadstem_acc_patch (begp:endp)); this%matrix_calloc_deadstem_acc_patch (:) = nan
+ allocate(this%matrix_calloc_deadstemst_acc_patch (begp:endp)); this%matrix_calloc_deadstemst_acc_patch (:) = nan
+ allocate(this%matrix_calloc_livecroot_acc_patch (begp:endp)); this%matrix_calloc_livecroot_acc_patch (:) = nan
+ allocate(this%matrix_calloc_livecrootst_acc_patch (begp:endp)); this%matrix_calloc_livecrootst_acc_patch (:) = nan
+ allocate(this%matrix_calloc_deadcroot_acc_patch (begp:endp)); this%matrix_calloc_deadcroot_acc_patch (:) = nan
+ allocate(this%matrix_calloc_deadcrootst_acc_patch (begp:endp)); this%matrix_calloc_deadcrootst_acc_patch (:) = nan
+ allocate(this%matrix_calloc_grain_acc_patch (begp:endp)); this%matrix_calloc_grain_acc_patch (:) = nan
+ allocate(this%matrix_calloc_grainst_acc_patch (begp:endp)); this%matrix_calloc_grainst_acc_patch (:) = nan
+
+ allocate(this%matrix_ctransfer_leafst_to_leafxf_acc_patch (begp:endp))
+ this%matrix_ctransfer_leafst_to_leafxf_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_leafxf_to_leaf_acc_patch (begp:endp))
+ this%matrix_ctransfer_leafxf_to_leaf_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_frootst_to_frootxf_acc_patch (begp:endp))
+ this%matrix_ctransfer_frootst_to_frootxf_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_frootxf_to_froot_acc_patch (begp:endp))
+ this%matrix_ctransfer_frootxf_to_froot_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_livestemst_to_livestemxf_acc_patch (begp:endp))
+ this%matrix_ctransfer_livestemst_to_livestemxf_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_livestemxf_to_livestem_acc_patch (begp:endp))
+ this%matrix_ctransfer_livestemxf_to_livestem_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch (begp:endp))
+ this%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch (begp:endp))
+ this%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch (begp:endp))
+ this%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch (begp:endp))
+ this%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch (begp:endp))
+ this%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch (begp:endp))
+ this%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_grainst_to_grainxf_acc_patch (begp:endp))
+ this%matrix_ctransfer_grainst_to_grainxf_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_grainxf_to_grain_acc_patch (begp:endp))
+ this%matrix_ctransfer_grainxf_to_grain_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_livestem_to_deadstem_acc_patch (begp:endp))
+ this%matrix_ctransfer_livestem_to_deadstem_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_livecroot_to_deadcroot_acc_patch (begp:endp))
+ this%matrix_ctransfer_livecroot_to_deadcroot_acc_patch (:) = nan
+
+ allocate(this%matrix_cturnover_leaf_acc_patch (begp:endp)) ; this%matrix_cturnover_leaf_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_leafst_acc_patch (begp:endp)) ; this%matrix_cturnover_leafst_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_leafxf_acc_patch (begp:endp)) ; this%matrix_cturnover_leafxf_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_froot_acc_patch (begp:endp)) ; this%matrix_cturnover_froot_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_frootst_acc_patch (begp:endp)) ; this%matrix_cturnover_frootst_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_frootxf_acc_patch (begp:endp)) ; this%matrix_cturnover_frootxf_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_livestem_acc_patch (begp:endp)) ; this%matrix_cturnover_livestem_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_livestemst_acc_patch (begp:endp)) ; this%matrix_cturnover_livestemst_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_livestemxf_acc_patch (begp:endp)) ; this%matrix_cturnover_livestemxf_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_deadstem_acc_patch (begp:endp)) ; this%matrix_cturnover_deadstem_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_deadstemst_acc_patch (begp:endp)) ; this%matrix_cturnover_deadstemst_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_deadstemxf_acc_patch (begp:endp)) ; this%matrix_cturnover_deadstemxf_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_livecroot_acc_patch (begp:endp)) ; this%matrix_cturnover_livecroot_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_livecrootst_acc_patch (begp:endp)) ; this%matrix_cturnover_livecrootst_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_livecrootxf_acc_patch (begp:endp)) ; this%matrix_cturnover_livecrootxf_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_deadcroot_acc_patch (begp:endp)) ; this%matrix_cturnover_deadcroot_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_deadcrootst_acc_patch (begp:endp)) ; this%matrix_cturnover_deadcrootst_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_deadcrootxf_acc_patch (begp:endp)) ; this%matrix_cturnover_deadcrootxf_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_grain_acc_patch (begp:endp)) ; this%matrix_cturnover_grain_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_grainst_acc_patch (begp:endp)) ; this%matrix_cturnover_grainst_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_grainxf_acc_patch (begp:endp)) ; this%matrix_cturnover_grainxf_acc_patch (:) = nan
+ end if
allocate(this%cropseedc_deficit_patch (begp:endp)) ; this%cropseedc_deficit_patch (:) = nan
allocate(this%seedc_grc (begg:endg)) ; this%seedc_grc (:) = nan
@@ -287,11 +552,6 @@ subroutine InitAllocate(this, bounds, alloc_full_veg)
allocate(this%totc_p2c_col (begc:endc)) ; this%totc_p2c_col (:) = nan
- ! Matrix solution variables
- if(use_matrixcn)then
- ! Initisl pool size for matrix solution
- end if
-
end subroutine InitAllocate
!------------------------------------------------------------------------
@@ -375,6 +635,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='leaf C transfer', &
ptr_patch=this%leafc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LEAFC_CAP', units='gC/m^2', &
+ avgflag='I', long_name='leaf C capacity', &
+ ptr_patch=this%matrix_cap_leafc_patch)
+
+ this%matrix_cap_leafc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LEAFC_STORAGE_CAP', units='gC/m^2', &
+ avgflag='I', long_name='leaf C storage capacity', &
+ ptr_patch=this%matrix_cap_leafc_storage_patch, default='inactive')
+
+ this%matrix_cap_leafc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LEAFC_XFER_CAP', units='gC/m^2', &
+ avgflag='I', long_name='leaf C transfer capacity', &
+ ptr_patch=this%matrix_cap_leafc_xfer_patch, default='inactive')
+ end if
+
this%leafc_storage_xfer_acc_patch(begp:endp) = spval
call hist_addfld1d (fname='LEAFC_STORAGE_XFER_ACC', units='gC/m^2', &
avgflag='A', long_name='Accumulated leaf C transfer', &
@@ -400,6 +677,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='fine root C transfer', &
ptr_patch=this%frootc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_frootc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='FROOTC_CAP', units='gC/m^2', &
+ avgflag='I', long_name='fine root C capacity', &
+ ptr_patch=this%matrix_cap_frootc_patch)
+
+ this%matrix_cap_frootc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='FROOTC_STORAGE_CAP', units='gC/m^2', &
+ avgflag='I', long_name='fine root C storage capacity', &
+ ptr_patch=this%matrix_cap_frootc_storage_patch, default='inactive')
+
+ this%matrix_cap_frootc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='FROOTC_XFER_CAP', units='gC/m^2', &
+ avgflag='I', long_name='fine root C transfer capacity', &
+ ptr_patch=this%matrix_cap_frootc_xfer_patch, default='inactive')
+ end if
+
this%livestemc_patch(begp:endp) = spval
call hist_addfld1d (fname='LIVESTEMC', units='gC/m^2', &
avgflag='A', long_name='live stem C', &
@@ -415,6 +709,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='live stem C transfer', &
ptr_patch=this%livestemc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_livestemc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVESTEMC_CAP', units='gC/m^2', &
+ avgflag='I', long_name='live stem C capacity', &
+ ptr_patch=this%matrix_cap_livestemc_patch)
+
+ this%matrix_cap_livestemc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVESTEMC_STORAGE_CAP', units='gC/m^2', &
+ avgflag='I', long_name='live stem C storage capcity', &
+ ptr_patch=this%matrix_cap_livestemc_storage_patch, default='inactive')
+
+ this%matrix_cap_livestemc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVESTEMC_XFER_CAP', units='gC/m^2', &
+ avgflag='I', long_name='live stem C transfer capacity', &
+ ptr_patch=this%matrix_cap_livestemc_xfer_patch, default='inactive')
+ end if
+
this%deadstemc_patch(begp:endp) = spval
call hist_addfld1d (fname='DEADSTEMC', units='gC/m^2', &
avgflag='A', long_name='dead stem C', &
@@ -430,6 +741,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='dead stem C transfer', &
ptr_patch=this%deadstemc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADSTEMC_CAP', units='gC/m^2', &
+ avgflag='I', long_name='dead stem C capacity', &
+ ptr_patch=this%matrix_cap_deadstemc_patch)
+
+ this%matrix_cap_deadstemc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADSTEMC_STORAGE_CAP', units='gC/m^2', &
+ avgflag='I', long_name='dead stem C storage capacity', &
+ ptr_patch=this%matrix_cap_deadstemc_storage_patch, default='inactive')
+
+ this%matrix_cap_deadstemc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADSTEMC_XFER_CAP', units='gC/m^2', &
+ avgflag='I', long_name='dead stem C transfer capacity', &
+ ptr_patch=this%matrix_cap_deadstemc_xfer_patch, default='inactive')
+ end if
+
this%livecrootc_patch(begp:endp) = spval
call hist_addfld1d (fname='LIVECROOTC', units='gC/m^2', &
avgflag='A', long_name='live coarse root C', &
@@ -445,6 +773,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='live coarse root C transfer', &
ptr_patch=this%livecrootc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_livecrootc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVECROOTC_CAP', units='gC/m^2', &
+ avgflag='I', long_name='live coarse root C capacity', &
+ ptr_patch=this%matrix_cap_livecrootc_patch)
+
+ this%matrix_cap_livecrootc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVECROOTC_STORAGE_CAP', units='gC/m^2', &
+ avgflag='I', long_name='live coarse root C storage capacity', &
+ ptr_patch=this%matrix_cap_livecrootc_storage_patch, default='inactive')
+
+ this%matrix_cap_livecrootc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVECROOTC_XFER_CAP', units='gC/m^2', &
+ avgflag='I', long_name='live coarse root C transfer capacity', &
+ ptr_patch=this%matrix_cap_livecrootc_xfer_patch, default='inactive')
+ end if
+
this%deadcrootc_patch(begp:endp) = spval
call hist_addfld1d (fname='DEADCROOTC', units='gC/m^2', &
avgflag='A', long_name='dead coarse root C', &
@@ -460,6 +805,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='dead coarse root C transfer', &
ptr_patch=this%deadcrootc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_deadcrootc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADCROOTC_CAP', units='gC/m^2', &
+ avgflag='I', long_name='dead coarse root C capacity', &
+ ptr_patch=this%matrix_cap_deadcrootc_patch)
+
+ this%matrix_cap_deadcrootc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADCROOTC_STORAGE_CAP', units='gC/m^2', &
+ avgflag='I', long_name='dead coarse root C storage capacity', &
+ ptr_patch=this%matrix_cap_deadcrootc_storage_patch, default='inactive')
+
+ this%matrix_cap_deadcrootc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADCROOTC_XFER_CAP', units='gC/m^2', &
+ avgflag='I', long_name='dead coarse root C transfer capacity', &
+ ptr_patch=this%matrix_cap_deadcrootc_xfer_patch, default='inactive')
+ end if
+
this%gresp_storage_patch(begp:endp) = spval
call hist_addfld1d (fname='GRESP_STORAGE', units='gC/m^2', &
avgflag='A', long_name='growth respiration storage', &
@@ -515,9 +877,6 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='fuel load', &
ptr_col=this%fuelc_col)
- ! Matrix solution history variables
- if ( use_matrixcn )then
- end if
end if
!-------------------------------
@@ -541,6 +900,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C13 leaf C transfer', &
ptr_patch=this%leafc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_LEAFC_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 leaf C capacity', &
+ ptr_patch=this%matrix_cap_leafc_patch)
+
+ this%matrix_cap_leafc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_LEAFC_STORAGE_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 leaf C storage capacity', &
+ ptr_patch=this%matrix_cap_leafc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_leafc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_LEAFC_XFER_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 leaf C transfer capacity', &
+ ptr_patch=this%matrix_cap_leafc_xfer_patch)!, default='inactive')
+ end if
+
this%leafc_storage_xfer_acc_patch(begp:endp) = spval
call hist_addfld1d (fname='C13_LEAFC_STORAGE_XFER_ACC', units='gC13/m^2', &
avgflag='A', long_name='Accumulated C13 leaf C transfer', &
@@ -561,6 +937,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C13 fine root C transfer', &
ptr_patch=this%frootc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_frootc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_FROOTC_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 fine root C capacity', &
+ ptr_patch=this%matrix_cap_frootc_patch)
+
+ this%matrix_cap_frootc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_FROOTC_STORAGE_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 fine root C storage capacity', &
+ ptr_patch=this%matrix_cap_frootc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_frootc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_FROOTC_XFER_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 fine root C transfer capacity', &
+ ptr_patch=this%matrix_cap_frootc_xfer_patch)!, default='inactive')
+ end if
+
this%livestemc_patch(begp:endp) = spval
call hist_addfld1d (fname='C13_LIVESTEMC', units='gC13/m^2', &
avgflag='A', long_name='C13 live stem C', &
@@ -576,6 +969,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C13 live stem C transfer', &
ptr_patch=this%livestemc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_livestemc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_LIVESTEMC_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 live stem C capacity', &
+ ptr_patch=this%matrix_cap_livestemc_patch)
+
+ this%matrix_cap_livestemc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_LIVESTEMC_STORAGE_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 live stem C storage capcity', &
+ ptr_patch=this%matrix_cap_livestemc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_livestemc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_LIVESTEMC_XFER_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 live stem C transfer capacity', &
+ ptr_patch=this%matrix_cap_livestemc_xfer_patch)!, default='inactive')
+ end if
+
this%deadstemc_patch(begp:endp) = spval
call hist_addfld1d (fname='C13_DEADSTEMC', units='gC13/m^2', &
avgflag='A', long_name='C13 dead stem C', &
@@ -591,6 +1001,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C13 dead stem C transfer', &
ptr_patch=this%deadstemc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_DEADSTEMC_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 dead stem C capacity', &
+ ptr_patch=this%matrix_cap_deadstemc_patch)
+
+ this%matrix_cap_deadstemc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_DEADSTEMC_STORAGE_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 dead stem C storage capacity', &
+ ptr_patch=this%matrix_cap_deadstemc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_deadstemc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_DEADSTEMC_XFER_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 dead stem C transfer capacity', &
+ ptr_patch=this%matrix_cap_deadstemc_xfer_patch)!, default='inactive')
+ end if
+
this%livecrootc_patch(begp:endp) = spval
call hist_addfld1d (fname='C13_LIVECROOTC', units='gC13/m^2', &
avgflag='A', long_name='C13 live coarse root C', &
@@ -606,6 +1033,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C13 live coarse root C transfer', &
ptr_patch=this%livecrootc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_livecrootc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_LIVECROOTC_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 live coarse root C capacity', &
+ ptr_patch=this%matrix_cap_livecrootc_patch)
+
+ this%matrix_cap_livecrootc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_LIVECROOTC_STORAGE_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 live coarse root C storage capacity', &
+ ptr_patch=this%matrix_cap_livecrootc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_livecrootc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_LIVECROOTC_XFER_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 live coarse root C transfer capacity', &
+ ptr_patch=this%matrix_cap_livecrootc_xfer_patch)!, default='inactive')
+ end if
+
this%deadcrootc_patch(begp:endp) = spval
call hist_addfld1d (fname='C13_DEADCROOTC', units='gC13/m^2', &
avgflag='A', long_name='C13 dead coarse root C', &
@@ -621,6 +1065,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C13 dead coarse root C transfer', &
ptr_patch=this%deadcrootc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_deadcrootc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_DEADCROOTC_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 dead coarse root C capacity', &
+ ptr_patch=this%matrix_cap_deadcrootc_patch)
+
+ this%matrix_cap_deadcrootc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_DEADCROOTC_STORAGE_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 dead coarse root C storage capacity', &
+ ptr_patch=this%matrix_cap_deadcrootc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_deadcrootc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_DEADCROOTC_XFER_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 dead coarse root C transfer capacity', &
+ ptr_patch=this%matrix_cap_deadcrootc_xfer_patch)!, default='inactive')
+ end if
+
this%gresp_storage_patch(begp:endp) = spval
call hist_addfld1d (fname='C13_GRESP_STORAGE', units='gC13/m^2', &
avgflag='A', long_name='C13 growth respiration storage', &
@@ -695,9 +1156,6 @@ subroutine InitHistory(this, bounds, carbon_type)
ptr_patch=this%xsmrpool_loss_patch, default='inactive')
end if
- ! Matrix solution history variables
- if ( use_matrixcn )then
- end if
endif
@@ -727,6 +1185,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='Accumulated C14 leaf C transfer', &
ptr_patch=this%leafc_storage_xfer_acc_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_LEAFC_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 leaf C capacity', &
+ ptr_patch=this%matrix_cap_leafc_patch)
+
+ this%matrix_cap_leafc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_LEAFC_STORAGE_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 leaf C storage capacity', &
+ ptr_patch=this%matrix_cap_leafc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_leafc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_LEAFC_XFER_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 leaf C transfer capacity', &
+ ptr_patch=this%matrix_cap_leafc_xfer_patch)!, default='inactive')
+ end if
+
this%frootc_patch(begp:endp) = spval
call hist_addfld1d (fname='C14_FROOTC', units='gC14/m^2', &
avgflag='A', long_name='C14 fine root C', &
@@ -742,6 +1217,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C14 fine root C transfer', &
ptr_patch=this%frootc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_frootc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_FROOTC_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 fine root C capacity', &
+ ptr_patch=this%matrix_cap_frootc_patch)
+
+ this%matrix_cap_frootc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_FROOTC_STORAGE_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 fine root C storage capacity', &
+ ptr_patch=this%matrix_cap_frootc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_frootc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_FROOTC_XFER_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 fine root C transfer capacity', &
+ ptr_patch=this%matrix_cap_frootc_xfer_patch)!, default='inactive')
+ end if
+
this%livestemc_patch(begp:endp) = spval
call hist_addfld1d (fname='C14_LIVESTEMC', units='gC14/m^2', &
avgflag='A', long_name='C14 live stem C', &
@@ -757,6 +1249,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C14 live stem C transfer', &
ptr_patch=this%livestemc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_livestemc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_LIVESTEMC_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 live stem C capacity', &
+ ptr_patch=this%matrix_cap_livestemc_patch)
+
+ this%matrix_cap_livestemc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_LIVESTEMC_STORAGE_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 live stem C storage capcity', &
+ ptr_patch=this%matrix_cap_livestemc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_livestemc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_LIVESTEMC_XFER_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 live stem C transfer capacity', &
+ ptr_patch=this%matrix_cap_livestemc_xfer_patch)!, default='inactive')
+ end if
+
this%deadstemc_patch(begp:endp) = spval
call hist_addfld1d (fname='C14_DEADSTEMC', units='gC14/m^2', &
avgflag='A', long_name='C14 dead stem C', &
@@ -772,6 +1281,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C14 dead stem C transfer', &
ptr_patch=this%deadstemc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_DEADSTEMC_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 dead stem C capacity', &
+ ptr_patch=this%matrix_cap_deadstemc_patch)
+
+ this%matrix_cap_deadstemc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_DEADSTEMC_STORAGE_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 dead stem C storage capacity', &
+ ptr_patch=this%matrix_cap_deadstemc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_deadstemc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_DEADSTEMC_XFER_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 dead stem C transfer capacity', &
+ ptr_patch=this%matrix_cap_deadstemc_xfer_patch)!, default='inactive')
+ end if
+
this%livecrootc_patch(begp:endp) = spval
call hist_addfld1d (fname='C14_LIVECROOTC', units='gC14/m^2', &
avgflag='A', long_name='C14 live coarse root C', &
@@ -787,6 +1313,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C14 live coarse root C transfer', &
ptr_patch=this%livecrootc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_livecrootc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_LIVECROOTC_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 live coarse root C capacity', &
+ ptr_patch=this%matrix_cap_livecrootc_patch)
+
+ this%matrix_cap_livecrootc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_LIVECROOTC_STORAGE_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 live coarse root C storage capacity', &
+ ptr_patch=this%matrix_cap_livecrootc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_livecrootc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_LIVECROOTC_XFER_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 live coarse root C transfer capacity', &
+ ptr_patch=this%matrix_cap_livecrootc_xfer_patch)!, default='inactive')
+ end if
+
this%deadcrootc_patch(begp:endp) = spval
call hist_addfld1d (fname='C14_DEADCROOTC', units='gC14/m^2', &
avgflag='A', long_name='C14 dead coarse root C', &
@@ -802,6 +1345,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C14 dead coarse root C transfer', &
ptr_patch=this%deadcrootc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_deadcrootc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_DEADCROOTC_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 dead coarse root C capacity', &
+ ptr_patch=this%matrix_cap_deadcrootc_patch)
+
+ this%matrix_cap_deadcrootc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_DEADCROOTC_STORAGE_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 dead coarse root C storage capacity', &
+ ptr_patch=this%matrix_cap_deadcrootc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_deadcrootc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_DEADCROOTC_XFER_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 dead coarse root C transfer capacity', &
+ ptr_patch=this%matrix_cap_deadcrootc_xfer_patch)!, default='inactive')
+ end if
+
this%gresp_storage_patch(begp:endp) = spval
call hist_addfld1d (fname='C14_GRESP_STORAGE', units='gC14/m^2', &
avgflag='A', long_name='C14 growth respiration storage', &
@@ -875,9 +1435,6 @@ subroutine InitHistory(this, bounds, carbon_type)
ptr_patch=this%xsmrpool_loss_patch, default='inactive')
end if
- ! Matrix solution history variables
- if ( use_matrixcn )then
- end if
endif
@@ -890,7 +1447,7 @@ subroutine InitCold(this, bounds, ratio, carbon_type, c12_cnveg_carbonstate_inst
! Initializes time varying variables used only in coupled carbon-nitrogen mode (CN):
!
! !USES:
- use landunit_varcon , only : istsoil, istcrop
+ use landunit_varcon , only : istsoil, istcrop
use clm_time_manager , only : is_restart, get_nstep
use clm_varctl, only : MM_Nuptake_opt, spinup_state
!
@@ -957,9 +1514,11 @@ subroutine InitCold(this, bounds, ratio, carbon_type, c12_cnveg_carbonstate_inst
this%leafc_storage_patch(p) = 0._r8
this%frootc_patch(p) = 0._r8
this%frootc_storage_patch(p) = 0._r8
-
- ! Set matrix solution bare-soil
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(p) = 0._r8
+ this%matrix_cap_leafc_storage_patch(p) = 0._r8
+ this%matrix_cap_frootc_patch(p) = 0._r8
+ this%matrix_cap_frootc_storage_patch(p) = 0._r8
end if
else
if (pftcon%evergreen(patch%itype(p)) == 1._r8) then
@@ -967,73 +1526,100 @@ subroutine InitCold(this, bounds, ratio, carbon_type, c12_cnveg_carbonstate_inst
this%leafc_storage_patch(p) = 0._r8
this%frootc_patch(p) = cnvegcstate_const%initial_vegC * ratio
this%frootc_storage_patch(p) = 0._r8
- ! Set matrix solution evergreen
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(p) = cnvegcstate_const%initial_vegC * ratio
+ this%matrix_cap_leafc_storage_patch(p) = 0._r8
+ this%matrix_cap_frootc_patch(p) = cnvegcstate_const%initial_vegC * ratio
+ this%matrix_cap_frootc_storage_patch(p) = 0._r8
end if
else if (patch%itype(p) >= npcropmin) then ! prognostic crop types
this%leafc_patch(p) = 0._r8
this%leafc_storage_patch(p) = 0._r8
this%frootc_patch(p) = 0._r8
this%frootc_storage_patch(p) = 0._r8
- ! Set matrix solution prognostic crops
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(p) = 0._r8
+ this%matrix_cap_leafc_storage_patch(p) = 0._r8
+ this%matrix_cap_frootc_patch(p) = 0._r8
+ this%matrix_cap_frootc_storage_patch(p) = 0._r8
end if
else
this%leafc_patch(p) = 0._r8
this%leafc_storage_patch(p) = cnvegcstate_const%initial_vegC * ratio
this%frootc_patch(p) = 0._r8
this%frootc_storage_patch(p) = cnvegcstate_const%initial_vegC * ratio
- ! Set matrix solution for everything else
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(p) = 0._r8
+ this%matrix_cap_leafc_storage_patch(p) = cnvegcstate_const%initial_vegC * ratio
+ this%matrix_cap_frootc_patch(p) = 0._r8
+ this%matrix_cap_frootc_storage_patch(p) = cnvegcstate_const%initial_vegC * ratio
end if
end if
end if
this%leafc_xfer_patch(p) = 0._r8
+ if(use_matrixcn)then
+ this%matrix_cap_leafc_xfer_patch(p) = 0._r8
+ end if
this%leafc_storage_xfer_acc_patch(p) = 0._r8
this%storage_cdemand_patch(p) = 0._r8
- ! Set matrix solution general
- if ( use_matrixcn )then
- end if
-
if (MM_Nuptake_opt .eqv. .false.) then ! if not running in floating CN ratio option
this%frootc_patch(p) = 0._r8
this%frootc_storage_patch(p) = 0._r8
- ! Set matrix solution
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_frootc_patch(p) = 0._r8
+ this%matrix_cap_frootc_storage_patch(p) = 0._r8
end if
end if
this%frootc_xfer_patch(p) = 0._r8
+ if(use_matrixcn)then
+ this%matrix_cap_frootc_xfer_patch(p) = 0._r8
+ end if
this%livestemc_patch(p) = 0._r8
this%livestemc_storage_patch(p) = 0._r8
this%livestemc_xfer_patch(p) = 0._r8
-
- ! Set matrix solution
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_livestemc_patch(p) = 0._r8
+ this%matrix_cap_livestemc_storage_patch(p) = 0._r8
+ this%matrix_cap_livestemc_xfer_patch(p) = 0._r8
end if
if (pftcon%woody(patch%itype(p)) == 1._r8) then
this%deadstemc_patch(p) = 0.1_r8 * ratio
- ! Set matrix solution for woody
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemc_patch(p) = 0.1_r8 * ratio
end if
else
this%deadstemc_patch(p) = 0._r8
- ! Set matrix solution for non-woody
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemc_patch(p) = 0._r8
end if
end if
this%deadstemc_storage_patch(p) = 0._r8
this%deadstemc_xfer_patch(p) = 0._r8
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemc_storage_patch(p) = 0._r8
+ this%matrix_cap_deadstemc_xfer_patch(p) = 0._r8
+ end if
this%livecrootc_patch(p) = 0._r8
this%livecrootc_storage_patch(p) = 0._r8
this%livecrootc_xfer_patch(p) = 0._r8
+ if(use_matrixcn)then
+ this%matrix_cap_livecrootc_patch(p) = 0._r8
+ this%matrix_cap_livecrootc_storage_patch(p) = 0._r8
+ this%matrix_cap_livecrootc_xfer_patch(p) = 0._r8
+ end if
this%deadcrootc_patch(p) = 0._r8
this%deadcrootc_storage_patch(p) = 0._r8
this%deadcrootc_xfer_patch(p) = 0._r8
+ if(use_matrixcn)then
+ this%matrix_cap_deadcrootc_patch(p) = 0._r8
+ this%matrix_cap_deadcrootc_storage_patch(p) = 0._r8
+ this%matrix_cap_deadcrootc_xfer_patch(p) = 0._r8
+ end if
this%gresp_storage_patch(p) = 0._r8
this%gresp_xfer_patch(p) = 0._r8
@@ -1045,10 +1631,103 @@ subroutine InitCold(this, bounds, ratio, carbon_type, c12_cnveg_carbonstate_inst
this%storvegc_patch(p) = 0._r8
this%woodc_patch(p) = 0._r8
this%totc_patch(p) = 0._r8
-
- ! Initial pool size for matrix solution
- if ( use_matrixcn )then
+!!!!initial pool size for matrix
+ if(use_matrixcn)then
+ this%leafc0_patch(p) = 1.e-30_r8
+ this%leafc0_storage_patch(p) = 1.e-30_r8
+ this%leafc0_xfer_patch(p) = 1.e-30_r8
+ this%frootc0_patch(p) = 1.e-30_r8
+ this%frootc0_storage_patch(p) = 1.e-30_r8
+ this%frootc0_xfer_patch(p) = 1.e-30_r8
+
+ this%livestemc0_patch(p) = 1.e-30_r8
+ this%livestemc0_storage_patch(p) = 1.e-30_r8
+ this%livestemc0_xfer_patch(p) = 1.e-30_r8
+ this%deadstemc0_patch(p) = 1.e-30_r8
+ this%deadstemc0_storage_patch(p) = 1.e-30_r8
+ this%deadstemc0_xfer_patch(p) = 1.e-30_r8
+
+ this%livecrootc0_patch(p) = 1.e-30_r8
+ this%livecrootc0_storage_patch(p) = 1.e-30_r8
+ this%livecrootc0_xfer_patch(p) = 1.e-30_r8
+
+ this%deadcrootc0_patch(p) = 1.e-30_r8
+ this%deadcrootc0_storage_patch(p) = 1.e-30_r8
+ this%deadcrootc0_xfer_patch(p) = 1.e-30_r8
+
+ this%reproc0_patch(p) = 1.e-30_r8
+ this%reproc0_storage_patch(p) = 1.e-30_r8
+ this%reproc0_xfer_patch(p) = 1.e-30_r8
+
+ this%leafc_SASUsave_patch(p) = 0._r8
+ this%leafc_storage_SASUsave_patch(p) = 0._r8
+ this%leafc_xfer_SASUsave_patch(p) = 0._r8
+ this%frootc_SASUsave_patch(p) = 0._r8
+ this%frootc_storage_SASUsave_patch(p) = 0._r8
+ this%frootc_xfer_SASUsave_patch(p) = 0._r8
+ this%livestemc_SASUsave_patch(p) = 0._r8
+ this%livestemc_storage_SASUsave_patch(p) = 0._r8
+ this%livestemc_xfer_SASUsave_patch(p) = 0._r8
+ this%deadstemc_SASUsave_patch(p) = 0._r8
+ this%deadstemc_storage_SASUsave_patch(p) = 0._r8
+ this%deadstemc_xfer_SASUsave_patch(p) = 0._r8
+ this%livecrootc_SASUsave_patch(p) = 0._r8
+ this%livecrootc_storage_SASUsave_patch(p) = 0._r8
+ this%livecrootc_xfer_SASUsave_patch(p) = 0._r8
+ this%deadcrootc_SASUsave_patch(p) = 0._r8
+ this%deadcrootc_storage_SASUsave_patch(p) = 0._r8
+ this%deadcrootc_xfer_SASUsave_patch(p) = 0._r8
+ this%grainc_SASUsave_patch(p) = 0._r8
+ this%grainc_storage_SASUsave_patch(p) = 0._r8
+
+ this%matrix_calloc_leaf_acc_patch(p) = 0._r8
+ this%matrix_calloc_leafst_acc_patch(p) = 0._r8
+ this%matrix_calloc_froot_acc_patch(p) = 0._r8
+ this%matrix_calloc_frootst_acc_patch(p) = 0._r8
+ this%matrix_calloc_livestem_acc_patch(p) = 0._r8
+ this%matrix_calloc_livestemst_acc_patch(p) = 0._r8
+ this%matrix_calloc_deadstem_acc_patch(p) = 0._r8
+ this%matrix_calloc_deadstemst_acc_patch(p) = 0._r8
+ this%matrix_calloc_livecroot_acc_patch(p) = 0._r8
+ this%matrix_calloc_livecrootst_acc_patch(p) = 0._r8
+ this%matrix_calloc_deadcroot_acc_patch(p) = 0._r8
+ this%matrix_calloc_deadcrootst_acc_patch(p) = 0._r8
+
+ this%matrix_ctransfer_leafst_to_leafxf_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_leafxf_to_leaf_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_frootst_to_frootxf_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_frootxf_to_froot_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_livestemst_to_livestemxf_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_livestemxf_to_livestem_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_livestem_to_deadstem_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_livecroot_to_deadcroot_acc_patch(p) = 0._r8
+
+ this%matrix_cturnover_leaf_acc_patch(p) = 0._r8
+ this%matrix_cturnover_leafst_acc_patch(p) = 0._r8
+ this%matrix_cturnover_leafxf_acc_patch(p) = 0._r8
+ this%matrix_cturnover_froot_acc_patch(p) = 0._r8
+ this%matrix_cturnover_frootst_acc_patch(p) = 0._r8
+ this%matrix_cturnover_frootxf_acc_patch(p) = 0._r8
+ this%matrix_cturnover_livestem_acc_patch(p) = 0._r8
+ this%matrix_cturnover_livestemst_acc_patch(p) = 0._r8
+ this%matrix_cturnover_livestemxf_acc_patch(p) = 0._r8
+ this%matrix_cturnover_deadstem_acc_patch(p) = 0._r8
+ this%matrix_cturnover_deadstemst_acc_patch(p) = 0._r8
+ this%matrix_cturnover_deadstemxf_acc_patch(p) = 0._r8
+ this%matrix_cturnover_livecroot_acc_patch(p) = 0._r8
+ this%matrix_cturnover_livecrootst_acc_patch(p) = 0._r8
+ this%matrix_cturnover_livecrootxf_acc_patch(p) = 0._r8
+ this%matrix_cturnover_deadcroot_acc_patch(p) = 0._r8
+ this%matrix_cturnover_deadcrootst_acc_patch(p) = 0._r8
+ this%matrix_cturnover_deadcrootxf_acc_patch(p) = 0._r8
end if
+
if ( use_crop )then
this%reproductivec_patch(p,:) = 0._r8
@@ -1056,8 +1735,18 @@ subroutine InitCold(this, bounds, ratio, carbon_type, c12_cnveg_carbonstate_inst
this%reproductivec_xfer_patch(p,:) = 0._r8
this%cropseedc_deficit_patch(p) = 0._r8
this%xsmrpool_loss_patch(p) = 0._r8
-
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_reproc_patch(p) = 0._r8
+ this%matrix_cap_reproc_storage_patch(p) = 0._r8
+ this%matrix_cap_reproc_xfer_patch(p) = 0._r8
+ ! I think these need to change as well...
+ this%matrix_calloc_grain_acc_patch(p) = 0._r8
+ this%matrix_calloc_grainst_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_grainst_to_grainxf_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_grainxf_to_grain_acc_patch(p) = 0._r8
+ this%matrix_cturnover_grain_acc_patch(p) = 0._r8
+ this%matrix_cturnover_grainst_acc_patch(p) = 0._r8
+ this%matrix_cturnover_grainxf_acc_patch(p) = 0._r8
end if
end if
@@ -1107,7 +1796,7 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
use clm_varctl , only : spinup_state, use_cndv, MM_Nuptake_opt
use clm_varctl , only : spinup_state, use_cndv, MM_Nuptake_opt
use clm_time_manager , only : is_restart
- use landunit_varcon , only : istsoil, istcrop
+ use landunit_varcon , only : istsoil, istcrop
use spmdMod , only : mpicom
use shr_mpi_mod , only : shr_mpi_sum
use restUtilMod
@@ -1186,6 +1875,61 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%leafc_xfer_patch)
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='leafc_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_leaf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_leafst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_leafst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_leafst_to_leafxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_leafst_to_leafxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_leafxf_to_leaf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_leafxf_to_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_leaf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_leafst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_leafst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctrunover_leafxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_leafxf_acc_patch)
+
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='leafc_storage_xfer_acc', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%leafc_storage_xfer_acc_patch)
@@ -1206,6 +1950,60 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%frootc_xfer_patch)
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='frootc_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_froot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_frootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_frootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_frootst_to_frootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_frootst_to_frootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_frootxf_to_froot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_frootxf_to_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_froot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_frootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_frootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_frootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_frootxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='livestemc', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%livestemc_patch)
@@ -1218,6 +2016,64 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%livestemc_xfer_patch)
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livestem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livestemst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livestemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livestemst_to_livestemxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livestemst_to_livestemxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livestemxf_to_livestem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livestemxf_to_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livestem_to_deadstem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livestem_to_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livestem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livestemst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livestemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livestemxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livestemxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='deadstemc', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%deadstemc_patch)
@@ -1230,6 +2086,60 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%deadstemc_xfer_patch)
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadstem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadstemst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadstemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadstemst_to_deadstemxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadstemxf_to_deadstem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadstem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadstemst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadstemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadstemxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadstemxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='livecrootc', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%livecrootc_patch)
@@ -1242,6 +2152,64 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%livecrootc_xfer_patch)
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livecroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livecrootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livecrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livecrootst_to_livecrootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livecrootxf_to_livecroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livecroot_to_deadcroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livecroot_to_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livecroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livecrootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livecrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livecrootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livecrootxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='deadcrootc', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%deadcrootc_patch)
@@ -1254,37 +2222,125 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%deadcrootc_xfer_patch)
- call restartvar(ncid=ncid, flag=flag, varname='gresp_storage', xtype=ncd_double, &
- dim1name='pft', long_name='', units='', &
- interpinic_flag='interp', readvar=readvar, data=this%gresp_storage_patch)
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootc_patch)
- call restartvar(ncid=ncid, flag=flag, varname='gresp_xfer', xtype=ncd_double, &
- dim1name='pft', long_name='', units='', &
- interpinic_flag='interp', readvar=readvar, data=this%gresp_xfer_patch)
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootc_storage_patch)
- call restartvar(ncid=ncid, flag=flag, varname='cpool', xtype=ncd_double, &
- dim1name='pft', long_name='', units='', &
- interpinic_flag='interp', readvar=readvar, data=this%cpool_patch)
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootc_xfer_patch)
- call restartvar(ncid=ncid, flag=flag, varname='xsmrpool', xtype=ncd_double, &
- dim1name='pft', long_name='', units='', &
- interpinic_flag='interp', readvar=readvar, data=this%xsmrpool_patch)
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootc0_patch)
- ! Restart variables for matrix solution
- if ( use_matrixcn )then
- end if
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootc0_storage_patch)
- if (use_crop) then
- call restartvar(ncid=ncid, flag=flag, varname='xsmrpool_loss', xtype=ncd_double, &
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootc0_xfer_patch)
+!
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadcroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadcrootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadcrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadcrootst_to_deadcrootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadcrootxf_to_deadcroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadcroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadcrootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadcrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadcrootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadcrootxf_acc_patch)
+ end if
+
+ if(use_matrixcn .and. use_crop)then
+ call restartvar(ncid=ncid, flag=flag, varname='reproc0', xtype=ncd_double, &
+ dim1name='pft', long_name='initial grain C', units='gC/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%reproc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='reproc0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='initial grain C storage', units='gC/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%reproc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='reproc0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='initial grain C transfer', units='gC/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%reproc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_grain_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='C accumulated allocation to grain', units='gC/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_grainst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='C accumulated allocation to grain storage', units='gC/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_grainst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_grainst_to_grainxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_grainst_to_grainxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_grainxf_to_grain_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_grainxf_to_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_grain_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_grainst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_grainst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_grainxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_grainxf_acc_patch)
+ end if
+
+ call restartvar(ncid=ncid, flag=flag, varname='gresp_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%gresp_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='gresp_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%gresp_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='cpool', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%cpool_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='xsmrpool', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%xsmrpool_patch)
+
+ if (use_crop) then
+ call restartvar(ncid=ncid, flag=flag, varname='xsmrpool_loss', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%xsmrpool_loss_patch)
if (flag == 'read' .and. (.not. readvar) ) then
this%xsmrpool_loss_patch(bounds%begp:bounds%endp) = 0._r8
end if
-
- ! Restart variables for matrix solution with prognostic crop
- if ( use_matrixcn )then
- end if
end if
call restartvar(ncid=ncid, flag=flag, varname='pft_ctrunc', xtype=ncd_double, &
@@ -1372,9 +2428,11 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
this%leafc_storage_patch(i) = 0._r8
this%frootc_patch(i) = 0._r8
this%frootc_storage_patch(i) = 0._r8
-
- ! Bare soil matrix solution
if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(i) = 0._r8
+ this%matrix_cap_leafc_storage_patch(i) = 0._r8
+ this%matrix_cap_frootc_patch(i) = 0._r8
+ this%matrix_cap_frootc_storage_patch(i) = 0._r8
end if
else
if (pftcon%evergreen(patch%itype(i)) == 1._r8) then
@@ -1382,35 +2440,38 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
this%leafc_storage_patch(i) = 0._r8
this%frootc_patch(i) = cnvegcstate_const%initial_vegC * ratio
this%frootc_storage_patch(i) = 0._r8
- ! Evergreen matrix solution
if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(i) = cnvegcstate_const%initial_vegC * ratio
+ this%matrix_cap_leafc_storage_patch(i) = 0._r8
+ this%matrix_cap_frootc_patch(i) = cnvegcstate_const%initial_vegC * ratio
+ this%matrix_cap_frootc_storage_patch(i) = 0._r8
end if
else
this%leafc_patch(i) = 0._r8
this%leafc_storage_patch(i) = cnvegcstate_const%initial_vegC * ratio
this%frootc_patch(i) = 0._r8
this%frootc_storage_patch(i) = cnvegcstate_const%initial_vegC * ratio
-
- ! Otherwise matrix solution
if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(i) = 0._r8
+ this%matrix_cap_leafc_storage_patch(i) = cnvegcstate_const%initial_vegC * ratio
+ this%matrix_cap_frootc_patch(i) = 0._r8
+ this%matrix_cap_frootc_storage_patch(i) = cnvegcstate_const%initial_vegC * ratio
end if
end if
end if
this%leafc_xfer_patch(i) = 0._r8
- this%leafc_storage_xfer_acc_patch(i) = 0._r8
- this%storage_cdemand_patch(i) = 0._r8
-
- ! General matrix solution
if(use_matrixcn)then
+ this%matrix_cap_leafc_xfer_patch(i) = 0._r8
end if
-
+ this%leafc_storage_xfer_acc_patch(i) = 0._r8
+ this%storage_cdemand_patch(i) = 0._r8
if (MM_Nuptake_opt .eqv. .false.) then ! if not running in floating CN ratio option
this%frootc_patch(i) = 0._r8
this%frootc_storage_patch(i) = 0._r8
-
- ! Flex CN for matrix solution
if(use_matrixcn)then
+ this%matrix_cap_frootc_patch(i) = 0._r8
+ this%matrix_cap_frootc_storage_patch(i) = 0._r8
end if
end if
this%frootc_xfer_patch(i) = 0._r8
@@ -1418,20 +2479,30 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
this%livestemc_patch(i) = 0._r8
this%livestemc_storage_patch(i) = 0._r8
this%livestemc_xfer_patch(i) = 0._r8
+ if(use_matrixcn)then
+ this%matrix_cap_frootc_xfer_patch(i) = 0._r8
+ this%matrix_cap_livestemc_patch(i) = 0._r8
+ this%matrix_cap_livestemc_storage_patch(i) = 0._r8
+ this%matrix_cap_livestemc_xfer_patch(i) = 0._r8
+ end if
if (pftcon%woody(patch%itype(i)) == 1._r8) then
this%deadstemc_patch(i) = 0.1_r8 * ratio
- ! Woody for matrix solution
if(use_matrixcn)then
+ this%matrix_cap_deadstemc_patch(i) = 0.1_r8 * ratio
end if
else
this%deadstemc_patch(i) = 0._r8
- ! Non-Woody for matrix solution
if(use_matrixcn)then
+ this%matrix_cap_deadstemc_patch(i) = 0._r8
end if
end if
this%deadstemc_storage_patch(i) = 0._r8
this%deadstemc_xfer_patch(i) = 0._r8
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemc_storage_patch(i) = 0._r8
+ this%matrix_cap_deadstemc_xfer_patch(i) = 0._r8
+ end if
this%livecrootc_patch(i) = 0._r8
this%livecrootc_storage_patch(i) = 0._r8
@@ -1441,8 +2512,14 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
this%deadcrootc_storage_patch(i) = 0._r8
this%deadcrootc_xfer_patch(i) = 0._r8
- ! Live/Dead course roots for matrix solution
if(use_matrixcn)then
+ this%matrix_cap_livecrootc_patch(i) = 0._r8
+ this%matrix_cap_livecrootc_storage_patch(i) = 0._r8
+ this%matrix_cap_livecrootc_xfer_patch(i) = 0._r8
+
+ this%matrix_cap_deadcrootc_patch(i) = 0._r8
+ this%matrix_cap_deadcrootc_storage_patch(i) = 0._r8
+ this%matrix_cap_deadcrootc_xfer_patch(i) = 0._r8
end if
this%gresp_storage_patch(i) = 0._r8
@@ -1460,12 +2537,16 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
this%reproductivec_patch(i,:) = 0._r8
this%reproductivec_storage_patch(i,:) = 0._r8
this%reproductivec_xfer_patch(i,:) = 0._r8
- this%cropseedc_deficit_patch(i) = 0._r8
- this%xsmrpool_loss_patch(i) = 0._r8
-
- ! Reproductive pools for matrix solution
if(use_matrixcn)then
+ this%reproc0_patch(i) = 0._r8
+ this%reproc0_storage_patch(i) = 0._r8
+ this%reproc0_xfer_patch(i) = 0._r8
+ this%matrix_cap_reproc_patch(i) = 0._r8
+ this%matrix_cap_reproc_storage_patch(i) = 0._r8
+ this%matrix_cap_reproc_xfer_patch(i) = 0._r8
end if
+ this%cropseedc_deficit_patch(i) = 0._r8
+ this%xsmrpool_loss_patch(i) = 0._r8
end if
! calculate totvegc explicitly so that it is available for the isotope
@@ -1633,6 +2714,61 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='leafc_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc_storage_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc_xfer_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc0_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc0_storage_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc0_xfer_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_leaf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_leafst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_leafst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_leafst_to_leafxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_leafst_to_leafxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_leafxf_to_leaf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_leafxf_to_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_leaf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_leafst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_leafst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctrunover_leafxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_leafxf_acc_patch)
+
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='frootc_13', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%frootc_patch)
@@ -1675,6 +2811,61 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='frootc_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc_storage_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc_xfer_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc0_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc0_storage_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc0_xfer_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_froot_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_frootst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_frootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_frootst_to_frootxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_frootst_to_frootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_frootxf_to_froot_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_frootxf_to_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_froot_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_frootst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_frootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_frootxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_frootxf_acc_patch)
+ end if
+
+
call restartvar(ncid=ncid, flag=flag, varname='livestemc_13', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%livestemc_patch)
@@ -1717,6 +2908,64 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc_storage_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc_xfer_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc0_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc0_storage_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc0_xfer_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livestem_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livestemst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livestemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livestemst_to_livestemxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livestemst_to_livestemxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livestemxf_to_livestem_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livestemxf_to_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livestem_to_deadstem_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livestem_to_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livestem_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livestemst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livestemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livestemxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livestemxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='deadstemc_13', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%deadstemc_patch)
@@ -1759,6 +3008,60 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc_storage_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc_xfer_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc0_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc0_storage_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc0_xfer_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadstem_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadstemst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadstemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadstemst_to_deadstemxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadstemxf_to_deadstem_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadstem_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadstemst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadstemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadstemxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadstemxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='livecrootc_13', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%livecrootc_patch)
@@ -1801,6 +3104,64 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc_storage_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc_xfer_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc0_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc0_storage_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc0_xfer_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livecroot_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livecrootst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livecrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livecrootst_to_livecrootxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livecrootxf_to_livecroot_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livecroot_to_deadcroot_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livecroot_to_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livecroot_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livecrootst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livecrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livecrootxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livecrootxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_13', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%deadcrootc_patch)
@@ -1843,6 +3204,102 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_storage_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_xfer_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc0_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc0_storage_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc0_xfer_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootc0_xfer_patch)
+!
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadcroot_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadcrootst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadcrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadcrootxf_to_deadcroot_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadcroot_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadcrootst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadcrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadcrootxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadcrootxf_acc_patch)
+ end if
+
+ if(use_matrixcn .and. use_crop)then
+ call restartvar(ncid=ncid, flag=flag, varname='reproc0_13', xtype=ncd_double, &
+ dim1name='pft', long_name='initial grain C13', units='gC13/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%reproc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='reproc0_storage_13', xtype=ncd_double, &
+ dim1name='pft', long_name='initial grain C13 storage', units='gC13/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%reproc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='reproc0_xfer_13', xtype=ncd_double, &
+ dim1name='pft', long_name='initial grain C13 transfer', units='gC13/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%reproc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_grain_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='C13 accumulated allocation to grain', units='gC13/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_grainst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='C13 accumulated allocation to grain storage', units='gC13/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_grainst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_grainst_to_grainxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_grainst_to_grainxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_grainxf_to_grain_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_grainxf_to_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_grain_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_grainst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_grainst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_grainxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_grainxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='gresp_storage_13', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%gresp_storage_patch)
@@ -1930,14 +3387,6 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
- ! Restart variables for matrix solution and C13
- if(use_matrixcn)then
-
- ! Prgnostic crop C13 variables for matrix solution
- if ( use_crop )then
- end if
- end if
-
end if
!--------------------------------
@@ -1997,6 +3446,61 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='leafc_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc_storage_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc_xfer_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc0_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc0_storage_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc0_xfer_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_leaf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_leafst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_leafst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_leafst_to_leafxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_leafst_to_leafxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_leafxf_to_leaf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_leafxf_to_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_leaf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_leafst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_leafst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctrunover_leafxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_leafxf_acc_patch)
+
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='frootc_14', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%frootc_patch)
@@ -2036,6 +3540,60 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='frootc_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc_storage_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc_xfer_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc0_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc0_storage_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc0_xfer_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_froot_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_frootst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_frootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_frootst_to_frootxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_frootst_to_frootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_frootxf_to_froot_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_frootxf_to_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_froot_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_frootst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_frootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_frootxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_frootxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='livestemc_14', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%livestemc_patch)
@@ -2072,6 +3630,64 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc_storage_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc_xfer_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc0_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc0_storage_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc0_xfer_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livestem_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livestemst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livestemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livestemst_to_livestemxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livestemst_to_livestemxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livestemxf_to_livestem_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livestemxf_to_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livestem_to_deadstem_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livestem_to_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livestem_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livestemst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livestemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livestemxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livestemxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='deadstemc_14', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%deadstemc_patch)
@@ -2108,6 +3724,60 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc_storage_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc_xfer_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc0_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc0_storage_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc0_xfer_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadstem_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadstemst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadstemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadstemst_to_deadstemxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadstemxf_to_deadstem_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadstem_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadstemst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadstemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadstemxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadstemxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='livecrootc_14', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%livecrootc_patch)
@@ -2144,6 +3814,64 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc_storage_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc_xfer_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc0_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc0_storage_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc0_xfer_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livecroot_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livecrootst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livecrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livecrootst_to_livecrootxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livecrootxf_to_livecroot_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livecroot_to_deadcroot_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livecroot_to_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livecroot_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livecrootst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livecrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livecrootxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livecrootxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_14', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%deadcrootc_patch)
@@ -2180,6 +3908,102 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_storage_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_xfer_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc0_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc0_storage_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc0_xfer_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootc0_xfer_patch)
+!
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadcroot_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadcrootst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadcrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadcrootxf_to_deadcroot_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadcroot_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadcrootst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadcrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadcrootxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadcrootxf_acc_patch)
+ end if
+
+ if(use_matrixcn .and. use_crop)then
+ call restartvar(ncid=ncid, flag=flag, varname='reproc0_14', xtype=ncd_double, &
+ dim1name='pft', long_name='initial grain C14', units='gC14/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%reproc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='reproc0_storage_14', xtype=ncd_double, &
+ dim1name='pft', long_name='initial grain C14 storage', units='gC14/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%reproc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='reproc0_xfer_14', xtype=ncd_double, &
+ dim1name='pft', long_name='initial grain C14 transfer', units='gC14/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%reproc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_grain_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='C14 accumulated allocation to grain', units='gC14/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_grainst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='C14 accumulated allocation to grain storage', units='gC14/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_grainst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_grainst_to_grainxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_grainst_to_grainxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_grainxf_to_grain_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_grainxf_to_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_grain_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_grainst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_grainst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_grainxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_grainxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='gresp_storage_14', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%gresp_storage_patch)
@@ -2252,13 +4076,6 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
- ! Restart variables for matrix solution and C13
- if(use_matrixcn)then
-
- ! Prgnostic crop C13 variables for matrix solution
- if ( use_crop )then
- end if
- end if
end if
!--------------------------------
@@ -2537,6 +4354,95 @@ subroutine SetValues ( this, &
this%deadcrootc_patch(i) = value_patch
this%deadcrootc_storage_patch(i) = value_patch
this%deadcrootc_xfer_patch(i) = value_patch
+ if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(i) = value_patch
+ this%matrix_cap_leafc_storage_patch(i) = value_patch
+ this%matrix_cap_leafc_xfer_patch(i) = value_patch
+ this%matrix_cap_frootc_patch(i) = value_patch
+ this%matrix_cap_frootc_storage_patch(i) = value_patch
+ this%matrix_cap_frootc_xfer_patch(i) = value_patch
+ this%matrix_cap_livestemc_patch(i) = value_patch
+ this%matrix_cap_livestemc_storage_patch(i) = value_patch
+ this%matrix_cap_livestemc_xfer_patch(i) = value_patch
+ this%matrix_cap_deadstemc_patch(i) = value_patch
+ this%matrix_cap_deadstemc_storage_patch(i) = value_patch
+ this%matrix_cap_deadstemc_xfer_patch(i) = value_patch
+ this%matrix_cap_livecrootc_patch(i) = value_patch
+ this%matrix_cap_livecrootc_storage_patch(i) = value_patch
+ this%matrix_cap_livecrootc_xfer_patch(i) = value_patch
+ this%matrix_cap_deadcrootc_patch(i) = value_patch
+ this%matrix_cap_deadcrootc_storage_patch(i) = value_patch
+ this%matrix_cap_deadcrootc_xfer_patch(i) = value_patch
+
+ this%leafc0_patch(i) = value_patch
+ this%leafc0_storage_patch(i) = value_patch
+ this%leafc0_xfer_patch(i) = value_patch
+ this%frootc0_patch(i) = value_patch
+ this%frootc0_storage_patch(i) = value_patch
+ this%frootc0_xfer_patch(i) = value_patch
+ this%livestemc0_patch(i) = value_patch
+ this%livestemc0_storage_patch(i) = value_patch
+ this%livestemc0_xfer_patch(i) = value_patch
+ this%deadstemc0_patch(i) = value_patch
+ this%deadstemc0_storage_patch(i) = value_patch
+ this%deadstemc0_xfer_patch(i) = value_patch
+ this%livecrootc0_patch(i) = value_patch
+ this%livecrootc0_storage_patch(i) = value_patch
+ this%livecrootc0_xfer_patch(i) = value_patch
+ this%deadcrootc0_patch(i) = value_patch
+ this%deadcrootc0_storage_patch(i) = value_patch
+ this%deadcrootc0_xfer_patch(i) = value_patch
+ this%reproc0_patch(i) = value_patch
+ this%reproc0_storage_patch(i) = value_patch
+ this%reproc0_xfer_patch(i) = value_patch
+!!!!matrix
+ this%matrix_calloc_leaf_acc_patch(i) = value_patch
+ this%matrix_calloc_leafst_acc_patch(i) = value_patch
+ this%matrix_calloc_froot_acc_patch(i) = value_patch
+ this%matrix_calloc_frootst_acc_patch(i) = value_patch
+ this%matrix_calloc_livestem_acc_patch(i) = value_patch
+ this%matrix_calloc_livestemst_acc_patch(i) = value_patch
+ this%matrix_calloc_deadstem_acc_patch(i) = value_patch
+ this%matrix_calloc_deadstemst_acc_patch(i) = value_patch
+ this%matrix_calloc_livecroot_acc_patch(i) = value_patch
+ this%matrix_calloc_livecrootst_acc_patch(i) = value_patch
+ this%matrix_calloc_deadcroot_acc_patch(i) = value_patch
+ this%matrix_calloc_deadcrootst_acc_patch(i) = value_patch
+
+ this%matrix_ctransfer_leafst_to_leafxf_acc_patch (i) = value_patch
+ this%matrix_ctransfer_leafxf_to_leaf_acc_patch (i) = value_patch
+ this%matrix_ctransfer_frootst_to_frootxf_acc_patch (i) = value_patch
+ this%matrix_ctransfer_frootxf_to_froot_acc_patch (i) = value_patch
+ this%matrix_ctransfer_livestemst_to_livestemxf_acc_patch (i) = value_patch
+ this%matrix_ctransfer_livestemxf_to_livestem_acc_patch (i) = value_patch
+ this%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch (i) = value_patch
+ this%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch (i) = value_patch
+ this%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch (i) = value_patch
+ this%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch (i) = value_patch
+ this%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch (i) = value_patch
+ this%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch (i) = value_patch
+ this%matrix_ctransfer_livestem_to_deadstem_acc_patch (i) = value_patch
+ this%matrix_ctransfer_livecroot_to_deadcroot_acc_patch (i) = value_patch
+
+ this%matrix_cturnover_leaf_acc_patch(i) = value_patch
+ this%matrix_cturnover_leafst_acc_patch(i) = value_patch
+ this%matrix_cturnover_leafxf_acc_patch(i) = value_patch
+ this%matrix_cturnover_froot_acc_patch(i) = value_patch
+ this%matrix_cturnover_frootst_acc_patch(i) = value_patch
+ this%matrix_cturnover_frootxf_acc_patch(i) = value_patch
+ this%matrix_cturnover_livestem_acc_patch(i) = value_patch
+ this%matrix_cturnover_livestemst_acc_patch(i) = value_patch
+ this%matrix_cturnover_livestemxf_acc_patch(i) = value_patch
+ this%matrix_cturnover_deadstem_acc_patch(i) = value_patch
+ this%matrix_cturnover_deadstemst_acc_patch(i) = value_patch
+ this%matrix_cturnover_deadstemxf_acc_patch(i) = value_patch
+ this%matrix_cturnover_livecroot_acc_patch(i) = value_patch
+ this%matrix_cturnover_livecrootst_acc_patch(i) = value_patch
+ this%matrix_cturnover_livecrootxf_acc_patch(i) = value_patch
+ this%matrix_cturnover_deadcroot_acc_patch(i) = value_patch
+ this%matrix_cturnover_deadcrootst_acc_patch(i) = value_patch
+ this%matrix_cturnover_deadcrootxf_acc_patch(i) = value_patch
+ end if
this%gresp_storage_patch(i) = value_patch
this%gresp_xfer_patch(i) = value_patch
this%cpool_patch(i) = value_patch
@@ -2547,18 +4453,18 @@ subroutine SetValues ( this, &
this%woodc_patch(i) = value_patch
this%totvegc_patch(i) = value_patch
this%totc_patch(i) = value_patch
-
- ! Set matrix solution values
- if ( use_matrixcn )then
- end if
-
if ( use_crop ) then
+ if(use_matrixcn)then
+ this%matrix_calloc_grain_acc_patch(i) = value_patch
+ this%matrix_calloc_grainst_acc_patch(i) = value_patch
+ this%matrix_ctransfer_grainst_to_grainxf_acc_patch (i) = value_patch
+ this%matrix_ctransfer_grainxf_to_grain_acc_patch (i) = value_patch
+ this%matrix_cturnover_grain_acc_patch(i) = value_patch
+ this%matrix_cturnover_grainst_acc_patch(i) = value_patch
+ this%matrix_cturnover_grainxf_acc_patch(i) = value_patch
+ end if
this%cropseedc_deficit_patch(i) = value_patch
this%xsmrpool_loss_patch(i) = value_patch
-
- ! Set matrix solution values for prognostic crop
- if ( use_matrixcn )then
- end if
end if
end do
@@ -2569,12 +4475,16 @@ subroutine SetValues ( this, &
this%reproductivec_patch(i,k) = value_patch
this%reproductivec_storage_patch(i,k) = value_patch
this%reproductivec_xfer_patch(i,k) = value_patch
-
- ! Set matrix solution values for prognostic crop reproductive patches
- if ( use_matrixcn )then
- end if
end do
end do
+ if(use_matrixcn)then
+ do fi = 1,num_column
+ i = filter_column(fi)
+ this%matrix_cap_reproc_patch(i) = value_patch
+ this%matrix_cap_reproc_storage_patch(i) = value_patch
+ this%matrix_cap_reproc_xfer_patch(i) = value_patch
+ end do
+ end if
end if
do fi = 1,num_column
diff --git a/src/biogeochem/CNVegMatrixMod.F90 b/src/biogeochem/CNVegMatrixMod.F90
new file mode 100644
index 0000000000..5582afeffe
--- /dev/null
+++ b/src/biogeochem/CNVegMatrixMod.F90
@@ -0,0 +1,3851 @@
+module CNVegMatrixMod
+
+ !---------------------------------------------------------------------------------------
+ ! The matrix model of CLM5.0 was developed by Yiqi Luo EcoLab members,
+ ! Drs. Xingjie Lu, Yuanyuan Huang and Zhengguang Du, at Northern Arizona University
+ !---------------------------------------------------------------------------------------
+ !
+ ! DESCRIPTION:
+ ! Matrix solution for vegetation C and N cycles
+ ! The matrix equation
+ ! Xn+1 = Xn + B*I*dt + (Aph*Kph + Agm*Kgm + Afi*Kfi) * Xn*dt
+ ! Xn is the state variable of last time step n, and Xn+1 is the state variable of
+ ! the next time step n+1, I is the input to the vegetation, i.e. NPP in this case.
+ ! B is allocation fraction vector.
+ ! Aph, Agm and Afi represent transfer coefficient matrix A from phenology, gap mortality
+ ! and fire related C and N transfers.
+ ! Kph, Kgm and Kfi represent turnover rate matrix K from phenology, gap mortality
+ ! and fire related C and N transfers.
+ !---------------------------------------------------------------------------------------
+
+ ! !USES:
+ use shr_kind_mod , only : r8 => shr_kind_r8
+ use clm_time_manager , only : get_step_size,is_end_curr_year,is_first_step_of_this_run_segment,&
+ is_beg_curr_year,update_DA_nstep
+ use decompMod , only : bounds_type
+ use clm_varcon , only : spval
+ use clm_varpar , only : nlevdecomp, nvegcpool, nvegnpool
+ use clm_varpar , only : ileaf,ileaf_st,ileaf_xf,ifroot,ifroot_st,ifroot_xf,&
+ ilivestem,ilivestem_st,ilivestem_xf,&
+ ideadstem,ideadstem_st,ideadstem_xf,&
+ ilivecroot,ilivecroot_st,ilivecroot_xf,&
+ ideadcroot,ideadcroot_st,ideadcroot_xf,&
+ igrain,igrain_st,igrain_xf,iretransn,ioutc,ioutn,&
+ ncphtrans,nnphtrans,ncgmtrans,nngmtrans,ncfitrans,nnfitrans,&
+ ncphouttrans,nnphouttrans,ncgmouttrans,nngmouttrans,ncfiouttrans,nnfiouttrans
+ use perf_mod , only : t_startf, t_stopf
+ use PatchType , only : patch
+ use pftconMod , only : pftcon,npcropmin
+ use CNVegCarbonStateType , only : cnveg_carbonstate_type
+ use CNVegNitrogenStateType , only : cnveg_nitrogenstate_type
+ use CNVegCarbonFluxType , only : cnveg_carbonflux_type !include: callocation,ctransfer, cturnover
+ use CNVegNitrogenFluxType , only : cnveg_nitrogenflux_type
+ use CNVegStateType , only : cnveg_state_type
+ use SoilBiogeochemNitrogenFluxType , only : soilbiogeochem_nitrogenflux_type
+ use clm_varctl , only : spinup_matrixcn, hist_wrt_matrixcn_diag, nyr_forcing, nyr_SASU, iloop_avg
+ use clm_varctl , only : use_c13, use_c14
+ use SparseMatrixMultiplyMod , only : sparse_matrix_type,diag_matrix_type,vector_type
+ use MatrixMod , only : inverse
+ !
+ implicit none
+ private
+ !
+ ! !PUBLIC MEMBER FUNCTIONS:
+ public:: CNVegMatrix
+ public:: matrix_update_phc,matrix_update_gmc,matrix_update_fic
+ public:: matrix_update_phn,matrix_update_gmn,matrix_update_fin
+ public:: CNVegMatrixRest
+
+ ! ! PRIVATE MEMBER DATA:
+ integer,save, private :: iyr=0 ! Cycling year number into forcing sequence
+ integer,save, private :: iloop=0 ! The iloop^th forcing loop
+ !-----------------------------------------------------------------------
+
+contains
+
+ !-----------------------------------------------------------------------
+ subroutine CNVegMatrix(bounds,num_soilp,filter_soilp,num_actfirep,filter_actfirep,cnveg_carbonstate_inst,cnveg_nitrogenstate_inst,&
+ cnveg_carbonflux_inst, cnveg_nitrogenflux_inst,cnveg_state_inst,soilbiogeochem_nitrogenflux_inst, &
+ c13_cnveg_carbonstate_inst,c14_cnveg_carbonstate_inst,c13_cnveg_carbonflux_inst,&
+ c14_cnveg_carbonflux_inst)
+ ! !DESCRIPTION:
+ ! !ARGUMENTS:
+ type(bounds_type) , intent(in) :: bounds
+ integer , intent(in) :: num_soilp ! number of soil patches in filter
+ integer , intent(in) :: filter_soilp(:) ! filter for soil patches
+ integer , intent(in) :: num_actfirep ! number of soil patches in filter
+ integer , intent(in) :: filter_actfirep(:) ! filter for soil patches
+ type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst
+ type(cnveg_nitrogenstate_type) , intent(inout) :: cnveg_nitrogenstate_inst
+ type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst
+ type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst
+ type(soilbiogeochem_nitrogenflux_type) , intent(inout) :: soilbiogeochem_nitrogenflux_inst
+ type(cnveg_carbonstate_type) , intent(inout) :: c13_cnveg_carbonstate_inst
+ type(cnveg_carbonstate_type) , intent(inout) :: c14_cnveg_carbonstate_inst
+ type(cnveg_carbonflux_type) , intent(inout) :: c13_cnveg_carbonflux_inst
+ type(cnveg_carbonflux_type) , intent(inout) :: c14_cnveg_carbonflux_inst
+ type(cnveg_state_type) , intent(in) :: cnveg_state_inst
+
+! LOCAL VARIABLES:
+ integer :: fc,fp,j,i,k ! indices
+ integer :: p,c !
+
+ ! Temporary variables matrix A for different processes
+ real(r8),dimension(:,:) :: Aphconed(bounds%begp:bounds%endp,ncphtrans-ncphouttrans)
+ real(r8),dimension(:,:) :: Aphnoned(bounds%begp:bounds%endp,nnphtrans-nnphouttrans)
+ real(r8),dimension(:,:) :: Agmconed(bounds%begp:bounds%endp,ncgmtrans-ncgmouttrans)
+ real(r8),dimension(:,:) :: Agmnoned(bounds%begp:bounds%endp,nngmtrans-nngmouttrans)
+ real(r8),dimension(:,:) :: Aficoned(bounds%begp:bounds%endp,ncfitrans-ncfiouttrans)
+ real(r8),dimension(:,:) :: Afic14oned(bounds%begp:bounds%endp,ncfitrans-ncfiouttrans)
+ real(r8),dimension(:,:) :: Afinoned(bounds%begp:bounds%endp,nnfitrans-nnfiouttrans)
+
+ ! Temporary variables saving row indices of all transfers in different processes
+ integer,dimension(:) :: AI_phc(ncphtrans-ncphouttrans)
+ integer,dimension(:) :: AI_phn(nnphtrans-nnphouttrans)
+ integer,dimension(:) :: AI_gmc(ncgmtrans-ncgmouttrans)
+ integer,dimension(:) :: AI_gmn(nngmtrans-nngmouttrans)
+ integer,dimension(:) :: AI_fic(ncfitrans-ncfiouttrans)
+ integer,dimension(:) :: AI_fic14(ncfitrans-ncfiouttrans)
+ integer,dimension(:) :: AI_fin(nnfitrans-nnfiouttrans)
+
+ ! Temporary variables saving column indices of all transfers in different processes
+ integer,dimension(:) :: AJ_phc(ncphtrans-ncphouttrans)
+ integer,dimension(:) :: AJ_phn(nnphtrans-nnphouttrans)
+ integer,dimension(:) :: AJ_gmc(ncgmtrans-ncgmouttrans)
+ integer,dimension(:) :: AJ_gmn(nngmtrans-nngmouttrans)
+ integer,dimension(:) :: AJ_fic(ncfitrans-ncfiouttrans)
+ integer,dimension(:) :: AJ_fic14(ncfitrans-ncfiouttrans)
+ integer,dimension(:) :: AJ_fin(nnfitrans-nnfiouttrans)
+
+ ! Temporary variables for matrix operation, which save C and N inputs to different vegetation compartments as a vector type.
+ type(vector_type) :: vegmatrixc_input
+ type(vector_type) :: vegmatrixc13_input
+ type(vector_type) :: vegmatrixc14_input
+ type(vector_type) :: vegmatrixn_input
+
+ ! "init" indicators indicate whether A matrices have been initialized.
+ logical, save :: init_ready_aphc = .false.
+ logical, save :: init_ready_agmc = .false.
+ logical, save :: init_ready_afic = .false.
+ logical, save :: init_ready_afic14 = .false.
+ logical, save :: init_ready_aphn = .false.
+ logical, save :: init_ready_agmn = .false.
+ logical, save :: init_ready_afin = .false.
+
+ ! "list" indicators indicate whether operation of sparse matrix plus SPMP_AB or SPMP_ABC has already been saved.
+ logical, save :: list_ready_phgmfic = .false.
+ logical, save :: list_ready_phgmfic14 = .false.
+ logical, save :: list_ready_phgmc = .false.
+ logical, save :: list_ready_phgmfin = .false.
+ logical, save :: list_ready_phgmn = .false.
+
+ ! Temporary variables are only used at end of the year to calculate C and N storage capacity
+ real(r8),dimension(:) :: matrix_calloc_acc (1:nvegcpool)
+ real(r8),dimension(:) :: matrix_nalloc_acc (1:nvegnpool)
+ real(r8),dimension(:,:) :: matrix_ctransfer_acc (1:nvegcpool,1:nvegcpool)
+ real(r8),dimension(:,:) :: matrix_ntransfer_acc (1:nvegnpool,1:nvegnpool)
+ real(r8),dimension(:) :: matrix_c13alloc_acc (1:nvegcpool)
+ real(r8),dimension(:,:) :: matrix_c13transfer_acc (1:nvegcpool,1:nvegcpool)
+ real(r8),dimension(:) :: matrix_c14alloc_acc (1:nvegcpool)
+ real(r8),dimension(:,:) :: matrix_c14transfer_acc (1:nvegcpool,1:nvegcpool)
+
+ ! Local variables for capacity calculation and spin up
+ real(r8),dimension(:) :: vegmatrixc_rt(1:nvegcpool) ! C storage capacity
+ real(r8),dimension(:) :: vegmatrixc13_rt(1:nvegcpool) ! C13 storage capacity
+ real(r8),dimension(:) :: vegmatrixc14_rt(1:nvegcpool) ! C14 storage capacity
+ real(r8),dimension(:) :: vegmatrixn_rt(1:nvegnpool) ! N storage capacity
+ real(r8),dimension(:,:) :: AKinvc(1:nvegcpool,1:nvegcpool),AKinvn(1:nvegnpool,1:nvegnpool)
+ real(r8):: epsi
+
+
+ real(r8):: dt ! time step (seconds)
+#ifdef _OPENMP
+ integer, external :: OMP_GET_MAX_THREADS
+ integer :: nthreads ! Number of threads
+#else
+ integer, parameter :: nthreads = 0 ! Number of threads
+#endif
+ integer, parameter :: irepr = 1 ! Reproductive index to use for grain
+
+fr: associate( &
+ ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type
+ cf13_veg => c13_cnveg_carbonflux_inst , & ! In
+ cf14_veg => c14_cnveg_carbonflux_inst , & ! In
+ cs13_veg => c13_cnveg_carbonstate_inst , & ! In/Output
+ cs14_veg => c14_cnveg_carbonstate_inst , & ! In/Output
+
+ fire_closs => cnveg_carbonflux_inst%fire_closs_patch , &
+
+ ! Original vegetation variables are updated by matrix operation in this module
+ leafc => cnveg_carbonstate_inst%leafc_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf C
+ leafc_storage => cnveg_carbonstate_inst%leafc_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf storage C
+ leafc_xfer => cnveg_carbonstate_inst%leafc_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf transfer C
+ frootc => cnveg_carbonstate_inst%frootc_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) fine root C
+ frootc_storage => cnveg_carbonstate_inst%frootc_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) fine root storage C
+ frootc_xfer => cnveg_carbonstate_inst%frootc_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) fine root transfer C
+ livestemc => cnveg_carbonstate_inst%livestemc_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live stem C
+ livestemc_storage => cnveg_carbonstate_inst%livestemc_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live stem storage C
+ livestemc_xfer => cnveg_carbonstate_inst%livestemc_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live stem transfer C
+ deadstemc => cnveg_carbonstate_inst%deadstemc_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead stem C
+ deadstemc_storage => cnveg_carbonstate_inst%deadstemc_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead stem storage C
+ deadstemc_xfer => cnveg_carbonstate_inst%deadstemc_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead stem transfer C
+ livecrootc => cnveg_carbonstate_inst%livecrootc_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live coarse root C
+ livecrootc_storage => cnveg_carbonstate_inst%livecrootc_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live coarse root storage C
+ livecrootc_xfer => cnveg_carbonstate_inst%livecrootc_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live coarse root transfer C
+ deadcrootc => cnveg_carbonstate_inst%deadcrootc_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead coarse root C
+ deadcrootc_storage => cnveg_carbonstate_inst%deadcrootc_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead coarse root storage C
+ deadcrootc_xfer => cnveg_carbonstate_inst%deadcrootc_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead coarse root transfer C
+ reproductivec => cnveg_carbonstate_inst%reproductivec_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) grain C
+ reproductivec_storage => cnveg_carbonstate_inst%reproductivec_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) grain storage C
+ reproductivec_xfer => cnveg_carbonstate_inst%reproductivec_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) grain transfer C
+
+ leafn => cnveg_nitrogenstate_inst%leafn_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) leaf N
+ leafn_storage => cnveg_nitrogenstate_inst%leafn_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) leaf storage N
+ leafn_xfer => cnveg_nitrogenstate_inst%leafn_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) leaf transfer N
+ frootn => cnveg_nitrogenstate_inst%frootn_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) fine root N
+ frootn_storage => cnveg_nitrogenstate_inst%frootn_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) fine root storage N
+ frootn_xfer => cnveg_nitrogenstate_inst%frootn_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) fine root transfer N
+ livestemn => cnveg_nitrogenstate_inst%livestemn_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live stem N
+ livestemn_storage => cnveg_nitrogenstate_inst%livestemn_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live stem storage N
+ livestemn_xfer => cnveg_nitrogenstate_inst%livestemn_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live stem transfer N
+ deadstemn => cnveg_nitrogenstate_inst%deadstemn_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead stem N
+ deadstemn_storage => cnveg_nitrogenstate_inst%deadstemn_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead stem storage N
+ deadstemn_xfer => cnveg_nitrogenstate_inst%deadstemn_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead stem transfer N
+ livecrootn => cnveg_nitrogenstate_inst%livecrootn_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live coarse root N
+ livecrootn_storage => cnveg_nitrogenstate_inst%livecrootn_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live coarse root storage N
+ livecrootn_xfer => cnveg_nitrogenstate_inst%livecrootn_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live coarse root transfer N
+ deadcrootn => cnveg_nitrogenstate_inst%deadcrootn_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead coarse root N
+ deadcrootn_storage => cnveg_nitrogenstate_inst%deadcrootn_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead coarse root storage N
+ deadcrootn_xfer => cnveg_nitrogenstate_inst%deadcrootn_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead coarse root transfer N
+ reproductiven => cnveg_nitrogenstate_inst%reproductiven_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) grain N
+ reproductiven_storage => cnveg_nitrogenstate_inst%reproductiven_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) grain storage N
+ reproductiven_xfer => cnveg_nitrogenstate_inst%reproductiven_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) grain transfer N
+ retransn => cnveg_nitrogenstate_inst%retransn_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) plant retranslocated N
+
+ leafc_SASUsave => cnveg_carbonstate_inst%leafc_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf C for SASU
+ leafc_storage_SASUsave => cnveg_carbonstate_inst%leafc_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf C for SASU
+ leafc_xfer_SASUsave => cnveg_carbonstate_inst%leafc_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf C for SASU
+ frootc_SASUsave => cnveg_carbonstate_inst%frootc_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) froot C for SASU
+ frootc_storage_SASUsave => cnveg_carbonstate_inst%frootc_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) froot C for SASU
+ frootc_xfer_SASUsave => cnveg_carbonstate_inst%frootc_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) froot C for SASU
+ livestemc_SASUsave => cnveg_carbonstate_inst%livestemc_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livestem C for SASU
+ livestemc_storage_SASUsave => cnveg_carbonstate_inst%livestemc_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livestem C for SASU
+ livestemc_xfer_SASUsave => cnveg_carbonstate_inst%livestemc_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livestem C for SASU
+ deadstemc_SASUsave => cnveg_carbonstate_inst%deadstemc_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadstem C for SASU
+ deadstemc_storage_SASUsave => cnveg_carbonstate_inst%deadstemc_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadstem C for SASU
+ deadstemc_xfer_SASUsave => cnveg_carbonstate_inst%deadstemc_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadstem C for SASU
+ livecrootc_SASUsave => cnveg_carbonstate_inst%livecrootc_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livecroot C for SASU
+ livecrootc_storage_SASUsave => cnveg_carbonstate_inst%livecrootc_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livecroot C for SASU
+ livecrootc_xfer_SASUsave => cnveg_carbonstate_inst%livecrootc_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livecroot C for SASU
+ deadcrootc_SASUsave => cnveg_carbonstate_inst%deadcrootc_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadcroot C for SASU
+ deadcrootc_storage_SASUsave => cnveg_carbonstate_inst%deadcrootc_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadcroot C for SASU
+ deadcrootc_xfer_SASUsave => cnveg_carbonstate_inst%deadcrootc_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadcroot C for SASU
+ grainc_SASUsave => cnveg_carbonstate_inst%grainc_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) grain C for SASU
+ grainc_storage_SASUsave => cnveg_carbonstate_inst%grainc_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) grain storage C for SASU
+
+ leafn_SASUsave => cnveg_nitrogenstate_inst%leafn_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf N for SASU
+ leafn_storage_SASUsave => cnveg_nitrogenstate_inst%leafn_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf N for SASU
+ leafn_xfer_SASUsave => cnveg_nitrogenstate_inst%leafn_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf N for SASU
+ frootn_SASUsave => cnveg_nitrogenstate_inst%frootn_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) froot N for SASU
+ frootn_storage_SASUsave => cnveg_nitrogenstate_inst%frootn_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) froot N for SASU
+ frootn_xfer_SASUsave => cnveg_nitrogenstate_inst%frootn_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) froot N for SASU
+ livestemn_SASUsave => cnveg_nitrogenstate_inst%livestemn_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livestem N for SASU
+ livestemn_storage_SASUsave => cnveg_nitrogenstate_inst%livestemn_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livestem N for SASU
+ livestemn_xfer_SASUsave => cnveg_nitrogenstate_inst%livestemn_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livestem N for SASU
+ deadstemn_SASUsave => cnveg_nitrogenstate_inst%deadstemn_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadstem N for SASU
+ deadstemn_storage_SASUsave => cnveg_nitrogenstate_inst%deadstemn_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadstem N for SASU
+ deadstemn_xfer_SASUsave => cnveg_nitrogenstate_inst%deadstemn_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadstem N for SASU
+ livecrootn_SASUsave => cnveg_nitrogenstate_inst%livecrootn_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livecroot N for SASU
+ livecrootn_storage_SASUsave => cnveg_nitrogenstate_inst%livecrootn_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livecroot N for SASU
+ livecrootn_xfer_SASUsave => cnveg_nitrogenstate_inst%livecrootn_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livecroot N for SASU
+ deadcrootn_SASUsave => cnveg_nitrogenstate_inst%deadcrootn_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadcroot N for SASU
+ deadcrootn_storage_SASUsave => cnveg_nitrogenstate_inst%deadcrootn_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadcroot N for SASU
+ deadcrootn_xfer_SASUsave => cnveg_nitrogenstate_inst%deadcrootn_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadcroot N for SASU
+ grainn_SASUsave => cnveg_nitrogenstate_inst%grainn_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) grain N for SASU
+ grainn_storage_SASUsave => cnveg_nitrogenstate_inst%grainn_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) grain storage N for SASU
+
+ ! Vegetation capacity variables "matrix_cap_*", save the capacity of each vegetation compartment.
+ matrix_cap_leafc => cnveg_carbonstate_inst%matrix_cap_leafc_patch ,&!Output:[real(r8)(:)] (gC/m2) leaf C capacity
+ matrix_cap_leafc_storage => cnveg_carbonstate_inst%matrix_cap_leafc_storage_patch ,&!Output:[real(r8)(:)] (gC/m2) leaf storage C capacity
+ matrix_cap_leafc_xfer => cnveg_carbonstate_inst%matrix_cap_leafc_xfer_patch ,&!Output:[real(r8)(:)] (gC/m2) leaf transfer C capacity
+ matrix_cap_frootc => cnveg_carbonstate_inst%matrix_cap_frootc_patch ,&!Output:[real(r8)(:)] (gC/m2) fine root C capacity
+ matrix_cap_frootc_storage => cnveg_carbonstate_inst%matrix_cap_frootc_storage_patch ,&!Output:[real(r8)(:)] (gC/m2) fine root storage C capacity
+ matrix_cap_frootc_xfer => cnveg_carbonstate_inst%matrix_cap_frootc_xfer_patch ,&!Output:[real(r8)(:)] (gC/m2) fine root transfer C capacity
+ matrix_cap_livestemc => cnveg_carbonstate_inst%matrix_cap_livestemc_patch ,&!Output:[real(r8)(:)] (gC/m2) live stem C capacity
+ matrix_cap_livestemc_storage => cnveg_carbonstate_inst%matrix_cap_livestemc_storage_patch ,&!Output:[real(r8)(:)] (gC/m2) live stem storage C capacity
+ matrix_cap_livestemc_xfer => cnveg_carbonstate_inst%matrix_cap_livestemc_xfer_patch ,&!Output:[real(r8)(:)] (gC/m2) live stem transfer C capacity
+ matrix_cap_deadstemc => cnveg_carbonstate_inst%matrix_cap_deadstemc_patch ,&!Output:[real(r8)(:)] (gC/m2) dead stem C capacity
+ matrix_cap_deadstemc_storage => cnveg_carbonstate_inst%matrix_cap_deadstemc_storage_patch ,&!Output:[real(r8)(:)] (gC/m2) dead stem storage C capaicty
+ matrix_cap_deadstemc_xfer => cnveg_carbonstate_inst%matrix_cap_deadstemc_xfer_patch ,&!Output:[real(r8)(:)] (gC/m2) dead stem transfer C capacity
+ matrix_cap_livecrootc => cnveg_carbonstate_inst%matrix_cap_livecrootc_patch ,&!Output:[real(r8)(:)] (gC/m2) live coarse root C capacity
+ matrix_cap_livecrootc_storage => cnveg_carbonstate_inst%matrix_cap_livecrootc_storage_patch ,&!Output:[real(r8)(:)] (gC/m2) live coarse root storage C capacity
+ matrix_cap_livecrootc_xfer => cnveg_carbonstate_inst%matrix_cap_livecrootc_xfer_patch ,&!Output:[real(r8)(:)] (gC/m2) live coarse root transfer C capacity
+ matrix_cap_deadcrootc => cnveg_carbonstate_inst%matrix_cap_deadcrootc_patch ,&!Output:[real(r8)(:)] (gC/m2) dead coarse root C capacity
+ matrix_cap_deadcrootc_storage => cnveg_carbonstate_inst%matrix_cap_deadcrootc_storage_patch ,&!Output:[real(r8)(:)] (gC/m2) dead coarse root storage C capacity
+ matrix_cap_deadcrootc_xfer => cnveg_carbonstate_inst%matrix_cap_deadcrootc_xfer_patch ,&!Output:[real(r8)(:)] (gC/m2) dead coarse root transfer C capacity
+ matrix_cap_reproc => cnveg_carbonstate_inst%matrix_cap_reproc_patch ,&!Output:[real(r8)(:)] (gC/m2) grain C capacity
+ matrix_cap_reproc_storage => cnveg_carbonstate_inst%matrix_cap_reproc_storage_patch ,&!Output:[real(r8)(:)] (gC/m2) grain storage C capacity
+ matrix_cap_reproc_xfer => cnveg_carbonstate_inst%matrix_cap_reproc_xfer_patch ,&!Output:[real(r8)(:)] (gC/m2) grain transfer C
+
+ matrix_cap_leafn => cnveg_nitrogenstate_inst%matrix_cap_leafn_patch ,&!Output:[real(r8)(:)] (gN/m2) leaf N capacity
+ matrix_cap_leafn_storage => cnveg_nitrogenstate_inst%matrix_cap_leafn_storage_patch ,&!Output:[real(r8)(:)] (gN/m2) leaf storage N capacity
+ matrix_cap_leafn_xfer => cnveg_nitrogenstate_inst%matrix_cap_leafn_xfer_patch ,&!Output:[real(r8)(:)] (gN/m2) leaf transfer N capacity
+ matrix_cap_frootn => cnveg_nitrogenstate_inst%matrix_cap_frootn_patch ,&!Output:[real(r8)(:)] (gN/m2) fine root N capacity
+ matrix_cap_frootn_storage => cnveg_nitrogenstate_inst%matrix_cap_frootn_storage_patch ,&!Output:[real(r8)(:)] (gN/m2) fine root storage N capacity
+ matrix_cap_frootn_xfer => cnveg_nitrogenstate_inst%matrix_cap_frootn_xfer_patch ,&!Output:[real(r8)(:)] (gN/m2) fine root transfer N capacity
+ matrix_cap_livestemn => cnveg_nitrogenstate_inst%matrix_cap_livestemn_patch ,&!Output:[real(r8)(:)] (gN/m2) live stem N capacity
+ matrix_cap_livestemn_storage => cnveg_nitrogenstate_inst%matrix_cap_livestemn_storage_patch ,&!Output:[real(r8)(:)] (gN/m2) live stem storage N capacity
+ matrix_cap_livestemn_xfer => cnveg_nitrogenstate_inst%matrix_cap_livestemn_xfer_patch ,&!Output:[real(r8)(:)] (gN/m2) live stem transfer N capacity
+ matrix_cap_deadstemn => cnveg_nitrogenstate_inst%matrix_cap_deadstemn_patch ,&!Output:[real(r8)(:)] (gN/m2) dead stem N capacity
+ matrix_cap_deadstemn_storage => cnveg_nitrogenstate_inst%matrix_cap_deadstemn_storage_patch ,&!Output:[real(r8)(:)] (gN/m2) dead stem storage N capacity
+ matrix_cap_deadstemn_xfer => cnveg_nitrogenstate_inst%matrix_cap_deadstemn_xfer_patch ,&!Output:[real(r8)(:)] (gN/m2) dead stem transfer N capacity
+ matrix_cap_livecrootn => cnveg_nitrogenstate_inst%matrix_cap_livecrootn_patch ,&!Output:[real(r8)(:)] (gN/m2) live coarse root N capacity
+ matrix_cap_livecrootn_storage => cnveg_nitrogenstate_inst%matrix_cap_livecrootn_storage_patch,&!Output:[real(r8)(:)] (gN/m2) live coarse root storage N capacity
+ matrix_cap_livecrootn_xfer => cnveg_nitrogenstate_inst%matrix_cap_livecrootn_xfer_patch ,&!Output:[real(r8)(:)] (gN/m2) live coarse root transfer N capacity
+ matrix_cap_deadcrootn => cnveg_nitrogenstate_inst%matrix_cap_deadcrootn_patch ,&!Output:[real(r8)(:)] (gN/m2) dead coarse root N capacity
+ matrix_cap_deadcrootn_storage => cnveg_nitrogenstate_inst%matrix_cap_deadcrootn_storage_patch,&!Output:[real(r8)(:)] (gN/m2) dead coarse root storage N capacity
+ matrix_cap_deadcrootn_xfer => cnveg_nitrogenstate_inst%matrix_cap_deadcrootn_xfer_patch ,&!Output:[real(r8)(:)] (gN/m2) dead coarse root transfer N capacity
+ matrix_cap_repron => cnveg_nitrogenstate_inst%matrix_cap_repron_patch ,&!Output:[real(r8)(:)] (gN/m2) grain N capacity
+ matrix_cap_repron_storage => cnveg_nitrogenstate_inst%matrix_cap_repron_storage_patch ,&!Output:[real(r8)(:)] (gN/m2) grain storage N capacity
+ matrix_cap_repron_xfer => cnveg_nitrogenstate_inst%matrix_cap_repron_xfer_patch ,&!Output:[real(r8)(:)] (gN/m2) grain transfer N capacity
+
+ ! Variables matrix_calloc_*_acc, matrix_ctransfer_*_acc, and matrix_cturnover_*_acc are used to calculate the C capacity as the C steady state estimates in spin up.
+ ! These variables are all state variables, saving accumulated N transfers during the calendar year.
+ matrix_calloc_leaf_acc => cnveg_carbonstate_inst%matrix_calloc_leaf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to leaf during this year
+ matrix_calloc_leafst_acc => cnveg_carbonstate_inst%matrix_calloc_leafst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to leaf storage during this year
+ matrix_calloc_froot_acc => cnveg_carbonstate_inst%matrix_calloc_froot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to fine root during this year
+ matrix_calloc_frootst_acc => cnveg_carbonstate_inst%matrix_calloc_frootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to fine root storage during this year
+ matrix_calloc_livestem_acc => cnveg_carbonstate_inst%matrix_calloc_livestem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to live stem during this year
+ matrix_calloc_livestemst_acc => cnveg_carbonstate_inst%matrix_calloc_livestemst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to live stem storage during this year
+ matrix_calloc_deadstem_acc => cnveg_carbonstate_inst%matrix_calloc_deadstem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to dead stem during this year
+ matrix_calloc_deadstemst_acc => cnveg_carbonstate_inst%matrix_calloc_deadstemst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to dead stem storage during this year
+ matrix_calloc_livecroot_acc => cnveg_carbonstate_inst%matrix_calloc_livecroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to live corase root during this year
+ matrix_calloc_livecrootst_acc => cnveg_carbonstate_inst%matrix_calloc_livecrootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to live corase root storage during this year
+ matrix_calloc_deadcroot_acc => cnveg_carbonstate_inst%matrix_calloc_deadcroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to dead corase root during this year
+ matrix_calloc_deadcrootst_acc => cnveg_carbonstate_inst%matrix_calloc_deadcrootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to dead corase root storage during this year
+ matrix_calloc_grain_acc => cnveg_carbonstate_inst%matrix_calloc_grain_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to grain during this year
+ matrix_calloc_grainst_acc => cnveg_carbonstate_inst%matrix_calloc_grainst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to grain storage during this year
+
+ matrix_ctransfer_leafst_to_leafxf_acc => cnveg_carbonstate_inst%matrix_ctransfer_leafst_to_leafxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from leaf storage to leaf transfer pool during this year
+ matrix_ctransfer_leafxf_to_leaf_acc => cnveg_carbonstate_inst%matrix_ctransfer_leafxf_to_leaf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from leaf transfer to leaf pool during this year
+ matrix_ctransfer_frootst_to_frootxf_acc => cnveg_carbonstate_inst%matrix_ctransfer_frootst_to_frootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from fine root storage to fine root transfer pool during this year
+ matrix_ctransfer_frootxf_to_froot_acc => cnveg_carbonstate_inst%matrix_ctransfer_frootxf_to_froot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from fine root transfer to fine root pool during this year
+ matrix_ctransfer_livestemst_to_livestemxf_acc => cnveg_carbonstate_inst%matrix_ctransfer_livestemst_to_livestemxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from live stem storage to live stem transfer pool during this year
+ matrix_ctransfer_livestemxf_to_livestem_acc => cnveg_carbonstate_inst%matrix_ctransfer_livestemxf_to_livestem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from live stem transfer to live stem pool during this year
+ matrix_ctransfer_deadstemst_to_deadstemxf_acc => cnveg_carbonstate_inst%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from dead stem storage to dead stem transfer pool during this year
+ matrix_ctransfer_deadstemxf_to_deadstem_acc => cnveg_carbonstate_inst%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from dead stem transfer to dead stem pool during this year
+ matrix_ctransfer_livecrootst_to_livecrootxf_acc => cnveg_carbonstate_inst%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from live coarse root storage to live coarse root transfer pool during this year
+ matrix_ctransfer_livecrootxf_to_livecroot_acc => cnveg_carbonstate_inst%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from live coarse root transfer to live coarse root pool during this year
+ matrix_ctransfer_deadcrootst_to_deadcrootxf_acc => cnveg_carbonstate_inst%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from dead coarse root storage to dead coarse root transfer pool during this year
+ matrix_ctransfer_deadcrootxf_to_deadcroot_acc => cnveg_carbonstate_inst%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from dead coarse root transfer to dead coarse root pool during this year
+ matrix_ctransfer_grainst_to_grainxf_acc => cnveg_carbonstate_inst%matrix_ctransfer_grainst_to_grainxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from grain storage to grain transfer pool during this year
+ matrix_ctransfer_grainxf_to_grain_acc => cnveg_carbonstate_inst%matrix_ctransfer_grainxf_to_grain_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from grain transfer to grain pool during this year
+ matrix_ctransfer_livestem_to_deadstem_acc => cnveg_carbonstate_inst%matrix_ctransfer_livestem_to_deadstem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from live stem to dead stem pool during this year
+ matrix_ctransfer_livecroot_to_deadcroot_acc => cnveg_carbonstate_inst%matrix_ctransfer_livecroot_to_deadcroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from live coarse root to dead coarse root pool during this year
+
+ matrix_cturnover_leaf_acc => cnveg_carbonstate_inst%matrix_cturnover_leaf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from leaf
+ matrix_cturnover_leafst_acc => cnveg_carbonstate_inst%matrix_cturnover_leafst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from leaf storage
+ matrix_cturnover_leafxf_acc => cnveg_carbonstate_inst%matrix_cturnover_leafxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from leaf transfer
+ matrix_cturnover_froot_acc => cnveg_carbonstate_inst%matrix_cturnover_froot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from fine root
+ matrix_cturnover_frootst_acc => cnveg_carbonstate_inst%matrix_cturnover_frootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from fine root storage
+ matrix_cturnover_frootxf_acc => cnveg_carbonstate_inst%matrix_cturnover_frootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from fine root transfer
+ matrix_cturnover_livestem_acc => cnveg_carbonstate_inst%matrix_cturnover_livestem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from live stem
+ matrix_cturnover_livestemst_acc => cnveg_carbonstate_inst%matrix_cturnover_livestemst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from live stem storage
+ matrix_cturnover_livestemxf_acc => cnveg_carbonstate_inst%matrix_cturnover_livestemxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from live stem transfer
+ matrix_cturnover_deadstem_acc => cnveg_carbonstate_inst%matrix_cturnover_deadstem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from dead stem
+ matrix_cturnover_deadstemst_acc => cnveg_carbonstate_inst%matrix_cturnover_deadstemst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from dead stem storage
+ matrix_cturnover_deadstemxf_acc => cnveg_carbonstate_inst%matrix_cturnover_deadstemxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from dead stem transfer
+ matrix_cturnover_livecroot_acc => cnveg_carbonstate_inst%matrix_cturnover_livecroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from live coarse root
+ matrix_cturnover_livecrootst_acc => cnveg_carbonstate_inst%matrix_cturnover_livecrootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from live coarse root storage
+ matrix_cturnover_livecrootxf_acc => cnveg_carbonstate_inst%matrix_cturnover_livecrootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from live coarse root transfer
+ matrix_cturnover_deadcroot_acc => cnveg_carbonstate_inst%matrix_cturnover_deadcroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from dead coarse root
+ matrix_cturnover_deadcrootst_acc => cnveg_carbonstate_inst%matrix_cturnover_deadcrootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from dead coarse root storage
+ matrix_cturnover_deadcrootxf_acc => cnveg_carbonstate_inst%matrix_cturnover_deadcrootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from dead coarse root transfer
+ matrix_cturnover_grain_acc => cnveg_carbonstate_inst%matrix_cturnover_grain_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from grain
+ matrix_cturnover_grainst_acc => cnveg_carbonstate_inst%matrix_cturnover_grainst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from grain storage
+ matrix_cturnover_grainxf_acc => cnveg_carbonstate_inst%matrix_cturnover_grainxf_acc_patch &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from grain transfer
+ )
+od: associate( &
+
+ ! Variables matrix_nalloc_*_acc, matrix_ntransfer_*_acc, and matrix_nturnover_*_acc are used to calculate the N capacity as the N steady state estimates in spin up.
+ ! These variables are all state variables, saving accumulated N transfers during the calendar year.
+ matrix_nalloc_leaf_acc => cnveg_nitrogenstate_inst%matrix_nalloc_leaf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to leaf during this year
+ matrix_nalloc_leafst_acc => cnveg_nitrogenstate_inst%matrix_nalloc_leafst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to leaf storage during this year
+ matrix_nalloc_froot_acc => cnveg_nitrogenstate_inst%matrix_nalloc_froot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to fine root during this year
+ matrix_nalloc_frootst_acc => cnveg_nitrogenstate_inst%matrix_nalloc_frootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to fine root storage during this year
+ matrix_nalloc_livestem_acc => cnveg_nitrogenstate_inst%matrix_nalloc_livestem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to live stem during this year
+ matrix_nalloc_livestemst_acc => cnveg_nitrogenstate_inst%matrix_nalloc_livestemst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to live stem storage during this year
+ matrix_nalloc_deadstem_acc => cnveg_nitrogenstate_inst%matrix_nalloc_deadstem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to dead stem during this year
+ matrix_nalloc_deadstemst_acc => cnveg_nitrogenstate_inst%matrix_nalloc_deadstemst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to dead stem storage during this year
+ matrix_nalloc_livecroot_acc => cnveg_nitrogenstate_inst%matrix_nalloc_livecroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to live coarse root during this year
+ matrix_nalloc_livecrootst_acc => cnveg_nitrogenstate_inst%matrix_nalloc_livecrootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to live coarse root storage during this year
+ matrix_nalloc_deadcroot_acc => cnveg_nitrogenstate_inst%matrix_nalloc_deadcroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to dead coarse root during this year
+ matrix_nalloc_deadcrootst_acc => cnveg_nitrogenstate_inst%matrix_nalloc_deadcrootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to dead coarse root storage during this year
+ matrix_nalloc_grain_acc => cnveg_nitrogenstate_inst%matrix_nalloc_grain_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to grain during this year
+ matrix_nalloc_grainst_acc => cnveg_nitrogenstate_inst%matrix_nalloc_grainst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to grain storage during this year
+
+ matrix_ntransfer_leafst_to_leafxf_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_leafst_to_leafxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from leaf storage to leaf transfer pool during this year
+ matrix_ntransfer_leafxf_to_leaf_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_leafxf_to_leaf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from leaf transfer to leaf pool during this year
+ matrix_ntransfer_frootst_to_frootxf_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_frootst_to_frootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from fine root storage to fine root transfer pool during this year
+ matrix_ntransfer_frootxf_to_froot_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_frootxf_to_froot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from fine root transfer to fine root pool during this year
+ matrix_ntransfer_livestemst_to_livestemxf_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_livestemst_to_livestemxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from live stem storage to live stem transfer pool during this year
+ matrix_ntransfer_livestemxf_to_livestem_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_livestemxf_to_livestem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from live stem transfer to live stem pool during this year
+ matrix_ntransfer_deadstemst_to_deadstemxf_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_deadstemst_to_deadstemxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from dead stem storage to dead stem transfer pool during this year
+ matrix_ntransfer_deadstemxf_to_deadstem_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_deadstemxf_to_deadstem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from dead stem transfer to dead stem pool during this year
+ matrix_ntransfer_livecrootst_to_livecrootxf_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_livecrootst_to_livecrootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from live coarese root storage to live coarese root transfer pool during this year
+ matrix_ntransfer_livecrootxf_to_livecroot_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_livecrootxf_to_livecroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from live coarese root transfer to live coarese root pool during this year
+ matrix_ntransfer_deadcrootst_to_deadcrootxf_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_deadcrootst_to_deadcrootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from dead coarse root storage to dead coarse root transfer pool during this year
+ matrix_ntransfer_deadcrootxf_to_deadcroot_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_deadcrootxf_to_deadcroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from dead coarse root transfer to dead coarse root pool during this year
+ matrix_ntransfer_grainst_to_grainxf_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_grainst_to_grainxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from grain storage to grain transfer pool during this year
+ matrix_ntransfer_grainxf_to_grain_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_grainxf_to_grain_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from grain transfer to grain pool during this year
+ matrix_ntransfer_livestem_to_deadstem_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_livestem_to_deadstem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from live stem storage to dead stem transfer pool during this year
+ matrix_ntransfer_livecroot_to_deadcroot_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_livecroot_to_deadcroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from live coarse root to dead coarse root pool during this year
+
+ matrix_ntransfer_retransn_to_leaf_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_leaf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to leaf pool during this year
+ matrix_ntransfer_retransn_to_leafst_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_leafst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to leaf storage pool during this year
+ matrix_ntransfer_retransn_to_froot_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_froot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to fine root pool during this year
+ matrix_ntransfer_retransn_to_frootst_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_frootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to fine root storage pool during this year
+ matrix_ntransfer_retransn_to_livestem_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_livestem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to live stem pool during this year
+ matrix_ntransfer_retransn_to_livestemst_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_livestemst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to livestem storage pool during this year
+ matrix_ntransfer_retransn_to_deadstem_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_deadstem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to dead stem pool during this year
+ matrix_ntransfer_retransn_to_deadstemst_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_deadstemst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to dead stem storage pool during this year
+ matrix_ntransfer_retransn_to_livecroot_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_livecroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to live coarse root pool during this year
+ matrix_ntransfer_retransn_to_livecrootst_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_livecrootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to live coarse root storage pool during this year
+ matrix_ntransfer_retransn_to_deadcroot_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_deadcroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to dead coarse root pool during this year
+ matrix_ntransfer_retransn_to_deadcrootst_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_deadcrootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to dead coarse root storage pool during this year
+ matrix_ntransfer_retransn_to_grain_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_grain_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to grain pool during this year
+ matrix_ntransfer_retransn_to_grainst_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_grainst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to grain storage pool during this year
+
+ matrix_ntransfer_leaf_to_retransn_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_leaf_to_retransn_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from leaf pool to retranslocated N pool during this year
+ matrix_ntransfer_froot_to_retransn_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_froot_to_retransn_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from fine root pool to retranslocated N pool during this year
+ matrix_ntransfer_livestem_to_retransn_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_livestem_to_retransn_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from live stem pool to retranslocated N pool during this year
+ matrix_ntransfer_livecroot_to_retransn_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_livecroot_to_retransn_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from live coarse root pool to retranslocated N pool during this year
+
+ matrix_nturnover_leaf_acc => cnveg_nitrogenstate_inst%matrix_nturnover_leaf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from leaf
+ matrix_nturnover_leafst_acc => cnveg_nitrogenstate_inst%matrix_nturnover_leafst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from leaf storage
+ matrix_nturnover_leafxf_acc => cnveg_nitrogenstate_inst%matrix_nturnover_leafxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from leaf transfer
+ matrix_nturnover_froot_acc => cnveg_nitrogenstate_inst%matrix_nturnover_froot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from fine root
+ matrix_nturnover_frootst_acc => cnveg_nitrogenstate_inst%matrix_nturnover_frootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from fine root storage
+ matrix_nturnover_frootxf_acc => cnveg_nitrogenstate_inst%matrix_nturnover_frootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from fine root transfer
+ matrix_nturnover_livestem_acc => cnveg_nitrogenstate_inst%matrix_nturnover_livestem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from live stem
+ matrix_nturnover_livestemst_acc => cnveg_nitrogenstate_inst%matrix_nturnover_livestemst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from live stem storage
+ matrix_nturnover_livestemxf_acc => cnveg_nitrogenstate_inst%matrix_nturnover_livestemxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from live stem transfer
+ matrix_nturnover_deadstem_acc => cnveg_nitrogenstate_inst%matrix_nturnover_deadstem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from dead stem
+ matrix_nturnover_deadstemst_acc => cnveg_nitrogenstate_inst%matrix_nturnover_deadstemst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from dead stem storage
+ matrix_nturnover_deadstemxf_acc => cnveg_nitrogenstate_inst%matrix_nturnover_deadstemxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from dead stem transfer
+ matrix_nturnover_livecroot_acc => cnveg_nitrogenstate_inst%matrix_nturnover_livecroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from live coarse root
+ matrix_nturnover_livecrootst_acc => cnveg_nitrogenstate_inst%matrix_nturnover_livecrootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from live coarse root storage
+ matrix_nturnover_livecrootxf_acc => cnveg_nitrogenstate_inst%matrix_nturnover_livecrootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from live coarse root transfer
+ matrix_nturnover_deadcroot_acc => cnveg_nitrogenstate_inst%matrix_nturnover_deadcroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from dead coarse root
+ matrix_nturnover_deadcrootst_acc => cnveg_nitrogenstate_inst%matrix_nturnover_deadcrootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from dead coarse root storage
+ matrix_nturnover_deadcrootxf_acc => cnveg_nitrogenstate_inst%matrix_nturnover_deadcrootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from dead coarse root transfer
+ matrix_nturnover_grain_acc => cnveg_nitrogenstate_inst%matrix_nturnover_grain_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from grain
+ matrix_nturnover_grainst_acc => cnveg_nitrogenstate_inst%matrix_nturnover_grainst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from grain storage
+ matrix_nturnover_grainxf_acc => cnveg_nitrogenstate_inst%matrix_nturnover_grainxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from grain transfer
+ matrix_nturnover_retransn_acc => cnveg_nitrogenstate_inst%matrix_nturnover_retransn_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from retranslocated N pool
+
+ ! *c0* variables save vegetation pool size at beginning of each year as a base for capacity calculation. For examples,
+ ! C turnover rate of pool KC_leaf (yr-1) is calculated by C turnover during the calendar year: matrix_cturnover_leaf_acc (gC/m2/yr) / leafc0 (gC/m2)
+ leafc0 => cnveg_carbonstate_inst%leafc0_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf C at begin of this year
+ leafc0_storage => cnveg_carbonstate_inst%leafc0_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf storage C at begin of this year
+ leafc0_xfer => cnveg_carbonstate_inst%leafc0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf transfer C at begin of this year
+ frootc0 => cnveg_carbonstate_inst%frootc0_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) fine root C at begin of this year
+ frootc0_storage => cnveg_carbonstate_inst%frootc0_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) fine root storage C at begin of this year
+ frootc0_xfer => cnveg_carbonstate_inst%frootc0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) fine root transfer C at begin of this year
+ livestemc0 => cnveg_carbonstate_inst%livestemc0_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live stem C at begin of this year
+ livestemc0_storage => cnveg_carbonstate_inst%livestemc0_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live stem storage C at begin of this year
+ livestemc0_xfer => cnveg_carbonstate_inst%livestemc0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live stem transfer C at begin of this year
+ deadstemc0 => cnveg_carbonstate_inst%deadstemc0_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead stem C at begin of this year
+ deadstemc0_storage => cnveg_carbonstate_inst%deadstemc0_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead stem storage C at begin of this year
+ deadstemc0_xfer => cnveg_carbonstate_inst%deadstemc0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead stem transfer C at begin of this year
+ livecrootc0 => cnveg_carbonstate_inst%livecrootc0_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live coarse root C at begin of this year
+ livecrootc0_storage => cnveg_carbonstate_inst%livecrootc0_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live coarse root storage C at begin of this year
+ livecrootc0_xfer => cnveg_carbonstate_inst%livecrootc0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live coarse root transfer C at begin of this year
+ deadcrootc0 => cnveg_carbonstate_inst%deadcrootc0_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead coarse root C at begin of this year
+ deadcrootc0_storage => cnveg_carbonstate_inst%deadcrootc0_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead coarse root storage C at begin of this year
+ deadcrootc0_xfer => cnveg_carbonstate_inst%deadcrootc0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead coarse root transfer C at begin of this year
+ reproc0 => cnveg_carbonstate_inst%reproc0_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) grain C at begin of this year
+ reproc0_storage => cnveg_carbonstate_inst%reproc0_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) grain storage C at begin of this year
+ reproc0_xfer => cnveg_carbonstate_inst%reproc0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) grain transfer C at begin of this year
+
+ ! *n0* variables save vegetation pool size at beginning of each year as a base for capacity calculation. For examples,
+ ! N turnover rate of pool KN_leaf (yr-1) is calculated by N turnover during the calendar year matrix_nturnover_leaf_acc (gN/m2/yr) / leafn0 (gN/m2)
+ leafn0 => cnveg_nitrogenstate_inst%leafn0_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) leaf N at begin of this year
+ leafn0_storage => cnveg_nitrogenstate_inst%leafn0_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) leaf storage N at begin of this year
+ leafn0_xfer => cnveg_nitrogenstate_inst%leafn0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) leaf transfer N at begin of this year
+ frootn0 => cnveg_nitrogenstate_inst%frootn0_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) fine root N at begin of this year
+ frootn0_storage => cnveg_nitrogenstate_inst%frootn0_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) fine root storage N at begin of this year
+ frootn0_xfer => cnveg_nitrogenstate_inst%frootn0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) fine root transfer N at begin of this year
+ livestemn0 => cnveg_nitrogenstate_inst%livestemn0_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live stem N at begin of this year
+ livestemn0_storage => cnveg_nitrogenstate_inst%livestemn0_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live stem storage N at begin of this year
+ livestemn0_xfer => cnveg_nitrogenstate_inst%livestemn0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live stem transfer N at begin of this year
+ deadstemn0 => cnveg_nitrogenstate_inst%deadstemn0_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead stem N at begin of this year
+ deadstemn0_storage => cnveg_nitrogenstate_inst%deadstemn0_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead stem storage N at begin of this year
+ deadstemn0_xfer => cnveg_nitrogenstate_inst%deadstemn0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead stem transfer N at begin of this year
+ livecrootn0 => cnveg_nitrogenstate_inst%livecrootn0_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live coarse root N at begin of this year
+ livecrootn0_storage => cnveg_nitrogenstate_inst%livecrootn0_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live coarse root storage N at begin of this year
+ livecrootn0_xfer => cnveg_nitrogenstate_inst%livecrootn0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live coarse root transfer N at begin of this year
+ deadcrootn0 => cnveg_nitrogenstate_inst%deadcrootn0_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead coarse root N at begin of this year
+ deadcrootn0_storage => cnveg_nitrogenstate_inst%deadcrootn0_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead coarse root storage N at begin of this year
+ deadcrootn0_xfer => cnveg_nitrogenstate_inst%deadcrootn0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead coarse root transfer N at begin of this year
+ repron0 => cnveg_nitrogenstate_inst%repron0_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) grain N at begin of this year
+ repron0_storage => cnveg_nitrogenstate_inst%repron0_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) grain storage N at begin of this year
+ repron0_xfer => cnveg_nitrogenstate_inst%repron0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) grain transfer N at begin of this year
+ retransn0 => cnveg_nitrogenstate_inst%retransn0_patch & ! In/Output: [real(r8) (:) ] (gN/m2) plant retranslocated N at begin of this year
+ )
+sd: associate( &
+
+ ! Following variables save the C and N transfer rate of different processes at current time step.
+ ! Eg. ph: phenology, gm: gap mortality (including harvest), fi: fire.
+ matrix_alloc => cnveg_carbonflux_inst%matrix_alloc_patch , & ! Input: [real(r8) (:,:)] (gC/gC) input C allocation matrix, updated in NutrientCompetitionFlexibleCNMod or NutrientCompetitionCLM45defaultMod
+ matrix_nalloc => cnveg_nitrogenflux_inst%matrix_nalloc_patch , & ! Input: [real(r8) (:,:)] (gC/gC) input N allocation matrix, updated in NutrientCompetitionFlexibleCNMod or NutrientCompetitionCLM45defaultMod
+ matrix_phtransfer => cnveg_carbonflux_inst%matrix_phtransfer_patch , & ! Input: [real(r8) (:,:)] (gC/m2/s) C transfer rate from phenology processes, updated in CNPhenology
+ matrix_gmtransfer => cnveg_carbonflux_inst%matrix_gmtransfer_patch , & ! Input: [real(r8) (:,:)] (gC/m2/s) C transfer rate from gap mortality processes, updated in CNGapMortality
+ matrix_fitransfer => cnveg_carbonflux_inst%matrix_fitransfer_patch , & ! Input: [real(r8) (:,:)] (gC/m2/s) C transfer rate from fire processes, updated in CNFireBaseMod or CNFireLi2014Mod
+ matrix_phturnover => cnveg_carbonflux_inst%matrix_phturnover_patch , & ! Output: [real(r8) (:,:)] (gC/m2/step) C turnover rate from phenology processes, updated in CNVegMatrixMod and dynHarvestMod
+ matrix_gmturnover => cnveg_carbonflux_inst%matrix_gmturnover_patch , & ! Output: [real(r8) (:,:)] (gC/m2/step) C turnover rate from gap mortality processe, updated in CNVegMatrixMods
+ matrix_fiturnover => cnveg_carbonflux_inst%matrix_fiturnover_patch , & ! Output: [real(r8) (:,:)] (gC/m2/step) C turnover rate from fire processe, updated in CNVegMatrixMods
+
+ matrix_nphtransfer => cnveg_nitrogenflux_inst%matrix_nphtransfer_patch , & ! Input: [real(r8) (:,:)] (gN/m2/s) N transfer rate from phenology processes, updated in CNPhenology and (NutrientCompetitionFlexibleCNMod or NutrientCompetitionCLM45defaultMod)
+ matrix_ngmtransfer => cnveg_nitrogenflux_inst%matrix_ngmtransfer_patch , & ! Input: [real(r8) (:,:)] (gN/m2/s) N transfer rate from gap mortality processes, updated in CNGapMortality and dynHarvestMod
+ matrix_nfitransfer => cnveg_nitrogenflux_inst%matrix_nfitransfer_patch , & ! Input: [real(r8) (:,:)] (gN/m2/s) N transfer rate from fire processes, updated in CNFireBaseMod or CNFireLi2014Mod
+ matrix_nphturnover => cnveg_nitrogenflux_inst%matrix_nphturnover_patch , & ! Output: [real(r8) (:,:)] (gN/m2/step) N turnover rate from phenology processes, updated in CNVegMatrixMod
+ matrix_ngmturnover => cnveg_nitrogenflux_inst%matrix_ngmturnover_patch , & ! Output: [real(r8) (:,:)] (gN/m2/step) N turnover rate from gap mortality processes, updated in CNVegMatrixMod
+ matrix_nfiturnover => cnveg_nitrogenflux_inst%matrix_nfiturnover_patch , & ! Output: [real(r8) (:,:)] (gN/m2/step) N turnover rate from fire processes, updated in CNVegMatrixMod
+
+ matrix_Cinput => cnveg_carbonflux_inst%matrix_Cinput_patch , & ! Input: [real(r8) (:)] (gC/m2/s) C input to vegetation, updated in NutrientCompetitionFlexibleCNMod or NutrientCompetitionCLM45defaultMod
+ matrix_C13input => cnveg_carbonflux_inst%matrix_C13input_patch , & ! Input: [real(r8) (:)] (gC/m2/s) C13 input to vegetation, updated in NutrientCompetitionFlexibleCNMod or NutrientCompetitionCLM45defaultMod
+ matrix_C14input => cnveg_carbonflux_inst%matrix_C14input_patch , & ! Input: [real(r8) (:)] (gC/m2/s) C14 input to vegetation, updated in NutrientCompetitionFlexibleCNMod or NutrientCompetitionCLM45defaultMod
+ matrix_Ninput => cnveg_nitrogenflux_inst%matrix_Ninput_patch , & ! Input: [real(r8) (:)] (gN/m2/s) N input to vegetation, updated in NutrientCompetitionFlexibleCNMod or NutrientCompetitionCLM45defaultMod
+
+ ! Doners and receivers of all transfers from different processes have been prescribed in following variables:
+ doner_phc => cnveg_carbonflux_inst%matrix_phtransfer_doner_patch , & ! Input: [integer (:)] Doners of phenology related C transfer
+ receiver_phc => cnveg_carbonflux_inst%matrix_phtransfer_receiver_patch , & ! Input: [integer (:)] Receiver of phenology related C transfer
+ doner_gmc => cnveg_carbonflux_inst%matrix_gmtransfer_doner_patch , & ! Input: [integer (:)] Doners of gap mortality related C transfer
+ receiver_gmc => cnveg_carbonflux_inst%matrix_gmtransfer_receiver_patch , & ! Input: [integer (:)] Receiver of gap mortality related C transfer
+ doner_fic => cnveg_carbonflux_inst%matrix_fitransfer_doner_patch , & ! Input: [integer (:)] Doners of fire related C transfer
+ receiver_fic => cnveg_carbonflux_inst%matrix_fitransfer_receiver_patch , & ! Input: [integer (:)] Receiver of fire related C transfer
+ doner_phn => cnveg_nitrogenflux_inst%matrix_nphtransfer_doner_patch , & ! Input: [integer (:)] Doners of phenology related N transfer
+ receiver_phn => cnveg_nitrogenflux_inst%matrix_nphtransfer_receiver_patch , & ! Input: [integer (:)] Receiver of phenology related N transfer
+ doner_gmn => cnveg_nitrogenflux_inst%matrix_ngmtransfer_doner_patch , & ! Input: [integer (:)] Doners of gap mortality related N transfer
+ receiver_gmn => cnveg_nitrogenflux_inst%matrix_ngmtransfer_receiver_patch , & ! Input: [integer (:)] Receiver of gap mortality related N transfer
+ doner_fin => cnveg_nitrogenflux_inst%matrix_nfitransfer_doner_patch , & ! Input: [integer (:)] Doners of fire related N transfer
+ receiver_fin => cnveg_nitrogenflux_inst%matrix_nfitransfer_receiver_patch , & ! Input: [integer (:)] Receiver of fire related N transfer
+
+ ! Index of each processes related C transfers. See subroutine InitTransfer in CNVegCarbonFluxType.F90 for details.
+ ileafst_to_ileafxf_phc => cnveg_carbonflux_inst%ileafst_to_ileafxf_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phc => cnveg_carbonflux_inst%ileafxf_to_ileaf_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phc => cnveg_carbonflux_inst%ifrootst_to_ifrootxf_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phc => cnveg_carbonflux_inst%ifrootxf_to_ifroot_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phc => cnveg_carbonflux_inst%ilivestemst_to_ilivestemxf_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phc => cnveg_carbonflux_inst%ilivestemxf_to_ilivestem_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phc => cnveg_carbonflux_inst%ideadstemst_to_ideadstemxf_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phc => cnveg_carbonflux_inst%ideadstemxf_to_ideadstem_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phc => cnveg_carbonflux_inst%ilivecrootst_to_ilivecrootxf_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phc => cnveg_carbonflux_inst%ilivecrootxf_to_ilivecroot_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phc => cnveg_carbonflux_inst%ideadcrootst_to_ideadcrootxf_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phc => cnveg_carbonflux_inst%ideadcrootxf_to_ideadcroot_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phc => cnveg_carbonflux_inst%ilivestem_to_ideadstem_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phc => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from live coarse root pool to dead coarse root pool
+ ileaf_to_iout_phc => cnveg_carbonflux_inst%ileaf_to_iout_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phc => cnveg_carbonflux_inst%ifroot_to_iout_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phc => cnveg_carbonflux_inst%ilivestem_to_iout_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ igrain_to_iout_phc => cnveg_carbonflux_inst%igrain_to_iout_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
+ ileaf_to_iout_gmc => cnveg_carbonflux_inst%ileaf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_gmc => cnveg_carbonflux_inst%ileafst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_gmc => cnveg_carbonflux_inst%ileafxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_gmc => cnveg_carbonflux_inst%ifroot_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_gmc => cnveg_carbonflux_inst%ifrootst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_gmc => cnveg_carbonflux_inst%ifrootxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from fine root transfer pool to outside of vegetation pools
+ ilivestem_to_iout_gmc => cnveg_carbonflux_inst%ilivestem_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_gmc => cnveg_carbonflux_inst%ilivestemst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from live stem storage pool to outside of vegetation pools
+ ilivestemxf_to_iout_gmc => cnveg_carbonflux_inst%ilivestemxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_gmc => cnveg_carbonflux_inst%ideadstem_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_gmc => cnveg_carbonflux_inst%ideadstemst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_gmc => cnveg_carbonflux_inst%ideadstemxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_gmc => cnveg_carbonflux_inst%ilivecroot_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_gmc => cnveg_carbonflux_inst%ilivecrootst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_gmc => cnveg_carbonflux_inst%ilivecrootxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_gmc => cnveg_carbonflux_inst%ideadcroot_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_gmc => cnveg_carbonflux_inst%ideadcrootst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_gmc => cnveg_carbonflux_inst%ideadcrootxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from dead coarse root transfer pool to outside of vegetation pools
+ ileaf_to_iout_fic => cnveg_carbonflux_inst%ileaf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_fic => cnveg_carbonflux_inst%ileafst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_fic => cnveg_carbonflux_inst%ileafxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_fic => cnveg_carbonflux_inst%ifroot_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_fic => cnveg_carbonflux_inst%ifrootst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_fic => cnveg_carbonflux_inst%ifrootxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from fine root transfer pool to outside of vegetation pools
+ ilivestem_to_iout_fic => cnveg_carbonflux_inst%ilivestem_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_fic => cnveg_carbonflux_inst%ilivestemst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from live stem storage pool to outside of vegetation pools
+ ilivestemxf_to_iout_fic => cnveg_carbonflux_inst%ilivestemxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_fic => cnveg_carbonflux_inst%ideadstem_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_fic => cnveg_carbonflux_inst%ideadstemst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_fic => cnveg_carbonflux_inst%ideadstemxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_fic => cnveg_carbonflux_inst%ilivecroot_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_fic => cnveg_carbonflux_inst%ilivecrootst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_fic => cnveg_carbonflux_inst%ilivecrootxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_fic => cnveg_carbonflux_inst%ideadcroot_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_fic => cnveg_carbonflux_inst%ideadcrootst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_fic => cnveg_carbonflux_inst%ideadcrootxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from dead coarse root transfer pool to outside of vegetation pools
+ ilivestem_to_ideadstem_fic => cnveg_carbonflux_inst%ilivestem_to_ideadstem_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_fic => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from live coarse root pool to dead coarse root pool
+ ! Index of each processes related N transfers. See subroutine InitTransfer in CNVegNitrogenFluxType.F90 for details.
+ ileafst_to_ileafxf_phn => cnveg_nitrogenflux_inst%ileafst_to_ileafxf_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phn => cnveg_nitrogenflux_inst%ileafxf_to_ileaf_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phn => cnveg_nitrogenflux_inst%ifrootst_to_ifrootxf_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phn => cnveg_nitrogenflux_inst%ifrootxf_to_ifroot_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phn => cnveg_nitrogenflux_inst%ilivestemst_to_ilivestemxf_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phn => cnveg_nitrogenflux_inst%ilivestemxf_to_ilivestem_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phn => cnveg_nitrogenflux_inst%ideadstemst_to_ideadstemxf_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phn => cnveg_nitrogenflux_inst%ideadstemxf_to_ideadstem_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phn => cnveg_nitrogenflux_inst%ilivecrootst_to_ilivecrootxf_ph, &
+ ! Input: [integer (:)] Index of phenology related N transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phn => cnveg_nitrogenflux_inst%ilivecrootxf_to_ilivecroot_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phn => cnveg_nitrogenflux_inst%ideadcrootst_to_ideadcrootxf_ph, &
+ ! Input: [integer (:)] Index of phenology related N transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ideadcrootxf_to_ideadcroot_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phn => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from live coarse root pool to dead coarse root pool
+ ileaf_to_iout_phn => cnveg_nitrogenflux_inst%ileaf_to_iout_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phn => cnveg_nitrogenflux_inst%ifroot_to_iout_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phn => cnveg_nitrogenflux_inst%ilivestem_to_iout_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from live stem pool to outside of vegetation pools
+ iretransn_to_iout_phn => cnveg_nitrogenflux_inst%iretransn_to_iout_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to outside of vegetation pools
+ igrain_to_iout_phn => cnveg_nitrogenflux_inst%igrain_to_iout_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from grain pool to outside of vegetation pools
+ ileaf_to_iretransn_phn => cnveg_nitrogenflux_inst%ileaf_to_iretransn_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from leaf pool to retranslocated N pool
+ ifroot_to_iretransn_phn => cnveg_nitrogenflux_inst%ifroot_to_iretransn_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from fine root pool to retranslocated N pool
+ ilivestem_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivestem_to_iretransn_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from live stem pool to retranslocated N pool
+ ilivecroot_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivecroot_to_iretransn_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from live coarse root pool to retranslocated N pool
+ iretransn_to_ileaf_phn => cnveg_nitrogenflux_inst%iretransn_to_ileaf_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to leaf pool
+ iretransn_to_ileafst_phn => cnveg_nitrogenflux_inst%iretransn_to_ileafst_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to leaf storage pool
+ iretransn_to_ifroot_phn => cnveg_nitrogenflux_inst%iretransn_to_ifroot_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to fine root pool
+ iretransn_to_ifrootst_phn => cnveg_nitrogenflux_inst%iretransn_to_ifrootst_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to fine root storage pool
+ iretransn_to_ilivestem_phn => cnveg_nitrogenflux_inst%iretransn_to_ilivestem_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to live stem pool
+ iretransn_to_ilivestemst_phn => cnveg_nitrogenflux_inst%iretransn_to_ilivestemst_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to live stem storage pool
+ iretransn_to_ideadstem_phn => cnveg_nitrogenflux_inst%iretransn_to_ideadstem_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to dead stem pool
+ iretransn_to_ideadstemst_phn => cnveg_nitrogenflux_inst%iretransn_to_ideadstemst_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to dead stem storage pool
+ iretransn_to_ilivecroot_phn => cnveg_nitrogenflux_inst%iretransn_to_ilivecroot_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to live coarse root pool
+ iretransn_to_ilivecrootst_phn => cnveg_nitrogenflux_inst%iretransn_to_ilivecrootst_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to live coarse root storage pool
+ iretransn_to_ideadcroot_phn => cnveg_nitrogenflux_inst%iretransn_to_ideadcroot_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to dead coarse root pool
+ iretransn_to_ideadcrootst_phn => cnveg_nitrogenflux_inst%iretransn_to_ideadcrootst_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to dead coarse root storage pool
+ iretransn_to_igrain_phn => cnveg_nitrogenflux_inst%iretransn_to_igrain_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to grain pool
+ iretransn_to_igrainst_phn => cnveg_nitrogenflux_inst%iretransn_to_igrainst_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to grain storage pool
+ ileaf_to_iout_gmn => cnveg_nitrogenflux_inst%ileaf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_gmn => cnveg_nitrogenflux_inst%ileafst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_gmn => cnveg_nitrogenflux_inst%ileafxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_gmn => cnveg_nitrogenflux_inst%ifroot_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ifrootst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ifrootxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from fine root transfer pool to outside of vegetation pools
+ ilivestem_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestem_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestemst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from live stem storage pool to outside of vegetation pools
+ ilivestemxf_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestemxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstem_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstemst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstemxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecroot_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecrootst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecrootxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcroot_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcrootst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcrootxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from dead coarse root transfer pool to outside of vegetation pools
+ iretransn_to_iout_gmn => cnveg_nitrogenflux_inst%iretransn_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from retranslocated N pool to outside of vegetation pools
+ ileaf_to_iout_fin => cnveg_nitrogenflux_inst%ileaf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_fin => cnveg_nitrogenflux_inst%ileafst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_fin => cnveg_nitrogenflux_inst%ileafxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_fin => cnveg_nitrogenflux_inst%ifroot_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_fin => cnveg_nitrogenflux_inst%ifrootst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_fin => cnveg_nitrogenflux_inst%ifrootxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from fine transfer pool to outside of vegetation pools
+ ilivestem_to_iout_fin => cnveg_nitrogenflux_inst%ilivestem_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_fin => cnveg_nitrogenflux_inst%ilivestemst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from live stem storage pool to outside of vegetation pools
+ ilivestemxf_to_iout_fin => cnveg_nitrogenflux_inst%ilivestemxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_fin => cnveg_nitrogenflux_inst%ideadstem_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_fin => cnveg_nitrogenflux_inst%ideadstemst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_fin => cnveg_nitrogenflux_inst%ideadstemxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_fin => cnveg_nitrogenflux_inst%ilivecroot_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_fin => cnveg_nitrogenflux_inst%ilivecrootst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_fin => cnveg_nitrogenflux_inst%ilivecrootxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_fin => cnveg_nitrogenflux_inst%ideadcroot_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_fin => cnveg_nitrogenflux_inst%ideadcrootst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_fin => cnveg_nitrogenflux_inst%ideadcrootxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from dead coarse root transfer pool to outside of vegetation pools
+ ilivestem_to_ideadstem_fin => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from live stem to dead stem pool
+ ilivecroot_to_ideadcroot_fin => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from live coarse root pool to dead coarse root pool
+ iretransn_to_iout_fin => cnveg_nitrogenflux_inst%iretransn_to_iout_fi &
+ ! Input: [integer (:)] Index of fire related N transfer from retranslocated N pool to outside of vegetation pools
+ )
+td: associate( &
+
+ ! Sparse matrix type of A*K
+ AKphvegc => cnveg_carbonflux_inst%AKphvegc , & ! Aph*Kph for C cycle in sparse matrix format
+ AKgmvegc => cnveg_carbonflux_inst%AKgmvegc , & ! Agm*Kgm for C cycle in sparse matrix format
+ AKfivegc => cnveg_carbonflux_inst%AKfivegc , & ! Afi*Kfi for C cycle in sparse matrix format
+ AKallvegc => cnveg_carbonflux_inst%AKallvegc , & ! Aph*Kph + Agm*Kgm + Afi*Kfi for C cycle in sparse matrix format
+ NE_AKallvegc => cnveg_carbonflux_inst%NE_AKallvegc , & ! Number of entries in AKallvegc
+ RI_AKallvegc => cnveg_carbonflux_inst%RI_AKallvegc , & ! Row indices in Akallvegc
+ CI_AKallvegc => cnveg_carbonflux_inst%CI_AKallvegc , & ! Column indices in AKallvegc
+ Kvegc => cnveg_carbonflux_inst%Kvegc , & ! Temporary variable of Kph, Kgm or Kfi for C cycle in diagonal matrix format
+ Xvegc => cnveg_carbonflux_inst%Xvegc , & ! Vegetation C of each compartment in a vector format
+ AKphvegn => cnveg_nitrogenflux_inst%AKphvegn , & ! Aph*Kph for N cycle in sparse matrix format
+ AKgmvegn => cnveg_nitrogenflux_inst%AKgmvegn , & ! Agm*Kgm for N cycle in sparse matrix format
+ AKfivegn => cnveg_nitrogenflux_inst%AKfivegn , & ! Afi*Kfi for N cycle in sparse matrix format
+ AKallvegn => cnveg_nitrogenflux_inst%AKallvegn , & ! Aph*Kph + Agm*Kgm + Afi*Kfi for N cycle in sparse matrix format
+ NE_AKallvegn => cnveg_nitrogenflux_inst%NE_AKallvegn , & ! Number of entries in AKallvegn
+ RI_AKallvegn => cnveg_nitrogenflux_inst%RI_AKallvegn , & ! Row indices in Akallvegn
+ CI_AKallvegn => cnveg_nitrogenflux_inst%CI_AKallvegn , & ! Column indices in AKallvegn
+ Kvegn => cnveg_nitrogenflux_inst%Kvegn , & ! Temporary variable of Kph, Kgm or Kfi for N cycle in diagonal matrix format
+ Xvegn => cnveg_nitrogenflux_inst%Xvegn , & ! Vegetation N of each compartment in a vector format
+ Xveg13c => cnveg_carbonflux_inst%Xveg13c , & ! Vegetation C13 of each compartment in a vector format
+ Xveg14c => cnveg_carbonflux_inst%Xveg14c , & ! Vegetation C14 of each compartment in a vector format
+
+ ! Row and column indices of A matrices
+ RI_phc => cnveg_carbonflux_inst%RI_phc , & ! Row indices of non-diagonal entires in Aph for C cycle
+ CI_phc => cnveg_carbonflux_inst%CI_phc , & ! Column indices of non-diagonal entries in Aph for C cycle
+ RI_gmc => cnveg_carbonflux_inst%RI_gmc , & ! Row indices of non-diagonal entires in Agm for C cycle
+ CI_gmc => cnveg_carbonflux_inst%CI_gmc , & ! Column indices of non-diagonal entries in Agm for C cycle
+ RI_fic => cnveg_carbonflux_inst%RI_fic , & ! Row indices of non-diagonal entires in Afi for C cycle
+ CI_fic => cnveg_carbonflux_inst%CI_fic , & ! Column indices of non-diagonal entries in Afi for C cycle
+ RI_phn => cnveg_nitrogenflux_inst%RI_phn , & ! Row indices of non-diagonal entires in Aph for N cycle
+ CI_phn => cnveg_nitrogenflux_inst%CI_phn , & ! Column indices of non-diagonal entries in Aph for N cycle
+ RI_gmn => cnveg_nitrogenflux_inst%RI_gmn , & ! Row indices of non-diagonal entires in Agm for N cycle
+ CI_gmn => cnveg_nitrogenflux_inst%CI_gmn , & ! Column indices of non-diagonal entries in Agm for N cycle
+ RI_fin => cnveg_nitrogenflux_inst%RI_fin , & ! Row indices of non-diagonal entires in Afi for N cycle
+ CI_fin => cnveg_nitrogenflux_inst%CI_fin , & ! Column indices of non-diagonal entries in Afi for N cycle
+
+ ! Following list contains indices of non-diagonal entries in full sparse matrix
+ list_aphc => cnveg_carbonflux_inst%list_aphc , & ! Indices of non-diagnoal entries in full sparse matrix Aph for C cycle
+ list_agmc => cnveg_carbonflux_inst%list_agmc , & ! Indices of non-diagnoal entries in full sparse matrix Agm for C cycle
+ list_afic => cnveg_carbonflux_inst%list_afic , & ! Indices of non-diagnoal entries in full sparse matrix Afi for C cycle
+ list_aphn => cnveg_nitrogenflux_inst%list_aphn , & ! Indices of non-diagnoal entries in full sparse matrix Aph for N cycle
+ list_agmn => cnveg_nitrogenflux_inst%list_agmn , & ! Indices of non-diagnoal entries in full sparse matrix Agm for N cycle
+ list_afin => cnveg_nitrogenflux_inst%list_afin , & ! Indices of non-diagnoal entries in full sparse matrix Afi for N cycle
+
+ ! For sparse matrix A, B and A + B, following list contains locations of entries in A or B or C mapped into matrix (A+B) or (A+B+C)
+ list_phc_phgm => cnveg_carbonflux_inst%list_phc_phgmc , & ! The locations of entries in AKphvegc mapped into (AKphvegc+AKgmvegc)
+ list_gmc_phgm => cnveg_carbonflux_inst%list_gmc_phgmc , & ! The locations of entries in AKgmvegc mapped into (AKphvegc+AKgmvegc)
+ list_phc_phgmfi => cnveg_carbonflux_inst%list_phc_phgmfic , & ! The locations of entries in AKphvegc mapped into (AKphvegc+AKgmvegc+AKfivegc)
+ list_gmc_phgmfi => cnveg_carbonflux_inst%list_gmc_phgmfic , & ! The locations of entries in AKgmvegc mapped into (AKphvegc+AKgmvegc+AKfivegc)
+ list_fic_phgmfi => cnveg_carbonflux_inst%list_fic_phgmfic , & ! The locations of entries in AKfivegc mapped into (AKphvegc+AKgmvegc+AKfivegc)
+ list_phn_phgm => cnveg_nitrogenflux_inst%list_phn_phgmn , & ! The locations of entries in AKphvegn mapped into (AKphvegn+AKgmvegn)
+ list_gmn_phgm => cnveg_nitrogenflux_inst%list_gmn_phgmn , & ! The locations of entries in AKgmvegn mapped into (AKphvegn+AKgmvegn)
+ list_phn_phgmfi => cnveg_nitrogenflux_inst%list_phn_phgmfin , & ! The locations of entries in AKphvegn mapped into (AKphvegn+AKgmvegn+AKfivegn)
+ list_gmn_phgmfi => cnveg_nitrogenflux_inst%list_gmn_phgmfin , & ! The locations of entries in AKgmvegn mapped into (AKphvegn+AKgmvegn+AKfivegn)
+ list_fin_phgmfi => cnveg_nitrogenflux_inst%list_fin_phgmfin & ! The locations of entries in AKfivegn mapped into (AKphvegn+AKgmvegn+AKfivegn)
+ )
+#ifdef _OPENMP
+ nthreads = OMP_GET_MAX_THREADS()
+#endif
+ !-----------------------------------------------------------------------
+ ! set time steps
+ call t_startf('CN veg matrix-init')
+ dt = real( get_step_size(), r8 )
+
+ ! Initialize local variables
+ call vegmatrixc_input%InitV(nvegcpool,bounds%begp,bounds%endp)
+ if(use_c13)then
+ call vegmatrixc13_input%InitV(nvegcpool,bounds%begp,bounds%endp)
+ end if
+ if(use_c14)then
+ call vegmatrixc14_input%InitV(nvegcpool,bounds%begp,bounds%endp)
+ end if
+ call vegmatrixn_input%InitV(nvegnpool,bounds%begp,bounds%endp)
+
+ matrix_calloc_acc (:) = 0._r8
+ matrix_nalloc_acc (:) = 0._r8
+ matrix_ctransfer_acc (:,:) = 0._r8
+ matrix_ntransfer_acc (:,:) = 0._r8
+ if(use_c13)then
+ matrix_c13alloc_acc (:) = 0._r8
+ matrix_c13transfer_acc (:,:) = 0._r8
+ end if
+ if(use_c14)then
+ matrix_c14alloc_acc (:) = 0._r8
+ matrix_c14transfer_acc (:,:) = 0._r8
+ end if
+
+ AKinvc (:,:) = 0._r8
+ AKinvn (:,:) = 0._r8
+
+ epsi = 1.e-30_r8 ! small number
+
+ call t_stopf('CN veg matrix-init')
+
+ call t_startf('CN veg matrix-assigning matrix')
+
+ ! Calculate A matrices from C transfers and C turnovers
+ if(ncphtrans .gt. ncphouttrans)then
+ do k=1,ncphtrans-ncphouttrans
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(matrix_phturnover(p,doner_phc(k)) .ne. 0)then
+ Aphconed(p,k) = matrix_phtransfer(p,k) * dt / matrix_phturnover(p,doner_phc(k))
+ else
+ Aphconed(p,k) = 0._r8
+ end if
+ end do
+ end do
+ end if
+
+ if(ncgmtrans .gt. ncgmouttrans)then
+ do k=1,ncgmtrans-ncgmouttrans
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(matrix_gmturnover(p,doner_gmc(k)) .ne. 0)then
+ Agmconed(p,k) = matrix_gmtransfer(p,k) * dt / matrix_gmturnover(p,doner_gmc(k))
+ else
+ Agmconed(p,k) = 0._r8
+ end if
+ end do
+ end do
+ end if
+
+ if(ncfitrans .gt. ncfiouttrans)then
+ do k=1,ncfitrans-ncfiouttrans
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(matrix_fiturnover(p,doner_fic(k)) .ne. 0)then
+ Aficoned(p,k) = matrix_fitransfer(p,k) * dt / matrix_fiturnover(p,doner_fic(k))
+ else
+ Aficoned(p,k) = 0._r8
+ end if
+ if(use_c14)then
+ associate( &
+ matrix_c14fitransfer => c14_cnveg_carbonflux_inst%matrix_fitransfer_patch , & ! Input: [real(r8) (:,:)] (gC/m2/s) C transfer rate from fire processes, updated in (CNFireBaseMod or CNFireLi2014Mod) and CNC14decayMod
+ matrix_c14fiturnover => c14_cnveg_carbonflux_inst%matrix_fiturnover_patch & ! Output: [real(r8) (:,:)] (gC/m2/step) C turnover rate from fire processe, updated in CNVegMatrixMods
+ )
+ if(matrix_c14fiturnover(p,doner_fic(k)) .ne. 0)then
+ Afic14oned(p,k) = matrix_c14fitransfer(p,k) * dt / matrix_c14fiturnover(p,doner_fic(k))
+ else
+ Afic14oned(p,k) = 0._r8
+ end if
+ end associate
+ end if
+ end do
+ end do
+ end if
+
+ if(nnphtrans .gt. nnphouttrans)then
+ do k=1,nnphtrans-nnphouttrans
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(matrix_nphturnover(p,doner_phn(k)) .ne. 0)then
+ Aphnoned(p,k) = matrix_nphtransfer(p,k) * dt / matrix_nphturnover(p,doner_phn(k))
+ else
+ Aphnoned(p,k) = 0._r8
+ end if
+ end do
+ end do
+ end if
+
+ if(nngmtrans .gt. nngmouttrans)then
+ do k=1,nngmtrans-nngmouttrans
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(matrix_ngmturnover(p,doner_phn(k)) .ne. 0)then
+ Agmnoned(p,k) = matrix_ngmtransfer(p,k) * dt / matrix_ngmturnover(p,doner_phn(k))
+ else
+ Agmnoned(p,k) = 0._r8
+ end if
+ end do
+ end do
+ end if
+
+ if(nnfitrans .gt. nnfiouttrans)then
+ do k=1,nnfitrans-nnfiouttrans
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(matrix_nfiturnover(p,doner_fin(k)) .ne. 0)then
+ Afinoned(p,k) = matrix_nfitransfer(p,k) * dt / matrix_nfiturnover(p,doner_fin(k))
+ else
+ Afinoned(p,k) = 0._r8
+ end if
+ end do
+ end do
+ end if
+
+ call t_stopf('CN veg matrix-assigning matrix')
+
+ ! Assign old state variables to vector Xveg*
+ call t_startf('CN veg matrix-set old value')
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ Xvegc%V(p,ileaf) = leafc(p)
+ Xvegc%V(p,ileaf_st) = leafc_storage(p)
+ Xvegc%V(p,ileaf_xf) = leafc_xfer(p)
+ Xvegc%V(p,ifroot) = frootc(p)
+ Xvegc%V(p,ifroot_st) = frootc_storage(p)
+ Xvegc%V(p,ifroot_xf) = frootc_xfer(p)
+ Xvegc%V(p,ilivestem) = livestemc(p)
+ Xvegc%V(p,ilivestem_st) = livestemc_storage(p)
+ Xvegc%V(p,ilivestem_xf) = livestemc_xfer(p)
+ Xvegc%V(p,ideadstem) = deadstemc(p)
+ Xvegc%V(p,ideadstem_st) = deadstemc_storage(p)
+ Xvegc%V(p,ideadstem_xf) = deadstemc_xfer(p)
+ Xvegc%V(p,ilivecroot) = livecrootc(p)
+ Xvegc%V(p,ilivecroot_st) = livecrootc_storage(p)
+ Xvegc%V(p,ilivecroot_xf) = livecrootc_xfer(p)
+ Xvegc%V(p,ideadcroot) = deadcrootc(p)
+ Xvegc%V(p,ideadcroot_st) = deadcrootc_storage(p)
+ Xvegc%V(p,ideadcroot_xf) = deadcrootc_xfer(p)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ ! Use one index of the grain reproductive pools to operate on
+ Xvegc%V(p,igrain) = reproductivec(p,irepr)
+ Xvegc%V(p,igrain_st) = reproductivec_storage(p,irepr)
+ Xvegc%V(p,igrain_xf) = reproductivec_xfer(p,irepr)
+ end if
+ end do
+
+ if ( use_c13 )then
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ Xveg13c%V(p,ileaf) = cs13_veg%leafc_patch(p)
+ Xveg13c%V(p,ileaf_st) = cs13_veg%leafc_storage_patch(p)
+ Xveg13c%V(p,ileaf_xf) = cs13_veg%leafc_xfer_patch(p)
+ Xveg13c%V(p,ifroot) = cs13_veg%frootc_patch(p)
+ Xveg13c%V(p,ifroot_st) = cs13_veg%frootc_storage_patch(p)
+ Xveg13c%V(p,ifroot_xf) = cs13_veg%frootc_xfer_patch(p)
+ Xveg13c%V(p,ilivestem) = cs13_veg%livestemc_patch(p)
+ Xveg13c%V(p,ilivestem_st) = cs13_veg%livestemc_storage_patch(p)
+ Xveg13c%V(p,ilivestem_xf) = cs13_veg%livestemc_xfer_patch(p)
+ Xveg13c%V(p,ideadstem) = cs13_veg%deadstemc_patch(p)
+ Xveg13c%V(p,ideadstem_st) = cs13_veg%deadstemc_storage_patch(p)
+ Xveg13c%V(p,ideadstem_xf) = cs13_veg%deadstemc_xfer_patch(p)
+ Xveg13c%V(p,ilivecroot) = cs13_veg%livecrootc_patch(p)
+ Xveg13c%V(p,ilivecroot_st) = cs13_veg%livecrootc_storage_patch(p)
+ Xveg13c%V(p,ilivecroot_xf) = cs13_veg%livecrootc_xfer_patch(p)
+ Xveg13c%V(p,ideadcroot) = cs13_veg%deadcrootc_patch(p)
+ Xveg13c%V(p,ideadcroot_st) = cs13_veg%deadcrootc_storage_patch(p)
+ Xveg13c%V(p,ideadcroot_xf) = cs13_veg%deadcrootc_xfer_patch(p)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ ! Use one index of the grain reproductive pools to operate on
+ Xveg13c%V(p,igrain) = cs13_veg%reproductivec_patch(p,irepr)
+ Xveg13c%V(p,igrain_st) = cs13_veg%reproductivec_storage_patch(p,irepr)
+ Xveg13c%V(p,igrain_xf) = cs13_veg%reproductivec_xfer_patch(p,irepr)
+ end if
+ end do
+ end if
+
+ if ( use_c14 )then
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ Xveg14c%V(p,ileaf) = cs14_veg%leafc_patch(p)
+ Xveg14c%V(p,ileaf_st) = cs14_veg%leafc_storage_patch(p)
+ Xveg14c%V(p,ileaf_xf) = cs14_veg%leafc_xfer_patch(p)
+ Xveg14c%V(p,ifroot) = cs14_veg%frootc_patch(p)
+ Xveg14c%V(p,ifroot_st) = cs14_veg%frootc_storage_patch(p)
+ Xveg14c%V(p,ifroot_xf) = cs14_veg%frootc_xfer_patch(p)
+ Xveg14c%V(p,ilivestem) = cs14_veg%livestemc_patch(p)
+ Xveg14c%V(p,ilivestem_st) = cs14_veg%livestemc_storage_patch(p)
+ Xveg14c%V(p,ilivestem_xf) = cs14_veg%livestemc_xfer_patch(p)
+ Xveg14c%V(p,ideadstem) = cs14_veg%deadstemc_patch(p)
+ Xveg14c%V(p,ideadstem_st) = cs14_veg%deadstemc_storage_patch(p)
+ Xveg14c%V(p,ideadstem_xf) = cs14_veg%deadstemc_xfer_patch(p)
+ Xveg14c%V(p,ilivecroot) = cs14_veg%livecrootc_patch(p)
+ Xveg14c%V(p,ilivecroot_st) = cs14_veg%livecrootc_storage_patch(p)
+ Xveg14c%V(p,ilivecroot_xf) = cs14_veg%livecrootc_xfer_patch(p)
+ Xveg14c%V(p,ideadcroot) = cs14_veg%deadcrootc_patch(p)
+ Xveg14c%V(p,ideadcroot_st) = cs14_veg%deadcrootc_storage_patch(p)
+ Xveg14c%V(p,ideadcroot_xf) = cs14_veg%deadcrootc_xfer_patch(p)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ ! Use one index of the grain reproductive pools to operate on
+ Xveg14c%V(p,igrain) = cs14_veg%reproductivec_patch(p,irepr)
+ Xveg14c%V(p,igrain_st) = cs14_veg%reproductivec_storage_patch(p,irepr)
+ Xveg14c%V(p,igrain_xf) = cs14_veg%reproductivec_xfer_patch(p,irepr)
+ end if
+ end do
+ end if
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ Xvegn%V(p,ileaf) = leafn(p)
+ Xvegn%V(p,ileaf_st) = leafn_storage(p)
+ Xvegn%V(p,ileaf_xf) = leafn_xfer(p)
+ Xvegn%V(p,ifroot) = frootn(p)
+ Xvegn%V(p,ifroot_st) = frootn_storage(p)
+ Xvegn%V(p,ifroot_xf) = frootn_xfer(p)
+ Xvegn%V(p,ilivestem) = livestemn(p)
+ Xvegn%V(p,ilivestem_st) = livestemn_storage(p)
+ Xvegn%V(p,ilivestem_xf) = livestemn_xfer(p)
+ Xvegn%V(p,ideadstem) = deadstemn(p)
+ Xvegn%V(p,ideadstem_st) = deadstemn_storage(p)
+ Xvegn%V(p,ideadstem_xf) = deadstemn_xfer(p)
+ Xvegn%V(p,ilivecroot) = livecrootn(p)
+ Xvegn%V(p,ilivecroot_st) = livecrootn_storage(p)
+ Xvegn%V(p,ilivecroot_xf) = livecrootn_xfer(p)
+ Xvegn%V(p,ideadcroot) = deadcrootn(p)
+ Xvegn%V(p,ideadcroot_st) = deadcrootn_storage(p)
+ Xvegn%V(p,ideadcroot_xf) = deadcrootn_xfer(p)
+ Xvegn%V(p,iretransn) = retransn(p)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ Xvegn%V(p,igrain) = sum(reproductiven(p,:))
+ Xvegn%V(p,igrain_st) = sum(reproductiven_storage(p,:))
+ Xvegn%V(p,igrain_xf) = sum(reproductiven_xfer(p,:))
+ end if
+ end do
+
+ ! Save *c0* and *n0* variables at begin of each year.
+ if (is_beg_curr_year())then
+ iyr = iyr + 1
+ if(mod(iyr-1,nyr_forcing) .eq. 0)then
+ iloop = iloop + 1
+ end if
+ if(.not. spinup_matrixcn .or. spinup_matrixcn .and. mod(iyr-1,nyr_SASU) .eq. 0)then
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ leafc0(p) = max(leafc(p), epsi)
+ leafc0_storage(p) = max(leafc_storage(p), epsi)
+ leafc0_xfer(p) = max(leafc_xfer(p), epsi)
+ frootc0(p) = max(frootc(p), epsi)
+ frootc0_storage(p) = max(frootc_storage(p), epsi)
+ frootc0_xfer(p) = max(frootc_xfer(p), epsi)
+ livestemc0(p) = max(livestemc(p), epsi)
+ livestemc0_storage(p) = max(livestemc_storage(p), epsi)
+ livestemc0_xfer(p) = max(livestemc_xfer(p), epsi)
+ deadstemc0(p) = max(deadstemc(p), epsi)
+ deadstemc0_storage(p) = max(deadstemc_storage(p), epsi)
+ deadstemc0_xfer(p) = max(deadstemc_xfer(p), epsi)
+ livecrootc0(p) = max(livecrootc(p), epsi)
+ livecrootc0_storage(p) = max(livecrootc_storage(p), epsi)
+ livecrootc0_xfer(p) = max(livecrootc_xfer(p), epsi)
+ deadcrootc0(p) = max(deadcrootc(p), epsi)
+ deadcrootc0_storage(p) = max(deadcrootc_storage(p), epsi)
+ deadcrootc0_xfer(p) = max(deadcrootc_xfer(p), epsi)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ ! Use one index of the grain reproductive pools to operate on
+ reproc0(p) = max(reproductivec(p,irepr), epsi)
+ reproc0_storage(p) = max(reproductivec_storage(p,irepr), epsi)
+ reproc0_xfer(p) = max(reproductivec_xfer(p,irepr), epsi)
+ end if
+ end do
+
+ if(use_c13)then
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ cs13_veg%leafc0_patch(p) = max(cs13_veg%leafc_patch(p), epsi)
+ cs13_veg%leafc0_storage_patch(p) = max(cs13_veg%leafc_storage_patch(p), epsi)
+ cs13_veg%leafc0_xfer_patch(p) = max(cs13_veg%leafc_xfer_patch(p), epsi)
+ cs13_veg%frootc0_patch(p) = max(cs13_veg%frootc_patch(p), epsi)
+ cs13_veg%frootc0_storage_patch(p) = max(cs13_veg%frootc_storage_patch(p), epsi)
+ cs13_veg%frootc0_xfer_patch(p) = max(cs13_veg%frootc_xfer_patch(p), epsi)
+ cs13_veg%livestemc0_patch(p) = max(cs13_veg%livestemc_patch(p), epsi)
+ cs13_veg%livestemc0_storage_patch(p) = max(cs13_veg%livestemc_storage_patch(p), epsi)
+ cs13_veg%livestemc0_xfer_patch(p) = max(cs13_veg%livestemc_xfer_patch(p), epsi)
+ cs13_veg%deadstemc0_patch(p) = max(cs13_veg%deadstemc_patch(p), epsi)
+ cs13_veg%deadstemc0_storage_patch(p) = max(cs13_veg%deadstemc_storage_patch(p), epsi)
+ cs13_veg%deadstemc0_xfer_patch(p) = max(cs13_veg%deadstemc_xfer_patch(p), epsi)
+ cs13_veg%livecrootc0_patch(p) = max(cs13_veg%livecrootc_patch(p), epsi)
+ cs13_veg%livecrootc0_storage_patch(p) = max(cs13_veg%livecrootc_storage_patch(p), epsi)
+ cs13_veg%livecrootc0_xfer_patch(p) = max(cs13_veg%livecrootc_xfer_patch(p), epsi)
+ cs13_veg%deadcrootc0_patch(p) = max(cs13_veg%deadcrootc_patch(p), epsi)
+ cs13_veg%deadcrootc0_storage_patch(p) = max(cs13_veg%deadcrootc_storage_patch(p), epsi)
+ cs13_veg%deadcrootc0_xfer_patch(p) = max(cs13_veg%deadcrootc_xfer_patch(p), epsi)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ ! Use one index of the grain reproductive pools to operate on
+ cs13_veg%reproc0_patch(p) = max(cs13_veg%reproductivec_patch(p,irepr), epsi)
+ cs13_veg%reproc0_storage_patch(p) = max(cs13_veg%reproductivec_storage_patch(p,irepr), epsi)
+ cs13_veg%reproc0_xfer_patch(p) = max(cs13_veg%reproductivec_xfer_patch(p,irepr), epsi)
+ end if
+ end do
+ end if
+
+ if(use_c14)then
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ cs14_veg%leafc0_patch(p) = max(cs14_veg%leafc_patch(p), epsi)
+ cs14_veg%leafc0_storage_patch(p) = max(cs14_veg%leafc_storage_patch(p), epsi)
+ cs14_veg%leafc0_xfer_patch(p) = max(cs14_veg%leafc_xfer_patch(p), epsi)
+ cs14_veg%frootc0_patch(p) = max(cs14_veg%frootc_patch(p), epsi)
+ cs14_veg%frootc0_storage_patch(p) = max(cs14_veg%frootc_storage_patch(p), epsi)
+ cs14_veg%frootc0_xfer_patch(p) = max(cs14_veg%frootc_xfer_patch(p), epsi)
+ cs14_veg%livestemc0_patch(p) = max(cs14_veg%livestemc_patch(p), epsi)
+ cs14_veg%livestemc0_storage_patch(p) = max(cs14_veg%livestemc_storage_patch(p), epsi)
+ cs14_veg%livestemc0_xfer_patch(p) = max(cs14_veg%livestemc_xfer_patch(p), epsi)
+ cs14_veg%deadstemc0_patch(p) = max(cs14_veg%deadstemc_patch(p), epsi)
+ cs14_veg%deadstemc0_storage_patch(p) = max(cs14_veg%deadstemc_storage_patch(p), epsi)
+ cs14_veg%deadstemc0_xfer_patch(p) = max(cs14_veg%deadstemc_xfer_patch(p), epsi)
+ cs14_veg%livecrootc0_patch(p) = max(cs14_veg%livecrootc_patch(p), epsi)
+ cs14_veg%livecrootc0_storage_patch(p) = max(cs14_veg%livecrootc_storage_patch(p), epsi)
+ cs14_veg%livecrootc0_xfer_patch(p) = max(cs14_veg%livecrootc_xfer_patch(p), epsi)
+ cs14_veg%deadcrootc0_patch(p) = max(cs14_veg%deadcrootc_patch(p), epsi)
+ cs14_veg%deadcrootc0_storage_patch(p) = max(cs14_veg%deadcrootc_storage_patch(p), epsi)
+ cs14_veg%deadcrootc0_xfer_patch(p) = max(cs14_veg%deadcrootc_xfer_patch(p), epsi)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ ! Use one index of the grain reproductive pools to operate on
+ cs14_veg%reproc0_patch(p) = max(cs14_veg%reproductivec_patch(p,irepr), epsi)
+ cs14_veg%reproc0_storage_patch(p) = max(cs14_veg%reproductivec_storage_patch(p,irepr), epsi)
+ cs14_veg%reproc0_xfer_patch(p) = max(cs14_veg%reproductivec_xfer_patch(p,irepr), epsi)
+ end if
+ end do
+ end if
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ leafn0(p) = max(leafn(p), epsi)
+ leafn0_storage(p) = max(leafn_storage(p), epsi)
+ leafn0_xfer(p) = max(leafn_xfer(p), epsi)
+ frootn0(p) = max(frootn(p), epsi)
+ frootn0_storage(p) = max(frootn_storage(p), epsi)
+ frootn0_xfer(p) = max(frootn_xfer(p), epsi)
+ livestemn0(p) = max(livestemn(p), epsi)
+ livestemn0_storage(p) = max(livestemn_storage(p), epsi)
+ livestemn0_xfer(p) = max(livestemn_xfer(p), epsi)
+ deadstemn0(p) = max(deadstemn(p), epsi)
+ deadstemn0_storage(p) = max(deadstemn_storage(p), epsi)
+ deadstemn0_xfer(p) = max(deadstemn_xfer(p), epsi)
+ livecrootn0(p) = max(livecrootn(p), epsi)
+ livecrootn0_storage(p) = max(livecrootn_storage(p), epsi)
+ livecrootn0_xfer(p) = max(livecrootn_xfer(p), epsi)
+ deadcrootn0(p) = max(deadcrootn(p), epsi)
+ deadcrootn0_storage(p) = max(deadcrootn_storage(p), epsi)
+ deadcrootn0_xfer(p) = max(deadcrootn_xfer(p), epsi)
+ retransn0(p) = max(retransn(p), epsi)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ ! Use one index of the grain reproductive pools to operate on
+ repron0(p) = max(reproductiven(p,irepr), epsi)
+ repron0_storage(p) = max(reproductiven_storage(p,irepr), epsi)
+ repron0_xfer(p) = max(reproductiven_xfer(p,irepr), epsi)
+ end if
+ end do
+ end if
+ end if
+
+ call t_stopf('CN veg matrix-set old value')
+
+ call t_startf('CN veg matrix-matrix multi.')
+
+ ! Start matrix operation
+ ! Calculate B*I
+
+ do i=1,nvegcpool
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ vegmatrixc_input%V(p,i) = matrix_alloc(p,i) * matrix_Cinput(p) * dt
+ end do
+ end do
+
+ ! Set up sparse matrix Aph_c from non-diagonal entires Aphconed, diagonal entries are all set to -1.
+ ! Note that AKphvegc here only represent A matrix instead of A * K
+
+ if(ncphtrans .gt. ncphouttrans)then
+ AI_phc = receiver_phc(1:ncphtrans-ncphouttrans)
+ AJ_phc = doner_phc (1:ncphtrans-ncphouttrans)
+ call AKphvegc%SetValueA(bounds%begp,bounds%endp,num_soilp,filter_soilp,Aphconed,&
+ AI_phc,AJ_phc,ncphtrans-ncphouttrans,init_ready_aphc,list_aphc,RI_phc,CI_phc)
+ else
+ call AKphvegc%SetValueA_diag(num_soilp,filter_soilp,-1._r8)
+ end if
+
+ ! Set up diagonal matrix Kph_c from diagonal entries matrix_phturnover
+ call Kvegc%SetValueDM(bounds%begp,bounds%endp,num_soilp,filter_soilp,matrix_phturnover(bounds%begp:bounds%endp,1:nvegcpool))
+
+ ! Calculate Aph_c*Kph_c using SPMM_AK.
+ call AKphvegc%SPMM_AK(num_soilp,filter_soilp,Kvegc)
+
+
+
+ ! Set up sparse matrix Agm_c from non-diagonal entires Agmconed, diagonal entries are all set to -1.
+ ! Note that AKgmvegc here only represent A matrix instead of A * K
+
+ if(ncgmtrans .gt. ncgmouttrans)then
+ AI_gmc = receiver_gmc(1:ncgmtrans-ncgmouttrans)
+ AJ_gmc = doner_gmc (1:ncgmtrans-ncgmouttrans)
+ call AKgmvegc%SetValueA(bounds%begp,bounds%endp,num_soilp,filter_soilp,Agmconed,&
+ AI_gmc,AJ_gmc,ncgmtrans-ncgmouttrans,init_ready_agmc,list_agmc,RI_gmc,CI_gmc)
+ else
+ call AKgmvegc%SetValueA_diag(num_soilp,filter_soilp,-1._r8)
+ end if
+
+ ! Set up diagonal matrix Kgm_c from diagonal entries matrix_gmturnover
+ call Kvegc%SetValueDM(bounds%begp,bounds%endp,num_soilp,filter_soilp,matrix_gmturnover(bounds%begp:bounds%endp,1:nvegcpool))
+
+ ! Calculate Agm_c*Kgm_c using SPMM_AK.
+ call AKgmvegc%SPMM_AK(num_soilp,filter_soilp,Kvegc)
+
+
+
+ ! Set up sparse matrix Afi_c from non-diagonal entires Aficoned, diagonal entries are all set to -1.
+ ! Note that AKfivegc here only represent A matrix instead of A * K
+
+ if(ncfitrans .gt. ncfiouttrans)then
+ AI_fic = receiver_fic(1:ncfitrans-ncfiouttrans)
+ AJ_fic = doner_fic (1:ncfitrans-ncfiouttrans)
+ call AKfivegc%SetValueA(bounds%begp,bounds%endp,num_soilp,filter_soilp,Aficoned,&
+ AI_fic,AJ_fic,ncfitrans-ncfiouttrans,init_ready_afic,list_afic,RI_fic,CI_fic)
+ if(use_c14)then
+ associate( &
+ AKfivegc14 => c14_cnveg_carbonflux_inst%AKfivegc , & ! Afi*Kfi for C14 cycle in sparse matrix format
+ RI_fic14 => c14_cnveg_carbonflux_inst%RI_fic , & ! Row indices of non-diagonal entires in Afi for C cycle
+ CI_fic14 => c14_cnveg_carbonflux_inst%CI_fic , & ! Column indices of non-diagonal entries in Afi for C cycle
+ list_afic14 => c14_cnveg_carbonflux_inst%list_afic & ! Indices of non-diagnoal entries in full sparse matrix Afi for C cycle
+ )
+ AI_fic14 = receiver_fic(1:ncfitrans-ncfiouttrans)
+ AJ_fic14 = doner_fic (1:ncfitrans-ncfiouttrans)
+ call AKfivegc14%SetValueA(bounds%begp,bounds%endp,num_soilp,filter_soilp,Afic14oned,&
+ AI_fic14,AJ_fic14,ncfitrans-ncfiouttrans,init_ready_afic14,list_afic14,RI_fic14,CI_fic14)
+ end associate
+ end if
+ else
+ call AKfivegc%SetValueA_diag(num_soilp,filter_soilp,-1._r8)
+ if(use_c14)then
+ associate( &
+ AKfivegc14 => c14_cnveg_carbonflux_inst%AKfivegc & ! Afi*Kfi for C14 cycle in sparse matrix format
+ )
+ call AKfivegc14%SetValueA_diag(num_soilp,filter_soilp,-1._r8)
+ end associate
+ end if
+ end if
+
+ ! Set up diagonal matrix Kfi_c from diagonal entries matrix_fiturnover
+ call Kvegc%SetValueDM(bounds%begp,bounds%endp,num_soilp,filter_soilp,matrix_fiturnover(bounds%begp:bounds%endp,1:nvegcpool))
+
+ ! Calculate Afi_c*Kfi_c using SPMM_AK.
+ call AKfivegc%SPMM_AK(num_soilp,filter_soilp,Kvegc)
+
+ if(use_c14)then
+ associate( &
+ AKfivegc14 => c14_cnveg_carbonflux_inst%AKfivegc , & ! Afi*Kfi for C14 cycle in sparse matrix format
+ matrix_c14fitransfer => c14_cnveg_carbonflux_inst%matrix_fitransfer_patch , & ! Input: [real(r8) (:,:)] (gC/m2/s) C transfer rate from fire processes, updated in (CNFireBaseMod or CNFireLi2014Mod) and CNC14decayMod
+ matrix_c14fiturnover => c14_cnveg_carbonflux_inst%matrix_fiturnover_patch & ! Output: [real(r8) (:,:)] (gC/m2/step) C turnover rate from fire processe, updated in CNVegMatrixMods
+ )
+ ! Set up diagonal matrix Kfi_c from diagonal entries matrix_fiturnover
+ call Kvegc%SetValueDM(bounds%begp,bounds%endp,num_soilp,filter_soilp,matrix_c14fiturnover(bounds%begp:bounds%endp,1:nvegcpool))
+
+ ! Calculate Afi_c*Kfi_c using SPMM_AK.
+ call AKfivegc14%SPMM_AK(num_soilp,filter_soilp,Kvegc)
+ end associate
+ end if
+
+ ! Caclulate AKallvegc = Aph_c*Kph_c + Agm_c*Kgm_c + Afi_c*Kfi_c
+ ! When no fire, Afi_c*Kfi_c = 0, AKallvegc = Aph_c*Kph_c + Agm_c*Kgm_c
+ ! When fire is on, AKallvegc = Aph_c*Kph_c + Agm_c*Kgm_c + Afi_c*Kfi_c
+
+ if(num_actfirep .eq. 0 .and. nthreads < 2)then
+ call AKallvegc%SPMP_AB(num_soilp,filter_soilp,AKphvegc,AKgmvegc,list_ready_phgmc,list_A=list_phc_phgm,list_B=list_gmc_phgm,&
+ NE_AB=NE_AKallvegc,RI_AB=RI_AKallvegc,CI_AB=CI_AKallvegc)
+ else
+ call AKallvegc%SPMP_ABC(num_soilp,filter_soilp,AKphvegc,AKgmvegc,AKfivegc,list_ready_phgmfic,list_A=list_phc_phgmfi,&
+ list_B=list_gmc_phgmfi,list_C=list_fic_phgmfi,NE_ABC=NE_AKallvegc,RI_ABC=RI_AKallvegc,CI_ABC=CI_AKallvegc,&
+ use_actunit_list_C=.True.,num_actunit_C=num_actfirep,filter_actunit_C=filter_actfirep)
+ end if
+
+ if(use_c14)then
+ associate( &
+ AKfivegc14 => c14_cnveg_carbonflux_inst%AKfivegc , & ! Afi*Kfi for C14 cycle in sparse matrix format
+ AKallvegc14 => c14_cnveg_carbonflux_inst%AKallvegc , & ! Aph*Kph + Agm*Kgm + Afi*Kfi for C14 cycle in sparse matrix format
+ NE_AKallvegc14 => c14_cnveg_carbonflux_inst%NE_AKallvegc , & ! Number of entries in AKallvegc
+ RI_AKallvegc14 => c14_cnveg_carbonflux_inst%RI_AKallvegc , & ! Row indices in Akallvegc
+ CI_AKallvegc14 => c14_cnveg_carbonflux_inst%CI_AKallvegc , & ! Column indices in AKallvegc
+ list_phc14_phgmfi => c14_cnveg_carbonflux_inst%list_phc_phgmfic , & ! The locations of entries in AKphvegc mapped into (AKphvegc+AKgmvegc+AKfivegc)
+ list_gmc14_phgmfi => c14_cnveg_carbonflux_inst%list_gmc_phgmfic , & ! The locations of entries in AKgmvegc mapped into (AKphvegc+AKgmvegc+AKfivegc)
+ list_fic14_phgmfi => c14_cnveg_carbonflux_inst%list_fic_phgmfic & ! The locations of entries in AKfivegc mapped into (AKphvegc+AKgmvegc+AKfivegc)
+ )
+ call AKallvegc14%SPMP_ABC(num_soilp,filter_soilp,AKphvegc,AKgmvegc,AKfivegc14,list_ready_phgmfic14,list_A=list_phc14_phgmfi,&
+ list_B=list_gmc14_phgmfi,list_C=list_fic14_phgmfi,NE_ABC=NE_AKallvegc14,RI_ABC=RI_AKallvegc14,CI_ABC=CI_AKallvegc14)
+ end associate
+ end if
+
+
+ ! Xvegc_n+1 = (Aph_c*Kph_c + Agm_c*Kgm_c + Afi_c*Kfi_c) * Xvegc_n + Xvegc_n
+ call Xvegc%SPMM_AX(num_soilp,filter_soilp,AKallvegc)
+
+ ! Xvegc_n+1 = (Aph_c*Kph_c + Agm_c*Kgm_c + Afi_c*Kfi_c) * Xvegc_n + Xvegc_n + B*I
+ do i = 1,nvegcpool
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ Xvegc%V(p,i) = Xvegc%V(p,i) + vegmatrixc_input%V(p,i)
+ end do
+ end do
+
+
+ if ( use_c13 ) then
+ ! Calculate B*I_C13
+ do i=1,nvegcpool
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ vegmatrixc13_input%V(p,i) = matrix_alloc(p,i) * matrix_C13input(p) * dt
+ end do
+ end do
+
+ ! Xveg13c_n+1 = (Aph_c*Kph_c + Agm_c*Kgm_c + Afi_c*Kfi_c) * Xveg13c_n + Xveg13c_n
+ call Xveg13c%SPMM_AX(num_soilp,filter_soilp,AKallvegc)
+
+ ! Xveg13c_n+1 = (Aph_c*Kph_c + Agm_c*Kgm_c + Afi_c*Kfi_c) * Xveg13c_n + Xveg13c_n + B*I_C13
+ do i=1,nvegcpool
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ Xveg13c%V(p,i) = Xveg13c%V(p,i) + vegmatrixc13_input%V(p,i)
+ end do
+ end do
+ end if
+
+
+ if ( use_c14 ) then
+ associate( &
+ matrix_C14input => cnveg_carbonflux_inst%matrix_C14input_patch, & ! Input: [real(r8) (:)] (gC/m2/s) C14 input to vegetation, updated in NutrientCompetitionFlexibleCNMod or NutrientCompetitionCLM45defaultMod
+ AKallvegc14 => c14_cnveg_carbonflux_inst%AKallvegc & ! Aph*Kph + Agm*Kgm + Afi*Kfi for C14 cycle in sparse matrix format
+ )
+ ! Calculate B*I_C14
+ do i=1,nvegcpool
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ vegmatrixc14_input%V(p,i) = matrix_alloc(p,i) * matrix_C14input(p) * dt
+ end do
+ end do
+
+ ! Xveg14c_n+1 = (Aph_c*Kph_c + Agm_c*Kgm_c + Afi_c*Kfi_c) * Xveg14c_n + Xveg14c_n
+ call Xveg14c%SPMM_AX(num_soilp,filter_soilp,AKallvegc14)
+
+ ! Xveg14c_n+1 = (Aph_c*Kph_c + Agm_c*Kgm_c + Afi_c*Kfi_c) * Xveg14c_n + Xveg14c_n + B*I_C14
+ do i=1,nvegcpool
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ Xveg14c%V(p,i) = Xveg14c%V(p,i) + vegmatrixc14_input%V(p,i)
+ end do
+ end do
+ end associate
+ end if
+
+
+
+ ! Calculate B_N*I_N
+ do i=1,nvegnpool
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ vegmatrixn_input%V(p,i) = matrix_nalloc(p,i) * matrix_Ninput(p) * dt
+ end do
+ end do
+
+
+ ! Set up sparse matrix Aph_n from non-diagonal entires Aficoned, diagonal entries are all set to -1.
+ ! Note that AKphvegn here only represent A matrix instead of A * K
+
+ if(nnphtrans .gt. nnphouttrans)then
+ AI_phn = receiver_phn(1:nnphtrans-nnphouttrans)
+ AJ_phn = doner_phn (1:nnphtrans-nnphouttrans)
+ call AKphvegn%SetValueA(bounds%begp,bounds%endp,num_soilp,filter_soilp,Aphnoned,&
+ AI_phn,AJ_phn,nnphtrans-nnphouttrans,init_ready_aphn,list_aphn,RI_phn,CI_phn)
+ else
+ call AKphvegn%SetValueA_diag(num_soilp,filter_soilp,-1._r8)
+ end if
+
+ ! Set up diagonal matrix Kph_n from diagonal entries matrix_nphturnover
+ call Kvegn%SetValueDM(bounds%begp,bounds%endp,num_soilp,filter_soilp,matrix_nphturnover(bounds%begp:bounds%endp,1:nvegnpool))
+
+ ! Calculate Aph_n*Kph_n using SPMM_AK.
+ call AKphvegn%SPMM_AK(num_soilp,filter_soilp,Kvegn)
+
+
+ ! Set up sparse matrix Agm_n from non-diagonal entires Aficoned, diagonal entries are all set to -1.
+ ! Note that AKgmvegn here only represent A matrix instead of A * K
+
+ if(nngmtrans .gt. nngmouttrans)then
+ AI_gmn = receiver_gmn(1:nngmtrans-nngmouttrans)
+ AJ_gmn = doner_gmn (1:nngmtrans-nngmouttrans)
+ call AKgmvegn%SetValueA(bounds%begp,bounds%endp,num_soilp,filter_soilp,Agmnoned,&
+ AI_gmn,AJ_gmn,nngmtrans-nngmouttrans,init_ready_agmn,list_agmn,RI_gmn,CI_gmn)
+ else
+ call AKgmvegn%SetValueA_diag(num_soilp,filter_soilp,-1._r8)
+ end if
+
+ ! Set up diagonal matrix Kgm_n from diagonal entries matrix_ngmturnover
+ call Kvegn%SetValueDM(bounds%begp,bounds%endp,num_soilp,filter_soilp,matrix_ngmturnover(bounds%begp:bounds%endp,1:nvegnpool))
+
+ ! Calculate Agm_n*Kgm_n using SPMM_AK.
+ call AKgmvegn%SPMM_AK(num_soilp,filter_soilp,Kvegn)
+
+
+ ! Set up sparse matrix Afi_n from non-diagonal entires Aficoned, diagonal entries are all set to -1.
+ ! Note that AKfivegn here only represent A matrix instead of A * K
+
+ if(nnfitrans .gt. nnfiouttrans)then
+ AI_fin = receiver_fin(1:nnfitrans-nnfiouttrans)
+ AJ_fin = doner_fin (1:nnfitrans-nnfiouttrans)
+ call AKfivegn%SetValueA(bounds%begp,bounds%endp,num_soilp,filter_soilp,Afinoned,&
+ AI_fin,AJ_fin,nnfitrans-nnfiouttrans,init_ready_afin,list_afin,RI_fin,CI_fin)
+ else
+ call AKfivegn%SetValueA_diag(num_soilp,filter_soilp,-1._r8)
+ end if
+
+ ! Set up diagonal matrix Kfi_n from diagonal entries matrix_nfiturnover
+ call Kvegn%SetValueDM(bounds%begp,bounds%endp,num_soilp,filter_soilp,matrix_nfiturnover(bounds%begp:bounds%endp,1:nvegnpool))
+
+ ! Calculate Afi_n*Kfi_n using SPMM_AK.
+ call AKfivegn%SPMM_AK(num_soilp,filter_soilp,Kvegn)
+
+
+ ! Caclulate AKallvegn = Aph_n*Kph_n + Agm_n*Kgm_n + Afi_n*Kfi_n
+ ! When no fire, Afi_n*Kfi_n = 0, AKallvegn = Aph_n*Kph_n + Agm_n*Kgm_n
+ ! When fire is on, AKallvegn = Aph_n*Kph_n + Agm_n*Kgm_n + Afi_n*Kfi_n
+
+ if(num_actfirep .eq. 0 .and. nthreads < 2)then
+ call AKallvegn%SPMP_AB(num_soilp,filter_soilp,AKphvegn,AKgmvegn,list_ready_phgmn,list_A=list_phn_phgm,list_B=list_gmn_phgm,&
+ NE_AB=NE_AKallvegn,RI_AB=RI_AKallvegn,CI_AB=CI_AKallvegn)
+ else
+ call AKallvegn%SPMP_ABC(num_soilp,filter_soilp,AKphvegn,AKgmvegn,AKfivegn,list_ready_phgmfin,list_A=list_phn_phgmfi,&
+ list_B=list_gmn_phgmfi,list_C=list_fin_phgmfi,NE_ABC=NE_AKallvegn,RI_ABC=RI_AKallvegn,CI_ABC=CI_AKallvegn,&
+ use_actunit_list_C=.True.,num_actunit_C=num_actfirep,filter_actunit_C=filter_actfirep)
+ end if
+
+ ! Xvegn_n+1 = (Aph_n*Kph_n + Agm_n*Kgm_n + Afi_n*Kfi_n) * Xvegc_n + Xvegc_n
+ call Xvegn%SPMM_AX(num_soilp,filter_soilp,AKallvegn)
+
+ ! Xvegn_n+1 = (Aph_n*Kph_n + Agm_n*Kgm_n + Afi_n*Kfi_n) * Xvegc_n + Xvegc_n + B_N*I_N
+ do i=1,nvegnpool
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ Xvegn%V(p,i) = Xvegn%V(p,i) + vegmatrixn_input%V(p,i)
+ end do
+ end do
+
+ call t_stopf('CN veg matrix-matrix multi.')
+
+
+ ! Accumulate transfers during the whole calendar year
+
+ call t_startf('CN veg matrix-accum. trans.')
+ if(spinup_matrixcn .or. hist_wrt_matrixcn_diag)then
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ matrix_calloc_leaf_acc(p) = matrix_calloc_leaf_acc(p) + vegmatrixc_input%V(p,ileaf)
+ matrix_calloc_leafst_acc(p) = matrix_calloc_leafst_acc(p) + vegmatrixc_input%V(p,ileaf_st)
+ matrix_calloc_froot_acc(p) = matrix_calloc_froot_acc(p) + vegmatrixc_input%V(p,ifroot)
+ matrix_calloc_frootst_acc(p) = matrix_calloc_frootst_acc(p) + vegmatrixc_input%V(p,ifroot_st)
+ matrix_calloc_livestem_acc(p) = matrix_calloc_livestem_acc(p) + vegmatrixc_input%V(p,ilivestem)
+ matrix_calloc_livestemst_acc(p) = matrix_calloc_livestemst_acc(p) + vegmatrixc_input%V(p,ilivestem_st)
+ matrix_calloc_deadstem_acc(p) = matrix_calloc_deadstem_acc(p) + vegmatrixc_input%V(p,ideadstem)
+ matrix_calloc_deadstemst_acc(p) = matrix_calloc_deadstemst_acc(p) + vegmatrixc_input%V(p,ideadstem_st)
+ matrix_calloc_livecroot_acc(p) = matrix_calloc_livecroot_acc(p) + vegmatrixc_input%V(p,ilivecroot)
+ matrix_calloc_livecrootst_acc(p) = matrix_calloc_livecrootst_acc(p) + vegmatrixc_input%V(p,ilivecroot_st)
+ matrix_calloc_deadcroot_acc(p) = matrix_calloc_deadcroot_acc(p) + vegmatrixc_input%V(p,ideadcroot)
+ matrix_calloc_deadcrootst_acc(p) = matrix_calloc_deadcrootst_acc(p) + vegmatrixc_input%V(p,ideadcroot_st)
+ if(use_c13)then
+ cs13_veg%matrix_calloc_leaf_acc_patch(p) = cs13_veg%matrix_calloc_leaf_acc_patch(p) + vegmatrixc13_input%V(p,ileaf)
+ cs13_veg%matrix_calloc_leafst_acc_patch(p) = cs13_veg%matrix_calloc_leafst_acc_patch(p) + vegmatrixc13_input%V(p,ileaf_st)
+ cs13_veg%matrix_calloc_froot_acc_patch(p) = cs13_veg%matrix_calloc_froot_acc_patch(p) + vegmatrixc13_input%V(p,ifroot)
+ cs13_veg%matrix_calloc_frootst_acc_patch(p) = cs13_veg%matrix_calloc_frootst_acc_patch(p) + vegmatrixc13_input%V(p,ifroot_st)
+ cs13_veg%matrix_calloc_livestem_acc_patch(p) = cs13_veg%matrix_calloc_livestem_acc_patch(p) + vegmatrixc13_input%V(p,ilivestem)
+ cs13_veg%matrix_calloc_livestemst_acc_patch(p) = cs13_veg%matrix_calloc_livestemst_acc_patch(p) + vegmatrixc13_input%V(p,ilivestem_st)
+ cs13_veg%matrix_calloc_deadstem_acc_patch(p) = cs13_veg%matrix_calloc_deadstem_acc_patch(p) + vegmatrixc13_input%V(p,ideadstem)
+ cs13_veg%matrix_calloc_deadstemst_acc_patch(p) = cs13_veg%matrix_calloc_deadstemst_acc_patch(p) + vegmatrixc13_input%V(p,ideadstem_st)
+ cs13_veg%matrix_calloc_livecroot_acc_patch(p) = cs13_veg%matrix_calloc_livecroot_acc_patch(p) + vegmatrixc13_input%V(p,ilivecroot)
+ cs13_veg%matrix_calloc_livecrootst_acc_patch(p) = cs13_veg%matrix_calloc_livecrootst_acc_patch(p) + vegmatrixc13_input%V(p,ilivecroot_st)
+ cs13_veg%matrix_calloc_deadcroot_acc_patch(p) = cs13_veg%matrix_calloc_deadcroot_acc_patch(p) + vegmatrixc13_input%V(p,ideadcroot)
+ cs13_veg%matrix_calloc_deadcrootst_acc_patch(p) = cs13_veg%matrix_calloc_deadcrootst_acc_patch(p) + vegmatrixc13_input%V(p,ideadcroot_st)
+ end if
+ if(use_c14)then
+ cs14_veg%matrix_calloc_leaf_acc_patch(p) = cs14_veg%matrix_calloc_leaf_acc_patch(p) + vegmatrixc14_input%V(p,ileaf)
+ cs14_veg%matrix_calloc_leafst_acc_patch(p) = cs14_veg%matrix_calloc_leafst_acc_patch(p) + vegmatrixc14_input%V(p,ileaf_st)
+ cs14_veg%matrix_calloc_froot_acc_patch(p) = cs14_veg%matrix_calloc_froot_acc_patch(p) + vegmatrixc14_input%V(p,ifroot)
+ cs14_veg%matrix_calloc_frootst_acc_patch(p) = cs14_veg%matrix_calloc_frootst_acc_patch(p) + vegmatrixc14_input%V(p,ifroot_st)
+ cs14_veg%matrix_calloc_livestem_acc_patch(p) = cs14_veg%matrix_calloc_livestem_acc_patch(p) + vegmatrixc14_input%V(p,ilivestem)
+ cs14_veg%matrix_calloc_livestemst_acc_patch(p) = cs14_veg%matrix_calloc_livestemst_acc_patch(p) + vegmatrixc14_input%V(p,ilivestem_st)
+ cs14_veg%matrix_calloc_deadstem_acc_patch(p) = cs14_veg%matrix_calloc_deadstem_acc_patch(p) + vegmatrixc14_input%V(p,ideadstem)
+ cs14_veg%matrix_calloc_deadstemst_acc_patch(p) = cs14_veg%matrix_calloc_deadstemst_acc_patch(p) + vegmatrixc14_input%V(p,ideadstem_st)
+ cs14_veg%matrix_calloc_livecroot_acc_patch(p) = cs14_veg%matrix_calloc_livecroot_acc_patch(p) + vegmatrixc14_input%V(p,ilivecroot)
+ cs14_veg%matrix_calloc_livecrootst_acc_patch(p) = cs14_veg%matrix_calloc_livecrootst_acc_patch(p) + vegmatrixc14_input%V(p,ilivecroot_st)
+ cs14_veg%matrix_calloc_deadcroot_acc_patch(p) = cs14_veg%matrix_calloc_deadcroot_acc_patch(p) + vegmatrixc14_input%V(p,ideadcroot)
+ cs14_veg%matrix_calloc_deadcrootst_acc_patch(p) = cs14_veg%matrix_calloc_deadcrootst_acc_patch(p) + vegmatrixc14_input%V(p,ideadcroot_st)
+ end if
+ end do
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ matrix_calloc_grain_acc(p) = matrix_calloc_grain_acc(p) + vegmatrixc_input%V(p,igrain)
+ matrix_calloc_grainst_acc(p) = matrix_calloc_grainst_acc(p) + vegmatrixc_input%V(p,igrain_st)
+ if(use_c13)then
+ cs13_veg%matrix_calloc_grain_acc_patch(p) = cs13_veg%matrix_calloc_grain_acc_patch(p) + vegmatrixc13_input%V(p,igrain)
+ cs13_veg%matrix_calloc_grainst_acc_patch(p) = cs13_veg%matrix_calloc_grainst_acc_patch(p) + vegmatrixc13_input%V(p,igrain_st)
+ end if
+ if(use_c14)then
+ cs14_veg%matrix_calloc_grain_acc_patch(p) = cs14_veg%matrix_calloc_grain_acc_patch(p) + vegmatrixc14_input%V(p,igrain)
+ cs14_veg%matrix_calloc_grainst_acc_patch(p) = cs14_veg%matrix_calloc_grainst_acc_patch(p) + vegmatrixc14_input%V(p,igrain_st)
+ end if
+ end if
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ matrix_ctransfer_leafst_to_leafxf_acc(p) = matrix_ctransfer_leafst_to_leafxf_acc(p) &
+ + matrix_phtransfer(p,ileafst_to_ileafxf_phc) &
+ * dt * leafc_storage(p) !matrix_phturnover(p,ileaf_st)*leafc_storage(p)
+ matrix_ctransfer_leafxf_to_leaf_acc(p) = matrix_ctransfer_leafxf_to_leaf_acc(p) &
+ + matrix_phtransfer(p,ileafxf_to_ileaf_phc) &
+ * dt * leafc_xfer(p)!matrix_phturnover(p,ileaf_xf)*leafc_xfer(p)
+ matrix_ctransfer_frootst_to_frootxf_acc(p) = matrix_ctransfer_frootst_to_frootxf_acc(p) &
+ + matrix_phtransfer(p,ifrootst_to_ifrootxf_phc) &
+ * dt * frootc_storage(p)!matrix_phturnover(p,ifroot_st)*frootc_storage(p)
+ matrix_ctransfer_frootxf_to_froot_acc(p) = matrix_ctransfer_frootxf_to_froot_acc(p) &
+ + matrix_phtransfer(p,ifrootxf_to_ifroot_phc) &
+ * dt * frootc_xfer(p)!matrix_phturnover(p,ifroot_xf)*frootc_xfer(p)
+ matrix_ctransfer_livestemst_to_livestemxf_acc(p) = matrix_ctransfer_livestemst_to_livestemxf_acc(p) &
+ + matrix_phtransfer(p,ilivestemst_to_ilivestemxf_phc) &
+ * dt * livestemc_storage(p)!matrix_phturnover(p,ilivestem_st)*livestemc_storage(p)
+ matrix_ctransfer_livestemxf_to_livestem_acc(p) = matrix_ctransfer_livestemxf_to_livestem_acc(p) &
+ + matrix_phtransfer(p,ilivestemxf_to_ilivestem_phc) &
+ * dt * livestemc_xfer(p)!matrix_phturnover(p,ilivestem_xf)*livestemc_xfer(p)
+ matrix_ctransfer_deadstemst_to_deadstemxf_acc(p) = matrix_ctransfer_deadstemst_to_deadstemxf_acc(p) &
+ + matrix_phtransfer(p,ideadstemst_to_ideadstemxf_phc) &
+ * dt * deadstemc_storage(p)!matrix_phturnover(p,ideadstem_st)*deadstemc_storage(p)
+ matrix_ctransfer_deadstemxf_to_deadstem_acc(p) = matrix_ctransfer_deadstemxf_to_deadstem_acc(p) &
+ + matrix_phtransfer(p,ideadstemxf_to_ideadstem_phc) &
+ * dt * deadstemc_xfer(p)!matrix_phturnover(p,ideadstem_xf)*deadstemc_xfer(p)
+ matrix_ctransfer_livecrootst_to_livecrootxf_acc(p) = matrix_ctransfer_livecrootst_to_livecrootxf_acc(p) &
+ + matrix_phtransfer(p,ilivecrootst_to_ilivecrootxf_phc) &
+ * dt * livecrootc_storage(p)!matrix_phturnover(p,ilivecroot_st)*livecrootc_storage(p)
+ matrix_ctransfer_livecrootxf_to_livecroot_acc(p) = matrix_ctransfer_livecrootxf_to_livecroot_acc(p) &
+ + matrix_phtransfer(p,ilivecrootxf_to_ilivecroot_phc) &
+ * dt * livecrootc_xfer(p)!matrix_phturnover(p,ilivecroot_xf)*livecrootc_xfer(p)
+ matrix_ctransfer_deadcrootst_to_deadcrootxf_acc(p) = matrix_ctransfer_deadcrootst_to_deadcrootxf_acc(p) &
+ + matrix_phtransfer(p,ideadcrootst_to_ideadcrootxf_phc) &
+ * dt * deadcrootc_storage(p)!matrix_phturnover(p,ideadcroot_st)*deadcrootc_storage(p)
+ matrix_ctransfer_deadcrootxf_to_deadcroot_acc(p) = matrix_ctransfer_deadcrootxf_to_deadcroot_acc(p) &
+ + matrix_phtransfer(p,ideadcrootxf_to_ideadcroot_phc) &
+ * dt * deadcrootc_xfer(p)!matrix_phturnover(p,ideadcroot_st)*deadcrootc_xfer(p)
+ matrix_ctransfer_livestem_to_deadstem_acc(p) = matrix_ctransfer_livestem_to_deadstem_acc(p) &
+ +(matrix_phtransfer(p,ilivestem_to_ideadstem_phc)&!matrix_phturnover(p,ilivestem) &
+ + matrix_fitransfer(p,ilivestem_to_ideadstem_fic))&!matrix_fiturnover(p,ilivestem))&
+ * dt * livestemc(p)
+ matrix_ctransfer_livecroot_to_deadcroot_acc(p) = matrix_ctransfer_livecroot_to_deadcroot_acc(p) &
+ +(matrix_phtransfer(p,ilivecroot_to_ideadcroot_phc)&!*matrix_phturnover(p,ilivecroot) &
+ + matrix_fitransfer(p,ilivecroot_to_ideadcroot_fic))&!*matrix_fiturnover(p,ilivecroot))&
+ * dt * livecrootc(p)
+ matrix_cturnover_leaf_acc(p) = matrix_cturnover_leaf_acc(p) &
+ + (matrix_phturnover(p,ileaf)+matrix_gmturnover(p,ileaf)+matrix_fiturnover(p,ileaf)) &
+ * leafc(p)
+ matrix_cturnover_leafst_acc(p) = matrix_cturnover_leafst_acc(p) &
+ + (matrix_phturnover(p,ileaf_st)+matrix_gmturnover(p,ileaf_st)+matrix_fiturnover(p,ileaf_st)) &
+ * leafc_storage(p)
+ matrix_cturnover_leafxf_acc(p) = matrix_cturnover_leafxf_acc(p) &
+ + (matrix_phturnover(p,ileaf_xf)+matrix_gmturnover(p,ileaf_xf)+matrix_fiturnover(p,ileaf_xf)) &
+ * leafc_xfer(p)
+ matrix_cturnover_froot_acc(p) = matrix_cturnover_froot_acc(p) &
+ + (matrix_phturnover(p,ifroot)+matrix_gmturnover(p,ifroot)+matrix_fiturnover(p,ifroot)) &
+ * frootc(p)
+ matrix_cturnover_frootst_acc(p) = matrix_cturnover_frootst_acc(p) &
+ + (matrix_phturnover(p,ifroot_st)+matrix_gmturnover(p,ifroot_st)+matrix_fiturnover(p,ifroot_st)) &
+ * frootc_storage(p)
+ matrix_cturnover_frootxf_acc(p) = matrix_cturnover_frootxf_acc(p) &
+ + (matrix_phturnover(p,ifroot_xf)+matrix_gmturnover(p,ifroot_xf)+matrix_fiturnover(p,ifroot_xf)) &
+ * frootc_xfer(p)
+ matrix_cturnover_livestem_acc(p) = matrix_cturnover_livestem_acc(p) &
+ + (matrix_phturnover(p,ilivestem)+matrix_gmturnover(p,ilivestem)+matrix_fiturnover(p,ilivestem)) &
+ * livestemc(p)
+ matrix_cturnover_livestemst_acc(p) = matrix_cturnover_livestemst_acc(p) &
+ + (matrix_phturnover(p,ilivestem_st)+matrix_gmturnover(p,ilivestem_st)+matrix_fiturnover(p,ilivestem_st)) &
+ * livestemc_storage(p)
+ matrix_cturnover_livestemxf_acc(p) = matrix_cturnover_livestemxf_acc(p) &
+ + (matrix_phturnover(p,ilivestem_xf)+matrix_gmturnover(p,ilivestem_xf)+matrix_fiturnover(p,ilivestem_xf)) &
+ * livestemc_xfer(p)
+ matrix_cturnover_deadstem_acc(p) = matrix_cturnover_deadstem_acc(p) &
+ + (matrix_phturnover(p,ideadstem)+matrix_gmturnover(p,ideadstem)+matrix_fiturnover(p,ideadstem)) &
+ * deadstemc(p)
+ matrix_cturnover_deadstemst_acc(p) = matrix_cturnover_deadstemst_acc(p) &
+ + (matrix_phturnover(p,ideadstem_st)+matrix_gmturnover(p,ideadstem_st)+matrix_fiturnover(p,ideadstem_st)) &
+ * deadstemc_storage(p)
+ matrix_cturnover_deadstemxf_acc(p) = matrix_cturnover_deadstemxf_acc(p) &
+ + (matrix_phturnover(p,ideadstem_xf)+matrix_gmturnover(p,ideadstem_xf)+matrix_fiturnover(p,ideadstem_xf)) &
+ * deadstemc_xfer(p)
+ matrix_cturnover_livecroot_acc(p) = matrix_cturnover_livecroot_acc(p) &
+ + (matrix_phturnover(p,ilivecroot)+matrix_gmturnover(p,ilivecroot)+matrix_fiturnover(p,ilivecroot)) &
+ * livecrootc(p)
+ matrix_cturnover_livecrootst_acc(p) = matrix_cturnover_livecrootst_acc(p) &
+ + (matrix_phturnover(p,ilivecroot_st)+matrix_gmturnover(p,ilivecroot_st)+matrix_fiturnover(p,ilivecroot_st)) &
+ * livecrootc_storage(p)
+ matrix_cturnover_livecrootxf_acc(p) = matrix_cturnover_livecrootxf_acc(p) &
+ + (matrix_phturnover(p,ilivecroot_xf)+matrix_gmturnover(p,ilivecroot_xf)+matrix_fiturnover(p,ilivecroot_xf)) &
+ * livecrootc_xfer(p)
+ matrix_cturnover_deadcroot_acc(p) = matrix_cturnover_deadcroot_acc(p) &
+ + (matrix_phturnover(p,ideadcroot)+matrix_gmturnover(p,ideadcroot)+matrix_fiturnover(p,ideadcroot)) &
+ * deadcrootc(p)
+ matrix_cturnover_deadcrootst_acc(p) = matrix_cturnover_deadcrootst_acc(p) &
+ + (matrix_phturnover(p,ideadcroot_st)+matrix_gmturnover(p,ideadcroot_st)+matrix_fiturnover(p,ideadcroot_st)) &
+ * deadcrootc_storage(p)
+ matrix_cturnover_deadcrootxf_acc(p) = matrix_cturnover_deadcrootxf_acc(p) &
+ + (matrix_phturnover(p,ideadcroot_xf)+matrix_gmturnover(p,ideadcroot_xf)+matrix_fiturnover(p,ideadcroot_xf)) &
+ * deadcrootc_xfer(p)
+ if(use_c13)then
+ cs13_veg%matrix_ctransfer_leafst_to_leafxf_acc_patch(p) = cs13_veg%matrix_ctransfer_leafst_to_leafxf_acc_patch(p) &
+ + matrix_phtransfer(p,ileafst_to_ileafxf_phc) &
+ * dt * cs13_veg%leafc_storage_patch(p) !matrix_phturnover(p,ileaf_st)*leafc_storage(p)
+ cs13_veg%matrix_ctransfer_leafxf_to_leaf_acc_patch(p) = cs13_veg%matrix_ctransfer_leafxf_to_leaf_acc_patch(p) &
+ + matrix_phtransfer(p,ileafxf_to_ileaf_phc) &
+ * dt * cs13_veg%leafc_xfer_patch(p)!matrix_phturnover(p,ileaf_xf)*leafc_xfer(p)
+ cs13_veg%matrix_ctransfer_frootst_to_frootxf_acc_patch(p) = cs13_veg%matrix_ctransfer_frootst_to_frootxf_acc_patch(p) &
+ + matrix_phtransfer(p,ifrootst_to_ifrootxf_phc) &
+ * dt * cs13_veg%frootc_storage_patch(p)!matrix_phturnover(p,ifroot_st)*frootc_storage(p)
+ cs13_veg%matrix_ctransfer_frootxf_to_froot_acc_patch(p) = cs13_veg%matrix_ctransfer_frootxf_to_froot_acc_patch(p) &
+ + matrix_phtransfer(p,ifrootxf_to_ifroot_phc) &
+ * dt * cs13_veg%frootc_xfer_patch(p)!matrix_phturnover(p,ifroot_xf)*frootc_xfer(p)
+ cs13_veg%matrix_ctransfer_livestemst_to_livestemxf_acc_patch(p) = cs13_veg%matrix_ctransfer_livestemst_to_livestemxf_acc_patch(p) &
+ + matrix_phtransfer(p,ilivestemst_to_ilivestemxf_phc) &
+ * dt * cs13_veg%livestemc_storage_patch(p)!matrix_phturnover(p,ilivestem_st)*livestemc_storage(p)
+ cs13_veg%matrix_ctransfer_livestemxf_to_livestem_acc_patch(p) = cs13_veg%matrix_ctransfer_livestemxf_to_livestem_acc_patch(p) &
+ + matrix_phtransfer(p,ilivestemxf_to_ilivestem_phc) &
+ * dt * cs13_veg%livestemc_xfer_patch(p)!matrix_phturnover(p,ilivestem_xf)*livestemc_xfer(p)
+ cs13_veg%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch(p) = cs13_veg%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch(p) &
+ + matrix_phtransfer(p,ideadstemst_to_ideadstemxf_phc) &
+ * dt * cs13_veg%deadstemc_storage_patch(p)!matrix_phturnover(p,ideadstem_st)*deadstemc_storage(p)
+ cs13_veg%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch(p) = cs13_veg%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch(p) &
+ + matrix_phtransfer(p,ideadstemxf_to_ideadstem_phc) &
+ * dt * cs13_veg%deadstemc_xfer_patch(p)!matrix_phturnover(p,ideadstem_xf)*deadstemc_xfer(p)
+ cs13_veg%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch(p) = cs13_veg%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch(p) &
+ + matrix_phtransfer(p,ilivecrootst_to_ilivecrootxf_phc) &
+ * dt * cs13_veg%livecrootc_storage_patch(p)!matrix_phturnover(p,ilivecroot_st)*livecrootc_storage(p)
+ cs13_veg%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch(p) = cs13_veg%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch(p) &
+ + matrix_phtransfer(p,ilivecrootxf_to_ilivecroot_phc) &
+ * dt * cs13_veg%livecrootc_xfer_patch(p)!matrix_phturnover(p,ilivecroot_xf)*livecrootc_xfer(p)
+ cs13_veg%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch(p) = cs13_veg%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch(p) &
+ + matrix_phtransfer(p,ideadcrootst_to_ideadcrootxf_phc) &
+ * dt * cs13_veg%deadcrootc_storage_patch(p)!matrix_phturnover(p,ideadcroot_st)*deadcrootc_storage(p)
+ cs13_veg%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch(p) = cs13_veg%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch(p) &
+ + matrix_phtransfer(p,ideadcrootxf_to_ideadcroot_phc) &
+ * dt * cs13_veg%deadcrootc_xfer_patch(p)!matrix_phturnover(p,ideadcroot_st)*deadcrootc_xfer(p)
+ cs13_veg%matrix_ctransfer_livestem_to_deadstem_acc_patch(p) = cs13_veg%matrix_ctransfer_livestem_to_deadstem_acc_patch(p) &
+ +(matrix_phtransfer(p,ilivestem_to_ideadstem_phc)&!matrix_phturnover(p,ilivestem) &
+ + matrix_fitransfer(p,ilivestem_to_ideadstem_fic))&!matrix_fiturnover(p,ilivestem))&
+ * dt * cs13_veg%livestemc_patch(p)
+ cs13_veg%matrix_ctransfer_livecroot_to_deadcroot_acc_patch(p) = cs13_veg%matrix_ctransfer_livecroot_to_deadcroot_acc_patch(p) &
+ +(matrix_phtransfer(p,ilivecroot_to_ideadcroot_phc)&!*matrix_phturnover(p,ilivecroot) &
+ + matrix_fitransfer(p,ilivecroot_to_ideadcroot_fic))&!*matrix_fiturnover(p,ilivecroot))&
+ * dt * cs13_veg%livecrootc_patch(p)
+ cs13_veg%matrix_cturnover_leaf_acc_patch(p) = cs13_veg%matrix_cturnover_leaf_acc_patch(p) &
+ + (matrix_phturnover(p,ileaf)+matrix_gmturnover(p,ileaf)+matrix_fiturnover(p,ileaf)) &
+ * cs13_veg%leafc_patch(p)
+ cs13_veg%matrix_cturnover_leafst_acc_patch(p) = cs13_veg%matrix_cturnover_leafst_acc_patch(p) &
+ + (matrix_phturnover(p,ileaf_st)+matrix_gmturnover(p,ileaf_st)+matrix_fiturnover(p,ileaf_st)) &
+ * cs13_veg%leafc_storage_patch(p)
+ cs13_veg%matrix_cturnover_leafxf_acc_patch(p) = cs13_veg%matrix_cturnover_leafxf_acc_patch(p) &
+ + (matrix_phturnover(p,ileaf_xf)+matrix_gmturnover(p,ileaf_xf)+matrix_fiturnover(p,ileaf_xf)) &
+ * cs13_veg%leafc_xfer_patch(p)
+ cs13_veg%matrix_cturnover_froot_acc_patch(p) = cs13_veg%matrix_cturnover_froot_acc_patch(p) &
+ + (matrix_phturnover(p,ifroot)+matrix_gmturnover(p,ifroot)+matrix_fiturnover(p,ifroot)) &
+ * cs13_veg%frootc_patch(p)
+ cs13_veg%matrix_cturnover_frootst_acc_patch(p) = cs13_veg%matrix_cturnover_frootst_acc_patch(p) &
+ + (matrix_phturnover(p,ifroot_st)+matrix_gmturnover(p,ifroot_st)+matrix_fiturnover(p,ifroot_st)) &
+ * cs13_veg%frootc_storage_patch(p)
+ cs13_veg%matrix_cturnover_frootxf_acc_patch(p) = cs13_veg%matrix_cturnover_frootxf_acc_patch(p) &
+ + (matrix_phturnover(p,ifroot_xf)+matrix_gmturnover(p,ifroot_xf)+matrix_fiturnover(p,ifroot_xf)) &
+ * cs13_veg%frootc_xfer_patch(p)
+ cs13_veg%matrix_cturnover_livestem_acc_patch(p) = cs13_veg%matrix_cturnover_livestem_acc_patch(p) &
+ + (matrix_phturnover(p,ilivestem)+matrix_gmturnover(p,ilivestem)+matrix_fiturnover(p,ilivestem)) &
+ * cs13_veg%livestemc_patch(p)
+ cs13_veg%matrix_cturnover_livestemst_acc_patch(p) = cs13_veg%matrix_cturnover_livestemst_acc_patch(p) &
+ + (matrix_phturnover(p,ilivestem_st)+matrix_gmturnover(p,ilivestem_st)+matrix_fiturnover(p,ilivestem_st)) &
+ * cs13_veg%livestemc_storage_patch(p)
+ cs13_veg%matrix_cturnover_livestemxf_acc_patch(p) = cs13_veg%matrix_cturnover_livestemxf_acc_patch(p) &
+ + (matrix_phturnover(p,ilivestem_xf)+matrix_gmturnover(p,ilivestem_xf)+matrix_fiturnover(p,ilivestem_xf)) &
+ * cs13_veg%livestemc_xfer_patch(p)
+ cs13_veg%matrix_cturnover_deadstem_acc_patch(p) = cs13_veg%matrix_cturnover_deadstem_acc_patch(p) &
+ + (matrix_phturnover(p,ideadstem)+matrix_gmturnover(p,ideadstem)+matrix_fiturnover(p,ideadstem)) &
+ * cs13_veg%deadstemc_patch(p)
+ cs13_veg%matrix_cturnover_deadstemst_acc_patch(p) = cs13_veg%matrix_cturnover_deadstemst_acc_patch(p) &
+ + (matrix_phturnover(p,ideadstem_st)+matrix_gmturnover(p,ideadstem_st)+matrix_fiturnover(p,ideadstem_st)) &
+ * cs13_veg%deadstemc_storage_patch(p)
+ cs13_veg%matrix_cturnover_deadstemxf_acc_patch(p) = cs13_veg%matrix_cturnover_deadstemxf_acc_patch(p) &
+ + (matrix_phturnover(p,ideadstem_xf)+matrix_gmturnover(p,ideadstem_xf)+matrix_fiturnover(p,ideadstem_xf)) &
+ * cs13_veg%deadstemc_xfer_patch(p)
+ cs13_veg%matrix_cturnover_livecroot_acc_patch(p) = cs13_veg%matrix_cturnover_livecroot_acc_patch(p) &
+ + (matrix_phturnover(p,ilivecroot)+matrix_gmturnover(p,ilivecroot)+matrix_fiturnover(p,ilivecroot)) &
+ * cs13_veg%livecrootc_patch(p)
+ cs13_veg%matrix_cturnover_livecrootst_acc_patch(p) = cs13_veg%matrix_cturnover_livecrootst_acc_patch(p) &
+ + (matrix_phturnover(p,ilivecroot_st)+matrix_gmturnover(p,ilivecroot_st)+matrix_fiturnover(p,ilivecroot_st)) &
+ * cs13_veg%livecrootc_storage_patch(p)
+ cs13_veg%matrix_cturnover_livecrootxf_acc_patch(p) = cs13_veg%matrix_cturnover_livecrootxf_acc_patch(p) &
+ + (matrix_phturnover(p,ilivecroot_xf)+matrix_gmturnover(p,ilivecroot_xf)+matrix_fiturnover(p,ilivecroot_xf)) &
+ * cs13_veg%livecrootc_xfer_patch(p)
+ cs13_veg%matrix_cturnover_deadcroot_acc_patch(p) = cs13_veg%matrix_cturnover_deadcroot_acc_patch(p) &
+ + (matrix_phturnover(p,ideadcroot)+matrix_gmturnover(p,ideadcroot)+matrix_fiturnover(p,ideadcroot)) &
+ * cs13_veg%deadcrootc_patch(p)
+ cs13_veg%matrix_cturnover_deadcrootst_acc_patch(p) = cs13_veg%matrix_cturnover_deadcrootst_acc_patch(p) &
+ + (matrix_phturnover(p,ideadcroot_st)+matrix_gmturnover(p,ideadcroot_st)+matrix_fiturnover(p,ideadcroot_st)) &
+ * cs13_veg%deadcrootc_storage_patch(p)
+ cs13_veg%matrix_cturnover_deadcrootxf_acc_patch(p) = cs13_veg%matrix_cturnover_deadcrootxf_acc_patch(p) &
+ + (matrix_phturnover(p,ideadcroot_xf)+matrix_gmturnover(p,ideadcroot_xf)+matrix_fiturnover(p,ideadcroot_xf)) &
+ * cs13_veg%deadcrootc_xfer_patch(p)
+ end if
+ if(use_c14)then
+ associate( &
+ matrix_c14fitransfer => c14_cnveg_carbonflux_inst%matrix_fitransfer_patch , & ! Input: [real(r8) (:,:)] (gC/m2/s) C transfer rate from fire processes, updated in (CNFireBaseMod or CNFireLi2014Mod) and CNC14decayMod
+ matrix_c14fiturnover => c14_cnveg_carbonflux_inst%matrix_fiturnover_patch & ! Output: [real(r8) (:,:)] (gC/m2/step) C turnover rate from fire processe, updated in CNVegMatrixMods
+ )
+ cs14_veg%matrix_ctransfer_leafst_to_leafxf_acc_patch(p) = cs14_veg%matrix_ctransfer_leafst_to_leafxf_acc_patch(p) &
+ + matrix_phtransfer(p,ileafst_to_ileafxf_phc) &
+ * dt * cs14_veg%leafc_storage_patch(p) !matrix_phturnover(p,ileaf_st)*leafc_storage(p)
+ cs14_veg%matrix_ctransfer_leafxf_to_leaf_acc_patch(p) = cs14_veg%matrix_ctransfer_leafxf_to_leaf_acc_patch(p) &
+ + matrix_phtransfer(p,ileafxf_to_ileaf_phc) &
+ * dt * cs14_veg%leafc_xfer_patch(p)!matrix_phturnover(p,ileaf_xf)*leafc_xfer(p)
+ cs14_veg%matrix_ctransfer_frootst_to_frootxf_acc_patch(p) = cs14_veg%matrix_ctransfer_frootst_to_frootxf_acc_patch(p) &
+ + matrix_phtransfer(p,ifrootst_to_ifrootxf_phc) &
+ * dt * cs14_veg%frootc_storage_patch(p)!matrix_phturnover(p,ifroot_st)*frootc_storage(p)
+ cs14_veg%matrix_ctransfer_frootxf_to_froot_acc_patch(p) = cs14_veg%matrix_ctransfer_frootxf_to_froot_acc_patch(p) &
+ + matrix_phtransfer(p,ifrootxf_to_ifroot_phc) &
+ * dt * cs14_veg%frootc_xfer_patch(p)!matrix_phturnover(p,ifroot_xf)*frootc_xfer(p)
+ cs14_veg%matrix_ctransfer_livestemst_to_livestemxf_acc_patch(p) = cs14_veg%matrix_ctransfer_livestemst_to_livestemxf_acc_patch(p) &
+ + matrix_phtransfer(p,ilivestemst_to_ilivestemxf_phc) &
+ * dt * cs14_veg%livestemc_storage_patch(p)!matrix_phturnover(p,ilivestem_st)*livestemc_storage(p)
+ cs14_veg%matrix_ctransfer_livestemxf_to_livestem_acc_patch(p) = cs14_veg%matrix_ctransfer_livestemxf_to_livestem_acc_patch(p) &
+ + matrix_phtransfer(p,ilivestemxf_to_ilivestem_phc) &
+ * dt * cs14_veg%livestemc_xfer_patch(p)!matrix_phturnover(p,ilivestem_xf)*livestemc_xfer(p)
+ cs14_veg%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch(p) = cs14_veg%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch(p) &
+ + matrix_phtransfer(p,ideadstemst_to_ideadstemxf_phc) &
+ * dt * cs14_veg%deadstemc_storage_patch(p)!matrix_phturnover(p,ideadstem_st)*deadstemc_storage(p)
+ cs14_veg%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch(p) = cs14_veg%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch(p) &
+ + matrix_phtransfer(p,ideadstemxf_to_ideadstem_phc) &
+ * dt * cs14_veg%deadstemc_xfer_patch(p)!matrix_phturnover(p,ideadstem_xf)*deadstemc_xfer(p)
+ cs14_veg%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch(p) = cs14_veg%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch(p) &
+ + matrix_phtransfer(p,ilivecrootst_to_ilivecrootxf_phc) &
+ * dt * cs14_veg%livecrootc_storage_patch(p)!matrix_phturnover(p,ilivecroot_st)*livecrootc_storage(p)
+ cs14_veg%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch(p) = cs14_veg%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch(p) &
+ + matrix_phtransfer(p,ilivecrootxf_to_ilivecroot_phc) &
+ * dt * cs14_veg%livecrootc_xfer_patch(p)!matrix_phturnover(p,ilivecroot_xf)*livecrootc_xfer(p)
+ cs14_veg%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch(p) = cs14_veg%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch(p) &
+ + matrix_phtransfer(p,ideadcrootst_to_ideadcrootxf_phc) &
+ * dt * cs14_veg%deadcrootc_storage_patch(p)!matrix_phturnover(p,ideadcroot_st)*deadcrootc_storage(p)
+ cs14_veg%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch(p) = cs14_veg%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch(p) &
+ + matrix_phtransfer(p,ideadcrootxf_to_ideadcroot_phc) &
+ * dt * cs14_veg%deadcrootc_xfer_patch(p)!matrix_phturnover(p,ideadcroot_st)*deadcrootc_xfer(p)
+ cs14_veg%matrix_ctransfer_livestem_to_deadstem_acc_patch(p) = cs14_veg%matrix_ctransfer_livestem_to_deadstem_acc_patch(p) &
+ +(matrix_phtransfer(p,ilivestem_to_ideadstem_phc)&!matrix_phturnover(p,ilivestem) &
+ + matrix_c14fitransfer(p,ilivestem_to_ideadstem_fic))&!matrix_fiturnover(p,ilivestem))&
+ * dt * cs14_veg%livestemc_patch(p)
+ cs14_veg%matrix_ctransfer_livecroot_to_deadcroot_acc_patch(p) = cs14_veg%matrix_ctransfer_livecroot_to_deadcroot_acc_patch(p) &
+ +(matrix_phtransfer(p,ilivecroot_to_ideadcroot_phc)&!*matrix_phturnover(p,ilivecroot) &
+ + matrix_c14fitransfer(p,ilivecroot_to_ideadcroot_fic))&!*matrix_fiturnover(p,ilivecroot))&
+ * dt * cs14_veg%livecrootc_patch(p)
+ cs14_veg%matrix_cturnover_leaf_acc_patch(p) = cs14_veg%matrix_cturnover_leaf_acc_patch(p) &
+ + (matrix_phturnover(p,ileaf)+matrix_gmturnover(p,ileaf)+matrix_c14fiturnover(p,ileaf)) &
+ * cs14_veg%leafc_patch(p)
+ cs14_veg%matrix_cturnover_leafst_acc_patch(p) = cs14_veg%matrix_cturnover_leafst_acc_patch(p) &
+ + (matrix_phturnover(p,ileaf_st)+matrix_gmturnover(p,ileaf_st)+matrix_c14fiturnover(p,ileaf_st)) &
+ * cs14_veg%leafc_storage_patch(p)
+ cs14_veg%matrix_cturnover_leafxf_acc_patch(p) = cs14_veg%matrix_cturnover_leafxf_acc_patch(p) &
+ + (matrix_phturnover(p,ileaf_xf)+matrix_gmturnover(p,ileaf_xf)+matrix_c14fiturnover(p,ileaf_xf)) &
+ * cs14_veg%leafc_xfer_patch(p)
+ cs14_veg%matrix_cturnover_froot_acc_patch(p) = cs14_veg%matrix_cturnover_froot_acc_patch(p) &
+ + (matrix_phturnover(p,ifroot)+matrix_gmturnover(p,ifroot)+matrix_c14fiturnover(p,ifroot)) &
+ * cs14_veg%frootc_patch(p)
+ cs14_veg%matrix_cturnover_frootst_acc_patch(p) = cs14_veg%matrix_cturnover_frootst_acc_patch(p) &
+ + (matrix_phturnover(p,ifroot_st)+matrix_gmturnover(p,ifroot_st)+matrix_c14fiturnover(p,ifroot_st)) &
+ * cs14_veg%frootc_storage_patch(p)
+ cs14_veg%matrix_cturnover_frootxf_acc_patch(p) = cs14_veg%matrix_cturnover_frootxf_acc_patch(p) &
+ + (matrix_phturnover(p,ifroot_xf)+matrix_gmturnover(p,ifroot_xf)+matrix_c14fiturnover(p,ifroot_xf)) &
+ * cs14_veg%frootc_xfer_patch(p)
+ cs14_veg%matrix_cturnover_livestem_acc_patch(p) = cs14_veg%matrix_cturnover_livestem_acc_patch(p) &
+ + (matrix_phturnover(p,ilivestem)+matrix_gmturnover(p,ilivestem)+matrix_c14fiturnover(p,ilivestem)) &
+ * cs14_veg%livestemc_patch(p)
+ cs14_veg%matrix_cturnover_livestemst_acc_patch(p) = cs14_veg%matrix_cturnover_livestemst_acc_patch(p) &
+ + (matrix_phturnover(p,ilivestem_st)+matrix_gmturnover(p,ilivestem_st)+matrix_c14fiturnover(p,ilivestem_st)) &
+ * cs14_veg%livestemc_storage_patch(p)
+ cs14_veg%matrix_cturnover_livestemxf_acc_patch(p) = cs14_veg%matrix_cturnover_livestemxf_acc_patch(p) &
+ + (matrix_phturnover(p,ilivestem_xf)+matrix_gmturnover(p,ilivestem_xf)+matrix_c14fiturnover(p,ilivestem_xf)) &
+ * cs14_veg%livestemc_xfer_patch(p)
+ cs14_veg%matrix_cturnover_deadstem_acc_patch(p) = cs14_veg%matrix_cturnover_deadstem_acc_patch(p) &
+ + (matrix_phturnover(p,ideadstem)+matrix_gmturnover(p,ideadstem)+matrix_c14fiturnover(p,ideadstem)) &
+ * cs14_veg%deadstemc_patch(p)
+ cs14_veg%matrix_cturnover_deadstemst_acc_patch(p) = cs14_veg%matrix_cturnover_deadstemst_acc_patch(p) &
+ + (matrix_phturnover(p,ideadstem_st)+matrix_gmturnover(p,ideadstem_st)+matrix_c14fiturnover(p,ideadstem_st)) &
+ * cs14_veg%deadstemc_storage_patch(p)
+ cs14_veg%matrix_cturnover_deadstemxf_acc_patch(p) = cs14_veg%matrix_cturnover_deadstemxf_acc_patch(p) &
+ + (matrix_phturnover(p,ideadstem_xf)+matrix_gmturnover(p,ideadstem_xf)+matrix_c14fiturnover(p,ideadstem_xf)) &
+ * cs14_veg%deadstemc_xfer_patch(p)
+ cs14_veg%matrix_cturnover_livecroot_acc_patch(p) = cs14_veg%matrix_cturnover_livecroot_acc_patch(p) &
+ + (matrix_phturnover(p,ilivecroot)+matrix_gmturnover(p,ilivecroot)+matrix_c14fiturnover(p,ilivecroot)) &
+ * cs14_veg%livecrootc_patch(p)
+ cs14_veg%matrix_cturnover_livecrootst_acc_patch(p) = cs14_veg%matrix_cturnover_livecrootst_acc_patch(p) &
+ + (matrix_phturnover(p,ilivecroot_st)+matrix_gmturnover(p,ilivecroot_st)+matrix_c14fiturnover(p,ilivecroot_st)) &
+ * cs14_veg%livecrootc_storage_patch(p)
+ cs14_veg%matrix_cturnover_livecrootxf_acc_patch(p) = cs14_veg%matrix_cturnover_livecrootxf_acc_patch(p) &
+ + (matrix_phturnover(p,ilivecroot_xf)+matrix_gmturnover(p,ilivecroot_xf)+matrix_c14fiturnover(p,ilivecroot_xf)) &
+ * cs14_veg%livecrootc_xfer_patch(p)
+ cs14_veg%matrix_cturnover_deadcroot_acc_patch(p) = cs14_veg%matrix_cturnover_deadcroot_acc_patch(p) &
+ + (matrix_phturnover(p,ideadcroot)+matrix_gmturnover(p,ideadcroot)+matrix_c14fiturnover(p,ideadcroot)) &
+ * cs14_veg%deadcrootc_patch(p)
+ cs14_veg%matrix_cturnover_deadcrootst_acc_patch(p) = cs14_veg%matrix_cturnover_deadcrootst_acc_patch(p) &
+ + (matrix_phturnover(p,ideadcroot_st)+matrix_gmturnover(p,ideadcroot_st)+matrix_c14fiturnover(p,ideadcroot_st)) &
+ * cs14_veg%deadcrootc_storage_patch(p)
+ cs14_veg%matrix_cturnover_deadcrootxf_acc_patch(p) = cs14_veg%matrix_cturnover_deadcrootxf_acc_patch(p) &
+ + (matrix_phturnover(p,ideadcroot_xf)+matrix_gmturnover(p,ideadcroot_xf)+matrix_c14fiturnover(p,ideadcroot_xf)) &
+ * cs14_veg%deadcrootc_xfer_patch(p)
+ end associate
+ end if
+ end do
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ matrix_cturnover_grain_acc(p) = matrix_cturnover_grain_acc(p) &
+ + (matrix_phturnover(p,igrain)+matrix_gmturnover(p,igrain)+matrix_fiturnover(p,igrain)) &
+ * reproductivec(p,irepr)
+ matrix_cturnover_grainst_acc(p) = matrix_cturnover_grainst_acc(p) &
+ + (matrix_phturnover(p,igrain_st)+matrix_gmturnover(p,igrain_st)+matrix_fiturnover(p,igrain_st)) &
+ * reproductivec_storage(p,irepr)
+ matrix_cturnover_grainxf_acc(p) = matrix_cturnover_grainxf_acc(p) &
+ + (matrix_phturnover(p,igrain_xf)+matrix_gmturnover(p,igrain_xf)+matrix_fiturnover(p,igrain_xf)) &
+ * reproductivec_xfer(p,irepr)
+ if(use_c13)then
+ cs13_veg%matrix_cturnover_grain_acc_patch(p) = cs13_veg%matrix_cturnover_grain_acc_patch(p) &
+ + (matrix_phturnover(p,igrain)+matrix_gmturnover(p,igrain)+matrix_fiturnover(p,igrain)) &
+ * cs13_veg%reproductivec_patch(p,irepr)
+ cs13_veg%matrix_cturnover_grainst_acc_patch(p) = cs13_veg%matrix_cturnover_grainst_acc_patch(p) &
+ + (matrix_phturnover(p,igrain_st)+matrix_gmturnover(p,igrain_st)+matrix_fiturnover(p,igrain_st)) &
+ * cs13_veg%reproductivec_storage_patch(p,irepr)
+ cs13_veg%matrix_cturnover_grainxf_acc_patch(p) = cs13_veg%matrix_cturnover_grainxf_acc_patch(p) &
+ + (matrix_phturnover(p,igrain_xf)+matrix_gmturnover(p,igrain_xf)+matrix_fiturnover(p,igrain_xf)) &
+ * cs13_veg%reproductivec_xfer_patch(p,irepr)
+ end if
+ if(use_c14)then
+ associate( &
+ matrix_c14fitransfer => c14_cnveg_carbonflux_inst%matrix_fitransfer_patch , & ! Input: [real(r8) (:,:)] (gC/m2/s) C transfer rate from fire processes, updated in (CNFireBaseMod or CNFireLi2014Mod) and CNC14decayMod
+ matrix_c14fiturnover => c14_cnveg_carbonflux_inst%matrix_fiturnover_patch & ! Output: [real(r8) (:,:)] (gC/m2/step) C turnover rate from fire processe, updated in CNVegMatrixMods
+ )
+ cs14_veg%matrix_cturnover_grain_acc_patch(p) = cs14_veg%matrix_cturnover_grain_acc_patch(p) &
+ + (matrix_phturnover(p,igrain)+matrix_gmturnover(p,igrain)+matrix_c14fiturnover(p,igrain)) &
+ * cs14_veg%reproductivec_patch(p,irepr)
+ cs14_veg%matrix_cturnover_grainst_acc_patch(p) = cs14_veg%matrix_cturnover_grainst_acc_patch(p) &
+ + (matrix_phturnover(p,igrain_st)+matrix_gmturnover(p,igrain_st)+matrix_c14fiturnover(p,igrain_st)) &
+ * cs14_veg%reproductivec_storage_patch(p,irepr)
+ cs14_veg%matrix_cturnover_grainxf_acc_patch(p) = cs14_veg%matrix_cturnover_grainxf_acc_patch(p) &
+ + (matrix_phturnover(p,igrain_xf)+matrix_gmturnover(p,igrain_xf)+matrix_c14fiturnover(p,igrain_xf)) &
+ * cs14_veg%reproductivec_xfer_patch(p,irepr)
+ end associate
+ end if
+ end if
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ matrix_nalloc_leaf_acc(p) = matrix_nalloc_leaf_acc(p) + vegmatrixn_input%V(p,ileaf)
+ matrix_nalloc_leafst_acc(p) = matrix_nalloc_leafst_acc(p) + vegmatrixn_input%V(p,ileaf_st)
+ matrix_nalloc_froot_acc(p) = matrix_nalloc_froot_acc(p) + vegmatrixn_input%V(p,ifroot)
+ matrix_nalloc_frootst_acc(p) = matrix_nalloc_frootst_acc(p) + vegmatrixn_input%V(p,ifroot_st)
+ matrix_nalloc_livestem_acc(p) = matrix_nalloc_livestem_acc(p) + vegmatrixn_input%V(p,ilivestem)
+ matrix_nalloc_livestemst_acc(p) = matrix_nalloc_livestemst_acc(p) + vegmatrixn_input%V(p,ilivestem_st)
+ matrix_nalloc_deadstem_acc(p) = matrix_nalloc_deadstem_acc(p) + vegmatrixn_input%V(p,ideadstem)
+ matrix_nalloc_deadstemst_acc(p) = matrix_nalloc_deadstemst_acc(p) + vegmatrixn_input%V(p,ideadstem_st)
+ matrix_nalloc_livecroot_acc(p) = matrix_nalloc_livecroot_acc(p) + vegmatrixn_input%V(p,ilivecroot)
+ matrix_nalloc_livecrootst_acc(p) = matrix_nalloc_livecrootst_acc(p) + vegmatrixn_input%V(p,ilivecroot_st)
+ matrix_nalloc_deadcroot_acc(p) = matrix_nalloc_deadcroot_acc(p) + vegmatrixn_input%V(p,ideadcroot)
+ matrix_nalloc_deadcrootst_acc(p) = matrix_nalloc_deadcrootst_acc(p) + vegmatrixn_input%V(p,ideadcroot_st)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ matrix_nalloc_grain_acc(p) = matrix_nalloc_grain_acc(p) + vegmatrixn_input%V(p,igrain)
+ matrix_nalloc_grainst_acc(p) = matrix_nalloc_grainst_acc(p) + vegmatrixn_input%V(p,igrain_st)
+ end if
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ matrix_ntransfer_leafst_to_leafxf_acc(p) = matrix_ntransfer_leafst_to_leafxf_acc(p) &
+ + matrix_nphtransfer(p,ileafst_to_ileafxf_phn) &
+ * dt * leafn_storage(p)!matrix_nphturnover(p,ileaf_st)*leafn_storage(p)
+ matrix_ntransfer_leafxf_to_leaf_acc(p) = matrix_ntransfer_leafxf_to_leaf_acc(p) &
+ + matrix_nphtransfer(p,ileafxf_to_ileaf_phn) &
+ * dt * leafn_xfer(p)!matrix_nphturnover(p,ileaf_xf)*leafn_xfer(p)
+ matrix_ntransfer_frootst_to_frootxf_acc(p) = matrix_ntransfer_frootst_to_frootxf_acc(p) &
+ + matrix_nphtransfer(p,ifrootst_to_ifrootxf_phn) &
+ * dt * frootn_storage(p)!matrix_nphturnover(p,ifroot_st)*frootn_storage(p)
+ matrix_ntransfer_frootxf_to_froot_acc(p) = matrix_ntransfer_frootxf_to_froot_acc(p) &
+ + matrix_nphtransfer(p,ifrootxf_to_ifroot_phn) &
+ * dt * frootn_xfer(p)!matrix_nphturnover(p,ifroot_xf)*frootn_xfer(p)
+ matrix_ntransfer_livestemst_to_livestemxf_acc(p) = matrix_ntransfer_livestemst_to_livestemxf_acc(p) &
+ + matrix_nphtransfer(p,ilivestemst_to_ilivestemxf_phn) &
+ * dt * livestemn_storage(p)!matrix_nphturnover(p,ilivestem_st)*livestemn_storage(p)
+ matrix_ntransfer_livestemxf_to_livestem_acc(p) = matrix_ntransfer_livestemxf_to_livestem_acc(p) &
+ + matrix_nphtransfer(p,ilivestemxf_to_ilivestem_phn) &
+ * dt * livestemn_xfer(p)!matrix_nphturnover(p,ilivestem_xf)*livestemn_xfer(p)
+ matrix_ntransfer_deadstemst_to_deadstemxf_acc(p) = matrix_ntransfer_deadstemst_to_deadstemxf_acc(p) &
+ + matrix_nphtransfer(p,ideadstemst_to_ideadstemxf_phn) &
+ * dt * deadstemn_storage(p)!matrix_nphturnover(p,ideadstem_st)*deadstemn_storage(p)
+ matrix_ntransfer_deadstemxf_to_deadstem_acc(p) = matrix_ntransfer_deadstemxf_to_deadstem_acc(p) &
+ + matrix_nphtransfer(p,ideadstemxf_to_ideadstem_phn) &
+ * dt * deadstemn_xfer(p)!matrix_nphturnover(p,ideadstem_xf)*deadstemn_storage(p)
+ matrix_ntransfer_livecrootst_to_livecrootxf_acc(p) = matrix_ntransfer_livecrootst_to_livecrootxf_acc(p) &
+ + matrix_nphtransfer(p,ilivecrootst_to_ilivecrootxf_phn) &
+ * dt * livecrootn_storage(p)!matrix_nphturnover(p,ilivecroot_st)*livecrootn_storage(p)
+ matrix_ntransfer_livecrootxf_to_livecroot_acc(p) = matrix_ntransfer_livecrootxf_to_livecroot_acc(p) &
+ + matrix_nphtransfer(p,ilivecrootxf_to_ilivecroot_phn) &
+ * dt * livecrootn_xfer(p)!matrix_nphturnover(p,ilivecroot_xf)*livecrootn_xfer(p)
+ matrix_ntransfer_deadcrootst_to_deadcrootxf_acc(p) = matrix_ntransfer_deadcrootst_to_deadcrootxf_acc(p) &
+ + matrix_nphtransfer(p,ideadcrootst_to_ideadcrootxf_phn) &
+ * dt * deadcrootn_storage(p)!matrix_nphturnover(p,ideadcroot_st)*deadcrootn_storage(p)
+ matrix_ntransfer_deadcrootxf_to_deadcroot_acc(p) = matrix_ntransfer_deadcrootxf_to_deadcroot_acc(p) &
+ + matrix_nphtransfer(p,ideadcrootxf_to_ideadcroot_phn) &
+ * dt * deadcrootn_xfer(p)!matrix_nphturnover(p,ideadcroot_st)*deadcrootn_xfer(p)
+ matrix_ntransfer_livestem_to_deadstem_acc(p) = matrix_ntransfer_livestem_to_deadstem_acc(p) &
+ +(matrix_nphtransfer(p,ilivestem_to_ideadstem_phn) &!*matrix_nphturnover(p,ilivestem) &
+ + matrix_nfitransfer(p,ilivestem_to_ideadstem_fin)) &!*matrix_nfiturnover(p,ilivestem)) &
+ * dt * livestemn(p)
+ matrix_ntransfer_livecroot_to_deadcroot_acc(p) = matrix_ntransfer_livecroot_to_deadcroot_acc(p) &
+ +(matrix_nphtransfer(p,ilivecroot_to_ideadcroot_phn) &!*matrix_nphturnover(p,ilivecroot) &
+ + matrix_nfitransfer(p,ilivecroot_to_ideadcroot_fin)) &!*matrix_nfiturnover(p,ilivecroot)) &
+ * dt * livecrootn(p)
+
+ matrix_ntransfer_retransn_to_leaf_acc(p) = matrix_ntransfer_retransn_to_leaf_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ileaf_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_leafst_acc(p) = matrix_ntransfer_retransn_to_leafst_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ileafst_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_froot_acc(p) = matrix_ntransfer_retransn_to_froot_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ifroot_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_frootst_acc(p) = matrix_ntransfer_retransn_to_frootst_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ifrootst_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_livestem_acc(p) = matrix_ntransfer_retransn_to_livestem_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ilivestem_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_livestemst_acc(p) = matrix_ntransfer_retransn_to_livestemst_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ilivestemst_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_deadstem_acc(p) = matrix_ntransfer_retransn_to_deadstem_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ideadstem_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_deadstemst_acc(p) = matrix_ntransfer_retransn_to_deadstemst_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ideadstemst_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_livecroot_acc(p) = matrix_ntransfer_retransn_to_livecroot_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ilivecroot_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_livecrootst_acc(p) = matrix_ntransfer_retransn_to_livecrootst_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ilivecrootst_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_deadcroot_acc(p) = matrix_ntransfer_retransn_to_deadcroot_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ideadcroot_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_deadcrootst_acc(p) = matrix_ntransfer_retransn_to_deadcrootst_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ideadcrootst_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_leaf_to_retransn_acc(p) = matrix_ntransfer_leaf_to_retransn_acc(p) &
+ + matrix_nphtransfer(p,ileaf_to_iretransn_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,ileaf)*leafn(p)
+ matrix_ntransfer_froot_to_retransn_acc(p) = matrix_ntransfer_froot_to_retransn_acc(p) &
+ + matrix_nphtransfer(p,ifroot_to_iretransn_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,ifroot)*frootn(p)
+ matrix_ntransfer_livestem_to_retransn_acc(p) = matrix_ntransfer_livestem_to_retransn_acc(p) &
+ + matrix_nphtransfer(p,ilivestem_to_iretransn_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,ilivestem)*livestemn(p)
+ matrix_ntransfer_livecroot_to_retransn_acc(p) = matrix_ntransfer_livecroot_to_retransn_acc(p) &
+ + matrix_nphtransfer(p,ilivecroot_to_iretransn_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,ilivecroot)*livecrootn(p)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ matrix_ntransfer_retransn_to_grain_acc(p) = matrix_ntransfer_retransn_to_grain_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_igrain_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_grainst_acc(p) = matrix_ntransfer_retransn_to_grainst_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_igrainst_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ end if
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ matrix_nturnover_leaf_acc(p) = matrix_nturnover_leaf_acc(p) &
+ + (matrix_nphturnover(p,ileaf)+matrix_ngmturnover(p,ileaf)+matrix_nfiturnover(p,ileaf)) &
+ * leafn(p)
+ matrix_nturnover_leafst_acc(p) = matrix_nturnover_leafst_acc(p) &
+ + (matrix_nphturnover(p,ileaf_st)+matrix_ngmturnover(p,ileaf_st)+matrix_nfiturnover(p,ileaf_st)) &
+ * leafn_storage(p)
+ matrix_nturnover_leafxf_acc(p) = matrix_nturnover_leafxf_acc(p) &
+ + (matrix_nphturnover(p,ileaf_xf)+matrix_ngmturnover(p,ileaf_xf)+matrix_nfiturnover(p,ileaf_xf)) &
+ * leafn_xfer(p)
+ matrix_nturnover_froot_acc(p) = matrix_nturnover_froot_acc(p) &
+ + (matrix_nphturnover(p,ifroot)+matrix_ngmturnover(p,ifroot)+matrix_nfiturnover(p,ifroot)) &
+ * frootn(p)
+ matrix_nturnover_frootst_acc(p) = matrix_nturnover_frootst_acc(p) &
+ + (matrix_nphturnover(p,ifroot_st)+matrix_ngmturnover(p,ifroot_st)+matrix_nfiturnover(p,ifroot_st)) &
+ * frootn_storage(p)
+ matrix_nturnover_frootxf_acc(p) = matrix_nturnover_frootxf_acc(p) &
+ + (matrix_nphturnover(p,ifroot_xf)+matrix_ngmturnover(p,ifroot_xf)+matrix_nfiturnover(p,ifroot_xf)) &
+ * frootn_xfer(p)
+ matrix_nturnover_livestem_acc(p) = matrix_nturnover_livestem_acc(p) &
+ + (matrix_nphturnover(p,ilivestem)+matrix_ngmturnover(p,ilivestem)+matrix_nfiturnover(p,ilivestem)) &
+ * livestemn(p)
+ matrix_nturnover_livestemst_acc(p) = matrix_nturnover_livestemst_acc(p) &
+ + (matrix_nphturnover(p,ilivestem_st)+matrix_ngmturnover(p,ilivestem_st)+matrix_nfiturnover(p,ilivestem_st)) &
+ * livestemn_storage(p)
+ matrix_nturnover_livestemxf_acc(p) = matrix_nturnover_livestemxf_acc(p) &
+ + (matrix_nphturnover(p,ilivestem_xf)+matrix_ngmturnover(p,ilivestem_xf)+matrix_nfiturnover(p,ilivestem_xf)) &
+ * livestemn_xfer(p)
+ matrix_nturnover_deadstem_acc(p) = matrix_nturnover_deadstem_acc(p) &
+ + (matrix_nphturnover(p,ideadstem)+matrix_ngmturnover(p,ideadstem)+matrix_nfiturnover(p,ideadstem)) &
+ * deadstemn(p)
+ matrix_nturnover_deadstemst_acc(p) = matrix_nturnover_deadstemst_acc(p) &
+ + (matrix_nphturnover(p,ideadstem_st)+matrix_ngmturnover(p,ideadstem_st)+matrix_nfiturnover(p,ideadstem_st)) &
+ * deadstemn_storage(p)
+ matrix_nturnover_deadstemxf_acc(p) = matrix_nturnover_deadstemxf_acc(p) &
+ + (matrix_nphturnover(p,ideadstem_xf)+matrix_ngmturnover(p,ideadstem_xf)+matrix_nfiturnover(p,ideadstem_xf)) &
+ * deadstemn_xfer(p)
+ matrix_nturnover_livecroot_acc(p) = matrix_nturnover_livecroot_acc(p) &
+ + (matrix_nphturnover(p,ilivecroot)+matrix_ngmturnover(p,ilivecroot)+matrix_nfiturnover(p,ilivecroot)) &
+ * livecrootn(p)
+ matrix_nturnover_livecrootst_acc(p) = matrix_nturnover_livecrootst_acc(p) &
+ + (matrix_nphturnover(p,ilivecroot_st)+matrix_ngmturnover(p,ilivecroot_st)+matrix_nfiturnover(p,ilivecroot_st)) &
+ * livecrootn_storage(p)
+ matrix_nturnover_livecrootxf_acc(p) = matrix_nturnover_livecrootxf_acc(p) &
+ + (matrix_nphturnover(p,ilivecroot_xf)+matrix_ngmturnover(p,ilivecroot_xf)+matrix_nfiturnover(p,ilivecroot_xf)) &
+ * livecrootn_xfer(p)
+ matrix_nturnover_deadcroot_acc(p) = matrix_nturnover_deadcroot_acc(p) &
+ + (matrix_nphturnover(p,ideadcroot)+matrix_ngmturnover(p,ideadcroot)+matrix_nfiturnover(p,ideadcroot)) &
+ * deadcrootn(p)
+ matrix_nturnover_deadcrootst_acc(p) = matrix_nturnover_deadcrootst_acc(p) &
+ + (matrix_nphturnover(p,ideadcroot_st)+matrix_ngmturnover(p,ideadcroot_st)+matrix_nfiturnover(p,ideadcroot_st)) &
+ * deadcrootn_storage(p)
+ matrix_nturnover_deadcrootxf_acc(p) = matrix_nturnover_deadcrootxf_acc(p) &
+ + (matrix_nphturnover(p,ideadcroot_xf)+matrix_ngmturnover(p,ideadcroot_xf)+matrix_nfiturnover(p,ideadcroot_xf)) &
+ * deadcrootn_xfer(p)
+ matrix_nturnover_retransn_acc(p) = matrix_nturnover_retransn_acc(p) &
+ + (matrix_nphturnover(p,iretransn)+matrix_ngmturnover(p,iretransn)+matrix_nfiturnover(p,iretransn)) &
+ * retransn(p)
+ end do
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ matrix_nturnover_grain_acc(p) = matrix_nturnover_grain_acc(p) &
+ + (matrix_nphturnover(p,igrain)+matrix_ngmturnover(p,igrain)+matrix_nfiturnover(p,igrain)) &
+ * reproductiven(p,irepr)
+ matrix_nturnover_grainst_acc(p) = matrix_nturnover_grainst_acc(p) &
+ + (matrix_nphturnover(p,igrain_st)+matrix_ngmturnover(p,igrain_st)+matrix_nfiturnover(p,igrain_st)) &
+ * reproductiven_storage(p,irepr)
+ matrix_nturnover_grainxf_acc(p) = matrix_nturnover_grainxf_acc(p) &
+ + (matrix_nphturnover(p,igrain_xf)+matrix_ngmturnover(p,igrain_xf)+matrix_nfiturnover(p,igrain_xf)) &
+ * reproductiven_xfer(p,irepr)
+ end if
+ end do
+ end if
+ call t_stopf('CN veg matrix-accum. trans.')
+
+ ! Update state variables
+ call t_startf('CN veg matrix-assign new value')
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ leafc(p) = Xvegc%V(p,ileaf)
+ leafc_storage(p) = Xvegc%V(p,ileaf_st)
+ leafc_xfer(p) = Xvegc%V(p,ileaf_xf)
+ frootc(p) = Xvegc%V(p,ifroot)
+ frootc_storage(p) = Xvegc%V(p,ifroot_st)
+ frootc_xfer(p) = Xvegc%V(p,ifroot_xf)
+ livestemc(p) = Xvegc%V(p,ilivestem)
+ livestemc_storage(p) = Xvegc%V(p,ilivestem_st)
+ livestemc_xfer(p) = Xvegc%V(p,ilivestem_xf)
+ deadstemc(p) = Xvegc%V(p,ideadstem)
+ deadstemc_storage(p) = Xvegc%V(p,ideadstem_st)
+ deadstemc_xfer(p) = Xvegc%V(p,ideadstem_xf)
+ livecrootc(p) = Xvegc%V(p,ilivecroot)
+ livecrootc_storage(p) = Xvegc%V(p,ilivecroot_st)
+ livecrootc_xfer(p) = Xvegc%V(p,ilivecroot_xf)
+ deadcrootc(p) = Xvegc%V(p,ideadcroot)
+ deadcrootc_storage(p) = Xvegc%V(p,ideadcroot_st)
+ deadcrootc_xfer(p) = Xvegc%V(p,ideadcroot_xf)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ ! NOTE: This assumes only a single grain pool! (i.e nrepr is
+ ! fixed at 1)!
+ reproductivec(p,:) = Xvegc%V(p,igrain)
+ reproductivec_storage(p,:) = Xvegc%V(p,igrain_st)
+ reproductivec_xfer(p,:) = Xvegc%V(p,igrain_xf)
+ end if
+ end do
+
+ if ( use_c13 ) then
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ cs13_veg%leafc_patch(p) = Xveg13c%V(p,ileaf)
+ cs13_veg%leafc_storage_patch(p) = Xveg13c%V(p,ileaf_st)
+ cs13_veg%leafc_xfer_patch(p) = Xveg13c%V(p,ileaf_xf)
+ cs13_veg%frootc_patch(p) = Xveg13c%V(p,ifroot)
+ cs13_veg%frootc_storage_patch(p) = Xveg13c%V(p,ifroot_st)
+ cs13_veg%frootc_xfer_patch(p) = Xveg13c%V(p,ifroot_xf)
+ cs13_veg%livestemc_patch(p) = Xveg13c%V(p,ilivestem)
+ cs13_veg%livestemc_storage_patch(p) = Xveg13c%V(p,ilivestem_st)
+ cs13_veg%livestemc_xfer_patch(p) = Xveg13c%V(p,ilivestem_xf)
+ cs13_veg%deadstemc_patch(p) = Xveg13c%V(p,ideadstem)
+ cs13_veg%deadstemc_storage_patch(p) = Xveg13c%V(p,ideadstem_st)
+ cs13_veg%deadstemc_xfer_patch(p) = Xveg13c%V(p,ideadstem_xf)
+ cs13_veg%livecrootc_patch(p) = Xveg13c%V(p,ilivecroot)
+ cs13_veg%livecrootc_storage_patch(p) = Xveg13c%V(p,ilivecroot_st)
+ cs13_veg%livecrootc_xfer_patch(p) = Xveg13c%V(p,ilivecroot_xf)
+ cs13_veg%deadcrootc_patch(p) = Xveg13c%V(p,ideadcroot)
+ cs13_veg%deadcrootc_storage_patch(p) = Xveg13c%V(p,ideadcroot_st)
+ cs13_veg%deadcrootc_xfer_patch(p) = Xveg13c%V(p,ideadcroot_xf)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ ! NOTE: This assumes only a single grain pool! (i.e nrepr is
+ ! fixed at 1)!
+ cs13_veg%reproductivec_patch(p,:) = Xveg13c%V(p,igrain)
+ cs13_veg%reproductivec_storage_patch(p,:) = Xveg13c%V(p,igrain_st)
+ cs13_veg%reproductivec_xfer_patch(p,:) = Xveg13c%V(p,igrain_xf)
+ end if
+ end do
+ end if
+
+ if ( use_c14 ) then
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ cs14_veg%leafc_patch(p) = Xveg14c%V(p,ileaf)
+ cs14_veg%leafc_storage_patch(p) = Xveg14c%V(p,ileaf_st)
+ cs14_veg%leafc_xfer_patch(p) = Xveg14c%V(p,ileaf_xf)
+ cs14_veg%frootc_patch(p) = Xveg14c%V(p,ifroot)
+ cs14_veg%frootc_storage_patch(p) = Xveg14c%V(p,ifroot_st)
+ cs14_veg%frootc_xfer_patch(p) = Xveg14c%V(p,ifroot_xf)
+ cs14_veg%livestemc_patch(p) = Xveg14c%V(p,ilivestem)
+ cs14_veg%livestemc_storage_patch(p) = Xveg14c%V(p,ilivestem_st)
+ cs14_veg%livestemc_xfer_patch(p) = Xveg14c%V(p,ilivestem_xf)
+ cs14_veg%deadstemc_patch(p) = Xveg14c%V(p,ideadstem)
+ cs14_veg%deadstemc_storage_patch(p) = Xveg14c%V(p,ideadstem_st)
+ cs14_veg%deadstemc_xfer_patch(p) = Xveg14c%V(p,ideadstem_xf)
+ cs14_veg%livecrootc_patch(p) = Xveg14c%V(p,ilivecroot)
+ cs14_veg%livecrootc_storage_patch(p) = Xveg14c%V(p,ilivecroot_st)
+ cs14_veg%livecrootc_xfer_patch(p) = Xveg14c%V(p,ilivecroot_xf)
+ cs14_veg%deadcrootc_patch(p) = Xveg14c%V(p,ideadcroot)
+ cs14_veg%deadcrootc_storage_patch(p) = Xveg14c%V(p,ideadcroot_st)
+ cs14_veg%deadcrootc_xfer_patch(p) = Xveg14c%V(p,ideadcroot_xf)
+ end do
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ ! NOTE: This assumes only a single grain pool! (i.e nrepr is
+ ! fixed at 1)!
+ cs14_veg%reproductivec_patch(p,:) = Xveg14c%V(p,igrain)
+ cs14_veg%reproductivec_storage_patch(p,:) = Xveg14c%V(p,igrain_st)
+ cs14_veg%reproductivec_xfer_patch(p,:) = Xveg14c%V(p,igrain_xf)
+ end if
+ end do
+ end if
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ leafn(p) = Xvegn%V(p,ileaf)
+ leafn_storage(p) = Xvegn%V(p,ileaf_st)
+ leafn_xfer(p) = Xvegn%V(p,ileaf_xf)
+ frootn(p) = Xvegn%V(p,ifroot)
+ frootn_storage(p) = Xvegn%V(p,ifroot_st)
+ frootn_xfer(p) = Xvegn%V(p,ifroot_xf)
+ livestemn(p) = Xvegn%V(p,ilivestem)
+ livestemn_storage(p) = Xvegn%V(p,ilivestem_st)
+ livestemn_xfer(p) = Xvegn%V(p,ilivestem_xf)
+ deadstemn(p) = Xvegn%V(p,ideadstem)
+ deadstemn_storage(p) = Xvegn%V(p,ideadstem_st)
+ deadstemn_xfer(p) = Xvegn%V(p,ideadstem_xf)
+ livecrootn(p) = Xvegn%V(p,ilivecroot)
+ livecrootn_storage(p) = Xvegn%V(p,ilivecroot_st)
+ livecrootn_xfer(p) = Xvegn%V(p,ilivecroot_xf)
+ deadcrootn(p) = Xvegn%V(p,ideadcroot)
+ deadcrootn_storage(p) = Xvegn%V(p,ideadcroot_st)
+ deadcrootn_xfer(p) = Xvegn%V(p,ideadcroot_xf)
+ retransn(p) = Xvegn%V(p,iretransn)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ reproductiven(p,:) = Xvegn%V(p,igrain)
+ reproductiven_storage(p,:) = Xvegn%V(p,igrain_st)
+ reproductiven_xfer(p,:) = Xvegn%V(p,igrain_xf)
+ end if
+ end do
+ call t_stopf('CN veg matrix-assign new value')
+
+ ! Calculate C storage capacity. 2D matrix instead of sparse matrix is still used when calculating the inverse
+ if(spinup_matrixcn .or. hist_wrt_matrixcn_diag)then
+ if((.not. spinup_matrixcn .and. is_end_curr_year()) .or. (spinup_matrixcn .and. is_end_curr_year() .and. mod(iyr,nyr_SASU) .eq. 0))then
+ do fp = 1,num_soilp
+ call t_startf('CN veg matrix-prepare AK^-1')
+ p = filter_soilp(fp)
+ matrix_calloc_acc(ileaf) = matrix_calloc_leaf_acc(p)
+ matrix_calloc_acc(ileaf_st) = matrix_calloc_leafst_acc(p)
+ matrix_calloc_acc(ifroot) = matrix_calloc_froot_acc(p)
+ matrix_calloc_acc(ifroot_st) = matrix_calloc_frootst_acc(p)
+ matrix_calloc_acc(ilivestem) = matrix_calloc_livestem_acc(p)
+ matrix_calloc_acc(ilivestem_st) = matrix_calloc_livestemst_acc(p)
+ matrix_calloc_acc(ideadstem) = matrix_calloc_deadstem_acc(p)
+ matrix_calloc_acc(ideadstem_st) = matrix_calloc_deadstemst_acc(p)
+ matrix_calloc_acc(ilivecroot) = matrix_calloc_livecroot_acc(p)
+ matrix_calloc_acc(ilivecroot_st) = matrix_calloc_livecrootst_acc(p)
+ matrix_calloc_acc(ideadcroot) = matrix_calloc_deadcroot_acc(p)
+ matrix_calloc_acc(ideadcroot_st) = matrix_calloc_deadcrootst_acc(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_calloc_acc(igrain) = matrix_calloc_grain_acc(p)
+ matrix_calloc_acc(igrain_st) = matrix_calloc_grainst_acc(p)
+ end if
+
+ matrix_ctransfer_acc(ileaf_xf,ileaf_st) = matrix_ctransfer_leafst_to_leafxf_acc(p)
+ matrix_ctransfer_acc(ileaf,ileaf_xf) = matrix_ctransfer_leafxf_to_leaf_acc(p)
+ matrix_ctransfer_acc(ifroot_xf,ifroot_st) = matrix_ctransfer_frootst_to_frootxf_acc(p)
+ matrix_ctransfer_acc(ifroot,ifroot_xf) = matrix_ctransfer_frootxf_to_froot_acc(p)
+ matrix_ctransfer_acc(ilivestem_xf,ilivestem_st) = matrix_ctransfer_livestemst_to_livestemxf_acc(p)
+ matrix_ctransfer_acc(ilivestem,ilivestem_xf) = matrix_ctransfer_livestemxf_to_livestem_acc(p)
+ matrix_ctransfer_acc(ideadstem_xf,ideadstem_st) = matrix_ctransfer_deadstemst_to_deadstemxf_acc(p)
+ matrix_ctransfer_acc(ideadstem,ideadstem_xf) = matrix_ctransfer_deadstemxf_to_deadstem_acc(p)
+ matrix_ctransfer_acc(ilivecroot_xf,ilivecroot_st) = matrix_ctransfer_livecrootst_to_livecrootxf_acc(p)
+ matrix_ctransfer_acc(ilivecroot,ilivecroot_xf) = matrix_ctransfer_livecrootxf_to_livecroot_acc(p)
+ matrix_ctransfer_acc(ideadcroot_xf,ideadcroot_st) = matrix_ctransfer_deadcrootst_to_deadcrootxf_acc(p)
+ matrix_ctransfer_acc(ideadcroot,ideadcroot_xf) = matrix_ctransfer_deadcrootxf_to_deadcroot_acc(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_ctransfer_acc(igrain_xf,igrain_st) = matrix_ctransfer_grainst_to_grainxf_acc(p)
+ matrix_ctransfer_acc(igrain,igrain_xf) = matrix_ctransfer_grainxf_to_grain_acc(p)
+ end if
+ matrix_ctransfer_acc(ideadstem,ilivestem) = matrix_ctransfer_livestem_to_deadstem_acc(p)
+ matrix_ctransfer_acc(ideadcroot,ilivecroot) = matrix_ctransfer_livecroot_to_deadcroot_acc(p)
+
+ matrix_ctransfer_acc(ileaf,ileaf) = -matrix_cturnover_leaf_acc(p)
+ matrix_ctransfer_acc(ileaf_st,ileaf_st) = -matrix_cturnover_leafst_acc(p)
+ matrix_ctransfer_acc(ileaf_xf,ileaf_xf) = -matrix_cturnover_leafxf_acc(p)
+ matrix_ctransfer_acc(ifroot,ifroot) = -matrix_cturnover_froot_acc(p)
+ matrix_ctransfer_acc(ifroot_st,ifroot_st) = -matrix_cturnover_frootst_acc(p)
+ matrix_ctransfer_acc(ifroot_xf,ifroot_xf) = -matrix_cturnover_frootxf_acc(p)
+ matrix_ctransfer_acc(ilivestem,ilivestem) = -matrix_cturnover_livestem_acc(p)
+ matrix_ctransfer_acc(ilivestem_st,ilivestem_st) = -matrix_cturnover_livestemst_acc(p)
+ matrix_ctransfer_acc(ilivestem_xf,ilivestem_xf) = -matrix_cturnover_livestemxf_acc(p)
+ matrix_ctransfer_acc(ideadstem,ideadstem) = -matrix_cturnover_deadstem_acc(p)
+ matrix_ctransfer_acc(ideadstem_st,ideadstem_st) = -matrix_cturnover_deadstemst_acc(p)
+ matrix_ctransfer_acc(ideadstem_xf,ideadstem_xf) = -matrix_cturnover_deadstemxf_acc(p)
+ matrix_ctransfer_acc(ilivecroot,ilivecroot) = -matrix_cturnover_livecroot_acc(p)
+ matrix_ctransfer_acc(ilivecroot_st,ilivecroot_st) = -matrix_cturnover_livecrootst_acc(p)
+ matrix_ctransfer_acc(ilivecroot_xf,ilivecroot_xf) = -matrix_cturnover_livecrootxf_acc(p)
+ matrix_ctransfer_acc(ideadcroot,ideadcroot) = -matrix_cturnover_deadcroot_acc(p)
+ matrix_ctransfer_acc(ideadcroot_st,ideadcroot_st) = -matrix_cturnover_deadcrootst_acc(p)
+ matrix_ctransfer_acc(ideadcroot_xf,ideadcroot_xf) = -matrix_cturnover_deadcrootxf_acc(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_ctransfer_acc(igrain,igrain) = -matrix_cturnover_grain_acc(p)
+ matrix_ctransfer_acc(igrain_st,igrain_st) = -matrix_cturnover_grainst_acc(p)
+ matrix_ctransfer_acc(igrain_xf,igrain_xf) = -matrix_cturnover_grainxf_acc(p)
+ end if
+
+ if(use_c13)then
+ matrix_c13alloc_acc(ileaf) = cs13_veg%matrix_calloc_leaf_acc_patch(p)
+ matrix_c13alloc_acc(ileaf_st) = cs13_veg%matrix_calloc_leafst_acc_patch(p)
+ matrix_c13alloc_acc(ifroot) = cs13_veg%matrix_calloc_froot_acc_patch(p)
+ matrix_c13alloc_acc(ifroot_st) = cs13_veg%matrix_calloc_frootst_acc_patch(p)
+ matrix_c13alloc_acc(ilivestem) = cs13_veg%matrix_calloc_livestem_acc_patch(p)
+ matrix_c13alloc_acc(ilivestem_st) = cs13_veg%matrix_calloc_livestemst_acc_patch(p)
+ matrix_c13alloc_acc(ideadstem) = cs13_veg%matrix_calloc_deadstem_acc_patch(p)
+ matrix_c13alloc_acc(ideadstem_st) = cs13_veg%matrix_calloc_deadstemst_acc_patch(p)
+ matrix_c13alloc_acc(ilivecroot) = cs13_veg%matrix_calloc_livecroot_acc_patch(p)
+ matrix_c13alloc_acc(ilivecroot_st) = cs13_veg%matrix_calloc_livecrootst_acc_patch(p)
+ matrix_c13alloc_acc(ideadcroot) = cs13_veg%matrix_calloc_deadcroot_acc_patch(p)
+ matrix_c13alloc_acc(ideadcroot_st) = cs13_veg%matrix_calloc_deadcrootst_acc_patch(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_c13alloc_acc(igrain) = cs13_veg%matrix_calloc_grain_acc_patch(p)
+ matrix_c13alloc_acc(igrain_st) = cs13_veg%matrix_calloc_grainst_acc_patch(p)
+ end if
+
+ matrix_c13transfer_acc(ileaf_xf,ileaf_st) = cs13_veg%matrix_ctransfer_leafst_to_leafxf_acc_patch(p)
+ matrix_c13transfer_acc(ileaf,ileaf_xf) = cs13_veg%matrix_ctransfer_leafxf_to_leaf_acc_patch(p)
+ matrix_c13transfer_acc(ifroot_xf,ifroot_st) = cs13_veg%matrix_ctransfer_frootst_to_frootxf_acc_patch(p)
+ matrix_c13transfer_acc(ifroot,ifroot_xf) = cs13_veg%matrix_ctransfer_frootxf_to_froot_acc_patch(p)
+ matrix_c13transfer_acc(ilivestem_xf,ilivestem_st) = cs13_veg%matrix_ctransfer_livestemst_to_livestemxf_acc_patch(p)
+ matrix_c13transfer_acc(ilivestem,ilivestem_xf) = cs13_veg%matrix_ctransfer_livestemxf_to_livestem_acc_patch(p)
+ matrix_c13transfer_acc(ideadstem_xf,ideadstem_st) = cs13_veg%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch(p)
+ matrix_c13transfer_acc(ideadstem,ideadstem_xf) = cs13_veg%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch(p)
+ matrix_c13transfer_acc(ilivecroot_xf,ilivecroot_st) = cs13_veg%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch(p)
+ matrix_c13transfer_acc(ilivecroot,ilivecroot_xf) = cs13_veg%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch(p)
+ matrix_c13transfer_acc(ideadcroot_xf,ideadcroot_st) = cs13_veg%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch(p)
+ matrix_c13transfer_acc(ideadcroot,ideadcroot_xf) = cs13_veg%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_c13transfer_acc(igrain_xf,igrain_st) = cs13_veg%matrix_ctransfer_grainst_to_grainxf_acc_patch(p)
+ matrix_c13transfer_acc(igrain,igrain_xf) = cs13_veg%matrix_ctransfer_grainxf_to_grain_acc_patch(p)
+ end if
+ matrix_c13transfer_acc(ideadstem,ilivestem) = cs13_veg%matrix_ctransfer_livestem_to_deadstem_acc_patch(p)
+ matrix_c13transfer_acc(ideadcroot,ilivecroot) = cs13_veg%matrix_ctransfer_livecroot_to_deadcroot_acc_patch(p)
+
+ matrix_c13transfer_acc(ileaf,ileaf) = -cs13_veg%matrix_cturnover_leaf_acc_patch(p)
+ matrix_c13transfer_acc(ileaf_st,ileaf_st) = -cs13_veg%matrix_cturnover_leafst_acc_patch(p)
+ matrix_c13transfer_acc(ileaf_xf,ileaf_xf) = -cs13_veg%matrix_cturnover_leafxf_acc_patch(p)
+ matrix_c13transfer_acc(ifroot,ifroot) = -cs13_veg%matrix_cturnover_froot_acc_patch(p)
+ matrix_c13transfer_acc(ifroot_st,ifroot_st) = -cs13_veg%matrix_cturnover_frootst_acc_patch(p)
+ matrix_c13transfer_acc(ifroot_xf,ifroot_xf) = -cs13_veg%matrix_cturnover_frootxf_acc_patch(p)
+ matrix_c13transfer_acc(ilivestem,ilivestem) = -cs13_veg%matrix_cturnover_livestem_acc_patch(p)
+ matrix_c13transfer_acc(ilivestem_st,ilivestem_st) = -cs13_veg%matrix_cturnover_livestemst_acc_patch(p)
+ matrix_c13transfer_acc(ilivestem_xf,ilivestem_xf) = -cs13_veg%matrix_cturnover_livestemxf_acc_patch(p)
+ matrix_c13transfer_acc(ideadstem,ideadstem) = -cs13_veg%matrix_cturnover_deadstem_acc_patch(p)
+ matrix_c13transfer_acc(ideadstem_st,ideadstem_st) = -cs13_veg%matrix_cturnover_deadstemst_acc_patch(p)
+ matrix_c13transfer_acc(ideadstem_xf,ideadstem_xf) = -cs13_veg%matrix_cturnover_deadstemxf_acc_patch(p)
+ matrix_c13transfer_acc(ilivecroot,ilivecroot) = -cs13_veg%matrix_cturnover_livecroot_acc_patch(p)
+ matrix_c13transfer_acc(ilivecroot_st,ilivecroot_st) = -cs13_veg%matrix_cturnover_livecrootst_acc_patch(p)
+ matrix_c13transfer_acc(ilivecroot_xf,ilivecroot_xf) = -cs13_veg%matrix_cturnover_livecrootxf_acc_patch(p)
+ matrix_c13transfer_acc(ideadcroot,ideadcroot) = -cs13_veg%matrix_cturnover_deadcroot_acc_patch(p)
+ matrix_c13transfer_acc(ideadcroot_st,ideadcroot_st) = -cs13_veg%matrix_cturnover_deadcrootst_acc_patch(p)
+ matrix_c13transfer_acc(ideadcroot_xf,ideadcroot_xf) = -cs13_veg%matrix_cturnover_deadcrootxf_acc_patch(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_c13transfer_acc(igrain,igrain) = -cs13_veg%matrix_cturnover_grain_acc_patch(p)
+ matrix_c13transfer_acc(igrain_st,igrain_st) = -cs13_veg%matrix_cturnover_grainst_acc_patch(p)
+ matrix_c13transfer_acc(igrain_xf,igrain_xf) = -cs13_veg%matrix_cturnover_grainxf_acc_patch(p)
+ end if
+ end if
+
+ if(use_c14)then
+ matrix_c14alloc_acc(ileaf) = cs14_veg%matrix_calloc_leaf_acc_patch(p)
+ matrix_c14alloc_acc(ileaf_st) = cs14_veg%matrix_calloc_leafst_acc_patch(p)
+ matrix_c14alloc_acc(ifroot) = cs14_veg%matrix_calloc_froot_acc_patch(p)
+ matrix_c14alloc_acc(ifroot_st) = cs14_veg%matrix_calloc_frootst_acc_patch(p)
+ matrix_c14alloc_acc(ilivestem) = cs14_veg%matrix_calloc_livestem_acc_patch(p)
+ matrix_c14alloc_acc(ilivestem_st) = cs14_veg%matrix_calloc_livestemst_acc_patch(p)
+ matrix_c14alloc_acc(ideadstem) = cs14_veg%matrix_calloc_deadstem_acc_patch(p)
+ matrix_c14alloc_acc(ideadstem_st) = cs14_veg%matrix_calloc_deadstemst_acc_patch(p)
+ matrix_c14alloc_acc(ilivecroot) = cs14_veg%matrix_calloc_livecroot_acc_patch(p)
+ matrix_c14alloc_acc(ilivecroot_st) = cs14_veg%matrix_calloc_livecrootst_acc_patch(p)
+ matrix_c14alloc_acc(ideadcroot) = cs14_veg%matrix_calloc_deadcroot_acc_patch(p)
+ matrix_c14alloc_acc(ideadcroot_st) = cs14_veg%matrix_calloc_deadcrootst_acc_patch(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_c14alloc_acc(igrain) = cs14_veg%matrix_calloc_grain_acc_patch(p)
+ matrix_c14alloc_acc(igrain_st) = cs14_veg%matrix_calloc_grainst_acc_patch(p)
+ end if
+
+ matrix_c14transfer_acc(ileaf_xf,ileaf_st) = cs14_veg%matrix_ctransfer_leafst_to_leafxf_acc_patch(p)
+ matrix_c14transfer_acc(ileaf,ileaf_xf) = cs14_veg%matrix_ctransfer_leafxf_to_leaf_acc_patch(p)
+ matrix_c14transfer_acc(ifroot_xf,ifroot_st) = cs14_veg%matrix_ctransfer_frootst_to_frootxf_acc_patch(p)
+ matrix_c14transfer_acc(ifroot,ifroot_xf) = cs14_veg%matrix_ctransfer_frootxf_to_froot_acc_patch(p)
+ matrix_c14transfer_acc(ilivestem_xf,ilivestem_st) = cs14_veg%matrix_ctransfer_livestemst_to_livestemxf_acc_patch(p)
+ matrix_c14transfer_acc(ilivestem,ilivestem_xf) = cs14_veg%matrix_ctransfer_livestemxf_to_livestem_acc_patch(p)
+ matrix_c14transfer_acc(ideadstem_xf,ideadstem_st) = cs14_veg%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch(p)
+ matrix_c14transfer_acc(ideadstem,ideadstem_xf) = cs14_veg%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch(p)
+ matrix_c14transfer_acc(ilivecroot_xf,ilivecroot_st) = cs14_veg%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch(p)
+ matrix_c14transfer_acc(ilivecroot,ilivecroot_xf) = cs14_veg%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch(p)
+ matrix_c14transfer_acc(ideadcroot_xf,ideadcroot_st) = cs14_veg%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch(p)
+ matrix_c14transfer_acc(ideadcroot,ideadcroot_xf) = cs14_veg%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_c14transfer_acc(igrain_xf,igrain_st) = cs14_veg%matrix_ctransfer_grainst_to_grainxf_acc_patch(p)
+ matrix_c14transfer_acc(igrain,igrain_xf) = cs14_veg%matrix_ctransfer_grainxf_to_grain_acc_patch(p)
+ end if
+ matrix_c14transfer_acc(ideadstem,ilivestem) = cs14_veg%matrix_ctransfer_livestem_to_deadstem_acc_patch(p)
+ matrix_c14transfer_acc(ideadcroot,ilivecroot) = cs14_veg%matrix_ctransfer_livecroot_to_deadcroot_acc_patch(p)
+
+ matrix_c14transfer_acc(ileaf,ileaf) = -cs14_veg%matrix_cturnover_leaf_acc_patch(p)
+ matrix_c14transfer_acc(ileaf_st,ileaf_st) = -cs14_veg%matrix_cturnover_leafst_acc_patch(p)
+ matrix_c14transfer_acc(ileaf_xf,ileaf_xf) = -cs14_veg%matrix_cturnover_leafxf_acc_patch(p)
+ matrix_c14transfer_acc(ifroot,ifroot) = -cs14_veg%matrix_cturnover_froot_acc_patch(p)
+ matrix_c14transfer_acc(ifroot_st,ifroot_st) = -cs14_veg%matrix_cturnover_frootst_acc_patch(p)
+ matrix_c14transfer_acc(ifroot_xf,ifroot_xf) = -cs14_veg%matrix_cturnover_frootxf_acc_patch(p)
+ matrix_c14transfer_acc(ilivestem,ilivestem) = -cs14_veg%matrix_cturnover_livestem_acc_patch(p)
+ matrix_c14transfer_acc(ilivestem_st,ilivestem_st) = -cs14_veg%matrix_cturnover_livestemst_acc_patch(p)
+ matrix_c14transfer_acc(ilivestem_xf,ilivestem_xf) = -cs14_veg%matrix_cturnover_livestemxf_acc_patch(p)
+ matrix_c14transfer_acc(ideadstem,ideadstem) = -cs14_veg%matrix_cturnover_deadstem_acc_patch(p)
+ matrix_c14transfer_acc(ideadstem_st,ideadstem_st) = -cs14_veg%matrix_cturnover_deadstemst_acc_patch(p)
+ matrix_c14transfer_acc(ideadstem_xf,ideadstem_xf) = -cs14_veg%matrix_cturnover_deadstemxf_acc_patch(p)
+ matrix_c14transfer_acc(ilivecroot,ilivecroot) = -cs14_veg%matrix_cturnover_livecroot_acc_patch(p)
+ matrix_c14transfer_acc(ilivecroot_st,ilivecroot_st) = -cs14_veg%matrix_cturnover_livecrootst_acc_patch(p)
+ matrix_c14transfer_acc(ilivecroot_xf,ilivecroot_xf) = -cs14_veg%matrix_cturnover_livecrootxf_acc_patch(p)
+ matrix_c14transfer_acc(ideadcroot,ideadcroot) = -cs14_veg%matrix_cturnover_deadcroot_acc_patch(p)
+ matrix_c14transfer_acc(ideadcroot_st,ideadcroot_st) = -cs14_veg%matrix_cturnover_deadcrootst_acc_patch(p)
+ matrix_c14transfer_acc(ideadcroot_xf,ideadcroot_xf) = -cs14_veg%matrix_cturnover_deadcrootxf_acc_patch(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_c14transfer_acc(igrain,igrain) = -cs14_veg%matrix_cturnover_grain_acc_patch(p)
+ matrix_c14transfer_acc(igrain_st,igrain_st) = -cs14_veg%matrix_cturnover_grainst_acc_patch(p)
+ matrix_c14transfer_acc(igrain_xf,igrain_xf) = -cs14_veg%matrix_cturnover_grainxf_acc_patch(p)
+ end if
+ end if
+
+ matrix_nalloc_acc(ileaf) = matrix_nalloc_leaf_acc(p)
+ matrix_nalloc_acc(ileaf_st) = matrix_nalloc_leafst_acc(p)
+ matrix_nalloc_acc(ifroot) = matrix_nalloc_froot_acc(p)
+ matrix_nalloc_acc(ifroot_st) = matrix_nalloc_frootst_acc(p)
+ matrix_nalloc_acc(ilivestem) = matrix_nalloc_livestem_acc(p)
+ matrix_nalloc_acc(ilivestem_st) = matrix_nalloc_livestemst_acc(p)
+ matrix_nalloc_acc(ideadstem) = matrix_nalloc_deadstem_acc(p)
+ matrix_nalloc_acc(ideadstem_st) = matrix_nalloc_deadstemst_acc(p)
+ matrix_nalloc_acc(ilivecroot) = matrix_nalloc_livecroot_acc(p)
+ matrix_nalloc_acc(ilivecroot_st) = matrix_nalloc_livecrootst_acc(p)
+ matrix_nalloc_acc(ideadcroot) = matrix_nalloc_deadcroot_acc(p)
+ matrix_nalloc_acc(ideadcroot_st) = matrix_nalloc_deadcrootst_acc(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_nalloc_acc(igrain) = matrix_nalloc_grain_acc(p)
+ matrix_nalloc_acc(igrain_st) = matrix_nalloc_grainst_acc(p)
+ end if
+
+ matrix_ntransfer_acc(ileaf_xf,ileaf_st) = matrix_ntransfer_leafst_to_leafxf_acc(p)
+ matrix_ntransfer_acc(ileaf,ileaf_xf) = matrix_ntransfer_leafxf_to_leaf_acc(p)
+ matrix_ntransfer_acc(ifroot_xf,ifroot_st) = matrix_ntransfer_frootst_to_frootxf_acc(p)
+ matrix_ntransfer_acc(ifroot,ifroot_xf) = matrix_ntransfer_frootxf_to_froot_acc(p)
+ matrix_ntransfer_acc(ilivestem_xf,ilivestem_st) = matrix_ntransfer_livestemst_to_livestemxf_acc(p)
+ matrix_ntransfer_acc(ilivestem,ilivestem_xf) = matrix_ntransfer_livestemxf_to_livestem_acc(p)
+ matrix_ntransfer_acc(ideadstem_xf,ideadstem_st) = matrix_ntransfer_deadstemst_to_deadstemxf_acc(p)
+ matrix_ntransfer_acc(ideadstem,ideadstem_xf) = matrix_ntransfer_deadstemxf_to_deadstem_acc(p)
+ matrix_ntransfer_acc(ilivecroot_xf,ilivecroot_st) = matrix_ntransfer_livecrootst_to_livecrootxf_acc(p)
+ matrix_ntransfer_acc(ilivecroot,ilivecroot_xf) = matrix_ntransfer_livecrootxf_to_livecroot_acc(p)
+ matrix_ntransfer_acc(ideadcroot_xf,ideadcroot_st) = matrix_ntransfer_deadcrootst_to_deadcrootxf_acc(p)
+ matrix_ntransfer_acc(ideadcroot,ideadcroot_xf) = matrix_ntransfer_deadcrootxf_to_deadcroot_acc(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_ntransfer_acc(igrain_xf,igrain_st) = matrix_ntransfer_grainst_to_grainxf_acc(p)
+ matrix_ntransfer_acc(igrain,igrain_xf) = matrix_ntransfer_grainxf_to_grain_acc(p)
+ end if
+ matrix_ntransfer_acc(ideadstem,ilivestem) = matrix_ntransfer_livestem_to_deadstem_acc(p)
+ matrix_ntransfer_acc(ideadcroot,ilivecroot) = matrix_ntransfer_livecroot_to_deadcroot_acc(p)
+
+ matrix_ntransfer_acc(ileaf,iretransn) = matrix_ntransfer_retransn_to_leaf_acc(p)
+ matrix_ntransfer_acc(ileaf_st,iretransn) = matrix_ntransfer_retransn_to_leafst_acc(p)
+ matrix_ntransfer_acc(ifroot,iretransn) = matrix_ntransfer_retransn_to_froot_acc(p)
+ matrix_ntransfer_acc(ifroot_st,iretransn) = matrix_ntransfer_retransn_to_frootst_acc(p)
+ matrix_ntransfer_acc(ilivestem,iretransn) = matrix_ntransfer_retransn_to_livestem_acc(p)
+ matrix_ntransfer_acc(ilivestem_st,iretransn) = matrix_ntransfer_retransn_to_livestemst_acc(p)
+ matrix_ntransfer_acc(ideadstem,iretransn) = matrix_ntransfer_retransn_to_deadstem_acc(p)
+ matrix_ntransfer_acc(ideadstem_st,iretransn) = matrix_ntransfer_retransn_to_deadstemst_acc(p)
+ matrix_ntransfer_acc(ilivecroot,iretransn) = matrix_ntransfer_retransn_to_livecroot_acc(p)
+ matrix_ntransfer_acc(ilivecroot_st,iretransn) = matrix_ntransfer_retransn_to_livecrootst_acc(p)
+ matrix_ntransfer_acc(ideadcroot,iretransn) = matrix_ntransfer_retransn_to_deadcroot_acc(p)
+ matrix_ntransfer_acc(ideadcroot_st,iretransn) = matrix_ntransfer_retransn_to_deadcrootst_acc(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_ntransfer_acc(igrain,iretransn) = matrix_ntransfer_retransn_to_grain_acc(p)
+ matrix_ntransfer_acc(igrain_st,iretransn) = matrix_ntransfer_retransn_to_grainst_acc(p)
+ end if
+ matrix_ntransfer_acc(iretransn,ileaf) = matrix_ntransfer_leaf_to_retransn_acc(p)
+ matrix_ntransfer_acc(iretransn,ifroot) = matrix_ntransfer_froot_to_retransn_acc(p)
+ matrix_ntransfer_acc(iretransn,ilivestem) = matrix_ntransfer_livestem_to_retransn_acc(p)
+ matrix_ntransfer_acc(iretransn,ilivecroot) = matrix_ntransfer_livecroot_to_retransn_acc(p)
+
+ matrix_ntransfer_acc(ileaf,ileaf) = -matrix_nturnover_leaf_acc(p)
+ matrix_ntransfer_acc(ileaf_st,ileaf_st) = -matrix_nturnover_leafst_acc(p)
+ matrix_ntransfer_acc(ileaf_xf,ileaf_xf) = -matrix_nturnover_leafxf_acc(p)
+ matrix_ntransfer_acc(ifroot,ifroot) = -matrix_nturnover_froot_acc(p)
+ matrix_ntransfer_acc(ifroot_st,ifroot_st) = -matrix_nturnover_frootst_acc(p)
+ matrix_ntransfer_acc(ifroot_xf,ifroot_xf) = -matrix_nturnover_frootxf_acc(p)
+ matrix_ntransfer_acc(ilivestem,ilivestem) = -matrix_nturnover_livestem_acc(p)
+ matrix_ntransfer_acc(ilivestem_st,ilivestem_st) = -matrix_nturnover_livestemst_acc(p)
+ matrix_ntransfer_acc(ilivestem_xf,ilivestem_xf) = -matrix_nturnover_livestemxf_acc(p)
+ matrix_ntransfer_acc(ideadstem,ideadstem) = -matrix_nturnover_deadstem_acc(p)
+ matrix_ntransfer_acc(ideadstem_st,ideadstem_st) = -matrix_nturnover_deadstemst_acc(p)
+ matrix_ntransfer_acc(ideadstem_xf,ideadstem_xf) = -matrix_nturnover_deadstemxf_acc(p)
+ matrix_ntransfer_acc(ilivecroot,ilivecroot) = -matrix_nturnover_livecroot_acc(p)
+ matrix_ntransfer_acc(ilivecroot_st,ilivecroot_st) = -matrix_nturnover_livecrootst_acc(p)
+ matrix_ntransfer_acc(ilivecroot_xf,ilivecroot_xf) = -matrix_nturnover_livecrootxf_acc(p)
+ matrix_ntransfer_acc(ideadcroot,ideadcroot) = -matrix_nturnover_deadcroot_acc(p)
+ matrix_ntransfer_acc(ideadcroot_st,ideadcroot_st) = -matrix_nturnover_deadcrootst_acc(p)
+ matrix_ntransfer_acc(ideadcroot_xf,ideadcroot_xf) = -matrix_nturnover_deadcrootxf_acc(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_ntransfer_acc(igrain,igrain) = -matrix_nturnover_grain_acc(p)
+ matrix_ntransfer_acc(igrain_st,igrain_st) = -matrix_nturnover_grainst_acc(p)
+ matrix_ntransfer_acc(igrain_xf,igrain_xf) = -matrix_nturnover_grainxf_acc(p)
+ end if
+ matrix_ntransfer_acc(iretransn,iretransn) = -matrix_nturnover_retransn_acc(p)
+
+ do i=1,nvegcpool
+ if(matrix_ctransfer_acc(i,i) == 0)then
+ matrix_ctransfer_acc(i,i) = spval
+ end if
+ end do
+ if(use_c13)then
+ do i=1,nvegcpool
+ if(matrix_c13transfer_acc(i,i) == 0)then
+ matrix_c13transfer_acc(i,i) = spval
+ end if
+ end do
+ end if
+ if(use_c14)then
+ do i=1,nvegcpool
+ if(matrix_c14transfer_acc(i,i) == 0)then
+ matrix_c14transfer_acc(i,i) = spval
+ end if
+ end do
+ end if
+ do i=1,nvegnpool
+ if(matrix_ntransfer_acc(i,i) == 0)then
+ matrix_ntransfer_acc(i,i) = spval
+ end if
+ end do
+
+ ! Calculate the transfer rate based on the initial value of the calendar year.
+ matrix_ctransfer_acc(1:nvegcpool,ileaf) = matrix_ctransfer_acc(1:nvegcpool,ileaf) / leafc0(p)
+ matrix_ctransfer_acc(1:nvegcpool,ileaf_st) = matrix_ctransfer_acc(1:nvegcpool,ileaf_st) / leafc0_storage(p)
+ matrix_ctransfer_acc(1:nvegcpool,ileaf_xf) = matrix_ctransfer_acc(1:nvegcpool,ileaf_xf) / leafc0_xfer(p)
+ matrix_ctransfer_acc(1:nvegcpool,ifroot) = matrix_ctransfer_acc(1:nvegcpool,ifroot) / frootc0(p)
+ matrix_ctransfer_acc(1:nvegcpool,ifroot_st) = matrix_ctransfer_acc(1:nvegcpool,ifroot_st) / frootc0_storage(p)
+ matrix_ctransfer_acc(1:nvegcpool,ifroot_xf) = matrix_ctransfer_acc(1:nvegcpool,ifroot_xf) / frootc0_xfer(p)
+ matrix_ctransfer_acc(1:nvegcpool,ilivestem) = matrix_ctransfer_acc(1:nvegcpool,ilivestem) / livestemc0(p)
+ matrix_ctransfer_acc(1:nvegcpool,ilivestem_st) = matrix_ctransfer_acc(1:nvegcpool,ilivestem_st) / livestemc0_storage(p)
+ matrix_ctransfer_acc(1:nvegcpool,ilivestem_xf) = matrix_ctransfer_acc(1:nvegcpool,ilivestem_xf) / livestemc0_xfer(p)
+ matrix_ctransfer_acc(1:nvegcpool,ideadstem) = matrix_ctransfer_acc(1:nvegcpool,ideadstem) / deadstemc0(p)
+ matrix_ctransfer_acc(1:nvegcpool,ideadstem_st) = matrix_ctransfer_acc(1:nvegcpool,ideadstem_st) / deadstemc0_storage(p)
+ matrix_ctransfer_acc(1:nvegcpool,ideadstem_xf) = matrix_ctransfer_acc(1:nvegcpool,ideadstem_xf) / deadstemc0_xfer(p)
+ matrix_ctransfer_acc(1:nvegcpool,ilivecroot) = matrix_ctransfer_acc(1:nvegcpool,ilivecroot) / livecrootc0(p)
+ matrix_ctransfer_acc(1:nvegcpool,ilivecroot_st) = matrix_ctransfer_acc(1:nvegcpool,ilivecroot_st) / livecrootc0_storage(p)
+ matrix_ctransfer_acc(1:nvegcpool,ilivecroot_xf) = matrix_ctransfer_acc(1:nvegcpool,ilivecroot_xf) / livecrootc0_xfer(p)
+ matrix_ctransfer_acc(1:nvegcpool,ideadcroot) = matrix_ctransfer_acc(1:nvegcpool,ideadcroot) / deadcrootc0(p)
+ matrix_ctransfer_acc(1:nvegcpool,ideadcroot_st) = matrix_ctransfer_acc(1:nvegcpool,ideadcroot_st) / deadcrootc0_storage(p)
+ matrix_ctransfer_acc(1:nvegcpool,ideadcroot_xf) = matrix_ctransfer_acc(1:nvegcpool,ideadcroot_xf) / deadcrootc0_xfer(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_ctransfer_acc(1:nvegcpool,igrain) = matrix_ctransfer_acc(1:nvegcpool,igrain) / reproc0(p)
+ matrix_ctransfer_acc(1:nvegcpool,igrain_st) = matrix_ctransfer_acc(1:nvegcpool,igrain_st) / reproc0_storage(p)
+ matrix_ctransfer_acc(1:nvegcpool,igrain_xf) = matrix_ctransfer_acc(1:nvegcpool,igrain_xf) / reproc0_xfer(p)
+ end if
+
+ if(use_c13)then
+ matrix_c13transfer_acc(1:nvegcpool,ileaf) = matrix_c13transfer_acc(1:nvegcpool,ileaf) / cs13_veg%leafc0_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ileaf_st) = matrix_c13transfer_acc(1:nvegcpool,ileaf_st) / cs13_veg%leafc0_storage_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ileaf_xf) = matrix_c13transfer_acc(1:nvegcpool,ileaf_xf) / cs13_veg%leafc0_xfer_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ifroot) = matrix_c13transfer_acc(1:nvegcpool,ifroot) / cs13_veg%frootc0_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ifroot_st) = matrix_c13transfer_acc(1:nvegcpool,ifroot_st) / cs13_veg%frootc0_storage_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ifroot_xf) = matrix_c13transfer_acc(1:nvegcpool,ifroot_xf) / cs13_veg%frootc0_xfer_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ilivestem) = matrix_c13transfer_acc(1:nvegcpool,ilivestem) / cs13_veg%livestemc0_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ilivestem_st) = matrix_c13transfer_acc(1:nvegcpool,ilivestem_st) / cs13_veg%livestemc0_storage_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ilivestem_xf) = matrix_c13transfer_acc(1:nvegcpool,ilivestem_xf) / cs13_veg%livestemc0_xfer_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ideadstem) = matrix_c13transfer_acc(1:nvegcpool,ideadstem) / cs13_veg%deadstemc0_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ideadstem_st) = matrix_c13transfer_acc(1:nvegcpool,ideadstem_st) / cs13_veg%deadstemc0_storage_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ideadstem_xf) = matrix_c13transfer_acc(1:nvegcpool,ideadstem_xf) / cs13_veg%deadstemc0_xfer_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ilivecroot) = matrix_c13transfer_acc(1:nvegcpool,ilivecroot) / cs13_veg%livecrootc0_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ilivecroot_st) = matrix_c13transfer_acc(1:nvegcpool,ilivecroot_st) / cs13_veg%livecrootc0_storage_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ilivecroot_xf) = matrix_c13transfer_acc(1:nvegcpool,ilivecroot_xf) / cs13_veg%livecrootc0_xfer_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ideadcroot) = matrix_c13transfer_acc(1:nvegcpool,ideadcroot) / cs13_veg%deadcrootc0_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ideadcroot_st) = matrix_c13transfer_acc(1:nvegcpool,ideadcroot_st) / cs13_veg%deadcrootc0_storage_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ideadcroot_xf) = matrix_c13transfer_acc(1:nvegcpool,ideadcroot_xf) / cs13_veg%deadcrootc0_xfer_patch(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_c13transfer_acc(1:nvegcpool,igrain) = matrix_c13transfer_acc(1:nvegcpool,igrain) / cs13_veg%reproc0_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,igrain_st) = matrix_c13transfer_acc(1:nvegcpool,igrain_st) / cs13_veg%reproc0_storage_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,igrain_xf) = matrix_c13transfer_acc(1:nvegcpool,igrain_xf) / cs13_veg%reproc0_xfer_patch(p)
+ end if
+ end if
+
+ if(use_c14)then
+ matrix_c14transfer_acc(1:nvegcpool,ileaf) = matrix_c14transfer_acc(1:nvegcpool,ileaf) / cs14_veg%leafc0_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ileaf_st) = matrix_c14transfer_acc(1:nvegcpool,ileaf_st) / cs14_veg%leafc0_storage_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ileaf_xf) = matrix_c14transfer_acc(1:nvegcpool,ileaf_xf) / cs14_veg%leafc0_xfer_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ifroot) = matrix_c14transfer_acc(1:nvegcpool,ifroot) / cs14_veg%frootc0_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ifroot_st) = matrix_c14transfer_acc(1:nvegcpool,ifroot_st) / cs14_veg%frootc0_storage_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ifroot_xf) = matrix_c14transfer_acc(1:nvegcpool,ifroot_xf) / cs14_veg%frootc0_xfer_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ilivestem) = matrix_c14transfer_acc(1:nvegcpool,ilivestem) / cs14_veg%livestemc0_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ilivestem_st) = matrix_c14transfer_acc(1:nvegcpool,ilivestem_st) / cs14_veg%livestemc0_storage_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ilivestem_xf) = matrix_c14transfer_acc(1:nvegcpool,ilivestem_xf) / cs14_veg%livestemc0_xfer_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ideadstem) = matrix_c14transfer_acc(1:nvegcpool,ideadstem) / cs14_veg%deadstemc0_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ideadstem_st) = matrix_c14transfer_acc(1:nvegcpool,ideadstem_st) / cs14_veg%deadstemc0_storage_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ideadstem_xf) = matrix_c14transfer_acc(1:nvegcpool,ideadstem_xf) / cs14_veg%deadstemc0_xfer_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ilivecroot) = matrix_c14transfer_acc(1:nvegcpool,ilivecroot) / cs14_veg%livecrootc0_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ilivecroot_st) = matrix_c14transfer_acc(1:nvegcpool,ilivecroot_st) / cs14_veg%livecrootc0_storage_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ilivecroot_xf) = matrix_c14transfer_acc(1:nvegcpool,ilivecroot_xf) / cs14_veg%livecrootc0_xfer_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ideadcroot) = matrix_c14transfer_acc(1:nvegcpool,ideadcroot) / cs14_veg%deadcrootc0_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ideadcroot_st) = matrix_c14transfer_acc(1:nvegcpool,ideadcroot_st) / cs14_veg%deadcrootc0_storage_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ideadcroot_xf) = matrix_c14transfer_acc(1:nvegcpool,ideadcroot_xf) / cs14_veg%deadcrootc0_xfer_patch(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_c14transfer_acc(1:nvegcpool,igrain) = matrix_c14transfer_acc(1:nvegcpool,igrain) / cs14_veg%reproc0_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,igrain_st) = matrix_c14transfer_acc(1:nvegcpool,igrain_st) / cs14_veg%reproc0_storage_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,igrain_xf) = matrix_c14transfer_acc(1:nvegcpool,igrain_xf) / cs14_veg%reproc0_xfer_patch(p)
+ end if
+ end if
+
+ matrix_ntransfer_acc(1:nvegnpool,ileaf) = matrix_ntransfer_acc(1:nvegnpool,ileaf) / leafn0(p)
+ matrix_ntransfer_acc(1:nvegnpool,ileaf_st) = matrix_ntransfer_acc(1:nvegnpool,ileaf_st) / leafn0_storage(p)
+ matrix_ntransfer_acc(1:nvegnpool,ileaf_xf) = matrix_ntransfer_acc(1:nvegnpool,ileaf_xf) / leafn0_xfer(p)
+ matrix_ntransfer_acc(1:nvegnpool,ifroot) = matrix_ntransfer_acc(1:nvegnpool,ifroot) / frootn0(p)
+ matrix_ntransfer_acc(1:nvegnpool,ifroot_st) = matrix_ntransfer_acc(1:nvegnpool,ifroot_st) / frootn0_storage(p)
+ matrix_ntransfer_acc(1:nvegnpool,ifroot_xf) = matrix_ntransfer_acc(1:nvegnpool,ifroot_xf) / frootn0_xfer(p)
+ matrix_ntransfer_acc(1:nvegnpool,ilivestem) = matrix_ntransfer_acc(1:nvegnpool,ilivestem) / livestemn0(p)
+ matrix_ntransfer_acc(1:nvegnpool,ilivestem_st) = matrix_ntransfer_acc(1:nvegnpool,ilivestem_st) / livestemn0_storage(p)
+ matrix_ntransfer_acc(1:nvegnpool,ilivestem_xf) = matrix_ntransfer_acc(1:nvegnpool,ilivestem_xf) / livestemn0_xfer(p)
+ matrix_ntransfer_acc(1:nvegnpool,ideadstem) = matrix_ntransfer_acc(1:nvegnpool,ideadstem) / deadstemn0(p)
+ matrix_ntransfer_acc(1:nvegnpool,ideadstem_st) = matrix_ntransfer_acc(1:nvegnpool,ideadstem_st) / deadstemn0_storage(p)
+ matrix_ntransfer_acc(1:nvegnpool,ideadstem_xf) = matrix_ntransfer_acc(1:nvegnpool,ideadstem_xf) / deadstemn0_xfer(p)
+ matrix_ntransfer_acc(1:nvegnpool,ilivecroot) = matrix_ntransfer_acc(1:nvegnpool,ilivecroot) / livecrootn0(p)
+ matrix_ntransfer_acc(1:nvegnpool,ilivecroot_st) = matrix_ntransfer_acc(1:nvegnpool,ilivecroot_st) / livecrootn0_storage(p)
+ matrix_ntransfer_acc(1:nvegnpool,ilivecroot_xf) = matrix_ntransfer_acc(1:nvegnpool,ilivecroot_xf) / livecrootn0_xfer(p)
+ matrix_ntransfer_acc(1:nvegnpool,ideadcroot) = matrix_ntransfer_acc(1:nvegnpool,ideadcroot) / deadcrootn0(p)
+ matrix_ntransfer_acc(1:nvegnpool,ideadcroot_st) = matrix_ntransfer_acc(1:nvegnpool,ideadcroot_st) / deadcrootn0_storage(p)
+ matrix_ntransfer_acc(1:nvegnpool,ideadcroot_xf) = matrix_ntransfer_acc(1:nvegnpool,ideadcroot_xf) / deadcrootn0_xfer(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_ntransfer_acc(1:nvegnpool,igrain) = matrix_ntransfer_acc(1:nvegnpool,igrain) / repron0(p)
+ matrix_ntransfer_acc(1:nvegnpool,igrain_st) = matrix_ntransfer_acc(1:nvegnpool,igrain_st) / repron0_storage(p)
+ matrix_ntransfer_acc(1:nvegnpool,igrain_xf) = matrix_ntransfer_acc(1:nvegnpool,igrain_xf) / repron0_xfer(p)
+ end if
+ matrix_ntransfer_acc(1:nvegnpool,iretransn) = matrix_ntransfer_acc(1:nvegnpool,iretransn) / retransn0(p)
+
+ call t_stopf('CN veg matrix-prepare AK^-1')
+ call t_startf('CN veg matrix-inv matrix operation')
+
+ ! Calculate the residence time and C storage capacity
+ call inverse(matrix_ctransfer_acc(1:nvegcpool,1:nvegcpool),AKinvc(1:nvegcpool,1:nvegcpool),nvegcpool)
+ vegmatrixc_rt(:) = -matmul(AKinvc(1:nvegcpool,1:nvegcpool),matrix_calloc_acc(1:nvegcpool))
+
+ ! Calculate the residence time and C13 storage capacity
+ if(use_c13)then
+ call inverse(matrix_c13transfer_acc(1:nvegcpool,1:nvegcpool),AKinvc(1:nvegcpool,1:nvegcpool),nvegcpool)
+ vegmatrixc13_rt(:) = -matmul(AKinvc(1:nvegcpool,1:nvegcpool),matrix_c13alloc_acc(1:nvegcpool))
+ end if
+
+ ! Calculate the residence time and C14 storage capacity
+ if(use_c14)then
+ call inverse(matrix_c14transfer_acc(1:nvegcpool,1:nvegcpool),AKinvc(1:nvegcpool,1:nvegcpool),nvegcpool)
+ vegmatrixc14_rt(:) = -matmul(AKinvc(1:nvegcpool,1:nvegcpool),matrix_c14alloc_acc(1:nvegcpool))
+ end if
+
+ ! Calculate the residence time and N storage capacity
+ call inverse(matrix_ntransfer_acc(1:nvegnpool,1:nvegnpool),AKinvn(1:nvegnpool,1:nvegnpool),nvegnpool)
+ vegmatrixn_rt(:) = -matmul(AKinvn(1:nvegnpool,1:nvegnpool),matrix_nalloc_acc(1:nvegnpool))
+
+ do i=1,nvegcpool
+ if(vegmatrixc_rt(i) .lt. 0)vegmatrixc_rt(i) = epsi
+ end do
+ if(use_c13)then
+ do i=1,nvegcpool
+ if(vegmatrixc13_rt(i) .lt. 0)vegmatrixc13_rt(i) = epsi
+ end do
+ end if
+ if(use_c14)then
+ do i=1,nvegcpool
+ if(vegmatrixc14_rt(i) .lt. 0)vegmatrixc14_rt(i) = epsi
+ end do
+ end if
+ do i=1,nvegnpool
+ if(vegmatrixn_rt(i) .lt. 0)vegmatrixn_rt(i) = epsi
+ end do
+
+ call t_stopf('CN veg matrix-inv matrix operation')
+
+ call t_startf('CN veg matrix-finalize spinup')
+
+ if(spinup_matrixcn .and. .not. is_first_step_of_this_run_segment())then
+ deadstemc(p) = vegmatrixc_rt(ideadstem)
+ deadstemc_storage(p) = vegmatrixc_rt(ideadstem_st)
+ deadcrootc(p) = vegmatrixc_rt(ideadcroot)
+ deadcrootc_storage(p) = vegmatrixc_rt(ideadcroot_st)
+ if(use_c13)then
+ cs13_veg%deadstemc_patch(p) = vegmatrixc13_rt(ideadstem)
+ cs13_veg%deadstemc_storage_patch(p) = vegmatrixc13_rt(ideadstem_st)
+ cs13_veg%deadcrootc_patch(p) = vegmatrixc13_rt(ideadcroot)
+ cs13_veg%deadcrootc_storage_patch(p) = vegmatrixc13_rt(ideadcroot_st)
+ end if
+ if(use_c14)then
+ cs14_veg%deadstemc_patch(p) = vegmatrixc14_rt(ideadstem)
+ cs14_veg%deadstemc_storage_patch(p) = vegmatrixc14_rt(ideadstem_st)
+ cs14_veg%deadcrootc_patch(p) = vegmatrixc14_rt(ideadcroot)
+ cs14_veg%deadcrootc_storage_patch(p) = vegmatrixc14_rt(ideadcroot_st)
+ end if
+ deadstemn(p) = vegmatrixn_rt(ideadstem)
+ deadstemn_storage(p) = vegmatrixn_rt(ideadstem_st)
+ deadcrootn(p) = vegmatrixn_rt(ideadcroot)
+ deadcrootn_storage(p) = vegmatrixn_rt(ideadcroot_st)
+
+ if(iloop .eq. iloop_avg)then
+ leafc_SASUsave(p) = leafc_SASUsave(p) + leafc(p)
+ leafc_storage_SASUsave(p) = leafc_storage_SASUsave(p) + leafc_storage(p)
+ leafc_xfer_SASUsave(p) = leafc_xfer_SASUsave(p) + leafc_xfer(p)
+ frootc_SASUsave(p) = frootc_SASUsave(p) + frootc(p)
+ frootc_storage_SASUsave(p) = frootc_storage_SASUsave(p) + frootc_storage(p)
+ frootc_xfer_SASUsave(p) = frootc_xfer_SASUsave(p) + frootc_xfer(p)
+ livestemc_SASUsave(p) = livestemc_SASUsave(p) + livestemc(p)
+ livestemc_storage_SASUsave(p) = livestemc_storage_SASUsave(p) + livestemc_storage(p)
+ livestemc_xfer_SASUsave(p) = livestemc_xfer_SASUsave(p) + livestemc_xfer(p)
+ deadstemc_SASUsave(p) = deadstemc_SASUsave(p) + deadstemc(p)
+ deadstemc_storage_SASUsave(p) = deadstemc_storage_SASUsave(p) + deadstemc_storage(p)
+ deadstemc_xfer_SASUsave(p) = deadstemc_xfer_SASUsave(p) + deadstemc_xfer(p)
+ livecrootc_SASUsave(p) = livecrootc_SASUsave(p) + livecrootc(p)
+ livecrootc_storage_SASUsave(p) = livecrootc_storage_SASUsave(p) + livecrootc_storage(p)
+ livecrootc_xfer_SASUsave(p) = livecrootc_xfer_SASUsave(p) + livecrootc_xfer(p)
+ deadcrootc_SASUsave(p) = deadcrootc_SASUsave(p) + deadcrootc(p)
+ deadcrootc_storage_SASUsave(p) = deadcrootc_storage_SASUsave(p) + deadcrootc_storage(p)
+ deadcrootc_xfer_SASUsave(p) = deadcrootc_xfer_SASUsave(p) + deadcrootc_xfer(p)
+ if(ivt(p) >= npcropmin)then
+ grainc_SASUsave(p) = grainc_SASUsave(p) + sum(reproductivec(p,:))
+ grainc_storage_SASUsave(p) = grainc_storage_SASUsave(p) + sum(reproductivec_storage(p,:))
+ end if
+ if(use_c13)then
+ cs13_veg%leafc_SASUsave_patch(p) = cs13_veg%leafc_SASUsave_patch(p) + cs13_veg%leafc_patch(p)
+ cs13_veg%leafc_storage_SASUsave_patch(p) = cs13_veg%leafc_storage_SASUsave_patch(p) + cs13_veg%leafc_storage_patch(p)
+ cs13_veg%leafc_xfer_SASUsave_patch(p) = cs13_veg%leafc_xfer_SASUsave_patch(p) + cs13_veg%leafc_xfer_patch(p)
+ cs13_veg%frootc_SASUsave_patch(p) = cs13_veg%frootc_SASUsave_patch(p) + cs13_veg%frootc_patch(p)
+ cs13_veg%frootc_storage_SASUsave_patch(p) = cs13_veg%frootc_storage_SASUsave_patch(p) + cs13_veg%frootc_storage_patch(p)
+ cs13_veg%frootc_xfer_SASUsave_patch(p) = cs13_veg%frootc_xfer_SASUsave_patch(p) + cs13_veg%frootc_xfer_patch(p)
+ cs13_veg%livestemc_SASUsave_patch(p) = cs13_veg%livestemc_SASUsave_patch(p) + cs13_veg%livestemc_patch(p)
+ cs13_veg%livestemc_storage_SASUsave_patch(p) = cs13_veg%livestemc_storage_SASUsave_patch(p) + cs13_veg%livestemc_storage_patch(p)
+ cs13_veg%livestemc_xfer_SASUsave_patch(p) = cs13_veg%livestemc_xfer_SASUsave_patch(p) + cs13_veg%livestemc_xfer_patch(p)
+ cs13_veg%deadstemc_SASUsave_patch(p) = cs13_veg%deadstemc_SASUsave_patch(p) + cs13_veg%deadstemc_patch(p)
+ cs13_veg%deadstemc_storage_SASUsave_patch(p) = cs13_veg%deadstemc_storage_SASUsave_patch(p) + cs13_veg%deadstemc_storage_patch(p)
+ cs13_veg%deadstemc_xfer_SASUsave_patch(p) = cs13_veg%deadstemc_xfer_SASUsave_patch(p) + cs13_veg%deadstemc_xfer_patch(p)
+ cs13_veg%livecrootc_SASUsave_patch(p) = cs13_veg%livecrootc_SASUsave_patch(p) + cs13_veg%livecrootc_patch(p)
+ cs13_veg%livecrootc_storage_SASUsave_patch(p) = cs13_veg%livecrootc_storage_SASUsave_patch(p) + cs13_veg%livecrootc_storage_patch(p)
+ cs13_veg%livecrootc_xfer_SASUsave_patch(p) = cs13_veg%livecrootc_xfer_SASUsave_patch(p) + cs13_veg%livecrootc_xfer_patch(p)
+ cs13_veg%deadcrootc_SASUsave_patch(p) = cs13_veg%deadcrootc_SASUsave_patch(p) + cs13_veg%deadcrootc_patch(p)
+ cs13_veg%deadcrootc_storage_SASUsave_patch(p) = cs13_veg%deadcrootc_storage_SASUsave_patch(p) + cs13_veg%deadcrootc_storage_patch(p)
+ cs13_veg%deadcrootc_xfer_SASUsave_patch(p) = cs13_veg%deadcrootc_xfer_SASUsave_patch(p) + cs13_veg%deadcrootc_xfer_patch(p)
+ if(ivt(p) >= npcropmin)then
+ cs13_veg%grainc_SASUsave_patch(p) = cs13_veg%grainc_SASUsave_patch(p) + cs13_veg%reproductivec_patch(p,irepr)
+ cs13_veg%grainc_storage_SASUsave_patch(p) = cs13_veg%grainc_storage_SASUsave_patch(p) + cs13_veg%reproductivec_storage_patch(p,irepr)
+ end if
+ end if
+ if(use_c14)then
+ cs14_veg%leafc_SASUsave_patch(p) = cs14_veg%leafc_SASUsave_patch(p) + cs14_veg%leafc_patch(p)
+ cs14_veg%leafc_storage_SASUsave_patch(p) = cs14_veg%leafc_storage_SASUsave_patch(p) + cs14_veg%leafc_storage_patch(p)
+ cs14_veg%leafc_xfer_SASUsave_patch(p) = cs14_veg%leafc_xfer_SASUsave_patch(p) + cs14_veg%leafc_xfer_patch(p)
+ cs14_veg%frootc_SASUsave_patch(p) = cs14_veg%frootc_SASUsave_patch(p) + cs14_veg%frootc_patch(p)
+ cs14_veg%frootc_storage_SASUsave_patch(p) = cs14_veg%frootc_storage_SASUsave_patch(p) + cs14_veg%frootc_storage_patch(p)
+ cs14_veg%frootc_xfer_SASUsave_patch(p) = cs14_veg%frootc_xfer_SASUsave_patch(p) + cs14_veg%frootc_xfer_patch(p)
+ cs14_veg%livestemc_SASUsave_patch(p) = cs14_veg%livestemc_SASUsave_patch(p) + cs14_veg%livestemc_patch(p)
+ cs14_veg%livestemc_storage_SASUsave_patch(p) = cs14_veg%livestemc_storage_SASUsave_patch(p) + cs14_veg%livestemc_storage_patch(p)
+ cs14_veg%livestemc_xfer_SASUsave_patch(p) = cs14_veg%livestemc_xfer_SASUsave_patch(p) + cs14_veg%livestemc_xfer_patch(p)
+ cs14_veg%deadstemc_SASUsave_patch(p) = cs14_veg%deadstemc_SASUsave_patch(p) + cs14_veg%deadstemc_patch(p)
+ cs14_veg%deadstemc_storage_SASUsave_patch(p) = cs14_veg%deadstemc_storage_SASUsave_patch(p) + cs14_veg%deadstemc_storage_patch(p)
+ cs14_veg%deadstemc_xfer_SASUsave_patch(p) = cs14_veg%deadstemc_xfer_SASUsave_patch(p) + cs14_veg%deadstemc_xfer_patch(p)
+ cs14_veg%livecrootc_SASUsave_patch(p) = cs14_veg%livecrootc_SASUsave_patch(p) + cs14_veg%livecrootc_patch(p)
+ cs14_veg%livecrootc_storage_SASUsave_patch(p) = cs14_veg%livecrootc_storage_SASUsave_patch(p) + cs14_veg%livecrootc_storage_patch(p)
+ cs14_veg%livecrootc_xfer_SASUsave_patch(p) = cs14_veg%livecrootc_xfer_SASUsave_patch(p) + cs14_veg%livecrootc_xfer_patch(p)
+ cs14_veg%deadcrootc_SASUsave_patch(p) = cs14_veg%deadcrootc_SASUsave_patch(p) + cs14_veg%deadcrootc_patch(p)
+ cs14_veg%deadcrootc_storage_SASUsave_patch(p) = cs14_veg%deadcrootc_storage_SASUsave_patch(p) + cs14_veg%deadcrootc_storage_patch(p)
+ cs14_veg%deadcrootc_xfer_SASUsave_patch(p) = cs14_veg%deadcrootc_xfer_SASUsave_patch(p) + cs14_veg%deadcrootc_xfer_patch(p)
+ if(ivt(p) >= npcropmin)then
+ cs14_veg%grainc_SASUsave_patch(p) = cs14_veg%grainc_SASUsave_patch(p) + cs14_veg%reproductivec_patch(p,irepr)
+ cs14_veg%grainc_storage_SASUsave_patch(p) = cs14_veg%grainc_storage_SASUsave_patch(p) + cs14_veg%reproductivec_storage_patch(p,irepr)
+ end if
+ end if
+ leafn_SASUsave(p) = leafn_SASUsave(p) + leafn(p)
+ leafn_storage_SASUsave(p) = leafn_storage_SASUsave(p) + leafn_storage(p)
+ leafn_xfer_SASUsave(p) = leafn_xfer_SASUsave(p) + leafn_xfer(p)
+ frootn_SASUsave(p) = frootn_SASUsave(p) + frootn(p)
+ frootn_storage_SASUsave(p) = frootn_storage_SASUsave(p) + frootn_storage(p)
+ frootn_xfer_SASUsave(p) = frootn_xfer_SASUsave(p) + frootn_xfer(p)
+ livestemn_SASUsave(p) = livestemn_SASUsave(p) + livestemn(p)
+ livestemn_storage_SASUsave(p) = livestemn_storage_SASUsave(p) + livestemn_storage(p)
+ livestemn_xfer_SASUsave(p) = livestemn_xfer_SASUsave(p) + livestemn_xfer(p)
+ deadstemn_SASUsave(p) = deadstemn_SASUsave(p) + deadstemn(p)
+ deadstemn_storage_SASUsave(p) = deadstemn_storage_SASUsave(p) + deadstemn_storage(p)
+ deadstemn_xfer_SASUsave(p) = deadstemn_xfer_SASUsave(p) + deadstemn_xfer(p)
+ livecrootn_SASUsave(p) = livecrootn_SASUsave(p) + livecrootn(p)
+ livecrootn_storage_SASUsave(p) = livecrootn_storage_SASUsave(p) + livecrootn_storage(p)
+ livecrootn_xfer_SASUsave(p) = livecrootn_xfer_SASUsave(p) + livecrootn_xfer(p)
+ deadcrootn_SASUsave(p) = deadcrootn_SASUsave(p) + deadcrootn(p)
+ deadcrootn_storage_SASUsave(p) = deadcrootn_storage_SASUsave(p) + deadcrootn_storage(p)
+ deadcrootn_xfer_SASUsave(p) = deadcrootn_xfer_SASUsave(p) + deadcrootn_xfer(p)
+ if(ivt(p) >= npcropmin)then
+ grainn_SASUsave(p) = grainn_SASUsave(p) + reproductiven(p,irepr)
+ end if
+ if(iyr .eq. nyr_forcing)then
+ leafc(p) = leafc_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ leafc_storage(p) = leafc_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ leafc_xfer(p) = leafc_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ frootc(p) = frootc_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ frootc_storage(p) = frootc_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ frootc_xfer(p) = frootc_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livestemc(p) = livestemc_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livestemc_storage(p) = livestemc_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livestemc_xfer(p) = livestemc_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadstemc(p) = deadstemc_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadstemc_storage(p) = deadstemc_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadstemc_xfer(p) = deadstemc_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livecrootc(p) = livecrootc_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livecrootc_storage(p) = livecrootc_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livecrootc_xfer(p) = livecrootc_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadcrootc(p) = deadcrootc_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadcrootc_storage(p) = deadcrootc_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadcrootc_xfer(p) = deadcrootc_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ if(ivt(p) >= npcropmin)then
+ reproductivec(p,:) = grainc_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ reproductivec_storage(p,:) = grainc_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ end if
+ if(use_c13)then
+ cs13_veg%leafc_patch(p) = cs13_veg%leafc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%leafc_storage_patch(p) = cs13_veg%leafc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%leafc_xfer_patch(p) = cs13_veg%leafc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%frootc_patch(p) = cs13_veg%frootc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%frootc_storage_patch(p) = cs13_veg%frootc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%frootc_xfer_patch(p) = cs13_veg%frootc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%livestemc_patch(p) = cs13_veg%livestemc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%livestemc_storage_patch(p) = cs13_veg%livestemc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%livestemc_xfer_patch(p) = cs13_veg%livestemc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%deadstemc_patch(p) = cs13_veg%deadstemc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%deadstemc_storage_patch(p) = cs13_veg%deadstemc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%deadstemc_xfer_patch(p) = cs13_veg%deadstemc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%livecrootc_patch(p) = cs13_veg%livecrootc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%livecrootc_storage_patch(p) = cs13_veg%livecrootc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%livecrootc_xfer_patch(p) = cs13_veg%livecrootc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%deadcrootc_patch(p) = cs13_veg%deadcrootc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%deadcrootc_storage_patch(p) = cs13_veg%deadcrootc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%deadcrootc_xfer_patch(p) = cs13_veg%deadcrootc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ if(ivt(p) >= npcropmin)then
+ cs13_veg%reproductivec_patch(p,:) = cs13_veg%grainc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%reproductivec_storage_patch(p,:) = cs13_veg%grainc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ end if
+ end if
+ if(use_c14)then
+ cs14_veg%leafc_patch(p) = cs14_veg%leafc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%leafc_storage_patch(p) = cs14_veg%leafc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%leafc_xfer_patch(p) = cs14_veg%leafc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%frootc_patch(p) = cs14_veg%frootc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%frootc_storage_patch(p) = cs14_veg%frootc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%frootc_xfer_patch(p) = cs14_veg%frootc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%livestemc_patch(p) = cs14_veg%livestemc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%livestemc_storage_patch(p) = cs14_veg%livestemc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%livestemc_xfer_patch(p) = cs14_veg%livestemc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%deadstemc_patch(p) = cs14_veg%deadstemc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%deadstemc_storage_patch(p) = cs14_veg%deadstemc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%deadstemc_xfer_patch(p) = cs14_veg%deadstemc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%livecrootc_patch(p) = cs14_veg%livecrootc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%livecrootc_storage_patch(p) = cs14_veg%livecrootc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%livecrootc_xfer_patch(p) = cs14_veg%livecrootc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%deadcrootc_patch(p) = cs14_veg%deadcrootc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%deadcrootc_storage_patch(p) = cs14_veg%deadcrootc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%deadcrootc_xfer_patch(p) = cs14_veg%deadcrootc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ if(ivt(p) >= npcropmin)then
+ cs14_veg%reproductivec_patch(p,:) = cs14_veg%grainc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%reproductivec_storage_patch(p,:) = cs14_veg%grainc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ end if
+ end if
+ leafn(p) = leafn_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ leafn_storage(p) = leafn_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ leafn_xfer(p) = leafn_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ frootn(p) = frootn_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ frootn_storage(p) = frootn_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ frootn_xfer(p) = frootn_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livestemn(p) = livestemn_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livestemn_storage(p) = livestemn_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livestemn_xfer(p) = livestemn_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadstemn(p) = deadstemn_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadstemn_storage(p) = deadstemn_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadstemn_xfer(p) = deadstemn_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livecrootn(p) = livecrootn_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livecrootn_storage(p) = livecrootn_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livecrootn_xfer(p) = livecrootn_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadcrootn(p) = deadcrootn_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadcrootn_storage(p) = deadcrootn_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadcrootn_xfer(p) = deadcrootn_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ if(ivt(p) >= npcropmin)then
+ reproductiven(p,:) = grainn_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ end if
+ leafc_SASUsave(p) = 0
+ leafc_storage_SASUsave(p) = 0
+ leafc_xfer_SASUsave(p) = 0
+ frootc_SASUsave(p) = 0
+ frootc_storage_SASUsave(p) = 0
+ frootc_xfer_SASUsave(p) = 0
+ livestemc_SASUsave(p) = 0
+ livestemc_storage_SASUsave(p) = 0
+ livestemc_xfer_SASUsave(p) = 0
+ deadstemc_SASUsave(p) = 0
+ deadstemc_storage_SASUsave(p) = 0
+ deadstemc_xfer_SASUsave(p) = 0
+ livecrootc_SASUsave(p) = 0
+ livecrootc_storage_SASUsave(p) = 0
+ livecrootc_xfer_SASUsave(p) = 0
+ deadcrootc_SASUsave(p) = 0
+ deadcrootc_storage_SASUsave(p) = 0
+ deadcrootc_xfer_SASUsave(p) = 0
+ if(ivt(p) >= npcropmin)then
+ grainc_SASUsave(p) = 0
+ grainc_storage_SASUsave(p) = 0
+ end if
+ if(use_c13)then
+ cs13_veg%leafc_SASUsave_patch(p) = 0
+ cs13_veg%leafc_storage_SASUsave_patch(p) = 0
+ cs13_veg%leafc_xfer_SASUsave_patch(p) = 0
+ cs13_veg%frootc_SASUsave_patch(p) = 0
+ cs13_veg%frootc_storage_SASUsave_patch(p) = 0
+ cs13_veg%frootc_xfer_SASUsave_patch(p) = 0
+ cs13_veg%livestemc_SASUsave_patch(p) = 0
+ cs13_veg%livestemc_storage_SASUsave_patch(p) = 0
+ cs13_veg%livestemc_xfer_SASUsave_patch(p) = 0
+ cs13_veg%deadstemc_SASUsave_patch(p) = 0
+ cs13_veg%deadstemc_storage_SASUsave_patch(p) = 0
+ cs13_veg%deadstemc_xfer_SASUsave_patch(p) = 0
+ cs13_veg%livecrootc_SASUsave_patch(p) = 0
+ cs13_veg%livecrootc_storage_SASUsave_patch(p) = 0
+ cs13_veg%livecrootc_xfer_SASUsave_patch(p) = 0
+ cs13_veg%deadcrootc_SASUsave_patch(p) = 0
+ cs13_veg%deadcrootc_storage_SASUsave_patch(p) = 0
+ cs13_veg%deadcrootc_xfer_SASUsave_patch(p) = 0
+ if(ivt(p) >= npcropmin)then
+ cs13_veg%grainc_SASUsave_patch(p) = 0
+ cs13_veg%grainc_storage_SASUsave_patch(p) = 0
+ end if
+ end if
+ if(use_c14)then
+ cs14_veg%leafc_SASUsave_patch(p) = 0
+ cs14_veg%leafc_storage_SASUsave_patch(p) = 0
+ cs14_veg%leafc_xfer_SASUsave_patch(p) = 0
+ cs14_veg%frootc_SASUsave_patch(p) = 0
+ cs14_veg%frootc_storage_SASUsave_patch(p) = 0
+ cs14_veg%frootc_xfer_SASUsave_patch(p) = 0
+ cs14_veg%livestemc_SASUsave_patch(p) = 0
+ cs14_veg%livestemc_storage_SASUsave_patch(p) = 0
+ cs14_veg%livestemc_xfer_SASUsave_patch(p) = 0
+ cs14_veg%deadstemc_SASUsave_patch(p) = 0
+ cs14_veg%deadstemc_storage_SASUsave_patch(p) = 0
+ cs14_veg%deadstemc_xfer_SASUsave_patch(p) = 0
+ cs14_veg%livecrootc_SASUsave_patch(p) = 0
+ cs14_veg%livecrootc_storage_SASUsave_patch(p) = 0
+ cs14_veg%livecrootc_xfer_SASUsave_patch(p) = 0
+ cs14_veg%deadcrootc_SASUsave_patch(p) = 0
+ cs14_veg%deadcrootc_storage_SASUsave_patch(p) = 0
+ cs14_veg%deadcrootc_xfer_SASUsave_patch(p) = 0
+ if(ivt(p) >= npcropmin)then
+ cs14_veg%grainc_SASUsave_patch(p) = 0
+ cs14_veg%grainc_storage_SASUsave_patch(p) = 0
+ end if
+ end if
+ leafn_SASUsave(p) = 0
+ leafn_storage_SASUsave(p) = 0
+ leafn_xfer_SASUsave(p) = 0
+ frootn_SASUsave(p) = 0
+ frootn_storage_SASUsave(p) = 0
+ frootn_xfer_SASUsave(p) = 0
+ livestemn_SASUsave(p) = 0
+ livestemn_storage_SASUsave(p) = 0
+ livestemn_xfer_SASUsave(p) = 0
+ deadstemn_SASUsave(p) = 0
+ deadstemn_storage_SASUsave(p) = 0
+ deadstemn_xfer_SASUsave(p) = 0
+ livecrootn_SASUsave(p) = 0
+ livecrootn_storage_SASUsave(p) = 0
+ livecrootn_xfer_SASUsave(p) = 0
+ deadcrootn_SASUsave(p) = 0
+ deadcrootn_storage_SASUsave(p) = 0
+ deadcrootn_xfer_SASUsave(p) = 0
+ if(ivt(p) >= npcropmin)then
+ grainn_SASUsave(p) = 0
+ end if
+ end if
+ end if
+ call update_DA_nstep()
+ end if
+
+ ! Save C storage capacity from temporary variables to module variables
+ if(hist_wrt_matrixcn_diag)then
+ matrix_cap_leafc(p) = vegmatrixc_rt(ileaf)
+ matrix_cap_leafc_storage(p) = vegmatrixc_rt(ileaf_st)
+ matrix_cap_leafc_xfer(p) = vegmatrixc_rt(ileaf_xf)
+ matrix_cap_frootc(p) = vegmatrixc_rt(ifroot)
+ matrix_cap_frootc_storage(p) = vegmatrixc_rt(ifroot_st)
+ matrix_cap_frootc_xfer(p) = vegmatrixc_rt(ifroot_xf)
+ matrix_cap_livestemc(p) = vegmatrixc_rt(ilivestem)
+ matrix_cap_livestemc_storage(p) = vegmatrixc_rt(ilivestem_st)
+ matrix_cap_livestemc_xfer(p) = vegmatrixc_rt(ilivestem_xf)
+ matrix_cap_deadstemc(p) = vegmatrixc_rt(ideadstem)
+ matrix_cap_deadstemc_storage(p) = vegmatrixc_rt(ideadstem_st)
+ matrix_cap_deadstemc_xfer(p) = vegmatrixc_rt(ideadstem_xf)
+ matrix_cap_livecrootc(p) = vegmatrixc_rt(ilivecroot)
+ matrix_cap_livecrootc_storage(p) = vegmatrixc_rt(ilivecroot_st)
+ matrix_cap_livecrootc_xfer(p) = vegmatrixc_rt(ilivecroot_xf)
+ matrix_cap_deadcrootc(p) = vegmatrixc_rt(ideadcroot)
+ matrix_cap_deadcrootc_storage(p) = vegmatrixc_rt(ideadcroot_st)
+ matrix_cap_deadcrootc_xfer(p) = vegmatrixc_rt(ideadcroot_xf)
+ if(ivt(p) >= npcropmin)then
+ matrix_cap_reproc(p) = vegmatrixc_rt(igrain)
+ matrix_cap_reproc_storage(p) = vegmatrixc_rt(igrain_st)
+ matrix_cap_reproc_xfer(p) = vegmatrixc_rt(igrain_xf)
+ end if
+ if(use_c13)then
+ cs13_veg%matrix_cap_leafc_patch(p) = vegmatrixc13_rt(ileaf)
+ cs13_veg%matrix_cap_leafc_storage_patch(p) = vegmatrixc13_rt(ileaf_st)
+ cs13_veg%matrix_cap_leafc_xfer_patch(p) = vegmatrixc13_rt(ileaf_xf)
+ cs13_veg%matrix_cap_frootc_patch(p) = vegmatrixc13_rt(ifroot)
+ cs13_veg%matrix_cap_frootc_storage_patch(p) = vegmatrixc13_rt(ifroot_st)
+ cs13_veg%matrix_cap_frootc_xfer_patch(p) = vegmatrixc13_rt(ifroot_xf)
+ cs13_veg%matrix_cap_livestemc_patch(p) = vegmatrixc13_rt(ilivestem)
+ cs13_veg%matrix_cap_livestemc_storage_patch(p) = vegmatrixc13_rt(ilivestem_st)
+ cs13_veg%matrix_cap_livestemc_xfer_patch(p) = vegmatrixc13_rt(ilivestem_xf)
+ cs13_veg%matrix_cap_deadstemc_patch(p) = vegmatrixc13_rt(ideadstem)
+ cs13_veg%matrix_cap_deadstemc_storage_patch(p) = vegmatrixc13_rt(ideadstem_st)
+ cs13_veg%matrix_cap_deadstemc_xfer_patch(p) = vegmatrixc13_rt(ideadstem_xf)
+ cs13_veg%matrix_cap_livecrootc_patch(p) = vegmatrixc13_rt(ilivecroot)
+ cs13_veg%matrix_cap_livecrootc_storage_patch(p) = vegmatrixc13_rt(ilivecroot_st)
+ cs13_veg%matrix_cap_livecrootc_xfer_patch(p) = vegmatrixc13_rt(ilivecroot_xf)
+ cs13_veg%matrix_cap_deadcrootc_patch(p) = vegmatrixc13_rt(ideadcroot)
+ cs13_veg%matrix_cap_deadcrootc_storage_patch(p) = vegmatrixc13_rt(ideadcroot_st)
+ cs13_veg%matrix_cap_deadcrootc_xfer_patch(p) = vegmatrixc13_rt(ideadcroot_xf)
+ if(ivt(p) >= npcropmin)then
+ cs13_veg%matrix_cap_reproc_patch(p) = vegmatrixc13_rt(igrain)
+ cs13_veg%matrix_cap_reproc_storage_patch(p) = vegmatrixc13_rt(igrain_st)
+ cs13_veg%matrix_cap_reproc_xfer_patch(p) = vegmatrixc13_rt(igrain_xf)
+ end if
+ end if
+ if(use_c14)then
+ cs14_veg%matrix_cap_leafc_patch(p) = vegmatrixc14_rt(ileaf)
+ cs14_veg%matrix_cap_leafc_storage_patch(p) = vegmatrixc14_rt(ileaf_st)
+ cs14_veg%matrix_cap_leafc_xfer_patch(p) = vegmatrixc14_rt(ileaf_xf)
+ cs14_veg%matrix_cap_frootc_patch(p) = vegmatrixc14_rt(ifroot)
+ cs14_veg%matrix_cap_frootc_storage_patch(p) = vegmatrixc14_rt(ifroot_st)
+ cs14_veg%matrix_cap_frootc_xfer_patch(p) = vegmatrixc14_rt(ifroot_xf)
+ cs14_veg%matrix_cap_livestemc_patch(p) = vegmatrixc14_rt(ilivestem)
+ cs14_veg%matrix_cap_livestemc_storage_patch(p) = vegmatrixc14_rt(ilivestem_st)
+ cs14_veg%matrix_cap_livestemc_xfer_patch(p) = vegmatrixc14_rt(ilivestem_xf)
+ cs14_veg%matrix_cap_deadstemc_patch(p) = vegmatrixc14_rt(ideadstem)
+ cs14_veg%matrix_cap_deadstemc_storage_patch(p) = vegmatrixc14_rt(ideadstem_st)
+ cs14_veg%matrix_cap_deadstemc_xfer_patch(p) = vegmatrixc14_rt(ideadstem_xf)
+ cs14_veg%matrix_cap_livecrootc_patch(p) = vegmatrixc14_rt(ilivecroot)
+ cs14_veg%matrix_cap_livecrootc_storage_patch(p) = vegmatrixc14_rt(ilivecroot_st)
+ cs14_veg%matrix_cap_livecrootc_xfer_patch(p) = vegmatrixc14_rt(ilivecroot_xf)
+ cs14_veg%matrix_cap_deadcrootc_patch(p) = vegmatrixc14_rt(ideadcroot)
+ cs14_veg%matrix_cap_deadcrootc_storage_patch(p) = vegmatrixc14_rt(ideadcroot_st)
+ cs14_veg%matrix_cap_deadcrootc_xfer_patch(p) = vegmatrixc14_rt(ideadcroot_xf)
+ if(ivt(p) >= npcropmin)then
+ cs14_veg%matrix_cap_reproc_patch(p) = vegmatrixc14_rt(igrain)
+ cs14_veg%matrix_cap_reproc_storage_patch(p) = vegmatrixc14_rt(igrain_st)
+ cs14_veg%matrix_cap_reproc_xfer_patch(p) = vegmatrixc14_rt(igrain_xf)
+ end if
+ end if
+ matrix_cap_leafn(p) = vegmatrixn_rt(ileaf)
+ matrix_cap_leafn_storage(p) = vegmatrixn_rt(ileaf_st)
+ matrix_cap_leafn_xfer(p) = vegmatrixn_rt(ileaf_xf)
+ matrix_cap_frootn(p) = vegmatrixn_rt(ifroot)
+ matrix_cap_frootn_storage(p) = vegmatrixn_rt(ifroot_st)
+ matrix_cap_frootn_xfer(p) = vegmatrixn_rt(ifroot_xf)
+ matrix_cap_livestemn(p) = vegmatrixn_rt(ilivestem)
+ matrix_cap_livestemn_storage(p) = vegmatrixn_rt(ilivestem_st)
+ matrix_cap_livestemn_xfer(p) = vegmatrixn_rt(ilivestem_xf)
+ matrix_cap_deadstemn(p) = vegmatrixn_rt(ideadstem)
+ matrix_cap_deadstemn_storage(p) = vegmatrixn_rt(ideadstem_st)
+ matrix_cap_deadstemn_xfer(p) = vegmatrixn_rt(ideadstem_xf)
+ matrix_cap_livecrootn(p) = vegmatrixn_rt(ilivecroot)
+ matrix_cap_livecrootn_storage(p) = vegmatrixn_rt(ilivecroot_st)
+ matrix_cap_livecrootn_xfer(p) = vegmatrixn_rt(ilivecroot_xf)
+ matrix_cap_deadcrootn(p) = vegmatrixn_rt(ideadcroot)
+ matrix_cap_deadcrootn_storage(p) = vegmatrixn_rt(ideadcroot_st)
+ if(ivt(p) >= npcropmin)then
+ matrix_cap_repron(p) = vegmatrixn_rt(igrain)
+ matrix_cap_repron_storage(p) = vegmatrixn_rt(igrain_st)
+ matrix_cap_repron_xfer(p) = vegmatrixn_rt(igrain_xf)
+ end if
+ end if
+
+ ! Reset accumulated variables to 0 at end of each year after calculating capacity
+ matrix_calloc_leaf_acc(p) = 0._r8
+ matrix_calloc_leafst_acc(p) = 0._r8
+ matrix_calloc_froot_acc(p) = 0._r8
+ matrix_calloc_frootst_acc(p) = 0._r8
+ matrix_calloc_livestem_acc(p) = 0._r8
+ matrix_calloc_livestemst_acc(p) = 0._r8
+ matrix_calloc_deadstem_acc(p) = 0._r8
+ matrix_calloc_deadstemst_acc(p) = 0._r8
+ matrix_calloc_livecroot_acc(p) = 0._r8
+ matrix_calloc_livecrootst_acc(p) = 0._r8
+ matrix_calloc_deadcroot_acc(p) = 0._r8
+ matrix_calloc_deadcrootst_acc(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ matrix_calloc_grain_acc(p) = 0._r8
+ matrix_calloc_grainst_acc(p) = 0._r8
+ end if
+
+ matrix_ctransfer_leafst_to_leafxf_acc(p) = 0._r8
+ matrix_ctransfer_leafxf_to_leaf_acc(p) = 0._r8
+ matrix_ctransfer_frootst_to_frootxf_acc(p) = 0._r8
+ matrix_ctransfer_frootxf_to_froot_acc(p) = 0._r8
+ matrix_ctransfer_livestemst_to_livestemxf_acc(p) = 0._r8
+ matrix_ctransfer_livestemxf_to_livestem_acc(p) = 0._r8
+ matrix_ctransfer_deadstemst_to_deadstemxf_acc(p) = 0._r8
+ matrix_ctransfer_deadstemxf_to_deadstem_acc(p) = 0._r8
+ matrix_ctransfer_livecrootst_to_livecrootxf_acc(p) = 0._r8
+ matrix_ctransfer_livecrootxf_to_livecroot_acc(p) = 0._r8
+ matrix_ctransfer_deadcrootst_to_deadcrootxf_acc(p) = 0._r8
+ matrix_ctransfer_deadcrootxf_to_deadcroot_acc(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ matrix_ctransfer_grainst_to_grainxf_acc(p) = 0._r8
+ matrix_ctransfer_grainxf_to_grain_acc(p) = 0._r8
+ end if
+ matrix_ctransfer_livestem_to_deadstem_acc(p) = 0._r8
+ matrix_ctransfer_livecroot_to_deadcroot_acc(p) = 0._r8
+
+ matrix_cturnover_leaf_acc(p) = 0._r8
+ matrix_cturnover_leafst_acc(p) = 0._r8
+ matrix_cturnover_leafxf_acc(p) = 0._r8
+ matrix_cturnover_froot_acc(p) = 0._r8
+ matrix_cturnover_frootst_acc(p) = 0._r8
+ matrix_cturnover_frootxf_acc(p) = 0._r8
+ matrix_cturnover_livestem_acc(p) = 0._r8
+ matrix_cturnover_livestemst_acc(p) = 0._r8
+ matrix_cturnover_livestemxf_acc(p) = 0._r8
+ matrix_cturnover_deadstem_acc(p) = 0._r8
+ matrix_cturnover_deadstemst_acc(p) = 0._r8
+ matrix_cturnover_deadstemxf_acc(p) = 0._r8
+ matrix_cturnover_livecroot_acc(p) = 0._r8
+ matrix_cturnover_livecrootst_acc(p) = 0._r8
+ matrix_cturnover_livecrootxf_acc(p) = 0._r8
+ matrix_cturnover_deadcroot_acc(p) = 0._r8
+ matrix_cturnover_deadcrootst_acc(p) = 0._r8
+ matrix_cturnover_deadcrootxf_acc(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ matrix_cturnover_grain_acc(p) = 0._r8
+ matrix_cturnover_grainst_acc(p) = 0._r8
+ matrix_cturnover_grainxf_acc(p) = 0._r8
+ end if
+
+ if(use_c13)then
+ cs13_veg%matrix_calloc_leaf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_leafst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_froot_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_frootst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_livestem_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_livestemst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_deadstem_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_deadstemst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_livecroot_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_livecrootst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_deadcroot_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_deadcrootst_acc_patch(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ cs13_veg%matrix_calloc_grain_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_grainst_acc_patch(p) = 0._r8
+ end if
+
+ cs13_veg%matrix_ctransfer_leafst_to_leafxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_leafxf_to_leaf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_frootst_to_frootxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_frootxf_to_froot_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_livestemst_to_livestemxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_livestemxf_to_livestem_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ cs13_veg%matrix_ctransfer_grainst_to_grainxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_grainxf_to_grain_acc_patch(p) = 0._r8
+ end if
+ cs13_veg%matrix_ctransfer_livestem_to_deadstem_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_livecroot_to_deadcroot_acc_patch(p) = 0._r8
+
+ cs13_veg%matrix_cturnover_leaf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_leafst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_leafxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_froot_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_frootst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_frootxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_livestem_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_livestemst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_livestemxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_deadstem_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_deadstemst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_deadstemxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_livecroot_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_livecrootst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_livecrootxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_deadcroot_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_deadcrootst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_deadcrootxf_acc_patch(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ cs13_veg%matrix_cturnover_grain_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_grainst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_grainxf_acc_patch(p) = 0._r8
+ end if
+ end if
+
+ if(use_c14)then
+ cs14_veg%matrix_calloc_leaf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_leafst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_froot_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_frootst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_livestem_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_livestemst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_deadstem_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_deadstemst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_livecroot_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_livecrootst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_deadcroot_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_deadcrootst_acc_patch(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ cs14_veg%matrix_calloc_grain_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_grainst_acc_patch(p) = 0._r8
+ end if
+
+ cs14_veg%matrix_ctransfer_leafst_to_leafxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_leafxf_to_leaf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_frootst_to_frootxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_frootxf_to_froot_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_livestemst_to_livestemxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_livestemxf_to_livestem_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ cs14_veg%matrix_ctransfer_grainst_to_grainxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_grainxf_to_grain_acc_patch(p) = 0._r8
+ end if
+ cs14_veg%matrix_ctransfer_livestem_to_deadstem_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_livecroot_to_deadcroot_acc_patch(p) = 0._r8
+
+ cs14_veg%matrix_cturnover_leaf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_leafst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_leafxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_froot_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_frootst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_frootxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_livestem_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_livestemst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_livestemxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_deadstem_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_deadstemst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_deadstemxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_livecroot_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_livecrootst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_livecrootxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_deadcroot_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_deadcrootst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_deadcrootxf_acc_patch(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ cs14_veg%matrix_cturnover_grain_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_grainst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_grainxf_acc_patch(p) = 0._r8
+ end if
+ end if
+
+ matrix_nalloc_leaf_acc(p) = 0._r8
+ matrix_nalloc_leafst_acc(p) = 0._r8
+ matrix_nalloc_froot_acc(p) = 0._r8
+ matrix_nalloc_frootst_acc(p) = 0._r8
+ matrix_nalloc_livestem_acc(p) = 0._r8
+ matrix_nalloc_livestemst_acc(p) = 0._r8
+ matrix_nalloc_deadstem_acc(p) = 0._r8
+ matrix_nalloc_deadstemst_acc(p) = 0._r8
+ matrix_nalloc_livecroot_acc(p) = 0._r8
+ matrix_nalloc_livecrootst_acc(p) = 0._r8
+ matrix_nalloc_deadcroot_acc(p) = 0._r8
+ matrix_nalloc_deadcrootst_acc(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ matrix_nalloc_grain_acc(p) = 0._r8
+ matrix_nalloc_grainst_acc(p) = 0._r8
+ end if
+
+ matrix_ntransfer_leafst_to_leafxf_acc(p) = 0._r8
+ matrix_ntransfer_leafxf_to_leaf_acc(p) = 0._r8
+ matrix_ntransfer_frootst_to_frootxf_acc(p) = 0._r8
+ matrix_ntransfer_frootxf_to_froot_acc(p) = 0._r8
+ matrix_ntransfer_livestemst_to_livestemxf_acc(p) = 0._r8
+ matrix_ntransfer_livestemxf_to_livestem_acc(p) = 0._r8
+ matrix_ntransfer_deadstemst_to_deadstemxf_acc(p) = 0._r8
+ matrix_ntransfer_deadstemxf_to_deadstem_acc(p) = 0._r8
+ matrix_ntransfer_livecrootst_to_livecrootxf_acc(p) = 0._r8
+ matrix_ntransfer_livecrootxf_to_livecroot_acc(p) = 0._r8
+ matrix_ntransfer_deadcrootst_to_deadcrootxf_acc(p) = 0._r8
+ matrix_ntransfer_deadcrootxf_to_deadcroot_acc(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ matrix_ntransfer_grainst_to_grainxf_acc(p) = 0._r8
+ matrix_ntransfer_grainxf_to_grain_acc(p) = 0._r8
+ end if
+ matrix_ntransfer_livestem_to_deadstem_acc(p) = 0._r8
+ matrix_ntransfer_livecroot_to_deadcroot_acc(p) = 0._r8
+
+ matrix_ntransfer_retransn_to_leaf_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_leafst_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_froot_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_frootst_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_livestem_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_livestemst_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_deadstem_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_deadstemst_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_livecroot_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_livecrootst_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_deadcroot_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_deadcrootst_acc(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ matrix_ntransfer_retransn_to_grain_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_grainst_acc(p) = 0._r8
+ end if
+ matrix_ntransfer_leaf_to_retransn_acc(p) = 0._r8
+ matrix_ntransfer_froot_to_retransn_acc(p) = 0._r8
+ matrix_ntransfer_livestem_to_retransn_acc(p) = 0._r8
+ matrix_ntransfer_livecroot_to_retransn_acc(p) = 0._r8
+
+ matrix_nturnover_leaf_acc(p) = 0._r8
+ matrix_nturnover_leafst_acc(p) = 0._r8
+ matrix_nturnover_leafxf_acc(p) = 0._r8
+ matrix_nturnover_froot_acc(p) = 0._r8
+ matrix_nturnover_frootst_acc(p) = 0._r8
+ matrix_nturnover_frootxf_acc(p) = 0._r8
+ matrix_nturnover_livestem_acc(p) = 0._r8
+ matrix_nturnover_livestemst_acc(p) = 0._r8
+ matrix_nturnover_livestemxf_acc(p) = 0._r8
+ matrix_nturnover_deadstem_acc(p) = 0._r8
+ matrix_nturnover_deadstemst_acc(p) = 0._r8
+ matrix_nturnover_deadstemxf_acc(p) = 0._r8
+ matrix_nturnover_livecroot_acc(p) = 0._r8
+ matrix_nturnover_livecrootst_acc(p) = 0._r8
+ matrix_nturnover_livecrootxf_acc(p) = 0._r8
+ matrix_nturnover_deadcroot_acc(p) = 0._r8
+ matrix_nturnover_deadcrootst_acc(p) = 0._r8
+ matrix_nturnover_deadcrootxf_acc(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ matrix_nturnover_grain_acc(p) = 0._r8
+ matrix_nturnover_grainst_acc(p) = 0._r8
+ matrix_nturnover_grainxf_acc(p) = 0._r8
+ end if
+ matrix_nturnover_retransn_acc(p) = 0._r8
+ matrix_calloc_acc(:) = 0._r8
+ matrix_ctransfer_acc(:,:) = 0._r8
+ matrix_nalloc_acc(:) = 0._r8
+ matrix_ntransfer_acc(:,:) = 0._r8
+
+ call t_stopf('CN veg matrix-finalize spinup')
+ end do
+ if(iloop .eq. iloop_avg .and. iyr .eq. nyr_forcing)iloop = 0
+ if(iyr .eq. nyr_forcing)iyr=0
+ end if
+ end if
+
+ call vegmatrixc_input%ReleaseV()
+ if ( use_c13 )then
+ call vegmatrixc13_input%ReleaseV()
+ end if
+ if ( use_c14 )then
+ call vegmatrixc14_input%ReleaseV()
+ end if
+ call vegmatrixn_input%ReleaseV()
+
+ end associate td
+ end associate sd
+ end associate od
+ end associate fr
+ end subroutine CNVegMatrix
+
+ function matrix_update_phc(p,itransfer,rate,dt,cnveg_carbonflux_inst,matrixcheck,acc)
+
+ integer ,intent(in) :: p
+ integer ,intent(in) :: itransfer
+ real(r8),intent(in) :: rate
+ real(r8),intent(in) :: dt
+ type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst
+ logical ,intent(in),optional :: matrixcheck
+ logical ,intent(in),optional :: acc
+ real(r8) :: matrix_update_phc
+
+ associate( &
+ matrix_phtransfer => cnveg_carbonflux_inst%matrix_phtransfer_patch , &
+ matrix_phturnover => cnveg_carbonflux_inst%matrix_phturnover_patch , &
+ doner_phc => cnveg_carbonflux_inst%matrix_phtransfer_doner_patch&
+ )
+ if(.not. present(matrixcheck) .or. matrixcheck)then
+ if((.not. present(acc) .or. acc) .and. matrix_phturnover(p,doner_phc(itransfer)) + rate * dt .ge. 1)then
+ matrix_update_phc = max(0._r8,(1._r8 - matrix_phturnover(p,doner_phc(itransfer))) / dt)
+ else
+ matrix_update_phc = rate
+ end if
+ else
+ matrix_update_phc = rate
+ end if
+ if(.not. present(acc) .or. acc)then
+ matrix_phturnover(p,doner_phc(itransfer)) = matrix_phturnover(p,doner_phc(itransfer)) + matrix_update_phc * dt
+ matrix_phtransfer(p,itransfer) = matrix_phtransfer(p,itransfer) + matrix_update_phc
+ else
+ matrix_phturnover(p,doner_phc(itransfer)) = matrix_phturnover(p,doner_phc(itransfer)) - matrix_phtransfer(p,itransfer) * dt + matrix_update_phc * dt
+ matrix_phtransfer(p,itransfer) = matrix_update_phc
+ end if
+
+ return
+ end associate
+
+ end function matrix_update_phc
+
+ function matrix_update_gmc(p,itransfer,rate,dt,cnveg_carbonflux_inst,matrixcheck,acc)
+
+ integer,intent(in) :: p
+ integer,intent(in) :: itransfer
+ real(r8),intent(in) :: rate
+ real(r8),intent(in) :: dt
+ type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst
+ logical ,intent(in),optional :: matrixcheck
+ logical ,intent(in),optional :: acc
+ real(r8) :: matrix_update_gmc
+
+ associate( &
+ matrix_phturnover => cnveg_carbonflux_inst%matrix_phturnover_patch , &
+ matrix_gmtransfer => cnveg_carbonflux_inst%matrix_gmtransfer_patch , &
+ matrix_gmturnover => cnveg_carbonflux_inst%matrix_gmturnover_patch , &
+ doner_gmc => cnveg_carbonflux_inst%matrix_gmtransfer_doner_patch & ! Input: [integer (:)] Doners of gap mortality related C transfer
+ )
+
+ if(.not. present(matrixcheck) .or. matrixcheck)then
+ if((.not. present(acc) .or. acc) .and. matrix_phturnover(p,doner_gmc(itransfer)) + matrix_gmturnover(p,doner_gmc(itransfer)) + rate * dt .ge. 1)then
+ matrix_update_gmc = max(0._r8,(1._r8 - matrix_phturnover(p,doner_gmc(itransfer)) - matrix_gmturnover(p,doner_gmc(itransfer))) / dt)
+ else
+ matrix_update_gmc = rate
+ end if
+ else
+ matrix_update_gmc = rate
+ end if
+ if(.not. present(acc) .or. acc)then
+ matrix_gmturnover(p,doner_gmc(itransfer)) = matrix_gmturnover(p,doner_gmc(itransfer)) + matrix_update_gmc * dt
+ matrix_gmtransfer(p,itransfer) = matrix_gmtransfer(p,itransfer) + matrix_update_gmc
+ else
+ matrix_gmturnover(p,doner_gmc(itransfer)) = matrix_gmturnover(p,doner_gmc(itransfer)) - matrix_gmtransfer(p,itransfer) * dt + matrix_update_gmc * dt
+ matrix_gmtransfer(p,itransfer) = matrix_update_gmc
+ end if
+ return
+ end associate
+
+ end function matrix_update_gmc
+
+
+ function matrix_update_fic(p,itransfer,rate,dt,cnveg_carbonflux_inst,matrixcheck,acc)
+
+ integer,intent(in) :: p
+ integer,intent(in) :: itransfer
+ real(r8),intent(in) :: rate
+ real(r8),intent(in) :: dt
+ type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst
+ logical ,intent(in),optional :: matrixcheck
+ logical ,intent(in),optional :: acc
+ real(r8) :: matrix_update_fic
+
+ associate( &
+ matrix_phturnover => cnveg_carbonflux_inst%matrix_phturnover_patch , &
+ matrix_gmturnover => cnveg_carbonflux_inst%matrix_gmturnover_patch , &
+ matrix_fitransfer => cnveg_carbonflux_inst%matrix_fitransfer_patch , &
+ matrix_fiturnover => cnveg_carbonflux_inst%matrix_fiturnover_patch , &
+ doner_fic => cnveg_carbonflux_inst%matrix_fitransfer_doner_patch &
+ )
+
+ if(.not. present(matrixcheck) .or. matrixcheck)then
+ if((.not. present(acc) .or. acc) .and. matrix_phturnover(p,doner_fic(itransfer)) + matrix_gmturnover(p,doner_fic(itransfer)) &
+ + matrix_fiturnover(p,doner_fic(itransfer)) + rate * dt .ge. 1)then
+ matrix_update_fic = max(0._r8,(1._r8 - matrix_phturnover(p,doner_fic(itransfer)) &
+ - matrix_gmturnover(p,doner_fic(itransfer)) - matrix_fiturnover(p,doner_fic(itransfer))) / dt)
+ else
+ matrix_update_fic = rate
+ end if
+ else
+ matrix_update_fic = rate
+ end if
+ if(.not. present(acc) .or. acc)then
+ matrix_fiturnover(p,doner_fic(itransfer)) = matrix_fiturnover(p,doner_fic(itransfer)) + matrix_update_fic * dt
+ matrix_fitransfer(p,itransfer) = matrix_fitransfer(p,itransfer) + matrix_update_fic
+ else
+ matrix_fiturnover(p,doner_fic(itransfer)) = matrix_fiturnover(p,doner_fic(itransfer)) - matrix_fitransfer(p,itransfer) * dt + matrix_update_fic * dt
+ matrix_fitransfer(p,itransfer) = matrix_update_fic
+ end if
+
+ return
+ end associate
+
+end function matrix_update_fic
+
+ function matrix_update_phn(p,itransfer,rate,dt,cnveg_nitrogenflux_inst,matrixcheck,acc)
+
+ integer,intent(in) :: p
+ integer,intent(in) :: itransfer
+ real(r8),intent(in) :: rate
+ real(r8),intent(in) :: dt
+ type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst
+ logical ,intent(in),optional :: matrixcheck
+ logical ,intent(in),optional :: acc
+ real(r8) :: matrix_update_phn
+
+ associate( &
+ matrix_nphtransfer => cnveg_nitrogenflux_inst%matrix_nphtransfer_patch , &
+ matrix_nphturnover => cnveg_nitrogenflux_inst%matrix_nphturnover_patch , &
+ doner_phn => cnveg_nitrogenflux_inst%matrix_nphtransfer_doner_patch & ! Input: [integer (:)] Doners of phenology related N transfer
+ )
+
+ if(.not. present(matrixcheck) .or. matrixcheck)then
+ if((.not. present(acc) .or. acc) .and. matrix_nphturnover(p,doner_phn(itransfer)) + rate * dt .ge. 1)then
+ matrix_update_phn = max(0._r8,(1._r8 - matrix_nphturnover(p,doner_phn(itransfer))) / dt)
+ else
+ matrix_update_phn = rate
+ end if
+ else
+ matrix_update_phn = rate
+ end if
+ if(.not. present(acc) .or. acc)then
+ matrix_nphturnover(p,doner_phn(itransfer)) = matrix_nphturnover(p,doner_phn(itransfer)) + matrix_update_phn * dt
+ matrix_nphtransfer(p,itransfer) = matrix_nphtransfer(p,itransfer) + matrix_update_phn
+ else
+ matrix_nphturnover(p,doner_phn(itransfer)) = matrix_nphturnover(p,doner_phn(itransfer)) - matrix_nphtransfer(p,itransfer) * dt + matrix_update_phn * dt
+ matrix_nphtransfer(p,itransfer) = matrix_update_phn
+ end if
+
+ return
+ end associate
+
+ end function matrix_update_phn
+
+ function matrix_update_gmn(p,itransfer,rate,dt,cnveg_nitrogenflux_inst,matrixcheck,acc)
+
+ integer ,intent(in) :: p
+ integer ,intent(in) :: itransfer
+ real(r8),intent(in) :: rate
+ real(r8),intent(in) :: dt
+ type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst
+ logical ,intent(in),optional :: matrixcheck
+ logical ,intent(in),optional :: acc
+ real(r8) :: matrix_update_gmn
+
+ associate( &
+ matrix_nphturnover => cnveg_nitrogenflux_inst%matrix_nphturnover_patch , &
+ matrix_ngmtransfer => cnveg_nitrogenflux_inst%matrix_ngmtransfer_patch , &
+ matrix_ngmturnover => cnveg_nitrogenflux_inst%matrix_ngmturnover_patch , &
+ doner_gmn => cnveg_nitrogenflux_inst%matrix_ngmtransfer_doner_patch & ! Input: [integer (:)] Doners of gap mortality related N transfer
+ )
+
+ if(.not. present(matrixcheck) .or. matrixcheck)then
+ if((.not. present(acc) .or. acc) .and. matrix_nphturnover(p,doner_gmn(itransfer)) + matrix_ngmturnover(p,doner_gmn(itransfer)) + rate * dt .ge. 1)then
+ matrix_update_gmn = max(0._r8,(1._r8 - matrix_nphturnover(p,doner_gmn(itransfer)) - matrix_ngmturnover(p,doner_gmn(itransfer))) / dt)
+ else
+ matrix_update_gmn = rate
+ end if
+ else
+ matrix_update_gmn = rate
+ end if
+ if(.not. present(acc) .or. acc)then
+ matrix_ngmturnover(p,doner_gmn(itransfer)) = matrix_ngmturnover(p,doner_gmn(itransfer)) + matrix_update_gmn * dt
+ matrix_ngmtransfer(p,itransfer) = matrix_ngmtransfer(p,itransfer) + matrix_update_gmn
+ else
+ matrix_ngmturnover(p,doner_gmn(itransfer)) = matrix_ngmturnover(p,doner_gmn(itransfer)) - matrix_ngmtransfer(p,itransfer) * dt + matrix_update_gmn * dt
+ matrix_ngmtransfer(p,itransfer) = matrix_update_gmn
+ end if
+
+ return
+ end associate
+
+ end function matrix_update_gmn
+
+
+ function matrix_update_fin(p,itransfer,rate,dt,cnveg_nitrogenflux_inst,matrixcheck,acc)
+
+ integer ,intent(in) :: p
+ integer ,intent(in) :: itransfer
+ real(r8),intent(in) :: rate
+ real(r8),intent(in) :: dt
+ type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst
+ logical ,intent(in),optional :: matrixcheck
+ logical ,intent(in),optional :: acc
+ real(r8) :: matrix_update_fin
+
+ associate( &
+ matrix_nphturnover => cnveg_nitrogenflux_inst%matrix_nphturnover_patch , &
+ matrix_ngmturnover => cnveg_nitrogenflux_inst%matrix_ngmturnover_patch , &
+ matrix_nfitransfer => cnveg_nitrogenflux_inst%matrix_nfitransfer_patch , &
+ matrix_nfiturnover => cnveg_nitrogenflux_inst%matrix_nfiturnover_patch , &
+ doner_fin => cnveg_nitrogenflux_inst%matrix_nfitransfer_doner_patch &
+ )
+
+ if(.not. present(matrixcheck) .or. matrixcheck)then
+ if((.not. present(acc) .or. acc) .and. matrix_nphturnover(p,doner_fin(itransfer)) + matrix_ngmturnover(p,doner_fin(itransfer)) &
+ + matrix_nfiturnover(p,doner_fin(itransfer)) + rate * dt .ge. 1)then
+ matrix_update_fin = max(0._r8,(1._r8 - matrix_nphturnover(p,doner_fin(itransfer)) &
+ - matrix_ngmturnover(p,doner_fin(itransfer)) - matrix_nfiturnover(p,doner_fin(itransfer))) / dt)
+ else
+ matrix_update_fin = rate
+ end if
+ else
+ matrix_update_fin = rate
+ end if
+ if(.not. present(acc) .or. acc)then
+ matrix_nfiturnover(p,doner_fin(itransfer)) = matrix_nfiturnover(p,doner_fin(itransfer)) + matrix_update_fin * dt
+ matrix_nfitransfer(p,itransfer) = matrix_nfitransfer(p,itransfer) + matrix_update_fin
+ else
+ matrix_nfiturnover(p,doner_fin(itransfer)) = matrix_nfiturnover(p,doner_fin(itransfer)) - matrix_nfitransfer(p,itransfer) * dt + matrix_update_fin * dt
+ matrix_nfitransfer(p,itransfer) = matrix_update_fin
+ end if
+
+ return
+ end associate
+
+ end function matrix_update_fin
+
+ !-----------------------------------------------------------------------
+ subroutine CNVegMatrixRest( ncid, flag )
+ ! !DESCRIPTION:
+ !
+ ! Read/write restart data needed for the CN Matrix model solution
+ !
+ ! !USES:
+ use restUtilMod , only: restartvar
+ use ncdio_pio , only: file_desc_t, ncd_int
+ !
+ ! !ARGUMENTS:
+ type(file_desc_t) , intent(inout) :: ncid ! netcdf id
+ character(len=*) , intent(in) :: flag !'read' or 'write'
+ !
+ ! !LOCAL VARIABLES:
+ logical :: readvar ! determine if variable is on initial file
+ !------------------------------------------------------------------------
+ call restartvar(ncid=ncid, flag=flag, varname='bgc_cycle_year', xtype=ncd_int, &
+ long_name='Year number in spinup cycle sequence', units='years', &
+ interpinic_flag='skip', readvar=readvar, data=iyr)
+
+ call restartvar(ncid=ncid, flag=flag, varname='bgc_cycle_loop', xtype=ncd_int, &
+ long_name='Loop number in spinup cycle sequence', units='years', &
+ interpinic_flag='skip', readvar=readvar, data=iloop)
+
+ !------------------------------------------------------------------------
+ end subroutine CNVegMatrixRest
+
+end module CNVegMatrixMod
diff --git a/src/biogeochem/CNVegNitrogenFluxType.F90 b/src/biogeochem/CNVegNitrogenFluxType.F90
index 3806de9838..788be23137 100644
--- a/src/biogeochem/CNVegNitrogenFluxType.F90
+++ b/src/biogeochem/CNVegNitrogenFluxType.F90
@@ -5,7 +5,14 @@ module CNVegNitrogenFluxType
use shr_log_mod , only : errMsg => shr_log_errMsg
use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_pools
use clm_varpar , only : nlevdecomp_full, nlevdecomp, i_litr_min, i_litr_max
- use clm_varpar , only : nvegnpool
+ use clm_varpar , only : nvegnpool,nnphtrans,nngmtrans,nnfitrans,nnphouttrans,&
+ nngmouttrans,nnfiouttrans
+ use clm_varpar , only : ileaf,ileaf_st,ileaf_xf,ifroot,ifroot_st,ifroot_xf,&
+ ilivestem,ilivestem_st,ilivestem_xf,&
+ ideadstem,ideadstem_st,ideadstem_xf,&
+ ilivecroot,ilivecroot_st,ilivecroot_xf,&
+ ideadcroot,ideadcroot_st,ideadcroot_xf,&
+ igrain,igrain_st,igrain_xf,iretransn,ioutn
use clm_varpar , only : mxharvests
use clm_varcon , only : spval, ispval, dzsoi_decomp
use clm_varctl , only : use_nitrif_denitrif, use_crop
@@ -277,8 +284,127 @@ module CNVegNitrogenFluxType
real(r8), pointer :: cost_nactive_patch (:) ! Average cost of active uptake (gN/m2/s)
real(r8), pointer :: cost_nretrans_patch (:) ! Average cost of retranslocation (gN/m2/s)
real(r8), pointer :: nuptake_npp_fraction_patch (:) ! frac of npp spent on N acquisition (gN/m2/s)
-
- ! Matrix solution variables
+ ! Matrix
+ real(r8), pointer :: matrix_nalloc_patch (:,:) ! B-matrix for nitrogen allocation
+ real(r8), pointer :: matrix_Ninput_patch (:) ! I-matrix for nitrogen input
+
+ real(r8), pointer :: matrix_nphtransfer_patch (:,:) ! A-matrix_phenologh for nitrogen
+ real(r8), pointer :: matrix_nphturnover_patch (:,:) ! K-matrix_phenologh for nitrogen
+ integer, pointer :: matrix_nphtransfer_doner_patch (:) ! A-matrix_phenology non-zero indices (column indices) for nitrogen
+ integer, pointer :: matrix_nphtransfer_receiver_patch (:) ! A-matrix_phenology non-zero indices (row indices) for nitrogen
+
+ real(r8), pointer :: matrix_ngmtransfer_patch (:,:) ! A-matrix_gap mortality for nitrogen
+ real(r8), pointer :: matrix_ngmturnover_patch (:,:) ! K-matrix_gap mortality for nitrogen
+ integer, pointer :: matrix_ngmtransfer_doner_patch (:) ! A-matrix_gap mortality non-zero indices (column indices) for nitrogen
+ integer, pointer :: matrix_ngmtransfer_receiver_patch (:) ! A-matrix_gap mortality non-zero indices (row indices) for nitrogen
+
+ real(r8), pointer :: matrix_nfitransfer_patch (:,:) ! A-matrix_fire for nitrogen
+ real(r8), pointer :: matrix_nfiturnover_patch (:,:) ! K-matrix_fire for nitrogen
+ integer, pointer :: matrix_nfitransfer_doner_patch (:) ! A-matrix_fire non-zero indices (column indices) for nitrogen
+ integer, pointer :: matrix_nfitransfer_receiver_patch (:) ! A-matrix_fire non-zero indices (row indices) for nitrogen
+
+ integer ileafst_to_ileafxf_ph ! Index of phenology related N transfer from leaf storage pool to leaf transfer pool
+ integer ileafxf_to_ileaf_ph ! Index of phenology related N transfer from leaf transfer pool to leaf pool
+ integer ifrootst_to_ifrootxf_ph ! Index of phenology related N transfer from fine root storage pool to fine root transfer pool
+ integer ifrootxf_to_ifroot_ph ! Index of phenology related N transfer from fine root transfer pool to fine root pool
+ integer ilivestemst_to_ilivestemxf_ph ! Index of phenology related N transfer from live stem storage pool to live stem transfer pool
+ integer ilivestemxf_to_ilivestem_ph ! Index of phenology related N transfer from live stem transfer pool to live stem pool
+ integer ideadstemst_to_ideadstemxf_ph ! Index of phenology related N transfer from dead stem storage pool to dead stem transfer pool
+ integer ideadstemxf_to_ideadstem_ph ! Index of phenology related N transfer from dead stem transfer pool to dead stem pool
+ integer ilivecrootst_to_ilivecrootxf_ph ! Index of phenology related N transfer from live coarse root storage pool to live coarse root transfer pool
+ integer ilivecrootxf_to_ilivecroot_ph ! Index of phenology related N transfer from live coarse root transfer pool to live coarse root pool
+ integer ideadcrootst_to_ideadcrootxf_ph ! Index of phenology related N transfer from dead coarse root storage pool to dead coarse root transfer pool
+ integer ideadcrootxf_to_ideadcroot_ph ! Index of phenology related N transfer from dead coarse root transfer pool to dead coarse root pool
+ integer ilivestem_to_ideadstem_ph ! Index of phenology related N transfer from live stem pool to dead stem pool
+ integer ilivecroot_to_ideadcroot_ph ! Index of phenology related N transfer from live coarse root pool to dead coarse root pool
+ integer iretransn_to_ileaf_ph ! Index of phenology related N transfer from retranslocation pool to leaf pool
+ integer iretransn_to_ileafst_ph ! Index of phenology related N transfer from retranslocation pool to leaf storage pool
+ integer iretransn_to_ifroot_ph ! Index of phenology related N transfer from retranslocation pool to fine root pool
+ integer iretransn_to_ifrootst_ph ! Index of phenology related N transfer from retranslocation pool to fine root storage pool
+ integer iretransn_to_ilivestem_ph ! Index of phenology related N transfer from retranslocation pool to live stem pool
+ integer iretransn_to_ilivestemst_ph ! Index of phenology related N transfer from retranslocation pool to live stem storage pool
+ integer iretransn_to_ideadstem_ph ! Index of phenology related N transfer from retranslocation pool to dead stem pool
+ integer iretransn_to_ideadstemst_ph ! Index of phenology related N transfer from retranslocation pool to dead stem storage pool
+ integer iretransn_to_ilivecroot_ph ! Index of phenology related N transfer from retranslocation pool to live coarse root pool
+ integer iretransn_to_ilivecrootst_ph ! Index of phenology related N transfer from retranslocation pool to live coarse root storage pool
+ integer iretransn_to_ideadcroot_ph ! Index of phenology related N transfer from retranslocation pool to dead coarse root pool
+ integer iretransn_to_ideadcrootst_ph ! Index of phenology related N transfer from retranslocation pool to dead coarse root storage pool
+ integer iretransn_to_igrain_ph ! Index of phenology related N transfer from retranslocation pool to grain pool
+ integer iretransn_to_igrainst_ph ! Index of phenology related N transfer from retranslocation pool to grain storage pool
+ integer ileaf_to_iout_ph ! Index of phenology related N transfer from leaf pool to outside of vegetation pools
+ integer ifroot_to_iout_ph ! Index of phenology related N transfer from fine root pool to outside of vegetation pools
+ integer ilivestem_to_iout_ph ! Index of phenology related N transfer from live stem pool to outside of vegetation pools
+ integer ileaf_to_iretransn_ph ! Index of phenology related N transfer from leaf pool to retranslocation pools
+ integer ifroot_to_iretransn_ph ! Index of phenology related N transfer from fine root pool to retranslocation pools
+ integer ilivestem_to_iretransn_ph ! Index of phenology related N transfer from live stem pool to retranslocation pools
+ integer ilivecroot_to_iretransn_ph ! Index of phenology related N transfer from live coarse root pool to retranslocation pools
+ integer igrain_to_iout_ph ! Index of phenology related N transfer from grain pool to outside of vegetation pools
+ integer iretransn_to_iout_ph ! Index of phenology related N transfer from retranslocation pool to outside of vegetation pools
+ integer ileaf_to_iout_gm ! Index of gap mortality related N transfer from leaf pool to outside of vegetation pools
+ integer ileafst_to_iout_gm ! Index of gap mortality related N transfer from leaf storage pool to outside of vegetation pools
+ integer ileafxf_to_iout_gm ! Index of gap mortality related N transfer from leaf transfer pool to outside of vegetation pools
+ integer ifroot_to_iout_gm ! Index of gap mortality related N transfer from fine root pool to outside of vegetation pools
+ integer ifrootst_to_iout_gm ! Index of gap mortality related N transfer from fine root storage pool to outside of vegetation pools
+ integer ifrootxf_to_iout_gm ! Index of gap mortality related N transfer from fine root transfer pool to outside of vegetation pools
+ integer ilivestem_to_iout_gm ! Index of gap mortality related N transfer from live stem pool to outside of vegetation pools
+ integer ilivestemst_to_iout_gm ! Index of gap mortality related N transfer from live stem storage pool to outside of vegetation pools
+ integer ilivestemxf_to_iout_gm ! Index of gap mortality related N transfer from live stem transfer pool to outside of vegetation pools
+ integer ideadstem_to_iout_gm ! Index of gap mortality related N transfer from dead stem pool to outside of vegetation pools
+ integer ideadstemst_to_iout_gm ! Index of gap mortality related N transfer from dead stem storage pool to outside of vegetation pools
+ integer ideadstemxf_to_iout_gm ! Index of gap mortality related N transfer from dead stem transfer pool to outside of vegetation pools
+ integer ilivecroot_to_iout_gm ! Index of gap mortality related N transfer from live coarse root pool to outside of vegetation pools
+ integer ilivecrootst_to_iout_gm ! Index of gap mortality related N transfer from live coarse root storage pool to outside of vegetation pools
+ integer ilivecrootxf_to_iout_gm ! Index of gap mortality related N transfer from live coarse root transfer pool to outside of vegetation pools
+ integer ideadcroot_to_iout_gm ! Index of gap mortality related N transfer from dead coarse root pool to outside of vegetation pools
+ integer ideadcrootst_to_iout_gm ! Index of gap mortality related N transfer from dead coarse root storage pool to outside of vegetation pools
+ integer ideadcrootxf_to_iout_gm ! Index of gap mortality related N transfer from dead coarse root transfer pool to outside of vegetation pools
+ integer iretransn_to_iout_gm ! Index of gap mortality related N transfer from retranslocation to outside of vegetation pools
+ integer ileaf_to_iout_fi ! Index of fire related N transfer from leaf pool to outside of vegetation pools
+ integer ileafst_to_iout_fi ! Index of fire related N transfer from leaf storage pool to outside of vegetation pools
+ integer ileafxf_to_iout_fi ! Index of fire related N transfer from leaf transfer pool to outside of vegetation pools
+ integer ifroot_to_iout_fi ! Index of fire related N transfer from fine root pool to outside of vegetation pools
+ integer ifrootst_to_iout_fi ! Index of fire related N transfer from fine root storage pool to outside of vegetation pools
+ integer ifrootxf_to_iout_fi ! Index of fire related N transfer from fine root transfer pool to outside of vegetation pools
+ integer ilivestem_to_iout_fi ! Index of fire related N transfer from live stem pool to outside of vegetation pools
+ integer ilivestemst_to_iout_fi ! Index of fire related N transfer from live stem storage pool to outside of vegetation pools
+ integer ilivestemxf_to_iout_fi ! Index of fire related N transfer from live stem transfer pool to outside of vegetation pools
+ integer ideadstem_to_iout_fi ! Index of fire related N transfer from dead stem pool to outside of vegetation pools
+ integer ideadstemst_to_iout_fi ! Index of fire related N transfer from dead stem storage pool to outside of vegetation pools
+ integer ideadstemxf_to_iout_fi ! Index of fire related N transfer from dead stem transfer pool to outside of vegetation pools
+ integer ilivecroot_to_iout_fi ! Index of fire related N transfer from live coarse root pool to outside of vegetation pools
+ integer ilivecrootst_to_iout_fi ! Index of fire related N transfer from live coarse root storage pool to outside of vegetation pools
+ integer ilivecrootxf_to_iout_fi ! Index of fire related N transfer from live coarse root transfer pool to outside of vegetation pools
+ integer ideadcroot_to_iout_fi ! Index of fire related N transfer from dead coarse root pool to outside of vegetation pools
+ integer ideadcrootst_to_iout_fi ! Index of fire related N transfer from dead coarse root storage pool to outside of vegetation pools
+ integer ideadcrootxf_to_iout_fi ! Index of fire related N transfer from dead coarse root transfer pool to outside of vegetation pools
+ integer iretransn_to_iout_fi ! Index of fire related N transfer from retranslocation transfer pool to outside of vegetation pools
+ integer ilivestem_to_ideadstem_fi ! Index of fire related N transfer from live stem pool to dead stem pools
+ integer ilivecroot_to_ideadcroot_fi ! Index of fire related N transfer from live coarse root pool to dead coarse root pools
+
+ integer,pointer :: list_phn_phgmn (:) ! Index mapping for sparse matrix addition (save to reduce computational cost): from AKphn to AKphn+AKgmn
+ integer,pointer :: list_gmn_phgmn (:) ! Index mapping for sparse matrix addition (save to reduce computational cost): from AKgmn to AKphn+AKgmn
+ integer,pointer :: list_phn_phgmfin (:) ! Index mapping for sparse matrix addition (save to reduce computational cost): from AKphn to AKphn+AKgmn+AKfin
+ integer,pointer :: list_gmn_phgmfin (:) ! Index mapping for sparse matrix addition (save to reduce computational cost): from AKgmn to AKphn+AKgmn+AKfin
+ integer,pointer :: list_fin_phgmfin (:) ! Index mapping for sparse matrix addition (save to reduce computational cost): from AKfin to AKphn+AKgmn+AKfin
+ integer,pointer :: list_aphn (:) ! Indices of non-diagnoal entries in full sparse matrix Aph for N cycle
+ integer,pointer :: list_agmn (:) ! Indices of non-diagnoal entries in full sparse matrix Agm for N cycle
+ integer,pointer :: list_afin (:) ! Indices of non-diagnoal entries in full sparse matrix Afi for N cycle
+
+ type(sparse_matrix_type) :: AKphvegn ! Aph*Kph for N cycle in sparse matrix format
+ type(sparse_matrix_type) :: AKgmvegn ! Agm*Kgm for N cycle in sparse matrix format
+ type(sparse_matrix_type) :: AKfivegn ! Afi*Kfi for N cycle in sparse matrix format
+ type(sparse_matrix_type) :: AKallvegn ! Aph*Kph + Agm*Kgm + Afi*Kfi for N cycle in sparse matrix format
+ integer :: NE_AKallvegn ! Number of entries in AKallvegn
+ integer,pointer,dimension(:) :: RI_AKallvegn ! Row indices in Akallvegn
+ integer,pointer,dimension(:) :: CI_AKallvegn ! Column indices in AKallvegn
+ integer,pointer,dimension(:) :: RI_phn ! Row indices of non-diagonal entires in Aph for N cycle
+ integer,pointer,dimension(:) :: CI_phn ! Column indices of non-diagonal entries in Aph for N cycle
+ integer,pointer,dimension(:) :: RI_gmn ! Row indices of non-diagonal entires in Agm for N cycle
+ integer,pointer,dimension(:) :: CI_gmn ! Column indices of non-diagonal entries in Agm for N cycle
+ integer,pointer,dimension(:) :: RI_fin ! Row indices of non-diagonal entires in Afi for N cycle
+ integer,pointer,dimension(:) :: CI_fin ! Column indices of non-diagonal entries in Afi for N cycle
+ type(diag_matrix_type) :: Kvegn ! Temporary variable of Kph, Kgm or Kfi for N cycle in diagonal matrix format
+ type(vector_type) :: Xvegn ! Vegetation N of each compartment in a vector format
contains
@@ -289,7 +415,7 @@ module CNVegNitrogenFluxType
procedure , public :: ZeroGRU
procedure , public :: Summary => Summary_nitrogenflux
procedure , private :: InitAllocate
- procedure , private :: InitTransfer
+ procedure , private :: InitTransfer
procedure , private :: InitHistory
procedure , private :: InitCold
@@ -317,20 +443,337 @@ subroutine Init(this, bounds, alloc_full_veg)
end subroutine Init
subroutine InitTransfer (this)
- !
- ! !DESCRIPTION:
- ! Initialize the transfer indices for the matrix solution method
!
! !AGRUMENTS:
class (cnveg_nitrogenflux_type) :: this
+
+ this%ileaf_to_iretransn_ph = 1
+ this%matrix_nphtransfer_doner_patch(this%ileaf_to_iretransn_ph) = ileaf
+ this%matrix_nphtransfer_receiver_patch(this%ileaf_to_iretransn_ph) = iretransn
+
+ this%ileafst_to_ileafxf_ph = 2
+ this%matrix_nphtransfer_doner_patch(this%ileafst_to_ileafxf_ph) = ileaf_st
+ this%matrix_nphtransfer_receiver_patch(this%ileafst_to_ileafxf_ph) = ileaf_xf
+
+ this%ileafxf_to_ileaf_ph = 3
+ this%matrix_nphtransfer_doner_patch(this%ileafxf_to_ileaf_ph) = ileaf_xf
+ this%matrix_nphtransfer_receiver_patch(this%ileafxf_to_ileaf_ph) = ileaf
+
+ this%ifroot_to_iretransn_ph = 4
+ this%matrix_nphtransfer_doner_patch(this%ifroot_to_iretransn_ph) = ifroot
+ this%matrix_nphtransfer_receiver_patch(this%ifroot_to_iretransn_ph) = iretransn
+
+ this%ifrootst_to_ifrootxf_ph = 5
+ this%matrix_nphtransfer_doner_patch(this%ifrootst_to_ifrootxf_ph) = ifroot_st
+ this%matrix_nphtransfer_receiver_patch(this%ifrootst_to_ifrootxf_ph) = ifroot_xf
+
+ this%ifrootxf_to_ifroot_ph = 6
+ this%matrix_nphtransfer_doner_patch(this%ifrootxf_to_ifroot_ph) = ifroot_xf
+ this%matrix_nphtransfer_receiver_patch(this%ifrootxf_to_ifroot_ph) = ifroot
+
+ this%ilivestem_to_ideadstem_ph = 7
+ this%matrix_nphtransfer_doner_patch(this%ilivestem_to_ideadstem_ph) = ilivestem
+ this%matrix_nphtransfer_receiver_patch(this%ilivestem_to_ideadstem_ph) = ideadstem
+
+ this%ilivestem_to_iretransn_ph = 8
+ this%matrix_nphtransfer_doner_patch(this%ilivestem_to_iretransn_ph) = ilivestem
+ this%matrix_nphtransfer_receiver_patch(this%ilivestem_to_iretransn_ph) = iretransn
+
+ this%ilivestemst_to_ilivestemxf_ph = 9
+ this%matrix_nphtransfer_doner_patch(this%ilivestemst_to_ilivestemxf_ph) = ilivestem_st
+ this%matrix_nphtransfer_receiver_patch(this%ilivestemst_to_ilivestemxf_ph) = ilivestem_xf
- ! General indices
+ this%ilivestemxf_to_ilivestem_ph = 10
+ this%matrix_nphtransfer_doner_patch(this%ilivestemxf_to_ilivestem_ph) = ilivestem_xf
+ this%matrix_nphtransfer_receiver_patch(this%ilivestemxf_to_ilivestem_ph) = ilivestem
+
+ this%ideadstemst_to_ideadstemxf_ph = 11
+ this%matrix_nphtransfer_doner_patch(this%ideadstemst_to_ideadstemxf_ph) = ideadstem_st
+ this%matrix_nphtransfer_receiver_patch(this%ideadstemst_to_ideadstemxf_ph) = ideadstem_xf
+
+ this%ideadstemxf_to_ideadstem_ph = 12
+ this%matrix_nphtransfer_doner_patch(this%ideadstemxf_to_ideadstem_ph) = ideadstem_xf
+ this%matrix_nphtransfer_receiver_patch(this%ideadstemxf_to_ideadstem_ph) = ideadstem
+
+ this%ilivecroot_to_ideadcroot_ph = 13
+ this%matrix_nphtransfer_doner_patch(this%ilivecroot_to_ideadcroot_ph) = ilivecroot
+ this%matrix_nphtransfer_receiver_patch(this%ilivecroot_to_ideadcroot_ph) = ideadcroot
+
+ this%ilivecroot_to_iretransn_ph = 14
+ this%matrix_nphtransfer_doner_patch(this%ilivecroot_to_iretransn_ph) = ilivecroot
+ this%matrix_nphtransfer_receiver_patch(this%ilivecroot_to_iretransn_ph) = iretransn
+
+ this%ilivecrootst_to_ilivecrootxf_ph = 15
+ this%matrix_nphtransfer_doner_patch(this%ilivecrootst_to_ilivecrootxf_ph) = ilivecroot_st
+ this%matrix_nphtransfer_receiver_patch(this%ilivecrootst_to_ilivecrootxf_ph) = ilivecroot_xf
+
+ this%ilivecrootxf_to_ilivecroot_ph = 16
+ this%matrix_nphtransfer_doner_patch(this%ilivecrootxf_to_ilivecroot_ph) = ilivecroot_xf
+ this%matrix_nphtransfer_receiver_patch(this%ilivecrootxf_to_ilivecroot_ph) = ilivecroot
+
+ this%ideadcrootst_to_ideadcrootxf_ph = 17
+ this%matrix_nphtransfer_doner_patch(this%ideadcrootst_to_ideadcrootxf_ph) = ideadcroot_st
+ this%matrix_nphtransfer_receiver_patch(this%ideadcrootst_to_ideadcrootxf_ph) = ideadcroot_xf
+
+ this%ideadcrootxf_to_ideadcroot_ph = 18
+ this%matrix_nphtransfer_doner_patch(this%ideadcrootxf_to_ideadcroot_ph) = ideadcroot_xf
+ this%matrix_nphtransfer_receiver_patch(this%ideadcrootxf_to_ideadcroot_ph) = ideadcroot
+
+ this%iretransn_to_ileaf_ph = 19
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ileaf_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ileaf_ph) = ileaf
+
+ this%iretransn_to_ileafst_ph = 20
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ileafst_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ileafst_ph) = ileaf_st
+
+ this%iretransn_to_ifroot_ph = 21
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ifroot_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ifroot_ph) = ifroot
+
+ this%iretransn_to_ifrootst_ph = 22
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ifrootst_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ifrootst_ph) = ifroot_st
+
+ this%iretransn_to_ilivestem_ph = 23
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ilivestem_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ilivestem_ph) = ilivestem
+
+ this%iretransn_to_ilivestemst_ph = 24
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ilivestemst_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ilivestemst_ph) = ilivestem_st
+
+ this%iretransn_to_ideadstem_ph = 25
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ideadstem_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ideadstem_ph) = ideadstem
+
+ this%iretransn_to_ideadstemst_ph = 26
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ideadstemst_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ideadstemst_ph) = ideadstem_st
+
+ this%iretransn_to_ilivecroot_ph = 27
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ilivecroot_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ilivecroot_ph) = ilivecroot
+
+ this%iretransn_to_ilivecrootst_ph = 28
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ilivecrootst_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ilivecrootst_ph) = ilivecroot_st
+
+ this%iretransn_to_ideadcroot_ph = 29
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ideadcroot_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ideadcroot_ph) = ideadcroot
+
+ this%iretransn_to_ideadcrootst_ph = 30
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ideadcrootst_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ideadcrootst_ph) = ideadcroot_st
+
if(.not. use_crop)then
- ! Indices for crop
+ this%ileaf_to_iout_ph = 31
+ this%matrix_nphtransfer_doner_patch(this%ileaf_to_iout_ph) = ileaf
+ this%matrix_nphtransfer_receiver_patch(this%ileaf_to_iout_ph) = ioutn
+
+ this%ifroot_to_iout_ph = 32
+ this%matrix_nphtransfer_doner_patch(this%ifroot_to_iout_ph) = ifroot
+ this%matrix_nphtransfer_receiver_patch(this%ifroot_to_iout_ph) = ioutn
+
+ this%ilivestem_to_iout_ph = 33
+ this%matrix_nphtransfer_doner_patch(this%ilivestem_to_iout_ph) = ilivestem
+ this%matrix_nphtransfer_receiver_patch(this%ilivestem_to_iout_ph) = ioutn
+
+ this%iretransn_to_iout_ph = 34
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_iout_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_iout_ph) = ioutn
else
+ this%iretransn_to_igrain_ph = 31
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_igrain_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_igrain_ph) = igrain
+
+ this%iretransn_to_igrainst_ph = 32
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_igrainst_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_igrainst_ph) = igrain_st
+
+ this%ileaf_to_iout_ph = 33
+ this%matrix_nphtransfer_doner_patch(this%ileaf_to_iout_ph) = ileaf
+ this%matrix_nphtransfer_receiver_patch(this%ileaf_to_iout_ph) = ioutn
+
+ this%ifroot_to_iout_ph = 34
+ this%matrix_nphtransfer_doner_patch(this%ifroot_to_iout_ph) = ifroot
+ this%matrix_nphtransfer_receiver_patch(this%ifroot_to_iout_ph) = ioutn
+
+ this%ilivestem_to_iout_ph = 35
+ this%matrix_nphtransfer_doner_patch(this%ilivestem_to_iout_ph) = ilivestem
+ this%matrix_nphtransfer_receiver_patch(this%ilivestem_to_iout_ph) = ioutn
+
+ this%igrain_to_iout_ph = 36
+ this%matrix_nphtransfer_doner_patch(this%igrain_to_iout_ph) = igrain
+ this%matrix_nphtransfer_receiver_patch(this%igrain_to_iout_ph) = ioutn
+
+ this%iretransn_to_iout_ph = 37
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_iout_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_iout_ph) = ioutn
end if
-
- end subroutine InitTransfer
+
+ this%ileaf_to_iout_gm = 1
+ this%matrix_ngmtransfer_doner_patch(this%ileaf_to_iout_gm) = ileaf
+ this%matrix_ngmtransfer_receiver_patch(this%ileaf_to_iout_gm) = ioutn
+
+ this%ileafst_to_iout_gm = 2
+ this%matrix_ngmtransfer_doner_patch(this%ileafst_to_iout_gm) = ileaf_st
+ this%matrix_ngmtransfer_receiver_patch(this%ileafst_to_iout_gm) = ioutn
+
+ this%ileafxf_to_iout_gm = 3
+ this%matrix_ngmtransfer_doner_patch(this%ileafxf_to_iout_gm) = ileaf_xf
+ this%matrix_ngmtransfer_receiver_patch(this%ileafxf_to_iout_gm) = ioutn
+
+ this%ifroot_to_iout_gm = 4
+ this%matrix_ngmtransfer_doner_patch(this%ifroot_to_iout_gm) = ifroot
+ this%matrix_ngmtransfer_receiver_patch(this%ifroot_to_iout_gm) = ioutn
+
+ this%ifrootst_to_iout_gm = 5
+ this%matrix_ngmtransfer_doner_patch(this%ifrootst_to_iout_gm) = ifroot_st
+ this%matrix_ngmtransfer_receiver_patch(this%ifrootst_to_iout_gm) = ioutn
+
+ this%ifrootxf_to_iout_gm = 6
+ this%matrix_ngmtransfer_doner_patch(this%ifrootxf_to_iout_gm) = ifroot_xf
+ this%matrix_ngmtransfer_receiver_patch(this%ifrootxf_to_iout_gm) = ioutn
+
+ this%ilivestem_to_iout_gm = 7
+ this%matrix_ngmtransfer_doner_patch(this%ilivestem_to_iout_gm) = ilivestem
+ this%matrix_ngmtransfer_receiver_patch(this%ilivestem_to_iout_gm) = ioutn
+
+ this%ilivestemst_to_iout_gm = 8
+ this%matrix_ngmtransfer_doner_patch(this%ilivestemst_to_iout_gm) = ilivestem_st
+ this%matrix_ngmtransfer_receiver_patch(this%ilivestemst_to_iout_gm) = ioutn
+
+ this%ilivestemxf_to_iout_gm = 9
+ this%matrix_ngmtransfer_doner_patch(this%ilivestemxf_to_iout_gm) = ilivestem_xf
+ this%matrix_ngmtransfer_receiver_patch(this%ilivestemxf_to_iout_gm) = ioutn
+
+ this%ideadstem_to_iout_gm = 10
+ this%matrix_ngmtransfer_doner_patch(this%ideadstem_to_iout_gm) = ideadstem
+ this%matrix_ngmtransfer_receiver_patch(this%ideadstem_to_iout_gm) = ioutn
+
+ this%ideadstemst_to_iout_gm = 11
+ this%matrix_ngmtransfer_doner_patch(this%ideadstemst_to_iout_gm) = ideadstem_st
+ this%matrix_ngmtransfer_receiver_patch(this%ideadstemst_to_iout_gm) = ioutn
+
+ this%ideadstemxf_to_iout_gm = 12
+ this%matrix_ngmtransfer_doner_patch(this%ideadstemxf_to_iout_gm) = ideadstem_xf
+ this%matrix_ngmtransfer_receiver_patch(this%ideadstemxf_to_iout_gm) = ioutn
+
+ this%ilivecroot_to_iout_gm = 13
+ this%matrix_ngmtransfer_doner_patch(this%ilivecroot_to_iout_gm) = ilivecroot
+ this%matrix_ngmtransfer_receiver_patch(this%ilivecroot_to_iout_gm) = ioutn
+
+ this%ilivecrootst_to_iout_gm = 14
+ this%matrix_ngmtransfer_doner_patch(this%ilivecrootst_to_iout_gm) = ilivecroot_st
+ this%matrix_ngmtransfer_receiver_patch(this%ilivecrootst_to_iout_gm) = ioutn
+
+ this%ilivecrootxf_to_iout_gm = 15
+ this%matrix_ngmtransfer_doner_patch(this%ilivecrootxf_to_iout_gm) = ilivecroot_xf
+ this%matrix_ngmtransfer_receiver_patch(this%ilivecrootxf_to_iout_gm) = ioutn
+
+ this%ideadcroot_to_iout_gm = 16
+ this%matrix_ngmtransfer_doner_patch(this%ideadcroot_to_iout_gm) = ideadcroot
+ this%matrix_ngmtransfer_receiver_patch(this%ideadcroot_to_iout_gm) = ioutn
+
+ this%ideadcrootst_to_iout_gm = 17
+ this%matrix_ngmtransfer_doner_patch(this%ideadcrootst_to_iout_gm) = ideadcroot_st
+ this%matrix_ngmtransfer_receiver_patch(this%ideadcrootst_to_iout_gm) = ioutn
+
+ this%ideadcrootxf_to_iout_gm = 18
+ this%matrix_ngmtransfer_doner_patch(this%ideadcrootxf_to_iout_gm) = ideadcroot_xf
+ this%matrix_ngmtransfer_receiver_patch(this%ideadcrootxf_to_iout_gm) = ioutn
+
+ this%iretransn_to_iout_gm = 19
+ this%matrix_ngmtransfer_doner_patch(this%iretransn_to_iout_gm) = iretransn
+ this%matrix_ngmtransfer_receiver_patch(this%iretransn_to_iout_gm) = ioutn
+
+ this%ilivestem_to_ideadstem_fi = 1
+ this%matrix_nfitransfer_doner_patch(this%ilivestem_to_ideadstem_fi) = ilivestem
+ this%matrix_nfitransfer_receiver_patch(this%ilivestem_to_ideadstem_fi) = ideadstem
+
+ this%ilivecroot_to_ideadcroot_fi = 2
+ this%matrix_nfitransfer_doner_patch(this%ilivecroot_to_ideadcroot_fi) = ilivecroot
+ this%matrix_nfitransfer_receiver_patch(this%ilivecroot_to_ideadcroot_fi) = ideadcroot
+
+ this%ileaf_to_iout_fi = 3
+ this%matrix_nfitransfer_doner_patch(this%ileaf_to_iout_fi) = ileaf
+ this%matrix_nfitransfer_receiver_patch(this%ileaf_to_iout_fi) = ioutn
+
+ this%ileafst_to_iout_fi = 4
+ this%matrix_nfitransfer_doner_patch(this%ileafst_to_iout_fi) = ileaf_st
+ this%matrix_nfitransfer_receiver_patch(this%ileafst_to_iout_fi) = ioutn
+
+ this%ileafxf_to_iout_fi = 5
+ this%matrix_nfitransfer_doner_patch(this%ileafxf_to_iout_fi) = ileaf_xf
+ this%matrix_nfitransfer_receiver_patch(this%ileafxf_to_iout_fi) = ioutn
+
+ this%ifroot_to_iout_fi = 6
+ this%matrix_nfitransfer_doner_patch(this%ifroot_to_iout_fi) = ifroot
+ this%matrix_nfitransfer_receiver_patch(this%ifroot_to_iout_fi) = ioutn
+
+ this%ifrootst_to_iout_fi = 7
+ this%matrix_nfitransfer_doner_patch(this%ifrootst_to_iout_fi) = ifroot_st
+ this%matrix_nfitransfer_receiver_patch(this%ifrootst_to_iout_fi) = ioutn
+
+ this%ifrootxf_to_iout_fi = 8
+ this%matrix_nfitransfer_doner_patch(this%ifrootxf_to_iout_fi) = ifroot_xf
+ this%matrix_nfitransfer_receiver_patch(this%ifrootxf_to_iout_fi) = ioutn
+
+ this%ilivestem_to_iout_fi = 9
+ this%matrix_nfitransfer_doner_patch(this%ilivestem_to_iout_fi) = ilivestem
+ this%matrix_nfitransfer_receiver_patch(this%ilivestem_to_iout_fi) = ioutn
+
+ this%ilivestemst_to_iout_fi = 10
+ this%matrix_nfitransfer_doner_patch(this%ilivestemst_to_iout_fi) = ilivestem_st
+ this%matrix_nfitransfer_receiver_patch(this%ilivestemst_to_iout_fi) = ioutn
+
+ this%ilivestemxf_to_iout_fi = 11
+ this%matrix_nfitransfer_doner_patch(this%ilivestemxf_to_iout_fi) = ilivestem_xf
+ this%matrix_nfitransfer_receiver_patch(this%ilivestemxf_to_iout_fi) = ioutn
+
+ this%ideadstem_to_iout_fi = 12
+ this%matrix_nfitransfer_doner_patch(this%ideadstem_to_iout_fi) = ideadstem
+ this%matrix_nfitransfer_receiver_patch(this%ideadstem_to_iout_fi) = ioutn
+
+ this%ideadstemst_to_iout_fi = 13
+ this%matrix_nfitransfer_doner_patch(this%ideadstemst_to_iout_fi) = ideadstem_st
+ this%matrix_nfitransfer_receiver_patch(this%ideadstemst_to_iout_fi) = ioutn
+
+ this%ideadstemxf_to_iout_fi = 14
+ this%matrix_nfitransfer_doner_patch(this%ideadstemxf_to_iout_fi) = ideadstem_xf
+ this%matrix_nfitransfer_receiver_patch(this%ideadstemxf_to_iout_fi) = ioutn
+
+ this%ilivecroot_to_iout_fi = 15
+ this%matrix_nfitransfer_doner_patch(this%ilivecroot_to_iout_fi) = ilivecroot
+ this%matrix_nfitransfer_receiver_patch(this%ilivecroot_to_iout_fi) = ioutn
+
+ this%ilivecrootst_to_iout_fi = 16
+ this%matrix_nfitransfer_doner_patch(this%ilivecrootst_to_iout_fi) = ilivecroot_st
+ this%matrix_nfitransfer_receiver_patch(this%ilivecrootst_to_iout_fi) = ioutn
+
+ this%ilivecrootxf_to_iout_fi = 17
+ this%matrix_nfitransfer_doner_patch(this%ilivecrootxf_to_iout_fi) = ilivecroot_xf
+ this%matrix_nfitransfer_receiver_patch(this%ilivecrootxf_to_iout_fi) = ioutn
+
+ this%ideadcroot_to_iout_fi = 18
+ this%matrix_nfitransfer_doner_patch(this%ideadcroot_to_iout_fi) = ideadcroot
+ this%matrix_nfitransfer_receiver_patch(this%ideadcroot_to_iout_fi) = ioutn
+
+ this%ideadcrootst_to_iout_fi = 19
+ this%matrix_nfitransfer_doner_patch(this%ideadcrootst_to_iout_fi) = ideadcroot_st
+ this%matrix_nfitransfer_receiver_patch(this%ideadcrootst_to_iout_fi) = ioutn
+
+ this%ideadcrootxf_to_iout_fi = 20
+ this%matrix_nfitransfer_doner_patch(this%ideadcrootxf_to_iout_fi) = ideadcroot_xf
+ this%matrix_nfitransfer_receiver_patch(this%ideadcrootxf_to_iout_fi) = ioutn
+
+ this%iretransn_to_iout_fi = 21
+ this%matrix_nfitransfer_doner_patch(this%iretransn_to_iout_fi) = iretransn
+ this%matrix_nfitransfer_receiver_patch(this%iretransn_to_iout_fi) = ioutn
+
+ end subroutine InitTransfer
!------------------------------------------------------------------------
subroutine InitAllocate(this, bounds, alloc_full_veg)
@@ -612,10 +1055,57 @@ subroutine InitAllocate(this, bounds, alloc_full_veg)
allocate(this%cost_nactive_patch (begp:endp)) ; this%cost_nactive_patch (:) = nan
allocate(this%cost_nretrans_patch (begp:endp)) ; this%cost_nretrans_patch (:) = nan
allocate(this%nuptake_npp_fraction_patch (begp:endp)) ; this%nuptake_npp_fraction_patch (:) = nan
-
- ! Allocate for matrix solution arrays
- if ( use_matrixcn )then
- end if
+ ! Matrix
+ if(use_matrixcn)then
+ allocate(this%matrix_Ninput_patch (begp:endp)) ; this%matrix_Ninput_patch (:) = nan
+ allocate(this%matrix_nalloc_patch (begp:endp,1:nvegnpool)) ; this%matrix_nalloc_patch (:,:) = nan
+
+ allocate(this%matrix_nphtransfer_patch (begp:endp,1:nnphtrans)) ; this%matrix_nphtransfer_patch (:,:) = nan
+ allocate(this%matrix_nphturnover_patch (begp:endp,1:nvegnpool)) ; this%matrix_nphturnover_patch (:,:) = nan
+ allocate(this%matrix_nphtransfer_doner_patch (1:nnphtrans)) ; this%matrix_nphtransfer_doner_patch (:) = -9999
+ allocate(this%matrix_nphtransfer_receiver_patch (1:nnphtrans)) ; this%matrix_nphtransfer_receiver_patch(:) = -9999
+
+ allocate(this%matrix_ngmtransfer_patch (begp:endp,1:nngmtrans)) ; this%matrix_ngmtransfer_patch (:,:) = nan
+ allocate(this%matrix_ngmturnover_patch (begp:endp,1:nvegnpool)) ; this%matrix_ngmturnover_patch (:,:) = nan
+ allocate(this%matrix_ngmtransfer_doner_patch (1:nngmtrans)) ; this%matrix_ngmtransfer_doner_patch (:) = -9999
+ allocate(this%matrix_ngmtransfer_receiver_patch (1:nngmtrans)) ; this%matrix_ngmtransfer_receiver_patch(:) = -9999
+
+ allocate(this%matrix_nfitransfer_patch (begp:endp,1:nnfitrans)) ; this%matrix_nfitransfer_patch (:,:) = nan
+ allocate(this%matrix_nfiturnover_patch (begp:endp,1:nvegnpool)) ; this%matrix_nfiturnover_patch (:,:) = nan
+ allocate(this%matrix_nfitransfer_doner_patch (1:nnfitrans)) ; this%matrix_nfitransfer_doner_patch (:) = -9999
+ allocate(this%matrix_nfitransfer_receiver_patch (1:nnfitrans)) ; this%matrix_nfitransfer_receiver_patch(:) = -9999
+
+ allocate(this%list_phn_phgmn (1:nnphtrans+nvegnpool)) ; this%list_phn_phgmn = -9999
+ allocate(this%list_gmn_phgmn (1:nvegnpool)) ; this%list_gmn_phgmn = -9999
+ allocate(this%list_phn_phgmfin (1:nnphtrans+nvegnpool)) ; this%list_phn_phgmfin = -9999
+ allocate(this%list_gmn_phgmfin (1:nvegnpool)) ; this%list_gmn_phgmfin = -9999
+ allocate(this%list_fin_phgmfin (1:nnfitrans+nvegnpool)) ; this%list_fin_phgmfin = -9999
+
+ allocate(this%list_aphn (1:nnphtrans-nnphouttrans)); this%list_aphn = -9999
+ allocate(this%list_agmn (1:nngmtrans-nngmouttrans)); this%list_agmn = -9999
+ allocate(this%list_afin (1:nnfitrans-nnfiouttrans)); this%list_afin = -9999
+
+ call this%AKphvegn%InitSM (nvegnpool,begp,endp,nnphtrans-nnphouttrans+nvegnpool)
+ call this%AKgmvegn%InitSM (nvegnpool,begp,endp,nngmtrans-nngmouttrans+nvegnpool)
+ call this%AKfivegn%InitSM (nvegnpool,begp,endp,nnfitrans-nnfiouttrans+nvegnpool)
+
+ this%NE_AKallvegn = (nnphtrans-nnphouttrans+nvegnpool) + (nngmtrans-nngmouttrans+nvegnpool) + &
+ nnfitrans-nnfiouttrans+nvegnpool
+
+ call this%AKallvegn%InitSM (nvegnpool,begp,endp,this%NE_AKallvegn)
+
+ allocate(this%RI_AKallvegn (1:this%NE_AKallvegn)) ; this%RI_AKallvegn(:) = -9999
+ allocate(this%CI_AKallvegn (1:this%NE_AKallvegn)) ; this%CI_AKallvegn(:) = -9999
+ allocate(this%RI_phn (1:nnphtrans-nnphouttrans+nvegnpool)) ; this%RI_phn(:) = -9999
+ allocate(this%CI_phn (1:nnphtrans-nnphouttrans+nvegnpool)) ; this%CI_phn(:) = -9999
+ allocate(this%RI_gmn (1:nngmtrans-nngmouttrans+nvegnpool)) ; this%RI_gmn(:) = -9999
+ allocate(this%CI_gmn (1:nngmtrans-nngmouttrans+nvegnpool)) ; this%CI_gmn(:) = -9999
+ allocate(this%RI_fin (1:nnfitrans-nnfiouttrans+nvegnpool)) ; this%RI_fin(:) = -9999
+ allocate(this%CI_fin (1:nnfitrans-nnfiouttrans+nvegnpool)) ; this%CI_fin(:) = -9999
+
+ call this%Kvegn%InitDM (nvegnpool,begp,endp)
+ call this%Xvegn%InitV (nvegnpool,begp,endp)
+ end if
end subroutine InitAllocate
@@ -1248,10 +1738,12 @@ subroutine InitHistory(this, bounds)
call hist_addfld1d (fname='PLANT_NALLOC', units='gN/m^2/s', &
avgflag='A', long_name='total allocated N flux', &
ptr_patch=this%plant_nalloc_patch, default='inactive')
-
- ! Matrix solution history variables
- if ( use_matrixcn )then
- end if
+ if (use_matrixcn) then
+ this%matrix_Ninput_patch(begp:endp) = spval
+ call hist_addfld1d (fname='MATRIX PLANT_NALLOC', units='gN/m^2/s', &
+ avgflag='A', long_name='total allocated N flux for matrix', &
+ ptr_patch=this%matrix_Ninput_patch, default='inactive')
+ end if
if ( use_fun ) then
this%Nactive_patch(begp:endp) = spval
@@ -1676,7 +2168,7 @@ subroutine Restart (this, bounds, ncid, flag )
long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%Nactive_patch)
call set_missing_vals_to_constant(this%Nactive_patch, 0._r8)
-
+
call restartvar(ncid=ncid, flag=flag, varname='Nnonmyc', xtype=ncd_double, &
dim1name='pft', &
long_name='', units='', &
@@ -1792,7 +2284,7 @@ subroutine Restart (this, bounds, ncid, flag )
end subroutine Restart
!-----------------------------------------------------------------------
- subroutine SetValues ( this, nvegnpool, &
+ subroutine SetValues ( this,nvegnpool, &
num_patch, filter_patch, value_patch, &
num_column, filter_column, value_column)
!
@@ -1802,8 +2294,7 @@ subroutine SetValues ( this, nvegnpool, &
! !ARGUMENTS:
! !ARGUMENTS:
class (cnveg_nitrogenflux_type) :: this
- integer , intent(in) :: num_patch
- integer , intent(in) :: nvegnpool
+ integer , intent(in) :: num_patch,nvegnpool
integer , intent(in) :: filter_patch(:)
real(r8), intent(in) :: value_patch
integer , intent(in) :: num_column
@@ -2042,12 +2533,40 @@ subroutine SetValues ( this, nvegnpool, &
this%m_decomp_npools_to_fire_col(i,k) = value_column
end do
end do
+! Matrix
+ if(use_matrixcn)then
+ do j = 1, nvegnpool
+ do fi = 1,num_patch
+ i = filter_patch(fi)
+ this%matrix_nalloc_patch(i,j) = value_patch
+ this%matrix_nphturnover_patch (i,j) = value_patch
+ this%matrix_ngmturnover_patch (i,j) = value_patch
+ this%matrix_nfiturnover_patch (i,j) = value_patch
+ end do
+ end do
- ! Matrix solution
- if ( use_matrixcn )then
- end if
+ do j = 1, nnphtrans
+ do fi = 1,num_patch
+ i = filter_patch(fi)
+ this%matrix_nphtransfer_patch (i,j) = value_patch
+ end do
+ end do
+
+ do j = 1, nngmtrans
+ do fi = 1,num_patch
+ i = filter_patch(fi)
+ this%matrix_ngmtransfer_patch (i,j) = value_patch
+ end do
+ end do
+ do j = 1, nnfitrans
+ do fi = 1,num_patch
+ i = filter_patch(fi)
+ this%matrix_nfitransfer_patch (i,j) = value_patch
+ end do
+ end do
+ end if
do k = 1, ndecomp_pools
do j = 1, nlevdecomp_full
do fi = 1,num_column
diff --git a/src/biogeochem/CNVegNitrogenStateType.F90 b/src/biogeochem/CNVegNitrogenStateType.F90
index 42bc47e102..61bb2d5d16 100644
--- a/src/biogeochem/CNVegNitrogenStateType.F90
+++ b/src/biogeochem/CNVegNitrogenStateType.F90
@@ -33,14 +33,23 @@ module CNVegNitrogenStateType
real(r8), pointer :: reproductiven_patch (:,:) ! (gN/m2) reproductive (e.g., grain) N (crop)
real(r8), pointer :: reproductiven_storage_patch (:,:) ! (gN/m2) reproductive (e.g., grain) N storage (crop)
real(r8), pointer :: reproductiven_xfer_patch (:,:) ! (gN/m2) reproductive (e.g., grain) N transfer (crop)
+ real(r8), pointer :: matrix_cap_repron_patch (:) ! (gN/m2) Capacity of grain N
+ real(r8), pointer :: matrix_cap_repron_storage_patch (:) ! (gN/m2) Capacity of grain N storage
+ real(r8), pointer :: matrix_cap_repron_xfer_patch (:) ! (gN/m2) Capacity of grain N transfer
real(r8), pointer :: leafn_patch (:) ! (gN/m2) leaf N
real(r8), pointer :: leafn_storage_patch (:) ! (gN/m2) leaf N storage
real(r8), pointer :: leafn_xfer_patch (:) ! (gN/m2) leaf N transfer
+ real(r8), pointer :: matrix_cap_leafn_patch (:) ! (gN/m2) Capacity of leaf N
+ real(r8), pointer :: matrix_cap_leafn_storage_patch (:) ! (gN/m2) Capacity of leaf N storage
+ real(r8), pointer :: matrix_cap_leafn_xfer_patch (:) ! (gN/m2) Capacity of leaf N transfer
real(r8), pointer :: leafn_storage_xfer_acc_patch (:) ! (gN/m2) Accmulated leaf N transfer
real(r8), pointer :: storage_ndemand_patch (:) ! (gN/m2) N demand during the offset period
real(r8), pointer :: frootn_patch (:) ! (gN/m2) fine root N
real(r8), pointer :: frootn_storage_patch (:) ! (gN/m2) fine root N storage
real(r8), pointer :: frootn_xfer_patch (:) ! (gN/m2) fine root N transfer
+ real(r8), pointer :: matrix_cap_frootn_patch (:) ! (gN/m2) Capacity of fine root N
+ real(r8), pointer :: matrix_cap_frootn_storage_patch (:) ! (gN/m2) Capacity of fine root N storage
+ real(r8), pointer :: matrix_cap_frootn_xfer_patch (:) ! (gN/m2) Capacity of fine root N transfer
real(r8), pointer :: livestemn_patch (:) ! (gN/m2) live stem N
real(r8), pointer :: livestemn_storage_patch (:) ! (gN/m2) live stem N storage
real(r8), pointer :: livestemn_xfer_patch (:) ! (gN/m2) live stem N transfer
@@ -53,14 +62,46 @@ module CNVegNitrogenStateType
real(r8), pointer :: deadcrootn_patch (:) ! (gN/m2) dead coarse root N
real(r8), pointer :: deadcrootn_storage_patch (:) ! (gN/m2) dead coarse root N storage
real(r8), pointer :: deadcrootn_xfer_patch (:) ! (gN/m2) dead coarse root N transfer
+ real(r8), pointer :: matrix_cap_livestemn_patch (:) ! (gN/m2) Capacity of live stem N
+ real(r8), pointer :: matrix_cap_livestemn_storage_patch (:) ! (gN/m2) Capacity of live stem N storage
+ real(r8), pointer :: matrix_cap_livestemn_xfer_patch (:) ! (gN/m2) Capacity of live stem N transfer
+ real(r8), pointer :: matrix_cap_deadstemn_patch (:) ! (gN/m2) Capacity of dead stem N
+ real(r8), pointer :: matrix_cap_deadstemn_storage_patch (:) ! (gN/m2) Capacity of dead stem N storage
+ real(r8), pointer :: matrix_cap_deadstemn_xfer_patch (:) ! (gN/m2) Capacity of dead stem N transfer
+ real(r8), pointer :: matrix_cap_livecrootn_patch (:) ! (gN/m2) Capacity of live coarse root N
+ real(r8), pointer :: matrix_cap_livecrootn_storage_patch (:) ! (gN/m2) Capacity of live coarse root N storage
+ real(r8), pointer :: matrix_cap_livecrootn_xfer_patch (:) ! (gN/m2) Capacity of live coarse root N transfer
+ real(r8), pointer :: matrix_cap_deadcrootn_patch (:) ! (gN/m2) Capacity of dead coarse root N
+ real(r8), pointer :: matrix_cap_deadcrootn_storage_patch (:) ! (gN/m2) Capacity of dead coarse root N storage
+ real(r8), pointer :: matrix_cap_deadcrootn_xfer_patch (:) ! (gN/m2) Capacity of dead coarse root N transfer
real(r8), pointer :: retransn_patch (:) ! (gN/m2) plant pool of retranslocated N
real(r8), pointer :: npool_patch (:) ! (gN/m2) temporary plant N pool
real(r8), pointer :: ntrunc_patch (:) ! (gN/m2) patch-level sink for N truncation
real(r8), pointer :: cropseedn_deficit_patch (:) ! (gN/m2) pool for seeding new crop growth; this is a NEGATIVE term, indicating the amount of seed usage that needs to be repaid
real(r8), pointer :: seedn_grc (:) ! (gN/m2) gridcell-level pool for seeding new pFTs via dynamic landcover
-
- ! Matrix solution variables
- ! Matrix solution pool for initial state for matrix spinup
+! Pool for initial step of year for matrix
+ real(r8), pointer :: leafn0_patch (:) ! (gN/m2) Initial value of leaf N for SASU
+ real(r8), pointer :: leafn0_storage_patch (:) ! (gN/m2) Initial value of leaf N storage for SASU
+ real(r8), pointer :: leafn0_xfer_patch (:) ! (gN/m2) Initial value of leaf N transfer for SASU
+ real(r8), pointer :: frootn0_patch (:) ! (gN/m2) Initial value of fine root N for SASU
+ real(r8), pointer :: frootn0_storage_patch (:) ! (gN/m2) Initial value of fine root N storage for SASU
+ real(r8), pointer :: frootn0_xfer_patch (:) ! (gN/m2) Initial value of fine root N transfer for SASU
+ real(r8), pointer :: livestemn0_patch (:) ! (gN/m2) Initial value of live stem N for SASU
+ real(r8), pointer :: livestemn0_storage_patch (:) ! (gN/m2) Initial value of live stem N storage for SASU
+ real(r8), pointer :: livestemn0_xfer_patch (:) ! (gN/m2) Initial value of live stem N transfer for SASU
+ real(r8), pointer :: deadstemn0_patch (:) ! (gN/m2) Initial value of dead stem N for SASU
+ real(r8), pointer :: deadstemn0_storage_patch (:) ! (gN/m2) Initial value of dead stem N storage for SASU
+ real(r8), pointer :: deadstemn0_xfer_patch (:) ! (gN/m2) Initial value of dead stem N transfer for SASU
+ real(r8), pointer :: livecrootn0_patch (:) ! (gN/m2) Initial value of live coarse root N for SASU
+ real(r8), pointer :: livecrootn0_storage_patch (:) ! (gN/m2) Initial value of live coarse root N storage for SASU
+ real(r8), pointer :: livecrootn0_xfer_patch (:) ! (gN/m2) Initial value of live coarse root N transfer for SASU
+ real(r8), pointer :: deadcrootn0_patch (:) ! (gN/m2) Initial value of dead coarse root N for SASU
+ real(r8), pointer :: deadcrootn0_storage_patch (:) ! (gN/m2) Initial value of dead coarse root N storage for SASU
+ real(r8), pointer :: deadcrootn0_xfer_patch (:) ! (gN/m2) Initial value of dead coarse root N transfer for SASU
+ real(r8), pointer :: retransn0_patch (:) ! (gN/m2) Initial value of dead coarse root N transfer for SASU
+ real(r8), pointer :: repron0_patch (:) ! (gN/m2) Initial value of grain N for SASU
+ real(r8), pointer :: repron0_storage_patch (:) ! (gN/m2) Initial value of grain N storage for SASU
+ real(r8), pointer :: repron0_xfer_patch (:) ! (gN/m2) Initial value of grain N transfer for SASU
! summary (diagnostic) state variables, not involved in mass balance
real(r8), pointer :: dispvegn_patch (:) ! (gN/m2) displayed veg nitrogen, excluding storage
@@ -69,9 +110,102 @@ module CNVegNitrogenStateType
real(r8), pointer :: totvegn_col (:) ! (gN/m2) total vegetation nitrogen (p2c)
real(r8), pointer :: totn_patch (:) ! (gN/m2) total patch-level nitrogen
real(r8), pointer :: totn_p2c_col (:) ! (gN/m2) totn_patch averaged to col
-
-
- ! acc spinup for matrix solution
+ ! acc spinup for matrix solution
+ real(r8), pointer :: matrix_nalloc_leaf_acc_patch (:) ! (gN/m2/year) Input N allocated to leaf during this year
+ real(r8), pointer :: matrix_nalloc_leafst_acc_patch (:) ! (gN/m2/year) Input N allocated to leaf storage during this year
+ real(r8), pointer :: matrix_nalloc_froot_acc_patch (:) ! (gN/m2/year) Input N allocated to fine root during this year
+ real(r8), pointer :: matrix_nalloc_frootst_acc_patch (:) ! (gN/m2/year) Input N allocated to fine root storage during this year
+ real(r8), pointer :: matrix_nalloc_livestem_acc_patch (:) ! (gN/m2/year) Input N allocated to live stem during this year
+ real(r8), pointer :: matrix_nalloc_livestemst_acc_patch (:) ! (gN/m2/year) Input N allocated to live stem storage during this year
+ real(r8), pointer :: matrix_nalloc_deadstem_acc_patch (:) ! (gN/m2/year) Input N allocated to dead stem during this year
+ real(r8), pointer :: matrix_nalloc_deadstemst_acc_patch (:) ! (gN/m2/year) Input N allocated to dead stem storage during this year
+ real(r8), pointer :: matrix_nalloc_livecroot_acc_patch (:) ! (gN/m2/year) Input N allocated to live coarse root during this year
+ real(r8), pointer :: matrix_nalloc_livecrootst_acc_patch (:) ! (gN/m2/year) Input N allocated to live coarse root storage during this year
+ real(r8), pointer :: matrix_nalloc_deadcroot_acc_patch (:) ! (gN/m2/year) Input N allocated to dead coarse root during this year
+ real(r8), pointer :: matrix_nalloc_deadcrootst_acc_patch (:) ! (gN/m2/year) Input N allocated to dead coarse root storage during this year
+ real(r8), pointer :: matrix_nalloc_grain_acc_patch (:) ! (gN/m2/year) Input N allocated to grain during this year
+ real(r8), pointer :: matrix_nalloc_grainst_acc_patch (:) ! (gN/m2/year) Input N allocated to grain storage during this year
+
+ real(r8), pointer :: matrix_ntransfer_leafst_to_leafxf_acc_patch (:) ! (gN/m2/year) N transfer from leaf storage to leaf transfer pool during this year
+ real(r8), pointer :: matrix_ntransfer_leafxf_to_leaf_acc_patch (:) ! (gN/m2/year) N transfer from leaf transfer to leaf pool during this year
+ real(r8), pointer :: matrix_ntransfer_frootst_to_frootxf_acc_patch (:) ! (gN/m2/year) N transfer from fine root storage to fine root transfer pool during this year
+ real(r8), pointer :: matrix_ntransfer_frootxf_to_froot_acc_patch (:) ! (gN/m2/year) N transfer from fine root transfer to fine root pool during this year
+ real(r8), pointer :: matrix_ntransfer_livestemst_to_livestemxf_acc_patch (:) ! (gN/m2/year) N transfer from live stem storage to live stem transfer pool during this year
+ real(r8), pointer :: matrix_ntransfer_livestemxf_to_livestem_acc_patch (:) ! (gN/m2/year) N transfer from live stem transfer to live stem pool during this year
+ real(r8), pointer :: matrix_ntransfer_deadstemst_to_deadstemxf_acc_patch (:) ! (gN/m2/year) N transfer from dead stem storage to dead stem transfer pool during this year
+ real(r8), pointer :: matrix_ntransfer_deadstemxf_to_deadstem_acc_patch (:) ! (gN/m2/year) N transfer from dead stem transfer to dead stem pool during this year
+ real(r8), pointer :: matrix_ntransfer_livecrootst_to_livecrootxf_acc_patch (:) ! (gN/m2/year) N transfer from live coarse root storage to live coarse root transfer pool during this year
+ real(r8), pointer :: matrix_ntransfer_livecrootxf_to_livecroot_acc_patch (:) ! (gN/m2/year) N transfer from live coarse root transfer to live coarse root pool during this year
+ real(r8), pointer :: matrix_ntransfer_deadcrootst_to_deadcrootxf_acc_patch (:) ! (gN/m2/year) N transfer from dead coarse root storage to dead coarse root transfer pool during this year
+ real(r8), pointer :: matrix_ntransfer_deadcrootxf_to_deadcroot_acc_patch (:) ! (gN/m2/year) N transfer from dead coarse root transfer to dead coarse root pool during this year
+ real(r8), pointer :: matrix_ntransfer_grainst_to_grainxf_acc_patch (:) ! (gN/m2/year) N transfer from grain storage to grain transfer pool during this year
+ real(r8), pointer :: matrix_ntransfer_grainxf_to_grain_acc_patch (:) ! (gN/m2/year) N transfer from grain transfer to grain pool during this year
+ real(r8), pointer :: matrix_ntransfer_livestem_to_deadstem_acc_patch (:) ! (gN/m2/year) N transfer from live stem to dead stem pool during this year
+ real(r8), pointer :: matrix_ntransfer_livecroot_to_deadcroot_acc_patch (:) ! (gN/m2/year) N transfer from live coarse root to dead coarse root pool during this year
+
+ real(r8), pointer :: matrix_ntransfer_retransn_to_leaf_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to leaf pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_leafst_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to leaf storage pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_froot_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to fine root pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_frootst_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to fine root storage pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_livestem_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to live stem pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_livestemst_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to live stem storage pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_deadstem_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to dead stem pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_deadstemst_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to dead stem storage pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_livecroot_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to live coarse root pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_livecrootst_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to live coarse root storage pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_deadcroot_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to dead coarse root pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_deadcrootst_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to dead coarse root storage pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_grain_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to grain pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_grainst_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to grain storage pool during this year
+
+ real(r8), pointer :: matrix_ntransfer_leaf_to_retransn_acc_patch (:) ! (gN/m2/year) N transfer from leaf to retranslocation pool during this year
+ real(r8), pointer :: matrix_ntransfer_froot_to_retransn_acc_patch (:) ! (gN/m2/year) N transfer from fine root to retranslocation pool during this year
+ real(r8), pointer :: matrix_ntransfer_livestem_to_retransn_acc_patch (:) ! (gN/m2/year) N transfer from live stem to retranslocation pool during this year
+ real(r8), pointer :: matrix_ntransfer_livecroot_to_retransn_acc_patch (:) ! (gN/m2/year) N transfer from live coarse root to retranslocation pool during this year
+
+ real(r8), pointer :: matrix_nturnover_leaf_acc_patch (:) ! (gN/m2/year) N turnover from leaf
+ real(r8), pointer :: matrix_nturnover_leafst_acc_patch (:) ! (gN/m2/year) N turnover from leaf storage
+ real(r8), pointer :: matrix_nturnover_leafxf_acc_patch (:) ! (gN/m2/year) N turnover from leaf transfer
+ real(r8), pointer :: matrix_nturnover_froot_acc_patch (:) ! (gN/m2/year) N turnover from root
+ real(r8), pointer :: matrix_nturnover_frootst_acc_patch (:) ! (gN/m2/year) N turnover from root storage
+ real(r8), pointer :: matrix_nturnover_frootxf_acc_patch (:) ! (gN/m2/year) N turnover from root transfer
+ real(r8), pointer :: matrix_nturnover_livestem_acc_patch (:) ! (gN/m2/year) N turnover from live stem
+ real(r8), pointer :: matrix_nturnover_livestemst_acc_patch (:) ! (gN/m2/year) N turnover from live stem storage
+ real(r8), pointer :: matrix_nturnover_livestemxf_acc_patch (:) ! (gN/m2/year) N turnover from live stem transfer
+ real(r8), pointer :: matrix_nturnover_deadstem_acc_patch (:) ! (gN/m2/year) N turnover from dead stem
+ real(r8), pointer :: matrix_nturnover_deadstemst_acc_patch (:) ! (gN/m2/year) N turnover from dead stem storage
+ real(r8), pointer :: matrix_nturnover_deadstemxf_acc_patch (:) ! (gN/m2/year) N turnover from dead stem transfer
+ real(r8), pointer :: matrix_nturnover_livecroot_acc_patch (:) ! (gN/m2/year) N turnover from live coarse root
+ real(r8), pointer :: matrix_nturnover_livecrootst_acc_patch (:) ! (gN/m2/year) N turnover from live coarse root storage
+ real(r8), pointer :: matrix_nturnover_livecrootxf_acc_patch (:) ! (gN/m2/year) N turnover from live coarse root transfer
+ real(r8), pointer :: matrix_nturnover_deadcroot_acc_patch (:) ! (gN/m2/year) N turnover from dead coarse root
+ real(r8), pointer :: matrix_nturnover_deadcrootst_acc_patch (:) ! (gN/m2/year) N turnover from dead coarse root storage
+ real(r8), pointer :: matrix_nturnover_deadcrootxf_acc_patch (:) ! (gN/m2/year) N turnover from dead coarse root transfer
+ real(r8), pointer :: matrix_nturnover_grain_acc_patch (:) ! (gN/m2/year) N turnover from grain
+ real(r8), pointer :: matrix_nturnover_grainst_acc_patch (:) ! (gN/m2/year) N turnover from grain storage
+ real(r8), pointer :: matrix_nturnover_grainxf_acc_patch (:) ! (gN/m2/year) N turnover from grain transfer
+ real(r8), pointer :: matrix_nturnover_retransn_acc_patch (:) ! (gN/m2/year) N turnover from retranslocation transfer
+
+ real(r8), pointer :: grainn_SASUsave_patch (:) ! (gC/m2) grain C (crop model)
+ real(r8), pointer :: grainn_storage_SASUsave_patch (:) ! (gC/m2) grain C storage (crop model)
+ real(r8), pointer :: leafn_SASUsave_patch (:) ! (gC/m2) leaf C
+ real(r8), pointer :: leafn_storage_SASUsave_patch (:) ! (gC/m2) leaf C storage
+ real(r8), pointer :: leafn_xfer_SASUsave_patch (:) ! (gC/m2) leaf C transfer
+ real(r8), pointer :: frootn_SASUsave_patch (:) ! (gC/m2) fine root C
+ real(r8), pointer :: frootn_storage_SASUsave_patch (:) ! (gC/m2) fine root C storage
+ real(r8), pointer :: frootn_xfer_SASUsave_patch (:) ! (gC/m2) fine root C transfer
+ real(r8), pointer :: livestemn_SASUsave_patch (:) ! (gC/m2) live stem C
+ real(r8), pointer :: livestemn_storage_SASUsave_patch (:) ! (gC/m2) live stem C storage
+ real(r8), pointer :: livestemn_xfer_SASUsave_patch (:) ! (gC/m2) live stem C transfer
+ real(r8), pointer :: deadstemn_SASUsave_patch (:) ! (gC/m2) dead stem C
+ real(r8), pointer :: deadstemn_storage_SASUsave_patch (:) ! (gC/m2) dead stem C storage
+ real(r8), pointer :: deadstemn_xfer_SASUsave_patch (:) ! (gC/m2) dead stem C transfer
+ real(r8), pointer :: livecrootn_SASUsave_patch (:) ! (gC/m2) live coarse root C
+ real(r8), pointer :: livecrootn_storage_SASUsave_patch (:) ! (gC/m2) live coarse root C storage
+ real(r8), pointer :: livecrootn_xfer_SASUsave_patch (:) ! (gC/m2) live coarse root C transfer
+ real(r8), pointer :: deadcrootn_SASUsave_patch (:) ! (gC/m2) dead coarse root C
+ real(r8), pointer :: deadcrootn_storage_SASUsave_patch (:) ! (gC/m2) dead coarse root C storage
+ real(r8), pointer :: deadcrootn_xfer_SASUsave_patch (:) ! (gC/m2) dead coarse root C transfer
contains
@@ -142,14 +276,29 @@ subroutine InitAllocate(this, bounds, alloc_full_veg)
allocate(this%reproductiven_patch (begp:endp, nrepr)) ; this%reproductiven_patch (:,:) = nan
allocate(this%reproductiven_storage_patch (begp:endp, nrepr)) ; this%reproductiven_storage_patch (:,:) = nan
allocate(this%reproductiven_xfer_patch (begp:endp, nrepr)) ; this%reproductiven_xfer_patch (:,:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_repron_patch (begp:endp)) ; this%matrix_cap_repron_patch (:) = nan
+ allocate(this%matrix_cap_repron_storage_patch (begp:endp)) ; this%matrix_cap_repron_storage_patch (:) = nan
+ allocate(this%matrix_cap_repron_xfer_patch (begp:endp)) ; this%matrix_cap_repron_xfer_patch (:) = nan
+ end if
allocate(this%leafn_patch (begp:endp)) ; this%leafn_patch (:) = nan
allocate(this%leafn_storage_patch (begp:endp)) ; this%leafn_storage_patch (:) = nan
allocate(this%leafn_xfer_patch (begp:endp)) ; this%leafn_xfer_patch (:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_leafn_patch (begp:endp)) ; this%matrix_cap_leafn_patch (:) = nan
+ allocate(this%matrix_cap_leafn_storage_patch (begp:endp)) ; this%matrix_cap_leafn_storage_patch (:) = nan
+ allocate(this%matrix_cap_leafn_xfer_patch (begp:endp)) ; this%matrix_cap_leafn_xfer_patch (:) = nan
+ end if
allocate(this%leafn_storage_xfer_acc_patch (begp:endp)) ; this%leafn_storage_xfer_acc_patch (:) = nan
allocate(this%storage_ndemand_patch (begp:endp)) ; this%storage_ndemand_patch (:) = nan
allocate(this%frootn_patch (begp:endp)) ; this%frootn_patch (:) = nan
allocate(this%frootn_storage_patch (begp:endp)) ; this%frootn_storage_patch (:) = nan
allocate(this%frootn_xfer_patch (begp:endp)) ; this%frootn_xfer_patch (:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_frootn_patch (begp:endp)) ; this%matrix_cap_frootn_patch (:) = nan
+ allocate(this%matrix_cap_frootn_storage_patch (begp:endp)) ; this%matrix_cap_frootn_storage_patch (:) = nan
+ allocate(this%matrix_cap_frootn_xfer_patch (begp:endp)) ; this%matrix_cap_frootn_xfer_patch (:) = nan
+ end if
allocate(this%livestemn_patch (begp:endp)) ; this%livestemn_patch (:) = nan
allocate(this%livestemn_storage_patch (begp:endp)) ; this%livestemn_storage_patch (:) = nan
allocate(this%livestemn_xfer_patch (begp:endp)) ; this%livestemn_xfer_patch (:) = nan
@@ -162,6 +311,20 @@ subroutine InitAllocate(this, bounds, alloc_full_veg)
allocate(this%deadcrootn_patch (begp:endp)) ; this%deadcrootn_patch (:) = nan
allocate(this%deadcrootn_storage_patch (begp:endp)) ; this%deadcrootn_storage_patch (:) = nan
allocate(this%deadcrootn_xfer_patch (begp:endp)) ; this%deadcrootn_xfer_patch (:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_livestemn_patch (begp:endp)) ; this%matrix_cap_livestemn_patch (:) = nan
+ allocate(this%matrix_cap_livestemn_storage_patch (begp:endp)) ; this%matrix_cap_livestemn_storage_patch (:) = nan
+ allocate(this%matrix_cap_livestemn_xfer_patch (begp:endp)) ; this%matrix_cap_livestemn_xfer_patch (:) = nan
+ allocate(this%matrix_cap_deadstemn_patch (begp:endp)) ; this%matrix_cap_deadstemn_patch (:) = nan
+ allocate(this%matrix_cap_deadstemn_storage_patch (begp:endp)) ; this%matrix_cap_deadstemn_storage_patch (:) = nan
+ allocate(this%matrix_cap_deadstemn_xfer_patch (begp:endp)) ; this%matrix_cap_deadstemn_xfer_patch (:) = nan
+ allocate(this%matrix_cap_livecrootn_patch (begp:endp)) ; this%matrix_cap_livecrootn_patch (:) = nan
+ allocate(this%matrix_cap_livecrootn_storage_patch (begp:endp)) ; this%matrix_cap_livecrootn_storage_patch (:) = nan
+ allocate(this%matrix_cap_livecrootn_xfer_patch (begp:endp)) ; this%matrix_cap_livecrootn_xfer_patch (:) = nan
+ allocate(this%matrix_cap_deadcrootn_patch (begp:endp)) ; this%matrix_cap_deadcrootn_patch (:) = nan
+ allocate(this%matrix_cap_deadcrootn_storage_patch (begp:endp)) ; this%matrix_cap_deadcrootn_storage_patch (:) = nan
+ allocate(this%matrix_cap_deadcrootn_xfer_patch (begp:endp)) ; this%matrix_cap_deadcrootn_xfer_patch (:) = nan
+ end if
allocate(this%retransn_patch (begp:endp)) ; this%retransn_patch (:) = nan
allocate(this%npool_patch (begp:endp)) ; this%npool_patch (:) = nan
allocate(this%ntrunc_patch (begp:endp)) ; this%ntrunc_patch (:) = nan
@@ -176,8 +339,125 @@ subroutine InitAllocate(this, bounds, alloc_full_veg)
allocate(this%totn_p2c_col (begc:endc)) ; this%totn_p2c_col (:) = nan
- ! Matrix solution allocations
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ allocate(this%leafn0_patch (begp:endp)) ; this%leafn0_patch (:) = nan
+ allocate(this%leafn0_storage_patch (begp:endp)) ; this%leafn0_storage_patch (:) = nan
+ allocate(this%leafn0_xfer_patch (begp:endp)) ; this%leafn0_xfer_patch (:) = nan
+ allocate(this%frootn0_patch (begp:endp)) ; this%frootn0_patch (:) = nan
+ allocate(this%frootn0_storage_patch (begp:endp)) ; this%frootn0_storage_patch (:) = nan
+ allocate(this%frootn0_xfer_patch (begp:endp)) ; this%frootn0_xfer_patch (:) = nan
+ allocate(this%livestemn0_patch (begp:endp)) ; this%livestemn0_patch (:) = nan
+ allocate(this%livestemn0_storage_patch (begp:endp)) ; this%livestemn0_storage_patch (:) = nan
+ allocate(this%livestemn0_xfer_patch (begp:endp)) ; this%livestemn0_xfer_patch (:) = nan
+ allocate(this%deadstemn0_patch (begp:endp)) ; this%deadstemn0_patch (:) = nan
+ allocate(this%deadstemn0_storage_patch (begp:endp)) ; this%deadstemn0_storage_patch (:) = nan
+ allocate(this%deadstemn0_xfer_patch (begp:endp)) ; this%deadstemn0_xfer_patch (:) = nan
+ allocate(this%livecrootn0_patch (begp:endp)) ; this%livecrootn0_patch (:) = nan
+ allocate(this%livecrootn0_storage_patch (begp:endp)) ; this%livecrootn0_storage_patch (:) = nan
+ allocate(this%livecrootn0_xfer_patch (begp:endp)) ; this%livecrootn0_xfer_patch (:) = nan
+ allocate(this%deadcrootn0_patch (begp:endp)) ; this%deadcrootn0_patch (:) = nan
+ allocate(this%deadcrootn0_storage_patch (begp:endp)) ; this%deadcrootn0_storage_patch (:) = nan
+ allocate(this%deadcrootn0_xfer_patch (begp:endp)) ; this%deadcrootn0_xfer_patch (:) = nan
+ allocate(this%repron0_patch (begp:endp)) ; this%repron0_patch (:) = nan
+ allocate(this%repron0_storage_patch (begp:endp)) ; this%repron0_storage_patch (:) = nan
+ allocate(this%repron0_xfer_patch (begp:endp)) ; this%repron0_xfer_patch (:) = nan
+ allocate(this%retransn0_patch (begp:endp)) ; this%retransn0_patch (:) = nan
+
+ allocate(this%leafn_SASUsave_patch (begp:endp)) ; this%leafn_SASUsave_patch (:) = nan
+ allocate(this%leafn_storage_SASUsave_patch (begp:endp)) ; this%leafn_storage_SASUsave_patch (:) = nan
+ allocate(this%leafn_xfer_SASUsave_patch (begp:endp)) ; this%leafn_xfer_SASUsave_patch (:) = nan
+ allocate(this%frootn_SASUsave_patch (begp:endp)) ; this%frootn_SASUsave_patch (:) = nan
+ allocate(this%frootn_storage_SASUsave_patch (begp:endp)) ; this%frootn_storage_SASUsave_patch (:) = nan
+ allocate(this%frootn_xfer_SASUsave_patch (begp:endp)) ; this%frootn_xfer_SASUsave_patch (:) = nan
+ allocate(this%livestemn_SASUsave_patch (begp:endp)) ; this%livestemn_SASUsave_patch (:) = nan
+ allocate(this%livestemn_storage_SASUsave_patch (begp:endp)) ; this%livestemn_storage_SASUsave_patch (:) = nan
+ allocate(this%livestemn_xfer_SASUsave_patch (begp:endp)) ; this%livestemn_xfer_SASUsave_patch (:) = nan
+ allocate(this%deadstemn_SASUsave_patch (begp:endp)) ; this%deadstemn_SASUsave_patch (:) = nan
+ allocate(this%deadstemn_storage_SASUsave_patch (begp:endp)) ; this%deadstemn_storage_SASUsave_patch (:) = nan
+ allocate(this%deadstemn_xfer_SASUsave_patch (begp:endp)) ; this%deadstemn_xfer_SASUsave_patch (:) = nan
+ allocate(this%livecrootn_SASUsave_patch (begp:endp)) ; this%livecrootn_SASUsave_patch (:) = nan
+ allocate(this%livecrootn_storage_SASUsave_patch (begp:endp)) ; this%livecrootn_storage_SASUsave_patch (:) = nan
+ allocate(this%livecrootn_xfer_SASUsave_patch (begp:endp)) ; this%livecrootn_xfer_SASUsave_patch (:) = nan
+ allocate(this%deadcrootn_SASUsave_patch (begp:endp)) ; this%deadcrootn_SASUsave_patch (:) = nan
+ allocate(this%deadcrootn_storage_SASUsave_patch (begp:endp)) ; this%deadcrootn_storage_SASUsave_patch (:) = nan
+ allocate(this%deadcrootn_xfer_SASUsave_patch (begp:endp)) ; this%deadcrootn_xfer_SASUsave_patch (:) = nan
+ allocate(this%grainn_SASUsave_patch (begp:endp)) ; this%grainn_SASUsave_patch (:) = nan
+ allocate(this%grainn_storage_SASUsave_patch (begp:endp)) ; this%grainn_storage_SASUsave_patch (:) = nan
+
+ allocate(this%matrix_nalloc_leaf_acc_patch (begp:endp)) ; this%matrix_nalloc_leaf_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_leafst_acc_patch (begp:endp)) ; this%matrix_nalloc_leafst_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_froot_acc_patch (begp:endp)) ; this%matrix_nalloc_froot_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_frootst_acc_patch (begp:endp)) ; this%matrix_nalloc_frootst_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_livestem_acc_patch (begp:endp)) ; this%matrix_nalloc_livestem_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_livestemst_acc_patch (begp:endp)) ; this%matrix_nalloc_livestemst_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_deadstem_acc_patch (begp:endp)) ; this%matrix_nalloc_deadstem_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_deadstemst_acc_patch (begp:endp)) ; this%matrix_nalloc_deadstemst_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_livecroot_acc_patch (begp:endp)) ; this%matrix_nalloc_livecroot_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_livecrootst_acc_patch (begp:endp)) ; this%matrix_nalloc_livecrootst_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_deadcroot_acc_patch (begp:endp)) ; this%matrix_nalloc_deadcroot_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_deadcrootst_acc_patch (begp:endp)) ; this%matrix_nalloc_deadcrootst_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_grain_acc_patch (begp:endp)) ; this%matrix_nalloc_grain_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_grainst_acc_patch (begp:endp)) ; this%matrix_nalloc_grainst_acc_patch (:) = nan
+
+ allocate(this%matrix_ntransfer_leafst_to_leafxf_acc_patch (begp:endp)) ; this%matrix_ntransfer_leafst_to_leafxf_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_leafxf_to_leaf_acc_patch (begp:endp)) ; this%matrix_ntransfer_leafxf_to_leaf_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_frootst_to_frootxf_acc_patch (begp:endp)) ; this%matrix_ntransfer_frootst_to_frootxf_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_frootxf_to_froot_acc_patch (begp:endp)) ; this%matrix_ntransfer_frootxf_to_froot_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_livestemst_to_livestemxf_acc_patch (begp:endp)) ; this%matrix_ntransfer_livestemst_to_livestemxf_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_livestemxf_to_livestem_acc_patch (begp:endp)) ; this%matrix_ntransfer_livestemxf_to_livestem_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_deadstemst_to_deadstemxf_acc_patch (begp:endp)) ; this%matrix_ntransfer_deadstemst_to_deadstemxf_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_deadstemxf_to_deadstem_acc_patch (begp:endp)) ; this%matrix_ntransfer_deadstemxf_to_deadstem_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_livecrootst_to_livecrootxf_acc_patch (begp:endp)) ; this%matrix_ntransfer_livecrootst_to_livecrootxf_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_livecrootxf_to_livecroot_acc_patch (begp:endp)) ; this%matrix_ntransfer_livecrootxf_to_livecroot_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_deadcrootst_to_deadcrootxf_acc_patch (begp:endp)) ; this%matrix_ntransfer_deadcrootst_to_deadcrootxf_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_deadcrootxf_to_deadcroot_acc_patch (begp:endp)) ; this%matrix_ntransfer_deadcrootxf_to_deadcroot_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_grainst_to_grainxf_acc_patch (begp:endp)) ; this%matrix_ntransfer_grainst_to_grainxf_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_grainxf_to_grain_acc_patch (begp:endp)) ; this%matrix_ntransfer_grainxf_to_grain_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_livestem_to_deadstem_acc_patch (begp:endp)) ; this%matrix_ntransfer_livestem_to_deadstem_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_livecroot_to_deadcroot_acc_patch (begp:endp)) ; this%matrix_ntransfer_livecroot_to_deadcroot_acc_patch (:) = nan
+
+ allocate(this%matrix_ntransfer_retransn_to_leaf_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_leaf_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_leafst_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_leafst_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_froot_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_froot_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_frootst_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_frootst_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_livestem_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_livestem_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_livestemst_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_livestemst_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_deadstem_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_deadstem_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_deadstemst_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_deadstemst_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_livecroot_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_livecroot_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_livecrootst_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_livecrootst_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_deadcroot_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_deadcroot_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_deadcrootst_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_deadcrootst_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_grain_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_grain_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_grainst_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_grainst_acc_patch (:) = nan
+
+ allocate(this%matrix_ntransfer_leaf_to_retransn_acc_patch (begp:endp)) ; this%matrix_ntransfer_leaf_to_retransn_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_froot_to_retransn_acc_patch (begp:endp)) ; this%matrix_ntransfer_froot_to_retransn_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_livestem_to_retransn_acc_patch (begp:endp)) ; this%matrix_ntransfer_livestem_to_retransn_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_livecroot_to_retransn_acc_patch (begp:endp)) ; this%matrix_ntransfer_livecroot_to_retransn_acc_patch (:) = nan
+
+ allocate(this%matrix_nturnover_leaf_acc_patch (begp:endp)) ; this%matrix_nturnover_leaf_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_leafst_acc_patch (begp:endp)) ; this%matrix_nturnover_leafst_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_leafxf_acc_patch (begp:endp)) ; this%matrix_nturnover_leafxf_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_froot_acc_patch (begp:endp)) ; this%matrix_nturnover_froot_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_frootst_acc_patch (begp:endp)) ; this%matrix_nturnover_frootst_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_frootxf_acc_patch (begp:endp)) ; this%matrix_nturnover_frootxf_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_livestem_acc_patch (begp:endp)) ; this%matrix_nturnover_livestem_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_livestemst_acc_patch (begp:endp)) ; this%matrix_nturnover_livestemst_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_livestemxf_acc_patch (begp:endp)) ; this%matrix_nturnover_livestemxf_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_deadstem_acc_patch (begp:endp)) ; this%matrix_nturnover_deadstem_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_deadstemst_acc_patch (begp:endp)) ; this%matrix_nturnover_deadstemst_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_deadstemxf_acc_patch (begp:endp)) ; this%matrix_nturnover_deadstemxf_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_livecroot_acc_patch (begp:endp)) ; this%matrix_nturnover_livecroot_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_livecrootst_acc_patch (begp:endp)) ; this%matrix_nturnover_livecrootst_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_livecrootxf_acc_patch (begp:endp)) ; this%matrix_nturnover_livecrootxf_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_deadcroot_acc_patch (begp:endp)) ; this%matrix_nturnover_deadcroot_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_deadcrootst_acc_patch (begp:endp)) ; this%matrix_nturnover_deadcrootst_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_deadcrootxf_acc_patch (begp:endp)) ; this%matrix_nturnover_deadcrootxf_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_grain_acc_patch (begp:endp)) ; this%matrix_nturnover_grain_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_grainst_acc_patch (begp:endp)) ; this%matrix_nturnover_grainst_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_grainxf_acc_patch (begp:endp)) ; this%matrix_nturnover_grainxf_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_retransn_acc_patch (begp:endp)) ; this%matrix_nturnover_retransn_acc_patch (:) = nan
end if
end subroutine InitAllocate
@@ -246,8 +526,22 @@ subroutine InitHistory(this, bounds)
avgflag='A', long_name='leaf N transfer', &
ptr_patch=this%leafn_xfer_patch, default='inactive')
- ! Matrix solution history fields
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafn_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LEAFN_CAP', units='gN/m^2', &
+ avgflag='I', long_name='leaf N capacity', &
+ ptr_patch=this%matrix_cap_leafn_patch)
+
+ this%matrix_cap_leafn_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LEAFN_STORAGE_CAP', units='gN/m^2', &
+ avgflag='I', long_name='leaf N storage capacity', &
+ ptr_patch=this%matrix_cap_leafn_storage_patch, default='inactive')
+
+ this%matrix_cap_leafn_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LEAFN_XFER_CAP', units='gN/m^2', &
+ avgflag='I', long_name='leaf N transfer capacity', &
+ ptr_patch=this%matrix_cap_leafn_xfer_patch, default='inactive')
+
end if
if ( use_fun ) then
@@ -277,6 +571,24 @@ subroutine InitHistory(this, bounds)
avgflag='A', long_name='fine root N transfer', &
ptr_patch=this%frootn_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_frootn_patch(begp:endp) = spval
+ call hist_addfld1d (fname='FROOTN_CAP', units='gN/m^2', &
+ avgflag='I', long_name='fine root N capacity', &
+ ptr_patch=this%matrix_cap_frootn_patch)
+
+ this%matrix_cap_frootn_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='FROOTN_STORAGE_CAP', units='gN/m^2', &
+ avgflag='I', long_name='fine root N storage capacity', &
+ ptr_patch=this%matrix_cap_frootn_storage_patch, default='inactive')
+
+ this%matrix_cap_frootn_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='FROOTN_XFER_CAP', units='gN/m^2', &
+ avgflag='I', long_name='fine root N transfer capacity', &
+ ptr_patch=this%matrix_cap_frootn_xfer_patch, default='inactive')
+
+ end if
+
this%livestemn_patch(begp:endp) = spval
call hist_addfld1d (fname='LIVESTEMN', units='gN/m^2', &
avgflag='A', long_name='live stem N', &
@@ -292,6 +604,24 @@ subroutine InitHistory(this, bounds)
avgflag='A', long_name='live stem N transfer', &
ptr_patch=this%livestemn_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_livestemn_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVESTEMN_CAP', units='gN/m^2', &
+ avgflag='I', long_name='live stem N capacity', &
+ ptr_patch=this%matrix_cap_livestemn_patch)
+
+ this%matrix_cap_livestemn_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVESTEMN_STORAGE_CAP', units='gN/m^2', &
+ avgflag='I', long_name='live stem N storage capacity', &
+ ptr_patch=this%matrix_cap_livestemn_storage_patch, default='inactive')
+
+ this%matrix_cap_livestemn_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVESTEMN_XFER_CAP', units='gN/m^2', &
+ avgflag='I', long_name='live stem N transfer capacity', &
+ ptr_patch=this%matrix_cap_livestemn_xfer_patch, default='inactive')
+
+ end if
+
this%deadstemn_patch(begp:endp) = spval
call hist_addfld1d (fname='DEADSTEMN', units='gN/m^2', &
avgflag='A', long_name='dead stem N', &
@@ -307,6 +637,24 @@ subroutine InitHistory(this, bounds)
avgflag='A', long_name='dead stem N transfer', &
ptr_patch=this%deadstemn_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemn_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADSTEMN_CAP', units='gN/m^2', &
+ avgflag='I', long_name='dead stem N capacity', &
+ ptr_patch=this%matrix_cap_deadstemn_patch)
+
+ this%matrix_cap_deadstemn_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADSTEMN_STORAGE_CAP', units='gN/m^2', &
+ avgflag='I', long_name='dead stem N storage capacity', &
+ ptr_patch=this%matrix_cap_deadstemn_storage_patch, default='inactive')
+
+ this%matrix_cap_deadstemn_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADSTEMN_XFER_CAP', units='gN/m^2', &
+ avgflag='I', long_name='dead stem N transfer capacity', &
+ ptr_patch=this%matrix_cap_deadstemn_xfer_patch, default='inactive')
+
+ end if
+
this%livecrootn_patch(begp:endp) = spval
call hist_addfld1d (fname='LIVECROOTN', units='gN/m^2', &
avgflag='A', long_name='live coarse root N', &
@@ -322,6 +670,24 @@ subroutine InitHistory(this, bounds)
avgflag='A', long_name='live coarse root N transfer', &
ptr_patch=this%livecrootn_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_livecrootn_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVECROOTN_CAP', units='gN/m^2', &
+ avgflag='I', long_name='live coarse root N capacity', &
+ ptr_patch=this%matrix_cap_livecrootn_patch)
+
+ this%matrix_cap_livecrootn_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVECROOTN_STORAGE_CAP', units='gN/m^2', &
+ avgflag='I', long_name='live coarse root N storage capacity', &
+ ptr_patch=this%matrix_cap_livecrootn_storage_patch, default='inactive')
+
+ this%matrix_cap_livecrootn_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVECROOTN_XFER_CAP', units='gN/m^2', &
+ avgflag='I', long_name='live coarse root N transfer capacity', &
+ ptr_patch=this%matrix_cap_livecrootn_xfer_patch, default='inactive')
+
+ end if
+
this%deadcrootn_patch(begp:endp) = spval
call hist_addfld1d (fname='DEADCROOTN', units='gN/m^2', &
avgflag='A', long_name='dead coarse root N', &
@@ -337,6 +703,24 @@ subroutine InitHistory(this, bounds)
avgflag='A', long_name='dead coarse root N transfer', &
ptr_patch=this%deadcrootn_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_deadcrootn_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADCROOTN_CAP', units='gN/m^2', &
+ avgflag='I', long_name='dead coarse root N capacity', &
+ ptr_patch=this%matrix_cap_deadcrootn_patch)
+
+ this%matrix_cap_deadcrootn_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADCROOTN_STORAGE_CAP', units='gN/m^2', &
+ avgflag='I', long_name='dead coarse root N storage capacity', &
+ ptr_patch=this%matrix_cap_deadcrootn_storage_patch, default='inactive')
+
+ this%matrix_cap_deadcrootn_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADCROOTN_XFER_CAP', units='gN/m^2', &
+ avgflag='I', long_name='dead coarse root N transfer capacity', &
+ ptr_patch=this%matrix_cap_deadcrootn_xfer_patch, default='inactive')
+
+ end if
+
this%retransn_patch(begp:endp) = spval
call hist_addfld1d (fname='RETRANSN', units='gN/m^2', &
avgflag='A', long_name='plant pool of retranslocated N', &
@@ -450,37 +834,38 @@ subroutine InitCold(this, bounds, &
if (patch%itype(p) == noveg) then
this%leafn_patch(p) = 0._r8
this%leafn_storage_patch(p) = 0._r8
-
- ! Matrix solution settings for bare-soil
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafn_patch(p) = 0._r8
+ this%matrix_cap_leafn_storage_patch(p) = 0._r8
end if
if (MM_Nuptake_opt .eqv. .true.) then
this%frootn_patch(p) = 0._r8
this%frootn_storage_patch(p) = 0._r8
-
- ! Matrix solution settings for bare-soil and flex-CN
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_frootn_patch(p) = 0._r8
+ this%matrix_cap_frootn_storage_patch(p) = 0._r8
end if
end if
else
this%leafn_patch(p) = leafc_patch(p) / pftcon%leafcn(patch%itype(p))
this%leafn_storage_patch(p) = leafc_storage_patch(p) / pftcon%leafcn(patch%itype(p))
-
- ! Matrix solution settings
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafn_patch(p) = leafc_patch(p) / pftcon%leafcn(patch%itype(p))
+ this%matrix_cap_leafn_storage_patch(p) = leafc_storage_patch(p) / pftcon%leafcn(patch%itype(p))
end if
if (MM_Nuptake_opt .eqv. .true.) then
this%frootn_patch(p) = frootc_patch(p) / pftcon%frootcn(patch%itype(p))
this%frootn_storage_patch(p) = frootc_storage_patch(p) / pftcon%frootcn(patch%itype(p))
- ! Matrix solution settings for flex-CN
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_frootn_patch(p) = frootc_patch(p) / pftcon%frootcn(patch%itype(p))
+ this%matrix_cap_frootn_storage_patch(p) = frootc_storage_patch(p) / pftcon%frootcn(patch%itype(p))
end if
end if
end if
this%leafn_xfer_patch(p) = 0._r8
- ! Matrix solution settings
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafn_xfer_patch(p) = 0._r8
end if
this%leafn_storage_xfer_acc_patch(p) = 0._r8
@@ -490,27 +875,30 @@ subroutine InitCold(this, bounds, &
this%reproductiven_patch(p,:) = 0._r8
this%reproductiven_storage_patch(p,:) = 0._r8
this%reproductiven_xfer_patch(p,:) = 0._r8
- this%cropseedn_deficit_patch(p) = 0._r8
-
- ! Matrix reproductive pool settings
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_repron_patch(p) = 0._r8
+ this%matrix_cap_repron_storage_patch(p) = 0._r8
+ this%matrix_cap_repron_xfer_patch(p) = 0._r8
end if
+ this%cropseedn_deficit_patch(p) = 0._r8
end if
if (MM_Nuptake_opt .eqv. .false.) then ! if not running in floating CN ratio option
this%frootn_patch(p) = 0._r8
this%frootn_storage_patch(p) = 0._r8
-
- ! Matrix pool settings
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_frootn_patch(p) = 0._r8
+ this%matrix_cap_frootn_storage_patch(p) = 0._r8
end if
end if
this%frootn_xfer_patch(p) = 0._r8
this%livestemn_patch(p) = 0._r8
this%livestemn_storage_patch(p) = 0._r8
this%livestemn_xfer_patch(p) = 0._r8
-
- ! Matrix pool settings
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_frootn_xfer_patch(p) = 0._r8
+ this%matrix_cap_livestemn_patch(p) = 0._r8
+ this%matrix_cap_livestemn_storage_patch(p) = 0._r8
+ this%matrix_cap_livestemn_xfer_patch(p) = 0._r8
end if
! tree types need to be initialized with some stem mass so that
@@ -518,17 +906,21 @@ subroutine InitCold(this, bounds, &
if (pftcon%woody(patch%itype(p)) == 1._r8) then
this%deadstemn_patch(p) = deadstemc_patch(p) / pftcon%deadwdcn(patch%itype(p))
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemn_patch(p) = deadstemc_patch(p) / pftcon%deadwdcn(patch%itype(p))
end if
else
this%deadstemn_patch(p) = 0._r8
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemn_patch(p) = 0._r8
end if
end if
this%deadstemn_storage_patch(p) = 0._r8
this%deadstemn_xfer_patch(p) = 0._r8
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemn_storage_patch(p) = 0._r8
+ this%matrix_cap_deadstemn_xfer_patch(p) = 0._r8
end if
this%livecrootn_patch(p) = 0._r8
@@ -537,6 +929,14 @@ subroutine InitCold(this, bounds, &
this%deadcrootn_patch(p) = 0._r8
this%deadcrootn_storage_patch(p) = 0._r8
this%deadcrootn_xfer_patch(p) = 0._r8
+ if(use_matrixcn)then
+ this%matrix_cap_livecrootn_patch(p) = 0._r8
+ this%matrix_cap_livecrootn_storage_patch(p) = 0._r8
+ this%matrix_cap_livecrootn_xfer_patch(p) = 0._r8
+ this%matrix_cap_deadcrootn_patch(p) = 0._r8
+ this%matrix_cap_deadcrootn_storage_patch(p) = 0._r8
+ this%matrix_cap_deadcrootn_xfer_patch(p) = 0._r8
+ end if
this%retransn_patch(p) = 0._r8
this%npool_patch(p) = 0._r8
this%ntrunc_patch(p) = 0._r8
@@ -544,6 +944,128 @@ subroutine InitCold(this, bounds, &
this%storvegn_patch(p) = 0._r8
this%totvegn_patch(p) = 0._r8
this%totn_patch(p) = 0._r8
+
+ if(use_matrixcn)then
+ ! for matrix spin up and capacity calculation
+ this%leafn0_patch(p) = 1.e-30_r8
+ this%leafn0_storage_patch(p) = 1.e-30_r8
+ this%leafn0_xfer_patch(p) = 1.e-30_r8
+ this%frootn0_patch(p) = 1.e-30_r8
+ this%frootn0_storage_patch(p) = 1.e-30_r8
+ this%frootn0_xfer_patch(p) = 1.e-30_r8
+ this%livestemn0_patch(p) = 1.e-30_r8
+ this%livestemn0_storage_patch(p) = 1.e-30_r8
+ this%livestemn0_xfer_patch(p) = 1.e-30_r8
+ this%deadstemn0_patch(p) = 1.e-30_r8
+ this%deadstemn0_storage_patch(p) = 1.e-30_r8
+ this%deadstemn0_xfer_patch(p) = 1.e-30_r8
+ this%livecrootn0_patch(p) = 1.e-30_r8
+ this%livecrootn0_storage_patch(p) = 1.e-30_r8
+ this%livecrootn0_xfer_patch(p) = 1.e-30_r8
+ this%deadcrootn0_patch(p) = 1.e-30_r8
+ this%deadcrootn0_storage_patch(p) = 1.e-30_r8
+ this%deadcrootn0_xfer_patch(p) = 1.e-30_r8
+ this%repron0_patch(p) = 1.e-30_r8
+ this%repron0_storage_patch(p) = 1.e-30_r8
+ this%repron0_xfer_patch(p) = 1.e-30_r8
+ this%retransn0_patch(p) = 1.e-30_r8
+
+ this%leafn_SASUsave_patch(p) = 0._r8
+ this%leafn_storage_SASUsave_patch(p) = 0._r8
+ this%leafn_xfer_SASUsave_patch(p) = 0._r8
+ this%frootn_SASUsave_patch(p) = 0._r8
+ this%frootn_storage_SASUsave_patch(p) = 0._r8
+ this%frootn_xfer_SASUsave_patch(p) = 0._r8
+ this%livestemn_SASUsave_patch(p) = 0._r8
+ this%livestemn_storage_SASUsave_patch(p) = 0._r8
+ this%livestemn_xfer_SASUsave_patch(p) = 0._r8
+ this%deadstemn_SASUsave_patch(p) = 0._r8
+ this%deadstemn_storage_SASUsave_patch(p) = 0._r8
+ this%deadstemn_xfer_SASUsave_patch(p) = 0._r8
+ this%livecrootn_SASUsave_patch(p) = 0._r8
+ this%livecrootn_storage_SASUsave_patch(p) = 0._r8
+ this%livecrootn_xfer_SASUsave_patch(p) = 0._r8
+ this%deadcrootn_SASUsave_patch(p) = 0._r8
+ this%deadcrootn_storage_SASUsave_patch(p) = 0._r8
+ this%deadcrootn_xfer_SASUsave_patch(p) = 0._r8
+ this%grainn_SASUsave_patch(p) = 0._r8
+ this%grainn_storage_SASUsave_patch(p) = 0._r8
+
+ this%matrix_nalloc_leaf_acc_patch (p) = 0._r8
+ this%matrix_nalloc_leafst_acc_patch (p) = 0._r8
+ this%matrix_nalloc_froot_acc_patch (p) = 0._r8
+ this%matrix_nalloc_frootst_acc_patch (p) = 0._r8
+ this%matrix_nalloc_livestem_acc_patch (p) = 0._r8
+ this%matrix_nalloc_livestemst_acc_patch (p) = 0._r8
+ this%matrix_nalloc_deadstem_acc_patch (p) = 0._r8
+ this%matrix_nalloc_deadstemst_acc_patch (p) = 0._r8
+ this%matrix_nalloc_livecroot_acc_patch (p) = 0._r8
+ this%matrix_nalloc_livecrootst_acc_patch (p) = 0._r8
+ this%matrix_nalloc_deadcroot_acc_patch (p) = 0._r8
+ this%matrix_nalloc_deadcrootst_acc_patch (p) = 0._r8
+ this%matrix_nalloc_grain_acc_patch (p) = 0._r8
+ this%matrix_nalloc_grainst_acc_patch (p) = 0._r8
+
+ this%matrix_ntransfer_leafst_to_leafxf_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_leafxf_to_leaf_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_frootst_to_frootxf_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_frootxf_to_froot_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_livestemst_to_livestemxf_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_livestemxf_to_livestem_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_deadstemst_to_deadstemxf_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_deadstemxf_to_deadstem_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_livecrootst_to_livecrootxf_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_livecrootxf_to_livecroot_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_deadcrootst_to_deadcrootxf_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_deadcrootxf_to_deadcroot_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_grainst_to_grainxf_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_grainxf_to_grain_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_livestem_to_deadstem_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_livecroot_to_deadcroot_acc_patch (p) = 0._r8
+
+ this%matrix_ntransfer_retransn_to_leaf_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_leafst_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_froot_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_frootst_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_livestem_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_livestemst_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_deadstem_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_deadstemst_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_livecroot_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_livecrootst_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_deadcroot_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_deadcrootst_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_grain_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_grainst_acc_patch (p) = 0._r8
+
+ this%matrix_ntransfer_leaf_to_retransn_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_froot_to_retransn_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_livestem_to_retransn_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_livecroot_to_retransn_acc_patch (p) = 0._r8
+
+ this%matrix_nturnover_leaf_acc_patch (p) = 0._r8
+ this%matrix_nturnover_leafst_acc_patch (p) = 0._r8
+ this%matrix_nturnover_leafxf_acc_patch (p) = 0._r8
+ this%matrix_nturnover_froot_acc_patch (p) = 0._r8
+ this%matrix_nturnover_frootst_acc_patch (p) = 0._r8
+ this%matrix_nturnover_frootxf_acc_patch (p) = 0._r8
+ this%matrix_nturnover_livestem_acc_patch (p) = 0._r8
+ this%matrix_nturnover_livestemst_acc_patch (p) = 0._r8
+ this%matrix_nturnover_livestemxf_acc_patch (p) = 0._r8
+ this%matrix_nturnover_deadstem_acc_patch (p) = 0._r8
+ this%matrix_nturnover_deadstemst_acc_patch (p) = 0._r8
+ this%matrix_nturnover_deadstemxf_acc_patch (p) = 0._r8
+ this%matrix_nturnover_livecroot_acc_patch (p) = 0._r8
+ this%matrix_nturnover_livecrootst_acc_patch (p) = 0._r8
+ this%matrix_nturnover_livecrootxf_acc_patch (p) = 0._r8
+ this%matrix_nturnover_deadcroot_acc_patch (p) = 0._r8
+ this%matrix_nturnover_deadcrootst_acc_patch (p) = 0._r8
+ this%matrix_nturnover_deadcrootxf_acc_patch (p) = 0._r8
+ this%matrix_nturnover_grain_acc_patch (p) = 0._r8
+ this%matrix_nturnover_grainst_acc_patch (p) = 0._r8
+ this%matrix_nturnover_grainxf_acc_patch (p) = 0._r8
+ this%matrix_nturnover_retransn_acc_patch (p) = 0._r8
+ end if !use_matrixcn
end if
end do
@@ -635,12 +1157,74 @@ subroutine Restart ( this, bounds, ncid, flag, leafc_patch, &
call restartvar(ncid=ncid, flag=flag, varname='leafn_xfer', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%leafn_xfer_patch)
+!matrix
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='leafn_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafn_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafn_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafn_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafn_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafn_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafn0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafn0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafn0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafn0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafn0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafn0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_leaf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_leafst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_leafst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_leafst_to_leafxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_leafst_to_leafxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_leafxf_to_leaf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_leafxf_to_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_restransn_to_leaf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_restransn_to_leafst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_leafst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_leaf_to_retransn_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_leaf_to_retransn_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_leaf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_leafst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_leafst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_leafxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_leafxf_acc_patch)
+ end if
- ! Matrix restart variables
- if ( use_matrixcn )then
- end if
-
- if ( use_fun ) then
+ if ( use_fun ) then
call restartvar(ncid=ncid, flag=flag, varname='leafn_storage_xfer_acc', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%leafn_storage_xfer_acc_patch)
@@ -648,7 +1232,7 @@ subroutine Restart ( this, bounds, ncid, flag, leafc_patch, &
call restartvar(ncid=ncid, flag=flag, varname='storage_ndemand', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%storage_ndemand_patch)
- end if
+ end if
call restartvar(ncid=ncid, flag=flag, varname='frootn', xtype=ncd_double, &
@@ -662,6 +1246,72 @@ subroutine Restart ( this, bounds, ncid, flag, leafc_patch, &
call restartvar(ncid=ncid, flag=flag, varname='frootn_xfer', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%frootn_xfer_patch)
+
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='frootn_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootn_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootn_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootn_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootn_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootn_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootn0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootn0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootn0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootn0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootn0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootn0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_froot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_frootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_frootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_frootst_to_frootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_frootst_to_frootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_frootxf_to_froot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_frootxf_to_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_froot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_frootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_frootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_froot_to_retransn_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_froot_to_retransn_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_froot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_frootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_frootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_frootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_frootxf_acc_patch)
+ end if
call restartvar(ncid=ncid, flag=flag, varname='livestemn', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
@@ -710,6 +1360,272 @@ subroutine Restart ( this, bounds, ncid, flag, leafc_patch, &
call restartvar(ncid=ncid, flag=flag, varname='deadcrootn_xfer', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%deadcrootn_xfer_patch)
+
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='livestemn_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemn_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemn_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemn_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemn_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemn_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemn_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemn_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemn_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemn_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemn_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemn_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootn_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootn_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootn_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootn_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootn_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootn_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootn_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootn_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootn_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootn_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootn_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootn_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemn0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemn0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemn0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemn0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemn0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemn0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_livestem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_livestemst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_livestemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_livestemst_to_livestemxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_livestemst_to_livestemxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_livestemxf_to_livestem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_livestemxf_to_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_livestem_to_deadstem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_livestem_to_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_livestem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_livestemst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_livestemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_livestem_to_retransn_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_livestem_to_retransn_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_livestem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_livestemst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_livestemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_livestemxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_livestemxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemn0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemn0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemn0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemn0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemn0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemn0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_deadstem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_deadstemst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_deadstemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_deadstemst_to_deadstemxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_deadstemst_to_deadstemxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_deadstemxf_to_deadstem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_deadstemxf_to_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_deadstem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_deadstemst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_deadstemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_deadstem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_deadstemst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_deadstemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_deadstemxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_deadstemxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootn0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootn0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootn0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootn0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootn0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootn0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_livecroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_livecrootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_livecrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_livecrootst_to_livecrootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_livecrootst_to_livecrootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_livecrootxf_to_livecroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_livecrootxf_to_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_livecroot_to_deadcroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_livecroot_to_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_livecroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_livecrootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_livecrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_livecroot_to_retransn_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_livecroot_to_retransn_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_livecroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_livecrootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_livecrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_livecrootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_livecrootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootn0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootn0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootn0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootn0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootn0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootn0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='retransn0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%retransn0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_deadcroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_deadcrootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_deadcrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_deadcrootst_to_deadcrootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_deadcrootst_to_deadcrootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_deadcrootxf_to_deadcroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_deadcrootxf_to_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_deadcroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_deadcrootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_deadcrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_deadcroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_deadcrootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_deadcrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_deadcrootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_deadcrootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_retransn_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_retransn_acc_patch)
+ end if
call restartvar(ncid=ncid, flag=flag, varname='retransn', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
@@ -748,9 +1664,70 @@ subroutine Restart ( this, bounds, ncid, flag, leafc_patch, &
interpinic_flag='interp', readvar=readvar, data=data1dptr)
end do
+ if(use_matrixcn)then
+!--- Modify this...
+! call restartvar(ncid=ncid, flag=flag, varname='repron_cap', xtype=ncd_double, &
+! dim1name='pft', long_name='grain N capacity', units='gN/m2', &
+! interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_repron_patch)
+!
+! call restartvar(ncid=ncid, flag=flag, varname='repron_storage_cap', xtype=ncd_double, &
+! dim1name='pft', long_name='grain N storage capacity', units='gN/m2', &
+! interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_repron_storage_patch)
+!
+! call restartvar(ncid=ncid, flag=flag, varname='repron_xfer_cap', xtype=ncd_double, &
+! dim1name='pft', long_name='grain N transfer capacity', units='gN/m2', &
+! interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_repron_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='repron0', xtype=ncd_double, &
+ dim1name='pft', long_name='Reproductive N0', units='gN/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%repron0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='repron0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='Reproductive N0 storage', units='gN/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%repron0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='repron0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='Reproductive N0 transfer', units='gN/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%repron0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_grain_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_grainst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_grainst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_grainst_to_grainxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_grainst_to_grainxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_grainxf_to_grain_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_grainxf_to_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_grain_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_grainst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_grainst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_grain_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_grainst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_grainst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_grainxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_grainxf_acc_patch)
+ end if
do k = 1, nrepr
data1dptr => this%reproductiven_xfer_patch(:,k)
- ! e.g., grain-N_xfer
varname = get_repr_rest_fname(k)//'n_xfer'
call restartvar(ncid=ncid, flag=flag, varname=varname, &
xtype=ncd_double, &
@@ -825,32 +1802,38 @@ subroutine Restart ( this, bounds, ncid, flag, leafc_patch, &
if (patch%itype(p) == noveg) then
this%leafn_patch(p) = 0._r8
this%leafn_storage_patch(p) = 0._r8
-
- ! Set matrix solution variables for bare-soil
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafn_patch(p) = 0._r8
+ this%matrix_cap_leafn_storage_patch(p) = 0._r8
end if
if (MM_Nuptake_opt .eqv. .true.) then
this%frootn_patch(p) = 0._r8
this%frootn_storage_patch(p) = 0._r8
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_frootn_patch(p) = 0._r8
+ this%matrix_cap_frootn_storage_patch(p) = 0._r8
end if
end if
else
this%leafn_patch(p) = leafc_patch(p) / pftcon%leafcn(patch%itype(p))
this%leafn_storage_patch(p) = leafc_storage_patch(p) / pftcon%leafcn(patch%itype(p))
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafn_patch(p) = leafc_patch(p) / pftcon%leafcn(patch%itype(p))
+ this%matrix_cap_leafn_storage_patch(p) = leafc_storage_patch(p) / pftcon%leafcn(patch%itype(p))
end if
if (MM_Nuptake_opt .eqv. .true.) then
this%frootn_patch(p) = frootc_patch(p) / pftcon%frootcn(patch%itype(p))
this%frootn_storage_patch(p) = frootc_storage_patch(p) / pftcon%frootcn(patch%itype(p))
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_frootn_patch(p) = frootc_patch(p) / pftcon%frootcn(patch%itype(p))
+ this%matrix_cap_frootn_storage_patch(p) = frootc_storage_patch(p) / pftcon%frootcn(patch%itype(p))
end if
end if
end if
this%leafn_xfer_patch(p) = 0._r8
-
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafn_xfer_patch(p) = 0._r8
end if
this%leafn_storage_xfer_acc_patch(p) = 0._r8
@@ -860,24 +1843,30 @@ subroutine Restart ( this, bounds, ncid, flag, leafc_patch, &
this%reproductiven_patch(p,:) = 0._r8
this%reproductiven_storage_patch(p,:) = 0._r8
this%reproductiven_xfer_patch(p,:) = 0._r8
- this%cropseedn_deficit_patch(p) = 0._r8
-
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_repron_patch(p) = 0._r8
+ this%matrix_cap_repron_storage_patch(p) = 0._r8
+ this%matrix_cap_repron_xfer_patch(p) = 0._r8
end if
+ this%cropseedn_deficit_patch(p) = 0._r8
end if
if (MM_Nuptake_opt .eqv. .false.) then ! if not running in floating CN ratio option
this%frootn_patch(p) = 0._r8
this%frootn_storage_patch(p) = 0._r8
-
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_frootn_patch(p) = 0._r8
+ this%matrix_cap_frootn_storage_patch(p) = 0._r8
end if
end if
this%frootn_xfer_patch(p) = 0._r8
this%livestemn_patch(p) = 0._r8
this%livestemn_storage_patch(p) = 0._r8
this%livestemn_xfer_patch(p) = 0._r8
-
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_frootn_xfer_patch(p) = 0._r8
+ this%matrix_cap_livestemn_patch(p) = 0._r8
+ this%matrix_cap_livestemn_storage_patch(p) = 0._r8
+ this%matrix_cap_livestemn_xfer_patch(p) = 0._r8
end if
! tree types need to be initialized with some stem mass so that
@@ -885,22 +1874,37 @@ subroutine Restart ( this, bounds, ncid, flag, leafc_patch, &
if (pftcon%woody(patch%itype(p)) == 1._r8) then
this%deadstemn_patch(p) = deadstemc_patch(p) / pftcon%deadwdcn(patch%itype(p))
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemn_patch(p) = deadstemc_patch(p) / pftcon%deadwdcn(patch%itype(p))
end if
else
this%deadstemn_patch(p) = 0._r8
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemn_patch(p) = 0._r8
end if
end if
this%deadstemn_storage_patch(p) = 0._r8
this%deadstemn_xfer_patch(p) = 0._r8
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemn_storage_patch(p) = 0._r8
+ this%matrix_cap_deadstemn_xfer_patch(p) = 0._r8
+ end if
+
this%livecrootn_patch(p) = 0._r8
this%livecrootn_storage_patch(p) = 0._r8
this%livecrootn_xfer_patch(p) = 0._r8
this%deadcrootn_patch(p) = 0._r8
this%deadcrootn_storage_patch(p) = 0._r8
this%deadcrootn_xfer_patch(p) = 0._r8
+ if(use_matrixcn)then
+ this%matrix_cap_livecrootn_patch(p) = 0._r8
+ this%matrix_cap_livecrootn_storage_patch(p) = 0._r8
+ this%matrix_cap_livecrootn_xfer_patch(p) = 0._r8
+ this%matrix_cap_deadcrootn_patch(p) = 0._r8
+ this%matrix_cap_deadcrootn_storage_patch(p) = 0._r8
+ this%matrix_cap_deadcrootn_xfer_patch(p) = 0._r8
+ end if
this%retransn_patch(p) = 0._r8
this%npool_patch(p) = 0._r8
this%ntrunc_patch(p) = 0._r8
@@ -991,6 +1995,131 @@ subroutine SetValues ( this, &
this%deadcrootn_patch(i) = value_patch
this%deadcrootn_storage_patch(i) = value_patch
this%deadcrootn_xfer_patch(i) = value_patch
+ if(use_matrixcn)then
+ this%matrix_cap_leafn_patch(i) = value_patch
+ this%matrix_cap_leafn_storage_patch(i) = value_patch
+ this%matrix_cap_leafn_xfer_patch(i) = value_patch
+ this%matrix_cap_frootn_patch(i) = value_patch
+ this%matrix_cap_frootn_storage_patch(i) = value_patch
+ this%matrix_cap_frootn_xfer_patch(i) = value_patch
+ this%matrix_cap_livestemn_patch(i) = value_patch
+ this%matrix_cap_livestemn_storage_patch(i) = value_patch
+ this%matrix_cap_livestemn_xfer_patch(i) = value_patch
+ this%matrix_cap_deadstemn_patch(i) = value_patch
+ this%matrix_cap_deadstemn_storage_patch(i) = value_patch
+ this%matrix_cap_deadstemn_xfer_patch(i) = value_patch
+ this%matrix_cap_livecrootn_patch(i) = value_patch
+ this%matrix_cap_livecrootn_storage_patch(i) = value_patch
+ this%matrix_cap_livecrootn_xfer_patch(i) = value_patch
+ this%matrix_cap_deadcrootn_patch(i) = value_patch
+ this%matrix_cap_deadcrootn_storage_patch(i) = value_patch
+ this%matrix_cap_deadcrootn_xfer_patch(i) = value_patch
+
+ this%leafn0_patch(i) = value_patch
+ this%leafn0_storage_patch(i) = value_patch
+ this%leafn0_xfer_patch(i) = value_patch
+ this%frootn0_patch(i) = value_patch
+ this%frootn0_storage_patch(i) = value_patch
+ this%frootn0_xfer_patch(i) = value_patch
+ this%livestemn0_patch(i) = value_patch
+ this%livestemn0_storage_patch(i) = value_patch
+ this%livestemn0_xfer_patch(i) = value_patch
+ this%deadstemn0_patch(i) = value_patch
+ this%deadstemn0_storage_patch(i) = value_patch
+ this%deadstemn0_xfer_patch(i) = value_patch
+ this%livecrootn0_patch(i) = value_patch
+ this%livecrootn0_storage_patch(i) = value_patch
+ this%livecrootn0_xfer_patch(i) = value_patch
+ this%deadcrootn0_patch(i) = value_patch
+ this%deadcrootn0_storage_patch(i) = value_patch
+ this%deadcrootn0_xfer_patch(i) = value_patch
+ if ( use_crop )then
+ this%repron0_patch(i) = value_patch
+ this%repron0_storage_patch(i) = value_patch
+ this%repron0_xfer_patch(i) = value_patch
+ end if
+ this%retransn0_patch(i) = value_patch
+
+ this%matrix_nalloc_leaf_acc_patch(i) = value_patch
+ this%matrix_nalloc_leafst_acc_patch(i) = value_patch
+ this%matrix_nalloc_froot_acc_patch(i) = value_patch
+ this%matrix_nalloc_frootst_acc_patch(i) = value_patch
+ this%matrix_nalloc_livestem_acc_patch(i) = value_patch
+ this%matrix_nalloc_livestemst_acc_patch(i) = value_patch
+ this%matrix_nalloc_deadstem_acc_patch(i) = value_patch
+ this%matrix_nalloc_deadstemst_acc_patch(i) = value_patch
+ this%matrix_nalloc_livecroot_acc_patch(i) = value_patch
+ this%matrix_nalloc_livecrootst_acc_patch(i) = value_patch
+ this%matrix_nalloc_deadcroot_acc_patch(i) = value_patch
+ this%matrix_nalloc_deadcrootst_acc_patch(i) = value_patch
+ this%matrix_nalloc_grain_acc_patch(i) = value_patch
+ this%matrix_nalloc_grainst_acc_patch(i) = value_patch
+
+ this%matrix_ntransfer_leafst_to_leafxf_acc_patch(i) = value_patch
+ this%matrix_ntransfer_leafxf_to_leaf_acc_patch(i) = value_patch
+ this%matrix_ntransfer_frootst_to_frootxf_acc_patch(i) = value_patch
+ this%matrix_ntransfer_frootxf_to_froot_acc_patch(i) = value_patch
+ this%matrix_ntransfer_livestemst_to_livestemxf_acc_patch(i) = value_patch
+ this%matrix_ntransfer_livestemxf_to_livestem_acc_patch(i) = value_patch
+ this%matrix_ntransfer_deadstemst_to_deadstemxf_acc_patch(i) = value_patch
+ this%matrix_ntransfer_deadstemxf_to_deadstem_acc_patch(i) = value_patch
+ this%matrix_ntransfer_livecrootst_to_livecrootxf_acc_patch(i) = value_patch
+ this%matrix_ntransfer_livecrootxf_to_livecroot_acc_patch(i) = value_patch
+ this%matrix_ntransfer_deadcrootst_to_deadcrootxf_acc_patch(i) = value_patch
+ this%matrix_ntransfer_deadcrootxf_to_deadcroot_acc_patch(i) = value_patch
+ if ( use_crop )then
+ this%matrix_ntransfer_grainst_to_grainxf_acc_patch(i) = value_patch
+ this%matrix_ntransfer_grainxf_to_grain_acc_patch(i) = value_patch
+ end if
+ this%matrix_ntransfer_livestem_to_deadstem_acc_patch(i) = value_patch
+ this%matrix_ntransfer_livecroot_to_deadcroot_acc_patch(i) = value_patch
+
+ this%matrix_ntransfer_retransn_to_leaf_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_leafst_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_froot_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_frootst_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_livestem_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_livestemst_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_deadstem_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_deadstemst_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_livecroot_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_livecrootst_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_deadcroot_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_deadcrootst_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_grain_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_grainst_acc_patch(i) = value_patch
+
+ this%matrix_ntransfer_leaf_to_retransn_acc_patch(i) = value_patch
+ this%matrix_ntransfer_froot_to_retransn_acc_patch(i) = value_patch
+ this%matrix_ntransfer_livestem_to_retransn_acc_patch(i) = value_patch
+ this%matrix_ntransfer_livecroot_to_retransn_acc_patch(i) = value_patch
+
+ this%matrix_nturnover_leaf_acc_patch(i) = value_patch
+ this%matrix_nturnover_leafst_acc_patch(i) = value_patch
+ this%matrix_nturnover_leafxf_acc_patch(i) = value_patch
+ this%matrix_nturnover_froot_acc_patch(i) = value_patch
+ this%matrix_nturnover_frootst_acc_patch(i) = value_patch
+ this%matrix_nturnover_frootxf_acc_patch(i) = value_patch
+ this%matrix_nturnover_livestem_acc_patch(i) = value_patch
+ this%matrix_nturnover_livestemst_acc_patch(i) = value_patch
+ this%matrix_nturnover_livestemxf_acc_patch(i) = value_patch
+ this%matrix_nturnover_deadstem_acc_patch(i) = value_patch
+ this%matrix_nturnover_deadstemst_acc_patch(i) = value_patch
+ this%matrix_nturnover_deadstemxf_acc_patch(i) = value_patch
+ this%matrix_nturnover_livecroot_acc_patch(i) = value_patch
+ this%matrix_nturnover_livecrootst_acc_patch(i) = value_patch
+ this%matrix_nturnover_livecrootxf_acc_patch(i) = value_patch
+ this%matrix_nturnover_deadcroot_acc_patch(i) = value_patch
+ this%matrix_nturnover_deadcrootst_acc_patch(i) = value_patch
+ this%matrix_nturnover_deadcrootxf_acc_patch(i) = value_patch
+ this%matrix_nturnover_retransn_acc_patch(i) = value_patch
+ if ( use_crop )then
+ this%matrix_nturnover_grain_acc_patch(i) = value_patch
+ this%matrix_nturnover_grainst_acc_patch(i) = value_patch
+ this%matrix_nturnover_grainxf_acc_patch(i) = value_patch
+ end if
+
+ end if
this%retransn_patch(i) = value_patch
this%npool_patch(i) = value_patch
this%ntrunc_patch(i) = value_patch
diff --git a/src/biogeochem/CNVegetationFacade.F90 b/src/biogeochem/CNVegetationFacade.F90
index f42cf17d68..706d52da27 100644
--- a/src/biogeochem/CNVegetationFacade.F90
+++ b/src/biogeochem/CNVegetationFacade.F90
@@ -469,6 +469,8 @@ subroutine Restart(this, bounds, ncid, flag)
use clm_varcon, only : c3_r2, c14ratio
use SoilBiogeochemDecompCascadeConType, only : use_soil_matrixcn
use CNSharedParamsMod, only : use_matrixcn
+ use CNVegMatrixMod, only : CNVegMatrixRest
+ use CNSoilMatrixMod, only : CNSoilMatrixRest
!
! !ARGUMENTS:
class(cn_vegetation_type), intent(inout) :: this
@@ -545,6 +547,14 @@ subroutine Restart(this, bounds, ncid, flag)
template_multiplier = c14ratio)
end if
call this%n_products_inst%restart(bounds, ncid, flag)
+
+ if ( use_matrixcn )then
+ call CNVegMatrixRest( ncid, flag )
+ end if
+ end if
+
+ if ( use_soil_matrixcn )then
+ call CNSoilMatrixRest( ncid, flag )
end if
if (use_cndv) then
diff --git a/src/biogeochem/CropReprPoolsMod.F90 b/src/biogeochem/CropReprPoolsMod.F90
index 780b9f2d52..cbc2f3e2a2 100644
--- a/src/biogeochem/CropReprPoolsMod.F90
+++ b/src/biogeochem/CropReprPoolsMod.F90
@@ -57,6 +57,11 @@ subroutine crop_repr_pools_init()
! !DESCRIPTION:
! Initialize module-level data
!
+ ! !USES:
+ use abortutils, only: endrun
+ use shr_log_mod, only: errmsg => shr_log_errMsg
+ use CNSharedParamsMod, only: use_matrixcn
+ !
! !ARGUMENTS:
!
! !LOCAL VARIABLES:
@@ -77,16 +82,26 @@ subroutine crop_repr_pools_init()
! repr_hist_fnames(1) = 'GRAIN_MEAL', grain_hist_fnames(2) = 'GRAIN_OIL', etc.
if (for_testing_use_second_grain_pool) then
nrepr_grain = 2
+ if (use_matrixcn) then
+ call endrun(msg="ERROR: for_testing_use_second_grain_pool should be .false. when use_matrixcn = .true."//errmsg(sourcefile, __LINE__))
+ end if
else
nrepr_grain = 1
end if
if (for_testing_use_repr_structure_pool) then
nrepr_structure = 2
+ if (use_matrixcn) then
+ call endrun(msg="ERROR: for_testing_use_repr_structure_pool should be .false. when use_matrixcn = .true."//errMsg(sourcefile, __LINE__))
+ end if
else
nrepr_structure = 0
end if
nrepr = nrepr_grain + nrepr_structure
+ ! matrixcn works with nrepr = 1 only
+ if (use_matrixcn .and. nrepr /= 1) then
+ call endrun(msg="ERROR: nrepr should be 1 when use_matrixcn = .true."//errMsg(sourcefile, __LINE__))
+ end if
allocate(repr_hist_fnames(nrepr))
allocate(repr_rest_fnames(nrepr))
allocate(repr_longnames(nrepr))
diff --git a/src/biogeochem/CropType.F90 b/src/biogeochem/CropType.F90
index 760aa21b76..0f650a4a9f 100644
--- a/src/biogeochem/CropType.F90
+++ b/src/biogeochem/CropType.F90
@@ -52,6 +52,9 @@ module CropType
integer , pointer :: rx_swindow_starts_thisyr_patch(:,:) ! all prescribed sowing window start dates for this patch this year (day of year) [patch, mxsowings]
integer , pointer :: rx_swindow_ends_thisyr_patch (:,:) ! all prescribed sowing window end dates for this patch this year (day of year) [patch, mxsowings]
real(r8), pointer :: rx_cultivar_gdds_thisyr_patch (:,:) ! all cultivar GDD targets for this patch this year (ddays) [patch, mxsowings]
+ real(r8), pointer :: gdd20_baseline_patch (:) ! GDD20 baseline for this patch (ddays) [patch]
+ real(r8), pointer :: gdd20_season_start_patch(:) ! gdd20 season start date for this patch (day of year) [patch]. Real to enable history field.
+ real(r8), pointer :: gdd20_season_end_patch (:) ! gdd20 season end date for this patch (day of year) [patch]. Real to enable history field.
real(r8), pointer :: sdates_thisyr_patch (:,:) ! all actual sowing dates for this patch this year (day of year) [patch, mxsowings]
real(r8), pointer :: swindow_starts_thisyr_patch(:,:) ! all sowing window start dates for this patch this year (day of year) [patch, mxsowings]
real(r8), pointer :: swindow_ends_thisyr_patch (:,:) ! all sowing window end dates for this patch this year (day of year) [patch, mxsowings]
@@ -235,6 +238,9 @@ subroutine InitAllocate(this, bounds)
allocate(this%rx_swindow_starts_thisyr_patch(begp:endp,1:mxsowings)); this%rx_swindow_starts_thisyr_patch(:,:) = -1
allocate(this%rx_swindow_ends_thisyr_patch(begp:endp,1:mxsowings)) ; this%rx_swindow_ends_thisyr_patch (:,:) = -1
allocate(this%rx_cultivar_gdds_thisyr_patch(begp:endp,1:mxsowings)) ; this%rx_cultivar_gdds_thisyr_patch(:,:) = spval
+ allocate(this%gdd20_baseline_patch(begp:endp)) ; this%gdd20_baseline_patch(:) = spval
+ allocate(this%gdd20_season_start_patch(begp:endp)); this%gdd20_season_start_patch(:) = spval
+ allocate(this%gdd20_season_end_patch(begp:endp)) ; this%gdd20_season_end_patch (:) = spval
allocate(this%sdates_thisyr_patch(begp:endp,1:mxsowings)) ; this%sdates_thisyr_patch(:,:) = spval
allocate(this%swindow_starts_thisyr_patch(begp:endp,1:mxsowings)) ; this%swindow_starts_thisyr_patch(:,:) = spval
allocate(this%swindow_ends_thisyr_patch (begp:endp,1:mxsowings)) ; this%swindow_ends_thisyr_patch (:,:) = spval
@@ -358,6 +364,19 @@ subroutine InitHistory(this, bounds)
avgflag='I', long_name='Reason for each crop harvest; should only be output annually', &
ptr_patch=this%harvest_reason_thisyr_patch, default='inactive')
+ this%gdd20_baseline_patch(begp:endp) = spval
+ call hist_addfld1d (fname='GDD20_BASELINE', units='ddays', &
+ avgflag='I', long_name='Baseline mean growing-degree days accumulated during accumulation period (from input)', &
+ ptr_patch=this%gdd20_baseline_patch, default='inactive')
+ this%gdd20_season_start_patch(begp:endp) = spval
+ call hist_addfld1d (fname='GDD20_SEASON_START', units='day of year', &
+ avgflag='I', long_name='Start of the GDD20 accumulation season (from input)', &
+ ptr_patch=this%gdd20_season_start_patch, default='inactive')
+ this%gdd20_season_end_patch(begp:endp) = spval
+ call hist_addfld1d (fname='GDD20_SEASON_END', units='day of year', &
+ avgflag='I', long_name='End of the GDD20 accumulation season (from input)', &
+ ptr_patch=this%gdd20_season_end_patch, default='inactive')
+
end subroutine InitHistory
subroutine InitCold(this, bounds)
@@ -772,7 +791,7 @@ subroutine CropUpdateAccVars(this, bounds, t_ref2m_patch, t_soisno_col)
! Should only be called if use_crop is true.
!
! !USES:
- use accumulMod , only : update_accum_field, extract_accum_field, accumResetVal
+ use accumulMod , only : update_accum_field, extract_accum_field, markreset_accum_field
use shr_const_mod , only : SHR_CONST_CDAY, SHR_CONST_TKFRZ
use clm_time_manager , only : get_step_size, get_nstep
use clm_varpar , only : nlevsno, nlevmaxurbgrnd
@@ -848,7 +867,8 @@ subroutine CropUpdateAccVars(this, bounds, t_ref2m_patch, t_soisno_col)
rbufslp(p) = rbufslp(p) * this%vf_patch(p)
end if
else
- rbufslp(p) = accumResetVal
+ call markreset_accum_field('HUI', p)
+ call markreset_accum_field('GDDACCUM', p)
end if
end do
call update_accum_field ('HUI', rbufslp, nstep)
@@ -872,7 +892,7 @@ subroutine CropUpdateAccVars(this, bounds, t_ref2m_patch, t_soisno_col)
rbufslp(p) = rbufslp(p) * this%vf_patch(p)
end if
else
- rbufslp(p) = accumResetVal
+ call markreset_accum_field('GDDTSOI', p)
end if
end do
call update_accum_field ('GDDTSOI', rbufslp, nstep)
diff --git a/src/biogeochem/DustEmisBase.F90 b/src/biogeochem/DustEmisBase.F90
index c5e4260634..47f2f32688 100644
--- a/src/biogeochem/DustEmisBase.F90
+++ b/src/biogeochem/DustEmisBase.F90
@@ -31,7 +31,6 @@ module DustEmisBase
use LandunitType , only : lun
use ColumnType , only : col
use PatchType , only : patch
- use clm_varctl , only : dust_emis_method
!
! !PUBLIC TYPES
implicit none
diff --git a/src/biogeochem/DustEmisFactory.F90 b/src/biogeochem/DustEmisFactory.F90
index 371e77d6dc..344596cdb0 100644
--- a/src/biogeochem/DustEmisFactory.F90
+++ b/src/biogeochem/DustEmisFactory.F90
@@ -25,12 +25,22 @@ function create_dust_emissions(bounds, NLFilename) result(dust_emis)
!---------------------------------------------------------------------------
! Create a dust_emission base class objecct
! The method implemented depends on namelist input
+ !
+ ! DESIGN NOTES: Erik Kluzek 07/15/2024
+ ! This implementation is different from for example the Fire Factory functions
+ ! that use a direct namelist item with case statements to determine the method.
+ ! Here we use logical functions from the shr_dust_emis_mod code. Because shr_dust_emis_mod
+ ! is used by both CTSM and CAM I wanted it to be robust with neither CAM nor CTSM
+ ! being able to change internal settings so a functional programming design was used
+ ! (with function calls that can't change anything inside shr_dust_emis_mod). This is also
+ ! why I added a unit-tester for the shr_dust_emis_mod code, so that both CTSM and CAM
+ ! can rely on it's behavior.
!---------------------------------------------------------------------------
use DustEmisBase , only : dust_emis_base_type
use DustEmisZender2003, only : dust_emis_zender2003_type
- use clm_varctl , only : dust_emis_method
use decompMod , only : bounds_type
use shr_kind_mod , only : CL => shr_kind_cl
+ use shr_dust_emis_mod , only : is_dust_emis_zender, is_dust_emis_leung
implicit none
! Arguments
class(dust_emis_base_type), allocatable :: dust_emis
@@ -38,20 +48,18 @@ function create_dust_emissions(bounds, NLFilename) result(dust_emis)
character(len=*), intent(in) :: NLFilename
! Local variables
- select case ( trim(dust_emis_method) )
-
- case( "Zender_2003" )
+ if ( is_dust_emis_zender() )then
allocate(dust_emis, source=dust_emis_zender2003_type() )
! This will be added when the Leung2023 comes in
- !case( "Leung_2023" )
+ !else if ( is_dust_emis_leung() )
! allocate(dust_emis, source=dust_emis_zender2003_type() )
- case default
- write(iulog,*) 'ERROR: unknown dust_emis_method: ', dust_emis_method, &
+ else
+ write(iulog,*) 'ERROR: unknown dust_emis_method: ', &
errMsg(sourcefile, __LINE__)
call endrun( "Unrecognized dust_emis_method" )
- end select
+ end if
call dust_emis%Init(bounds, NLFilename)
diff --git a/src/biogeochem/NutrientCompetitionCLM45defaultMod.F90 b/src/biogeochem/NutrientCompetitionCLM45defaultMod.F90
index bb45074e7b..0980ff5378 100644
--- a/src/biogeochem/NutrientCompetitionCLM45defaultMod.F90
+++ b/src/biogeochem/NutrientCompetitionCLM45defaultMod.F90
@@ -92,7 +92,6 @@ subroutine calc_plant_nutrient_competition (this, &
use CNVegNitrogenStateType, only : cnveg_nitrogenstate_type
use CNVegNitrogenFluxType , only : cnveg_nitrogenflux_type
use SoilBiogeochemNitrogenStateType, only : soilbiogeochem_nitrogenstate_type
- use CNSharedParamsMod , only : use_fun
!
! !ARGUMENTS:
class(nutrient_competition_clm45default_type), intent(inout) :: this
@@ -114,7 +113,7 @@ subroutine calc_plant_nutrient_competition (this, &
call this%calc_plant_cn_alloc (bounds, num_soilp, filter_soilp, &
cnveg_state_inst, crop_inst, canopystate_inst, &
cnveg_carbonstate_inst, cnveg_carbonflux_inst, c13_cnveg_carbonflux_inst, &
- c14_cnveg_carbonflux_inst, cnveg_nitrogenflux_inst, cnveg_nitrogenstate_inst, &
+ c14_cnveg_carbonflux_inst, cnveg_nitrogenflux_inst, &
fpg_col=fpg_col(bounds%begc:bounds%endc))
end subroutine calc_plant_nutrient_competition
@@ -123,7 +122,7 @@ end subroutine calc_plant_nutrient_competition
subroutine calc_plant_cn_alloc (this, bounds, num_soilp, filter_soilp, &
cnveg_state_inst, crop_inst, canopystate_inst, &
cnveg_carbonstate_inst, cnveg_carbonflux_inst, c13_cnveg_carbonflux_inst, &
- c14_cnveg_carbonflux_inst, cnveg_nitrogenflux_inst, cnveg_nitrogenstate_inst, fpg_col)
+ c14_cnveg_carbonflux_inst, cnveg_nitrogenflux_inst, fpg_col)
!
! !USES:
use pftconMod , only : pftcon, npcropmin
@@ -134,8 +133,7 @@ subroutine calc_plant_cn_alloc (this, bounds, num_soilp, filter_soilp, &
use CNVegCarbonStateType , only : cnveg_carbonstate_type
use CNVegCarbonFluxType , only : cnveg_carbonflux_type
use CNVegNitrogenFluxType , only : cnveg_nitrogenflux_type
- use CNVegNitrogenStateType, only : cnveg_nitrogenstate_type
- use CNSharedParamsMod , only : use_fun, use_matrixcn
+ use CNSharedParamsMod , only : use_fun
use shr_infnan_mod , only : shr_infnan_isnan
!
@@ -152,7 +150,6 @@ subroutine calc_plant_cn_alloc (this, bounds, num_soilp, filter_soilp, &
type(cnveg_carbonflux_type) , intent(inout) :: c13_cnveg_carbonflux_inst
type(cnveg_carbonflux_type) , intent(inout) :: c14_cnveg_carbonflux_inst
type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst
- type(cnveg_nitrogenstate_type) , intent(inout) :: cnveg_nitrogenstate_inst
real(r8) , intent(in) :: fpg_col(bounds%begc:)
!
! !LOCAL VARIABLES:
@@ -229,7 +226,6 @@ subroutine calc_plant_cn_alloc (this, bounds, num_soilp, filter_soilp, &
npool_to_reproductiven_storage => cnveg_nitrogenflux_inst%npool_to_reproductiven_storage_patch , & ! Output: [real(r8) (:,:) ] allocation to grain N storage (gN/m2/s)
retransn_to_npool => cnveg_nitrogenflux_inst%retransn_to_npool_patch , & ! Output: [real(r8) (:) ] deployment of retranslocated N (gN/m2/s)
sminn_to_npool => cnveg_nitrogenflux_inst%sminn_to_npool_patch , & ! Output: [real(r8) (:) ] deployment of soil mineral N uptake (gN/m2/s)
- retransn => cnveg_nitrogenstate_inst%retransn_patch , & ! Input: [real(r8) (:) ] (gN/m2) plant pool of retranslocated N
npool_to_leafn => cnveg_nitrogenflux_inst%npool_to_leafn_patch , & ! Output: [real(r8) (:) ] allocation to leaf N (gN/m2/s)
npool_to_leafn_storage => cnveg_nitrogenflux_inst%npool_to_leafn_storage_patch , & ! Output: [real(r8) (:) ] allocation to leaf N storage (gN/m2/s)
npool_to_frootn => cnveg_nitrogenflux_inst%npool_to_frootn_patch , & ! Output: [real(r8) (:) ] allocation to fine root N (gN/m2/s)
@@ -311,11 +307,6 @@ subroutine calc_plant_cn_alloc (this, bounds, num_soilp, filter_soilp, &
plant_nalloc(p) = sminn_to_npool(p) + retransn_to_npool(p)
plant_calloc(p) = plant_nalloc(p) * (c_allometry(p)/n_allometry(p))
- ! Assign the above terms to the CN-Matrix solution
- if (use_matrixcn)then
- end if
-
-
if(.not.use_fun)then !ORIGINAL CLM(CN) downregulation code.
excess_cflux(p) = availc(p) - plant_calloc(p)
! reduce gpp fluxes due to N limitation
@@ -330,13 +321,13 @@ subroutine calc_plant_cn_alloc (this, bounds, num_soilp, filter_soilp, &
c13_cnveg_carbonflux_inst%psnsun_to_cpool_patch(p) *(1._r8 - downreg(p))
c13_cnveg_carbonflux_inst%psnshade_to_cpool_patch(p) = &
c13_cnveg_carbonflux_inst%psnshade_to_cpool_patch(p)*(1._r8 - downreg(p))
- end if
+ endif
if ( use_c14 ) then
c14_cnveg_carbonflux_inst%psnsun_to_cpool_patch(p) = &
c14_cnveg_carbonflux_inst%psnsun_to_cpool_patch(p) *(1._r8 - downreg(p))
c14_cnveg_carbonflux_inst%psnshade_to_cpool_patch(p) = &
c14_cnveg_carbonflux_inst%psnshade_to_cpool_patch(p)*(1._r8 - downreg(p))
- end if
+ endif
end if
end if !use_fun
@@ -411,10 +402,6 @@ subroutine calc_plant_cn_alloc (this, bounds, num_soilp, filter_soilp, &
end do
end if
- ! Assign above terms to the matrix solution
- if (use_matrixcn) then
- end if !end use_matrixcn
-
! Calculate the amount of carbon that needs to go into growth
! respiration storage to satisfy all of the storage growth demands.
! Allows for the fraction of growth respiration that is released at the
@@ -440,9 +427,6 @@ subroutine calc_plant_cn_alloc (this, bounds, num_soilp, filter_soilp, &
end if
cpool_to_gresp_storage(p) = gresp_storage * g1 * (1._r8 - g2)
- ! Assign above terms to the matrix solution
- if(use_matrixcn)then
- end if !end use_matrixcn
end do ! end patch loop
end associate
@@ -469,7 +453,6 @@ subroutine calc_plant_nutrient_demand(this, bounds, &
use SoilBiogeochemCarbonFluxType, only : soilbiogeochem_carbonflux_type
use SoilBiogeochemNitrogenStateType, only : soilbiogeochem_nitrogenstate_type
use EnergyFluxType , only : energyflux_type
- use CNSharedParamsMod , only : use_fun
!
! !ARGUMENTS:
class(nutrient_competition_clm45default_type), intent(inout) :: this
@@ -525,7 +508,6 @@ subroutine calc_plant_nitrogen_demand(this, bounds, &
use pftconMod , only : npcropmin, pftcon
use pftconMod , only : ntmp_soybean, nirrig_tmp_soybean
use pftconMod , only : ntrp_soybean, nirrig_trp_soybean
- use CNSharedParamsMod , only : use_matrixcn
use clm_time_manager , only : get_step_size_real
use CropType , only : crop_type
use CNVegStateType , only : cnveg_state_type
@@ -598,9 +580,6 @@ subroutine calc_plant_nitrogen_demand(this, bounds, &
livestemc => cnveg_carbonstate_inst%livestemc_patch , & ! Input: [real(r8) (:) ]
retransn => cnveg_nitrogenstate_inst%retransn_patch , & ! Input: [real(r8) (:) ] (gN/m2) plant pool of retranslocated N
- leafn => cnveg_nitrogenstate_inst%leafn_patch , & ! Input: [real(r8) (:) ] (gN/m2) leaf N
- livestemn => cnveg_nitrogenstate_inst%livestemn_patch , & ! Input: [real(r8) (:) ] (gN/m2) livestem N
- frootn => cnveg_nitrogenstate_inst%frootn_patch , & ! Input: [real(r8) (:) ] (gN/m2) fine root N
gpp => cnveg_carbonflux_inst%gpp_before_downreg_patch , & ! Input: [real(r8) (:) ] GPP flux before downregulation (gC/m2/s)
availc => cnveg_carbonflux_inst%availc_patch , & ! Input: [real(r8) (:) ] C flux available for allocation (gC/m2/s)
@@ -681,9 +660,6 @@ subroutine calc_plant_nitrogen_demand(this, bounds, &
end if !fun
grain_flag(p) = 1._r8
- ! Apply above to the matrix solution
- if(use_matrixcn)then
- end if
end if
end if
end if
diff --git a/src/biogeochem/NutrientCompetitionFlexibleCNMod.F90 b/src/biogeochem/NutrientCompetitionFlexibleCNMod.F90
index 6f8632658d..993c0a2e9a 100644
--- a/src/biogeochem/NutrientCompetitionFlexibleCNMod.F90
+++ b/src/biogeochem/NutrientCompetitionFlexibleCNMod.F90
@@ -29,9 +29,8 @@ module NutrientCompetitionFlexibleCNMod
use CropReprPoolsMod , only : nrepr
use CNPhenologyMod , only : CropPhase
use CropType , only : cphase_leafemerge, cphase_grainfill
- use clm_varctl , only : iulog, use_crop_agsys
+ use clm_varctl , only : use_crop_agsys
use CNSharedParamsMod , only : use_matrixcn
- use abortutils , only : endrun
!
implicit none
private
@@ -61,14 +60,13 @@ module NutrientCompetitionFlexibleCNMod
module procedure constructor
end interface nutrient_competition_FlexibleCN_type
!
-
! !PRIVATE MEMBER FUNCTIONS:
private :: calc_npool_to_components_flexiblecn ! Calculate npool_to_* terms for a single patch using the FlexibleCN approach
private :: calc_npool_to_components_agsys ! Calculate npool_to_* terms for a single crop patch when using AgSys
! !PRIVATE DATA:
- logical,parameter :: matrixcheck_ph = .True. ! If matrix solution check should be applied
- logical,parameter :: acc_ph = .False. ! Another matrix check option
+ logical,parameter :: matrixcheck_ph = .True.
+ logical,parameter :: acc_ph = .False.
character(len=*), parameter, private :: sourcefile = &
__FILE__
@@ -211,7 +209,14 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
use CNSharedParamsMod , only : use_fun
use CNPrecisionControlMod , only : n_min
use clm_varcon , only : spval
-
+ !index for matrixcn
+ use clm_varpar , only : ileaf,ileaf_st,ileaf_xf,ifroot,ifroot_st,ifroot_xf,&
+ ilivestem,ilivestem_st,ilivestem_xf,&
+ ideadstem,ideadstem_st,ideadstem_xf,&
+ ilivecroot,ilivecroot_st,ilivecroot_xf,&
+ ideadcroot,ideadcroot_st,ideadcroot_xf,&
+ igrain,igrain_st,igrain_xf,iretransn,ioutc,ioutn,nvegnpool
+ use CNVegMatrixMod , only : matrix_update_phn
!
! !ARGUMENTS:
class(nutrient_competition_FlexibleCN_type), intent(inout) :: this
@@ -238,6 +243,7 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
real(r8) :: gresp_storage ! temporary variable for growth resp to storage
real(r8) :: nlc ! temporary variable for total new leaf carbon allocation
real(r8) :: f5(nrepr) ! reproductive allocation parameters
+ real(r8) :: dt ! model time step
real(r8):: frootcn_storage_actual
real(r8):: frootcn_actual
@@ -249,8 +255,8 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
real(r8):: frootcn_max
real(r8):: livewdcn_max
real(r8):: frac_resp
- real(r8):: npool_to_veg ! Temporary for nitrogen pool transfer to vegetation components
- real(r8):: cpool_to_veg ! Temporary for carbon pool transfer to vegetation components
+ real(r8):: npool_to_veg
+ real(r8):: cpool_to_veg
real(r8) :: tmp
! -----------------------------------------------------------------------
@@ -292,7 +298,7 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
annsum_npp => cnveg_carbonflux_inst%annsum_npp_patch , & ! Input: [real(r8) (:) ] annual sum of NPP, for wood allocation
availc => cnveg_carbonflux_inst%availc_patch , & ! Output: [real(r8) (:) ] C flux available for allocation (gC/m2/s)
plant_calloc => cnveg_carbonflux_inst%plant_calloc_patch , & ! Output: [real(r8) (:) ] total allocated C flux (gC/m2/s)
- npp_growth => cnveg_carbonflux_inst%npp_growth_patch , & ! Output: [real(r8) (:) ] C for growth in FUN. g/m2/s
+ npp_growth => cnveg_carbonflux_inst%npp_growth_patch , & ! output: [real(r8) (:) ] c for growth in fun. g/m2/s
cpool_to_resp => cnveg_carbonflux_inst%cpool_to_resp_patch , & ! output: [real(r8) (:) ]
cpool_to_leafc_resp => cnveg_carbonflux_inst%cpool_to_leafc_resp_patch , & ! Output: [real(r8) (:) ]
cpool_to_leafc_storage_resp => cnveg_carbonflux_inst%cpool_to_leafc_storage_resp_patch , & ! Output: [real(r8) (:) ]
@@ -329,7 +335,7 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
npool_to_reproductiven => cnveg_nitrogenflux_inst%npool_to_reproductiven_patch , & ! Output: [real(r8) (:,:) ] allocation to grain N (gN/m2/s)
npool_to_reproductiven_storage => cnveg_nitrogenflux_inst%npool_to_reproductiven_storage_patch , & ! Output: [real(r8) (:,:) ] allocation to grain N storage (gN/m2/s)
retransn_to_npool => cnveg_nitrogenflux_inst%retransn_to_npool_patch , & ! Output: [real(r8) (:) ] deployment of retranslocated N (gN/m2/s)
- retransn => cnveg_nitrogenstate_inst%retransn_patch , & ! Input: [real(r8) (:) ] (gN/m2) plant pool of retranslocated N
+ retransn => cnveg_nitrogenstate_inst%retransn_patch , & ! Input: [real(r8) (:) ] (gN/m2) plant pool of retranslocated N
sminn_to_npool => cnveg_nitrogenflux_inst%sminn_to_npool_patch , & ! Output: [real(r8) (:) ] deployment of soil mineral N uptake (gN/m2/s)
npool_to_leafn => cnveg_nitrogenflux_inst%npool_to_leafn_patch , & ! Output: [real(r8) (:) ] allocation to leaf N (gN/m2/s)
npool_to_leafn_storage => cnveg_nitrogenflux_inst%npool_to_leafn_storage_patch , & ! Output: [real(r8) (:) ] allocation to leaf N storage (gN/m2/s)
@@ -349,9 +355,31 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
Nnonmyc => cnveg_nitrogenflux_inst%Nnonmyc_patch , & ! Output: [real(r8) (:) ] Non-mycorrhizal N uptake (gN/m2/s)
Nam => cnveg_nitrogenflux_inst%Nam_patch , & ! Output: [real(r8) (:) ] AM uptake (gN/m2/s)
Necm => cnveg_nitrogenflux_inst%Necm_patch , & ! Output: [real(r8) (:) ] ECM uptake (gN/m2/s)
- sminn_to_plant_fun => cnveg_nitrogenflux_inst%sminn_to_plant_fun_patch & ! Output: [real(r8) (:) ] Total soil N uptake of FUN (gN/m2/s)
+ sminn_to_plant_fun => cnveg_nitrogenflux_inst%sminn_to_plant_fun_patch , & ! Output: [real(r8) (:) ] Total soil N uptake of FUN (gN/m2/s)
+
+ iretransn_to_ileaf => cnveg_nitrogenflux_inst%iretransn_to_ileaf_ph , & ! Transfer index (from retranslocation pool to leaf pool)
+ iretransn_to_ileafst => cnveg_nitrogenflux_inst%iretransn_to_ileafst_ph , & ! Transfer index (from retranslocation pool to leaf storage pool)
+ iretransn_to_ifroot => cnveg_nitrogenflux_inst%iretransn_to_ifroot_ph , & ! Transfer index (from retranslocation pool to fine root pool)
+ iretransn_to_ifrootst => cnveg_nitrogenflux_inst%iretransn_to_ifrootst_ph , & ! Transfer index (from retranslocation pool to fine root storage pool)
+ iretransn_to_ilivestem => cnveg_nitrogenflux_inst%iretransn_to_ilivestem_ph , & ! Transfer index (from retranslocation pool to live stem pool)
+ iretransn_to_ilivestemst => cnveg_nitrogenflux_inst%iretransn_to_ilivestemst_ph , & ! Transfer index (from retranslocation pool to live stem storage pool)
+ iretransn_to_ideadstem => cnveg_nitrogenflux_inst%iretransn_to_ideadstem_ph , & ! Transfer index (from retranslocation pool to dead stem pool)
+ iretransn_to_ideadstemst => cnveg_nitrogenflux_inst%iretransn_to_ideadstemst_ph , & ! Transfer index (from retranslocation pool to dead stem storage pool)
+ iretransn_to_ilivecroot => cnveg_nitrogenflux_inst%iretransn_to_ilivecroot_ph , & ! Transfer index (from retranslocation pool to live coarse root pool)
+ iretransn_to_ilivecrootst => cnveg_nitrogenflux_inst%iretransn_to_ilivecrootst_ph , & ! Transfer index (from retranslocation pool to live coarse root storage pool)
+ iretransn_to_ideadcroot => cnveg_nitrogenflux_inst%iretransn_to_ideadcroot_ph , & ! Transfer index (from retranslocation pool to dead coarse root pool)
+ iretransn_to_ideadcrootst => cnveg_nitrogenflux_inst%iretransn_to_ideadcrootst_ph , & ! Transfer index (from retranslocation pool to dead coarse root storage pool)
+ iretransn_to_igrain => cnveg_nitrogenflux_inst%iretransn_to_igrain_ph , & ! Transfer index (from retranslocation pool to grain pool)
+ iretransn_to_igrainst => cnveg_nitrogenflux_inst%iretransn_to_igrainst_ph , & ! Transfer index (from retranslocation pool to grain storage pool)
+ iretransn_to_iout => cnveg_nitrogenflux_inst%iretransn_to_iout_ph , & ! Transfer index (from retranslocation pool to external)
+ ileaf_to_iretransn => cnveg_nitrogenflux_inst%ileaf_to_iretransn_ph , & ! Transfer index (from leaf pool to retranslocation pools)
+ ifroot_to_iretransn => cnveg_nitrogenflux_inst%ifroot_to_iretransn_ph , & ! Transfer index (from fine root pool to retranslocation pools)
+ ilivestem_to_iretransn => cnveg_nitrogenflux_inst%ilivestem_to_iretransn_ph & ! Transfer index (from live stem pool to retranslocation pools)
)
+ ! set time steps
+ dt = get_step_size_real()
+
! patch loop to distribute the available N between the competing patches
! on the basis of relative demand, and allocate C and N to new growth and storage
@@ -408,7 +436,6 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
! turning off this correction (PET, 12/11/03), instead using bgtr in
! phenology algorithm.
-
if(use_fun)then ! if we are using FUN, we get the N available from there.
sminn_to_npool(p) = sminn_to_plant_fun(p)
else ! no FUN. :( we get N available from the FPG calculation in soilbiogeochemistry competition.
@@ -416,24 +443,23 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
endif
plant_nalloc(p) = sminn_to_npool(p) + retransn_to_npool(p)
-
- ! Assign sminn_to_npool to matrix solution
if(use_matrixcn)then
- else
- ! Non-matrix equivalent for above is in CNNStateUpdateMod:NStateUpdate1
+ associate( &
+ matrix_Ninput => cnveg_nitrogenflux_inst%matrix_Ninput_patch & ! N input of matrix
+ )
+ matrix_Ninput(p) = sminn_to_npool(p)
+ end associate
end if
if(use_fun)then
- plant_calloc(p) = npp_growth(p)
-
- ! Assign npp_growth to matrix solution
+ plant_calloc(p) = npp_growth(p)
if(use_matrixcn)then
+ cnveg_carbonflux_inst%matrix_Cinput_patch(p) = npp_growth(p)
end if
else
plant_calloc(p) = availc(p)
-
- ! Assign availc to matrix solution
if(use_matrixcn)then
+ cnveg_carbonflux_inst%matrix_Cinput_patch(p) = availc(p)
end if
end if
@@ -450,11 +476,10 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
cpool_to_leafc_storage(p) = nlc * (1._r8 - fcur)
cpool_to_frootc(p) = nlc * f1 * fcur
cpool_to_frootc_storage(p) = nlc * f1 * (1._r8 - fcur)
-
- ! Assign above terms to cpool_to_veg for matrix solution
if(use_matrixcn)then
+ cpool_to_veg = cpool_to_leafc(p) + cpool_to_leafc_storage(p) &
+ + cpool_to_frootc(p) + cpool_to_frootc_storage(p)
end if
-
if (woody(ivt(p)) == 1._r8) then
cpool_to_livestemc(p) = nlc * f3 * f4 * fcur
cpool_to_livestemc_storage(p) = nlc * f3 * f4 * (1._r8 - fcur)
@@ -464,9 +489,12 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
cpool_to_livecrootc_storage(p) = nlc * f2 * f3 * f4 * (1._r8 - fcur)
cpool_to_deadcrootc(p) = nlc * f2 * f3 * (1._r8 - f4) * fcur
cpool_to_deadcrootc_storage(p) = nlc * f2 * f3 * (1._r8 - f4) * (1._r8 - fcur)
-
- ! Assign above terms to cpool_to_veg for matrix solution
if(use_matrixcn)then
+ cpool_to_veg = cpool_to_veg &
+ + cpool_to_livestemc(p) + cpool_to_livestemc_storage(p) &
+ + cpool_to_deadstemc(p) + cpool_to_deadstemc_storage(p) &
+ + cpool_to_livecrootc(p) + cpool_to_livecrootc_storage(p) &
+ + cpool_to_deadcrootc(p) + cpool_to_deadcrootc_storage(p)
end if
end if
if (ivt(p) >= npcropmin) then ! skip 2 generic crops
@@ -482,14 +510,63 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
cpool_to_reproductivec(p,k) = nlc * f5(k) * fcur
cpool_to_reproductivec_storage(p,k) = nlc * f5(k) * (1._r8 -fcur)
end do
-
- ! Assign above terms to cpool_to_veg for matrix solution
if(use_matrixcn)then
+ cpool_to_veg = cpool_to_veg &
+ + cpool_to_livestemc(p) + cpool_to_livestemc_storage(p) &
+ + cpool_to_deadstemc(p) + cpool_to_deadstemc_storage(p) &
+ + cpool_to_livecrootc(p) + cpool_to_livecrootc_storage(p) &
+ + cpool_to_deadcrootc(p) + cpool_to_deadcrootc_storage(p)
+ do k = 1, nrepr
+ cpool_to_veg = cpool_to_veg &
+ + cpool_to_reproductivec(p,k) + cpool_to_reproductivec_storage(p,k)
+ end do
end if
end if
- ! Assign above cpool_to_* terms to matrix solution
if (use_matrixcn) then
+ associate( &
+ matrix_Cinput => cnveg_carbonflux_inst%matrix_Cinput_patch, & ! C input of matrix
+ matrix_alloc => cnveg_carbonflux_inst%matrix_alloc_patch & ! B-matrix for carbon allocation
+ )
+ matrix_Cinput(p) = cpool_to_veg
+ if(cpool_to_veg .ne. 0)then
+ matrix_alloc(p,ileaf) = cpool_to_leafc(p) / cpool_to_veg
+ matrix_alloc(p,ileaf_st) = cpool_to_leafc_storage(p) / cpool_to_veg
+ matrix_alloc(p,ifroot) = cpool_to_frootc(p) / cpool_to_veg
+ matrix_alloc(p,ifroot_st) = cpool_to_frootc_storage(p) / cpool_to_veg
+ end if
+
+ if (woody(ivt(p)) == 1._r8) then
+ if(cpool_to_veg .ne. 0)then
+ matrix_alloc(p,ilivestem) = cpool_to_livestemc(p) / cpool_to_veg
+ matrix_alloc(p,ilivestem_st) = cpool_to_livestemc_storage(p) / cpool_to_veg
+ matrix_alloc(p,ideadstem) = cpool_to_deadstemc(p) / cpool_to_veg
+ matrix_alloc(p,ideadstem_st) = cpool_to_deadstemc_storage(p) / cpool_to_veg
+ matrix_alloc(p,ilivecroot) = cpool_to_livecrootc(p) / cpool_to_veg
+ matrix_alloc(p,ilivecroot_st) = cpool_to_livecrootc_storage(p) / cpool_to_veg
+ matrix_alloc(p,ideadcroot) = cpool_to_deadcrootc(p) / cpool_to_veg
+ matrix_alloc(p,ideadcroot_st) = cpool_to_deadcrootc_storage(p) / cpool_to_veg
+ end if
+ end if
+ if (ivt(p) >= npcropmin) then ! skip 2 generic crops
+ if(cpool_to_veg .ne. 0)then
+ matrix_alloc(p,ilivestem) = cpool_to_livestemc(p) / cpool_to_veg
+ matrix_alloc(p,ilivestem_st) = cpool_to_livestemc_storage(p) / cpool_to_veg
+ matrix_alloc(p,ideadstem) = cpool_to_deadstemc(p) / cpool_to_veg
+ matrix_alloc(p,ideadstem_st) = cpool_to_deadstemc_storage(p) / cpool_to_veg
+ matrix_alloc(p,ilivecroot) = cpool_to_livecrootc(p) / cpool_to_veg
+ matrix_alloc(p,ilivecroot_st) = cpool_to_livecrootc_storage(p) / cpool_to_veg
+ matrix_alloc(p,ideadcroot) = cpool_to_deadcrootc(p) / cpool_to_veg
+ matrix_alloc(p,ideadcroot_st) = cpool_to_deadcrootc_storage(p) / cpool_to_veg
+ matrix_alloc(p,igrain) = 0.0_r8
+ matrix_alloc(p,igrain_st) = 0.0_r8
+ do k = 1, nrepr
+ matrix_alloc(p,igrain) = matrix_alloc(p,igrain) + cpool_to_reproductivec(p,k) / cpool_to_veg
+ matrix_alloc(p,igrain_st) = matrix_alloc(p,igrain_st) + cpool_to_reproductivec_storage(p,k) / cpool_to_veg
+ end do
+ end if
+ end if
+ end associate
end if !use_matrixcn
! Calculate the amount of carbon that needs to go into growth
@@ -755,8 +832,8 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
cpool_to_frootc_storage_resp(p) + cpool_to_livecrootc_resp(p) + cpool_to_livecrootc_storage_resp(p) + &
cpool_to_livestemc_resp(p) + cpool_to_livestemc_storage_resp(p)
- ! Assign cpool_to_resp term to matrix solution
if(use_matrixcn)then
+ cnveg_carbonflux_inst%matrix_Cinput_patch(p) = cnveg_carbonflux_inst%matrix_Cinput_patch(p) - cpool_to_resp(p)
end if
end if ! end of if (carbon_resp_opt == 1 .AND. laisun(p)+laisha(p) > 0.0_r8) then
@@ -767,28 +844,80 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
!end if
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ! Do matrix update of above terms
if(use_matrixcn)then
associate( &
+ matrix_Ninput => cnveg_nitrogenflux_inst%matrix_Ninput_patch, & ! N input of matrix
+ matrix_nalloc => cnveg_nitrogenflux_inst%matrix_nalloc_patch, & ! B-matrix for nitrogen allocation
psnsun_to_cpool => cnveg_carbonflux_inst%psnsun_to_cpool_patch, & !
psnshade_to_cpool => cnveg_carbonflux_inst%psnshade_to_cpool_patch & !
)
- if(use_c13 .and. psnsun_to_cpool(p)+psnshade_to_cpool(p).ne. 0.)then
+ if(use_c13 .and. psnsun_to_cpool(p)+psnshade_to_cpool(p).ne. 0._r8)then
+ associate( &
+ matrix_C13input => cnveg_carbonflux_inst%matrix_C13input_patch & ! C13 input of matrix
+ )
+ matrix_C13input(p) = plant_calloc(p) * &
+ ((c13_cnveg_carbonflux_inst%psnsun_to_cpool_patch(p)+ c13_cnveg_carbonflux_inst%psnshade_to_cpool_patch(p))/ &
+ (psnsun_to_cpool(p)+psnshade_to_cpool(p)))
+ end associate
end if
- if(use_c14 .and. psnsun_to_cpool(p)+psnshade_to_cpool(p).ne. 0.)then
+ if(use_c14 .and. psnsun_to_cpool(p)+psnshade_to_cpool(p).ne. 0._r8)then
+ associate( &
+ matrix_C14input => cnveg_carbonflux_inst%matrix_C14input_patch & ! C14 input of matrix
+ )
+ matrix_C14input(p) = plant_calloc(p) * &
+ ((c14_cnveg_carbonflux_inst%psnsun_to_cpool_patch(p)+ c14_cnveg_carbonflux_inst%psnshade_to_cpool_patch(p))/ &
+ (psnsun_to_cpool(p)+psnshade_to_cpool(p)))
+ end associate
end if
+ npool_to_veg = npool_to_leafn(p) + npool_to_leafn_storage(p) &
+ + npool_to_frootn(p) + npool_to_frootn_storage(p) &
+ + npool_to_livestemn(p) + npool_to_livestemn_storage(p) &
+ + npool_to_deadstemn(p) + npool_to_deadstemn_storage(p) &
+ + npool_to_livecrootn(p) + npool_to_livecrootn_storage(p) &
+ + npool_to_deadcrootn(p) + npool_to_deadcrootn_storage(p)
if (ivt(p) >= npcropmin)then
+ npool_to_veg = npool_to_veg + npool_to_reproductiven(p,1) + npool_to_reproductiven_storage(p,1)
end if
- if(npool_to_veg .ne. 0)then
+ if(npool_to_veg .ne. 0._r8)then
+ matrix_nalloc(p,ileaf ) = npool_to_leafn(p) / npool_to_veg
+ matrix_nalloc(p,ileaf_st ) = npool_to_leafn_storage(p) / npool_to_veg
+ matrix_nalloc(p,ifroot ) = npool_to_frootn(p) / npool_to_veg
+ matrix_nalloc(p,ifroot_st ) = npool_to_frootn_storage(p) / npool_to_veg
+ matrix_nalloc(p,ilivestem ) = npool_to_livestemn(p) / npool_to_veg
+ matrix_nalloc(p,ilivestem_st ) = npool_to_livestemn_storage(p) / npool_to_veg
+ matrix_nalloc(p,ideadstem ) = npool_to_deadstemn(p) / npool_to_veg
+ matrix_nalloc(p,ideadstem_st ) = npool_to_deadstemn_storage(p) / npool_to_veg
+ matrix_nalloc(p,ilivecroot ) = npool_to_livecrootn(p) / npool_to_veg
+ matrix_nalloc(p,ilivecroot_st ) = npool_to_livecrootn_storage(p) / npool_to_veg
+ matrix_nalloc(p,ideadcroot ) = npool_to_deadcrootn(p) / npool_to_veg
+ matrix_nalloc(p,ideadcroot_st ) = npool_to_deadcrootn_storage(p) / npool_to_veg
if (ivt(p) >= npcropmin)then
+ matrix_nalloc(p,igrain ) = npool_to_reproductiven(p,1) / npool_to_veg
+ matrix_nalloc(p,igrain_st ) = npool_to_reproductiven_storage(p,1) / npool_to_veg
end if
+ matrix_Ninput(p) = npool_to_veg - retransn_to_npool(p)
else
- if(retransn(p) .ne. 0)then
+ if(retransn(p) .ne. 0._r8)then
+ retransn_to_npool(p) = retransn(p) * matrix_update_phn(p,iretransn_to_iout,retransn_to_npool(p)/retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
end if
end if
-
- if(retransn(p) .ne. 0)then
+
+ if(retransn(p) .ne. 0._r8)then
+ tmp = matrix_update_phn(p,iretransn_to_ileaf ,matrix_nalloc(p,ileaf ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ileafst ,matrix_nalloc(p,ileaf_st ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ifroot ,matrix_nalloc(p,ifroot ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ifrootst ,matrix_nalloc(p,ifroot_st ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ilivestem ,matrix_nalloc(p,ilivestem ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ilivestemst ,matrix_nalloc(p,ilivestem_st ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ideadstem ,matrix_nalloc(p,ideadstem ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ideadstemst ,matrix_nalloc(p,ideadstem_st ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ilivecroot ,matrix_nalloc(p,ilivecroot ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ilivecrootst ,matrix_nalloc(p,ilivecroot_st ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ideadcroot ,matrix_nalloc(p,ideadcroot ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ideadcrootst ,matrix_nalloc(p,ideadcroot_st ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
if(ivt(p) >= npcropmin)then
+ tmp = matrix_update_phn(p,iretransn_to_igrain ,matrix_nalloc(p,igrain ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_igrainst ,matrix_nalloc(p,igrain_st ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
end if
end if
end associate
@@ -1247,12 +1376,10 @@ subroutine calc_plant_nitrogen_demand(this, bounds, &
! - livestemn_to_retransn
!
! !USES:
- use pftconMod , only : npcropmin, pftcon
use pftconMod , only : ntmp_soybean, nirrig_tmp_soybean
use pftconMod , only : ntrp_soybean, nirrig_trp_soybean
use clm_varcon , only : dzsoi_decomp
use clm_varpar , only : nlevdecomp
- use clm_time_manager , only : get_step_size_real
use CanopyStateType , only : canopystate_type
use CropType , only : crop_type
use CNVegStateType , only : cnveg_state_type
@@ -1266,6 +1393,13 @@ subroutine calc_plant_nitrogen_demand(this, bounds, &
use CNSharedParamsMod , only : use_fun
use CNPrecisionControlMod , only : n_min
use clm_varcon , only : spval
+ use clm_varpar , only : ileaf,ileaf_st,ileaf_xf,ifroot,ifroot_st,ifroot_xf,&
+ ilivestem,ilivestem_st,ilivestem_xf,&
+ ideadstem,ideadstem_st,ideadstem_xf,&
+ ilivecroot,ilivecroot_st,ilivecroot_xf,&
+ ideadcroot,ideadcroot_st,ideadcroot_xf,&
+ igrain,igrain_st,igrain_xf,iretransn,ioutc,ioutn
+ use CNVegMatrixMod , only : matrix_update_phn
! !ARGUMENTS:
class(nutrient_competition_FlexibleCN_type), intent(inout) :: this
type(bounds_type) , intent(in) :: bounds
@@ -1356,16 +1490,16 @@ subroutine calc_plant_nitrogen_demand(this, bounds, &
plant_ndemand => cnveg_nitrogenflux_inst%plant_ndemand_patch , & ! Output: [real(r8) (:) ] N flux required to support initial GPP (gN/m2/s)
avail_retransn => cnveg_nitrogenflux_inst%avail_retransn_patch , & ! Output: [real(r8) (:) ] N flux available from retranslocation pool (gN/m2/s)
retransn_to_npool => cnveg_nitrogenflux_inst%retransn_to_npool_patch , & ! Output: [real(r8) (:) ] deployment of retranslocated N (gN/m2/s)
- leafn_to_litter => cnveg_nitrogenflux_inst%leafn_to_litter_patch , & ! Output: [real(r8) (:) ] leaf N litterfall (gN/m2/s)
- frootn_to_litter => cnveg_nitrogenflux_inst%frootn_to_litter_patch , & ! Output: [real(r8) (:) ] fine root N litterfall (gN/m2/s)
- livestemn_to_litter => cnveg_nitrogenflux_inst%livestemn_to_litter_patch , & ! Input: [real(r8) (:) ] livestem N to litter (gN/m2/s)
leafn_to_retransn => cnveg_nitrogenflux_inst%leafn_to_retransn_patch , & ! Output: [real(r8) (:) ]
frootn_to_retransn => cnveg_nitrogenflux_inst%frootn_to_retransn_patch , & ! Output: [real(r8) (:) ]
+ livestemn_to_retransn => cnveg_nitrogenflux_inst%livestemn_to_retransn_patch,& ! Output: [real(r8) (:) ]
livestemn => cnveg_nitrogenstate_inst%livestemn_patch , & ! Input: [real(r8) (:) ] (gN/m2) livestem N
frootn => cnveg_nitrogenstate_inst%frootn_patch , & ! Input: [real(r8) (:) ] (gN/m2) fine root N
- livestemn_to_retransn => cnveg_nitrogenflux_inst%livestemn_to_retransn_patch,& ! Output: [real(r8) (:) ]
sminn_vr => soilbiogeochem_nitrogenstate_inst%sminn_vr_col , & ! Input: [real(r8) (:,:) ] (gN/m3) soil mineral N
- t_scalar => soilbiogeochem_carbonflux_inst%t_scalar_col & ! Input: [real(r8) (:,:) ] soil temperature scalar for decomp
+ t_scalar => soilbiogeochem_carbonflux_inst%t_scalar_col , & ! Input: [real(r8) (:,:) ] soil temperature scalar for decomp
+ ileaf_to_iretransn_phn => cnveg_nitrogenflux_inst%ileaf_to_iretransn_ph, &
+ ifroot_to_iretransn_phn => cnveg_nitrogenflux_inst%ifroot_to_iretransn_ph, &
+ ilivestem_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivestem_to_iretransn_ph &
)
! set time steps
@@ -1386,7 +1520,6 @@ subroutine calc_plant_nitrogen_demand(this, bounds, &
this%actual_leafcn(p) = leafc(p) / leafn(p)
end if
-
leafcn_min = leafcn(ivt(p)) - 10.0_r8
leafcn_max = leafcn(ivt(p)) + 10.0_r8
@@ -1478,14 +1611,15 @@ subroutine calc_plant_nitrogen_demand(this, bounds, &
frootn_to_retransn(p) = t1 * max(frootn(p) - (frootc(p) / ffrootcn(ivt(p))),0._r8)
end if
grain_flag(p) = 1._r8
-
- ! Update matrix terms above
if(use_matrixcn)then
if(leafn(p) .ne. 0._r8)then
+ leafn_to_retransn(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iretransn_phn,leafn_to_retransn(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
end if
if(frootn(p) .ne. 0._r8)then
+ frootn_to_retransn(p) = frootn(p) * matrix_update_phn(p,ifroot_to_iretransn_phn,frootn_to_retransn(p) / frootn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
end if
if(livestemn(p) .ne. 0._r8)then
+ livestemn_to_retransn(p) = livestemn(p) * matrix_update_phn(p,ilivestem_to_iretransn_phn,livestemn_to_retransn(p) / livestemn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
end if
end if
diff --git a/src/biogeochem/test/DustEmis_test/test_DustEmisZender2003.pf b/src/biogeochem/test/DustEmis_test/test_DustEmisZender2003.pf
index 8641b8cceb..0289cadabc 100644
--- a/src/biogeochem/test/DustEmis_test/test_DustEmisZender2003.pf
+++ b/src/biogeochem/test/DustEmis_test/test_DustEmisZender2003.pf
@@ -9,6 +9,7 @@ module test_DustEmisZender2003
use DustEmisZender2003
use shr_kind_mod , only : r8 => shr_kind_r8
use DustEmisFactory, only : create_dust_emissions
+ use shr_dust_emis_mod, only : dust_emis_set_options
implicit none
@@ -37,6 +38,7 @@ contains
call this%input%setUp()
! Create the dust emission object last
+ call dust_emis_set_options( 'Zender_2003', 'atm')
allocate(this%dust_emis, source = create_dust_emissions(bounds, NLFilename))
end subroutine setUp
diff --git a/src/biogeophys/CanopyFluxesMod.F90 b/src/biogeophys/CanopyFluxesMod.F90
index 58334a70c0..a969dc0583 100644
--- a/src/biogeophys/CanopyFluxesMod.F90
+++ b/src/biogeophys/CanopyFluxesMod.F90
@@ -1624,7 +1624,8 @@ subroutine CanopyFluxes(bounds, num_exposedvegp, filter_exposedvegp,
! snocan < rel_epsilon * snocan_baseline will be set to zero
! See NumericsMod for rel_epsilon value
call truncate_small_values(fn, filterp, begp, endp, &
- snocan_baseline(begp:endp), snocan(begp:endp))
+ snocan_baseline(begp:endp), snocan(begp:endp), &
+ custom_rel_epsilon=1.e-10_r8)
if ( use_fates ) then
diff --git a/src/biogeophys/EnergyFluxType.F90 b/src/biogeophys/EnergyFluxType.F90
index 2e709596a1..16929d9708 100644
--- a/src/biogeophys/EnergyFluxType.F90
+++ b/src/biogeophys/EnergyFluxType.F90
@@ -988,7 +988,7 @@ subroutine UpdateAccVars (this, bounds)
!
! USES
use clm_time_manager , only : get_step_size, get_nstep, is_end_curr_day, get_curr_date
- use accumulMod , only : update_accum_field, extract_accum_field, accumResetVal
+ use accumulMod , only : update_accum_field, extract_accum_field
use abortutils , only : endrun
!
! !ARGUMENTS:
diff --git a/src/biogeophys/IrrigationMod.F90 b/src/biogeophys/IrrigationMod.F90
index 27cf050dd3..11c9132eea 100644
--- a/src/biogeophys/IrrigationMod.F90
+++ b/src/biogeophys/IrrigationMod.F90
@@ -221,9 +221,8 @@ module IrrigationMod
! There is no reason to make this a tunable parameter, because the behavior it governs
! (the trigger for irrigation) can be tuned via other parameters.
!
- ! TODO(wjs, 2016-09-08) It looks like there is other code in CLM that also uses an
- ! assumed wilting point (CNRootDynMod, maybe others). We should probably make this a
- ! shared parameter, e.g., in clm_varcon.
+ ! TODO(wjs, 2016-09-08, updated by slevis 2024-07-06) assumed wilting point:
+ ! Make this a shared parameter? E.g., in clm_varcon
real(r8), parameter, private :: wilting_point_smp = -150000._r8
! Conversion factors
diff --git a/src/biogeophys/SoilStateType.F90 b/src/biogeophys/SoilStateType.F90
index e301cc27b9..2e7225f962 100644
--- a/src/biogeophys/SoilStateType.F90
+++ b/src/biogeophys/SoilStateType.F90
@@ -9,7 +9,7 @@ module SoilStateType
use abortutils , only : endrun
use clm_varpar , only : nlevsoi, nlevgrnd, nlevlak, nlayer, nlevsno, nlevmaxurbgrnd
use clm_varcon , only : spval
- use clm_varctl , only : use_hydrstress, use_cn, use_lch4, use_dynroot, use_fates
+ use clm_varctl , only : use_hydrstress, use_cn, use_lch4, use_fates
use clm_varctl , only : iulog, hist_wrtch4diag
use LandunitType , only : lun
use ColumnType , only : col
@@ -231,20 +231,6 @@ subroutine InitHistory(this, bounds)
ptr_col=this%bsw_col, default='inactive')
end if
- if (use_dynroot) then
- this%rootfr_patch(begp:endp,:) = spval
- call hist_addfld2d (fname='ROOTFR', units='proportion', type2d='levgrnd', &
- avgflag='A', long_name='fraction of roots in each soil layer', &
- ptr_patch=this%rootfr_patch, default='active')
- end if
-
- if ( use_dynroot ) then
- this%root_depth_patch(begp:endp) = spval
- call hist_addfld1d (fname='ROOT_DEPTH', units="m", &
- avgflag='A', long_name='rooting depth', &
- ptr_patch=this%root_depth_patch )
- end if
-
if (use_cn) then
this%rootr_patch(begp:endp,:) = spval
call hist_addfld2d (fname='ROOTR', units='proportion', type2d='levgrnd', &
@@ -393,15 +379,7 @@ subroutine Restart(this, bounds, ncid, flag)
scale_by_thickness=.true., &
interpinic_flag='interp', readvar=readvar, data=this%hk_l_col)
- if( use_dynroot ) then
- call restartvar(ncid=ncid, flag=flag, varname='rootfr', xtype=ncd_double, &
- dim1name='pft', dim2name='levgrnd', switchdim=.true., &
- long_name='root fraction', units='', &
- scale_by_thickness=.false., &
- interpinic_flag='interp', readvar=readrootfr, data=this%rootfr_patch)
- else
- readrootfr = .false.
- end if
+ readrootfr = .false.
if (flag=='read' .and. .not. readrootfr ) then
if (masterproc) then
write(iulog,*) "can't find rootfr in restart (or initial) file..."
diff --git a/src/biogeophys/TemperatureType.F90 b/src/biogeophys/TemperatureType.F90
index 3771735bb7..899da6b882 100644
--- a/src/biogeophys/TemperatureType.F90
+++ b/src/biogeophys/TemperatureType.F90
@@ -8,6 +8,7 @@ module TemperatureType
use decompMod , only : bounds_type
use abortutils , only : endrun
use clm_varctl , only : use_cndv, iulog, use_luna, use_crop, use_biomass_heat_storage
+ use clm_varctl , only : flush_gdd20
use clm_varpar , only : nlevsno, nlevgrnd, nlevlak, nlevurb, nlevmaxurbgrnd, nlevsoi
use clm_varcon , only : spval, ispval
use GridcellType , only : grc
@@ -133,6 +134,7 @@ module TemperatureType
procedure, public :: InitAccBuffer
procedure, public :: InitAccVars
procedure, public :: UpdateAccVars
+ procedure, private :: UpdateAccVars_CropGDDs
procedure, private :: ReadNL
@@ -612,9 +614,7 @@ subroutine InitHistory(this, bounds, is_simple_buildtemp, is_prog_buildtemp )
call hist_addfld1d (fname='GDD0', units='ddays', &
avgflag='A', long_name='Growing degree days base 0C from planting', &
ptr_patch=this%gdd0_patch, default='inactive')
- end if
- if (use_crop) then
this%gdd8_patch(begp:endp) = spval
call hist_addfld1d (fname='GDD8', units='ddays', &
avgflag='A', long_name='Growing degree days base 8C from planting', &
@@ -625,6 +625,21 @@ subroutine InitHistory(this, bounds, is_simple_buildtemp, is_prog_buildtemp )
avgflag='A', long_name='Growing degree days base 10C from planting', &
ptr_patch=this%gdd10_patch, default='inactive')
+ this%gdd0_patch(begp:endp) = spval
+ call hist_addfld1d (fname='GDD0X', units='ddays', &
+ avgflag='X', long_name='Growing degree days base 0C from planting, max', &
+ ptr_patch=this%gdd0_patch, default='inactive')
+
+ this%gdd8_patch(begp:endp) = spval
+ call hist_addfld1d (fname='GDD8X', units='ddays', &
+ avgflag='X', long_name='Growing degree days base 8C from planting, max', &
+ ptr_patch=this%gdd8_patch, default='inactive')
+
+ this%gdd10_patch(begp:endp) = spval
+ call hist_addfld1d (fname='GDD10X', units='ddays', &
+ avgflag='X', long_name='Growing degree days base 10C from planting, max', &
+ ptr_patch=this%gdd10_patch, default='inactive')
+
this%gdd020_patch(begp:endp) = spval
call hist_addfld1d (fname='GDD020', units='ddays', &
avgflag='A', long_name='Twenty year average of growing degree days base 0C from planting', &
@@ -930,6 +945,7 @@ subroutine Restart(this, bounds, ncid, flag, is_simple_buildtemp, is_prog_buildt
! !LOCAL VARIABLES:
integer :: j,c ! indices
logical :: readvar ! determine if variable is on initial file
+ integer :: idata
!-----------------------------------------------------------------------
call restartvar(ncid=ncid, flag=flag, varname='T_SOISNO', xtype=ncd_double, &
@@ -1392,22 +1408,133 @@ subroutine InitAccVars(this, bounds)
end subroutine InitAccVars
- !-----------------------------------------------------------------------
- subroutine UpdateAccVars (this, bounds)
+ subroutine UpdateAccVars_CropGDDs(this, rbufslp, begp, endp, month, day, secs, dtime, nstep, basetemp_int, gddx_patch, crop_inst)
!
! USES
use shr_const_mod , only : SHR_CONST_CDAY, SHR_CONST_TKFRZ
+ use accumulMod , only : update_accum_field, extract_accum_field, markreset_accum_field
+ use clm_time_manager , only : is_doy_in_interval, get_curr_calday
+ use pftconMod , only : npcropmin
+ use CropType, only : crop_type
+ !
+ ! !ARGUMENTS
+ class(temperature_type) :: this
+ real(r8), intent(inout), pointer, dimension(:) :: rbufslp ! temporary single level - pft level
+ integer, intent(in) :: begp, endp
+ integer, intent(in) :: month, day, secs, dtime, nstep
+ integer, intent(in) :: basetemp_int ! Crop base temperature. Integer to avoid possible float weirdness
+ real(r8), intent(inout), pointer, dimension(:) :: gddx_patch ! E.g., gdd0_patch
+ type(crop_type), intent(inout) :: crop_inst
+ !
+ ! !LOCAL VARIABLES
+ real(r8) :: basetemp_r8 ! real(r8) version of basetemp for arithmetic
+ real(r8) :: max_accum ! Maximum daily accumulation
+ character(8) :: field_name ! E.g., GDD0
+ character(32) :: format_string
+ integer :: p
+ logical :: in_accumulation_season
+ real(r8) :: lat ! latitude
+ integer :: gdd20_season_start, gdd20_season_end
+ integer :: jday ! Julian day of year (1, ..., 366)
+ logical :: stream_gdd20_seasons_tt ! Local derivation of this to avoid circular dependency
+
+ associate( &
+ gdd20_season_starts => crop_inst%gdd20_season_start_patch, &
+ gdd20_season_ends => crop_inst%gdd20_season_end_patch &
+ )
+
+ basetemp_r8 = real(basetemp_int, r8)
+
+ ! SSR 2024-06-13: This should probably be _prev_. Keeping it _curr_ for now for consistency with
+ ! parent subroutine UpdateAccVars(), which uses get_curr_date() to get the month/day/etc. values
+ ! that are passed into this subroutine.
+ jday = int(get_curr_calday())
+
+ ! Get maximum daily accumulation
+ if (basetemp_int == 0) then
+ ! SSR 2024-05-31: I'm not sure why this was different for base temp 0, but I'm keeping it as I refactor into UpdateAccVars_CropGDDs()
+ max_accum = 26._r8
+ else
+ max_accum = 30._r8
+ end if
+
+ ! Get field name
+ if (basetemp_int < 10) then
+ format_string = "(A3,I1)"
+ else if (basetemp_int < 100) then
+ format_string = "(A3,I2)"
+ else
+ format_string = "(A3,I3)"
+ end if
+ write(field_name, format_string) "GDD",basetemp_int
+
+ stream_gdd20_seasons_tt = any(gdd20_season_starts(begp:endp) > 0.5_r8) .and. any(gdd20_season_starts(begp:endp) < 366.5_r8)
+
+ do p = begp,endp
+
+ ! Avoid unnecessary calculations over inactive points
+ if (.not. patch%active(p)) then
+ cycle
+ end if
+
+ ! Is this patch in its gdd20 accumulation season?
+ ! First, check based on latitude. This will be fallback if read-in gdd20 accumulation season is invalid.
+ lat = grc%latdeg(patch%gridcell(p))
+ in_accumulation_season = &
+ ((month > 3 .and. month < 10) .and. lat >= 0._r8) .or. &
+ ((month > 9 .or. month < 4) .and. lat < 0._r8)
+ ! Replace with read-in gdd20 accumulation season, if needed and valid
+ ! (If these aren't being read in or they're invalid, they'll be -1)
+ if (stream_gdd20_seasons_tt .and. patch%itype(p) >= npcropmin) then
+ gdd20_season_start = int(gdd20_season_starts(p))
+ gdd20_season_end = int(gdd20_season_ends(p))
+ if (gdd20_season_start >= 1 .and. gdd20_season_end >= 1) then
+ if (gdd20_season_start > 366 .or. gdd20_season_end > 366) then
+ write(iulog,*) 'invalid gdd20 season!'
+ write(iulog,*) ' start: ',gdd20_season_start
+ write(iulog,*) ' end: ',gdd20_season_end
+ call endrun(msg=errMsg(sourcefile, __LINE__))
+ end if
+ in_accumulation_season = is_doy_in_interval( &
+ gdd20_season_start, gdd20_season_end, jday)
+ end if
+ end if
+
+ if (month==1 .and. day==1 .and. secs==dtime) then
+ call markreset_accum_field(field_name, p)
+ else if (in_accumulation_season) then
+ rbufslp(p) = max(0._r8, min(max_accum, &
+ this%t_ref2m_patch(p)-(SHR_CONST_TKFRZ + basetemp_r8))) * dtime/SHR_CONST_CDAY
+ else
+ rbufslp(p) = 0._r8 ! keeps gdd unchanged outside accumulation season
+ end if
+ end do
+
+ ! Save
+ call update_accum_field (trim(field_name), rbufslp, nstep)
+ call extract_accum_field (trim(field_name), gddx_patch, nstep)
+
+ end associate
+ end subroutine UpdateAccVars_CropGDDs
+
+ !-----------------------------------------------------------------------
+ subroutine UpdateAccVars (this, bounds, crop_inst)
+ !
+ ! USES
+ use shr_const_mod , only : SHR_CONST_TKFRZ
use clm_time_manager , only : get_step_size, get_nstep, is_end_curr_day, get_curr_date, is_end_curr_year
- use accumulMod , only : update_accum_field, extract_accum_field, accumResetVal
+ use accumulMod , only : update_accum_field, extract_accum_field, markreset_accum_field
use CNSharedParamsMod, only : upper_soil_layer
+ use CropType , only : crop_type
!
! !ARGUMENTS:
class(temperature_type) :: this
type(bounds_type) , intent(in) :: bounds
+ type(crop_type), intent(inout) :: crop_inst
!
! !LOCAL VARIABLES:
- integer :: m,g,l,c,p ! indices
+ integer :: m,l,c,p ! indices
integer :: ier ! error status
integer :: dtime ! timestep size [seconds]
integer :: nstep ! timestep number
@@ -1427,6 +1554,7 @@ subroutine UpdateAccVars (this, bounds)
dtime = get_step_size()
nstep = get_nstep()
+ ! SSR 2024-06-13: This should probably be changed to _prev_
call get_curr_date (year, month, day, secs)
! Allocate needed dynamic memory for single level pft field
@@ -1570,69 +1698,25 @@ subroutine UpdateAccVars (this, bounds)
call update_accum_field ('TDM10', rbufslp, nstep)
call extract_accum_field ('TDM10', this%t_a10min_patch, nstep)
-
-
! Accumulate and extract GDD0
-
- do p = begp,endp
- ! Avoid unnecessary calculations over inactive points
- if (patch%active(p)) then
- g = patch%gridcell(p)
- if (month==1 .and. day==1 .and. secs==dtime) then
- rbufslp(p) = accumResetVal ! reset gdd
- else if (( month > 3 .and. month < 10 .and. grc%latdeg(g) >= 0._r8) .or. &
- ((month > 9 .or. month < 4) .and. grc%latdeg(g) < 0._r8) ) then
- rbufslp(p) = max(0._r8, min(26._r8, this%t_ref2m_patch(p)-SHR_CONST_TKFRZ)) * dtime/SHR_CONST_CDAY
- else
- rbufslp(p) = 0._r8 ! keeps gdd unchanged at other times (eg, through Dec in NH)
- end if
- end if
- end do
- call update_accum_field ('GDD0', rbufslp, nstep)
- call extract_accum_field ('GDD0', this%gdd0_patch, nstep)
+ call this%UpdateAccVars_CropGDDs(rbufslp, begp, endp, month, day, secs, dtime, nstep, 0, this%gdd0_patch, crop_inst)
! Accumulate and extract GDD8
-
- do p = begp,endp
- ! Avoid unnecessary calculations over inactive points
- if (patch%active(p)) then
- g = patch%gridcell(p)
- if (month==1 .and. day==1 .and. secs==dtime) then
- rbufslp(p) = accumResetVal ! reset gdd
- else if (( month > 3 .and. month < 10 .and. grc%latdeg(g) >= 0._r8) .or. &
- ((month > 9 .or. month < 4) .and. grc%latdeg(g) < 0._r8) ) then
- rbufslp(p) = max(0._r8, min(30._r8, &
- this%t_ref2m_patch(p)-(SHR_CONST_TKFRZ + 8._r8))) * dtime/SHR_CONST_CDAY
- else
- rbufslp(p) = 0._r8 ! keeps gdd unchanged at other times (eg, through Dec in NH)
- end if
- end if
- end do
- call update_accum_field ('GDD8', rbufslp, nstep)
- call extract_accum_field ('GDD8', this%gdd8_patch, nstep)
+ call this%UpdateAccVars_CropGDDs(rbufslp, begp, endp, month, day, secs, dtime, nstep, 8, this%gdd8_patch, crop_inst)
! Accumulate and extract GDD10
-
- do p = begp,endp
- ! Avoid unnecessary calculations over inactive points
- if (patch%active(p)) then
- g = patch%gridcell(p)
- if (month==1 .and. day==1 .and. secs==dtime) then
- rbufslp(p) = accumResetVal ! reset gdd
- else if (( month > 3 .and. month < 10 .and. grc%latdeg(g) >= 0._r8) .or. &
- ((month > 9 .or. month < 4) .and. grc%latdeg(g) < 0._r8) ) then
- rbufslp(p) = max(0._r8, min(30._r8, &
- this%t_ref2m_patch(p)-(SHR_CONST_TKFRZ + 10._r8))) * dtime/SHR_CONST_CDAY
- else
- rbufslp(p) = 0._r8 ! keeps gdd unchanged at other times (eg, through Dec in NH)
- end if
- end if
- end do
- call update_accum_field ('GDD10', rbufslp, nstep)
- call extract_accum_field ('GDD10', this%gdd10_patch, nstep)
+ call this%UpdateAccVars_CropGDDs(rbufslp, begp, endp, month, day, secs, dtime, nstep, 10, this%gdd10_patch, crop_inst)
! Accumulate and extract running 20-year means
if (is_end_curr_year()) then
+ ! Flush, if needed
+ if (flush_gdd20) then
+ write(iulog, *) 'Flushing GDD20 variables'
+ call markreset_accum_field('GDD020')
+ call markreset_accum_field('GDD820')
+ call markreset_accum_field('GDD1020')
+ flush_gdd20 = .false.
+ end if
call update_accum_field ('GDD020', this%gdd0_patch, nstep)
call extract_accum_field ('GDD020', this%gdd020_patch, nstep)
call update_accum_field ('GDD820', this%gdd8_patch, nstep)
diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90
index 4c985f0ab3..c680b13306 100644
--- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90
+++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90
@@ -210,7 +210,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec,
use clm_varctl , only : iulog
use abortutils , only : endrun
use clm_varpar , only : nlevurb, nlevsno, nlevmaxurbgrnd
- use UrbanParamsType , only : urban_hac, urban_hac_off, urban_hac_on, urban_wasteheat_on
+ use UrbanParamsType , only : urban_hac, urban_hac_off, urban_hac_on, urban_wasteheat_on, urban_explicit_ac
!
! !ARGUMENTS:
implicit none
@@ -236,6 +236,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec,
real(r8) :: t_floor_bef(bounds%begl:bounds%endl) ! floor temperature at previous time step (K)
real(r8) :: t_building_bef(bounds%begl:bounds%endl) ! internal building air temperature at previous time step [K]
real(r8) :: t_building_bef_hac(bounds%begl:bounds%endl)! internal building air temperature before applying HAC [K]
+ real(r8) :: eflx_urban_ac_sat(bounds%begl:bounds%endl) ! urban air conditioning flux under AC adoption saturation (W/m**2)
real(r8) :: hcv_roofi(bounds%begl:bounds%endl) ! roof convective heat transfer coefficient (W m-2 K-1)
real(r8) :: hcv_sunwi(bounds%begl:bounds%endl) ! sunwall convective heat transfer coefficient (W m-2 K-1)
real(r8) :: hcv_shdwi(bounds%begl:bounds%endl) ! shadewall convective heat transfer coefficient (W m-2 K-1)
@@ -324,6 +325,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec,
t_floor => temperature_inst%t_floor_lun , & ! InOut: [real(r8) (:)] floor temperature (K)
t_building => temperature_inst%t_building_lun , & ! InOut: [real(r8) (:)] internal building air temperature (K)
+ p_ac => urbantv_inst%p_ac , & ! Input: [real(r8) (:)] air-conditioning penetration rate (a fraction between 0 and 1)
t_building_max => urbantv_inst%t_building_max , & ! Input: [real(r8) (:)] maximum internal building air temperature (K)
t_building_min => urbanparams_inst%t_building_min , & ! Input: [real(r8) (:)] minimum internal building air temperature (K)
@@ -923,9 +925,19 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec,
! rho_dair(l) = pstd / (rair*t_building(l))
if (t_building_bef_hac(l) > t_building_max(l)) then
- t_building(l) = t_building_max(l)
- eflx_urban_ac(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building(l) &
- - (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building_bef_hac(l) )
+ if (urban_explicit_ac) then ! use explicit ac adoption rate parameterization scheme:
+ ! Here, t_building_max is the AC saturation setpoint
+ eflx_urban_ac_sat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building_max(l) &
+ - (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building_bef_hac(l) )
+ t_building(l) = t_building_max(l) + ( 1._r8 - p_ac(l) ) * eflx_urban_ac_sat(l) &
+ * dtime / (ht_roof(l) * rho_dair(l) * cpair * wtlunit_roof(l))
+ eflx_urban_ac(l) = p_ac(l) * eflx_urban_ac_sat(l)
+ else
+ t_building(l) = t_building_max(l)
+ eflx_urban_ac(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building(l) &
+ - (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building_bef_hac(l) )
+ end if
+
else if (t_building_bef_hac(l) < t_building_min(l)) then
t_building(l) = t_building_min(l)
eflx_urban_heat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building(l) &
diff --git a/src/biogeophys/UrbanParamsType.F90 b/src/biogeophys/UrbanParamsType.F90
index c490ad27cc..4b7b80e4fe 100644
--- a/src/biogeophys/UrbanParamsType.F90
+++ b/src/biogeophys/UrbanParamsType.F90
@@ -101,6 +101,7 @@ module UrbanParamsType
character(len= *), parameter, public :: urban_hac_on = 'ON'
character(len= *), parameter, public :: urban_wasteheat_on = 'ON_WASTEHEAT'
character(len= 16), public :: urban_hac = urban_hac_off
+ logical, public :: urban_explicit_ac = .true. ! whether to use explicit, time-varying AC adoption rate
logical, public :: urban_traffic = .false. ! urban traffic fluxes
! !PRIVATE MEMBER DATA:
@@ -847,7 +848,7 @@ subroutine UrbanReadNML ( NLFilename )
integer :: unitn ! unit for namelist file
character(len=32) :: subname = 'UrbanReadNML' ! subroutine name
- namelist / clmu_inparm / urban_hac, urban_traffic, building_temp_method
+ namelist / clmu_inparm / urban_hac, urban_explicit_ac, urban_traffic, building_temp_method
!EOP
!-----------------------------------------------------------------------
@@ -875,6 +876,7 @@ subroutine UrbanReadNML ( NLFilename )
! Broadcast namelist variables read in
call shr_mpi_bcast(urban_hac, mpicom)
+ call shr_mpi_bcast(urban_explicit_ac, mpicom)
call shr_mpi_bcast(urban_traffic, mpicom)
call shr_mpi_bcast(building_temp_method, mpicom)
@@ -886,6 +888,7 @@ subroutine UrbanReadNML ( NLFilename )
!
if ( masterproc )then
write(iulog,*) ' urban air conditioning/heating and wasteheat = ', urban_hac
+ write(iulog,*) ' urban explicit air-conditioning adoption rate = ', urban_explicit_ac
write(iulog,*) ' urban traffic flux = ', urban_traffic
end if
diff --git a/src/cpl/lilac/lnd_comp_esmf.F90 b/src/cpl/lilac/lnd_comp_esmf.F90
index 298aa730c0..6c8bb2a491 100644
--- a/src/cpl/lilac/lnd_comp_esmf.F90
+++ b/src/cpl/lilac/lnd_comp_esmf.F90
@@ -114,6 +114,8 @@ subroutine lnd_init(comp, import_state, export_state, clock, rc)
use ESMF , only : ESMF_StateAdd
use ESMF , only : operator(==)
+ use shr_dust_emis_mod , only : shr_dust_emis_readnl
+
! input/output variables
type(ESMF_GridComp) :: comp ! CLM gridded component
type(ESMF_State) :: import_state ! CLM import state
@@ -270,6 +272,9 @@ subroutine lnd_init(comp, import_state, export_state, clock, rc)
! Fill in the value for model_meshfile in lnd_comp_shr used by the stream routines in share_esmf/
model_meshfile = trim(lnd_mesh_filename)
+ ! Reading in the drv_flds_in namelist is required for dust emissions
+ call shr_dust_emis_readnl( mpicom, "drv_flds_in")
+
!----------------------
! Obtain caseid and start type from attributes in import state
!----------------------
diff --git a/src/cpl/nuopc/lnd_import_export.F90 b/src/cpl/nuopc/lnd_import_export.F90
index b9966f81e9..624590b9a6 100644
--- a/src/cpl/nuopc/lnd_import_export.F90
+++ b/src/cpl/nuopc/lnd_import_export.F90
@@ -160,9 +160,11 @@ subroutine advertise_fields(gcomp, flds_scalar_name, glc_present, cism_evolve, r
use shr_carma_mod , only : shr_carma_readnl
use shr_ndep_mod , only : shr_ndep_readnl
+ use shr_dust_emis_mod , only : shr_dust_emis_readnl
use shr_fire_emis_mod , only : shr_fire_emis_readnl
use clm_varctl , only : ndep_from_cpl
use controlMod , only : NLFilename
+ use spmdMod , only : mpicom
! input/output variables
type(ESMF_GridComp) :: gcomp
@@ -237,6 +239,9 @@ subroutine advertise_fields(gcomp, flds_scalar_name, glc_present, cism_evolve, r
! The following namelist reads should always be called regardless of the send_to_atm value
+ ! Dust emissions from land to atmosphere
+ call shr_dust_emis_readnl( mpicom, "drv_flds_in")
+
! Dry Deposition velocities from land - ALSO initialize drydep here
call shr_drydep_readnl("drv_flds_in", drydep_nflds)
diff --git a/src/cpl/share_esmf/UrbanTimeVarType.F90 b/src/cpl/share_esmf/UrbanTimeVarType.F90
index 088ec9eeae..926a2c0557 100644
--- a/src/cpl/share_esmf/UrbanTimeVarType.F90
+++ b/src/cpl/share_esmf/UrbanTimeVarType.F90
@@ -24,6 +24,7 @@ module UrbanTimeVarType
type, public :: urbantv_type
!
real(r8), public, pointer :: t_building_max(:) ! lun maximum internal building air temperature (K)
+ real(r8), public, pointer :: p_ac(:) ! lun air-conditioning adoption rate (unitless, between 0 and 1)
type(shr_strdata_type) :: sdat_urbantv ! urban time varying input data stream
contains
! !PUBLIC MEMBER FUNCTIONS:
@@ -31,8 +32,10 @@ module UrbanTimeVarType
procedure, public :: urbantv_init ! Initialize urban time varying stream
procedure, public :: urbantv_interp ! Interpolate urban time varying stream
end type urbantv_type
-
- character(15), private :: stream_varnames(isturb_MIN:isturb_MAX)
+
+ integer , private :: stream_varname_MIN ! minimum index for stream_varnames
+ integer , private :: stream_varname_MAX ! maximum index for stream_varnames
+ character(15), private, pointer :: stream_varnames(:) ! urban time varying variable names
character(len=*), parameter, private :: sourcefile = &
__FILE__
@@ -48,6 +51,7 @@ subroutine Init(this, bounds, NLFilename)
! !USES:
use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
use histFileMod , only : hist_addfld1d
+ use UrbanParamsType , only : urban_explicit_ac
!
! !ARGUMENTS:
class(urbantv_type) :: this
@@ -60,9 +64,22 @@ subroutine Init(this, bounds, NLFilename)
begl = bounds%begl; endl = bounds%endl
+ ! Determine the minimum and maximum indices for stream_varnames
+ stream_varname_MIN = 1
+ ! Get value for the maximum index for stream_varnames: if using explicit AC adoption scheme,
+ ! then set maximum index to 6 for reading in tbuildmax and p_ac for three urban density classes;
+ ! otherwise, set to 3 to only read in tbuildmax for three urban density classes.
+ if (urban_explicit_ac) then
+ stream_varname_MAX = 6
+ else
+ stream_varname_MAX = 3
+ end if
+
! Allocate urbantv data structure
allocate(this%t_building_max(begl:endl)); this%t_building_max(:) = nan
+ allocate(this%p_ac(begl:endl)); this%p_ac(:) = nan
+ allocate(stream_varnames(stream_varname_MIN:stream_varname_MAX))
call this%urbantv_init(bounds, NLFilename)
call this%urbantv_interp(bounds)
@@ -72,6 +89,12 @@ subroutine Init(this, bounds, NLFilename)
avgflag='A', long_name='prescribed maximum interior building temperature', &
ptr_lunit=this%t_building_max, default='inactive', set_nourb=spval, &
l2g_scale_type='unity')
+ if (urban_explicit_ac) then
+ call hist_addfld1d (fname='P_AC', units='a fraction between 0 and 1', &
+ avgflag='A', long_name='prescribed air-conditioning ownership rate', &
+ ptr_lunit=this%p_ac, default='inactive', set_nourb=spval, &
+ l2g_scale_type='unity')
+ end if
end subroutine Init
@@ -88,6 +111,7 @@ subroutine urbantv_init(this, bounds, NLFilename)
use landunit_varcon , only : isturb_tbd, isturb_hd, isturb_md
use dshr_strdata_mod , only : shr_strdata_init_from_inline
use lnd_comp_shr , only : mesh, model_clock
+ use UrbanParamsType , only : urban_explicit_ac
!
! !ARGUMENTS:
implicit none
@@ -107,7 +131,6 @@ subroutine urbantv_init(this, bounds, NLFilename)
character(len=CL) :: urbantvmapalgo = 'nn' ! mapping alogrithm for urban ac
character(len=CL) :: urbantv_tintalgo = 'linear' ! time interpolation alogrithm
integer :: rc ! error code
- character(*), parameter :: urbantvString = "tbuildmax_" ! base string for field string
character(*), parameter :: subName = "('urbantv_init')"
!-----------------------------------------------------------------------
@@ -126,9 +149,14 @@ subroutine urbantv_init(this, bounds, NLFilename)
model_year_align_urbantv = 1 ! align stream_year_first_urbantv with this model year
stream_fldFileName_urbantv = ' '
stream_meshfile_urbantv = ' '
- stream_varnames(isturb_tbd) = urbantvString//"TBD"
- stream_varnames(isturb_hd) = urbantvString//"HD"
- stream_varnames(isturb_md) = urbantvString//"MD"
+ stream_varnames(1) = "tbuildmax_TBD"
+ stream_varnames(2) = "tbuildmax_HD"
+ stream_varnames(3) = "tbuildmax_MD"
+ if (urban_explicit_ac) then
+ stream_varnames(4) = "p_ac_TBD"
+ stream_varnames(5) = "p_ac_HD"
+ stream_varnames(6) = "p_ac_MD"
+ end if
! Read urbantv_streams namelist
if (masterproc) then
@@ -159,7 +187,7 @@ subroutine urbantv_init(this, bounds, NLFilename)
write(iulog,'(a,a)' ) ' stream_fldFileName_urbantv = ',stream_fldFileName_urbantv
write(iulog,'(a,a)' ) ' stream_meshfile_urbantv = ',stream_meshfile_urbantv
write(iulog,'(a,a)' ) ' urbantv_tintalgo = ',urbantv_tintalgo
- do n = isturb_tbd,isturb_md
+ do n = stream_varname_MIN,stream_varname_MAX
write(iulog,'(a,a)' ) ' stream_varname = ',trim(stream_varnames(n))
end do
write(iulog,*) ' '
@@ -176,8 +204,8 @@ subroutine urbantv_init(this, bounds, NLFilename)
stream_lev_dimname = 'null', &
stream_mapalgo = trim(urbantvmapalgo), &
stream_filenames = (/trim(stream_fldfilename_urbantv)/), &
- stream_fldlistFile = stream_varnames(isturb_tbd:isturb_md),&
- stream_fldListModel = stream_varnames(isturb_tbd:isturb_md),&
+ stream_fldlistFile = stream_varnames(stream_varname_MIN:stream_varname_MAX), &
+ stream_fldListModel = stream_varnames(stream_varname_MIN:stream_varname_MAX), &
stream_yearFirst = stream_year_first_urbantv, &
stream_yearLast = stream_year_last_urbantv, &
stream_yearAlign = model_year_align_urbantv, &
@@ -204,6 +232,8 @@ subroutine urbantv_interp(this, bounds)
use clm_instur , only : urban_valid
use dshr_methods_mod , only : dshr_fldbun_getfldptr
use dshr_strdata_mod , only : shr_strdata_advance
+ use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
+ use UrbanParamsType , only : urban_explicit_ac
!
! !ARGUMENTS:
class(urbantv_type) :: this
@@ -235,8 +265,8 @@ subroutine urbantv_interp(this, bounds)
! Create 2d array for all stream variable data
lsize = bounds%endg - bounds%begg + 1
- allocate(dataptr2d(lsize, isturb_MIN:isturb_MAX))
- do n = isturb_MIN,isturb_MAX
+ allocate(dataptr2d(lsize, stream_varname_MIN:stream_varname_MAX))
+ do n = stream_varname_MIN,stream_varname_MAX
call dshr_fldbun_getFldPtr(this%sdat_urbantv%pstrm(1)%fldbun_model, trim(stream_varnames(n)), &
fldptr1=dataptr1d, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) then
@@ -249,18 +279,26 @@ subroutine urbantv_interp(this, bounds)
end do
end do
- ! Determine this%tbuilding_max for all landunits
+ ! Determine this%tbuilding_max (and this%p_ac, if applicable) for all landunits
do l = bounds%begl,bounds%endl
if (lun%urbpoi(l)) then
! Note that since l is within [begl, endl] bounds, we can assume
! lun%gricell(l) is within [begg, endg]
ig = lun%gridcell(l) - bounds%begg + 1
- ! Since we are within an urban land unit, we know that
- ! lun%itype is within [pisturb_MIN, isturb_MAX]
- this%t_building_max(l) = dataptr2d(ig, lun%itype(l))
+ do n = stream_varname_MIN,stream_varname_MAX
+ if (stream_varnames((lun%itype(l)-6)) == stream_varnames(n)) then
+ this%t_building_max(l) = dataptr2d(ig,n)
+ end if
+ if (urban_explicit_ac) then
+ if (stream_varnames((lun%itype(l)-3)) == stream_varnames(n)) then
+ this%p_ac(l) = dataptr2d(ig,n)
+ end if
+ end if
+ end do
else
this%t_building_max(l) = spval
+ this%p_ac(l) = spval
end if
end do
deallocate(dataptr2d)
@@ -272,11 +310,17 @@ subroutine urbantv_interp(this, bounds)
do g = bounds%begg,bounds%endg
if (g == lun%gridcell(l)) exit
end do
+ ! Check for valid urban data
if ( .not. urban_valid(g) .or. (this%t_building_max(l) <= 0._r8)) then
found = .true.
gindx = g
lindx = l
exit
+ else if (urban_explicit_ac .and. (this%p_ac(l) < 0._r8 .or. this%p_ac(l) > 1._r8)) then
+ found = .true.
+ gindx = g
+ lindx = l
+ exit
end if
end if
end do
@@ -285,6 +329,7 @@ subroutine urbantv_interp(this, bounds)
write(iulog,*)'landunit type: ',lun%itype(lindx)
write(iulog,*)'urban_valid: ',urban_valid(gindx)
write(iulog,*)'t_building_max: ',this%t_building_max(lindx)
+ write(iulog,*)'p_ac: ',this%p_ac(lindx)
call endrun(subgrid_index=lindx, subgrid_level=subgrid_level_landunit, &
msg=errmsg(sourcefile, __LINE__))
end if
diff --git a/src/cpl/share_esmf/ZenderSoilErodStreamType.F90 b/src/cpl/share_esmf/ZenderSoilErodStreamType.F90
index 194e022132..32e776063b 100644
--- a/src/cpl/share_esmf/ZenderSoilErodStreamType.F90
+++ b/src/cpl/share_esmf/ZenderSoilErodStreamType.F90
@@ -42,7 +42,6 @@ module ZenderSoilErodStreamType
! ! PRIVATE DATA:
type, private :: streamcontrol_type
- character(len=CL) :: zender_soil_erod_source ! if calculed in lnd or atm
character(len=CL) :: stream_fldFileName_zendersoilerod ! data Filename
character(len=CL) :: stream_meshfile_zendersoilerod ! mesh Filename
character(len=CL) :: zendersoilerod_mapalgo ! map algo
@@ -179,7 +178,7 @@ logical function UseStreams(this)
! file is being used with it
!
! !USES:
- use clm_varctl, only : dust_emis_method
+ use shr_dust_emis_mod, only : is_dust_emis_zender, is_zender_soil_erod_from_land
!
! !ARGUMENTS:
implicit none
@@ -189,7 +188,7 @@ logical function UseStreams(this)
if ( .not. control%namelist_set )then
call endrun(msg=' ERROR namelist NOT set before being used'//errMsg(sourcefile, __LINE__))
end if
- if ( (trim(dust_emis_method) == 'Zender_2003') .and. (control%zender_soil_erod_source == "lnd") )then
+ if ( is_dust_emis_zender() .and. is_zender_soil_erod_from_land() )then
UseStreams = .true.
else
UseStreams = .false.
@@ -289,6 +288,7 @@ subroutine ReadNML(this, bounds, NLFilename)
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
+ use shr_dust_emis_mod, only : is_zender_soil_erod_from_land
!
! arguments
implicit none
@@ -304,14 +304,13 @@ subroutine ReadNML(this, bounds, NLFilename)
character(len=CL) :: stream_meshfile_zendersoilerod = ' '
character(len=CL) :: zendersoilerod_mapalgo = ' '
character(len=CL) :: tmp_file_array(3)
- character(len=3) :: zender_soil_erod_source = 'atm'
character(len=*), parameter :: namelist_name = 'zendersoilerod' ! MUST agree with group name in namelist definition to read.
character(len=*), parameter :: subName = "('zendersoilerod::ReadNML')"
!-----------------------------------------------------------------------
namelist /zendersoilerod/ & ! MUST agree with namelist_name above
zendersoilerod_mapalgo, stream_fldFileName_zendersoilerod, &
- stream_meshfile_zendersoilerod, zender_soil_erod_source
+ stream_meshfile_zendersoilerod
! Default values for namelist
@@ -330,12 +329,11 @@ subroutine ReadNML(this, bounds, NLFilename)
close(nu_nml)
endif
- call shr_mpi_bcast(zender_soil_erod_source , mpicom)
call shr_mpi_bcast(zendersoilerod_mapalgo , mpicom)
call shr_mpi_bcast(stream_fldFileName_zendersoilerod , mpicom)
call shr_mpi_bcast(stream_meshfile_zendersoilerod , mpicom)
- if (masterproc .and. (zender_soil_erod_source == "lnd") ) then
+ if (masterproc .and. is_zender_soil_erod_from_land() ) then
write(iulog,*) ' '
write(iulog,*) namelist_name, ' stream settings:'
write(iulog,*) ' stream_fldFileName_zendersoilerod = ',stream_fldFileName_zendersoilerod
@@ -343,13 +341,10 @@ subroutine ReadNML(this, bounds, NLFilename)
write(iulog,*) ' zendersoilerod_mapalgo = ',zendersoilerod_mapalgo
endif
- if ( (trim(zender_soil_erod_source) /= 'atm') .and. (trim(zender_soil_erod_source) /= 'lnd') )then
- call endrun(msg=' ERROR zender_soil_erod_source must be either lnd or atm and is NOT'//errMsg(sourcefile, __LINE__))
- end if
tmp_file_array(1) = stream_fldFileName_zendersoilerod
tmp_file_array(2) = stream_meshfile_zendersoilerod
tmp_file_array(3) = zendersoilerod_mapalgo
- if ( trim(zender_soil_erod_source) == 'lnd' )then
+ if ( is_zender_soil_erod_from_land() ) then
do i = 1, size(tmp_file_array)
if ( len_trim(tmp_file_array(i)) == 0 )then
call endrun(msg=' ERROR '//trim(tmp_file_array(i))//' must be set when Zender_2003 is being used and zender_soil_erod_source is lnd'//errMsg(sourcefile, __LINE__))
@@ -365,7 +360,6 @@ subroutine ReadNML(this, bounds, NLFilename)
this%stream_fldFileName_zendersoilerod = stream_fldFileName_zendersoilerod
this%stream_meshfile_zendersoilerod = stream_meshfile_zendersoilerod
this%zendersoilerod_mapalgo = zendersoilerod_mapalgo
- this%zender_soil_erod_source = zender_soil_erod_source
this%namelist_set = .true.
diff --git a/src/cpl/share_esmf/cropcalStreamMod.F90 b/src/cpl/share_esmf/cropcalStreamMod.F90
index 0ea63f2c6d..5587641c21 100644
--- a/src/cpl/share_esmf/cropcalStreamMod.F90
+++ b/src/cpl/share_esmf/cropcalStreamMod.F90
@@ -14,7 +14,9 @@ module cropcalStreamMod
use decompMod , only : bounds_type
use abortutils , only : endrun
use clm_varctl , only : iulog
+ use clm_varctl , only : use_crop
use clm_varctl , only : use_cropcal_rx_swindows, use_cropcal_rx_cultivar_gdds, use_cropcal_streams
+ use clm_varctl , only : adapt_cropcal_rx_cultivar_gdds
use clm_varpar , only : mxpft
use clm_varpar , only : mxsowings
use perf_mod , only : t_startf, t_stopf
@@ -35,14 +37,26 @@ module cropcalStreamMod
integer, allocatable :: g_to_ig(:) ! Array matching gridcell index to data index
type(shr_strdata_type) :: sdat_cropcal_swindow_start ! sowing window start input data stream
type(shr_strdata_type) :: sdat_cropcal_swindow_end ! sowing window end input data stream
- type(shr_strdata_type) :: sdat_cropcal_cultivar_gdds ! sdate input data stream
+ type(shr_strdata_type) :: sdat_cropcal_cultivar_gdds ! maturity requirement input data stream
+ type(shr_strdata_type) :: sdat_cropcal_gdd20_baseline ! GDD20 baseline input data stream
+ type(shr_strdata_type) :: sdat_cropcal_gdd20_season_start ! gdd20 season start input data stream
+ type(shr_strdata_type) :: sdat_cropcal_gdd20_season_end ! gdd20 season end input data stream
character(len=CS), allocatable :: stream_varnames_sdate(:) ! used for both start and end dates
character(len=CS), allocatable :: stream_varnames_cultivar_gdds(:)
+ character(len=CS), allocatable :: stream_varnames_gdd20_baseline(:)
+ character(len=CS), allocatable :: stream_varnames_gdd20_season_enddate(:) ! start uses stream_varnames_sdate
integer :: ncft ! Number of crop functional types (excl. generic crops)
logical :: allow_invalid_swindow_inputs ! Fall back on paramfile sowing windows in cases of invalid values in stream_fldFileName_swindow_start and _end?
character(len=CL) :: stream_fldFileName_swindow_start ! sowing window start stream filename to read
character(len=CL) :: stream_fldFileName_swindow_end ! sowing window end stream filename to read
character(len=CL) :: stream_fldFileName_cultivar_gdds ! cultivar growing degree-days stream filename to read
+ character(len=CL) :: stream_fldFileName_gdd20_baseline ! GDD20 baseline stream filename to read
+ logical :: cropcals_rx ! Used only for setting input files in namelist; does nothing in code, but needs to be here so namelist read doesn't crash
+ logical :: cropcals_rx_adapt ! Used only for setting input files in namelist; does nothing in code, but needs to be here so namelist read doesn't crash
+ logical :: stream_gdd20_seasons ! Read start and end dates for gdd20 seasons from streams instead of using hemisphere-specific values
+ logical :: allow_invalid_gdd20_season_inputs ! Fall back on hemisphere "warm periods" in cases of invalid values in stream_fldFileName_gdd20_season_start and _end?
+ character(len=CL) :: stream_fldFileName_gdd20_season_start ! Stream filename to read for start of gdd20 season
+ character(len=CL) :: stream_fldFileName_gdd20_season_end ! Stream filename to read for end of gdd20 season
character(len=*), parameter :: sourcefile = &
__FILE__
@@ -67,9 +81,12 @@ subroutine cropcal_init(bounds)
!
! !LOCAL VARIABLES:
integer :: i,n,ivt ! index
- integer :: stream_year_first_cropcal ! first year in crop calendar streams to use
- integer :: stream_year_last_cropcal ! last year in crop calendar streams to use
- integer :: model_year_align_cropcal ! align stream_year_first_cropcal with
+ integer :: stream_year_first_cropcal_swindows ! first year in sowing window streams to use
+ integer :: stream_year_last_cropcal_swindows ! last year in sowing window streams to use
+ integer :: model_year_align_cropcal_swindows ! alignment year for sowing window streams
+ integer :: stream_year_first_cropcal_cultivar_gdds ! first year in cultivar gdd stream to use
+ integer :: stream_year_last_cropcal_cultivar_gdds ! last year in cultivar gdd stream to use
+ integer :: model_year_align_cropcal_cultivar_gdds ! alignment year for cultivar gdd stream
integer :: nu_nml ! unit for namelist file
integer :: nml_error ! namelist i/o error flag
character(len=CL) :: stream_meshfile_cropcal ! crop calendar stream meshfile
@@ -83,32 +100,54 @@ subroutine cropcal_init(bounds)
! deal with namelist variables here in init
!
namelist /cropcal_streams/ &
- stream_year_first_cropcal, &
- stream_year_last_cropcal, &
- model_year_align_cropcal, &
+ stream_year_first_cropcal_swindows, &
+ stream_year_last_cropcal_swindows, &
+ model_year_align_cropcal_swindows, &
+ stream_year_first_cropcal_cultivar_gdds, &
+ stream_year_last_cropcal_cultivar_gdds, &
+ model_year_align_cropcal_cultivar_gdds, &
allow_invalid_swindow_inputs, &
stream_fldFileName_swindow_start, &
stream_fldFileName_swindow_end, &
stream_fldFileName_cultivar_gdds, &
- stream_meshfile_cropcal
+ stream_fldFileName_gdd20_baseline, &
+ stream_meshfile_cropcal, &
+ cropcals_rx, &
+ cropcals_rx_adapt, &
+ stream_gdd20_seasons, &
+ allow_invalid_gdd20_season_inputs, &
+ stream_fldFileName_gdd20_season_start, &
+ stream_fldFileName_gdd20_season_end
! Default values for namelist
- stream_year_first_cropcal = 1 ! first year in stream to use
- stream_year_last_cropcal = 1 ! last year in stream to use
- model_year_align_cropcal = 1 ! align stream_year_first_cropcal with this model year
+ stream_year_first_cropcal_swindows = 1 ! first year in sowing window streams to use
+ stream_year_last_cropcal_swindows = 1 ! last year in sowing window streams to use
+ model_year_align_cropcal_swindows = 1 ! alignment year for sowing window streams
+ stream_year_first_cropcal_cultivar_gdds = 1 ! first year in cultivar gdd stream to use
+ stream_year_last_cropcal_cultivar_gdds = 1 ! last year in cultivar gdd stream to use
+ model_year_align_cropcal_cultivar_gdds = 1 ! alignment year for cultivar gdd stream
allow_invalid_swindow_inputs = .false.
stream_meshfile_cropcal = ''
stream_fldFileName_swindow_start = ''
stream_fldFileName_swindow_end = ''
stream_fldFileName_cultivar_gdds = ''
+ stream_fldFileName_gdd20_baseline = ''
+ stream_gdd20_seasons = .false.
+ allow_invalid_gdd20_season_inputs = .false.
+ stream_fldFileName_gdd20_season_start = ''
+ stream_fldFileName_gdd20_season_end = ''
! Will need modification to work with mxsowings > 1
ncft = mxpft - npcropmin + 1 ! Ignores generic crops
allocate(stream_varnames_sdate(ncft))
allocate(stream_varnames_cultivar_gdds(ncft))
+ allocate(stream_varnames_gdd20_baseline(ncft))
+ allocate(stream_varnames_gdd20_season_enddate(ncft))
do n = 1,ncft
ivt = npcropmin + n - 1
write(stream_varnames_sdate(n),'(a,i0)') "sdate1_",ivt
write(stream_varnames_cultivar_gdds(n),'(a,i0)') "gdd1_",ivt
+ write(stream_varnames_gdd20_baseline(n),'(a,i0)') "gdd20bl_",ivt
+ write(stream_varnames_gdd20_season_enddate(n),'(a,i0)') "hdate1_",ivt
end do
! Read cropcal_streams namelist
@@ -125,29 +164,47 @@ subroutine cropcal_init(bounds)
end if
close(nu_nml)
endif
- call shr_mpi_bcast(stream_year_first_cropcal , mpicom)
- call shr_mpi_bcast(stream_year_last_cropcal , mpicom)
- call shr_mpi_bcast(model_year_align_cropcal , mpicom)
+ call shr_mpi_bcast(stream_year_first_cropcal_swindows , mpicom)
+ call shr_mpi_bcast(stream_year_last_cropcal_swindows , mpicom)
+ call shr_mpi_bcast(model_year_align_cropcal_swindows , mpicom)
+ call shr_mpi_bcast(stream_year_first_cropcal_cultivar_gdds, mpicom)
+ call shr_mpi_bcast(stream_year_last_cropcal_cultivar_gdds , mpicom)
+ call shr_mpi_bcast(model_year_align_cropcal_cultivar_gdds , mpicom)
call shr_mpi_bcast(allow_invalid_swindow_inputs, mpicom)
call shr_mpi_bcast(stream_fldFileName_swindow_start, mpicom)
call shr_mpi_bcast(stream_fldFileName_swindow_end , mpicom)
call shr_mpi_bcast(stream_fldFileName_cultivar_gdds, mpicom)
+ call shr_mpi_bcast(stream_fldFileName_gdd20_baseline, mpicom)
call shr_mpi_bcast(stream_meshfile_cropcal , mpicom)
+ call shr_mpi_bcast(stream_gdd20_seasons, mpicom)
+ call shr_mpi_bcast(allow_invalid_gdd20_season_inputs, mpicom)
+ call shr_mpi_bcast(stream_fldFileName_gdd20_season_start, mpicom)
+ call shr_mpi_bcast(stream_fldFileName_gdd20_season_end, mpicom)
if (masterproc) then
write(iulog,*)
write(iulog,*) 'cropcal_stream settings:'
- write(iulog,'(a,i8)') ' stream_year_first_cropcal = ',stream_year_first_cropcal
- write(iulog,'(a,i8)') ' stream_year_last_cropcal = ',stream_year_last_cropcal
- write(iulog,'(a,i8)') ' model_year_align_cropcal = ',model_year_align_cropcal
+ write(iulog,'(a,i8)') ' stream_year_first_cropcal_swindows = ',stream_year_first_cropcal_swindows
+ write(iulog,'(a,i8)') ' stream_year_last_cropcal_swindows = ',stream_year_last_cropcal_swindows
+ write(iulog,'(a,i8)') ' model_year_align_cropcal_swindows = ',model_year_align_cropcal_swindows
+ write(iulog,'(a,i8)') ' stream_year_first_cropcal_cultivar_gdds = ',stream_year_first_cropcal_cultivar_gdds
+ write(iulog,'(a,i8)') ' stream_year_last_cropcal_cultivar_gdds = ',stream_year_last_cropcal_cultivar_gdds
+ write(iulog,'(a,i8)') ' model_year_align_cropcal_cultivar_gdds = ',model_year_align_cropcal_cultivar_gdds
write(iulog,'(a,l1)') ' allow_invalid_swindow_inputs = ',allow_invalid_swindow_inputs
write(iulog,'(a,a)' ) ' stream_fldFileName_swindow_start = ',trim(stream_fldFileName_swindow_start)
write(iulog,'(a,a)' ) ' stream_fldFileName_swindow_end = ',trim(stream_fldFileName_swindow_end)
write(iulog,'(a,a)' ) ' stream_fldFileName_cultivar_gdds = ',trim(stream_fldFileName_cultivar_gdds)
+ write(iulog,'(a,a)' ) ' stream_fldFileName_gdd20_baseline = ',trim(stream_fldFileName_gdd20_baseline)
write(iulog,'(a,a)' ) ' stream_meshfile_cropcal = ',trim(stream_meshfile_cropcal)
+ write(iulog,'(a,l1)') ' stream_gdd20_seasons = ',stream_gdd20_seasons
+ write(iulog,'(a,l1)') ' allow_invalid_gdd20_season_inputs = ',allow_invalid_gdd20_season_inputs
+ write(iulog,'(a,a)' ) ' stream_fldFileName_gdd20_season_start = ',stream_fldFileName_gdd20_season_start
+ write(iulog,'(a,a)' ) ' stream_fldFileName_gdd20_season_end = ',stream_fldFileName_gdd20_season_end
do n = 1,ncft
write(iulog,'(a,a)' ) ' stream_varnames_sdate = ',trim(stream_varnames_sdate(n))
write(iulog,'(a,a)' ) ' stream_varnames_cultivar_gdds = ',trim(stream_varnames_cultivar_gdds(n))
+ write(iulog,'(a,a)' ) ' stream_varnames_gdd20_season_enddate = ',trim(stream_varnames_gdd20_season_enddate(n))
+ write(iulog,'(a,a)' ) ' stream_varnames_gdd20_baseline = ',trim(stream_varnames_gdd20_baseline(n))
end do
write(iulog,*)
endif
@@ -155,9 +212,12 @@ subroutine cropcal_init(bounds)
! CLMBuildNamelist checks that both start and end files are provided if either is
use_cropcal_rx_swindows = stream_fldFileName_swindow_start /= ''
use_cropcal_rx_cultivar_gdds = stream_fldFileName_cultivar_gdds /= ''
- use_cropcal_streams = use_cropcal_rx_swindows .or. use_cropcal_rx_cultivar_gdds
+ adapt_cropcal_rx_cultivar_gdds = stream_fldFileName_gdd20_baseline /= ''
+ use_cropcal_streams = .false. ! Will be set to true if any file is read
if (use_cropcal_rx_swindows) then
+ use_cropcal_streams = .true.
+
! Initialize the cdeps data type sdat_cropcal_swindow_start
! NOTE: stream_dtlimit 1.5 didn't work for some reason
call shr_strdata_init_from_inline(sdat_cropcal_swindow_start, &
@@ -172,9 +232,9 @@ subroutine cropcal_init(bounds)
stream_filenames = (/trim(stream_fldFileName_swindow_start)/), &
stream_fldlistFile = stream_varnames_sdate, &
stream_fldListModel = stream_varnames_sdate, &
- stream_yearFirst = stream_year_first_cropcal, &
- stream_yearLast = stream_year_last_cropcal, &
- stream_yearAlign = model_year_align_cropcal, &
+ stream_yearFirst = stream_year_first_cropcal_swindows, &
+ stream_yearLast = stream_year_last_cropcal_swindows, &
+ stream_yearAlign = model_year_align_cropcal_swindows, &
stream_offset = cropcal_offset, &
stream_taxmode = 'extend', &
stream_dtlimit = 1.0e30_r8, &
@@ -199,9 +259,9 @@ subroutine cropcal_init(bounds)
stream_filenames = (/trim(stream_fldFileName_swindow_end)/), &
stream_fldlistFile = stream_varnames_sdate, &
stream_fldListModel = stream_varnames_sdate, &
- stream_yearFirst = stream_year_first_cropcal, &
- stream_yearLast = stream_year_last_cropcal, &
- stream_yearAlign = model_year_align_cropcal, &
+ stream_yearFirst = stream_year_first_cropcal_swindows, &
+ stream_yearLast = stream_year_last_cropcal_swindows, &
+ stream_yearAlign = model_year_align_cropcal_swindows, &
stream_offset = cropcal_offset, &
stream_taxmode = 'extend', &
stream_dtlimit = 1.0e30_r8, &
@@ -216,6 +276,7 @@ subroutine cropcal_init(bounds)
! Initialize the cdeps data type sdat_cropcal_cultivar_gdds
! NOTE: stream_dtlimit 1.5 didn't work for some reason
if (use_cropcal_rx_cultivar_gdds) then
+ use_cropcal_streams = .true.
call shr_strdata_init_from_inline(sdat_cropcal_cultivar_gdds, &
my_task = iam, &
logunit = iulog, &
@@ -228,9 +289,9 @@ subroutine cropcal_init(bounds)
stream_filenames = (/trim(stream_fldFileName_cultivar_gdds)/), &
stream_fldlistFile = stream_varnames_cultivar_gdds, &
stream_fldListModel = stream_varnames_cultivar_gdds, &
- stream_yearFirst = stream_year_first_cropcal, &
- stream_yearLast = stream_year_last_cropcal, &
- stream_yearAlign = model_year_align_cropcal, &
+ stream_yearFirst = stream_year_first_cropcal_cultivar_gdds,&
+ stream_yearLast = stream_year_last_cropcal_cultivar_gdds, &
+ stream_yearAlign = model_year_align_cropcal_cultivar_gdds, &
stream_offset = cropcal_offset, &
stream_taxmode = 'extend', &
stream_dtlimit = 1.0e30_r8, &
@@ -242,6 +303,109 @@ subroutine cropcal_init(bounds)
end if
end if
+ ! Initialize the cdeps data type sdat_cropcal_gdd20_baseline
+ ! NOTE: Hard-coded to one particular year because it should NOT vary over time. Note that the
+ ! particular year chosen doesn't matter. Users can base their file on whatever baseline they
+ ! want; they just need to put 2000 on the time axis.
+ if (adapt_cropcal_rx_cultivar_gdds) then
+ use_cropcal_streams = .true.
+ call shr_strdata_init_from_inline(sdat_cropcal_gdd20_baseline, &
+ my_task = iam, &
+ logunit = iulog, &
+ compname = 'LND', &
+ model_clock = model_clock, &
+ model_mesh = mesh, &
+ stream_meshfile = trim(stream_meshfile_cropcal), &
+ stream_lev_dimname = 'null', &
+ stream_mapalgo = 'nn', &
+ stream_filenames = (/trim(stream_fldFileName_gdd20_baseline)/), &
+ stream_fldlistFile = stream_varnames_gdd20_baseline, &
+ stream_fldListModel = stream_varnames_gdd20_baseline, &
+ stream_yearFirst = 2000, &
+ stream_yearLast = 2000, &
+ stream_yearAlign = 2000, &
+ stream_offset = cropcal_offset, &
+ stream_taxmode = 'extend', &
+ stream_dtlimit = 1.0e30_r8, &
+ stream_tintalgo = cropcal_tintalgo, &
+ stream_name = 'GDD20 baseline data', &
+ 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
+ end if
+
+ if (stream_gdd20_seasons) then
+ use_cropcal_streams = .true.
+
+ ! Initialize the cdeps data type sdat_cropcal_gdd20_season_start
+ ! NOTE: Hard-coded to one particular year because it should NOT vary over time. Note that the
+ ! particular year chosen doesn't matter.
+ call shr_strdata_init_from_inline(sdat_cropcal_gdd20_season_start, &
+ my_task = iam, &
+ logunit = iulog, &
+ compname = 'LND', &
+ model_clock = model_clock, &
+ model_mesh = mesh, &
+ stream_meshfile = trim(stream_meshfile_cropcal), &
+ stream_lev_dimname = 'null', &
+ stream_mapalgo = trim(cropcal_mapalgo), &
+ stream_filenames = (/trim(stream_fldFileName_gdd20_season_start)/), &
+ stream_fldlistFile = stream_varnames_sdate, &
+ stream_fldListModel = stream_varnames_sdate, &
+ stream_yearFirst = 2000, &
+ stream_yearLast = 2000, &
+ stream_yearAlign = 2000, &
+ stream_offset = cropcal_offset, &
+ stream_taxmode = 'extend', &
+ stream_dtlimit = 1.0e30_r8, &
+ stream_tintalgo = cropcal_tintalgo, &
+ stream_name = 'gdd20 season start data', &
+ 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
+
+ ! Initialize the cdeps data type sdat_cropcal_gdd20_season_end
+ ! NOTE: Hard-coded to one particular year because it should NOT vary over time. Note that the
+ ! particular year chosen doesn't matter.
+ call shr_strdata_init_from_inline(sdat_cropcal_gdd20_season_end, &
+ my_task = iam, &
+ logunit = iulog, &
+ compname = 'LND', &
+ model_clock = model_clock, &
+ model_mesh = mesh, &
+ stream_meshfile = trim(stream_meshfile_cropcal), &
+ stream_lev_dimname = 'null', &
+ stream_mapalgo = trim(cropcal_mapalgo), &
+ stream_filenames = (/trim(stream_fldFileName_gdd20_season_end)/), &
+ stream_fldlistFile = stream_varnames_gdd20_season_enddate, &
+ stream_fldListModel = stream_varnames_gdd20_season_enddate, &
+ stream_yearFirst = 2000, &
+ stream_yearLast = 2000, &
+ stream_yearAlign = 2000, &
+ stream_offset = cropcal_offset, &
+ stream_taxmode = 'extend', &
+ stream_dtlimit = 1.0e30_r8, &
+ stream_tintalgo = cropcal_tintalgo, &
+ stream_name = 'gdd20 season start data', &
+ 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
+
+ end if
+
+ if (masterproc) then
+ write(iulog,*)
+ write(iulog,*) 'cropcal_stream DERIVED settings:'
+ write(iulog,'(a,l1)') ' use_cropcal_rx_swindows = ',use_cropcal_rx_swindows
+ write(iulog,'(a,l1)') ' use_cropcal_rx_cultivar_gdds = ',use_cropcal_rx_cultivar_gdds
+ write(iulog,'(a,l1)') ' adapt_cropcal_rx_cultivar_gdds = ',adapt_cropcal_rx_cultivar_gdds
+ write(iulog,'(a,l1)') ' use_cropcal_streams = ',use_cropcal_streams
+ write(iulog,*)
+ endif
+
end subroutine cropcal_init
!================================================================
@@ -258,6 +422,7 @@ subroutine cropcal_advance( bounds )
!
! !LOCAL VARIABLES:
integer :: g, ig ! Indices
+ integer :: begg, endg ! gridcell bounds
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
@@ -266,6 +431,9 @@ subroutine cropcal_advance( bounds )
integer :: rc
!-----------------------------------------------------------------------
+ begg = bounds%begg
+ endg = bounds%endg
+
call get_curr_date(year, mon, day, sec)
mcdate = year*10000 + mon*100 + day
if (use_cropcal_rx_swindows) then
@@ -285,10 +453,31 @@ subroutine cropcal_advance( bounds )
end if
end if
+ ! The following should not have an associated time axis, but still need to be here
+ ! - GDD20 baseline values
+ ! - GDD20 season start dates
+ ! - GDD20 season end dates
+ if (adapt_cropcal_rx_cultivar_gdds) then
+ call shr_strdata_advance(sdat_cropcal_gdd20_baseline, ymd=mcdate, tod=sec, logunit=iulog, istr='cropcaldyn', 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
+ end if
+ if (stream_gdd20_seasons) then
+ call shr_strdata_advance(sdat_cropcal_gdd20_season_start, ymd=mcdate, tod=sec, logunit=iulog, istr='cropcaldyn', 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
+ call shr_strdata_advance(sdat_cropcal_gdd20_season_end, ymd=mcdate, tod=sec, logunit=iulog, istr='cropcaldyn', 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
+ end if
+
if ( .not. allocated(g_to_ig) )then
- allocate (g_to_ig(bounds%begg:bounds%endg) )
+ allocate (g_to_ig(begg:endg) )
ig = 0
- do g = bounds%begg,bounds%endg
+ do g = begg,endg
ig = ig+1
g_to_ig(g) = ig
end do
@@ -298,7 +487,7 @@ end subroutine cropcal_advance
!================================================================
- subroutine cropcal_interp(bounds, num_pcropp, filter_pcropp, crop_inst)
+ subroutine cropcal_interp(bounds, num_pcropp, filter_pcropp, init, crop_inst)
!
! Interpolate data stream information for crop calendars.
!
@@ -314,6 +503,7 @@ subroutine cropcal_interp(bounds, num_pcropp, filter_pcropp, crop_inst)
type(bounds_type) , intent(in) :: bounds
integer , intent(in) :: num_pcropp ! number of prog. crop patches in filter
integer , intent(in) :: filter_pcropp(:) ! filter for prognostic crop patches
+ logical , intent(in) :: init ! is this being called as initialization?
type(crop_type) , intent(inout) :: crop_inst
!
! !LOCAL VARIABLES:
@@ -321,39 +511,48 @@ subroutine cropcal_interp(bounds, num_pcropp, filter_pcropp, crop_inst)
integer :: nc, fp
integer :: dayspyr
integer :: n, g
- integer :: lsize
integer :: rc
+ integer :: begg, endg
integer :: begp, endp
real(r8), pointer :: dataptr1d_swindow_start(:)
real(r8), pointer :: dataptr1d_swindow_end (:)
real(r8), pointer :: dataptr1d_cultivar_gdds(:)
+ real(r8), pointer :: dataptr1d_gdd20_baseline(:)
+ real(r8), pointer :: dataptr1d_gdd20_season_start(:)
+ real(r8), pointer :: dataptr1d_gdd20_season_end (:)
real(r8), pointer :: dataptr2d_swindow_start(:,:)
real(r8), pointer :: dataptr2d_swindow_end (:,:)
real(r8), pointer :: dataptr2d_cultivar_gdds(:,:)
+ real(r8), pointer :: dataptr2d_gdd20_baseline(:,:)
+ real(r8), pointer :: dataptr2d_gdd20_season_start(:,:)
+ real(r8), pointer :: dataptr2d_gdd20_season_end (:,:)
!-----------------------------------------------------------------------
associate( &
- starts => crop_inst%rx_swindow_starts_thisyr_patch, &
- ends => crop_inst%rx_swindow_ends_thisyr_patch &
+ swindow_starts => crop_inst%rx_swindow_starts_thisyr_patch, &
+ swindow_ends => crop_inst%rx_swindow_ends_thisyr_patch, &
+ gdd20_season_starts => crop_inst%gdd20_season_start_patch, &
+ gdd20_season_ends => crop_inst%gdd20_season_end_patch &
)
- SHR_ASSERT_FL( (lbound(g_to_ig,1) <= bounds%begg ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (ubound(g_to_ig,1) >= bounds%endg ), sourcefile, __LINE__)
+ begg = bounds%begg
+ endg = bounds%endg
+ SHR_ASSERT_FL( (lbound(g_to_ig,1) <= begg ), sourcefile, __LINE__)
+ SHR_ASSERT_FL( (ubound(g_to_ig,1) >= endg ), sourcefile, __LINE__)
! Get pointer for stream data that is time and spatially interpolate to model time and grid
! Place all data from each type into a temporary 2d array
- lsize = bounds%endg - bounds%begg + 1
begp = bounds%begp
- endp= bounds%endp
+ endp = bounds%endp
dayspyr = get_curr_days_per_year()
! Read prescribed sowing window start dates from input files
- allocate(dataptr2d_swindow_start(lsize, ncft))
- dataptr2d_swindow_start(:,:) = -1._r8
- allocate(dataptr2d_swindow_end (lsize, ncft))
- dataptr2d_swindow_end(:,:) = -1._r8
+ allocate(dataptr2d_swindow_start(begg:endg, ncft))
+ dataptr2d_swindow_start(begg:endg,:) = -1._r8
+ allocate(dataptr2d_swindow_end (begg:endg, ncft))
+ dataptr2d_swindow_end(begg:endg,:) = -1._r8
if (use_cropcal_rx_swindows) then
! Starting with npcropmin will skip generic crops
do n = 1, ncft
@@ -369,7 +568,7 @@ subroutine cropcal_interp(bounds, num_pcropp, filter_pcropp, crop_inst)
end if
! Note that the size of dataptr1d includes ocean points so it will be around 3x larger than lsize
! So an explicit loop is required here
- do g = 1,lsize
+ do g = begg, endg
! If read-in value is invalid, set to -1. Will be handled later in this subroutine.
if (dataptr1d_swindow_start(g) <= 0 .or. dataptr1d_swindow_start(g) > dayspyr &
@@ -392,8 +591,8 @@ subroutine cropcal_interp(bounds, num_pcropp, filter_pcropp, crop_inst)
n = ivt - npcropmin + 1
! vegetated pft
ig = g_to_ig(patch%gridcell(p))
- starts(p,1) = dataptr2d_swindow_start(ig,n)
- ends(p,1) = dataptr2d_swindow_end (ig,n)
+ swindow_starts(p,1) = dataptr2d_swindow_start(ig,n)
+ swindow_ends(p,1) = dataptr2d_swindow_end (ig,n)
else
write(iulog,'(a,i0)') 'cropcal_interp(), prescribed sowing windows: Crop patch has ivt ',ivt
call ESMF_Finalize(endflag=ESMF_END_ABORT)
@@ -402,23 +601,23 @@ subroutine cropcal_interp(bounds, num_pcropp, filter_pcropp, crop_inst)
! Ensure that, if mxsowings > 1, sowing windows are ordered such that ENDS are monotonically increasing. This is necessary because of how get_swindow() works.
if (mxsowings > 1) then
- if (any(ends(begp:endp,2:mxsowings) <= ends(begp:endp,1:mxsowings-1) .and. &
- ends(begp:endp,2:mxsowings) >= 1)) then
+ if (any(swindow_ends(begp:endp,2:mxsowings) <= swindow_ends(begp:endp,1:mxsowings-1) .and. &
+ swindow_ends(begp:endp,2:mxsowings) >= 1)) then
write(iulog, *) 'Sowing window inputs must be ordered such that end dates are monotonically increasing.'
call ESMF_Finalize(endflag=ESMF_END_ABORT)
end if
end if
! Handle invalid sowing window values
- if (any(starts(begp:endp,:) < 1 .or. ends(begp:endp,:) < 1)) then
+ if (any(swindow_starts(begp:endp,:) < 1 .or. swindow_ends(begp:endp,:) < 1)) then
! Fail if not allowing fallback to paramfile sowing windows
- if ((.not. allow_invalid_swindow_inputs) .and. any(all(starts(begp:endp,:) < 1, dim=2) .and. patch%wtgcell > 0._r8 .and. patch%itype >= npcropmin)) then
+ if ((.not. allow_invalid_swindow_inputs) .and. any(all(swindow_starts(begp:endp,:) < 1, dim=2) .and. patch%wtgcell(begp:endp) > 0._r8 .and. patch%itype(begp:endp) >= npcropmin)) then
write(iulog, *) 'At least one crop in one gridcell has invalid prescribed sowing window start date(s). To ignore and fall back to paramfile sowing windows, set allow_invalid_swindow_inputs to .true.'
write(iulog, *) 'Affected crops:'
do ivt = npcropmin, mxpft
do fp = 1, num_pcropp
p = filter_pcropp(fp)
- if (ivt == patch%itype(p) .and. patch%wtgcell(p) > 0._r8 .and. all(starts(p,:) < 1)) then
+ if (ivt == patch%itype(p) .and. patch%wtgcell(p) > 0._r8 .and. all(swindow_starts(p,:) < 1)) then
write(iulog, *) ' ',pftname(ivt),' (',ivt,')'
exit ! Stop looking for patches of this type
end if
@@ -427,7 +626,7 @@ subroutine cropcal_interp(bounds, num_pcropp, filter_pcropp, crop_inst)
call ESMF_Finalize(endflag=ESMF_END_ABORT)
! Fail if a sowing window start date is prescribed without an end date (or vice versa)
- else if (any((starts(begp:endp,:) >= 1 .and. ends(begp:endp,:) < 1) .or. (starts(begp:endp,:) < 1 .and. ends(begp:endp,:) >= 1))) then
+ else if (any((swindow_starts(begp:endp,:) >= 1 .and. swindow_ends(begp:endp,:) < 1) .or. (swindow_starts(begp:endp,:) < 1 .and. swindow_ends(begp:endp,:) >= 1))) then
write(iulog, *) 'Every prescribed sowing window start date must have a corresponding end date.'
call ESMF_Finalize(endflag=ESMF_END_ABORT)
end if
@@ -437,7 +636,7 @@ subroutine cropcal_interp(bounds, num_pcropp, filter_pcropp, crop_inst)
deallocate(dataptr2d_swindow_start)
deallocate(dataptr2d_swindow_end)
- allocate(dataptr2d_cultivar_gdds(lsize, ncft))
+ allocate(dataptr2d_cultivar_gdds(begg:endg, ncft))
if (use_cropcal_rx_cultivar_gdds) then
! Read prescribed cultivar GDDs from input files
! Starting with npcropmin will skip generic crops
@@ -450,7 +649,7 @@ subroutine cropcal_interp(bounds, num_pcropp, filter_pcropp, crop_inst)
! Note that the size of dataptr1d includes ocean points so it will be around 3x larger than lsize
! So an explicit loop is required here
- do g = 1,lsize
+ do g = begg, endg
! If read-in value is invalid, have PlantCrop() set gddmaturity to PFT-default value.
if (dataptr1d_cultivar_gdds(g) < 0 .or. dataptr1d_cultivar_gdds(g) > 1000000._r8) then
@@ -478,8 +677,8 @@ subroutine cropcal_interp(bounds, num_pcropp, filter_pcropp, crop_inst)
! vegetated pft
ig = g_to_ig(patch%gridcell(p))
- if (ig > lsize) then
- write(iulog,'(a,i0,a,i0,a)') 'ig (',ig,') > lsize (',lsize,')'
+ if (ig < begg .or. ig > endg) then
+ write(iulog,'(a,i0,a,i0,a)') 'ig (',ig,') < begg (',begg,') or > endg (',endg,')'
call ESMF_Finalize(endflag=ESMF_END_ABORT)
end if
@@ -490,11 +689,147 @@ subroutine cropcal_interp(bounds, num_pcropp, filter_pcropp, crop_inst)
call ESMF_Finalize(endflag=ESMF_END_ABORT)
endif
end do
- write(iulog,*) 'cropcal_interp(): Reading cultivar_gdds file DONE'
end if ! use_cropcal_rx_cultivar_gdds
deallocate(dataptr2d_cultivar_gdds)
+ allocate(dataptr2d_gdd20_baseline(begg:endg, ncft))
+ if (adapt_cropcal_rx_cultivar_gdds) then
+ ! Read GDD20 baselines from input files
+ ! Starting with npcropmin will skip generic crops
+ do n = 1, ncft
+ call dshr_fldbun_getFldPtr(sdat_cropcal_gdd20_baseline%pstrm(1)%fldbun_model, trim(stream_varnames_gdd20_baseline(n)), &
+ fldptr1=dataptr1d_gdd20_baseline, 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
+
+ ! Note that the size of dataptr1d includes ocean points so it will be around 3x larger than lsize
+ ! So an explicit loop is required here
+ do g = begg, endg
+ dataptr2d_gdd20_baseline(g,n) = dataptr1d_gdd20_baseline(g)
+ end do
+ end do
+
+ ! Set gdd20_baseline_patch for each gridcell/patch combination
+ do fp = 1, num_pcropp
+ p = filter_pcropp(fp)
+
+ ivt = patch%itype(p)
+ ! Will skip generic crops
+ if (ivt >= npcropmin) then
+ n = ivt - npcropmin + 1
+
+ if (n > ncft) then
+ write(iulog,'(a,i0,a,i0,a)') 'n (',n,') > ncft (',ncft,')'
+ call ESMF_Finalize(endflag=ESMF_END_ABORT)
+ end if
+
+ ! vegetated pft
+ ig = g_to_ig(patch%gridcell(p))
+
+ if (ig < begg .or. ig > endg) then
+ write(iulog,'(a,i0,a,i0,a)') 'ig (',ig,') < begg (',begg,') or > endg (',endg,')'
+ call ESMF_Finalize(endflag=ESMF_END_ABORT)
+ end if
+
+ crop_inst%gdd20_baseline_patch(p) = dataptr2d_gdd20_baseline(ig,n)
+
+ else
+ write(iulog,'(a,i0)') 'cropcal_interp(), rx_gdd20_baseline: Crop patch has ivt ',ivt
+ call ESMF_Finalize(endflag=ESMF_END_ABORT)
+ endif
+ end do
+ end if ! adapt_cropcal_rx_cultivar_gdds
+
+ deallocate(dataptr2d_gdd20_baseline)
+
+
+ ! Read prescribed gdd20 season start dates from input files
+ allocate(dataptr2d_gdd20_season_start(begg:endg, ncft))
+ dataptr2d_gdd20_season_start(begg:endg,:) = -1._r8
+ allocate(dataptr2d_gdd20_season_end (begg:endg, ncft))
+ dataptr2d_gdd20_season_end(begg:endg,:) = -1._r8
+ if (stream_gdd20_seasons) then
+ ! Starting with npcropmin will skip generic crops
+ do n = 1, ncft
+ call dshr_fldbun_getFldPtr(sdat_cropcal_gdd20_season_start%pstrm(1)%fldbun_model, trim(stream_varnames_sdate(n)), &
+ fldptr1=dataptr1d_gdd20_season_start, 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
+ call dshr_fldbun_getFldPtr(sdat_cropcal_gdd20_season_end%pstrm(1)%fldbun_model, trim(stream_varnames_gdd20_season_enddate(n)), &
+ fldptr1=dataptr1d_gdd20_season_end, 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
+ ! Note that the size of dataptr1d includes ocean points so it will be around 3x larger than lsize
+ ! So an explicit loop is required here
+ do g = begg, endg
+
+ ! If read-in value is invalid, set to -1. Will be handled later in this subroutine.
+ if (dataptr1d_gdd20_season_start(g) <= 0 .or. dataptr1d_gdd20_season_start(g) > 366 &
+ .or. dataptr1d_gdd20_season_start(g) /= dataptr1d_gdd20_season_start(g)) then
+ dataptr1d_gdd20_season_start(g) = -1
+ end if
+ if (dataptr1d_gdd20_season_end(g) <= 0 .or. dataptr1d_gdd20_season_end(g) > 366 &
+ .or. dataptr1d_gdd20_season_end(g) /= dataptr1d_gdd20_season_end(g)) then
+ dataptr1d_gdd20_season_end (g) = -1
+ end if
+
+ dataptr2d_gdd20_season_start(g,n) = dataptr1d_gdd20_season_start(g)
+ dataptr2d_gdd20_season_end (g,n) = dataptr1d_gdd20_season_end (g)
+ end do
+ end do
+
+ ! Set gdd20 season for each gridcell/patch combination
+ do fp = 1, num_pcropp
+ p = filter_pcropp(fp)
+ ivt = patch%itype(p)
+ ! Will skip generic crops
+ if (ivt >= npcropmin) then
+ n = ivt - npcropmin + 1
+ ! vegetated pft
+ ig = g_to_ig(patch%gridcell(p))
+
+ gdd20_season_starts(p) = real(dataptr2d_gdd20_season_start(ig,n), r8)
+ gdd20_season_ends(p) = real(dataptr2d_gdd20_season_end (ig,n), r8)
+ else
+ write(iulog,'(a,i0)') 'cropcal_interp(), gdd20 seasons: Crop patch has ivt ',ivt
+ call ESMF_Finalize(endflag=ESMF_END_ABORT)
+ endif
+ end do
+
+ ! Handle invalid gdd20 season values
+ if (any(gdd20_season_starts(begp:endp) < 1._r8 .or. gdd20_season_ends(begp:endp) < 1._r8)) then
+ ! Fail if not allowing fallback to paramfile sowing windows. Only need to check for
+ ! values < 1 because values outside [1, 366] are set to -1 above.
+ if ((.not. allow_invalid_gdd20_season_inputs) .and. any(gdd20_season_starts(begp:endp) < 1._r8 .and. patch%wtgcell(begp:endp) > 0._r8 .and. patch%itype(begp:endp) >= npcropmin)) then
+ write(iulog, *) 'At least one crop in one gridcell has invalid gdd20 season start and/or end date(s). To ignore and fall back to paramfile sowing windows for such crop-gridcells, set allow_invalid_gdd20_season_inputs to .true.'
+ write(iulog, *) 'Affected crops:'
+ do ivt = npcropmin, mxpft
+ do fp = 1, num_pcropp
+ p = filter_pcropp(fp)
+ if (ivt == patch%itype(p) .and. patch%wtgcell(p) > 0._r8 .and. gdd20_season_starts(p) < 1._r8) then
+ write(iulog, *) ' ',pftname(ivt),' (',ivt,')'
+ exit ! Stop looking for patches of this type
+ end if
+ end do
+ end do
+ call ESMF_Finalize(endflag=ESMF_END_ABORT)
+
+ ! Fail if a gdd20 season start date is given without an end date (or vice versa)
+ else if (any((gdd20_season_starts(begp:endp) >= 1._r8 .and. gdd20_season_ends(begp:endp) < 1._r8) .or. (gdd20_season_starts(begp:endp) < 1._r8 .and. gdd20_season_ends(begp:endp) >= 1._r8))) then
+ write(iulog, *) 'Every gdd20 season start date must have a corresponding end date.'
+ call ESMF_Finalize(endflag=ESMF_END_ABORT)
+ end if
+ end if
+
+ end if ! stream_gdd20_seasons
+ deallocate(dataptr2d_gdd20_season_start)
+ deallocate(dataptr2d_gdd20_season_end)
+
+
end associate
end subroutine cropcal_interp
diff --git a/src/drv_test/CMakeLists.txt b/src/drv_test/CMakeLists.txt
new file mode 100644
index 0000000000..938e55a598
--- /dev/null
+++ b/src/drv_test/CMakeLists.txt
@@ -0,0 +1,3 @@
+# This test should be moved to be under CMEPS
+# See: https://github.com/ESCOMP/CMEPS/issues/458
+add_subdirectory(shr_dust_emis_test)
diff --git a/src/drv_test/shr_dust_emis_test/CMakeLists.txt b/src/drv_test/shr_dust_emis_test/CMakeLists.txt
new file mode 100644
index 0000000000..21fb9c8d47
--- /dev/null
+++ b/src/drv_test/shr_dust_emis_test/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_pfunit_ctest(dust_emis
+ TEST_SOURCES "test_shr_dust_emis.pf"
+ LINK_LIBRARIES clm csm_share)
diff --git a/src/drv_test/shr_dust_emis_test/test_shr_dust_emis.pf b/src/drv_test/shr_dust_emis_test/test_shr_dust_emis.pf
new file mode 100644
index 0000000000..c811cab5f5
--- /dev/null
+++ b/src/drv_test/shr_dust_emis_test/test_shr_dust_emis.pf
@@ -0,0 +1,112 @@
+module test_shr_dust_emis
+
+ ! Tests of shr_dust_emis_mod.F90 from CMEPS nuopc_cap_share
+
+ use funit
+ use shr_dust_emis_mod
+ use unittestUtils , only : endrun_msg
+
+ implicit none
+
+ @TestCase
+ type, extends(TestCase) :: TestDustEmis
+ contains
+ procedure :: setUp
+ procedure :: tearDown
+ end type TestDustEmis
+
+contains
+
+ ! ========================================================================
+ ! Helper routines
+ ! ========================================================================
+
+ subroutine setUp(this)
+ class(TestDustEmis), intent(inout) :: this
+ end subroutine setUp
+
+ subroutine tearDown(this)
+ class(TestDustEmis), intent(inout) :: this
+
+ end subroutine tearDown
+
+
+
+ ! ========================================================================
+ ! Begin tests
+ ! ========================================================================
+
+ @Test
+ subroutine check_if_initialized_aborts(this)
+ ! Test that the check_if_initialized check aborts when called initially
+ class(TestDustEmis), intent(inout) :: this
+ logical :: not_init
+
+ not_init = is_NOT_initialized()
+ @assertExceptionRaised(endrun_msg('ERROR: dust emission namelist has NOT been read in yet, shr_dust_emis_mod is NOT initialized') )
+ @assertTrue(not_init)
+
+ end subroutine check_if_initialized_aborts
+
+ @Test
+ subroutine check_when_initialized_runs(this)
+ ! Test that the initializiation check runs when it is initialized
+ class(TestDustEmis), intent(inout) :: this
+ logical :: not_init
+
+ call dust_emis_set_options( 'Zender_2003', 'lnd')
+ not_init = is_NOT_initialized()
+ @assertFalse(not_init)
+
+ end subroutine check_when_initialized_runs
+
+ @Test
+ subroutine check_dust_emis(this)
+ ! Test that the dust_emis logical functions work as expected
+ class(TestDustEmis), intent(inout) :: this
+ logical :: not_init
+
+ call dust_emis_set_options( 'Zender_2003', 'lnd')
+ @assertTrue( is_dust_emis_zender() )
+ @assertFalse( is_dust_emis_leung() )
+ call dust_emis_set_options( 'Leung_2023', 'none')
+ @assertFalse( is_dust_emis_zender() )
+ @assertTrue( is_dust_emis_leung() )
+
+ end subroutine check_dust_emis
+
+ @Test
+ subroutine check_zender_soil(this)
+ ! Test that the dust_emis_Zender logical functions work as expected
+ class(TestDustEmis), intent(inout) :: this
+ logical :: not_init
+
+ call dust_emis_set_options( 'Zender_2003', 'lnd')
+ @assertTrue( is_zender_soil_erod_from_land() )
+ @assertFalse( is_zender_soil_erod_from_atm() )
+ call dust_emis_set_options( 'Zender_2003', 'atm')
+ @assertFalse( is_zender_soil_erod_from_land() )
+ @assertTrue( is_zender_soil_erod_from_atm() )
+
+ end subroutine check_zender_soil
+
+ @Test
+ subroutine check_options(this)
+ ! Test that the check_options subroutine catches errors that should die
+ class(TestDustEmis), intent(inout) :: this
+ logical :: not_init
+
+ call dust_emis_set_options( 'zztop', 'zztop')
+ @assertExceptionRaised(endrun_msg('(check_options_finish_init) ERROR: dust_emis_method namelist item is not valid'))
+ call dust_emis_set_options( 'Leung_2023', 'lnd')
+ @assertExceptionRaised(endrun_msg('(check_options_finish_init) ERROR: zender_soil_erod_source should NOT be set, when dust_emis_method=Leung_2023'))
+ call dust_emis_set_options( 'Leung_2023', 'atm')
+ @assertExceptionRaised(endrun_msg('(check_options_finish_init) ERROR: zender_soil_erod_source should NOT be set, when dust_emis_method=Leung_2023'))
+ call dust_emis_set_options( 'Zender_2003', 'none')
+ @assertExceptionRaised(endrun_msg('(check_options_finish_init) ERROR: zender_soil_erod_source can only be lnd or atm'))
+ call dust_emis_set_options( 'Zender_2003', 'zztop')
+ @assertExceptionRaised(endrun_msg('(check_options_finish_init) ERROR: zender_soil_erod_source can only be lnd or atm'))
+
+ end subroutine check_options
+
+end module test_shr_dust_emis
diff --git a/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 b/src/dyn_subgrid/dynFATESLandUseChangeMod.F90
index 45f4340d6a..1bc6ab929e 100644
--- a/src/dyn_subgrid/dynFATESLandUseChangeMod.F90
+++ b/src/dyn_subgrid/dynFATESLandUseChangeMod.F90
@@ -26,13 +26,40 @@ module dynFATESLandUseChangeMod
! Landuse state at beginning of year (fraction of gridcell), landuse state name x gridcell
real(r8), allocatable, public :: landuse_states(:,:)
+ ! TODO SSR: Ask Charlie for description to go here
+ real(r8), allocatable, public :: landuse_harvest(:,:)
+
! Number of landuse transition and state names
integer, public, parameter :: num_landuse_transition_vars = 108
integer, public, parameter :: num_landuse_state_vars = 12
+ integer, public, parameter :: num_landuse_harvest_vars = 5
+
+ ! Define the fates landuse namelist mode switch values
+ character(len=18), public, parameter :: fates_harvest_no_logging = 'no_harvest'
+ character(len=18), public, parameter :: fates_harvest_logging_only = 'event_code'
+ character(len=18), public, parameter :: fates_harvest_clmlanduse = 'landuse_timeseries'
+ character(len=18), public, parameter :: fates_harvest_luh_area = 'luhdata_area'
+ character(len=18), public, parameter :: fates_harvest_luh_mass = 'luhdata_mass'
+
+ ! Define landuse harvest unit integer representation
+ integer, public, parameter :: landuse_harvest_area_units = 1
+ integer, public, parameter :: landuse_harvest_mass_units = 2
+ integer, public :: landuse_harvest_units
! landuse filename
type(dyn_file_type), target :: dynFatesLandUse_file
+ ! LUH2 raw wood harvest area fraction
+ ! LUH2 data set variable names can be found at https://luh.umd.edu/LUH2/LUH2_v2h_README.pdf
+ character(len=10), target :: landuse_harvest_area_varnames(num_landuse_harvest_vars) = &
+ [character(len=10) :: 'primf_harv', 'primn_harv', 'secmf_harv', 'secyf_harv', 'secnf_harv']
+
+ ! LUH2 raw wood harvest biomass carbon
+ character(len=10), target :: landuse_harvest_mass_varnames(num_landuse_harvest_vars) = &
+ [character(len=10) :: 'primf_bioh', 'primn_bioh', 'secmf_bioh', 'secyf_bioh', 'secnf_bioh']
+
+ character(len=10), public, pointer :: landuse_harvest_varnames(:) => null()
+
! Land use name arrays
character(len=5), public, parameter :: landuse_state_varnames(num_landuse_state_vars) = &
[character(len=5) :: 'primf','primn','secdf','secdn','pastr','range', &
@@ -64,8 +91,9 @@ module dynFATESLandUseChangeMod
'c3nfx_to_c3ann','c3nfx_to_c4ann','c3nfx_to_c3per','c3nfx_to_c4per', &
'c3nfx_to_secdf','c3nfx_to_secdn','c3nfx_to_pastr','c3nfx_to_range','c3nfx_to_urban']
- type(dyn_var_time_uninterp_type) :: landuse_transition_vars(num_landuse_transition_vars) ! value of each landuse variable
- type(dyn_var_time_uninterp_type) :: landuse_state_vars(num_landuse_state_vars) ! value of each landuse variable
+ type(dyn_var_time_uninterp_type) :: landuse_transition_vars(num_landuse_transition_vars) ! value of each transitions variable
+ type(dyn_var_time_uninterp_type) :: landuse_state_vars(num_landuse_state_vars) ! value of each state variable
+ type(dyn_var_time_uninterp_type) :: landuse_harvest_vars(num_landuse_harvest_vars) ! value of each harvest variable
public :: dynFatesLandUseInit
public :: dynFatesLandUseInterp
@@ -79,14 +107,15 @@ subroutine dynFatesLandUseInit(bounds, landuse_filename)
! Initialize data structures for land use information.
! !USES:
- use clm_varctl , only : use_cn, use_fates_luh
+ use clm_varctl , only : use_cn, use_fates_luh, fates_harvest_mode
+ use clm_varctl , only : use_fates_potentialveg
use dynVarTimeUninterpMod , only : dyn_var_time_uninterp_type
use dynTimeInfoMod , only : YEAR_POSITION_START_OF_TIMESTEP
use dynTimeInfoMod , only : YEAR_POSITION_END_OF_TIMESTEP
! !ARGUMENTS:
type(bounds_type), intent(in) :: bounds ! proc-level bounds
- character(len=*) , intent(in) :: landuse_filename ! name of file containing land use information
+ character(len=*) , intent(in) :: landuse_filename ! name of file containing landuse timeseries information (fates luh2)
! !LOCAL VARIABLES
integer :: varnum, i ! counter for harvest variables
@@ -111,37 +140,69 @@ subroutine dynFatesLandUseInit(bounds, landuse_filename)
if (ier /= 0) then
call endrun(msg=' allocation error for landuse_transitions'//errMsg(__FILE__, __LINE__))
end if
+ allocate(landuse_harvest(num_landuse_harvest_vars,bounds%begg:bounds%endg),stat=ier)
+ if (ier /= 0) then
+ call endrun(msg=' allocation error for landuse_harvest'//errMsg(__FILE__, __LINE__))
+ end if
+ ! Initialize the states, transitions and harvest mapping percentages as zero by default
landuse_states = 0._r8
landuse_transitions = 0._r8
-
- if (use_fates_luh) then
-
- ! Generate the dyn_file_type object. Note that the land use data being read in is for the
- ! transitions occuring within the current year
- dynFatesLandUse_file = dyn_file_type(landuse_filename, YEAR_POSITION_END_OF_TIMESTEP)
-
- ! Get initial land use data
- num_points = (bounds%endg - bounds%begg + 1)
- landuse_shape(1) = num_points ! Does this need an explicit array shape to be passed to the constructor?
- do varnum = 1, num_landuse_transition_vars
- landuse_transition_vars(varnum) = dyn_var_time_uninterp_type( &
- dyn_file=dynFatesLandUse_file, varname=landuse_transition_varnames(varnum), &
- dim1name=grlnd, conversion_factor=1.0_r8, &
- do_check_sums_equal_1=.false., data_shape=landuse_shape)
- end do
- do varnum = 1, num_landuse_state_vars
- landuse_state_vars(varnum) = dyn_var_time_uninterp_type( &
- dyn_file=dynFatesLandUse_file, varname=landuse_state_varnames(varnum), &
- dim1name=grlnd, conversion_factor=1.0_r8, &
- do_check_sums_equal_1=.false., data_shape=landuse_shape)
- end do
+ landuse_harvest = 0._r8
+
+ ! Avoid initializing the landuse timeseries file if in fates potential vegetation mode
+ if (.not. use_fates_potentialveg) then
+ if (use_fates_luh) then
+
+ ! Generate the dyn_file_type object.
+ ! Start calls get_prev_date, whereas end calls get_curr_date
+ dynFatesLandUse_file = dyn_file_type(landuse_filename, YEAR_POSITION_END_OF_TIMESTEP)
+
+ ! Get initial land use data from the fates luh2 timeseries dataset
+ num_points = (bounds%endg - bounds%begg + 1)
+ landuse_shape(1) = num_points ! Does this need an explicit array shape to be passed to the constructor?
+ do varnum = 1, num_landuse_transition_vars
+ landuse_transition_vars(varnum) = dyn_var_time_uninterp_type( &
+ dyn_file=dynFatesLandUse_file, varname=landuse_transition_varnames(varnum), &
+ dim1name=grlnd, conversion_factor=1.0_r8, &
+ do_check_sums_equal_1=.false., data_shape=landuse_shape)
+ end do
+ do varnum = 1, num_landuse_state_vars
+ landuse_state_vars(varnum) = dyn_var_time_uninterp_type( &
+ dyn_file=dynFatesLandUse_file, varname=landuse_state_varnames(varnum), &
+ dim1name=grlnd, conversion_factor=1.0_r8, &
+ do_check_sums_equal_1=.false., data_shape=landuse_shape)
+ end do
+
+ ! Get the harvest rate data from the fates luh2 timeseries dataset if enabled
+ if (trim(fates_harvest_mode) .eq. fates_harvest_luh_area .or. &
+ trim(fates_harvest_mode) .eq. fates_harvest_luh_mass) then
+
+ ! change the harvest varnames being used depending on the mode selected
+ if (trim(fates_harvest_mode) .eq. fates_harvest_luh_area ) then
+ landuse_harvest_varnames => landuse_harvest_area_varnames
+ landuse_harvest_units = landuse_harvest_area_units
+ elseif (trim(fates_harvest_mode) .eq. fates_harvest_luh_mass ) then
+ landuse_harvest_varnames => landuse_harvest_mass_varnames
+ landuse_harvest_units = landuse_harvest_mass_units
+ else
+ call endrun(msg=' undefined fates harvest mode selected'//errMsg(__FILE__, __LINE__))
+ end if
+
+ do varnum = 1, num_landuse_harvest_vars
+ landuse_harvest_vars(varnum) = dyn_var_time_uninterp_type( &
+ dyn_file=dynFatesLandUse_file, varname=landuse_harvest_varnames(varnum), &
+ dim1name=grlnd, conversion_factor=1.0_r8, &
+ do_check_sums_equal_1=.false., data_shape=landuse_shape)
+ end do
+ end if
+ end if
+
+ ! Since fates needs state data during initialization, make sure to call
+ ! the interpolation routine at the start
+ call dynFatesLandUseInterp(bounds,init_state=.true.)
end if
- ! Since fates needs state data during initialization, make sure to call
- ! the interpolation routine at the start
- call dynFatesLandUseInterp(bounds,init_state=.true.)
-
end subroutine dynFatesLandUseInit
@@ -159,7 +220,7 @@ subroutine dynFatesLandUseInterp(bounds, init_state)
! !USES:
use dynTimeInfoMod , only : time_info_type
- use clm_varctl , only : use_cn
+ use clm_varctl , only : use_cn, fates_harvest_mode
! !ARGUMENTS:
type(bounds_type), intent(in) :: bounds ! proc-level bounds
@@ -181,13 +242,14 @@ subroutine dynFatesLandUseInterp(bounds, init_state)
init_flag = init_state
end if
- ! Get the current year
+ ! Get the data for the current year
call dynFatesLandUse_file%time_info%set_current_year()
if (dynFatesLandUse_file%time_info%is_before_time_series() .and. .not.(init_flag)) then
! Reset the land use transitions to zero for safety
landuse_transitions(1:num_landuse_transition_vars,bounds%begg:bounds%endg) = 0._r8
landuse_states(1:num_landuse_state_vars,bounds%begg:bounds%endg) = 0._r8
+ landuse_harvest(1:num_landuse_harvest_vars,bounds%begg:bounds%endg) = 0._r8
else
! Loop through all variables on the data file and put data into the temporary array
! then update the global state and transitions array.
@@ -200,6 +262,13 @@ subroutine dynFatesLandUseInterp(bounds, init_state)
call landuse_state_vars(varnum)%get_current_data(this_data)
landuse_states(varnum,bounds%begg:bounds%endg) = this_data(bounds%begg:bounds%endg)
end do
+ if (trim(fates_harvest_mode) .eq. fates_harvest_luh_area .or. &
+ trim(fates_harvest_mode) .eq. fates_harvest_luh_mass) then
+ do varnum = 1, num_landuse_harvest_vars
+ call landuse_harvest_vars(varnum)%get_current_data(this_data)
+ landuse_harvest(varnum,bounds%begg:bounds%endg) = this_data(bounds%begg:bounds%endg)
+ end do
+ end if
deallocate(this_data)
end if
diff --git a/src/dyn_subgrid/dynGrossUnrepMod.F90 b/src/dyn_subgrid/dynGrossUnrepMod.F90
index 8d0e7ee004..7ad860f0ce 100644
--- a/src/dyn_subgrid/dynGrossUnrepMod.F90
+++ b/src/dyn_subgrid/dynGrossUnrepMod.F90
@@ -24,6 +24,7 @@ module dynGrossUnrepMod
use clm_varpar , only : natpft_size, i_litr_min, i_litr_max, i_met_lit
use ColumnType , only : col
use PatchType , only : patch
+ use CNSharedParamsMod , only : use_matrixcn
!
! !PUBLIC MEMBER FUNCTIONS:
implicit none
@@ -157,6 +158,7 @@ subroutine CNGrossUnrep (num_soilp, filter_soilp, &
use pftconMod , only : noveg, nbrdlf_evr_shrub, nc4_grass
use clm_varcon , only : secspday
use clm_time_manager, only : get_step_size_real, is_beg_curr_year
+ use CNVegMatrixMod , only : matrix_update_gmc, matrix_update_gmn
!
! !ARGUMENTS:
integer , intent(in) :: num_soilp ! number of soil patches in filter
@@ -266,7 +268,44 @@ subroutine CNGrossUnrep (num_soilp, filter_soilp, &
gru_livestemn_xfer_to_atm => cnveg_nitrogenflux_inst%gru_livestemn_xfer_to_atm_patch , & ! Output: [real(r8) (:)]
gru_deadstemn_xfer_to_atm => cnveg_nitrogenflux_inst%gru_deadstemn_xfer_to_atm_patch , & ! Output: [real(r8) (:)]
gru_livecrootn_xfer_to_atm => cnveg_nitrogenflux_inst%gru_livecrootn_xfer_to_atm_patch , & ! Output: [real(r8) (:)]
- gru_deadcrootn_xfer_to_atm => cnveg_nitrogenflux_inst%gru_deadcrootn_xfer_to_atm_patch & ! Output: [real(r8) (:)]
+ gru_deadcrootn_xfer_to_atm => cnveg_nitrogenflux_inst%gru_deadcrootn_xfer_to_atm_patch , & ! Output: [real(r8) (:)]
+ ileaf_to_iout_gmc => cnveg_carbonflux_inst%ileaf_to_iout_gm , &
+ ileafst_to_iout_gmc => cnveg_carbonflux_inst%ileafst_to_iout_gm , &
+ ileafxf_to_iout_gmc => cnveg_carbonflux_inst%ileafxf_to_iout_gm , &
+ ifroot_to_iout_gmc => cnveg_carbonflux_inst%ifroot_to_iout_gm , &
+ ifrootst_to_iout_gmc => cnveg_carbonflux_inst%ifrootst_to_iout_gm , &
+ ifrootxf_to_iout_gmc => cnveg_carbonflux_inst%ifrootxf_to_iout_gm , &
+ ilivestem_to_iout_gmc => cnveg_carbonflux_inst%ilivestem_to_iout_gm , &
+ ilivestemst_to_iout_gmc => cnveg_carbonflux_inst%ilivestemst_to_iout_gm , &
+ ilivestemxf_to_iout_gmc => cnveg_carbonflux_inst%ilivestemxf_to_iout_gm , &
+ ideadstem_to_iout_gmc => cnveg_carbonflux_inst%ideadstem_to_iout_gm , &
+ ideadstemst_to_iout_gmc => cnveg_carbonflux_inst%ideadstemst_to_iout_gm , &
+ ideadstemxf_to_iout_gmc => cnveg_carbonflux_inst%ideadstemxf_to_iout_gm , &
+ ilivecroot_to_iout_gmc => cnveg_carbonflux_inst%ilivecroot_to_iout_gm , &
+ ilivecrootst_to_iout_gmc => cnveg_carbonflux_inst%ilivecrootst_to_iout_gm , &
+ ilivecrootxf_to_iout_gmc => cnveg_carbonflux_inst%ilivecrootxf_to_iout_gm , &
+ ideadcroot_to_iout_gmc => cnveg_carbonflux_inst%ideadcroot_to_iout_gm , &
+ ideadcrootst_to_iout_gmc => cnveg_carbonflux_inst%ideadcrootst_to_iout_gm , &
+ ideadcrootxf_to_iout_gmc => cnveg_carbonflux_inst%ideadcrootxf_to_iout_gm , &
+ ileaf_to_iout_gmn => cnveg_nitrogenflux_inst%ileaf_to_iout_gm , &
+ ileafst_to_iout_gmn => cnveg_nitrogenflux_inst%ileafst_to_iout_gm , &
+ ileafxf_to_iout_gmn => cnveg_nitrogenflux_inst%ileafxf_to_iout_gm , &
+ ifroot_to_iout_gmn => cnveg_nitrogenflux_inst%ifroot_to_iout_gm , &
+ ifrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ifrootst_to_iout_gm , &
+ ifrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ifrootxf_to_iout_gm , &
+ ilivestem_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestem_to_iout_gm , &
+ ilivestemst_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestemst_to_iout_gm , &
+ ilivestemxf_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestemxf_to_iout_gm , &
+ ideadstem_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstem_to_iout_gm , &
+ ideadstemst_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstemst_to_iout_gm , &
+ ideadstemxf_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstemxf_to_iout_gm , &
+ ilivecroot_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecroot_to_iout_gm , &
+ ilivecrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecrootst_to_iout_gm , &
+ ilivecrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecrootxf_to_iout_gm , &
+ ideadcroot_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcroot_to_iout_gm , &
+ ideadcrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcrootst_to_iout_gm , &
+ ideadcrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcrootxf_to_iout_gm , &
+ iretransn_to_iout_gmn => cnveg_nitrogenflux_inst%iretransn_to_iout_gm &
)
dtime = get_step_size_real()
@@ -294,61 +333,157 @@ subroutine CNGrossUnrep (num_soilp, filter_soilp, &
m = 0._r8
end if
- ! patch-level gross unrepresented landcover change carbon fluxes
- ! displayed pools
- gru_leafc_to_litter(p) = leafc(p) * m
- gru_frootc_to_litter(p) = frootc(p) * m
- gru_livestemc_to_atm(p) = livestemc(p) * m
- gru_deadstemc_to_atm(p) = deadstemc(p) * m * convfrac(ivt(p))
- gru_wood_productc_gain(p) = deadstemc(p) * m * (1._r8 - convfrac(ivt(p)))
- gru_livecrootc_to_litter(p) = livecrootc(p) * m
- gru_deadcrootc_to_litter(p) = deadcrootc(p) * m
- gru_xsmrpool_to_atm(p) = xsmrpool(p) * m
-
- ! storage pools
- gru_leafc_storage_to_atm(p) = leafc_storage(p) * m
- gru_frootc_storage_to_atm(p) = frootc_storage(p) * m
- gru_livestemc_storage_to_atm(p) = livestemc_storage(p) * m
- gru_deadstemc_storage_to_atm(p) = deadstemc_storage(p) * m
- gru_livecrootc_storage_to_atm(p) = livecrootc_storage(p) * m
- gru_deadcrootc_storage_to_atm(p) = deadcrootc_storage(p) * m
- gru_gresp_storage_to_atm(p) = gresp_storage(p) * m
-
- ! transfer pools
- gru_leafc_xfer_to_atm(p) = leafc_xfer(p) * m
- gru_frootc_xfer_to_atm(p) = frootc_xfer(p) * m
- gru_livestemc_xfer_to_atm(p) = livestemc_xfer(p) * m
- gru_deadstemc_xfer_to_atm(p) = deadstemc_xfer(p) * m
- gru_livecrootc_xfer_to_atm(p) = livecrootc_xfer(p) * m
- gru_deadcrootc_xfer_to_atm(p) = deadcrootc_xfer(p) * m
- gru_gresp_xfer_to_atm(p) = gresp_xfer(p) * m
-
- ! patch-level gross unrepresented landcover change mortality nitrogen fluxes
- ! displayed pools
- gru_leafn_to_litter(p) = leafn(p) * m
- gru_frootn_to_litter(p) = frootn(p) * m
- gru_livestemn_to_atm(p) = livestemn(p) * m
- gru_deadstemn_to_atm(p) = deadstemn(p) * m * convfrac(ivt(p))
- gru_wood_productn_gain(p) = deadstemn(p) * m * (1._r8 - convfrac(ivt(p)))
- gru_livecrootn_to_litter(p) = livecrootn(p) * m
- gru_deadcrootn_to_litter(p) = deadcrootn(p) * m
- gru_retransn_to_litter(p) = retransn(p) * m
-
- ! storage pools
- gru_leafn_storage_to_atm(p) = leafn_storage(p) * m
- gru_frootn_storage_to_atm(p) = frootn_storage(p) * m
- gru_livestemn_storage_to_atm(p) = livestemn_storage(p) * m
- gru_deadstemn_storage_to_atm(p) = deadstemn_storage(p) * m
- gru_livecrootn_storage_to_atm(p) = livecrootn_storage(p) * m
- gru_deadcrootn_storage_to_atm(p) = deadcrootn_storage(p) * m
-
- ! transfer pools
- gru_leafn_xfer_to_atm(p) = leafn_xfer(p) * m
- gru_frootn_xfer_to_atm(p) = frootn_xfer(p) * m
- gru_livestemn_xfer_to_atm(p) = livestemn_xfer(p) * m
- gru_deadstemn_xfer_to_atm(p) = deadstemn_xfer(p) * m
- gru_livecrootn_xfer_to_atm(p) = livecrootn_xfer(p) * m
- gru_deadcrootn_xfer_to_atm(p) = deadcrootn_xfer(p) * m
+ if(.not. use_matrixcn)then
+ ! patch-level gross unrepresented landcover change carbon fluxes
+ ! displayed pools
+ gru_leafc_to_litter(p) = leafc(p) * m
+ gru_frootc_to_litter(p) = frootc(p) * m
+ gru_livestemc_to_atm(p) = livestemc(p) * m
+ gru_deadstemc_to_atm(p) = deadstemc(p) * m * convfrac(ivt(p))
+ gru_wood_productc_gain(p) = deadstemc(p) * m * (1._r8 - convfrac(ivt(p)))
+ gru_livecrootc_to_litter(p) = livecrootc(p) * m
+ gru_deadcrootc_to_litter(p) = deadcrootc(p) * m
+ gru_xsmrpool_to_atm(p) = xsmrpool(p) * m
+
+ ! storage pools
+ gru_leafc_storage_to_atm(p) = leafc_storage(p) * m
+ gru_frootc_storage_to_atm(p) = frootc_storage(p) * m
+ gru_livestemc_storage_to_atm(p) = livestemc_storage(p) * m
+ gru_deadstemc_storage_to_atm(p) = deadstemc_storage(p) * m
+ gru_livecrootc_storage_to_atm(p) = livecrootc_storage(p) * m
+ gru_deadcrootc_storage_to_atm(p) = deadcrootc_storage(p) * m
+ gru_gresp_storage_to_atm(p) = gresp_storage(p) * m
+
+ ! transfer pools
+ gru_leafc_xfer_to_atm(p) = leafc_xfer(p) * m
+ gru_frootc_xfer_to_atm(p) = frootc_xfer(p) * m
+ gru_livestemc_xfer_to_atm(p) = livestemc_xfer(p) * m
+ gru_deadstemc_xfer_to_atm(p) = deadstemc_xfer(p) * m
+ gru_livecrootc_xfer_to_atm(p) = livecrootc_xfer(p) * m
+ gru_deadcrootc_xfer_to_atm(p) = deadcrootc_xfer(p) * m
+ gru_gresp_xfer_to_atm(p) = gresp_xfer(p) * m
+
+ ! patch-level gross unrepresented landcover change mortality nitrogen fluxes
+ ! displayed pools
+ gru_leafn_to_litter(p) = leafn(p) * m
+ gru_frootn_to_litter(p) = frootn(p) * m
+ gru_livestemn_to_atm(p) = livestemn(p) * m
+ gru_deadstemn_to_atm(p) = deadstemn(p) * m * convfrac(ivt(p))
+ gru_wood_productn_gain(p) = deadstemn(p) * m * (1._r8 - convfrac(ivt(p)))
+ gru_livecrootn_to_litter(p) = livecrootn(p) * m
+ gru_deadcrootn_to_litter(p) = deadcrootn(p) * m
+ gru_retransn_to_litter(p) = retransn(p) * m
+
+ ! storage pools
+ gru_leafn_storage_to_atm(p) = leafn_storage(p) * m
+ gru_frootn_storage_to_atm(p) = frootn_storage(p) * m
+ gru_livestemn_storage_to_atm(p) = livestemn_storage(p) * m
+ gru_deadstemn_storage_to_atm(p) = deadstemn_storage(p) * m
+ gru_livecrootn_storage_to_atm(p) = livecrootn_storage(p) * m
+ gru_deadcrootn_storage_to_atm(p) = deadcrootn_storage(p) * m
+
+ ! transfer pools
+ gru_leafn_xfer_to_atm(p) = leafn_xfer(p) * m
+ gru_frootn_xfer_to_atm(p) = frootn_xfer(p) * m
+ gru_livestemn_xfer_to_atm(p) = livestemn_xfer(p) * m
+ gru_deadstemn_xfer_to_atm(p) = deadstemn_xfer(p) * m
+ gru_livecrootn_xfer_to_atm(p) = livecrootn_xfer(p) * m
+ gru_deadcrootn_xfer_to_atm(p) = deadcrootn_xfer(p) * m
+ else ! matrixcn solution
+ ! patch-level gross unrepresented landcover change carbon fluxes
+ ! displayed pools
+ gru_leafc_to_litter(p) = matrix_update_gmc(p,ileaf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ leafc(p)
+ gru_frootc_to_litter(p) = matrix_update_gmc(p,ifroot_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ frootc(p)
+ gru_livestemc_to_atm(p) = matrix_update_gmc(p,ilivestem_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livestemc(p)
+ gru_deadstemc_to_atm(p) = matrix_update_gmc(p,ideadstem_to_iout_gmc,m * convfrac(ivt(p)),dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadstemc(p)
+ gru_wood_productc_gain(p) = matrix_update_gmc(p,ideadstem_to_iout_gmc,m * (1._r8 - convfrac(ivt(p))),dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadstemc(p)
+ gru_livecrootc_to_litter(p) = matrix_update_gmc(p,ilivecroot_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livecrootc(p)
+ gru_deadcrootc_to_litter(p) = matrix_update_gmc(p,ideadcroot_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadcrootc(p)
+ gru_xsmrpool_to_atm(p) = xsmrpool(p) * m
+
+ ! storage pools
+ gru_leafc_storage_to_atm(p) = matrix_update_gmc(p,ileafst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ leafc_storage(p)
+ gru_frootc_storage_to_atm(p) = matrix_update_gmc(p,ifrootst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ frootc_storage(p)
+ gru_livestemc_storage_to_atm(p) = matrix_update_gmc(p,ilivestemst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livestemc_storage(p)
+ gru_deadstemc_storage_to_atm(p) = matrix_update_gmc(p,ideadstemst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadstemc_storage(p)
+ gru_livecrootc_storage_to_atm(p) = matrix_update_gmc(p,ilivecrootst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livecrootc_storage(p)
+ gru_deadcrootc_storage_to_atm(p) = matrix_update_gmc(p,ideadcrootst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadcrootc_storage(p)
+ gru_gresp_storage_to_atm(p) = gresp_storage(p) * m
+
+ ! transfer pools
+ gru_leafc_xfer_to_atm(p) = matrix_update_gmc(p,ileafxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ leafc_xfer(p)
+ gru_frootc_xfer_to_atm(p) = matrix_update_gmc(p,ifrootxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ frootc_xfer(p)
+ gru_livestemc_xfer_to_atm(p) = matrix_update_gmc(p,ilivestemxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livestemc_xfer(p)
+ gru_deadstemc_xfer_to_atm(p) = matrix_update_gmc(p,ideadstemxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadstemc_xfer(p)
+ gru_livecrootc_xfer_to_atm(p) = matrix_update_gmc(p,ilivecrootxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livecrootc_xfer(p)
+ gru_deadcrootc_xfer_to_atm(p) = matrix_update_gmc(p,ideadcrootxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadcrootc_xfer(p)
+ gru_gresp_xfer_to_atm(p) = gresp_xfer(p) * m
+
+ ! patch-level gross unrepresented landcover change mortality nitrogen fluxes
+ ! displayed pools
+ gru_leafn_to_litter(p) = matrix_update_gmn(p,ileaf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ leafn(p)
+ gru_frootn_to_litter(p) = matrix_update_gmn(p,ifroot_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ frootn(p)
+ gru_livestemn_to_atm(p) = matrix_update_gmn(p,ilivestem_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ livestemn(p)
+ gru_deadstemn_to_atm(p) = matrix_update_gmn(p,ideadstem_to_iout_gmn,m * convfrac(ivt(p)),dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ deadstemn(p)
+ gru_wood_productn_gain(p) = matrix_update_gmn(p,ideadstem_to_iout_gmn,m * (1._r8 - convfrac(ivt(p))),dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ deadstemn(p)
+ gru_livecrootn_to_litter(p) = matrix_update_gmn(p,ilivecroot_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ livecrootn(p)
+ gru_deadcrootn_to_litter(p) = matrix_update_gmn(p,ideadcroot_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ deadcrootn(p)
+ gru_retransn_to_litter(p) = matrix_update_gmn(p,iretransn_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ retransn(p)
+
+ ! storage pools
+ gru_leafn_storage_to_atm(p) = matrix_update_gmn(p,ileafst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ leafn_storage(p)
+ gru_frootn_storage_to_atm(p) = matrix_update_gmn(p,ifrootst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ frootn_storage(p)
+ gru_livestemn_storage_to_atm(p) = matrix_update_gmn(p,ilivestemst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ livestemn_storage(p)
+ gru_deadstemn_storage_to_atm(p) = matrix_update_gmn(p,ideadstemst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ deadstemn_storage(p)
+ gru_livecrootn_storage_to_atm(p) = matrix_update_gmn(p,ilivecrootst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.)* &
+ livecrootn_storage(p)
+ gru_deadcrootn_storage_to_atm(p) = matrix_update_gmn(p,ideadcrootst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.)* &
+ deadcrootn_storage(p)
+ ! transfer pools
+ gru_leafn_xfer_to_atm(p) = matrix_update_gmn(p,ileafxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ leafn_xfer(p)
+ gru_frootn_xfer_to_atm(p) = matrix_update_gmn(p,ifrootxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ frootn_xfer(p)
+ gru_livestemn_xfer_to_atm(p) = matrix_update_gmn(p,ilivestemxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ livestemn_xfer(p)
+ gru_deadstemn_xfer_to_atm(p) = matrix_update_gmn(p,ideadstemxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ deadstemn_xfer(p)
+ gru_livecrootn_xfer_to_atm(p) = matrix_update_gmn(p,ilivecrootxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ livecrootn_xfer(p)
+ gru_deadcrootn_xfer_to_atm(p) = matrix_update_gmn(p,ideadcrootxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ deadcrootn_xfer(p)
+ end if
end if ! end tree block
diff --git a/src/dyn_subgrid/dynHarvestMod.F90 b/src/dyn_subgrid/dynHarvestMod.F90
index d5a72aa547..fa4f5c33bb 100644
--- a/src/dyn_subgrid/dynHarvestMod.F90
+++ b/src/dyn_subgrid/dynHarvestMod.F90
@@ -23,8 +23,8 @@ module dynHarvestMod
use clm_varcon , only : grlnd
use ColumnType , only : col
use PatchType , only : patch
- use clm_varctl , only : use_fates
use CNSharedParamsMod , only : use_matrixcn
+ use clm_varctl , only : use_fates
!
! !PUBLIC MEMBER FUNCTIONS:
implicit none
@@ -245,6 +245,7 @@ subroutine CNHarvest (num_soilp, filter_soilp, &
use pftconMod , only : noveg, nbrdlf_evr_shrub
use clm_varcon , only : secspday
use clm_time_manager, only : get_step_size_real, is_beg_curr_year
+ use CNVegMatrixMod , only : matrix_update_gmc, matrix_update_gmn
!
! !ARGUMENTS:
integer , intent(in) :: num_soilp ! number of soil patches in filter
@@ -351,7 +352,44 @@ subroutine CNHarvest (num_soilp, filter_soilp, &
hrv_livestemn_xfer_to_litter => cnveg_nitrogenflux_inst%hrv_livestemn_xfer_to_litter_patch , & ! Output: [real(r8) (:)]
hrv_deadstemn_xfer_to_litter => cnveg_nitrogenflux_inst%hrv_deadstemn_xfer_to_litter_patch , & ! Output: [real(r8) (:)]
hrv_livecrootn_xfer_to_litter => cnveg_nitrogenflux_inst%hrv_livecrootn_xfer_to_litter_patch , & ! Output: [real(r8) (:)]
- hrv_deadcrootn_xfer_to_litter => cnveg_nitrogenflux_inst%hrv_deadcrootn_xfer_to_litter_patch & ! Output: [real(r8) (:)]
+ hrv_deadcrootn_xfer_to_litter => cnveg_nitrogenflux_inst%hrv_deadcrootn_xfer_to_litter_patch , & ! Output: [real(r8) (:)]
+ ileaf_to_iout_gmc => cnveg_carbonflux_inst%ileaf_to_iout_gm , &
+ ileafst_to_iout_gmc => cnveg_carbonflux_inst%ileafst_to_iout_gm , &
+ ileafxf_to_iout_gmc => cnveg_carbonflux_inst%ileafxf_to_iout_gm , &
+ ifroot_to_iout_gmc => cnveg_carbonflux_inst%ifroot_to_iout_gm , &
+ ifrootst_to_iout_gmc => cnveg_carbonflux_inst%ifrootst_to_iout_gm , &
+ ifrootxf_to_iout_gmc => cnveg_carbonflux_inst%ifrootxf_to_iout_gm , &
+ ilivestem_to_iout_gmc => cnveg_carbonflux_inst%ilivestem_to_iout_gm , &
+ ilivestemst_to_iout_gmc => cnveg_carbonflux_inst%ilivestemst_to_iout_gm , &
+ ilivestemxf_to_iout_gmc => cnveg_carbonflux_inst%ilivestemxf_to_iout_gm , &
+ ideadstem_to_iout_gmc => cnveg_carbonflux_inst%ideadstem_to_iout_gm , &
+ ideadstemst_to_iout_gmc => cnveg_carbonflux_inst%ideadstemst_to_iout_gm , &
+ ideadstemxf_to_iout_gmc => cnveg_carbonflux_inst%ideadstemxf_to_iout_gm , &
+ ilivecroot_to_iout_gmc => cnveg_carbonflux_inst%ilivecroot_to_iout_gm , &
+ ilivecrootst_to_iout_gmc => cnveg_carbonflux_inst%ilivecrootst_to_iout_gm , &
+ ilivecrootxf_to_iout_gmc => cnveg_carbonflux_inst%ilivecrootxf_to_iout_gm , &
+ ideadcroot_to_iout_gmc => cnveg_carbonflux_inst%ideadcroot_to_iout_gm , &
+ ideadcrootst_to_iout_gmc => cnveg_carbonflux_inst%ideadcrootst_to_iout_gm , &
+ ideadcrootxf_to_iout_gmc => cnveg_carbonflux_inst%ideadcrootxf_to_iout_gm , &
+ ileaf_to_iout_gmn => cnveg_nitrogenflux_inst%ileaf_to_iout_gm , &
+ ileafst_to_iout_gmn => cnveg_nitrogenflux_inst%ileafst_to_iout_gm , &
+ ileafxf_to_iout_gmn => cnveg_nitrogenflux_inst%ileafxf_to_iout_gm , &
+ ifroot_to_iout_gmn => cnveg_nitrogenflux_inst%ifroot_to_iout_gm , &
+ ifrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ifrootst_to_iout_gm , &
+ ifrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ifrootxf_to_iout_gm , &
+ ilivestem_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestem_to_iout_gm , &
+ ilivestemst_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestemst_to_iout_gm , &
+ ilivestemxf_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestemxf_to_iout_gm , &
+ ideadstem_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstem_to_iout_gm , &
+ ideadstemst_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstemst_to_iout_gm , &
+ ideadstemxf_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstemxf_to_iout_gm , &
+ ilivecroot_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecroot_to_iout_gm , &
+ ilivecrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecrootst_to_iout_gm , &
+ ilivecrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecrootxf_to_iout_gm , &
+ ideadcroot_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcroot_to_iout_gm , &
+ ideadcrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcrootst_to_iout_gm , &
+ ideadcrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcrootxf_to_iout_gm , &
+ iretransn_to_iout_gmn => cnveg_nitrogenflux_inst%iretransn_to_iout_gm &
)
dtime = get_step_size_real()
@@ -389,9 +427,9 @@ subroutine CNHarvest (num_soilp, filter_soilp, &
m = 0._r8
end if
- ! patch-level harvest carbon fluxes
- ! displayed pools
if(.not. use_matrixcn)then
+ ! patch-level harvest carbon fluxes
+ ! displayed pools
hrv_leafc_to_litter(p) = leafc(p) * m
hrv_frootc_to_litter(p) = frootc(p) * m
hrv_livestemc_to_litter(p) = livestemc(p) * m
@@ -447,8 +485,96 @@ subroutine CNHarvest (num_soilp, filter_soilp, &
! NOTE: The non-matrix part of this update is in CNCStatUpdate2 CStateUpdate2h (EBK 11/25/2019)
! and for Nitrogen The non-matrix part of this update is in CNNStatUpdate2 NStateUpdate2h (EBK 11/25/2019)
else
+ ! patch-level harvest carbon fluxes
+ ! displayed pools
+ hrv_leafc_to_litter(p) = matrix_update_gmc(p,ileaf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ leafc(p)
+ hrv_frootc_to_litter(p) = matrix_update_gmc(p,ifroot_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ frootc(p)
+ hrv_livestemc_to_litter(p) = matrix_update_gmc(p,ilivestem_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livestemc(p)
+ wood_harvestc(p) = matrix_update_gmc(p,ideadstem_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadstemc(p)
+ hrv_livecrootc_to_litter(p) = matrix_update_gmc(p,ilivecroot_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livecrootc(p)
+ hrv_deadcrootc_to_litter(p) = matrix_update_gmc(p,ideadcroot_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadcrootc(p)
+ hrv_xsmrpool_to_atm(p) = xsmrpool(p) * m
+
+ ! storage pools
+ hrv_leafc_storage_to_litter(p) = matrix_update_gmc(p,ileafst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ leafc_storage(p)
+ hrv_frootc_storage_to_litter(p) = matrix_update_gmc(p,ifrootst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ frootc_storage(p)
+ hrv_livestemc_storage_to_litter(p) = matrix_update_gmc(p,ilivestemst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livestemc_storage(p)
+ hrv_deadstemc_storage_to_litter(p) = matrix_update_gmc(p,ideadstemst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadstemc_storage(p)
+ hrv_livecrootc_storage_to_litter(p) = matrix_update_gmc(p,ilivecrootst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livecrootc_storage(p)
+ hrv_deadcrootc_storage_to_litter(p) = matrix_update_gmc(p,ideadcrootst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadcrootc_storage(p)
+ hrv_gresp_storage_to_litter(p) = gresp_storage(p) * m
+
+ ! transfer pools
+ hrv_leafc_xfer_to_litter(p) = matrix_update_gmc(p,ileafxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ leafc_xfer(p)
+ hrv_frootc_xfer_to_litter(p) = matrix_update_gmc(p,ifrootxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ frootc_xfer(p)
+ hrv_livestemc_xfer_to_litter(p) = matrix_update_gmc(p,ilivestemxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livestemc_xfer(p)
+ hrv_deadstemc_xfer_to_litter(p) = matrix_update_gmc(p,ideadstemxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadstemc_xfer(p)
+ hrv_livecrootc_xfer_to_litter(p) = matrix_update_gmc(p,ilivecrootxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livecrootc_xfer(p)
+ hrv_deadcrootc_xfer_to_litter(p) = matrix_update_gmc(p,ideadcrootxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadcrootc_xfer(p)
+ hrv_gresp_xfer_to_litter(p) = gresp_xfer(p) * m
+
+ ! patch-level harvest mortality nitrogen fluxes
+ ! displayed pools
+ hrv_leafn_to_litter(p) = matrix_update_gmn(p,ileaf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ leafn(p)
+ hrv_frootn_to_litter(p) = matrix_update_gmn(p,ifroot_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ frootn(p)
+ hrv_livestemn_to_litter(p) = matrix_update_gmn(p,ilivestem_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ livestemn(p)
+ wood_harvestn(p) = matrix_update_gmn(p,ideadstem_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ deadstemn(p)
+ hrv_livecrootn_to_litter(p) = matrix_update_gmn(p,ilivecroot_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ livecrootn(p)
+ hrv_deadcrootn_to_litter(p) = matrix_update_gmn(p,ideadcroot_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ deadcrootn(p)
+ hrv_retransn_to_litter(p) = matrix_update_gmn(p,iretransn_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ retransn(p)
+
+ ! storage pools
+ hrv_leafn_storage_to_litter(p) = matrix_update_gmn(p,ileafst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) *&
+ leafn_storage(p)
+ hrv_frootn_storage_to_litter(p) = matrix_update_gmn(p,ifrootst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) *&
+ frootn_storage(p)
+ hrv_livestemn_storage_to_litter(p) = matrix_update_gmn(p,ilivestemst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) *&
+ livestemn_storage(p)
+ hrv_deadstemn_storage_to_litter(p) = matrix_update_gmn(p,ideadstemst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) *&
+ deadstemn_storage(p)
+ hrv_livecrootn_storage_to_litter(p) = matrix_update_gmn(p,ilivecrootst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.)*&
+ livecrootn_storage(p)
+ hrv_deadcrootn_storage_to_litter(p) = matrix_update_gmn(p,ideadcrootst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.)*&
+ deadcrootn_storage(p)
+ ! transfer pools
+ hrv_leafn_xfer_to_litter(p) = matrix_update_gmn(p,ileafxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ leafn_xfer(p)
+ hrv_frootn_xfer_to_litter(p) = matrix_update_gmn(p,ifrootxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ frootn_xfer(p)
+ hrv_livestemn_xfer_to_litter(p) = matrix_update_gmn(p,ilivestemxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ livestemn_xfer(p)
+ hrv_deadstemn_xfer_to_litter(p) = matrix_update_gmn(p,ideadstemxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ deadstemn_xfer(p)
+ hrv_livecrootn_xfer_to_litter(p) = matrix_update_gmn(p,ilivecrootxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ livecrootn_xfer(p)
+ hrv_deadcrootn_xfer_to_litter(p) = matrix_update_gmn(p,ideadcrootxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ deadcrootn_xfer(p)
end if
-
end if ! end tree block
end do ! end of pft loop
diff --git a/src/dyn_subgrid/dynSubgridDriverMod.F90 b/src/dyn_subgrid/dynSubgridDriverMod.F90
index e5ca3f002e..ea1210521d 100644
--- a/src/dyn_subgrid/dynSubgridDriverMod.F90
+++ b/src/dyn_subgrid/dynSubgridDriverMod.F90
@@ -89,6 +89,11 @@ subroutine dynSubgrid_init(bounds_proc, glc_behavior, crop_inst)
! Note that dynpft_init needs to be called from outside any loops over clumps - so
! this routine needs to be called from outside any loops over clumps.
!
+ !
+ ! !USES:
+ use clm_varctl , only : fates_harvest_mode
+ use dynFATESLandUseChangeMod , only : fates_harvest_clmlanduse
+ !
! !ARGUMENTS:
type(bounds_type) , intent(in) :: bounds_proc ! processor-level bounds
type(glc_behavior_type) , intent(in) :: glc_behavior
@@ -123,7 +128,7 @@ subroutine dynSubgrid_init(bounds_proc, glc_behavior, crop_inst)
! flanduse_timeseries file. However, this could theoretically be changed so that the
! harvest data were separated from the pftdyn data, allowing them to differ in the
! years over which they apply.
- if (get_do_harvest()) then
+ if (get_do_harvest() .or. trim(fates_harvest_mode) == fates_harvest_clmlanduse) then
call dynHarvest_init(bounds_proc, harvest_filename=get_flanduse_timeseries())
end if
@@ -201,7 +206,7 @@ subroutine dynSubgrid_driver(bounds_proc,
! OUTSIDE any loops over clumps in the driver.
!
! !USES:
- use clm_varctl , only : use_cn, use_fates, use_fates_luh
+ use clm_varctl , only : use_cn, use_fates, use_fates_luh, use_fates_potentialveg
use dynInitColumnsMod , only : initialize_new_columns
use dynConsBiogeophysMod , only : dyn_hwcontent_init, dyn_hwcontent_final
use dynEDMod , only : dyn_ED
@@ -290,7 +295,7 @@ subroutine dynSubgrid_driver(bounds_proc,
call dynurban_interp(bounds_proc)
end if
- if (use_fates_luh) then
+ if (use_fates_luh .and. .not. use_fates_potentialveg) then
call dynFatesLandUseInterp(bounds_proc)
end if
diff --git a/src/fates b/src/fates
index adfa664806..1982b0032c 160000
--- a/src/fates
+++ b/src/fates
@@ -1 +1 @@
-Subproject commit adfa6648063408d443f5cae671bd37f713d3e3e8
+Subproject commit 1982b0032c3cab6278892eccb85f643114ffb1af
diff --git a/src/main/accumulMod.F90 b/src/main/accumulMod.F90
index e328632501..0c2462c1f8 100644
--- a/src/main/accumulMod.F90
+++ b/src/main/accumulMod.F90
@@ -40,6 +40,8 @@ module accumulMod
public :: print_accum_fields ! Print info about accumulator fields
public :: extract_accum_field ! Extracts the current value of an accumulator field
public :: update_accum_field ! Update the current value of an accumulator field
+ public :: markreset_accum_field ! Mark (value(s) in) an accumulator field as needing to be reset
+ public :: get_accum_reset ! Get reset array of accumulator
public :: clean_accum_fields ! Deallocate space and reset accum fields list
interface extract_accum_field
@@ -76,6 +78,7 @@ module accumulMod
logical, pointer :: active(:)!whether each point (patch, column, etc.) is active
real(r8) :: initval !initial value of accumulated field
real(r8), pointer :: val(:,:) !accumulated field
+ logical , pointer :: reset(:,:) !whether accumulated field needs to be reset
integer :: period !field accumulation period (in model time steps)
logical :: scale_by_thickness ! true/false flag to scale vertically interpolated variable by soil thickness or not
character(len=128) :: old_name !previous name of variable (may be present in restart files)
@@ -85,6 +88,8 @@ module accumulMod
! different reset points for different levels.
integer, pointer :: nsteps(:,:)!number of steps each point has accumulated, since last reset time
+ integer, pointer :: ndays_reset_shifted(:,:)!accumulated number of days that resetting timeavg field has moved it out of sync with model timestep
+
! NOTE(wjs, 2017-12-03) We should convert this to fully object-oriented (with
! inheritance / polymorphism). For now, in the interest of time, I'm going with a
! semi-object-oriented solution of using procedure pointers.
@@ -112,8 +117,6 @@ subroutine update_accum_field_interface(this, level, nstep, field)
end subroutine update_accum_field_interface
end interface
- real(r8), parameter, public :: accumResetVal = -99999._r8 ! used to do an annual reset ( put in for bug 1858)
-
integer, parameter :: ACCTYPE_TIMEAVG = 1
integer, parameter :: ACCTYPE_RUNMEAN = 2
integer, parameter :: ACCTYPE_RUNACCUM = 3
@@ -295,9 +298,15 @@ subroutine init_accum_field (name, units, desc, &
end if
accum(nf)%val(beg1d:end1d,1:numlev) = init_value
+ allocate(accum(nf)%reset(beg1d:end1d,numlev))
+ accum(nf)%reset(beg1d:end1d,1:numlev) = .false.
+
allocate(accum(nf)%nsteps(beg1d:end1d,numlev))
accum(nf)%nsteps(beg1d:end1d,1:numlev) = 0
+ allocate(accum(nf)%ndays_reset_shifted(beg1d:end1d,numlev))
+ accum(nf)%ndays_reset_shifted(beg1d:end1d,1:numlev) = 0
+
end subroutine init_accum_field
!------------------------------------------------------------------------
@@ -464,6 +473,7 @@ subroutine extract_accum_field_timeavg(this, level, nstep, field)
! !LOCAL VARIABLES:
integer :: begi,endi !subgrid beginning,ending indices
integer :: k, kf
+ integer :: effective_nstep ! Timestep accounting for resets
character(len=*), parameter :: subname = 'extract_accum_field_basic'
!-----------------------------------------------------------------------
@@ -472,17 +482,15 @@ subroutine extract_accum_field_timeavg(this, level, nstep, field)
endi = this%end1d
SHR_ASSERT_FL((size(field) == endi-begi+1), sourcefile, __LINE__)
- if (mod(nstep,this%period) == 0) then
- do k = begi, endi
- kf = k - begi + 1
+ do k = begi, endi
+ kf = k - begi + 1
+ effective_nstep = nstep - this%ndays_reset_shifted(k,level)
+ if (mod(effective_nstep,this%period) == 0) then
field(kf) = this%val(k,level)
- end do
- else
- do k = begi, endi
- kf = k - begi + 1
+ else
field(kf) = spval
- end do
- end if
+ end if
+ end do
end subroutine extract_accum_field_timeavg
@@ -572,6 +580,8 @@ subroutine update_accum_field_timeavg(this, level, nstep, field)
! !LOCAL VARIABLES:
integer :: begi,endi !subgrid beginning,ending indices
integer :: k, kf
+ logical :: time_to_reset
+ integer :: effective_nstep ! Timestep accounting for resets
character(len=*), parameter :: subname = 'update_accum_field_timeavg'
!-----------------------------------------------------------------------
@@ -583,14 +593,21 @@ subroutine update_accum_field_timeavg(this, level, nstep, field)
! time average field: reset every accumulation period; normalize at end of
! accumulation period
- if ((mod(nstep,this%period) == 1 .or. this%period == 1) .and. (nstep /= 0))then
- do k = begi,endi
- if (this%active(k)) then
- this%val(k,level) = 0._r8
- this%nsteps(k,level) = 0
+ do k = begi,endi
+ effective_nstep = nstep - this%ndays_reset_shifted(k,level)
+ time_to_reset = (mod(effective_nstep,this%period) == 1 .or. this%period == 1) .and. effective_nstep /= 0
+ if (this%active(k) .and. (time_to_reset .or. this%reset(k,level))) then
+ if (this%reset(k,level) .and. .not. time_to_reset) then
+ this%ndays_reset_shifted(k,level) = this%ndays_reset_shifted(k,level) + this%nsteps(k,level)
end if
- end do
- end if
+ this%val(k,level) = this%initval
+ this%nsteps(k,level) = 0
+ this%reset(k,level) = .false.
+ end if
+ end do
+
+ ! Ignore reset requests that occurred when patch was inactive
+ this%reset(begi:endi,level) = .false.
do k = begi,endi
if (this%active(k)) then
@@ -600,13 +617,12 @@ subroutine update_accum_field_timeavg(this, level, nstep, field)
end if
end do
- if (mod(nstep,this%period) == 0) then
- do k = begi,endi
- if (this%active(k)) then
- this%val(k,level) = this%val(k,level) / this%nsteps(k,level)
- end if
- end do
- end if
+ do k = begi,endi
+ effective_nstep = nstep - this%ndays_reset_shifted(k,level)
+ if (this%active(k) .and. mod(effective_nstep,this%period) == 0) then
+ this%val(k,level) = this%val(k,level) / this%nsteps(k,level)
+ end if
+ end do
end subroutine update_accum_field_timeavg
@@ -636,6 +652,11 @@ subroutine update_accum_field_runmean(this, level, nstep, field)
do k = begi,endi
if (this%active(k)) then
+ if (this%reset(k,level)) then
+ this%nsteps(k,level) = 0
+ this%val(k,level) = this%initval
+ this%reset(k,level) = .false.
+ end if
kf = k - begi + 1
this%nsteps(k,level) = this%nsteps(k,level) + 1
! Cap nsteps at 'period' - partly to avoid overflow, but also because it doesn't
@@ -649,7 +670,10 @@ subroutine update_accum_field_runmean(this, level, nstep, field)
((accper-1)*this%val(k,level) + field(kf)) / accper
end if
end do
-
+
+ ! SSR 2024-06-05: Note that, unlike other accumulator types, runmean preserves reset requests
+ ! that occurred when the patch was inactive.
+
end subroutine update_accum_field_runmean
!-----------------------------------------------------------------------
@@ -680,9 +704,12 @@ subroutine update_accum_field_runaccum(this, level, nstep, field)
do k = begi,endi
if (this%active(k)) then
kf = k - begi + 1
- if (nint(field(kf)) == -99999) then
+ if (this%reset(k,level)) then
+ ! SSR 2024-06-05: Note that, unlike the other accumulator types, runaccum can not
+ ! reset AND update in the same call of its update_accum_field subroutine.
this%val(k,level) = 0._r8
- this%nsteps(k,level) = 0
+ this%nsteps(k,level) = this%initval
+ this%reset(k,level) = .false.
else
this%val(k,level) = &
min(max(this%val(k,level) + field(kf), 0._r8), 99999._r8)
@@ -691,9 +718,85 @@ subroutine update_accum_field_runaccum(this, level, nstep, field)
end if
end do
+ ! Ignore reset requests that occurred when patch was inactive
+ this%reset(begi:endi,level) = .false.
+
end subroutine update_accum_field_runaccum
+ !-----------------------------------------------------------------------
+ subroutine markreset_accum_field(name, kf, level)
+ !
+ ! !DESCRIPTION:
+ ! Mark accumulator values as needing to be reset. Note that resetting happens in
+ ! update_accum_field subroutines.
+ !
+ ! !ARGUMENTS:
+ character(len=*), intent(in) :: name ! field name
+ integer, optional, intent(in) :: kf ! point index to update (in field, not accumulator's val)
+ integer, optional, intent(in) :: level ! level index to update (in accumulator's val; 1 for a 1-d field)
+ !
+ ! !LOCAL VARIABLES:
+ integer :: nf ! field index within the accum(nf) array
+ integer :: begi, endi ! subgrid beginning, ending indices
+ integer :: k ! index in accumulator's beg1d:end1d
+ integer :: numlev ! number of levels in this accumulator
+
+ character(len=*), parameter :: subname = 'markreset_accum_field'
+ !-----------------------------------------------------------------------
+
+ call find_field(field_name=name, caller_name=subname, field_index=nf)
+ begi = accum(nf)%beg1d
+ endi = accum(nf)%end1d
+ numlev = accum(nf)%numlev
+
+ if (present(kf)) then
+ k = kf + begi - 1
+ SHR_ASSERT_FL(k >= begi .and. k <= endi, sourcefile, __LINE__)
+ if (present(level)) then
+ ! Reset one level of a single point
+ accum(nf)%reset(k,level) = .true.
+ else
+ ! Reset all levels of a single point
+ accum(nf)%reset(k,1:numlev) = .true.
+ end if
+ else if (present(level)) then
+ ! Reset one level of all points
+ accum(nf)%reset(begi:endi,level) = .true.
+ else
+ ! Reset all levels of all points
+ accum(nf)%reset(begi:endi,1:numlev) = .true.
+ end if
+
+ end subroutine markreset_accum_field
+
+
+ !-----------------------------------------------------------------------
+ function get_accum_reset(name) result(reset)
+ !
+ ! !DESCRIPTION:
+ ! Get reset array for an accumulator
+ !
+ ! !ARGUMENTS:
+ character(len=*), intent(in) :: name ! field name
+ !
+ ! !RESULT:
+ logical, pointer :: reset(:,:)
+ !
+ ! !LOCAL VARIABLES:
+ integer :: nf ! field index within the accum(nf) array
+
+ character(len=*), parameter :: subname = 'get_reset'
+ !-----------------------------------------------------------------------
+
+ call find_field(field_name=name, caller_name=subname, field_index=nf)
+
+ allocate(reset(size(accum(nf)%reset, dim=1), size(accum(nf)%reset, dim=2)))
+ reset(:,:) = accum(nf)%reset
+
+ end function get_accum_reset
+
+
!------------------------------------------------------------------------
subroutine accumulRest( ncid, flag )
!
@@ -786,9 +889,15 @@ subroutine clean_accum_fields
if (associated(accum(i)%val)) then
deallocate(accum(i)%val)
end if
+ if (associated(accum(i)%reset)) then
+ deallocate(accum(i)%reset)
+ end if
if (associated(accum(i)%nsteps)) then
deallocate(accum(i)%nsteps)
end if
+ if (associated(accum(i)%ndays_reset_shifted)) then
+ deallocate(accum(i)%ndays_reset_shifted)
+ end if
end do
naccflds = 0
diff --git a/src/main/clm_driver.F90 b/src/main/clm_driver.F90
index c1845d0de6..53b1e55f7c 100644
--- a/src/main/clm_driver.F90
+++ b/src/main/clm_driver.F90
@@ -475,7 +475,7 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate, ro
! When crop calendar streams are being used
! NOTE: This call needs to happen outside loops over nclumps (as streams are not threadsafe)
- if (use_cropcal_streams .and. is_beg_curr_year()) then
+ if (use_crop .and. use_cropcal_streams .and. is_beg_curr_year()) then
call cropcal_advance( bounds_proc )
end if
@@ -1073,11 +1073,12 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate, ro
frictionvel_inst, photosyns_inst, drydepvel_inst)
call t_stopf('depvel')
- if (use_cropcal_streams .and. is_beg_curr_year()) then
+ if (use_crop .and. use_cropcal_streams .and. is_beg_curr_year()) then
! ============================================================================
! Update crop calendars
! ============================================================================
- call cropcal_interp(bounds_clump, filter_inactive_and_active(nc)%num_pcropp, filter_inactive_and_active(nc)%pcropp, crop_inst)
+ call cropcal_interp(bounds_clump, filter_inactive_and_active(nc)%num_pcropp, &
+ filter_inactive_and_active(nc)%pcropp, .false., crop_inst)
end if
! ============================================================================
@@ -1372,7 +1373,7 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate, ro
call atm2lnd_inst%UpdateAccVars(bounds_proc)
- call temperature_inst%UpdateAccVars(bounds_proc)
+ call temperature_inst%UpdateAccVars(bounds_proc, crop_inst)
call canopystate_inst%UpdateAccVars(bounds_proc)
diff --git a/src/main/clm_initializeMod.F90 b/src/main/clm_initializeMod.F90
index 9bf0cc59a2..0c0570c577 100644
--- a/src/main/clm_initializeMod.F90
+++ b/src/main/clm_initializeMod.F90
@@ -659,19 +659,21 @@ subroutine initialize2(ni,nj)
end if
! Initialize crop calendars
- call t_startf('init_cropcal')
- call cropcal_init(bounds_proc)
- if (use_cropcal_streams) then
- call cropcal_advance( bounds_proc )
- !$OMP PARALLEL DO PRIVATE (nc, bounds_clump)
- do nc = 1,nclumps
- call get_clump_bounds(nc, bounds_clump)
- call cropcal_interp(bounds_clump, filter_inactive_and_active(nc)%num_pcropp, &
- filter_inactive_and_active(nc)%pcropp, crop_inst)
- end do
- !$OMP END PARALLEL DO
+ if (use_crop) then
+ call t_startf('init_cropcal')
+ call cropcal_init(bounds_proc)
+ if (use_cropcal_streams) then
+ call cropcal_advance( bounds_proc )
+ !$OMP PARALLEL DO PRIVATE (nc, bounds_clump)
+ do nc = 1,nclumps
+ call get_clump_bounds(nc, bounds_clump)
+ call cropcal_interp(bounds_clump, filter_inactive_and_active(nc)%num_pcropp, &
+ filter_inactive_and_active(nc)%pcropp, .true., crop_inst)
+ end do
+ !$OMP END PARALLEL DO
+ end if
+ call t_stopf('init_cropcal')
end if
- call t_stopf('init_cropcal')
! Initialize active history fields.
! This is only done if not a restart run. If a restart run, then this
diff --git a/src/main/clm_instMod.F90 b/src/main/clm_instMod.F90
index b8a9a0ca79..ae83a1b31f 100644
--- a/src/main/clm_instMod.F90
+++ b/src/main/clm_instMod.F90
@@ -203,6 +203,7 @@ subroutine clm_instInit(bounds)
use SoilWaterRetentionCurveFactoryMod , only : create_soil_water_retention_curve
use decompMod , only : get_proc_bounds
use BalanceCheckMod , only : GetBalanceCheckSkipSteps
+ use clm_varctl , only : flandusepftdat
use clm_varctl , only : use_hillslope
use HillslopeHydrologyMod , only : SetHillslopeSoilThickness
use initVerticalMod , only : setSoilLayerClass
@@ -466,7 +467,7 @@ subroutine clm_instInit(bounds)
! Initialize the Functionaly Assembled Terrestrial Ecosystem Simulator (FATES)
!
if (use_fates) then
- call clm_fates%Init(bounds)
+ call clm_fates%Init(bounds, flandusepftdat)
end if
deallocate (h2osno_col)
diff --git a/src/main/clm_varctl.F90 b/src/main/clm_varctl.F90
index 8804ad2c01..cb7e2e3931 100644
--- a/src/main/clm_varctl.F90
+++ b/src/main/clm_varctl.F90
@@ -276,17 +276,25 @@ module clm_varctl
! option to activate OC in snow in SNICAR
logical, public :: do_sno_oc = .false. ! control to include organic carbon (OC) in snow
- !----------------------------------------------------------
- ! DUST emission method
- !----------------------------------------------------------
- character(len=25), public :: dust_emis_method = 'Zender_2003' ! Dust emisison method to use: Zender_2003 or Leung_2023
-
!----------------------------------------------------------
! C isotopes
!----------------------------------------------------------
logical, public :: use_c13 = .false. ! true => use C-13 model
logical, public :: use_c14 = .false. ! true => use C-14 model
+ !----------------------------------------------------------
+ ! CN matrix
+ !----------------------------------------------------------
+ logical, public :: spinup_matrixcn = .false. !.false. ! true => use acc spinup
+ logical, public :: hist_wrt_matrixcn_diag = .false.!.false. ! true => use acc spinup
+ ! SASU
+ integer, public :: nyr_forcing = 10 ! length of forcing years for the spin up. eg. if DATM_CLMNCEP_YR_START=1901;DATM_CLMNCEP_YR_END=1920, then nyr_forcing = 20
+ integer, public :: nyr_SASU = 1 ! length of each semi-analytic solution. eg. nyr_SASU=5, analytic solutions will be calculated every five years.
+ ! nyr_SASU=1: the fastest SASU, but inaccurate; nyr_SASU=nyr_forcing(eg. 20): the lowest SASU but accurate
+ integer, public :: iloop_avg = -999 ! The restart file will be based on the average of all analytic solutions within the iloop_avg^th loop.
+ ! eg. if nyr_forcing = 20, iloop_avg = 8, the restart file in yr 160 will be based on analytic solutions from yr 141 to 160.
+ ! The number of the analytic solutions within one loop depends on ratio between nyr_forcing and nyr_SASU.
+ ! eg. if nyr_forcing = 20, nyr_SASU = 5, number of analytic solutions is 20/5=4
! BUG(wjs, 2018-10-25, ESCOMP/ctsm#67) There is a bug that causes incorrect values for C
! isotopes if running init_interp from a case without C isotopes to a case with C
@@ -321,7 +329,7 @@ module clm_varctl
! > 1 for external data (lightning and/or anthropogenic ignitions)
! see bld/namelist_files/namelist_definition_clm4_5.xml for details
logical, public :: use_fates_tree_damage = .false. ! true => turn on tree damage module
- logical, public :: use_fates_logging = .false. ! true => turn on logging module
+ character(len=256), public :: fates_harvest_mode = '' ! five different harvest modes; see namelist definition
logical, public :: use_fates_planthydro = .false. ! true => turn on fates hydro
logical, public :: use_fates_cohort_age_tracking = .false. ! true => turn on cohort age tracking
logical, public :: use_fates_ed_st3 = .false. ! true => static stand structure
@@ -344,7 +352,10 @@ module clm_varctl
integer, dimension(2), public :: fates_history_dimlevel = (/2,2/)
logical, public :: use_fates_luh = .false. ! true => use FATES landuse data mode
+ logical, public :: use_fates_lupft = .false. ! true => use FATES landuse x pft static mapping mode
+ logical, public :: use_fates_potentialveg = .false. ! true => FATES potential veg only
character(len=256), public :: fluh_timeseries = '' ! filename for fates landuse timeseries data
+ character(len=256), public :: flandusepftdat = '' ! filename for fates landuse x pft data
character(len=256), public :: fates_inventory_ctrl_filename = '' ! filename for inventory control
! FATES SP AND FATES BGC are MUTUTALLY EXCLUSIVE, THEY CAN'T BOTH BE ON
@@ -391,6 +402,8 @@ module clm_varctl
logical, public :: use_cropcal_streams = .false.
logical, public :: use_cropcal_rx_swindows = .false.
logical, public :: use_cropcal_rx_cultivar_gdds = .false.
+ logical, public :: adapt_cropcal_rx_cultivar_gdds = .false.
+ logical, public :: flush_gdd20 = .false.
!----------------------------------------------------------
! biomass heat storage switch
@@ -428,12 +441,6 @@ module clm_varctl
logical, public :: use_hydrstress = .false. ! true => use plant hydraulic stress calculation
- !----------------------------------------------------------
- ! dynamic root switch
- !----------------------------------------------------------
-
- logical, public :: use_dynroot = .false. ! true => use dynamic root module
-
!----------------------------------------------------------
! glacier_mec control variables: default values (may be overwritten by namelist)
!----------------------------------------------------------
diff --git a/src/main/clm_varpar.F90 b/src/main/clm_varpar.F90
index 4ddacc38e4..4456ab16af 100644
--- a/src/main/clm_varpar.F90
+++ b/src/main/clm_varpar.F90
@@ -86,10 +86,53 @@ module clm_varpar
integer, public :: i_oli_mic = -9 ! index of oligotrophic microbial pool; overwritten in SoilBiogeochemDecompCascade*Mod
integer, public :: i_cwd = -9 ! index of cwd pool; overwritten in SoilBiogeochemDecompCascade*Mod
integer, public :: i_cwdl2 = -9 ! index of cwd to l2 transition; overwritten in SoilBiogeochemDecompCascade*Mod
+ integer, public, parameter :: ileaf = 1 ! leaf pool index
+ integer, public, parameter :: ileaf_st = 2 ! leaf storage pool index
+ integer, public, parameter :: ileaf_xf = 3 ! leaf transfer pool index
+ integer, public, parameter :: ifroot = 4 ! fine root pool index
+ integer, public, parameter :: ifroot_st = 5 ! fine root storage pool index
+ integer, public, parameter :: ifroot_xf = 6 ! fine root transfer pool index
+ integer, public, parameter :: ilivestem = 7 ! live stem pool index
+ integer, public, parameter :: ilivestem_st = 8 ! live stem storage pool index
+ integer, public, parameter :: ilivestem_xf = 9 ! live stem transfer pool index
+ integer, public, parameter :: ideadstem = 10 ! dead stem pool index
+ integer, public, parameter :: ideadstem_st = 11 ! dead stem storage pool index
+ integer, public, parameter :: ideadstem_xf = 12 ! dead stem transfer pool index
+ integer, public, parameter :: ilivecroot = 13 ! live coarse root pool index
+ integer, public, parameter :: ilivecroot_st = 14 ! live coarse root storage pool index
+ integer, public, parameter :: ilivecroot_xf = 15 ! live coarse root transfer pool index
+ integer, public, parameter :: ideadcroot = 16 ! dead coarse root pool index
+ integer, public, parameter :: ideadcroot_st = 17 ! dead coarse root storage pool index
+ integer, public, parameter :: ideadcroot_xf = 18 ! dead coarse root transfer pool index
+ integer, public, parameter :: igrain = 19 ! grain pool index
+ integer, public, parameter :: igrain_st = 20 ! grain storage pool index
+ integer, public, parameter :: igrain_xf = 21 ! grain transfer pool index
+
+ integer, public :: ncphtrans !maximum number of vegetation C transfers through phenology
+ integer, public :: ncphouttrans !maximum number of vegetation C transfers out of vegetation through phenology
+ integer, public :: ncgmtrans !maximum number of vegetation C transfers through gap mortality
+ integer, public :: ncgmouttrans !maximum number of vegetation C transfers out of vegetation through gap mortality
+ integer, public :: ncfitrans !maximum number of vegetation C transfers through fire
+ integer, public :: ncfiouttrans !maximum number of vegetation C transfers out of vegetation trhough fire
+ integer, public :: nnphtrans !maximum number of vegetation N transfers through phenology
+ integer, public :: nnphouttrans !maximum number of vegetation N transfers out of vegetation through phenology
+ integer, public :: nngmtrans !maximum number of vegetation N transfers through gap mortality
+ integer, public :: nngmouttrans !maximum number of vegetation N transfers out of vegetation through gap mortality
+ integer, public :: nnfitrans !maximum number of vegetation N transfers through fire
+ integer, public :: nnfiouttrans !maximum number of vegetation N transfers out of vegetation trhough fire
+
+ integer, public :: iretransn ! retranslocation pool index
+
+ integer, public :: ioutc ! external C pool index
+ integer, public :: ioutn ! external N pool index
integer, public :: ndecomp_pools_max
- integer, public :: ndecomp_pools
+ integer, public :: ndecomp_pools ! total number of pools
integer, public :: ndecomp_cascade_transitions
+ integer, public :: ndecomp_cascade_outtransitions
+
+ ! for soil matrix
+ integer, public :: ndecomp_pools_vr ! ndecomp_pools * levels in the vertical
! Indices used in surface file read and set in clm_varpar_init
@@ -285,9 +328,29 @@ subroutine clm_varpar_init(actual_maxsoil_patches, surf_numpft, surf_numcft, act
! CN Matrix settings
if (use_crop)then
nvegcpool = nvegpool_natveg + nvegpool_crop
+ ncphtrans = 18
+ nnphtrans = 37
+ ncphouttrans = 4
+ nnphouttrans = 5
else
nvegcpool = nvegpool_natveg
+ ncphtrans = 17
+ nnphtrans = 34
+ ncphouttrans = 3
+ nnphouttrans = 4
end if
+ ncgmtrans = 18
+ ncgmouttrans = 18
+ ncfitrans = 20
+ ncfiouttrans = 18
+ nngmtrans = 19
+ nngmouttrans = 19
+ nnfitrans = 21
+ nnfiouttrans = 19
+ nvegnpool = nvegcpool + 1
+ iretransn = nvegnpool
+ ioutc = nvegcpool + 1
+ ioutn = nvegnpool + 1
end subroutine clm_varpar_init
diff --git a/src/main/controlMod.F90 b/src/main/controlMod.F90
index 47ce6dce7c..0b4366a0cb 100644
--- a/src/main/controlMod.F90
+++ b/src/main/controlMod.F90
@@ -39,8 +39,9 @@ module controlMod
use UrbanParamsType , only: UrbanReadNML
use HumanIndexMod , only: HumanIndexReadNML
use CNPrecisionControlMod , only: CNPrecisionControlReadNML
- use CNSharedParamsMod , only: use_fun
+ use CNSharedParamsMod , only: use_fun, use_matrixcn
use CIsoAtmTimeseriesMod , only: use_c14_bombspike, atm_c14_filename, use_c13_timeseries, atm_c13_filename
+ use SoilBiogeochemDecompCascadeConType, only : use_soil_matrixcn
use SoilBiogeochemCompetitionMod , only: suplnitro, suplnNon
use SoilBiogeochemLittVertTranspMod , only: som_adv_flux, max_depth_cryoturb
use SoilBiogeochemVerticalProfileMod , only: surfprof_exp
@@ -121,6 +122,7 @@ subroutine control_init(dtime)
use CNNDynamicsMod , only : CNNDynamicsReadNML
use CNPhenologyMod , only : CNPhenologyReadNML
use landunit_varcon , only : max_lunit
+ use CNSoilMatrixMod , only : CNSoilMatrixInit
!
! ARGUMENTS
integer, intent(in) :: dtime ! model time step (seconds)
@@ -185,6 +187,10 @@ subroutine control_init(dtime)
namelist /clm_inparm / &
deepmixing_depthcrit, deepmixing_mixfact, lake_melt_icealb
+ ! CN Matrix solution
+ namelist /clm_inparm / &
+ use_matrixcn, use_soil_matrixcn, hist_wrt_matrixcn_diag, spinup_matrixcn, nyr_forcing, nyr_sasu, iloop_avg
+
! lake_melt_icealb is of dimension numrad
! Glacier_mec info
@@ -207,12 +213,6 @@ subroutine control_init(dtime)
for_testing_no_crop_seed_replenishment, &
z0param_method, use_z0m_snowmelt
- ! NOTE: EBK 02/26/2024: dust_emis_method is here in CTSM temporarily until it's moved to CMEPS
- ! See: https://github.com/ESCOMP/CMEPS/pull/429
- ! Normally this should also need error checking and a broadcast, but since
- ! there is only one hardcoded option right now that is unneeded.
- namelist /clm_inparm/ dust_emis_method
-
! vertical soil mixing variables
namelist /clm_inparm/ &
som_adv_flux, max_depth_cryoturb
@@ -228,7 +228,7 @@ subroutine control_init(dtime)
! FATES Flags
namelist /clm_inparm/ fates_paramfile, use_fates, &
- fates_spitfire_mode, use_fates_logging, &
+ fates_spitfire_mode, fates_harvest_mode, &
use_fates_planthydro, use_fates_ed_st3, &
use_fates_cohort_age_tracking, &
use_fates_ed_prescribed_phys, &
@@ -237,7 +237,10 @@ subroutine control_init(dtime)
use_fates_nocomp, &
use_fates_sp, &
use_fates_luh, &
+ use_fates_lupft, &
+ use_fates_potentialveg, &
fluh_timeseries, &
+ flandusepftdat, &
fates_inventory_ctrl_filename, &
fates_parteh_mode, &
fates_seeddisp_cadence, &
@@ -275,8 +278,6 @@ subroutine control_init(dtime)
namelist /clm_inparm/ use_hydrstress
- namelist /clm_inparm/ use_dynroot
-
namelist /clm_inparm/ &
use_c14_bombspike, atm_c14_filename, use_c13_timeseries, atm_c13_filename
@@ -305,7 +306,7 @@ subroutine control_init(dtime)
use_lch4, use_nitrif_denitrif, use_extralakelayers, &
use_vichydro, use_cn, use_cndv, use_crop, use_fertilizer, &
use_grainproduct, use_snicar_frc, use_vancouver, use_mexicocity, use_noio, &
- use_nguardrail, crop_residue_removal_frac
+ use_nguardrail, crop_residue_removal_frac, flush_gdd20
! SNICAR
namelist /clm_inparm/ &
@@ -327,6 +328,14 @@ subroutine control_init(dtime)
runtyp(nsrContinue + 1) = 'restart'
runtyp(nsrBranch + 1) = 'branch '
+ if(use_fates)then
+ use_matrixcn = .false.
+ use_soil_matrixcn = .false.
+ hist_wrt_matrixcn_diag = .false.
+ spinup_matrixcn = .false.
+ end if
+ nyr_forcing = 10
+
! Set clumps per procoessor
#if (defined _OPENMP)
@@ -601,9 +610,9 @@ subroutine control_init(dtime)
call CNPhenologyReadNML ( NLFilename )
end if
- ! ----------------------------------------------------------------------
- ! Initialize the CN soil matrix namelist items
- ! ----------------------------------------------------------------------
+ ! CN soil matrix
+
+ call CNSoilMatrixInit()
! ----------------------------------------------------------------------
! consistency checks
@@ -616,11 +625,6 @@ subroutine control_init(dtime)
errMsg(sourcefile, __LINE__))
end if
- if ( use_dynroot .and. use_hydrstress ) then
- call endrun(msg=' ERROR:: dynroot and hydrstress can NOT be on at the same time'//&
- errMsg(sourcefile, __LINE__))
- end if
-
! Check on run type
if (nsrest == iundef) then
call endrun(msg=' ERROR:: must set nsrest'//&
@@ -714,6 +718,7 @@ subroutine control_spmd()
call mpi_bcast (use_cndv, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_nguardrail, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_crop, 1, MPI_LOGICAL, 0, mpicom, ier)
+ call mpi_bcast (flush_gdd20, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_fertilizer, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_grainproduct, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (crop_residue_removal_frac, 1, MPI_REAL8, 0, mpicom, ier)
@@ -793,7 +798,7 @@ subroutine control_spmd()
call mpi_bcast (for_testing_allow_interp_non_ciso_to_ciso, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (fates_spitfire_mode, 1, MPI_INTEGER, 0, mpicom, ier)
- call mpi_bcast (use_fates_logging, 1, MPI_LOGICAL, 0, mpicom, ier)
+ call mpi_bcast (fates_harvest_mode, len(fates_harvest_mode) , MPI_CHARACTER, 0, mpicom, ier)
call mpi_bcast (use_fates_planthydro, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_fates_tree_damage, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_fates_cohort_age_tracking, 1, MPI_LOGICAL, 0, mpicom, ier)
@@ -804,10 +809,14 @@ subroutine control_spmd()
call mpi_bcast (use_fates_nocomp, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_fates_sp, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_fates_luh, 1, MPI_LOGICAL, 0, mpicom, ier)
+ call mpi_bcast (use_fates_lupft, 1, MPI_LOGICAL, 0, mpicom, ier)
+ call mpi_bcast (use_fates_potentialveg, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_fates_bgc, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (fates_inventory_ctrl_filename, len(fates_inventory_ctrl_filename), MPI_CHARACTER, 0, mpicom, ier)
call mpi_bcast (fates_paramfile, len(fates_paramfile) , MPI_CHARACTER, 0, mpicom, ier)
call mpi_bcast (fluh_timeseries, len(fluh_timeseries) , MPI_CHARACTER, 0, mpicom, ier)
+ call mpi_bcast (flandusepftdat, len(flandusepftdat) , MPI_CHARACTER, 0, mpicom, ier)
+
call mpi_bcast (fates_parteh_mode, 1, MPI_INTEGER, 0, mpicom, ier)
call mpi_bcast (fates_seeddisp_cadence, 1, MPI_INTEGER, 0, mpicom, ier)
call mpi_bcast (fates_history_dimlevel, 2, MPI_INTEGER, 0, mpicom, ier)
@@ -845,10 +854,15 @@ subroutine control_spmd()
call mpi_bcast (hillslope_fsat_equals_zero, 1, MPI_LOGICAL, 0, mpicom, ier)
+ call mpi_bcast (use_matrixcn, 1, MPI_LOGICAL, 0, mpicom, ier)
+ call mpi_bcast (use_soil_matrixcn, 1, MPI_LOGICAL, 0, mpicom, ier)
+ call mpi_bcast (hist_wrt_matrixcn_diag, 1, MPI_LOGICAL, 0, mpicom, ier)
+ call mpi_bcast (spinup_matrixcn, 1, MPI_LOGICAL, 0, mpicom, ier)
+ call mpi_bcast (nyr_forcing, 1, MPI_INTEGER, 0, mpicom, ier)
+ call mpi_bcast (nyr_sasu, 1, MPI_INTEGER, 0, mpicom, ier)
+ call mpi_bcast (iloop_avg, 1, MPI_INTEGER, 0, mpicom, ier)
call mpi_bcast (use_hydrstress, 1, MPI_LOGICAL, 0, mpicom, ier)
- call mpi_bcast (use_dynroot, 1, MPI_LOGICAL, 0, mpicom, ier)
-
if (use_cn .or. use_fates) then
! vertical soil mixing variables
call mpi_bcast (som_adv_flux, 1, MPI_REAL8, 0, mpicom, ier)
@@ -988,6 +1002,7 @@ subroutine control_print ()
write(iulog,*) ' use_cn = ', use_cn
write(iulog,*) ' use_cndv = ', use_cndv
write(iulog,*) ' use_crop = ', use_crop
+ write(iulog,*) ' flush_gdd20 = ', flush_gdd20
write(iulog,*) ' use_fertilizer = ', use_fertilizer
write(iulog,*) ' use_grainproduct = ', use_grainproduct
write(iulog,*) ' crop_residue_removal_frac = ', crop_residue_removal_frac
@@ -1136,7 +1151,6 @@ subroutine control_print ()
write(iulog,*) ' user-defined soil layer structure = ', soil_layerstruct_userdefined
write(iulog,*) ' user-defined number of soil layers = ', soil_layerstruct_userdefined_nlevsoi
write(iulog,*) ' plant hydraulic stress = ', use_hydrstress
- write(iulog,*) ' dynamic roots = ', use_dynroot
if (nsrest == nsrContinue) then
write(iulog,*) 'restart warning:'
write(iulog,*) ' Namelist not checked for agreement with initial run.'
@@ -1180,7 +1194,7 @@ subroutine control_print ()
write(iulog, *) ' use_fates = ', use_fates
if (use_fates) then
write(iulog, *) ' fates_spitfire_mode = ', fates_spitfire_mode
- write(iulog, *) ' use_fates_logging = ', use_fates_logging
+ write(iulog, *) ' fates_harvest_mode = ', fates_harvest_mode
write(iulog, *) ' fates_paramfile = ', fates_paramfile
write(iulog, *) ' fates_parteh_mode = ', fates_parteh_mode
write(iulog, *) ' use_fates_planthydro = ', use_fates_planthydro
@@ -1193,7 +1207,10 @@ subroutine control_print ()
write(iulog, *) ' use_fates_nocomp = ', use_fates_nocomp
write(iulog, *) ' use_fates_sp = ', use_fates_sp
write(iulog, *) ' use_fates_luh= ', use_fates_luh
+ write(iulog, *) ' use_fates_lupft= ', use_fates_lupft
+ write(iulog, *) ' use_fates_potentialveg = ', use_fates_potentialveg
write(iulog, *) ' fluh_timeseries = ', trim(fluh_timeseries)
+ write(iulog, *) ' flandusepftdat = ', trim(flandusepftdat)
write(iulog, *) ' fates_seeddisp_cadence = ', fates_seeddisp_cadence
write(iulog, *) ' fates_seeddisp_cadence: 0, 1, 2, 3 => off, daily, monthly, or yearly dispersal'
write(iulog, *) ' fates_inventory_ctrl_filename = ', trim(fates_inventory_ctrl_filename)
diff --git a/src/main/pftconMod.F90 b/src/main/pftconMod.F90
index e5379100e0..7988b57e75 100644
--- a/src/main/pftconMod.F90
+++ b/src/main/pftconMod.F90
@@ -280,9 +280,6 @@ module pftconMod
real(r8), allocatable :: FUN_fracfixers(:) ! Fraction of C that can be used for fixation.
- ! pft parameters for dynamic root code
- real(r8), allocatable :: root_dmx(:) !maximum root depth
-
contains
procedure, public :: Init
@@ -494,7 +491,6 @@ subroutine InitAllocate (this)
allocate( this%kn_nonmyc (0:mxpft) )
allocate( this%kr_resorb (0:mxpft) )
allocate( this%perecm (0:mxpft) )
- allocate( this%root_dmx (0:mxpft) )
allocate( this%fun_cn_flex_a (0:mxpft) )
allocate( this%fun_cn_flex_b (0:mxpft) )
allocate( this%fun_cn_flex_c (0:mxpft) )
@@ -520,7 +516,7 @@ subroutine InitRead(this)
use fileutils , only : getfil
use ncdio_pio , only : ncd_io, ncd_pio_closefile, ncd_pio_openfile, file_desc_t
use ncdio_pio , only : ncd_inqdid, ncd_inqdlen
- use clm_varctl , only : paramfile, use_fates, use_flexibleCN, use_dynroot, use_biomass_heat_storage, z0param_method
+ use clm_varctl , only : paramfile, use_fates, use_flexibleCN, use_biomass_heat_storage, z0param_method
use spmdMod , only : masterproc
use CLMFatesParamInterfaceMod, only : FatesReadPFTs
use SoilBiogeochemDecompCascadeConType, only : mimics_decomp, decomp_method
@@ -1105,13 +1101,8 @@ subroutine InitRead(this)
end if
!
- ! Dynamic Root variables for crops
!
- if ( use_crop .and. use_dynroot )then
- call ncd_io('root_dmx', this%root_dmx, 'read', ncid, readvar=readv)
- if ( .not. readv ) call endrun(msg=' ERROR: error in reading in pft data'//errMsg(sourcefile, __LINE__))
- end if
-
+ !
call ncd_io('nstem',this%nstem, 'read', ncid, readvar=readv)
if ( .not. readv ) call endrun(msg=' ERROR: error in reading in pft data'//errMsg(sourcefile, __LINE__))
call ncd_io('taper',this%taper, 'read', ncid, readvar=readv)
@@ -1583,7 +1574,6 @@ subroutine Clean(this)
deallocate( this%kn_nonmyc)
deallocate( this%kr_resorb)
deallocate( this%perecm)
- deallocate( this%root_dmx)
deallocate( this%fun_cn_flex_a)
deallocate( this%fun_cn_flex_b)
deallocate( this%fun_cn_flex_c)
diff --git a/src/main/surfrdUtilsMod.F90 b/src/main/surfrdUtilsMod.F90
index 007770b3c3..b79f97e0b4 100644
--- a/src/main/surfrdUtilsMod.F90
+++ b/src/main/surfrdUtilsMod.F90
@@ -317,8 +317,8 @@ subroutine collapse_to_dominant(weight, lower_bound, upper_bound, begg, endg, n_
! original sum of all the weights
wt_sum(g) = sum(weight(g,:))
- if (present(do_not_collapse) .and. do_not_collapse(g)) then
- cycle
+ if (present(do_not_collapse)) then
+ if (do_not_collapse(g)) cycle
end if
max_indices = 0 ! initialize
diff --git a/src/main/test/accumul_test/test_accumul.pf b/src/main/test/accumul_test/test_accumul.pf
index 15d2e7403e..423a0aea18 100644
--- a/src/main/test/accumul_test/test_accumul.pf
+++ b/src/main/test/accumul_test/test_accumul.pf
@@ -5,7 +5,7 @@ module test_accumul
use funit
use accumulMod
use unittestSubgridMod
- use unittestSimpleSubgridSetupsMod, only : setup_single_veg_patch
+ use unittestSimpleSubgridSetupsMod, only : setup_single_veg_patch, setup_n_veg_patches
use shr_kind_mod , only : r8 => shr_kind_r8
use clm_varcon, only : spval
use PatchType, only : patch
@@ -94,12 +94,12 @@ contains
numlev = nlev, &
subgrid_type = 'pft', &
init_value = l_init_value, &
- type2d = 'irrelevant', & ! type2d just needed for restart
+ type2d = 'patch', & ! Irrelevant for one-patch fields, but some tests have more than one
scale_by_thickness = .false.)
end subroutine init_ml_patch_field
subroutine update_and_extract_sl_patch_field(this, fieldname, values, val_output, &
- pactive, timestep_start)
+ pactive, timestep_start, reset)
! Calls update_accum_field once for each value in 'values', assuming that the values
! come once per timestep. For the first call, all input values are set equal to
! values(1); for the second call, all input values are set equal to values(2); etc.
@@ -122,17 +122,24 @@ contains
! If present, this specifies the starting nstep value. If absent, we start with 1.
integer, optional, intent(in) :: timestep_start
+ ! If present, same size as 'values', indicating whether each should be associated with a reset
+ logical, optional, intent(in) :: reset(:)
+
integer :: n_timesteps
integer :: timestep
integer :: timestep_offset
real(r8), pointer :: vals_input(:)
real(r8), pointer :: vals_output(:)
logical, allocatable :: l_pactive(:) ! local version of pactive
+ logical, allocatable :: l_reset(:) ! local version of reset
n_timesteps = size(values)
if (present(pactive)) then
@assertEqual(n_timesteps, size(pactive))
end if
+ if (present(reset)) then
+ @assertEqual(n_timesteps, size(reset))
+ end if
allocate(l_pactive(n_timesteps))
if (present(pactive)) then
@@ -147,11 +154,21 @@ contains
timestep_offset = 0
end if
+ allocate(l_reset(n_timesteps))
+ if (present(reset)) then
+ l_reset(:) = reset(:)
+ else
+ l_reset(:) = .false.
+ end if
+
allocate(vals_input(bounds%begp:bounds%endp))
allocate(vals_output(bounds%begp:bounds%endp))
do timestep = 1, n_timesteps
vals_input(:) = values(timestep)
patch%active(bounds%begp) = l_pactive(timestep)
+ if (l_reset(timestep)) then
+ call markreset_accum_field(fieldname)
+ end if
call update_accum_field(fieldname, vals_input, timestep+timestep_offset)
end do
call extract_accum_field(fieldname, vals_output, n_timesteps+timestep_offset)
@@ -257,6 +274,54 @@ contains
@assertEqual(expected, val_output, tolerance=tol)
end subroutine timeavg_basic
+ @Test
+ subroutine timeavg_reset1(this)
+ ! Test reset of timeavg field 1 day after period start
+ class(TestAccumul), intent(inout) :: this
+ character(len=*), parameter :: fieldname = 'foo'
+ integer, parameter :: accum_period = 3
+ real(r8), parameter :: values(accum_period+1) = [11._r8, 12._r8, 13._r8, 14._r8]
+ logical, parameter :: reset(accum_period+1) = [.false., .true., .false., .false.]
+ real(r8) :: val_output
+ real(r8) :: expected
+
+ ! Setup
+ call setup_single_veg_patch(pft_type=1)
+ call this%init_sl_patch_field(name=fieldname, accum_type='timeavg', &
+ accum_period = accum_period)
+
+ ! Exercise
+ call this%update_and_extract_sl_patch_field(fieldname, values, val_output, reset=reset)
+
+ ! Verify
+ expected = sum(values(2:4))/accum_period
+ @assertEqual(expected, val_output, tolerance=tol)
+ end subroutine timeavg_reset1
+
+ @Test
+ subroutine timeavg_reset2(this)
+ ! Test reset of timeavg field 2 days after period start
+ class(TestAccumul), intent(inout) :: this
+ character(len=*), parameter :: fieldname = 'foo'
+ integer, parameter :: accum_period = 3
+ real(r8), parameter :: values(accum_period+2) = [11._r8, 12._r8, 13._r8, 14._r8, 15._r8]
+ logical, parameter :: reset(accum_period+2) = [.false., .false., .true., .false., .false.]
+ real(r8) :: val_output
+ real(r8) :: expected
+
+ ! Setup
+ call setup_single_veg_patch(pft_type=1)
+ call this%init_sl_patch_field(name=fieldname, accum_type='timeavg', &
+ accum_period = accum_period)
+
+ ! Exercise
+ call this%update_and_extract_sl_patch_field(fieldname, values, val_output, reset=reset)
+
+ ! Verify
+ expected = sum(values(3:5))/accum_period
+ @assertEqual(expected, val_output, tolerance=tol)
+ end subroutine timeavg_reset2
+
@Test
subroutine timeavg_wrongTime(this)
! Test a timeavg field when it's the wrong time for producing an average
@@ -303,6 +368,32 @@ contains
@assertEqual(expected, val_output, tolerance=tol)
end subroutine timeavg_onlyLatestPeriod
+ @Test
+ subroutine timeavg_onlyLatestPeriod_redundantReset(this)
+ ! Manually requesting a reset when one was going to happen anyway should have no effect.
+ class(TestAccumul), intent(inout) :: this
+ character(len=*), parameter :: fieldname = 'foo'
+ integer, parameter :: accum_period = 3
+ real(r8), parameter :: values(accum_period*2) = &
+ [11._r8, 12._r8, 13._r8, 21._r8, 22._r8, 23._r8]
+ logical, parameter :: reset(accum_period*2) = &
+ [.false., .false., .false., .true., .false., .false.]
+ real(r8) :: val_output
+ real(r8) :: expected
+
+ ! Setup
+ call setup_single_veg_patch(pft_type=1)
+ call this%init_sl_patch_field(name=fieldname, accum_type='timeavg', &
+ accum_period = accum_period)
+
+ ! Exercise
+ call this%update_and_extract_sl_patch_field(fieldname, values, val_output, reset=reset)
+
+ ! Verify
+ expected = sum(values(accum_period+1:2*accum_period))/accum_period
+ @assertEqual(expected, val_output, tolerance=tol)
+ end subroutine timeavg_onlyLatestPeriod_redundantReset
+
@Test
subroutine timeavg_newlyActive(this)
! For timeavg: If a point becomes active in the middle of a period, then it should
@@ -505,6 +596,54 @@ contains
@assertEqual(expected_ts5, val_output, tolerance=tol)
end subroutine runmean_afterPeriod
+ @Test
+ subroutine runmean_afterPeriod_reset(this)
+ ! Test runmean accumulation after accum_period is reached, with a reset
+ class(TestAccumul), intent(inout) :: this
+ character(len=*), parameter :: fieldname = 'foo'
+ integer, parameter :: accum_period = 3
+ real(r8), parameter :: values(5) = [11._r8, 22._r8, 43._r8, 110._r8, 17._r8]
+ logical, parameter :: reset(5) = [.false., .false., .false., .true., .false.]
+ real(r8) :: val_output
+ real(r8) :: expected_ts5
+
+ ! Setup
+ call setup_single_veg_patch(pft_type=1)
+ call this%init_sl_patch_field(name=fieldname, accum_type='runmean', &
+ accum_period = accum_period)
+
+ ! Exercise
+ call this%update_and_extract_sl_patch_field(fieldname, values, val_output, reset=reset)
+
+ ! Verify
+ expected_ts5 = (values(4) + values(5)) / 2._r8
+ @assertEqual(expected_ts5, val_output, tolerance=tol)
+ end subroutine runmean_afterPeriod_reset
+
+ @Test
+ subroutine runmean_afterPeriod_resetWhileInactive(this)
+ ! Test runmean accumulation after accum_period is reached, with a reset while the patch was inactive. Unlike the other accumulator types, runmean should preserve this reset request and apply it when the patch is active again. This may or may not be the ideal behavior; we can change this if some other
+ ! behavior would be better in this situation.
+ class(TestAccumul), intent(inout) :: this
+ character(len=*), parameter :: fieldname = 'foo'
+ integer, parameter :: accum_period = 3
+ real(r8), parameter :: values(5) = [11._r8, 22._r8, 43._r8, 110._r8, 17._r8]
+ logical, parameter :: pactive(5) = [.true., .true., .true., .false., .true.]
+ logical, parameter :: reset(5) = [.false., .false., .false., .true., .false.]
+ real(r8) :: val_output
+
+ ! Setup
+ call setup_single_veg_patch(pft_type=1)
+ call this%init_sl_patch_field(name=fieldname, accum_type='runmean', &
+ accum_period = accum_period)
+
+ ! Exercise
+ call this%update_and_extract_sl_patch_field(fieldname, values, val_output, pactive=pactive, reset=reset)
+
+ ! Verify
+ @assertEqual(values(5), val_output, tolerance=tol)
+ end subroutine runmean_afterPeriod_resetWhileInactive
+
@Test
subroutine runmean_newlyActive(this)
! For runmean: If a point recently became active, its running mean should only
@@ -599,7 +738,8 @@ contains
class(TestAccumul), intent(inout) :: this
character(len=*), parameter :: fieldname = 'foo'
integer, parameter :: accum_period = 3 ! irrelevant for this type
- real(r8), parameter :: values(5) = [11._r8, 12._r8, accumResetVal, 13._r8, 24._r8]
+ real(r8), parameter :: values(5) = [11._r8, 12._r8, -99999._r8, 13._r8, 24._r8]
+ logical , parameter :: reset(5) = [.false., .false., .true., .false., .false.]
real(r8) :: val_output
real(r8) :: expected
@@ -609,7 +749,7 @@ contains
accum_period = accum_period)
! Exercise
- call this%update_and_extract_sl_patch_field(fieldname, values, val_output)
+ call this%update_and_extract_sl_patch_field(fieldname, values, val_output, reset=reset)
! Verify
expected = sum(values(4:5))
@@ -626,7 +766,8 @@ contains
class(TestAccumul), intent(inout) :: this
character(len=*), parameter :: fieldname = 'foo'
integer, parameter :: accum_period = 3 ! irrelevant for this type
- real(r8), parameter :: values(5) = [11._r8, accumResetVal, 12._r8, 13._r8, 24._r8]
+ real(r8), parameter :: values(5) = [11._r8, -99999._r8, 12._r8, 13._r8, 24._r8]
+ logical , parameter :: reset(5) = [.false., .true., .false., .false., .false.]
logical, parameter :: pactive(5) = [.false., .false., .false., .true., .true.]
real(r8) :: val_output
real(r8) :: expected
@@ -649,7 +790,7 @@ contains
! Test runaccum with a point that starts active, becomes inactive, then later becomes
! active again.
!
- ! Should ignore values and accumResetVal in the inactive steps.
+ ! Should ignore values and reset request in the inactive steps.
!
! Also, should continue where it left off - i.e., including the values accumulated
! when it was first active. This may or may not be the ideal behavior; we can change
@@ -657,7 +798,8 @@ contains
class(TestAccumul), intent(inout) :: this
character(len=*), parameter :: fieldname = 'foo'
integer, parameter :: accum_period = 3 ! irrelevant for this type
- real(r8), parameter :: values(5) = [11._r8, accumResetVal, 12._r8, 17._r8, 24._r8]
+ real(r8), parameter :: values(5) = [11._r8, -99999._r8, 12._r8, 17._r8, 24._r8]
+ logical , parameter :: reset(5) = [.false., .true., .false., .false., .false.]
logical, parameter :: pactive(5) = [.true., .false., .false., .true., .true.]
real(r8) :: val_output
real(r8) :: expected
@@ -668,7 +810,7 @@ contains
accum_period = accum_period)
! Exercise
- call this%update_and_extract_sl_patch_field(fieldname, values, val_output, pactive=pactive)
+ call this%update_and_extract_sl_patch_field(fieldname, values, val_output, pactive=pactive, reset=reset)
! Verify
expected = values(1) + values(4) + values(5)
@@ -718,4 +860,150 @@ contains
@assertEqual(expected2, val_output2, tolerance=tol)
end subroutine multipleFields
+ ! ------------------------------------------------------------------------
+ ! Tests of markreset_accum_field()
+ ! ------------------------------------------------------------------------
+
+ @Test
+ subroutine markreset_nopoints_nolevels(this)
+ ! Make sure that NOT calling markreset_accum_field() means no point-levels are marked for reset.
+ !
+ ! Note that type of accumulator and values don't matter.
+
+ class(TestAccumul), intent(inout) :: this
+ character(len=*), parameter :: fieldname = 'foo'
+ integer, parameter :: npatches = 2
+ integer, parameter :: nlevels = 5
+ real(r8), parameter :: pwtcol(npatches) = [0.5, 0.5]
+ integer, parameter :: pft_type(npatches) = [1, 2]
+ integer, parameter :: accum_period = 3
+ integer, parameter :: expected(npatches, nlevels) = transpose(reshape([ &
+ 0, 0, 0, 0, 0, &
+ 0, 0, 0, 0, 0 &
+ ], [nlevels, npatches]))
+ logical :: reset_output(npatches, nlevels)
+ integer :: reset_output_int(npatches, nlevels)
+ integer :: l, p
+
+ ! Setup
+ call setup_n_veg_patches(pwtcol, pft_type)
+ call this%init_ml_patch_field(name=fieldname, accum_type='timeavg', &
+ accum_period = accum_period, nlev=nlevels)
+
+ ! Exercise
+ reset_output = get_accum_reset(fieldname)
+
+ ! Verify
+ reset_output_int = merge(1, 0, reset_output)
+ @assertEqual(expected, reset_output_int)
+ end subroutine markreset_nopoints_nolevels
+
+ @Test
+ subroutine markreset_1point_nolevels(this)
+ ! Make sure that calling markreset_accum_field() with kf but no level works right (marks
+ ! all levels of that patch for reset).
+ ! Note that type of accumulator and values don't matter.
+
+ class(TestAccumul), intent(inout) :: this
+ character(len=*), parameter :: fieldname = 'foo'
+ integer, parameter :: npatches = 2
+ integer, parameter :: nlevels = 5
+ real(r8), parameter :: pwtcol(npatches) = [0.5, 0.5]
+ integer, parameter :: pft_type(npatches) = [1, 2]
+ integer, parameter :: accum_period = 3
+ integer, parameter :: expected(npatches, nlevels) = transpose(reshape([ &
+ 1, 1, 1, 1, 1, &
+ 0, 0, 0, 0, 0 &
+ ], [nlevels, npatches]))
+ logical :: reset_output(npatches, nlevels)
+ integer :: reset_output_int(npatches, nlevels)
+ integer :: l, p
+
+ ! Setup
+ call setup_n_veg_patches(pwtcol, pft_type)
+ call this%init_ml_patch_field(name=fieldname, accum_type='timeavg', &
+ accum_period = accum_period, nlev=nlevels)
+
+ ! Exercise
+ call markreset_accum_field(fieldname, kf=1)
+ reset_output = get_accum_reset(fieldname)
+
+ ! Verify
+ reset_output_int = merge(1, 0, reset_output)
+ @assertEqual(expected, reset_output_int)
+ end subroutine markreset_1point_nolevels
+
+ @Test
+ subroutine markreset_allpoints_1level(this)
+ ! Make sure that calling markreset_accum_field() with level but no kf works right (marks that
+ ! level for reset for all points).
+ !
+ ! Note that type of accumulator and values don't matter.
+
+ class(TestAccumul), intent(inout) :: this
+ character(len=*), parameter :: fieldname = 'foo'
+ integer, parameter :: npatches = 2
+ integer, parameter :: nlevels = 5
+ real(r8), parameter :: pwtcol(npatches) = [0.5, 0.5]
+ integer, parameter :: pft_type(npatches) = [1, 2]
+ integer, parameter :: accum_period = 3
+ integer, parameter :: expected(npatches, nlevels) = transpose(reshape([ &
+ 0, 0, 1, 0, 0, &
+ 0, 0, 1, 0, 0 &
+ ], [nlevels, npatches]))
+ logical :: reset_output(npatches, nlevels)
+ integer :: reset_output_int(npatches, nlevels)
+ integer :: l, p
+
+ ! Setup
+ call setup_n_veg_patches(pwtcol, pft_type)
+ call this%init_ml_patch_field(name=fieldname, accum_type='timeavg', &
+ accum_period = accum_period, nlev=nlevels)
+
+ ! Exercise
+ call markreset_accum_field(fieldname, level=3)
+ reset_output = get_accum_reset(fieldname)
+
+ ! Verify
+ reset_output_int = merge(1, 0, reset_output)
+ @assertEqual(expected, reset_output_int)
+end subroutine markreset_allpoints_1level
+
+@Test
+subroutine markreset_allpoints_alllevels(this)
+ ! Make sure that calling markreset_accum_field() with neither kf nor level works right (marks
+ ! all for reset).
+ !
+ ! Note that type of accumulator and values don't matter.
+
+ class(TestAccumul), intent(inout) :: this
+ character(len=*), parameter :: fieldname = 'foo'
+ integer, parameter :: npatches = 2
+ integer, parameter :: nlevels = 5
+ real(r8), parameter :: pwtcol(npatches) = [0.5, 0.5]
+ integer, parameter :: pft_type(npatches) = [1, 2]
+ integer, parameter :: accum_period = 3
+ integer, parameter :: expected(npatches, nlevels) = transpose(reshape([ &
+ 1, 1, 1, 1, 1, &
+ 1, 1, 1, 1, 1 &
+ ], [nlevels, npatches]))
+ logical :: reset_output(npatches, nlevels)
+ integer :: reset_output_int(npatches, nlevels)
+ integer :: l, p
+
+ ! Setup
+ call setup_n_veg_patches(pwtcol, pft_type)
+ call this%init_ml_patch_field(name=fieldname, accum_type='timeavg', &
+ accum_period = accum_period, nlev=nlevels)
+
+ ! Exercise
+ call markreset_accum_field(fieldname)
+ reset_output = get_accum_reset(fieldname)
+
+ ! Verify
+ reset_output_int = merge(1, 0, reset_output)
+ @assertEqual(expected, reset_output_int)
+end subroutine markreset_allpoints_alllevels
+
+
end module test_accumul
diff --git a/src/soilbiogeochem/CNSoilMatrixMod.F90 b/src/soilbiogeochem/CNSoilMatrixMod.F90
new file mode 100644
index 0000000000..56c1f11b5c
--- /dev/null
+++ b/src/soilbiogeochem/CNSoilMatrixMod.F90
@@ -0,0 +1,940 @@
+module CNSoilMatrixMod
+
+!#include "shr_assert.h"
+ !-----------------------------------------------------------------------
+ ! The matrix model of CLM5.0 was developed by Yiqi Luo EcoLab members,
+ ! Drs. Xingjie Lu, Yuanyuan Huang and Zhengguang Du, at Northern Arizona University
+ !----------------------------------------------------------------------------------
+ !
+ ! DESCRIPTION:
+ ! Module for CLM5.0BGC matrices
+ ! The matrix equation
+ ! Xn+1 = Xn + I*dt + (A*K(ksi) - Kfire - tri/dz)*Xn*dt
+ ! Or
+ ! Xn+1 = Xn + I*dt + (A*K(ksi) - Kfire - V)*Xn*dt
+
+ ! !USES:
+ use shr_kind_mod , only : r8 => shr_kind_r8
+ use shr_log_mod , only : errMsg => shr_log_errMsg
+ use decompMod , only : bounds_type
+ use abortutils , only : endrun
+ use clm_time_manager , only : get_step_size, is_end_curr_month,get_curr_date,update_DA_nstep
+ use clm_time_manager , only : is_first_restart_step,is_beg_curr_year,is_end_curr_year,is_first_step_of_this_run_segment
+ use clm_varpar , only : ndecomp_pools, nlevdecomp, ndecomp_pools_vr !number of biogeochemically active soil layers
+ use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_cascade_outtransitions
+ use clm_varpar , only : i_cwd
+ use clm_varcon , only : dzsoi_decomp,zsoi,secspday,c3_r2,c14ratio
+ use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con, use_soil_matrixcn
+ use CNVegCarbonFluxType , only : cnveg_carbonflux_type
+ use CNVegNitrogenFluxType , only : cnveg_nitrogenflux_type
+ use SoilBiogeochemStateType , only : soilbiogeochem_state_type
+ use SoilBiogeochemCarbonStateType , only : soilbiogeochem_carbonstate_type
+ use SoilBiogeochemCarbonFluxType , only : soilbiogeochem_carbonflux_type
+ use SoilBiogeochemNitrogenStateType , only : soilbiogeochem_nitrogenstate_type
+ use SoilBiogeochemNitrogenFluxType , only : soilbiogeochem_nitrogenflux_type
+ use CNSharedParamsMod , only : CNParamsShareInst
+ use SoilStateType , only : soilstate_type
+ use clm_varctl , only : spinup_matrixcn, hist_wrt_matrixcn_diag, nyr_forcing, nyr_SASU, iloop_avg
+ use ColumnType , only : col
+ use GridcellType , only : grc
+ use clm_varctl , only : use_c13, use_c14, iulog
+ use perf_mod , only : t_startf, t_stopf
+ use SparseMatrixMultiplyMod , only : sparse_matrix_type, diag_matrix_type, vector_type
+ use MatrixMod , only : inverse
+!
+ implicit none
+ private
+ !
+ ! !PUBLIC MEMBER FUNCTIONS:
+ public:: CNSoilMatrixInit ! Initialization for CN Soil Matrix solution
+ public:: CNSoilMatrix
+ public:: CNSoilMatrixRest ! Restart for CN Soil Matrix solution
+
+ ! ! PRIVATE MEMBER DATA:
+ integer,save, private :: iyr=0 ! Cycling year number into forcing sequence
+ integer,save, private :: iloop=0 ! The iloop^th forcing loop
+ !-----------------------------------------------------------------------
+
+contains
+
+ !-----------------------------------------------------------------------
+ subroutine CNSoilMatrixInit( )
+ ! !DESCRIPTION: Initialization for CN soil Matrix solution
+ ! !ARGUMENTS:
+ ! !LOCAL VARIABLES:
+ !-----------------------------------------------------------------------
+
+ if ( use_soil_matrixcn ) then
+ write(iulog,*) 'CN Soil matrix solution is on'
+ write(iulog,*) '*****************************'
+ if ( spinup_matrixcn ) then
+ write(iulog,*) ' Matrix spinup is on'
+ write(iulog,*) ' *******************'
+ write(iulog,*) ' nyr_forcing = ', nyr_forcing
+ write(iulog,*) ' nyr_SASU = ', nyr_SASU
+ write(iulog,*) ' iloop_avg = ', iloop_avg
+ end if
+ if ( hist_wrt_matrixcn_diag )then
+ write(iulog,*) ' Extra matrix solution tracability output is turned on'
+ else
+ write(iulog,*) ' no extra matrix solution tracability output'
+ end if
+ else
+ write(iulog,*) 'CN Soil matrix solution is off'
+ end if
+ end subroutine CNSoilMatrixInit
+
+ !-----------------------------------------------------------------------
+ subroutine CNSoilMatrix(bounds,num_soilc, filter_soilc, num_actfirec, filter_actfirec,&
+ cnveg_carbonflux_inst,soilbiogeochem_carbonstate_inst, &
+ soilbiogeochem_carbonflux_inst,soilbiogeochem_state_inst, &
+ cnveg_nitrogenflux_inst, soilbiogeochem_nitrogenflux_inst, &
+ soilbiogeochem_nitrogenstate_inst,c13_soilbiogeochem_carbonstate_inst,&
+ c13_soilbiogeochem_carbonflux_inst,c14_soilbiogeochem_carbonstate_inst,&
+ c14_soilbiogeochem_carbonflux_inst)
+ ! !DESCRIPTION:
+ ! !ARGUMENTS:
+ type(bounds_type) , intent(in) :: bounds
+ integer , intent(in) :: num_soilc ! number of soil columns in filter
+ integer , intent(in) :: filter_soilc(:) ! filter for soil columns
+ integer , intent(in) :: num_actfirec ! number of soil columns in filter
+ integer , intent(in) :: filter_actfirec(:) ! filter for soil columns
+ type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst
+ type(soilbiogeochem_carbonstate_type) , intent(inout) :: soilbiogeochem_carbonstate_inst
+ type(soilbiogeochem_carbonflux_type) , intent(inout) :: soilbiogeochem_carbonflux_inst
+ type(soilbiogeochem_state_type) , intent(inout) :: soilbiogeochem_state_inst
+ type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst
+ type(soilbiogeochem_nitrogenflux_type) , intent(inout) :: soilbiogeochem_nitrogenflux_inst
+ type(soilbiogeochem_nitrogenstate_type) , intent(inout) :: soilbiogeochem_nitrogenstate_inst
+ type(soilbiogeochem_carbonstate_type) , intent(inout) :: c13_soilbiogeochem_carbonstate_inst
+ type(soilbiogeochem_carbonflux_type) , intent(inout) :: c13_soilbiogeochem_carbonflux_inst
+ type(soilbiogeochem_carbonstate_type) , intent(inout) :: c14_soilbiogeochem_carbonstate_inst
+ type(soilbiogeochem_carbonflux_type) , intent(inout) :: c14_soilbiogeochem_carbonflux_inst
+
+ ! !LOCAL VARIABLES:
+ integer :: fc,j,i, l,k ! indices
+ integer :: c !
+ real(r8):: dt ! time step (seconds)
+ real(r8):: epsi,fire_delta ! small number
+
+ integer :: begc,endc ! bounds
+ real(r8),dimension(bounds%begc:bounds%endc,nlevdecomp*(ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)) :: a_ma_vr,na_ma_vr
+
+ real(r8),dimension(bounds%begc:bounds%endc,1:ndecomp_pools_vr,1) :: soilmatrixc_cap,soilmatrixc13_cap,soilmatrixc14_cap,soilmatrixn_cap
+ real(r8), dimension(1:ndecomp_pools_vr,1:ndecomp_pools_vr) :: AKinv,AKinvn
+
+ real(r8),dimension(bounds%begc:bounds%endc,1:nlevdecomp,1:ndecomp_pools) :: cn_decomp_pools
+ integer :: Ntrans
+ integer tranlist_a
+ integer j_decomp,j_lev,ilev,idecomp
+ integer,dimension(:) :: kfire_i(1:ndecomp_pools_vr)
+ integer,dimension(:) :: kfire_j(1:ndecomp_pools_vr)
+ real(r8),dimension(:,:) :: Cinter_old(bounds%begc:bounds%endc,1:ndecomp_pools_vr)
+ real(r8),dimension(:,:) :: C13inter_old(bounds%begc:bounds%endc,1:ndecomp_pools_vr)
+ real(r8),dimension(:,:) :: C14inter_old(bounds%begc:bounds%endc,1:ndecomp_pools_vr)
+ real(r8),dimension(:,:) :: Ninter_old(bounds%begc:bounds%endc,1:ndecomp_pools_vr)
+ logical,save :: list_ready1_fire = .False.
+ logical,save :: list_ready1_nofire = .False.
+ logical,save :: list_ready2_fire = .False.
+ logical,save :: list_ready2_nofire = .False.
+ logical,save :: list_ready3_fire = .False.
+ logical,save :: init_readyAsoilc = .False.
+ logical,save :: init_readyAsoiln = .False.
+ logical isbegofyear
+
+ !-----------------------------------------------------------------------
+ begc = bounds%begc; endc = bounds%endc
+
+! SHR_ASSERT_ALL((ubound(cn_decomp_pools) == (/endc,nlevdecomp,ndecomp_pools/)) , errMsg(sourcefile, __LINE__))
+ associate( &
+ cs_soil => soilbiogeochem_carbonstate_inst , & ! In/Output
+ ns_soil => soilbiogeochem_nitrogenstate_inst , & ! In/Output
+ cs13_soil => c13_soilbiogeochem_carbonstate_inst, & ! In/Output
+ cs14_soil => c14_soilbiogeochem_carbonstate_inst, & ! In/Output
+ cf13_soil => c13_soilbiogeochem_carbonflux_inst, & ! In/Output
+ cf14_soil => c14_soilbiogeochem_carbonflux_inst, & ! In/Output
+
+ fpi_vr => soilbiogeochem_state_inst%fpi_vr_col ,&!Input:[real(r8)(:,:)]fraction of potential immobilization (no units)
+ cascade_donor_pool => decomp_cascade_con%cascade_donor_pool ,&!Input:[integer(:)]which pool is C taken from for a given decomposition step
+ cascade_receiver_pool => decomp_cascade_con%cascade_receiver_pool ,&!Input:[integer(:)]which pool is C added to for a given decomposition step
+ floating_cn_ratio_decomp_pools=> decomp_cascade_con%floating_cn_ratio_decomp_pools ,&!Input:[logical(:)]TRUE => pool has fixed C:N ratio
+ initial_cn_ratio => decomp_cascade_con%initial_cn_ratio ,&!Input:[real(r8)(:)]c:n ratio for initialization of pools
+ rf_decomp_cascade => soilbiogeochem_carbonflux_inst%rf_decomp_cascade_col ,&!Input:[real(r8)(:,:,:)]respired fraction in decomposition step (frac)
+ pathfrac_decomp_cascade => soilbiogeochem_carbonflux_inst%pathfrac_decomp_cascade_col,&!Input:[real(r8)(:,:,:)]what fraction of C leaving a given pool passes
+ ! through a given transition (frac)
+ is_cwd => decomp_cascade_con%is_cwd ,&!Input:[logical(:)]TRUE => pool is a cwd pool
+ is_litter => decomp_cascade_con%is_litter ,&!Input:[logical(:)]TRUE => pool is a litter pool
+
+ hr => soilbiogeochem_carbonflux_inst%hr_col ,&!Output:[real(r8)(:)]heterotrophic respiration
+ trcr_ctendency => soilbiogeochem_carbonflux_inst%decomp_cpools_transport_tendency_col,&
+ trcr_ntendency => soilbiogeochem_nitrogenflux_inst%decomp_npools_transport_tendency_col,&
+ m_decomp_cpools_to_fire => cnveg_carbonflux_inst%m_decomp_cpools_to_fire_col ,&!Output:[real(r8)(:,:)]vertically-integrated decomposing C fire loss
+ tri_ma_vr => soilbiogeochem_carbonflux_inst%tri_ma_vr ,&!Input:[real(r8)(:,:)]vertical C transfer rate in sparse matrix format (gC*m3)/(gC*m3*step))
+ matrix_decomp_fire_k => soilbiogeochem_carbonflux_inst%matrix_decomp_fire_k_col ,&!Input:[real(r8)(:,:)]decomposition rate due to fire (gC*m3)/(gC*m3*step))
+
+ AKsoilc => soilbiogeochem_carbonflux_inst%AKsoilc ,&!Output:[SparseMatrix] A*K for C transfers between pools
+ RI_a => soilbiogeochem_carbonflux_inst%RI_a ,&!In/Output:[Integer(:)] Row numbers of all entries from AKsoilc, Automatically generated by SetValueA
+ CI_a => soilbiogeochem_carbonflux_inst%CI_a ,&!In/Output:[Integer(:)] Column numbers of all entries from AKsoilc, Automatically generated by SetValueA
+ AKsoiln => soilbiogeochem_nitrogenflux_inst%AKsoiln ,&!Output:[SparseMatrix] A*K for N transfers between pools
+ RI_na => soilbiogeochem_nitrogenflux_inst%RI_na ,&!In/Output:[Integer(:)] Row numbers of all entries from AKsoiln, Automatically generated by SetValueA
+ CI_na => soilbiogeochem_nitrogenflux_inst%CI_na ,&!In/Output:[Integer(:)] Column numbers of all entries from AKsoiln, Automatically generated by SetValueA
+
+ A_i => decomp_cascade_con%A_i ,&!Input:[integer(:)] Prescribed row number of all elements in a_ma_vr
+ A_j => decomp_cascade_con%A_j ,&!Input:[integer(:)] Prescribed column number of all elements in na_ma_vr
+ spm_tranlist_a => decomp_cascade_con%spm_tranlist_a ,&!Input:[integer(:,:)] Prescribed subscripts to map 2D variables (transitions,soil layer) to 1D sparse matrix format in a_ma_vr and na_ma_vr
+
+ AVsoil => soilbiogeochem_carbonflux_inst%AVsoil ,&!Output:[SparseMatrix] V for C and N transfers between soil layers
+ tri_i => decomp_cascade_con%tri_i ,&!Input:[integer(:)] Prescribed row index of all entries in AVsoil
+ tri_j => decomp_cascade_con%tri_j ,&!Input:[integer(:)] Prescribed column index of all entries in AVsoil
+ Ntri_setup => decomp_cascade_con%Ntri_setup ,&!Input:[integer] Number of non-zero entries in AVsoil
+
+ AKfiresoil => soilbiogeochem_carbonflux_inst%AKfiresoil,&!Output:[SparseMatrix] Kfire for CN transfers from soil to atm due to fire
+
+ AKallsoilc => soilbiogeochem_carbonflux_inst%AKallsoilc ,&!Output:[SparseMatrix] (A*K+V-Kfire) for soil C cycle
+ NE_AKallsoilc => soilbiogeochem_carbonflux_inst%NE_AKallsoilc ,&!In/Output:[Integer] Number of entries in AKallsoilc, Automatically generated by functions SPMP_*
+ RI_AKallsoilc => soilbiogeochem_carbonflux_inst%RI_AKallsoilc ,&!In/Output:[Integer(:)] Row numbers of entries in AKallsoilc, Automatically generated by functions SPMP_*
+ CI_AKallsoilc => soilbiogeochem_carbonflux_inst%CI_AKallsoilc ,&!In/Output:[Integer(:)] Column numbers of entries in AKallsoilc, Automatically generated by functions SPMP_*
+ AKallsoiln => soilbiogeochem_nitrogenflux_inst%AKallsoiln ,&!Output:[SparseMatrix] (A*K+V-Kfire) for soil N cycle
+ NE_AKallsoiln => soilbiogeochem_nitrogenflux_inst%NE_AKallsoiln,&!In/Output:[Integer] Number of entries in AKallsoilc, Automatically generated by functions SPMP_*
+ RI_AKallsoiln => soilbiogeochem_nitrogenflux_inst%RI_AKallsoiln,&!In/Output:[Integer(:)] Row numbers of entries in AKallsoilc, Automatically generated by functions SPMP_*
+ CI_AKallsoiln => soilbiogeochem_nitrogenflux_inst%CI_AKallsoiln,&!In/Output:[Integer(:)] Column numbers of entries in AKallsoilc, Automatically generated by functions SPMP_*
+ AKXcacc => soilbiogeochem_carbonstate_inst%AKXcacc ,&!In/Output:[SparseMatrix] Accumulated transfers for soil C cycle
+ AKXnacc => soilbiogeochem_nitrogenstate_inst%AKXnacc ,&!In/Output:[SparseMatrix] Accumulated transfers for soil N cycle
+ n_all_entries => decomp_cascade_con%n_all_entries ,&!Input:[integer] Number of all entries in AKallsoilc, AKallsoiln, AKXcacc, and AKXnacc
+ all_i => decomp_cascade_con%all_i ,&!Input:[integer(:)] Prescribed row index of all entries in AKallsoilc, AKallsoiln, AKXcacc, and AKXnacc
+ all_j => decomp_cascade_con%all_j ,&!Input:[integer(:)] Prescribed column index of all entries in AKallsoilc, AKallsoiln, AKXcacc, and AKXnacc
+
+ Ksoil => soilbiogeochem_carbonflux_inst%Ksoil ,&!Output:[DiagonalMatrix] C turnover rate in different soil pools and layers
+ Ksoiln => soilbiogeochem_nitrogenflux_inst%Ksoiln ,&!Output:[DiagonalMatrix] N turnover rate in different soil pools and layers
+ Xdiagsoil => soilbiogeochem_carbonflux_inst%Xdiagsoil ,&!Output:[DiagonalMatrix] Temporary C and N state variable to calculate accumulation transfers
+ matrix_Cinter => soilbiogeochem_carbonstate_inst%matrix_Cinter ,&!In/Output:[Vector] Soil C state variables (gC/m3) in different soil pools and layers
+ matrix_Ninter => soilbiogeochem_nitrogenstate_inst%matrix_Ninter ,&!In/Output:[Vector] Soil N state variables (gN/m3) in different soil pools and layers
+ matrix_Cinter13=> c13_soilbiogeochem_carbonstate_inst%matrix_Cinter,&!In/Output:[Vector] Soil C13 state variables (gC13/m3) in different soil pools and layers
+ matrix_Cinter14=> c14_soilbiogeochem_carbonstate_inst%matrix_Cinter,&!In/Output:[Vector] Soil C14 state variables (gC14/m3) in different soil pools and layers
+ matrix_Cinput => soilbiogeochem_carbonflux_inst%matrix_Cinput ,&!Input:[Vector] C input to different soil compartments (pools and layers) (gC/m3/step)
+ matrix_Cinput13=> c13_soilbiogeochem_carbonflux_inst%matrix_Cinput ,&!Input:[Vector] C13 input to different soil compartments (pools and layers) (gC13/m3/step)
+ matrix_Cinput14=> c14_soilbiogeochem_carbonflux_inst%matrix_Cinput ,&!Input:[Vector] C14 input to different soil compartments (pools and layers) (gC14/m3/step)
+ matrix_Ninput => soilbiogeochem_nitrogenflux_inst%matrix_Ninput ,&!Input:[Vector] N input to different soil compartments (pools and layers) (gN/m3/step)
+
+ list_Asoilc => decomp_cascade_con%list_Asoilc ,&!In/Output:[Integer(:)] Saves mapping indices from a_ma_vr to AKsoilc
+ list_Asoiln => decomp_cascade_con%list_Asoiln ,&!In/Output:[Integer(:)] Saves mapping indices from na_ma_vr to AKsoiln
+ list_V_AKVfire => decomp_cascade_con%list_V_AKVfire ,&!In/Output:[Integer(:)] Saves mapping indices from V to (A*K+V-Kfire) in the addition subroutine SPMP_ABC
+ list_fire_AKVfire=> decomp_cascade_con%list_fire_AKVfire,&!In/Output:[Integer(:)] Saves mapping indices from Kfire to (A*K+V-Kfire) in the addition subroutine SPMP_ABC
+ list_AK_AKVfire => decomp_cascade_con%list_AK_AKVfire ,&!In/Output:[Integer(:)] Saves mapping indices from A*K to (A*K+V-Kfire) in the addition subroutine SPMP_ABC
+ list_AK_AKV => decomp_cascade_con%list_AK_AKV ,&!In/Output:[Integer(:)] Saves mapping indices from A*K to (A*K+V) in the addition subroutine SPMP_AB
+ list_V_AKV => decomp_cascade_con%list_V_AKV &!In/Output:[Integer(:)] Saves mapping indices from V to (A*K+V) in the addition subroutine SPMP_AB
+ )
+
+ ! set time steps
+ call t_startf('CN Soil matrix-init. matrix')
+ dt = real( get_step_size(), r8 )
+
+ Ntrans = (ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)*nlevdecomp
+ epsi = 1.e-8_r8
+
+ isbegofyear = is_beg_curr_year()
+
+ ! calculate c:n ratios of applicable pools
+ do l = 1, ndecomp_pools
+ if ( floating_cn_ratio_decomp_pools(l)) then
+ do j = 1,nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ if ( ns_soil%decomp_npools_vr_col(c,j,l) > 0._r8 ) then
+ cn_decomp_pools(c,j,l) = cs_soil%decomp_cpools_vr_col(c,j,l) / ns_soil%decomp_npools_vr_col(c,j,l)
+ else
+ cn_decomp_pools(c,j,l) = initial_cn_ratio(l)
+ end if
+ end do
+ end do
+ else
+ do j = 1,nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cn_decomp_pools(c,j,l) = initial_cn_ratio(l)
+ end do
+ end do
+ end if
+ end do
+
+ call t_stopf('CN Soil matrix-init. matrix')
+
+ call t_startf('CN Soil matrix-assign matrix-a-na')
+ ! Calculate non-diagonal entries (a_ma_vr and na_ma_vr) in transfer coefficient matrix A
+ do k = 1, ndecomp_cascade_transitions
+ if(cascade_receiver_pool(k) .ne. 0)then !transition to atmosphere
+ do j = 1, nlevdecomp
+ tranlist_a = spm_tranlist_a(j,k)
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ a_ma_vr(c,tranlist_a) = (1.0_r8-rf_decomp_cascade(c,j,k))*pathfrac_decomp_cascade(c,j,k)
+ if( .not. floating_cn_ratio_decomp_pools(cascade_receiver_pool(k)))then
+ na_ma_vr(c,tranlist_a) = (1.0_r8-rf_decomp_cascade(c,j,k))* &
+ (cn_decomp_pools(c,j,cascade_donor_pool(k))/cn_decomp_pools(c,j,cascade_receiver_pool(k)))*pathfrac_decomp_cascade(c,j,k)
+ else
+ na_ma_vr(c,tranlist_a) = pathfrac_decomp_cascade(c,j,k)
+ end if
+ end do
+ end do
+ end if
+ end do
+
+ call t_stopf('CN Soil matrix-assign matrix-a-na')
+
+ ! Update the turnover rate matrix K with N limitation (fpi_vr)
+
+ ! Assign old value to vector, and be ready for matrix operation
+ call t_startf('CN Soil matrix-assign matrix-inter')
+ do i = 1,ndecomp_pools
+ do j = 1, nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ matrix_Cinter%V(c,j+(i-1)*nlevdecomp) = cs_soil%decomp_cpools_vr_col(c,j,i)
+ Cinter_old(c,j+(i-1)*nlevdecomp) = cs_soil%decomp_cpools_vr_col(c,j,i)
+ !Cinter_old is saved for accumulation of C transfer calculation and C flux (hr and fire) adjustment
+ matrix_Ninter%V(c,j+(i-1)*nlevdecomp) = ns_soil%decomp_npools_vr_col(c,j,i)
+ Ninter_old(c,j+(i-1)*nlevdecomp) = ns_soil%decomp_npools_vr_col(c,j,i)
+ !Ninter_old is saved for accumulation of N transfer calculation
+ end do
+ end do
+ end do
+ if ( use_c13 )then
+ do i = 1,ndecomp_pools
+ do j = 1, nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ matrix_Cinter13%V(c,j+(i-1)*nlevdecomp) = cs13_soil%decomp_cpools_vr_col(c,j,i)
+ C13inter_old(c,j+(i-1)*nlevdecomp) = cs13_soil%decomp_cpools_vr_col(c,j,i)
+ end do
+ end do
+ end do
+ end if !c13
+
+ if ( use_c14 )then
+ do i = 1,ndecomp_pools
+ do j = 1, nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ matrix_Cinter14%V(c,j+(i-1)*nlevdecomp) = cs14_soil%decomp_cpools_vr_col(c,j,i)
+ C14inter_old(c,j+(i-1)*nlevdecomp) = cs14_soil%decomp_cpools_vr_col(c,j,i)
+ end do
+ end do
+ end do
+ end if !c14
+ call t_stopf('CN Soil matrix-assign matrix-inter')
+
+ call Ksoiln%SetValueCopyDM(num_soilc,filter_soilc,Ksoil )
+ do i = 1,ndecomp_pools
+ if ( .not. floating_cn_ratio_decomp_pools(i) ) then
+ do j = 1,nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ if(ns_soil%decomp_npools_vr_col(c,j,i) > 0)then
+ Ksoiln%DM(c,j+(i-1)*nlevdecomp) = Ksoil%DM(c,j+(i-1)*nlevdecomp) * cs_soil%decomp_cpools_vr_col(c,j,i) / ns_soil%decomp_npools_vr_col(c,j,i) / initial_cn_ratio(i)
+ end if
+ end do
+ end do
+ end if
+ end do
+ ! Save the C and N pool size at begin of each year, which are used to calculate C and N capacity at end of each year.
+ call t_startf('CN Soil matrix-assign matrix-decomp0')
+ if (is_beg_curr_year())then
+ iyr = iyr + 1
+ if(mod(iyr-1,nyr_forcing) .eq. 0)then
+ iloop = iloop + 1
+ end if
+ if(.not. spinup_matrixcn .or. spinup_matrixcn .and. mod(iyr-1,nyr_SASU) .eq. 0)then
+ do i = 1,ndecomp_pools
+ do j = 1, nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cs_soil%decomp0_cpools_vr_col(c,j,i)=cs_soil%decomp_cpools_vr_col(c,j,i)
+ if(use_c13)then
+ cs13_soil%decomp0_cpools_vr_col(c,j,i)=cs13_soil%decomp_cpools_vr_col(c,j,i)
+ end if
+ if(use_c14)then
+ cs14_soil%decomp0_cpools_vr_col(c,j,i)=cs14_soil%decomp_cpools_vr_col(c,j,i)
+ end if
+ ns_soil%decomp0_npools_vr_col(c,j,i)=ns_soil%decomp_npools_vr_col(c,j,i)
+ end do
+ end do
+ end do
+ where(cs_soil%decomp0_cpools_vr_col .lt. epsi)
+ cs_soil%decomp0_cpools_vr_col = epsi
+ end where
+ if(use_c13)then
+ where(cs13_soil%decomp0_cpools_vr_col .lt. epsi*c3_r2)
+ cs13_soil%decomp0_cpools_vr_col = epsi*c3_r2
+ end where
+ end if
+ if(use_c14)then
+ where(cs14_soil%decomp0_cpools_vr_col .lt. epsi*c14ratio)
+ cs14_soil%decomp0_cpools_vr_col = epsi*c14ratio
+ end where
+ end if
+ where(ns_soil%decomp0_npools_vr_col .lt. epsi)
+ ns_soil%decomp0_npools_vr_col = epsi
+ end where
+ end if
+ end if
+ call t_stopf('CN Soil matrix-assign matrix-decomp0')
+
+ ! Set C transfer matrix Ac from a_ma_vr
+ call t_startf('CN Soil matrix-matrix mult1-lev3-SetValueAK1')
+ call AKsoilc%SetValueA(begc,endc,num_soilc,filter_soilc,a_ma_vr,A_i,A_j,Ntrans,init_readyAsoilc,list_Asoilc,RI_a,CI_a)
+ call t_stopf('CN Soil matrix-matrix mult1-lev3-SetValueAK1')
+
+ ! Set N transfer matrix An from na_ma_vr
+ call t_startf('CN Soil matrix-matrix mult1-lev3-SetValueAK2')
+ call AKsoiln%SetValueA(begc,endc,num_soilc,filter_soilc,na_ma_vr,A_i,A_j,Ntrans,init_readyAsoiln,list_Asoiln,RI_na,CI_na)
+ call t_stopf('CN Soil matrix-matrix mult1-lev3-SetValueAK2')
+
+ ! calculate matrix Ac*K for C
+ call t_startf('CN Soil matrix-matrix mult1-lev3-SPMM_AK1')
+ call AKsoilc%SPMM_AK(num_soilc,filter_soilc,Ksoil)
+ call t_stopf('CN Soil matrix-matrix mult1-lev3-SPMM_AK1')
+
+ ! calculate matrix An*K for N
+ call t_startf('CN Soil matrix-matrix mult1-lev3-SPMM_AK2')
+ call AKsoiln%SPMM_AK(num_soilc,filter_soilc,Ksoiln)
+ call t_stopf('CN Soil matrix-matrix mult1-lev3-SPMM_AK2')
+
+ ! Set vertical transfer matrix V from tri_ma_vr
+ call t_startf('CN Soil matrix-matrix mult1-lev3-SetValueAV,AKfire')
+ call AVsoil%SetValueSM(begc,endc,num_soilc,filter_soilc,tri_ma_vr(begc:endc,1:Ntri_setup),tri_i,tri_j,Ntri_setup)
+
+ ! Set fire decomposition matrix Kfire from matrix_decomp_fire_k
+ do j=1,ndecomp_pools_vr
+ kfire_i(j) = j
+ kfire_j(j) = j
+ end do
+ call AKfiresoil%SetValueSM(begc,endc,num_soilc,filter_soilc,matrix_decomp_fire_k(begc:endc,1:ndecomp_pools_vr),kfire_i,kfire_j,ndecomp_pools_vr)
+ if(use_c14)then
+ do i = 1,ndecomp_pools
+ do j = 1, nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cf14_soil%matrix_decomp_fire_k_col(c,j+(i-1)*nlevdecomp) = cf14_soil%matrix_decomp_fire_k_col(c,j+(i-1)*nlevdecomp) &
+ + matrix_decomp_fire_k(c,j+(i-1)*nlevdecomp)
+ end do
+ end do
+ end do
+ call cf14_soil%AKfiresoil%SetValueSM(begc,endc,num_soilc,filter_soilc,&
+ cf14_soil%matrix_decomp_fire_k_col(begc:endc,1:ndecomp_pools_vr),kfire_i,kfire_j,ndecomp_pools_vr)
+ end if
+ call t_stopf('CN Soil matrix-matrix mult1-lev3-SetValueAV,AKfire')
+
+ ! Calculate AKallsoilc = A*K + AVsoil + AKfiresoil. (AKfiresoil = -Kfire)
+ ! When no fire, AKallsoilc = A*K + AVsoil
+ ! When fire is on, AKallsoilc = A*K + AVsoil + AKfiresoil
+ ! Here, AKallsoilc represents all soil C transfer rate (gC/(gC*m3*step))
+ ! and AKallsoiln represents all soil N transfer rate (gN/(gN*m3*step))
+
+ call t_startf('CN Soil matrix-matrix mult1-lev3-SPMP_AB')
+ if(num_actfirec .eq. 0)then
+ call AKallsoilc%SPMP_AB(num_soilc,filter_soilc,AKsoilc,AVsoil,list_ready1_nofire,list_A=list_AK_AKV, list_B=list_V_AKV,&
+ NE_AB=NE_AKallsoilc,RI_AB=RI_AKallsoilc,CI_AB=CI_AKallsoilc)
+ call AKallsoiln%SPMP_AB(num_soilc,filter_soilc,AKsoiln,AVsoil,list_ready2_nofire,list_A=list_AK_AKV, list_B=list_V_AKV,&
+ NE_AB=NE_AKallsoiln,RI_AB=RI_AKallsoiln,CI_AB=CI_AKallsoiln)
+ else
+ call AKallsoilc%SPMP_ABC(num_soilc,filter_soilc,AKsoilc,AVsoil,AKfiresoil,list_ready1_fire,list_A=list_AK_AKVfire,&
+ list_B=list_V_AKVfire,list_C=list_fire_AKVfire,NE_ABC=NE_AKallsoilc,RI_ABC=RI_AKallsoilc,CI_ABC=CI_AKallsoilc,&
+ use_actunit_list_C=.True.,num_actunit_C=num_actfirec,filter_actunit_C=filter_actfirec)
+ call AKallsoiln%SPMP_ABC(num_soilc,filter_soilc,AKsoiln,AVsoil,AKfiresoil,list_ready2_fire,list_A=list_AK_AKVfire,&
+ list_B=list_V_AKVfire,list_C=list_fire_AKVfire,NE_ABC=NE_AKallsoiln,RI_ABC=RI_AKallsoiln,CI_ABC=CI_AKallsoiln,&
+ use_actunit_list_C=.True.,num_actunit_C=num_actfirec,filter_actunit_C=filter_actfirec)
+ end if
+ if(use_c14)then
+ call cf14_soil%AKallsoilc%SPMP_ABC(num_soilc,filter_soilc,AKsoilc,AVsoil,cf14_soil%AKfiresoil,list_ready3_fire,&
+ list_A=list_AK_AKVfire,list_B=list_V_AKVfire,list_C=list_fire_AKVfire,NE_ABC=cf14_soil%NE_AKallsoilc,&
+ RI_ABC=cf14_soil%RI_AKallsoilc,CI_ABC=cf14_soil%CI_AKallsoilc)
+ end if
+
+ call t_stopf('CN Soil matrix-matrix mult1-lev3-SPMP_AB')
+
+ call t_startf('CN Soil matrix-matrix mult2-lev2')
+
+ ! Update soil C pool size: X(matrix_Cinter) = X(matrix_Cinter) + (A*K + AVsoil + AKfiresoil) * X(matrix_Cinter)
+ ! Update soil N pool size: X(matrix_Ninter) = X(matrix_Ninter) + (A*K + AVsoil + AKfiresoil) * X(matrix_Ninter)
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ do i=1,AVsoil%NE
+ ilev = mod(AVsoil%RI(i)-1,nlevdecomp)+1
+ idecomp = (AVsoil%RI(i) - ilev)/nlevdecomp + 1
+ trcr_ctendency(c,ilev,idecomp) = trcr_ctendency(c,ilev,idecomp) + AVsoil%M(c,i)*matrix_Cinter%V(c,AVsoil%CI(i)) / dt
+ trcr_ntendency(c,ilev,idecomp) = trcr_ntendency(c,ilev,idecomp) + AVsoil%M(c,i)*matrix_Ninter%V(c,AVsoil%CI(i)) / dt
+ end do
+ end do
+
+ call matrix_Cinter%SPMM_AX(num_soilc,filter_soilc,AKallsoilc)
+ call matrix_Ninter%SPMM_AX(num_soilc,filter_soilc,AKallsoiln)
+
+ ! Update soil C13 pool size: X(matrix_Cinter13) = X(matrix_Cinter13) + (A*K + AVsoil + AKfiresoil) * X(matrix_Cinter13)
+ if ( use_c13)then
+ call matrix_Cinter13%SPMM_AX(num_soilc,filter_soilc,AKallsoilc)
+ end if
+
+ ! Update soil C14 pool size: X(matrix_Cinter14) = X(matrix_Cinter14) + (A*K + AVsoil + AKfiresoil) * X(matrix_Cinter14)
+ if ( use_c14)then
+ call matrix_Cinter14%SPMM_AX(num_soilc,filter_soilc,cf14_soil%AKallsoilc)
+ end if
+
+ ! Update soil C pool size: X(matrix_Cinter) = X(matrix_Cinter) + (A*K + AVsoil + AKfiresoil) * X(matrix_Cinter) + I(matrix_Cinput)
+ ! Update soil N pool size: X(matrix_Ninter) = X(matrix_Ninter) + (A*K + AVsoil + AKfiresoil) * X(matrix_Ninter) + I(matrix_Ninput)
+ do j = 1, ndecomp_pools_vr
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ matrix_Cinter%V(c,j) = matrix_Cinput%V(c,j) + matrix_Cinter%V(c,j)
+ matrix_Ninter%V(c,j) = matrix_Ninput%V(c,j) + matrix_Ninter%V(c,j)
+ end do
+ end do
+
+ ! Update soil C13 pool size: X(matrix_Cinter13) = X(matrix_Cinter13) + (A*K + AVsoil + AKfiresoil) * X(matrix_Cinter13) + I(matrix_Cinput13)
+ if ( use_c13)then
+ do j = 1, ndecomp_pools_vr
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ matrix_Cinter13%V(c,j) = matrix_Cinput13%V(c,j) + matrix_Cinter13%V(c,j)
+ end do
+ end do
+ end if
+
+ ! Update soil C14 pool size: X(matrix_Cinter14) = X(matrix_Cinter14) + (A*K + AVsoil + AKfiresoil) * X(matrix_Cinter14) + I(matrix_Cinput14)
+ if ( use_c14)then
+ do j = 1, ndecomp_pools_vr
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ matrix_Cinter14%V(c,j) = matrix_Cinput14%V(c,j) + matrix_Cinter14%V(c,j)
+ end do
+ end do
+ end if !c14
+
+ ! Adjust heterotrophic respiration and fire flux because the pool size updating order is different between default and matrix code, balance error will occur
+ ! while sudden big changes happen in C pool, eg. crop harvest and fire.
+ call t_stopf('CN Soil matrix-matrix mult2-lev2')
+
+ call t_startf('CN Soil matrix-assign back')
+
+ ! Send vector type soil C and N pool size back to decomp_cpools_vr_col and decomp_npools_vr_col
+ do i=1,ndecomp_pools
+ do j = 1,nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cs_soil%decomp_cpools_vr_col(c,j,i) = matrix_Cinter%V(c,j+(i-1)*nlevdecomp)
+ ns_soil%decomp_npools_vr_col(c,j,i) = matrix_Ninter%V(c,j+(i-1)*nlevdecomp)
+ end do
+ end do
+ end do
+
+ if( use_c13 ) then
+ do i=1,ndecomp_pools
+ do j = 1,nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cs13_soil%decomp_cpools_vr_col(c,j,i) = matrix_Cinter13%V(c,j+(i-1)*nlevdecomp)
+ end do
+ end do
+ end do
+ end if
+
+ if( use_c14 ) then
+ do i=1,ndecomp_pools
+ do j = 1,nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cs14_soil%decomp_cpools_vr_col(c,j,i) = matrix_Cinter14%V(c,j+(i-1)*nlevdecomp)
+ end do
+ end do
+ end do
+ end if
+
+ call t_stopf('CN Soil matrix-assign back')
+
+ if(use_soil_matrixcn .and. (hist_wrt_matrixcn_diag .or. spinup_matrixcn))then
+
+ ! Accumulate C transfers during a whole calendar year to calculate the C and N capacity
+ do j=1,ndecomp_pools*nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cs_soil%in_acc (c,j) = cs_soil%in_acc (c,j) + matrix_Cinput%V(c,j)
+ ns_soil%in_nacc(c,j) = ns_soil%in_nacc(c,j) + matrix_Ninput%V(c,j)
+ end do
+ end do
+ if(use_c13)then
+ do j=1,ndecomp_pools*nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cs13_soil%in_acc (c,j) = cs13_soil%in_acc (c,j) + matrix_Cinput13%V(c,j)
+ end do
+ end do
+ end if
+ if(use_c14)then
+ do j=1,ndecomp_pools*nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cs14_soil%in_acc (c,j) = cs14_soil%in_acc (c,j) + matrix_Cinput14%V(c,j)
+ end do
+ end do
+ end if
+
+ if(use_c13)then
+ call cf13_soil%AKallsoilc%SetValueCopySM (num_soilc,filter_soilc,AKallsoilc)
+ end if
+
+! if(use_c14)then
+! call cf14_soil%AKallsoilc%SetValueCopySM (num_soilc,filter_soilc,AKallsoilc)
+! end if
+ ! Calculate all the soil C transfers in current time step.
+ ! After this step, AKallsoilc represents all the C transfers (gC/m3/step)
+ call Xdiagsoil%SetValueDM(begc,endc,num_soilc,filter_soilc,Cinter_old(begc:endc,1:ndecomp_pools_vr))
+ call AKallsoilc%SPMM_AK(num_soilc,filter_soilc,Xdiagsoil)
+
+ if(use_c13)then
+ call Xdiagsoil%SetValueDM(begc,endc,num_soilc,filter_soilc,C13inter_old(begc:endc,1:ndecomp_pools_vr))
+ call cf13_soil%AKallsoilc%SPMM_AK(num_soilc,filter_soilc,Xdiagsoil)
+ end if
+
+ if(use_c14)then
+ call Xdiagsoil%SetValueDM(begc,endc,num_soilc,filter_soilc,C14inter_old(begc:endc,1:ndecomp_pools_vr))
+ call cf14_soil%AKallsoilc%SPMM_AK(num_soilc,filter_soilc,Xdiagsoil)
+ end if
+
+ ! Calculate all the soil N transfers in current time step
+ ! After this step, AKallsoiln represents all the N transfers (gN/m3/step)
+ call Xdiagsoil%SetValueDM(begc,endc,num_soilc,filter_soilc,Ninter_old(begc:endc,1:ndecomp_pools_vr))
+ call AKallsoiln%SPMM_AK(num_soilc,filter_soilc,Xdiagsoil)
+
+ !
+ ! Accumulate soil C transfers: AKXcacc = AKXcacc + AKallsoilc
+ !
+ ! Copy indices from AKallsoilc on restart step
+ if ( is_first_restart_step() )then
+ call AKXcacc%CopyIdxSM( AKallsoilc )
+ end if
+ if ( AKXcacc%IsValuesSetSM() )then
+ call AKXcacc%SPMP_B_ACC(num_soilc,filter_soilc,AKallsoilc)
+ else
+ ! This should only happen on the first time-step
+ call AKXcacc%SetValueCopySM(num_soilc,filter_soilc,AKallsoilc)
+ end if
+
+ !
+ ! Accumulate soil C13 transfers: cs13_soil%AKXcacc = cs13_soil%AKXcacc + cs13_soil%AKallsoilc
+ !
+ ! Copy indices from AKallsoilc on restart step
+ if(use_c13)then
+ if ( is_first_restart_step() )then
+ call cs13_soil%AKXcacc%CopyIdxSM( cf13_soil%AKallsoilc )
+ end if
+ if ( cs13_soil%AKXcacc%IsValuesSetSM() )then
+ call cs13_soil%AKXcacc%SPMP_B_ACC(num_soilc,filter_soilc,cf13_soil%AKallsoilc)
+ else
+ ! This should only happen on the first time-step
+ call cs13_soil%AKXcacc%SetValueCopySM(num_soilc,filter_soilc,cf13_soil%AKallsoilc)
+ end if
+ end if
+
+ !
+ ! Accumulate soil C14 transfers: cs14_soil%AKXcacc = cs14_soil%AKXcacc + cs14_soil%AKallsoilc
+ !
+ ! Copy indices from AKallsoilc on restart step
+ if(use_c14)then
+ if ( is_first_restart_step() )then
+ call cs14_soil%AKXcacc%CopyIdxSM( cf14_soil%AKallsoilc )
+ end if
+ if ( cs14_soil%AKXcacc%IsValuesSetSM() )then
+ call cs14_soil%AKXcacc%SPMP_B_ACC(num_soilc,filter_soilc,cf14_soil%AKallsoilc)
+ else
+ ! This should only happen on the first time-step
+ call cs14_soil%AKXcacc%SetValueCopySM(num_soilc,filter_soilc,cf14_soil%AKallsoilc)
+ end if
+ end if
+
+ !
+ ! Accumulate soil N transfers: AKXnacc = AKXnacc + AKallsoiln
+ !
+ ! Copy indices from AKallsoiln on restart step
+ if ( is_first_restart_step() )then
+ call AKXnacc%CopyIdxSM( AKallsoiln )
+ end if
+ if ( AKXnacc%IsValuesSetSM() )then
+ call AKXnacc%SPMP_B_ACC(num_soilc,filter_soilc,AKallsoiln)
+ else
+ ! This should only happen on the first time-step
+ call AKXnacc%SetValueCopySM(num_soilc,filter_soilc,AKallsoiln)
+ end if
+
+ call t_startf('CN Soil matrix-calc. C capacity')
+ if((.not. spinup_matrixcn .and. is_end_curr_year()) .or. (spinup_matrixcn .and. is_end_curr_year() .and. mod(iyr,nyr_SASU) .eq. 0))then
+ ! Copy C transfers from sparse matrix to 2D temporary variables tran_acc and tran_nacc
+ ! Calculate the C and N transfer rate by dividing CN transfer by base value saved at begin of each year.
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cs_soil%tran_acc (c,1:ndecomp_pools_vr,1:ndecomp_pools_vr) = 0._r8
+ ns_soil%tran_nacc(c,1:ndecomp_pools_vr,1:ndecomp_pools_vr) = 0._r8
+ if(use_c13)then
+ cs13_soil%tran_acc (c,1:ndecomp_pools_vr,1:ndecomp_pools_vr) = 0._r8
+ end if
+ if(use_c14)then
+ cs14_soil%tran_acc (c,1:ndecomp_pools_vr,1:ndecomp_pools_vr) = 0._r8
+ end if
+ end do
+ do j=1,n_all_entries
+ j_lev = mod(all_j(j)-1,nlevdecomp)+1
+ j_decomp = (all_j(j) - j_lev)/nlevdecomp + 1
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cs_soil%tran_acc(c,all_i(j),all_j(j)) = AKXcacc%M(c,j) / cs_soil%decomp0_cpools_vr_col(c,j_lev,j_decomp)
+ ns_soil%tran_nacc(c,all_i(j),all_j(j)) = AKXnacc%M(c,j) / ns_soil%decomp0_npools_vr_col(c,j_lev,j_decomp)
+ if(use_c13)then
+ cs13_soil%tran_acc(c,all_i(j),all_j(j)) = cs13_soil%AKXcacc%M(c,j) / cs13_soil%decomp0_cpools_vr_col(c,j_lev,j_decomp)
+ end if
+ if(use_c14)then
+ cs14_soil%tran_acc(c,all_i(j),all_j(j)) = cs14_soil%AKXcacc%M(c,j) / cs14_soil%decomp0_cpools_vr_col(c,j_lev,j_decomp)
+ end if
+ end do
+ end do
+
+ do i=1,ndecomp_pools_vr
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ if (abs(cs_soil%tran_acc(c,i,i)) .le. epsi)then !avoid inversion nan
+ cs_soil%tran_acc(c,i,i) = 1.e+36_r8
+ end if
+ end do
+ end do
+
+ if(use_c13)then
+ do i=1,ndecomp_pools_vr
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ if (abs(cs13_soil%tran_acc(c,i,i)) .le. epsi)then !avoid inversion nan
+ cs13_soil%tran_acc(c,i,i) = 1.e+36_r8
+ end if
+ end do
+ end do
+ end if
+
+ if(use_c14)then
+ do i=1,ndecomp_pools_vr
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ if (abs(cs14_soil%tran_acc(c,i,i)) .le. epsi)then !avoid inversion nan
+ cs14_soil%tran_acc(c,i,i) = 1.e+36_r8
+ end if
+ end do
+ end do
+ end if
+
+ do i=1,ndecomp_pools_vr
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ if (abs(ns_soil%tran_nacc(c,i,i)) .le. epsi)then
+ ns_soil%tran_nacc(c,i,i) = 1.e+36_r8
+ end if
+ end do
+ end do
+
+ ! Calculate capacity
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ call inverse(cs_soil%tran_acc(c,1:ndecomp_pools_vr,1:ndecomp_pools_vr),AKinv(1:ndecomp_pools_vr,1:ndecomp_pools_vr),ndecomp_pools_vr)
+ soilmatrixc_cap(c,:,1) = -matmul(AKinv(1:ndecomp_pools_vr,1:ndecomp_pools_vr),cs_soil%in_acc(c,1:ndecomp_pools_vr))
+ if(use_c13)then
+ call inverse(cs13_soil%tran_acc(c,1:ndecomp_pools_vr,1:ndecomp_pools_vr),AKinv(1:ndecomp_pools_vr,1:ndecomp_pools_vr),ndecomp_pools_vr)
+ soilmatrixc13_cap(c,:,1) = -matmul(AKinv(1:ndecomp_pools_vr,1:ndecomp_pools_vr),cs13_soil%in_acc(c,1:ndecomp_pools_vr))
+ end if
+ if(use_c14)then
+ call inverse(cs14_soil%tran_acc(c,1:ndecomp_pools_vr,1:ndecomp_pools_vr),AKinv(1:ndecomp_pools_vr,1:ndecomp_pools_vr),ndecomp_pools_vr)
+ soilmatrixc14_cap(c,:,1) = -matmul(AKinv(1:ndecomp_pools_vr,1:ndecomp_pools_vr),cs14_soil%in_acc(c,1:ndecomp_pools_vr))
+ end if
+ call inverse(ns_soil%tran_nacc(c,1:ndecomp_pools_vr,1:ndecomp_pools_vr),AKinvn(1:ndecomp_pools_vr,1:ndecomp_pools_vr),ndecomp_pools_vr)
+ soilmatrixn_cap(c,:,1) = -matmul(AKinvn(1:ndecomp_pools_vr,1:ndecomp_pools_vr),ns_soil%in_nacc(c,1:ndecomp_pools_vr))
+ end do
+
+ do i = 1,ndecomp_pools
+ do j = 1,nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ if(soilmatrixc_cap(c,j+(i-1)*nlevdecomp,1) .lt. 0)then
+ soilmatrixc_cap(c,j+(i-1)*nlevdecomp,1) = 0._r8
+ endif
+ if(use_c13 .and. soilmatrixc13_cap(c,j+(i-1)*nlevdecomp,1) .lt. 0)then
+ soilmatrixc13_cap(c,j+(i-1)*nlevdecomp,1) = 0._r8
+ endif
+ if(use_c14 .and. soilmatrixc14_cap(c,j+(i-1)*nlevdecomp,1) .lt. 0)then
+ soilmatrixc14_cap(c,j+(i-1)*nlevdecomp,1) = 0._r8
+ endif
+ if(soilmatrixn_cap(c,j+(i-1)*nlevdecomp,1) .lt. 0)then
+ soilmatrixn_cap(c,j+(i-1)*nlevdecomp,1) = 0._r8
+ endif
+ end do
+ end do
+ end do
+
+
+ do i = 1,ndecomp_pools
+ do j = 1,nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ if(nyr_SASU .eq. nyr_forcing .and. &
+ (soilmatrixc_cap(c,j+(i-1)*nlevdecomp,1)/cs_soil%decomp0_cpools_vr_col(c,j,i) .gt. 100 .and. soilmatrixc_cap(c,j+(i-1)*nlevdecomp,1) .gt. 1.e+5_r8 &
+ .or. soilmatrixn_cap(c,j+(i-1)*nlevdecomp,1)/ns_soil%decomp0_npools_vr_col(c,j,i) .gt. 100 .and. soilmatrixn_cap(c,j+(i-1)*nlevdecomp,1) .gt. 1.e+3_r8) &
+ .or. nyr_SASU .lt. nyr_forcing .and. i .eq. i_cwd .and. &
+ (soilmatrixc_cap(c,j+(i-1)*nlevdecomp,1)/cs_soil%decomp0_cpools_vr_col(c,j,i) .gt. 100 .and. soilmatrixc_cap(c,j+(i-1)*nlevdecomp,1) .gt. 1.e+5_r8 &
+ .or. soilmatrixn_cap(c,j+(i-1)*nlevdecomp,1)/ns_soil%decomp0_npools_vr_col(c,j,i) .gt. 100 .and. soilmatrixn_cap(c,j+(i-1)*nlevdecomp,1) .gt. 1.e+3_r8) )then
+ soilmatrixc_cap(c,j+(i-1)*nlevdecomp,1) = matrix_Cinter%V(c,j+(i-1)*nlevdecomp)
+ if(use_c13)then
+ soilmatrixc13_cap(c,j+(i-1)*nlevdecomp,1) = matrix_Cinter13%V(c,j+(i-1)*nlevdecomp)
+ end if
+ if(use_c14)then
+ soilmatrixc14_cap(c,j+(i-1)*nlevdecomp,1) = matrix_Cinter14%V(c,j+(i-1)*nlevdecomp)
+ end if
+ soilmatrixn_cap(c,j+(i-1)*nlevdecomp,1) = matrix_Ninter%V(c,j+(i-1)*nlevdecomp)
+ end if
+ end do
+ end do
+ end do
+
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ if(any(soilmatrixc_cap(c,:,1) .gt. 1.e+8_r8) .or. any(soilmatrixn_cap(c,:,1) .gt. 1.e+8_r8))then
+ soilmatrixc_cap(c,:,1) = matrix_Cinter%V(c,:)
+ if(use_c13)then
+ soilmatrixc13_cap(c,:,1) = matrix_Cinter13%V(c,:)
+ end if
+ if(use_c14)then
+ soilmatrixc14_cap(c,:,1) = matrix_Cinter14%V(c,:)
+ end if
+ soilmatrixn_cap(c,:,1) = matrix_Ninter%V(c,:)
+ end if
+ end do
+
+ ! If spin up is on, the capacity replaces the pool size with capacity.
+ ! Copy the capacity into a 3D variable, and be ready to write to history files.
+ do i=1,ndecomp_pools
+ do j = 1,nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ if(spinup_matrixcn .and. .not. is_first_step_of_this_run_segment())then
+ cs_soil%decomp_cpools_vr_col(c,j,i) = soilmatrixc_cap(c,j+(i-1)*nlevdecomp,1)
+ if(use_c13)then
+ cs13_soil%decomp_cpools_vr_col(c,j,i) = soilmatrixc13_cap(c,j+(i-1)*nlevdecomp,1)
+ end if
+ if(use_c14)then
+ cs14_soil%decomp_cpools_vr_col(c,j,i) = soilmatrixc14_cap(c,j+(i-1)*nlevdecomp,1)
+ end if
+ if(floating_cn_ratio_decomp_pools(i))then
+ ns_soil%decomp_npools_vr_col(c,j,i) = soilmatrixn_cap(c,j+(i-1)*nlevdecomp,1)
+ else
+ ns_soil%decomp_npools_vr_col(c,j,i) = cs_soil%decomp_cpools_vr_col(c,j,i) / cn_decomp_pools(c,j,i)
+ end if
+ ! calculate the average of the storage capacity when iloop equals to iloop_avg
+ if(iloop .eq. iloop_avg)then
+ cs_soil%decomp_cpools_vr_SASUsave_col(c,j,i) = cs_soil%decomp_cpools_vr_SASUsave_col(c,j,i) + cs_soil%decomp_cpools_vr_col(c,j,i)
+ if(use_c13)then
+ cs13_soil%decomp_cpools_vr_SASUsave_col(c,j,i) = cs13_soil%decomp_cpools_vr_SASUsave_col(c,j,i) + cs13_soil%decomp_cpools_vr_col(c,j,i)
+ end if
+ if(use_c14)then
+ cs14_soil%decomp_cpools_vr_SASUsave_col(c,j,i) = cs14_soil%decomp_cpools_vr_SASUsave_col(c,j,i) + cs14_soil%decomp_cpools_vr_col(c,j,i)
+ end if
+ ns_soil%decomp_npools_vr_SASUsave_col(c,j,i) = ns_soil%decomp_npools_vr_SASUsave_col(c,j,i) + ns_soil%decomp_npools_vr_col(c,j,i)
+ if(iyr .eq. nyr_forcing)then
+ cs_soil%decomp_cpools_vr_col(c,j,i) = cs_soil%decomp_cpools_vr_SASUsave_col(c,j,i) / (nyr_forcing/nyr_SASU)
+ if(use_c13)then
+ cs13_soil%decomp_cpools_vr_col(c,j,i) = cs13_soil%decomp_cpools_vr_SASUsave_col(c,j,i) / (nyr_forcing/nyr_SASU)
+ end if
+ if(use_c14)then
+ cs14_soil%decomp_cpools_vr_col(c,j,i) = cs14_soil%decomp_cpools_vr_SASUsave_col(c,j,i) / (nyr_forcing/nyr_SASU)
+ end if
+ ns_soil%decomp_npools_vr_col(c,j,i) = ns_soil%decomp_npools_vr_SASUsave_col(c,j,i) / (nyr_forcing/nyr_SASU)
+ cs_soil%decomp_cpools_vr_SASUsave_col(c,j,i) = 0._r8
+ if(use_c13)then
+ cs13_soil%decomp_cpools_vr_SASUsave_col(c,j,i) = 0._r8
+ end if
+ if(use_c14)then
+ cs14_soil%decomp_cpools_vr_SASUsave_col(c,j,i) = 0._r8
+ end if
+ ns_soil%decomp_npools_vr_SASUsave_col(c,j,i) = 0._r8
+ end if
+ end if
+ end if
+ cs_soil%matrix_cap_decomp_cpools_vr_col(c,j,i) = soilmatrixc_cap(c,j+(i-1)*nlevdecomp,1)
+ if(use_c13)then
+ cs13_soil%matrix_cap_decomp_cpools_vr_col(c,j,i) = soilmatrixc13_cap(c,j+(i-1)*nlevdecomp,1)
+ end if
+ if(use_c14)then
+ cs14_soil%matrix_cap_decomp_cpools_vr_col(c,j,i) = soilmatrixc14_cap(c,j+(i-1)*nlevdecomp,1)
+ end if
+ ns_soil%matrix_cap_decomp_npools_vr_col(c,j,i) = soilmatrixn_cap(c,j+(i-1)*nlevdecomp,1)
+ end do
+ end do
+ end do
+
+ if(spinup_matrixcn)call update_DA_nstep()
+ if(iloop .eq. iloop_avg .and. iyr .eq. nyr_forcing)iloop = 0
+ if(iyr .eq. nyr_forcing)iyr = 0
+
+ ! Reset to accumulation variables to 0 at end of each year
+ do j=1,n_all_entries
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ AKXcacc%M(c,j) = 0._r8
+ if(use_c13)then
+ cs13_soil%AKXcacc%M(c,j) = 0._r8
+ end if
+ if(use_c14)then
+ cs14_soil%AKXcacc%M(c,j) = 0._r8
+ end if
+ AKXnacc%M(c,j) = 0._r8
+ end do
+ end do
+
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cs_soil%in_acc (c,:) = 0._r8
+ if(use_c13)then
+ cs13_soil%in_acc (c,:) = 0._r8
+ end if
+ if(use_c14)then
+ cs14_soil%in_acc (c,:) = 0._r8
+ end if
+ ns_soil%in_nacc (c,:) = 0._r8
+ end do
+ end if
+ call t_stopf('CN Soil matrix-calc. C capacity')
+ end if !is out_matrix
+
+ end associate
+ end subroutine CNSoilMatrix
+
+ !-----------------------------------------------------------------------
+ subroutine CNSoilMatrixRest( ncid, flag )
+ ! !DESCRIPTION:
+ !
+ ! Read/write restart data needed for the CN soil Matrix model solution
+ !
+ ! !USES:
+ use restUtilMod , only: restartvar
+ use ncdio_pio , only: file_desc_t, ncd_int
+ !
+ ! !ARGUMENTS:
+ type(file_desc_t) , intent(inout) :: ncid ! netcdf id
+ character(len=*) , intent(in) :: flag !'read' or 'write'
+ !
+ ! !LOCAL VARIABLES:
+ logical :: readvar ! determine if variable is on initial file
+ !------------------------------------------------------------------------
+ call restartvar(ncid=ncid, flag=flag, varname='soil_cycle_year', xtype=ncd_int, &
+ long_name='Year number in soil spinup cycle sequence', units='years', &
+ interpinic_flag='skip', readvar=readvar, data=iyr)
+
+ call restartvar(ncid=ncid, flag=flag, varname='soil_cycle_loop', xtype=ncd_int, &
+ long_name='Loop number in soil spinup cycle sequence', units='years', &
+ interpinic_flag='skip', readvar=readvar, data=iloop)
+
+ !------------------------------------------------------------------------
+ end subroutine CNSoilMatrixRest
+
+end module CNSoilMatrixMod
+
diff --git a/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 b/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90
index 2cb28f04e9..23f24e44d5 100644
--- a/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90
+++ b/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90
@@ -3,8 +3,8 @@ module SoilBiogeochemCarbonFluxType
use shr_kind_mod , only : r8 => shr_kind_r8
use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
use decompMod , only : bounds_type
- use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_pools, nlevcan
- use clm_varpar , only : nlevdecomp_full, nlevgrnd, nlevdecomp, nlevsoi, i_cwdl2
+ use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_pools, ndecomp_cascade_outtransitions
+ use clm_varpar , only : nlevdecomp_full, nlevgrnd, nlevdecomp, nlevsoi, ndecomp_pools_vr, i_cwdl2
use clm_varcon , only : spval, ispval, dzsoi_decomp
use clm_varctl , only : use_fates,use_cn
use pftconMod , only : pftcon
@@ -40,6 +40,7 @@ module SoilBiogeochemCarbonFluxType
real(r8), pointer :: rf_decomp_cascade_col (:,:,:) ! (frac) respired fraction in decomposition step
real(r8), pointer :: pathfrac_decomp_cascade_col (:,:,:) ! (frac) what fraction of C passes from donor to receiver pool through a given transition
real(r8), pointer :: decomp_k_col (:,:,:) ! rate coefficient for decomposition (1./sec)
+ ! foi soil-matrix
real(r8), pointer :: hr_vr_col (:,:) ! (gC/m3/s) total vertically-resolved het. resp. from decomposing C pools
real(r8), pointer :: o_scalar_col (:,:) ! fraction by which decomposition is limited by anoxia
real(r8), pointer :: w_scalar_col (:,:) ! fraction by which decomposition is limited by moisture availability
@@ -61,8 +62,25 @@ module SoilBiogeochemCarbonFluxType
real(r8), pointer :: fates_litter_flux (:) ! (gC/m2/s) A summary of the total litter
! flux passed in from FATES.
! This is a diagnostic for balance checks only
+ ! track tradiagonal matrix
+ real(r8), pointer :: matrix_decomp_fire_k_col (:,:) ! decomposition rate due to fire (gC*m3)/(gC*m3*step))
+ real(r8), pointer :: tri_ma_vr (:,:) ! vertical C transfer rate in sparse matrix format (gC*m3)/(gC*m3*step))
+
+ type(sparse_matrix_type) :: AKsoilc ! A*K for C transfers between pools
+ type(sparse_matrix_type) :: AVsoil ! V for C and N transfers between soil layers
+ type(sparse_matrix_type) :: AKfiresoil ! Kfire for CN transfers from soil to atm due to fire
+ type(sparse_matrix_type) :: AKallsoilc ! (A*K+V-Kfire) for soil C cycle
+ integer :: NE_AKallsoilc ! Number of entries in AKallsoilc, Automatically generated by functions SPMP_*
+ integer,pointer,dimension(:) :: RI_AKallsoilc ! Row numbers of entries in AKallsoilc, Automatically generated by functions SPMP_*
+ integer,pointer,dimension(:) :: CI_AKallsoilc ! Column numbers of entries in AKallsoilc, Automatically generated by functions SPMP_*
+ integer,pointer,dimension(:) :: RI_a ! Row numbers of all entries from AKsoilc, Automatically generated by SetValueA
+ integer,pointer,dimension(:) :: CI_a ! Column numbers of all entries from AKsoilc, Automatically generated by SetValueA
+
+ type(diag_matrix_type) :: Ksoil ! CN turnover rate in different soil pools and layers
+ type(diag_matrix_type) :: Xdiagsoil ! Temporary C and N state variable to calculate accumulation transfers
+
+ type(vector_type) :: matrix_Cinput ! C input to different soil compartments (pools and layers) (gC/m3/step)
-
contains
procedure , public :: Init
@@ -168,6 +186,25 @@ subroutine InitAllocate(this, bounds)
end if
if(use_soil_matrixcn)then
+ allocate(this%matrix_decomp_fire_k_col(begc:endc,1:nlevdecomp*ndecomp_pools)); this%matrix_decomp_fire_k_col(:,:)= nan
+ Ntrans = (ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)*nlevdecomp
+ call this%AKsoilc%InitSM (ndecomp_pools*nlevdecomp,begc,endc,Ntrans+ndecomp_pools*nlevdecomp)
+ call this%AVsoil%InitSM (ndecomp_pools*nlevdecomp,begc,endc,decomp_cascade_con%Ntri_setup)
+ call this%AKfiresoil%InitSM (ndecomp_pools*nlevdecomp,begc,endc,ndecomp_pools*nlevdecomp)
+ call this%AKallsoilc%InitSM (ndecomp_pools*nlevdecomp,begc,endc,Ntrans+decomp_cascade_con%Ntri_setup+nlevdecomp)
+ this%NE_AKallsoilc = Ntrans+ndecomp_pools*nlevdecomp+decomp_cascade_con%Ntri_setup+ndecomp_pools*nlevdecomp
+ allocate(this%RI_AKallsoilc(1:this%NE_AKallsoilc)); this%RI_AKallsoilc(1:this%NE_AKallsoilc)=-9999
+ allocate(this%CI_AKallsoilc(1:this%NE_AKallsoilc)); this%CI_AKallsoilc(1:this%NE_AKallsoilc)=-9999
+ Ntrans_diag = (ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)*nlevdecomp+ndecomp_pools_vr
+ allocate(this%RI_a(1:Ntrans_diag)); this%RI_a(1:Ntrans_diag) = -9999
+ allocate(this%CI_a(1:Ntrans_diag)); this%CI_a(1:Ntrans_diag) = -9999
+ call this%Ksoil%InitDM (ndecomp_pools*nlevdecomp,begc,endc)
+ call this%Xdiagsoil%InitDM (ndecomp_pools*nlevdecomp,begc,endc)
+ call this%matrix_Cinput%InitV(ndecomp_pools*nlevdecomp,begc,endc)
+
+ allocate(this%tri_ma_vr(begc:endc,1:decomp_cascade_con%Ntri_setup))
+ else
+ allocate(this%tri_ma_vr(1,1)); this%tri_ma_vr(:,:) = nan
end if
allocate(this%litr_lig_c_to_n_col(begc:endc))
@@ -724,6 +761,22 @@ subroutine SetValues ( this, num_column, filter_column, value_column)
! for matrix
if(use_soil_matrixcn)then
+ do k = 1, ndecomp_pools
+ do j = 1, nlevdecomp
+ do fi = 1,num_column
+ i = filter_column(fi)
+ this%matrix_decomp_fire_k_col(i,j+nlevdecomp*(k-1)) = value_column
+ end do
+ end do
+ end do
+ call this%matrix_Cinput%SetValueV_scaler(num_column,filter_column(1:num_column),value_column)
+ !
+ do k = 1,decomp_cascade_con%Ntri_setup
+ do fi = 1,num_column
+ i = filter_column(fi)
+ this%tri_ma_vr(i,k) = value_column
+ end do
+ end do
end if
do j = 1, nlevdecomp_full
do fi = 1,num_column
diff --git a/src/soilbiogeochem/SoilBiogeochemCarbonStateType.F90 b/src/soilbiogeochem/SoilBiogeochemCarbonStateType.F90
index de269a4c78..768811925d 100644
--- a/src/soilbiogeochem/SoilBiogeochemCarbonStateType.F90
+++ b/src/soilbiogeochem/SoilBiogeochemCarbonStateType.F90
@@ -27,6 +27,8 @@ module SoilBiogeochemCarbonStateType
! all c pools involved in decomposition
real(r8), pointer :: decomp_cpools_vr_col (:,:,:) ! (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
+ real(r8), pointer :: decomp0_cpools_vr_col(:,:,:) ! (gC/m3) vertically-resolved C baseline (initial value of this year) in decomposing (litter, cwd, soil) pools in dimension (col,nlev,npools)
+ real(r8), pointer :: decomp_cpools_vr_SASUsave_col(:,:,:) ! (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
real(r8), pointer :: decomp_soilc_vr_col (:,:) ! (gC/m3) vertically-resolved decomposing total soil c pool
real(r8), pointer :: ctrunc_vr_col (:,:) ! (gC/m3) vertically-resolved column-level sink for C truncation
@@ -54,6 +56,17 @@ module SoilBiogeochemCarbonStateType
! Matrix-cn
+ real(r8), pointer :: matrix_cap_decomp_cpools_col (:,:) ! (gC/m2) C capacity in decomposing (litter, cwd, soil) N pools in dimension (col,npools)
+ real(r8), pointer :: matrix_cap_decomp_cpools_vr_col (:,:,:) ! (gC/m3) vertically-resolved C capacity in decomposing (litter, cwd, soil) pools in dimension(col,nlev,npools)
+ real(r8), pointer :: in_acc (:,:) ! (gC/m3/yr) accumulated litter fall C input per year in dimension(col,nlev*npools)
+ real(r8), pointer :: in_acc_2d (:,:,:) ! (gC/m3/yr) accumulated litter fall C input per year in dimension(col,nlev,npools)
+ real(r8), pointer :: tran_acc (:,:,:) ! (gC/m3/yr) accumulated C transfers from j to i (col,i,j) per year in dimension(col,nlev*npools,nlev*npools)
+ real(r8), pointer :: vert_up_tran_acc (:,:,:) ! (gC/m3/yr) accumulated upward vertical C transport in dimension(col,nlev,npools)
+ real(r8), pointer :: vert_down_tran_acc (:,:,:) ! (gC/m3/yr) accumulated downward vertical C transport in dimension(col,nlev,npools)
+ real(r8), pointer :: exit_acc (:,:,:) ! (gC/m3/yr) accumulated exit C in dimension(col,nlev,npools)
+ real(r8), pointer :: hori_tran_acc (:,:,:) ! (gC/m3/yr) accumulated C transport between pools at the same level in dimension(col,nlev,ntransfers)
+ type(sparse_matrix_type) :: AKXcacc ! (gC/m3/yr) accumulated N transfers from j to i (col,i,j) per year in dimension(col,nlev*npools,nlev*npools) in sparse matrix type
+ type(vector_type) :: matrix_Cinter ! (gC/m3) vertically-resolved decomposing (litter, cwd, soil) N pools in dimension(col,nlev*npools) in vector type
contains
@@ -113,17 +126,41 @@ subroutine InitAllocate(this, bounds)
allocate( this%decomp_cpools_col (begc :endc,1:ndecomp_pools)) ; this%decomp_cpools_col (:,:) = nan
allocate( this%decomp_cpools_1m_col (begc :endc,1:ndecomp_pools)) ; this%decomp_cpools_1m_col (:,:) = nan
+ if(use_soil_matrixcn)then
+ allocate( this%matrix_cap_decomp_cpools_col (begc :endc,1:ndecomp_pools)) ; this%matrix_cap_decomp_cpools_col (:,:) = nan
+ end if
allocate( this%ctrunc_vr_col(begc :endc,1:nlevdecomp_full)) ;
this%ctrunc_vr_col (:,:) = nan
allocate(this%decomp_cpools_vr_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
this%decomp_cpools_vr_col(:,:,:)= nan
-
- ! Matrix-spinup
+ !matrix-spinup
if(use_soil_matrixcn)then
+ allocate(this%matrix_cap_decomp_cpools_vr_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%matrix_cap_decomp_cpools_vr_col(:,:,:)= nan
+ allocate(this%decomp0_cpools_vr_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%decomp0_cpools_vr_col(:,:,:)= nan
+ allocate(this%decomp_cpools_vr_SASUsave_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%decomp_cpools_vr_SASUsave_col(:,:,:)= nan
+ allocate(this%in_acc(begc:endc,1:nlevdecomp*ndecomp_pools))
+ this%in_acc(:,:)= nan
+ allocate(this%tran_acc(begc:endc,1:nlevdecomp*ndecomp_pools,1:nlevdecomp*ndecomp_pools))
+ this%tran_acc(:,:,:)= nan
+
+ allocate(this%in_acc_2d(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%in_acc_2d(:,:,:)= nan
+ allocate(this%vert_up_tran_acc(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%vert_up_tran_acc(:,:,:)= nan
+ allocate(this%vert_down_tran_acc(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%vert_down_tran_acc(:,:,:)= nan
+ allocate(this%exit_acc(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%exit_acc(:,:,:)= nan
+ allocate(this%hori_tran_acc(begc:endc,1:nlevdecomp_full,1:ndecomp_cascade_transitions))
+ this%hori_tran_acc(:,:,:)= nan
+ call this%AKXcacc%InitSM(ndecomp_pools*nlevdecomp,begc,endc,decomp_cascade_con%n_all_entries)
+ call this%matrix_Cinter%InitV (ndecomp_pools*nlevdecomp,begc,endc)
end if
-
allocate(this%decomp_soilc_vr_col(begc:endc,1:nlevdecomp_full))
this%decomp_soilc_vr_col(:,:)= nan
@@ -217,11 +254,24 @@ subroutine InitHistory(this, bounds, carbon_type)
! Matrix solution history fields
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_col(begc:endc,:) = spval
do l = 1, ndecomp_pools
if ( nlevdecomp_full > 1 ) then
+ data2dptr => this%matrix_cap_decomp_cpools_vr_col(:,1:nlevsoi,l)
+ fieldname = trim(decomp_cascade_con%decomp_pool_name_history(l))//'C_Cap_vr'
+ longname = trim(decomp_cascade_con%decomp_pool_name_history(l))//' C capacity (vertically resolved)'
+ call hist_addfld2d (fname=fieldname, units='gC/m^3', type2d='levsoi', &
+ avgflag='I', long_name=longname, &
+ ptr_col=data2dptr)
endif
if ( nlevdecomp_full .eq. 1)then
+ data1dptr => this%matrix_cap_decomp_cpools_col(:,l)
+ fieldname = trim(decomp_cascade_con%decomp_pool_name_history(l))//'C_Cap'
+ longname = trim(decomp_cascade_con%decomp_pool_name_history(l))//' C capacity'
+ call hist_addfld1d (fname=fieldname, units='gC/m^2', &
+ avgflag='I', long_name=longname, &
+ ptr_col=data1dptr)
end if
end do
@@ -317,11 +367,24 @@ subroutine InitHistory(this, bounds, carbon_type)
! Matrix solution history fields
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_vr_col(begc:endc,:,:) = spval
do l = 1, ndecomp_pools
if ( nlevdecomp_full > 1 ) then
+ data2dptr => this%matrix_cap_decomp_cpools_vr_col(:,1:nlevsoi,l)
+ fieldname = 'C13_'//trim(decomp_cascade_con%decomp_pool_name_history(l))//'C_Cap_vr'
+ longname = 'C13 '//trim(decomp_cascade_con%decomp_pool_name_history(l))//' C capacity (vertically resolved)'
+ call hist_addfld2d (fname=fieldname, units='gC13/m^3', type2d='levsoi', &
+ avgflag='I', long_name=longname, &
+ ptr_col=data2dptr, default='inactive')
endif
if ( nlevdecomp_full .eq. 1)then
+ data1dptr => this%matrix_cap_decomp_cpools_col(:,l)
+ fieldname = 'C13_'//trim(decomp_cascade_con%decomp_pool_name_history(l))//'C_Cap'
+ longname = 'C13 '//trim(decomp_cascade_con%decomp_pool_name_history(l))//' C capacity'
+ call hist_addfld1d (fname=fieldname, units='gC13/m^2', &
+ avgflag='I', long_name=longname, &
+ ptr_col=data1dptr)
end if
end do
end if
@@ -420,11 +483,22 @@ subroutine InitHistory(this, bounds, carbon_type)
end if
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_vr_col(begc:endc,:,:) = spval
do l = 1, ndecomp_pools
if ( nlevdecomp_full > 1 ) then
+ data2dptr => this%matrix_cap_decomp_cpools_vr_col(:,1:nlevsoi,l)
+ fieldname = 'C14_'//trim(decomp_cascade_con%decomp_pool_name_history(l))//'C_Cap_vr'
+ longname = 'C14 '//trim(decomp_cascade_con%decomp_pool_name_history(l))//' C capacity (vertically resolved)'
+ call hist_addfld2d (fname=fieldname, units='gC14/m^3', type2d='levsoi', &
+ avgflag='I', long_name=longname, ptr_col=data2dptr, default='inactive')
endif
if ( nlevdecomp_full .eq. 1)then
+ data1dptr => this%matrix_cap_decomp_cpools_col(:,l)
+ fieldname = 'C14_'//trim(decomp_cascade_con%decomp_pool_name_history(l))//'C_Cap'
+ longname = 'C14 '//trim(decomp_cascade_con%decomp_pool_name_history(l))//' C capacity'
+ call hist_addfld1d (fname=fieldname, units='gC14/m^2', &
+ avgflag='I', long_name=longname, ptr_col=data1dptr)
end if
end do
end if
@@ -502,8 +576,10 @@ subroutine InitCold(this, bounds, ratio, c12_soilbiogeochem_carbonstate_inst)
do c = bounds%begc, bounds%endc
l = col%landunit(c)
- ! matrix-spinup
+ ! matrix spinup
if(use_soil_matrixcn)then
+ this%in_acc(c,:) = 0._r8
+ this%AKXcacc%M(c,:) = 0._r8
end if
if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then
@@ -514,10 +590,12 @@ subroutine InitCold(this, bounds, ratio, c12_soilbiogeochem_carbonstate_inst)
if (zsoi(j) < decomp_cascade_con%initial_stock_soildepth ) then !! only initialize upper soil column
this%decomp_cpools_vr_col(c,j,k) = decomp_cascade_con%initial_stock(k)
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_vr_col(c,j,k) = decomp_cascade_con%initial_stock(k)
end if
else
this%decomp_cpools_vr_col(c,j,k) = 0._r8
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_vr_col(c,j,k) = 0._r8
end if
endif
end do
@@ -528,6 +606,7 @@ subroutine InitCold(this, bounds, ratio, c12_soilbiogeochem_carbonstate_inst)
do k = 1, ndecomp_pools
this%decomp_cpools_vr_col(c,j,k) = 0._r8
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_vr_col(c,j,k) = 0._r8
end if
end do
this%ctrunc_vr_col(c,j) = 0._r8
@@ -536,6 +615,7 @@ subroutine InitCold(this, bounds, ratio, c12_soilbiogeochem_carbonstate_inst)
this%decomp_cpools_col(c,1:ndecomp_pools) = decomp_cascade_con%initial_stock(1:ndecomp_pools)
this%decomp_cpools_1m_col(c,1:ndecomp_pools) = decomp_cascade_con%initial_stock(1:ndecomp_pools)
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_col(c,1:ndecomp_pools) = decomp_cascade_con%initial_stock(1:ndecomp_pools)
end if
else
@@ -544,6 +624,7 @@ subroutine InitCold(this, bounds, ratio, c12_soilbiogeochem_carbonstate_inst)
do k = 1, ndecomp_pools
this%decomp_cpools_vr_col(c,j,k) = c12_soilbiogeochem_carbonstate_inst%decomp_cpools_vr_col(c,j,k) * ratio
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_vr_col(c,j,k) = c12_soilbiogeochem_carbonstate_inst%matrix_cap_decomp_cpools_vr_col(c,j,k) * ratio
end if
end do
this%ctrunc_vr_col(c,j) = c12_soilbiogeochem_carbonstate_inst%ctrunc_vr_col(c,j) * ratio
@@ -553,6 +634,7 @@ subroutine InitCold(this, bounds, ratio, c12_soilbiogeochem_carbonstate_inst)
do k = 1, ndecomp_pools
this%decomp_cpools_vr_col(c,j,k) = 0._r8
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_vr_col(c,j,k) = 0._r8
end if
end do
this%ctrunc_vr_col(c,j) = 0._r8
@@ -562,11 +644,28 @@ subroutine InitCold(this, bounds, ratio, c12_soilbiogeochem_carbonstate_inst)
this%decomp_cpools_col(c,k) = c12_soilbiogeochem_carbonstate_inst%decomp_cpools_col(c,k) * ratio
this%decomp_cpools_1m_col(c,k) = c12_soilbiogeochem_carbonstate_inst%decomp_cpools_1m_col(c,k) * ratio
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_col(c,k) = c12_soilbiogeochem_carbonstate_inst%matrix_cap_decomp_cpools_col(c,k) * ratio
end if
end do
endif
if(use_soil_matrixcn)then
+ do j = 1, nlevdecomp_full
+ do k = 1, ndecomp_pools
+ this%in_acc_2d(c,j,k) = 0._r8
+ this%vert_up_tran_acc(c,j,k) = 0._r8
+ this%vert_down_tran_acc(c,j,k) = 0._r8
+ this%exit_acc(c,j,k) = 0._r8
+ this%decomp0_cpools_vr_col(c,j,k) = max(this%decomp_cpools_vr_col(c,j,k),1.e-30_r8)
+ this%decomp_cpools_vr_SASUsave_col(c,j,k) = 0._r8
+ end do
+ do k = 1, ndecomp_cascade_transitions
+ this%hori_tran_acc(c,j,k) = 0._r8
+ end do
+ end do
+ do j = 1,decomp_cascade_con%n_all_entries
+ this%AKXcacc%M(c,j) = 0._r8
+ end do
end if
end if
@@ -669,6 +768,126 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, totvegc_col, c12_so
end do
if (use_soil_matrixcn)then
+ do k = 1, ndecomp_pools
+ varname=trim(decomp_cascade_con%decomp_pool_name_restart(k))//'c'
+ ptr2d => this%matrix_cap_decomp_cpools_vr_col(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_Cap_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%decomp0_cpools_vr_col(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"0_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ end do
+ if(flag=='write')then
+ do i = 1,ndecomp_pools
+ do j = 1,nlevdecomp
+ this%in_acc_2d(:,j,i) = this%in_acc(:,j+(i-1)*nlevdecomp)
+ end do
+ end do
+ do i = 1,decomp_cascade_con%n_all_entries
+ found = .false.
+ j_lev = mod(decomp_cascade_con%all_j(i) - 1,nlevdecomp) + 1
+ j_decomp = (decomp_cascade_con%all_j(i) - j_lev)/nlevdecomp + 1
+ i_lev = mod(decomp_cascade_con%all_i(i) - 1,nlevdecomp) + 1
+ i_decomp = (decomp_cascade_con%all_i(i) - i_lev)/nlevdecomp + 1
+ if(i_decomp .eq. j_decomp .and. j_lev - i_lev .eq. 1)then
+ this%vert_up_tran_acc(:,i_lev,i_decomp) = this%AKXcacc%M(:,i)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev - j_lev .eq. 1)then
+ this%vert_down_tran_acc(:,i_lev,i_decomp) = this%AKXcacc%M(:,i)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev .eq. j_lev)then
+ this%exit_acc(:,i_lev,i_decomp) = this%AKXcacc%M(:,i)
+ found = .true.
+ else
+ do k=1,ndecomp_cascade_transitions
+ if(i_decomp .ne. j_decomp .and. i_lev .eq. j_lev .and. &
+ i_decomp .eq. decomp_cascade_con%cascade_receiver_pool(k) .and. &
+ j_decomp .eq. decomp_cascade_con%cascade_donor_pool(k) .and. .not. found)then
+ this%hori_tran_acc(:,i_lev,k) = this%AKXcacc%M(:,i)
+ found = .true.
+ end if
+ end do
+ end if
+ end if
+ end if
+ if(.not. found) write(iulog,*) 'Error in storing matrix restart variables',i
+ end do
+ end if
+ do k = 1, ndecomp_pools
+ varname=trim(decomp_cascade_con%decomp_pool_name_restart(k))//'c'
+ ptr2d => this%in_acc_2d(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_input_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%vert_up_tran_acc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_vert_up_tran_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%vert_down_tran_acc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_vert_down_tran_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%exit_acc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_exit_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ end do
+ do i = 1, ndecomp_cascade_transitions
+ varname=trim(decomp_cascade_con%cascade_step_name(i))//'c'
+ ptr2d => this%hori_tran_acc(:,:,i)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_hori_tran_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ end do
+ if(flag=='read')then
+ do i = 1,ndecomp_pools
+ do j = 1,nlevdecomp
+ this%in_acc(:,j+(i-1)*nlevdecomp) = this%in_acc_2d(:,j,i)
+ end do
+ end do
+ do i = 1,decomp_cascade_con%n_all_entries
+ found = .false.
+ j_lev = mod(decomp_cascade_con%all_j(i) - 1,nlevdecomp) + 1
+ j_decomp = (decomp_cascade_con%all_j(i) - j_lev)/nlevdecomp + 1
+ i_lev = mod(decomp_cascade_con%all_i(i) - 1,nlevdecomp) + 1
+ i_decomp = (decomp_cascade_con%all_i(i) - i_lev)/nlevdecomp + 1
+ if(i_decomp .eq. j_decomp .and. j_lev - i_lev .eq. 1)then
+ this%AKXcacc%M(:,i) = this%vert_up_tran_acc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev - j_lev .eq. 1)then
+ this%AKXcacc%M(:,i) = this%vert_down_tran_acc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev .eq. j_lev)then
+ this%AKXcacc%M(:,i) = this%exit_acc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ do k=1,ndecomp_cascade_transitions
+ if(i_decomp .ne. j_decomp .and. i_lev .eq. j_lev .and. &
+ i_decomp .eq. decomp_cascade_con%cascade_receiver_pool(k) .and. &
+ j_decomp .eq. decomp_cascade_con%cascade_donor_pool(k) .and. .not. found)then
+ this%AKXcacc%M(:,i) = this%hori_tran_acc(:,i_lev,k)
+ found = .true.
+ end if
+ end do
+ end if
+ end if
+ end if
+ if(.not. found) write(iulog,*) 'Error in storing matrix restart variables',i
+ end do
+ end if
end if
ptr2d => this%ctrunc_vr_col
@@ -699,6 +918,16 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, totvegc_col, c12_so
scale_by_thickness=.false., &
interpinic_flag='interp', readvar=readvar, data=ptr2d)
if(use_soil_matrixcn)then
+ ptr2d => this%matrix_cap_decomp_cpools_vr_col(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_Cap_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%decomp0_cpools_vr_col(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"0_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
end if
if (flag=='read' .and. .not. readvar) then
write(iulog,*) 'initializing soilbiogeochem_carbonstate_inst%decomp_cpools_vr_col' &
@@ -709,6 +938,9 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, totvegc_col, c12_so
this%decomp_cpools_vr_col(i,j,k) = c12_soilbiogeochem_carbonstate_inst%decomp_cpools_vr_col(i,j,k) * c3_r2
endif
if(use_soil_matrixcn)then
+ if (this%matrix_cap_decomp_cpools_vr_col(i,j,k) /= spval .and. .not. isnan(this%matrix_cap_decomp_cpools_vr_col(i,j,k)) ) then
+ this%matrix_cap_decomp_cpools_vr_col(i,j,k) = c12_soilbiogeochem_carbonstate_inst%matrix_cap_decomp_cpools_vr_col(i,j,k) * c3_r2
+ endif
end if
end do
end do
@@ -716,6 +948,113 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, totvegc_col, c12_so
end do
if (use_soil_matrixcn)then
+ if(flag=='write')then
+ do i = 1,ndecomp_pools
+ do j = 1,nlevdecomp
+ this%in_acc_2d(:,j,i) = this%in_acc(:,j+(i-1)*nlevdecomp)
+ end do
+ end do
+ do i = 1,decomp_cascade_con%n_all_entries
+ found = .false.
+ j_lev = mod(decomp_cascade_con%all_j(i) - 1,nlevdecomp) + 1
+ j_decomp = (decomp_cascade_con%all_j(i) - j_lev)/nlevdecomp + 1
+ i_lev = mod(decomp_cascade_con%all_i(i) - 1,nlevdecomp) + 1
+ i_decomp = (decomp_cascade_con%all_i(i) - i_lev)/nlevdecomp + 1
+ if(i_decomp .eq. j_decomp .and. j_lev - i_lev .eq. 1)then
+ this%vert_up_tran_acc(:,i_lev,i_decomp) = this%AKXcacc%M(:,i)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev - j_lev .eq. 1)then
+ this%vert_down_tran_acc(:,i_lev,i_decomp) = this%AKXcacc%M(:,i)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev .eq. j_lev)then
+ this%exit_acc(:,i_lev,i_decomp) = this%AKXcacc%M(:,i)
+ found = .true.
+ else
+ do k=1,ndecomp_cascade_transitions
+ if(i_decomp .ne. j_decomp .and. i_lev .eq. j_lev .and. &
+ i_decomp .eq. decomp_cascade_con%cascade_receiver_pool(k) .and. &
+ j_decomp .eq. decomp_cascade_con%cascade_donor_pool(k) .and. .not. found)then
+ this%hori_tran_acc(:,i_lev,k) = this%AKXcacc%M(:,i)
+ found = .true.
+ end if
+ end do
+ end if
+ end if
+ end if
+ if(.not. found) write(iulog,*) 'Error in storing matrix restart variables',i
+ end do
+ end if
+ do k = 1, ndecomp_pools
+ varname=trim(decomp_cascade_con%decomp_pool_name_restart(k))//'c_13'
+ ptr2d => this%in_acc_2d(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_input_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%vert_up_tran_acc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_vert_up_tran_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%vert_down_tran_acc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_vert_down_tran_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%exit_acc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_exit_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ end do
+ do i = 1, ndecomp_cascade_transitions
+ varname=trim(decomp_cascade_con%cascade_step_name(i))//'c_13'
+ ptr2d => this%hori_tran_acc(:,:,i)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_hori_tran_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ end do
+ if(flag=='read')then
+ do i = 1,ndecomp_pools
+ do j = 1,nlevdecomp
+ this%in_acc(:,j+(i-1)*nlevdecomp) = this%in_acc_2d(:,j,i)
+ end do
+ end do
+ do i = 1,decomp_cascade_con%n_all_entries
+ found = .false.
+ j_lev = mod(decomp_cascade_con%all_j(i) - 1,nlevdecomp) + 1
+ j_decomp = (decomp_cascade_con%all_j(i) - j_lev)/nlevdecomp + 1
+ i_lev = mod(decomp_cascade_con%all_i(i) - 1,nlevdecomp) + 1
+ i_decomp = (decomp_cascade_con%all_i(i) - i_lev)/nlevdecomp + 1
+ if(i_decomp .eq. j_decomp .and. j_lev - i_lev .eq. 1)then
+ this%AKXcacc%M(:,i) = this%vert_up_tran_acc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev - j_lev .eq. 1)then
+ this%AKXcacc%M(:,i) = this%vert_down_tran_acc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev .eq. j_lev)then
+ this%AKXcacc%M(:,i) = this%exit_acc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ do k=1,ndecomp_cascade_transitions
+ if(i_decomp .ne. j_decomp .and. i_lev .eq. j_lev .and. &
+ i_decomp .eq. decomp_cascade_con%cascade_receiver_pool(k) .and. &
+ j_decomp .eq. decomp_cascade_con%cascade_donor_pool(k) .and. .not. found)then
+ this%AKXcacc%M(:,i) = this%hori_tran_acc(:,i_lev,k)
+ found = .true.
+ end if
+ end do
+ end if
+ end if
+ end if
+ if(.not. found) write(iulog,*) 'Error in storing matrix restart variables',i
+ end do
+ end if
end if
ptr2d => this%ctrunc_vr_col
@@ -741,6 +1080,16 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, totvegc_col, c12_so
scale_by_thickness=.false., &
interpinic_flag='interp', readvar=readvar, data=ptr2d)
if(use_soil_matrixcn)then
+ ptr2d => this%matrix_cap_decomp_cpools_vr_col(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_Cap_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%decomp0_cpools_vr_col(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"0_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
end if
if (flag=='read' .and. .not. readvar) then
write(iulog,*) 'initializing soilbiogeochem_carbonstate_inst%decomp_cpools_vr_col with atmospheric c14 value for: '//&
@@ -751,6 +1100,9 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, totvegc_col, c12_so
this%decomp_cpools_vr_col(i,j,k) = c12_soilbiogeochem_carbonstate_inst%decomp_cpools_vr_col(i,j,k) * c3_r2
endif
if(use_soil_matrixcn)then
+ if (this%matrix_cap_decomp_cpools_vr_col(i,j,k) /= spval .and. .not. isnan(this%matrix_cap_decomp_cpools_vr_col(i,j,k)) ) then
+ this%matrix_cap_decomp_cpools_vr_col(i,j,k) = c12_soilbiogeochem_carbonstate_inst%matrix_cap_decomp_cpools_vr_col(i,j,k) * c3_r2
+ endif
end if
end do
end do
@@ -758,6 +1110,113 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, totvegc_col, c12_so
end do
if (use_soil_matrixcn)then
+ if(flag=='write')then
+ do i = 1,ndecomp_pools
+ do j = 1,nlevdecomp
+ this%in_acc_2d(:,j,i) = this%in_acc(:,j+(i-1)*nlevdecomp)
+ end do
+ end do
+ do i = 1,decomp_cascade_con%n_all_entries
+ found = .false.
+ j_lev = mod(decomp_cascade_con%all_j(i) - 1,nlevdecomp) + 1
+ j_decomp = (decomp_cascade_con%all_j(i) - j_lev)/nlevdecomp + 1
+ i_lev = mod(decomp_cascade_con%all_i(i) - 1,nlevdecomp) + 1
+ i_decomp = (decomp_cascade_con%all_i(i) - i_lev)/nlevdecomp + 1
+ if(i_decomp .eq. j_decomp .and. j_lev - i_lev .eq. 1)then
+ this%vert_up_tran_acc(:,i_lev,i_decomp) = this%AKXcacc%M(:,i)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev - j_lev .eq. 1)then
+ this%vert_down_tran_acc(:,i_lev,i_decomp) = this%AKXcacc%M(:,i)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev .eq. j_lev)then
+ this%exit_acc(:,i_lev,i_decomp) = this%AKXcacc%M(:,i)
+ found = .true.
+ else
+ do k=1,ndecomp_cascade_transitions
+ if(i_decomp .ne. j_decomp .and. i_lev .eq. j_lev .and. &
+ i_decomp .eq. decomp_cascade_con%cascade_receiver_pool(k) .and. &
+ j_decomp .eq. decomp_cascade_con%cascade_donor_pool(k) .and. .not. found)then
+ this%hori_tran_acc(:,i_lev,k) = this%AKXcacc%M(:,i)
+ found = .true.
+ end if
+ end do
+ end if
+ end if
+ end if
+ if(.not. found) write(iulog,*) 'Error in storing matrix restart variables',i
+ end do
+ end if
+ do k = 1, ndecomp_pools
+ varname=trim(decomp_cascade_con%decomp_pool_name_restart(k))//'c_14'
+ ptr2d => this%in_acc_2d(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_input_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%vert_up_tran_acc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_vert_up_tran_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%vert_down_tran_acc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_vert_down_tran_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%exit_acc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_exit_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ end do
+ do i = 1, ndecomp_cascade_transitions
+ varname=trim(decomp_cascade_con%cascade_step_name(i))//'c_14'
+ ptr2d => this%hori_tran_acc(:,:,i)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_hori_tran_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ end do
+ if(flag=='read')then
+ do i = 1,ndecomp_pools
+ do j = 1,nlevdecomp
+ this%in_acc(:,j+(i-1)*nlevdecomp) = this%in_acc_2d(:,j,i)
+ end do
+ end do
+ do i = 1,decomp_cascade_con%n_all_entries
+ found = .false.
+ j_lev = mod(decomp_cascade_con%all_j(i) - 1,nlevdecomp) + 1
+ j_decomp = (decomp_cascade_con%all_j(i) - j_lev)/nlevdecomp + 1
+ i_lev = mod(decomp_cascade_con%all_i(i) - 1,nlevdecomp) + 1
+ i_decomp = (decomp_cascade_con%all_i(i) - i_lev)/nlevdecomp + 1
+ if(i_decomp .eq. j_decomp .and. j_lev - i_lev .eq. 1)then
+ this%AKXcacc%M(:,i) = this%vert_up_tran_acc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev - j_lev .eq. 1)then
+ this%AKXcacc%M(:,i) = this%vert_down_tran_acc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev .eq. j_lev)then
+ this%AKXcacc%M(:,i) = this%exit_acc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ do k=1,ndecomp_cascade_transitions
+ if(i_decomp .ne. j_decomp .and. i_lev .eq. j_lev .and. &
+ i_decomp .eq. decomp_cascade_con%cascade_receiver_pool(k) .and. &
+ j_decomp .eq. decomp_cascade_con%cascade_donor_pool(k) .and. .not. found)then
+ this%AKXcacc%M(:,i) = this%hori_tran_acc(:,i_lev,k)
+ found = .true.
+ end if
+ end do
+ end if
+ end if
+ end if
+ if(.not. found) write(iulog,*) 'Error in storing matrix restart variables',i
+ end do
+ end if
end if
ptr2d => this%ctrunc_vr_col
@@ -895,6 +1354,7 @@ subroutine SetValues ( this, num_column, filter_column, value_column)
this%decomp_cpools_col(i,k) = value_column
this%decomp_cpools_1m_col(i,k) = value_column
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_col(i,k) = value_column
end if
end do
end do
@@ -905,6 +1365,8 @@ subroutine SetValues ( this, num_column, filter_column, value_column)
i = filter_column(fi)
this%decomp_cpools_vr_col(i,j,k) = value_column
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_vr_col(i,j,k) = value_column
+ this%decomp0_cpools_vr_col(i,j,k) = value_column
end if
end do
end do
@@ -915,17 +1377,28 @@ subroutine SetValues ( this, num_column, filter_column, value_column)
do k = 1, ndecomp_pools
do fi = 1, num_column
i = filter_column(fi)
+ this%in_acc_2d(i,j,k) = value_column
+ this%vert_up_tran_acc(i,j,k) = value_column
+ this%vert_down_tran_acc(i,j,k) = value_column
+ this%exit_acc(i,j,k) = value_column
end do
end do
do k = 1, ndecomp_cascade_transitions
do fi = 1, num_column
i = filter_column(fi)
+ this%hori_tran_acc(i,j,k) = value_column
end do
end do
end do
end if
if(use_soil_matrixcn)then
+ do j = 1,decomp_cascade_con%n_all_entries
+ do fi = 1, num_column
+ i = filter_column(fi)
+ this%AKXcacc%M(i,j) = value_column
+ end do
+ end do
end if
end subroutine SetValues
@@ -963,6 +1436,7 @@ subroutine Summary(this, bounds, num_allc, filter_allc, num_bgc_soilc, filter_bg
c = filter_allc(fc)
this%decomp_cpools_col(c,l) = 0._r8
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_col(c,l) = 0._r8
end if
end do
end do
@@ -974,6 +1448,9 @@ subroutine Summary(this, bounds, num_allc, filter_allc, num_bgc_soilc, filter_bg
this%decomp_cpools_col(c,l) + &
this%decomp_cpools_vr_col(c,j,l) * dzsoi_decomp(j)
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_col(c,l) = &
+ this%matrix_cap_decomp_cpools_col(c,l) + &
+ this%matrix_cap_decomp_cpools_vr_col(c,j,l) * dzsoi_decomp(j)
end if
end do
end do
diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeBGCMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeBGCMod.F90
index f4785fc4d8..49fc95d6f5 100644
--- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeBGCMod.F90
+++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeBGCMod.F90
@@ -588,7 +588,8 @@ subroutine decomp_rate_constants_bgc(bounds, num_bgc_soilc, filter_bgc_soilc, &
w_scalar => soilbiogeochem_carbonflux_inst%w_scalar_col , & ! Output: [real(r8) (:,:) ] soil water scalar for decomp
o_scalar => soilbiogeochem_carbonflux_inst%o_scalar_col , & ! Output: [real(r8) (:,:) ] fraction by which decomposition is limited by anoxia
decomp_k => soilbiogeochem_carbonflux_inst%decomp_k_col , & ! Output: [real(r8) (:,:,:) ] rate constant for decomposition (1./sec)
- spinup_factor => decomp_cascade_con%spinup_factor & ! Input: [real(r8) (:) ] factor for AD spinup associated with each pool
+ Ksoil => soilbiogeochem_carbonflux_inst%Ksoil , & ! Output: [real(r8) (:,:,:) ] rate constant for decomposition (1./sec)
+ spinup_factor => decomp_cascade_con%spinup_factor & ! Input: [real(r8) (:) ] factor for AD spinup associated with each pool
)
mino2lim = CNParamsShareInst%mino2lim
@@ -910,9 +911,16 @@ subroutine decomp_rate_constants_bgc(bounds, num_bgc_soilc, filter_bgc_soilc, &
! Above into soil matrix
if(use_soil_matrixcn)then
+ Ksoil%DM(c,j+nlevdecomp*(i_met_lit-1)) = decomp_k(c,j,i_met_lit) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_cel_lit-1)) = decomp_k(c,j,i_cel_lit) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_lig_lit-1)) = decomp_k(c,j,i_lig_lit) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_act_som-1)) = decomp_k(c,j,i_act_som) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_slo_som-1)) = decomp_k(c,j,i_slo_som) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_pas_som-1)) = decomp_k(c,j,i_pas_som) * dt
! same for cwd but only if fates is not enabled; fates handles CWD
! on its own structure
if (.not. use_fates) then
+ Ksoil%DM(c,j+nlevdecomp*(i_cwd-1)) = decomp_k(c,j,i_cwd) * dt
end if
end if !use_soil_matrixcn
end do
diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeConType.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeConType.F90
index 0474ab9a63..929db2a46f 100644
--- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeConType.F90
+++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeConType.F90
@@ -8,10 +8,11 @@ module SoilBiogeochemDecompCascadeConType
use shr_kind_mod , only : r8 => shr_kind_r8
use abortutils , only : endrun
use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
- use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_pools, nlevdecomp
+ use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_pools, nlevdecomp, ndecomp_pools_vr
+ use clm_varpar , only : ndecomp_cascade_outtransitions
use clm_varcon , only : ispval
- use SparseMatrixMultiplyMod, only : sparse_matrix_type, diag_matrix_type, vector_type
use clm_varctl , only : iulog
+ use SparseMatrixMultiplyMod, only : sparse_matrix_type, diag_matrix_type, vector_type
!
implicit none
@@ -47,6 +48,25 @@ module SoilBiogeochemDecompCascadeConType
real(r8) , pointer :: spinup_factor(:) ! factor by which to scale AD and relevant processes by
! Matrix data
+ integer,pointer :: spm_tranlist_a(:,:) ! Prescribed subscripts to map 2D variables (transitions,soil layer) to 1D sparse matrix format in a_ma_vr and na_ma_vr
+ integer,pointer :: A_i(:) ! Prescribed row number of all elements in a_ma_vr
+ integer,pointer :: A_j(:) ! Prescribed column number of all elements in na_ma_vr
+ integer,pointer :: tri_i(:) ! Prescribed row index of all entries in AVsoil
+ integer,pointer :: tri_j(:) ! Prescribed column index of all entries in AVsoil
+ integer,pointer :: all_i(:) ! Prescribed row index of all entries in AKallsoilc, AKallsoiln, AKXcacc, and AKXnacc
+ integer,pointer :: all_j(:) ! Prescribed column index of all entries in AKallsoilc, AKallsoiln, AKXcacc, and AKXnacc
+
+ integer,pointer :: list_V_AKVfire (:) ! Saves mapping indices from V to (A*K+V-Kfire) in the addition subroutine SPMP_ABC
+ integer,pointer :: list_AK_AKVfire(:) ! Saves mapping indices from A*K to (A*K+V-Kfire) in the addition subroutine SPMP_ABC
+ integer,pointer :: list_fire_AKVfire(:) ! Saves mapping indices from Kfire to (A*K+V-Kfire) in the addition subroutine SPMP_ABC
+ integer,pointer :: list_AK_AKV (:) ! Saves mapping indices from A*K to (A*K+V) in the addition subroutine SPMP_AB
+ integer,pointer :: list_V_AKV (:) ! Saves mapping indices from V to (A*K+V) in the addition subroutine SPMP_AB
+ integer,pointer :: list_Asoilc (:) ! Saves mapping indices from a_ma_vr to AKsoilc
+ integer,pointer :: list_Asoiln (:) ! Saves mapping indices from na_ma_vr to AKsoiln
+
+ integer, public :: n_all_entries ! Number of all entries in AKallsoilc, AKallsoiln, AKXcacc, and AKXnacc
+ integer, public :: Ntrans_setup ! Number of horizontal transfers between soil and litter pools
+ integer, public :: Ntri_setup ! Number of non-zero entries in AVsoil
end type decomp_cascade_type
@@ -55,7 +75,7 @@ module SoilBiogeochemDecompCascadeConType
integer, public, parameter :: century_decomp = 1 ! CENTURY decomposition method type
integer, public, parameter :: mimics_decomp = 2 ! MIMICS decomposition method type
integer, public :: decomp_method = ispval ! Type of decomposition to use
- logical, public, parameter :: use_soil_matrixcn = .false. ! true => use cn matrix solution for soil BGC
+ logical, public :: use_soil_matrixcn = .false. ! true => use cn matrix solution for soil BGC
type(decomp_cascade_type), public :: decomp_cascade_con
!------------------------------------------------------------------------
@@ -153,7 +173,7 @@ subroutine decomp_cascade_par_init( NLFilename )
ndecomp_cascade_transitions = 7
ndecomp_pools_max = 8
end if
- ! Set ndecomp_pools_vr needed for Matrix solution
+ ndecomp_pools_vr = ndecomp_pools * nlevdecomp
end subroutine decomp_cascade_par_init
@@ -196,9 +216,12 @@ subroutine init_decomp_cascade_constants( )
allocate(decomp_cascade_con%is_cellulose(ibeg:ndecomp_pools))
allocate(decomp_cascade_con%is_lignin(ibeg:ndecomp_pools))
allocate(decomp_cascade_con%spinup_factor(1:ndecomp_pools))
-
- ! Allocate soil matrix data
if(use_soil_matrixcn)then
+ allocate(decomp_cascade_con%spm_tranlist_a(1:nlevdecomp,1:ndecomp_cascade_transitions)); decomp_cascade_con%spm_tranlist_a(:,:) = -9999
+ allocate(decomp_cascade_con%A_i(1:(ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)*nlevdecomp));decomp_cascade_con%A_i(:) = -9999
+ allocate(decomp_cascade_con%A_j(1:(ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)*nlevdecomp));decomp_cascade_con%A_j(:) = -9999
+ allocate(decomp_cascade_con%tri_i(1:(3*nlevdecomp-2)*(ndecomp_pools-1))); decomp_cascade_con%tri_i(:) = -9999
+ allocate(decomp_cascade_con%tri_j(1:(3*nlevdecomp-2)*(ndecomp_pools-1))); decomp_cascade_con%tri_j(:) = -9999
end if
!-- properties of each pathway along decomposition cascade
@@ -225,25 +248,122 @@ subroutine init_decomp_cascade_constants( )
decomp_cascade_con%spinup_factor(1:ndecomp_pools) = nan
end if
- ! Soil matrix sizes
if(use_soil_matrixcn)then
+ decomp_cascade_con%Ntrans_setup = (ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)*nlevdecomp
+ decomp_cascade_con%Ntri_setup = (3*nlevdecomp-2)*(ndecomp_pools - 1) !exclude one cwd
else
- ! Set to missing value if not used
+ decomp_cascade_con%Ntrans_setup = -9999
+ decomp_cascade_con%Ntri_setup = -9999
end if
end subroutine init_decomp_cascade_constants
- !------------------------------------------------------------------------
- subroutine InitSoilTransfer()
- !
- ! !DESCRIPTION:
- ! Initialize sparse matrix variables and index. Count possible non-zero entries and record their x and y in the matrix.
- ! Collect those non-zero entry information, and save them into the list.
- !------------------------------------------------------------------------
- ! !USES:
- use SparseMatrixMultiplyMod, only : sparse_matrix_type, diag_matrix_type, vector_type
- ! !LOGAL VARIABLES:
- integer i,j,k,m,n
+ subroutine InitSoilTransfer()
+! Initialize sparse matrix variables and index. Count possible non-zero entries and record their x and y in the matrix.
+! Collect those non-zero entry information, and save them into the list.
+
+ use SparseMatrixMultiplyMod, only : sparse_matrix_type, diag_matrix_type, vector_type
+
+ integer i,j,k,m,n
+ integer,dimension(:) :: ntrans_per_donor(1:ndecomp_pools)
+ real(r8),dimension(:) :: SM(1:1,1:decomp_cascade_con%Ntrans_setup),TRI(1:1,1:decomp_cascade_con%Ntri_setup)
+ type(sparse_matrix_type) :: AK, AV, AKfire, AKallsoil!, AKtmp1, AKtmp2
+ logical list_ready,init_readyAK
+ integer num_soilc,filter_c(1:1)
- end subroutine InitSoilTransfer
+ init_readyAK = .false.
+ ntrans_per_donor = 0
+
+ do k = 1,ndecomp_cascade_transitions
+ ntrans_per_donor(decomp_cascade_con%cascade_donor_pool(k)) &
+ = ntrans_per_donor(decomp_cascade_con%cascade_donor_pool(k)) + 1
+ end do
+
+ k = 0
+ n = 1
+ do i = 1,ndecomp_pools
+ do j=1,nlevdecomp
+ do m=1,ntrans_per_donor(i)
+ if(decomp_cascade_con%cascade_receiver_pool(m+k) .ne. 0)then
+ decomp_cascade_con%spm_tranlist_a(j,m+k) = n
+ decomp_cascade_con%A_i(n) = (decomp_cascade_con%cascade_receiver_pool(m+k)-1)*nlevdecomp+j
+ decomp_cascade_con%A_j(n) = (decomp_cascade_con%cascade_donor_pool(m+k)-1)*nlevdecomp+j
+ n = n + 1
+ end if
+ end do
+ end do
+ k = k + ntrans_per_donor(i)
+ end do
+
+ SM = 1._r8
+ if(n-1 .ne. decomp_cascade_con%Ntrans_setup)then
+ write(iulog,*) 'error in InitSoilTransfer: number of transfers is error in count'
+ end if
+
+ n = 1
+ do i = 1,ndecomp_pools
+ do j = 1, nlevdecomp
+ if(.not. decomp_cascade_con%is_cwd(i))then
+ if (j > 1) then ! avoid tranfer from for example,soil1_1st layer to litr3_10th layer
+ TRI(1,n) = 1._r8
+ decomp_cascade_con%tri_j(n) = (i-1)*nlevdecomp + j
+ decomp_cascade_con%tri_i(n) = (i-1)*nlevdecomp + j - 1
+ n = n + 1
+ end if
+ TRI(1,n) = 1._r8
+ decomp_cascade_con%tri_j(n) = (i-1)*nlevdecomp + j
+ decomp_cascade_con%tri_i(n) = (i-1)*nlevdecomp + j
+ n = n + 1
+ if (j < nlevdecomp) then ! avoid tranfer from for example, litr3_10th layer to soil1_1st layer
+ TRI(1,n) = 1._r8
+ decomp_cascade_con%tri_j(n) = (i-1)*nlevdecomp + j
+ decomp_cascade_con%tri_i(n) = (i-1)*nlevdecomp + j + 1
+ n = n + 1
+ end if
+ end if
+ end do
+ end do
+
+ if(n-1 .ne. decomp_cascade_con%Ntri_setup)then
+ write(iulog,*) 'error in InitSoilTransfer: number of vertical-transfers is error in count'
+ end if
+
+ num_soilc = 1
+ filter_c(1:1) = 1
+ if ( AK%IsAllocSM() ) call AK%ReleaseSM()
+ call AK%InitSM(ndecomp_pools*nlevdecomp,1,1)
+ call AK%SetValueA(1,1,num_soilc,filter_c(1:num_soilc),SM,decomp_cascade_con%A_i,decomp_cascade_con%A_j,decomp_cascade_con%Ntrans_setup,init_readyAK)
+ allocate(decomp_cascade_con%list_AK_AKVfire(1:AK%NE))
+ allocate(decomp_cascade_con%list_AK_AKV (1:AK%NE))
+
+ if ( AV%IsAllocSM() ) call AV%ReleaseSM()
+ call AV%InitSM(ndecomp_pools*nlevdecomp,1,1)
+ call AV%SetValueSM(1,1,num_soilc,filter_c(1:num_soilc),TRI,decomp_cascade_con%tri_i,decomp_cascade_con%tri_j,decomp_cascade_con%Ntri_setup)
+ allocate(decomp_cascade_con%list_V_AKVfire (1:AV%NE))
+ allocate(decomp_cascade_con%list_V_AKV (1:AV%NE))
+
+ if ( AKfire%IsAllocSM() ) call AKfire%ReleaseSM()
+ call AKfire%InitSM(ndecomp_pools*nlevdecomp,1,1)
+ call AKfire%SetValueA_diag(num_soilc,filter_c(1:num_soilc),1._r8)
+ allocate(decomp_cascade_con%list_fire_AKVfire(1:AKfire%NE))
+
+ list_ready = .false.
+ if ( AKallsoil%IsAllocSM() ) call AKallsoil%ReleaseSM()
+ call AKallsoil%InitSM(ndecomp_pools*nlevdecomp,1,1)
+ call AKallsoil%SPMP_ABC(num_soilc,filter_c(1:num_soilc),AK,AV,AKfire,list_ready)
+
+ decomp_cascade_con%n_all_entries = AKallsoil%NE
+ allocate(decomp_cascade_con%all_i(1:decomp_cascade_con%n_all_entries))
+ allocate(decomp_cascade_con%all_j(1:decomp_cascade_con%n_all_entries))
+ decomp_cascade_con%all_i(:) = AKallsoil%RI(1:decomp_cascade_con%n_all_entries)
+ decomp_cascade_con%all_j(:) = AKallsoil%CI(1:decomp_cascade_con%n_all_entries)
+
+ allocate(decomp_cascade_con%list_Asoilc (1:(ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)*nlevdecomp))
+ allocate(decomp_cascade_con%list_Asoiln (1:(ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)*nlevdecomp))
+
+ call AK%ReleaseSM()
+ call AV%ReleaseSM()
+ call AKfire%ReleaseSM()
+ call AKallsoil%ReleaseSM()
+ end subroutine InitSoilTransfer
end module SoilBiogeochemDecompCascadeConType
diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90
index 65091755f5..e9bb60bcec 100644
--- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90
+++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90
@@ -18,7 +18,7 @@ module SoilBiogeochemDecompCascadeMIMICSMod
use spmdMod , only : masterproc
use abortutils , only : endrun
use CNSharedParamsMod , only : CNParamsShareInst, nlev_soildecomp_standard
- use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con
+ use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con, InitSoilTransfer, use_soil_matrixcn
use SoilBiogeochemStateType , only : soilbiogeochem_state_type
use SoilBiogeochemCarbonFluxType , only : soilbiogeochem_carbonflux_type
use SoilBiogeochemCarbonStateType , only : soilbiogeochem_carbonstate_type
@@ -734,6 +734,8 @@ subroutine init_decompcascade_mimics(bounds, soilbiogeochem_state_inst, soilstat
nue_decomp_cascade(i_cwdl2) = 1.0_r8
end if
+ if (use_soil_matrixcn) call InitSoilTransfer()
+
deallocate(params_inst%mimics_mge)
deallocate(params_inst%mimics_vmod)
deallocate(params_inst%mimics_vint)
@@ -763,7 +765,7 @@ subroutine decomp_rates_mimics(bounds, num_bgc_soilc, filter_bgc_soilc, &
! decomposition cascade model
!
! !USES:
- use clm_time_manager , only : get_average_days_per_year
+ use clm_time_manager , only : get_average_days_per_year, get_step_size
use clm_varcon , only : secspday, secsphr, tfrz
use clm_varcon , only : g_to_mg, cm3_to_m3
use subgridAveMod , only : p2c
@@ -822,6 +824,7 @@ subroutine decomp_rates_mimics(bounds, num_bgc_soilc, filter_bgc_soilc, &
integer :: p, fp, c, fc, j, k, l, s ! indices
integer :: pf ! fates patch index
integer :: nc ! clump index
+ real(r8):: dt ! decomposition time step
real(r8):: days_per_year ! days per year
real(r8):: depth_scalar(bounds%begc:bounds%endc,1:nlevdecomp)
real(r8):: w_d_o_scalars ! product of w_scalar * depth_scalar * o_scalar
@@ -882,6 +885,7 @@ subroutine decomp_rates_mimics(bounds, num_bgc_soilc, filter_bgc_soilc, &
cn_col => soilbiogeochem_carbonflux_inst%cn_col , & ! Output: [real(r8) (:,:) ] C:N ratio
ligninNratioAvg => soilbiogeochem_carbonflux_inst%litr_lig_c_to_n_col, & ! Input: [real(r8) (:) ] C:N ratio of litter lignin
decomp_k => soilbiogeochem_carbonflux_inst%decomp_k_col , & ! Output: [real(r8) (:,:,:) ] rate for decomposition (1./sec)
+ Ksoil => soilbiogeochem_carbonflux_inst%Ksoil , & ! Output: [real(r8) (:,:,:) ] rate constant for decomposition (1./sec)
spinup_factor => decomp_cascade_con%spinup_factor & ! Input: [real(r8) (:) ] factor for AD spinup associated with each pool
)
@@ -892,6 +896,7 @@ subroutine decomp_rates_mimics(bounds, num_bgc_soilc, filter_bgc_soilc, &
mino2lim = CNParamsShareInst%mino2lim
days_per_year = get_average_days_per_year()
+ dt = real( get_step_size(), r8 )
! ! Set "decomp_depth_efolding" parameter
! decomp_depth_efolding = CNParamsShareInst%decomp_depth_efolding
@@ -1311,6 +1316,23 @@ subroutine decomp_rates_mimics(bounds, num_bgc_soilc, filter_bgc_soilc, &
if (get_do_tillage()) then
call get_apply_tillage_multipliers(idop, c, j, decomp_k(c,j,:))
end if
+
+! Above into soil matrix
+ if(use_soil_matrixcn)then
+ Ksoil%DM(c,j+nlevdecomp*(i_met_lit-1)) = decomp_k(c,j,i_met_lit) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_str_lit-1)) = decomp_k(c,j,i_str_lit) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_avl_som-1)) = decomp_k(c,j,i_avl_som) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_phys_som-1)) = decomp_k(c,j,i_phys_som) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_chem_som-1)) = decomp_k(c,j,i_chem_som) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_cop_mic-1)) = decomp_k(c,j,i_cop_mic) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_oli_mic-1)) = decomp_k(c,j,i_oli_mic) * dt
+ ! same for cwd but only if fates is not enabled; fates handles
+ ! CWD
+ ! on its own structure
+ if (.not. use_fates) then
+ Ksoil%DM(c,j+nlevdecomp*(i_cwd-1)) = decomp_k(c,j,i_cwd) * dt
+ end if
+ end if !use_soil_matrixcn
end do
end do
diff --git a/src/soilbiogeochem/SoilBiogeochemDecompMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompMod.F90
index 9bd8b13008..6be924bcf5 100644
--- a/src/soilbiogeochem/SoilBiogeochemDecompMod.F90
+++ b/src/soilbiogeochem/SoilBiogeochemDecompMod.F90
@@ -131,7 +131,8 @@ subroutine SoilBiogeochemDecomp (bounds, num_bgc_soilc, filter_bgc_soilc,
decomp_cascade_hr_vr => soilbiogeochem_carbonflux_inst%decomp_cascade_hr_vr_col , & ! Output: [real(r8) (:,:,:) ] vertically-resolved het. resp. from decomposing C pools (gC/m3/s)
decomp_cascade_ctransfer_vr => soilbiogeochem_carbonflux_inst%decomp_cascade_ctransfer_vr_col , & ! Output: [real(r8) (:,:,:) ] vertically-resolved het. resp. from decomposing C pools (gC/m3/s)
phr_vr => soilbiogeochem_carbonflux_inst%phr_vr_col , & ! Input: [real(r8) (:,:) ] potential HR (gC/m3/s)
- fphr => soilbiogeochem_carbonflux_inst%fphr_col & ! Output: [real(r8) (:,:) ] fraction of potential SOM + LITTER heterotrophic
+ fphr => soilbiogeochem_carbonflux_inst%fphr_col , & ! Output: [real(r8) (:,:) ] fraction of potential SOM + LITTER heterotrophic
+ Ksoil => soilbiogeochem_carbonflux_inst%Ksoil & ! In/Output: [real(r8) (:,:,:) ] rate constant for decomposition (1./sec)
)
! column loop to calculate actual immobilization and decomp rates, following
@@ -177,6 +178,8 @@ subroutine SoilBiogeochemDecomp (bounds, num_bgc_soilc, filter_bgc_soilc,
p_decomp_cpool_loss(c,j,k) = p_decomp_cpool_loss(c,j,k) * fpi_vr(c,j)
pmnf_decomp_cascade(c,j,k) = pmnf_decomp_cascade(c,j,k) * fpi_vr(c,j)
if (use_soil_matrixcn)then ! correct only when one transfer from each litter pool
+ Ksoil%DM(c,j+nlevdecomp*(cascade_donor_pool(k)-1)) = &
+ Ksoil%DM(c,j+nlevdecomp*(cascade_donor_pool(k)-1)) * fpi_vr(c,j)
end if
if (.not. use_nitrif_denitrif) then
sminn_to_denit_decomp_cascade_vr(c,j,k) = 0._r8
diff --git a/src/soilbiogeochem/SoilBiogeochemLittVertTranspMod.F90 b/src/soilbiogeochem/SoilBiogeochemLittVertTranspMod.F90
index e58e2f22d6..889fda5bdb 100644
--- a/src/soilbiogeochem/SoilBiogeochemLittVertTranspMod.F90
+++ b/src/soilbiogeochem/SoilBiogeochemLittVertTranspMod.F90
@@ -149,9 +149,8 @@ subroutine SoilBiogeochemLittVertTransp(bounds, num_bgc_soilc, filter_bgc_soilc,
real(r8) :: epsilon ! small number
real(r8), pointer :: conc_ptr(:,:,:) ! pointer, concentration state variable being transported
real(r8), pointer :: source(:,:,:) ! pointer, source term
- real(r8), pointer :: trcr_tendency_ptr(:,:,:) ! pointer, store the vertical tendency (gain/loss due to vertical transport)
- ! Pointer for matrix
-
+ real(r8), pointer :: trcr_tendency_ptr(:,:,:) ! poiner, store the vertical tendency (gain/loss due to vertical transport)
+ real(r8), pointer :: matrix_input(:,:) ! poiner, store the vertical tendency (gain/loss due to vertical transport)
!-----------------------------------------------------------------------
! Set statement functions
@@ -165,7 +164,8 @@ subroutine SoilBiogeochemLittVertTransp(bounds, num_bgc_soilc, filter_bgc_soilc,
altmax_lastyear => active_layer_inst%altmax_lastyear_col , & ! Input: [real(r8) (:) ] prior year maximum annual depth of thaw
som_adv_coef => soilbiogeochem_state_inst%som_adv_coef_col , & ! Output: [real(r8) (:,:) ] SOM advective flux (m/s)
- som_diffus_coef => soilbiogeochem_state_inst%som_diffus_coef_col & ! Output: [real(r8) (:,:) ] SOM diffusivity due to bio/cryo-turbation (m2/s)
+ som_diffus_coef => soilbiogeochem_state_inst%som_diffus_coef_col,& ! Output: [real(r8) (:,:) ] SOM diffusivity due to bio/cryo-turbation (m2/s)
+ tri_ma_vr => soilbiogeochem_carbonflux_inst%tri_ma_vr & ! Output: [real(r8) (:,:) ] Vertical CN transfer rate in sparse matrix format (gC*m3)/(gC*m3*step))
)
!Set parameters of vertical mixing of SOM
@@ -237,16 +237,17 @@ subroutine SoilBiogeochemLittVertTransp(bounds, num_bgc_soilc, filter_bgc_soilc,
!------ loop over litter/som types
do i_type = 1, ntype
- ! For matrix solution figure out which matrix data to point to
select case (i_type)
case (1) ! C
conc_ptr => soilbiogeochem_carbonstate_inst%decomp_cpools_vr_col
source => soilbiogeochem_carbonflux_inst%decomp_cpools_sourcesink_col
trcr_tendency_ptr => soilbiogeochem_carbonflux_inst%decomp_cpools_transport_tendency_col
+ matrix_input => soilbiogeochem_carbonflux_inst%matrix_Cinput%V
case (2) ! N
conc_ptr => soilbiogeochem_nitrogenstate_inst%decomp_npools_vr_col
source => soilbiogeochem_nitrogenflux_inst%decomp_npools_sourcesink_col
trcr_tendency_ptr => soilbiogeochem_nitrogenflux_inst%decomp_npools_transport_tendency_col
+ matrix_input => soilbiogeochem_nitrogenflux_inst%matrix_Ninput%V
case (3)
if ( use_c13 ) then
! C13
@@ -399,6 +400,8 @@ subroutine SoilBiogeochemLittVertTransp(bounds, num_bgc_soilc, filter_bgc_soilc,
r_tri(c,j) = source(c,j,s) * dzsoi_decomp(j) /dtime + (a_p_0 - adv_flux(c,j)) * conc_trcr(c,j)
if(s .eq. 1 .and. i_type .eq. 1 .and. use_soil_matrixcn )then !vertical matrix are the same for all pools
do i = 1,ndecomp_pools-1 !excluding cwd
+ tri_ma_vr(c,1+(i-1)*(nlevdecomp*3-2)) = (b_tri(c,j) - a_p_0) / dzsoi_decomp(j) * (-dtime)
+ tri_ma_vr(c,3+(i-1)*(nlevdecomp*3-2)) = c_tri(c,j) / dzsoi_decomp(j) * (-dtime)
end do
end if
elseif (j < nlevdecomp+1) then
@@ -409,12 +412,17 @@ subroutine SoilBiogeochemLittVertTransp(bounds, num_bgc_soilc, filter_bgc_soilc,
if(s .eq. 1 .and. i_type .eq. 1 .and. use_soil_matrixcn )then
if(j .le. col%nbedrock(c))then
do i = 1,ndecomp_pools-1
+ tri_ma_vr(c,j*3-4+(i-1)*(nlevdecomp*3-2)) = a_tri(c,j) / dzsoi_decomp(j) * (-dtime)
if(j .ne. nlevdecomp)then
+ tri_ma_vr(c,j*3 +(i-1)*(nlevdecomp*3-2)) = c_tri(c,j) / dzsoi_decomp(j) * (-dtime)
end if
+ tri_ma_vr(c,j*3-2+(i-1)*(nlevdecomp*3-2)) = (b_tri(c,j) - a_p_0) / dzsoi_decomp(j) * (-dtime)
end do
else
if(j .eq. col%nbedrock(c) + 1 .and. j .ne. nlevdecomp .and. j .gt. 1)then
do i = 1,ndecomp_pools-1
+ tri_ma_vr(c,(j-1)*3-2+(i-1)*(nlevdecomp*3-2)) = tri_ma_vr(c,(j-1)*3-2+(i-1)*(nlevdecomp*3-2)) &
+ + a_tri(c,j) / dzsoi_decomp(j-1)*(-dtime)
end do
end if
end if
@@ -463,11 +471,11 @@ subroutine SoilBiogeochemLittVertTransp(bounds, num_bgc_soilc, filter_bgc_soilc,
trcr_tendency_ptr(c,j,s) = trcr_tendency_ptr(c,j,s) / dtime
end do
end do
- else
- ! For matrix solution set the matrix input array
+ else ! For matrix solution set the matrix input array
do j = 1,nlevdecomp
do fc =1,num_bgc_soilc
c = filter_bgc_soilc(fc)
+ matrix_input(c,j+(s-1)*nlevdecomp) = matrix_input(c,j+(s-1)*nlevdecomp) + source(c,j,s)
end do
end do
end if !soil_matrix
@@ -479,7 +487,7 @@ subroutine SoilBiogeochemLittVertTransp(bounds, num_bgc_soilc, filter_bgc_soilc,
if(.not. use_soil_matrixcn)then
conc_trcr(c,j) = conc_ptr(c,j,s) + source(c,j,s)
else
- ! For matrix solution set the matrix input array
+ matrix_input(c,j+(s-1)*nlevdecomp) = matrix_input(c,j+(s-1)*nlevdecomp) + source(c,j,s)
end if
if (j > col%nbedrock(c) .and. source(c,j,s) > 0._r8) then
write(iulog,*) 'source >0',c,j,s,source(c,j,s)
diff --git a/src/soilbiogeochem/SoilBiogeochemNStateUpdate1Mod.F90 b/src/soilbiogeochem/SoilBiogeochemNStateUpdate1Mod.F90
index 4b70459aca..8655b6c72d 100644
--- a/src/soilbiogeochem/SoilBiogeochemNStateUpdate1Mod.F90
+++ b/src/soilbiogeochem/SoilBiogeochemNStateUpdate1Mod.F90
@@ -9,11 +9,12 @@ module SoilBiogeochemNStateUpdate1Mod
use clm_time_manager , only : get_step_size_real
use clm_varpar , only : nlevdecomp, ndecomp_cascade_transitions
use clm_varctl , only : iulog, use_nitrif_denitrif, use_crop
+ use SoilBiogeochemDecompCascadeConType , only : use_soil_matrixcn
use clm_varcon , only : nitrif_n2o_loss_frac
use SoilBiogeochemStateType , only : soilbiogeochem_state_type
use SoilBiogeochemNitrogenStateType , only : soilbiogeochem_nitrogenstate_type
use SoilBiogeochemNitrogenfluxType , only : soilbiogeochem_nitrogenflux_type
- use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con, use_soil_matrixcn
+ use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con
use CNSharedParamsMod , only : use_fun
use ColumnType , only : col
!
@@ -118,49 +119,48 @@ subroutine SoilBiogeochemNStateUpdate1(num_bgc_soilc, filter_bgc_soilc, &
end if
! decomposition fluxes
- if (.not. use_soil_matrixcn) then
- do k = 1, ndecomp_cascade_transitions
+ ! TODO slevis: improve indentation
+ if (.not. use_soil_matrixcn) then
+ do k = 1, ndecomp_cascade_transitions
+ do j = 1, nlevdecomp
+ ! column loop
+ do fc = 1,num_bgc_soilc
+ c = filter_bgc_soilc(fc)
+
+ nf%decomp_npools_sourcesink_col(c,j,cascade_donor_pool(k)) = &
+ nf%decomp_npools_sourcesink_col(c,j,cascade_donor_pool(k)) - &
+ nf%decomp_cascade_ntransfer_vr_col(c,j,k) * dt
+ end do
+ end do
+ end do
+
+
+ do k = 1, ndecomp_cascade_transitions
+ if ( cascade_receiver_pool(k) /= 0 ) then ! skip terminal transitions
do j = 1, nlevdecomp
! column loop
do fc = 1,num_bgc_soilc
c = filter_bgc_soilc(fc)
+ nf%decomp_npools_sourcesink_col(c,j,cascade_receiver_pool(k)) = &
+ nf%decomp_npools_sourcesink_col(c,j,cascade_receiver_pool(k)) + &
+ (nf%decomp_cascade_ntransfer_vr_col(c,j,k) + &
+ nf%decomp_cascade_sminn_flux_vr_col(c,j,k)) * dt
+ end do
+ end do
+ else ! terminal transitions
+ do j = 1, nlevdecomp
+ ! column loop
+ do fc = 1,num_bgc_soilc
+ c = filter_bgc_soilc(fc)
nf%decomp_npools_sourcesink_col(c,j,cascade_donor_pool(k)) = &
nf%decomp_npools_sourcesink_col(c,j,cascade_donor_pool(k)) - &
- nf%decomp_cascade_ntransfer_vr_col(c,j,k) * dt
+ nf%decomp_cascade_sminn_flux_vr_col(c,j,k) * dt
end do
end do
- end do
-
-
- do k = 1, ndecomp_cascade_transitions
- if ( cascade_receiver_pool(k) /= 0 ) then ! skip terminal transitions
- do j = 1, nlevdecomp
- ! column loop
- do fc = 1,num_bgc_soilc
- c = filter_bgc_soilc(fc)
-
- nf%decomp_npools_sourcesink_col(c,j,cascade_receiver_pool(k)) = &
- nf%decomp_npools_sourcesink_col(c,j,cascade_receiver_pool(k)) + &
- (nf%decomp_cascade_ntransfer_vr_col(c,j,k) + &
- nf%decomp_cascade_sminn_flux_vr_col(c,j,k)) * dt
- end do
- end do
- else ! terminal transitions
- do j = 1, nlevdecomp
- ! column loop
- do fc = 1,num_bgc_soilc
- c = filter_bgc_soilc(fc)
- nf%decomp_npools_sourcesink_col(c,j,cascade_donor_pool(k)) = &
- nf%decomp_npools_sourcesink_col(c,j,cascade_donor_pool(k)) - &
- nf%decomp_cascade_sminn_flux_vr_col(c,j,k) * dt
- end do
- end do
- end if
- end do
- else
- ! Matrix solution equvalent to above is in CNSoilMatrixMod.F90? (TODO check on this)
- end if !
+ end if
+ end do
+ end if !
if (.not. use_nitrif_denitrif) then
diff --git a/src/soilbiogeochem/SoilBiogeochemNitrogenFluxType.F90 b/src/soilbiogeochem/SoilBiogeochemNitrogenFluxType.F90
index 90213b8123..94d5b4324f 100644
--- a/src/soilbiogeochem/SoilBiogeochemNitrogenFluxType.F90
+++ b/src/soilbiogeochem/SoilBiogeochemNitrogenFluxType.F90
@@ -3,8 +3,8 @@ module SoilBiogeochemNitrogenFluxType
use shr_kind_mod , only : r8 => shr_kind_r8
use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
use shr_log_mod , only : errMsg => shr_log_errMsg
- use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_pools
- use clm_varpar , only : nlevdecomp_full, nlevdecomp
+ use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_pools, ndecomp_cascade_outtransitions
+ use clm_varpar , only : nlevdecomp_full, nlevdecomp, ndecomp_pools_vr
use clm_varcon , only : spval, ispval, dzsoi_decomp
use decompMod , only : bounds_type
use clm_varctl , only : use_nitrif_denitrif, use_crop, use_fates
@@ -12,7 +12,7 @@ module SoilBiogeochemNitrogenFluxType
use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con, use_soil_matrixcn
use abortutils , only : endrun
use LandunitType , only : lun
- use ColumnType , only : col
+ use ColumnType , only : col
use SparseMatrixMultiplyMod , only : sparse_matrix_type, diag_matrix_type, vector_type
!
! !PUBLIC TYPES:
@@ -132,7 +132,16 @@ module SoilBiogeochemNitrogenFluxType
! flux passed in from FATES.
! This is a diagnostic for balance checks only
! track tradiagonal matrix
-
+ type(sparse_matrix_type) :: AKsoiln ! A*K for N transfers between pools
+ type(sparse_matrix_type) :: AKallsoiln ! (A*K+V-Kfire) for soil N cycle
+ integer :: NE_AKallsoiln ! Number of non-zero entries in AKallsoiln. Automatically generated by functions SPMP_*
+ integer,pointer,dimension(:) :: RI_AKallsoiln ! Row numbers of entries in AKallsoiln. Automatically generated by functions in SPMP_*
+ integer,pointer,dimension(:) :: CI_AKallsoiln ! Column numbers of entries in AKallsoiln, Automatically generated by functions in SPMP_*
+ integer,pointer,dimension(:) :: RI_na ! Row numbers of all entries from AKsoiln. Automatically generated by SetValueA
+ integer,pointer,dimension(:) :: CI_na ! Column numbers of all entries from AKsoiln. Automatically generated by SetValueA
+ type(diag_matrix_type) :: Ksoiln ! N turnover rate in different soil pools and layers
+ type(vector_type) :: matrix_Ninput ! N input to different soil compartments (pools and layers) (gN/m3/step)
+
contains
procedure , public :: Init
@@ -173,7 +182,7 @@ subroutine InitAllocate(this, bounds)
type(bounds_type) , intent(in) :: bounds
!
! !LOCAL VARIABLES:
- integer :: begc,endc ! column begin and end indices
+ integer :: begc,endc,Ntrans,Ntrans_diag
!------------------------------------------------------------------------
begc = bounds%begc; endc = bounds%endc
@@ -282,8 +291,20 @@ subroutine InitAllocate(this, bounds)
allocate(this%fates_litter_flux(0:0)); this%fates_litter_flux(:) = nan
end if
- ! Allocate soil Matrix setug
+ ! Allocate soil Matrix setup
if(use_soil_matrixcn)then
+
+ Ntrans = (ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)*nlevdecomp
+ call this%AKsoiln%InitSM (ndecomp_pools*nlevdecomp,begc,endc,Ntrans+ndecomp_pools*nlevdecomp)
+ call this%AKallsoiln%InitSM (ndecomp_pools*nlevdecomp,begc,endc,Ntrans+decomp_cascade_con%Ntri_setup+nlevdecomp)
+ this%NE_AKallsoiln = (Ntrans+nlevdecomp*ndecomp_pools) + (Ntrans+decomp_cascade_con%Ntri_setup + nlevdecomp) + (ndecomp_pools*nlevdecomp)
+ allocate(this%RI_AKallsoiln(1:this%NE_AKallsoiln)); this%RI_AKallsoiln(1:this%NE_AKallsoiln)=-9999
+ allocate(this%CI_AKallsoiln(1:this%NE_AKallsoiln)); this%CI_AKallsoiln(1:this%NE_AKallsoiln)=-9999
+ Ntrans_diag = (ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)*nlevdecomp+ndecomp_pools_vr
+ allocate(this%RI_na(1:Ntrans_diag)); this%RI_na(1:Ntrans_diag) = -9999
+ allocate(this%CI_na(1:Ntrans_diag)); this%CI_na(1:Ntrans_diag) = -9999
+ call this%Ksoiln%InitDM (ndecomp_pools*nlevdecomp,begc,endc)
+ call this%matrix_Ninput%InitV (ndecomp_pools*nlevdecomp,begc,endc)
end if
end subroutine InitAllocate
@@ -1005,8 +1026,9 @@ subroutine SetValues ( this, &
this%decomp_npools_leached_col(i,k) = value_column
end do
end do
-
+
if(use_soil_matrixcn)then
+ call this%matrix_Ninput%SetValueV_scaler(num_column,filter_column(1:num_column),value_column)
end if
do k = 1, ndecomp_pools
diff --git a/src/soilbiogeochem/SoilBiogeochemNitrogenStateType.F90 b/src/soilbiogeochem/SoilBiogeochemNitrogenStateType.F90
index ee889503d0..d3042b02e8 100644
--- a/src/soilbiogeochem/SoilBiogeochemNitrogenStateType.F90
+++ b/src/soilbiogeochem/SoilBiogeochemNitrogenStateType.F90
@@ -12,10 +12,10 @@ module SoilBiogeochemNitrogenStateType
use clm_varpar , only : nlevdecomp_full, nlevdecomp, nlevsoi
use clm_varcon , only : spval, dzsoi_decomp, zisoi
use clm_varctl , only : use_nitrif_denitrif, use_fates_bgc
- use SoilBiogeochemDecompCascadeConType , only : mimics_decomp, century_decomp, decomp_method, use_soil_matrixcn
use clm_varctl , only : iulog, override_bgc_restart_mismatch_dump, spinup_state
use landunit_varcon , only : istcrop, istsoil
- use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con
+ use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con, use_soil_matrixcn
+ use SoilBiogeochemDecompCascadeConType , only : mimics_decomp, century_decomp, decomp_method
use LandunitType , only : lun
use ColumnType , only : col
use GridcellType , only : grc
@@ -30,6 +30,8 @@ module SoilBiogeochemNitrogenStateType
type, public :: soilbiogeochem_nitrogenstate_type
real(r8), pointer :: decomp_npools_vr_col (:,:,:) ! col (gN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
+ real(r8), pointer :: decomp0_npools_vr_col (:,:,:) ! col (gN/m3) vertically-resolved N baseline (initial value of this year) in decomposing (litter, cwd, soil) pools in dimension (col,nlev,npools)
+ real(r8), pointer :: decomp_npools_vr_SASUsave_col(:,:,:) ! col (gN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
real(r8), pointer :: decomp_soiln_vr_col (:,:) ! col (gN/m3) vertically-resolved decomposing total soil N pool
@@ -66,6 +68,17 @@ module SoilBiogeochemNitrogenStateType
real(r8), pointer :: totn_grc (:) ! (gN/m2) total gridcell nitrogen
! Matrix-cn
+ real(r8), pointer :: matrix_cap_decomp_npools_col (:,:) ! col (gN/m2) N capacity in decomposing (litter, cwd, soil) N pools in dimension (col,npools)
+ real(r8), pointer :: matrix_cap_decomp_npools_vr_col (:,:,:) ! col (gN/m3) vertically-resolved N capacity in decomposing (litter, cwd, soil) pools in dimension(col,nlev,npools)
+ real(r8), pointer :: in_nacc (:,:) ! col (gN/m3/yr) accumulated litter fall N input per year in dimension(col,nlev*npools)
+ real(r8), pointer :: in_nacc_2d (:,:,:) ! col (gN/m3/yr) accumulated litter fall N input per year in dimension(col,nlev,npools)
+ real(r8), pointer :: tran_nacc (:,:,:) ! col (gN/m3/yr) accumulated N transfers from j to i (col,i,j) per year in dimension(col,nlev*npools,nlev*npools)
+ real(r8), pointer :: vert_up_tran_nacc (:,:,:) ! col (gN/m3/yr) accumulated upward vertical N transport in dimension(col,nlev,npools)
+ real(r8), pointer :: vert_down_tran_nacc (:,:,:) ! col (gN/m3/yr) accumulated downward vertical N transport in dimension(col,nlev,npools)
+ real(r8), pointer :: exit_nacc (:,:,:) ! col (gN/m3/yr) accumulated exit N in dimension(col,nlev,npools)
+ real(r8), pointer :: hori_tran_nacc (:,:,:) ! col (gN/m3/yr) accumulated N transport between pools at the same level in dimension(col,nlev,ntransfers)
+ type(sparse_matrix_type) :: AKXnacc ! col (gN/m3/yr) accumulated N transfers from j to i (col,i,j) per year in dimension(col,nlev*npools,nlev*npools) in sparse matrix type
+ type(vector_type) :: matrix_Ninter ! col (gN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools in dimension(col,nlev*npools) in vector type
contains
@@ -140,11 +153,36 @@ subroutine InitAllocate(this, bounds)
allocate(this%decomp_npools_col (begc:endc,1:ndecomp_pools)) ; this%decomp_npools_col (:,:) = nan
allocate(this%decomp_npools_1m_col (begc:endc,1:ndecomp_pools)) ; this%decomp_npools_1m_col (:,:) = nan
if(use_soil_matrixcn)then
+ allocate(this%matrix_cap_decomp_npools_col (begc:endc,1:ndecomp_pools)) ; this%matrix_cap_decomp_npools_col (:,:) = nan
end if
allocate(this%decomp_npools_vr_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools));
this%decomp_npools_vr_col(:,:,:)= nan
if(use_soil_matrixcn)then
+ allocate(this%matrix_cap_decomp_npools_vr_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools));
+ this%matrix_cap_decomp_npools_vr_col(:,:,:)= nan
+! for matrix-spinup
+ allocate(this%decomp0_npools_vr_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools));
+ this%decomp0_npools_vr_col(:,:,:)= nan
+ allocate(this%decomp_npools_vr_SASUsave_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools));
+ this%decomp_npools_vr_SASUsave_col(:,:,:)= nan
+ allocate(this%in_nacc(begc:endc,1:nlevdecomp*ndecomp_pools))
+ this%in_nacc(:,:)= nan
+ allocate(this%tran_nacc(begc:endc,1:nlevdecomp*ndecomp_pools,1:nlevdecomp*ndecomp_pools))
+ this%tran_nacc(:,:,:)= nan
+
+ allocate(this%in_nacc_2d(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%in_nacc_2d(:,:,:)= nan
+ allocate(this%vert_up_tran_nacc(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%vert_up_tran_nacc(:,:,:)= nan
+ allocate(this%vert_down_tran_nacc(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%vert_down_tran_nacc(:,:,:)= nan
+ allocate(this%exit_nacc(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%exit_nacc(:,:,:)= nan
+ allocate(this%hori_tran_nacc(begc:endc,1:nlevdecomp_full,1:ndecomp_cascade_transitions))
+ this%hori_tran_nacc(:,:,:)= nan
+ call this%AKXnacc%InitSM(ndecomp_pools*nlevdecomp,begc,endc,decomp_cascade_con%n_all_entries)
+ call this%matrix_Ninter%InitV (ndecomp_pools*nlevdecomp,begc,endc)
end if
allocate(this%decomp_soiln_vr_col(begc:endc,1:nlevdecomp_full))
this%decomp_soiln_vr_col(:,:)= nan
@@ -195,10 +233,12 @@ subroutine InitHistory(this, bounds)
this%decomp_npools_vr_col(begc:endc,:,:) = spval
this%decomp_npools_1m_col(begc:endc,:) = spval
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_npools_vr_col(begc:endc,:,:) = spval
end if
end if
this%decomp_npools_col(begc:endc,:) = spval
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_npools_col(begc:endc,:) = spval
end if
do l = 1, ndecomp_pools
if ( nlevdecomp_full > 1 ) then
@@ -209,6 +249,12 @@ subroutine InitHistory(this, bounds)
avgflag='A', long_name=longname, &
ptr_col=data2dptr)
if(use_soil_matrixcn)then
+ data2dptr => this%matrix_cap_decomp_npools_vr_col(:,:,l)
+ fieldname = trim(decomp_cascade_con%decomp_pool_name_history(l))//'N_Cap_vr'
+ longname = trim(decomp_cascade_con%decomp_pool_name_history(l))//' N capacity (vertically resolved)'
+ call hist_addfld2d (fname=fieldname, units='gN/m^3', type2d='levdcmp', &
+ avgflag='I', long_name=longname, &
+ ptr_col=data2dptr)
end if
endif
@@ -220,6 +266,12 @@ subroutine InitHistory(this, bounds)
ptr_col=data1dptr)
if(nlevdecomp_full .eq. 1)then
if(use_soil_matrixcn)then
+ data1dptr => this%matrix_cap_decomp_npools_col(:,l)
+ fieldname = trim(decomp_cascade_con%decomp_pool_name_history(l))//'N_Cap'
+ longname = trim(decomp_cascade_con%decomp_pool_name_history(l))//' N capacity'
+ call hist_addfld1d (fname=fieldname, units='gN/m^2', &
+ avgflag='I', long_name=longname, &
+ ptr_col=data1dptr)
end if
end if
@@ -382,6 +434,7 @@ subroutine InitCold(this, bounds, &
l = col%landunit(c)
! matrix-spinup
if(use_soil_matrixcn)then
+ this%in_nacc(c,:) = 0._r8
end if
if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then
@@ -393,9 +446,19 @@ subroutine InitCold(this, bounds, &
do k = 1, ndecomp_pools
this%decomp_npools_vr_col(c,j,k) = decomp_cpools_vr_col(c,j,k) / decomp_cascade_con%initial_cn_ratio(k)
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_npools_vr_col(c,j,k) = decomp_cpools_vr_col(c,j,k) / decomp_cascade_con%initial_cn_ratio(k)
+ this%in_nacc_2d(c,j,k) = 0._r8
+ this%vert_up_tran_nacc(c,j,k) = 0._r8
+ this%vert_down_tran_nacc(c,j,k) = 0._r8
+ this%exit_nacc(c,j,k) = 0._r8
+ this%decomp0_npools_vr_col(c,j,k) = max(this%decomp_npools_vr_col(c,j,k),1.e-30_r8)
+ this%decomp_npools_vr_SASUsave_col(c,j,k) = 0._r8
end if
end do
if(use_soil_matrixcn)then
+ do k = 1, ndecomp_cascade_transitions
+ this%hori_tran_nacc(c,j,k) = 0._r8
+ end do
end if
this%sminn_vr_col(c,j) = 0._r8
@@ -403,6 +466,9 @@ subroutine InitCold(this, bounds, &
end do
if(use_soil_matrixcn)then
+ do j = 1,decomp_cascade_con%n_all_entries
+ this%AKXnacc%M(c,j) = 0._r8
+ end do
end if
if ( nlevdecomp > 1 ) then
@@ -410,9 +476,18 @@ subroutine InitCold(this, bounds, &
do k = 1, ndecomp_pools
this%decomp_npools_vr_col(c,j,k) = 0._r8
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_npools_vr_col(c,j,k) = 0._r8
+ this%in_nacc_2d(c,j,k) = 0._r8
+ this%vert_up_tran_nacc(c,j,k) = 0._r8
+ this%vert_down_tran_nacc(c,j,k) = 0._r8
+ this%exit_nacc(c,j,k) = 0._r8
+ this%decomp0_npools_vr_col(c,j,k) = this%decomp_npools_vr_col(c,j,k)
end if
end do
if(use_soil_matrixcn)then
+ do k = 1, ndecomp_cascade_transitions
+ this%hori_tran_nacc(c,j,k) = 0._r8
+ end do
end if
this%sminn_vr_col(c,j) = 0._r8
this%ntrunc_vr_col(c,j) = 0._r8
@@ -422,6 +497,7 @@ subroutine InitCold(this, bounds, &
this%decomp_npools_col(c,k) = decomp_cpools_col(c,k) / decomp_cascade_con%initial_cn_ratio(k)
this%decomp_npools_1m_col(c,k) = decomp_cpools_1m_col(c,k) / decomp_cascade_con%initial_cn_ratio(k)
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_npools_col(c,k) = decomp_cpools_col(c,k) / decomp_cascade_con%initial_cn_ratio(k)
end if
end do
@@ -539,12 +615,128 @@ subroutine Restart ( this, bounds, ncid, flag, totvegc_col )
errMsg(sourcefile, __LINE__))
end if
end do
- if(flag=='write')then
- if(use_soil_matrixcn)then
+ if(use_soil_matrixcn)then
+ if(flag=='write')then
+ do i = 1,ndecomp_pools
+ do j = 1,nlevdecomp
+ this%in_nacc_2d(:,j,i) = this%in_nacc(:,j+(i-1)*nlevdecomp)
+ end do
+ end do
+ do i = 1,decomp_cascade_con%n_all_entries
+ found = .false.
+ j_lev = mod(decomp_cascade_con%all_j(i) - 1,nlevdecomp) + 1
+ j_decomp = (decomp_cascade_con%all_j(i) - j_lev)/nlevdecomp + 1
+ i_lev = mod(decomp_cascade_con%all_i(i) - 1,nlevdecomp) + 1
+ i_decomp = (decomp_cascade_con%all_i(i) - i_lev)/nlevdecomp + 1
+ if(i_decomp .eq. j_decomp .and. j_lev - i_lev .eq. 1)then
+ this%vert_up_tran_nacc(:,i_lev,i_decomp) = this%AKXnacc%M(:,i)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev - j_lev .eq. 1)then
+ this%vert_down_tran_nacc(:,i_lev,i_decomp) = this%AKXnacc%M(:,i)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev .eq. j_lev)then
+ this%exit_nacc(:,i_lev,i_decomp) = this%AKXnacc%M(:,i)
+ found = .true.
+ else
+ do k=1,ndecomp_cascade_transitions
+ if(i_decomp .ne. j_decomp .and. i_lev .eq. j_lev .and. &
+ i_decomp .eq. decomp_cascade_con%cascade_receiver_pool(k) .and. &
+ j_decomp .eq. decomp_cascade_con%cascade_donor_pool(k) .and. .not. found)then
+ this%hori_tran_nacc(:,i_lev,k) = this%AKXnacc%M(:,i)
+ found = .true.
+ end if
+ end do
+ end if
+ end if
+ end if
+ if(.not. found) write(iulog,*) 'Error in storing matrix restart variables',i,i_decomp,j_decomp,i_lev,j_lev
+ end do
end if
+
+ do k = 1, ndecomp_pools
+ varname=trim(decomp_cascade_con%decomp_pool_name_restart(k))//'n'
+ ptr2d => this%matrix_cap_decomp_npools_vr_col(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_Cap_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., scale_by_thickness=.false., &
+ long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%decomp0_npools_vr_col(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"0_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., scale_by_thickness=.false., &
+ long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%in_nacc_2d(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_input_nacc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%vert_up_tran_nacc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_vert_up_tran_nacc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%vert_down_tran_nacc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_vert_down_tran_nacc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%exit_nacc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_exit_nacc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ end do
+
+ do i = 1, ndecomp_cascade_transitions
+ varname=trim(decomp_cascade_con%cascade_step_name(i))//'n'
+ ptr2d => this%hori_tran_nacc(:,:,i)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_hori_tran_nacc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ end do
end if
+
if(use_soil_matrixcn)then
if(flag=='read')then
+ do i = 1,ndecomp_pools
+ do j = 1,nlevdecomp
+ this%in_nacc(:,j+(i-1)*nlevdecomp) = this%in_nacc_2d(:,j,i)
+ end do
+ end do
+ do i = 1,decomp_cascade_con%n_all_entries
+ found = .false.
+ j_lev = mod(decomp_cascade_con%all_j(i) - 1,nlevdecomp) + 1
+ j_decomp = (decomp_cascade_con%all_j(i) - j_lev)/nlevdecomp + 1
+ i_lev = mod(decomp_cascade_con%all_i(i) - 1,nlevdecomp) + 1
+ i_decomp = (decomp_cascade_con%all_i(i) - i_lev)/nlevdecomp + 1
+ if(i_decomp .eq. j_decomp .and. j_lev - i_lev .eq. 1)then
+ this%AKXnacc%M(:,i) = this%vert_up_tran_nacc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev - j_lev .eq. 1)then
+ this%AKXnacc%M(:,i) = this%vert_down_tran_nacc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev .eq. j_lev)then
+ this%AKXnacc%M(:,i) = this%exit_nacc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ do k=1,ndecomp_cascade_transitions
+ if(i_decomp .ne. j_decomp .and. i_lev .eq. j_lev .and. &
+ i_decomp .eq. decomp_cascade_con%cascade_receiver_pool(k) .and. &
+ j_decomp .eq. decomp_cascade_con%cascade_donor_pool(k) .and. .not. found)then
+ this%AKXnacc%M(:,i) = this%hori_tran_nacc(:,i_lev,k)
+ found = .true.
+ end if
+ end do
+ end if
+ end if
+ end if
+ if(.not. found) write(iulog,*) 'Error in storing matrix restart variables',i
+ end do
end if
end if
@@ -775,6 +967,7 @@ subroutine SetValues ( this, num_column, filter_column, value_column )
this%decomp_npools_col(i,k) = value_column
this%decomp_npools_1m_col(i,k) = value_column
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_npools_col(i,k) = value_column
end if
end do
end do
@@ -786,6 +979,8 @@ subroutine SetValues ( this, num_column, filter_column, value_column )
i = filter_column(fi)
this%decomp_npools_vr_col(i,j,k) = value_column
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_npools_vr_col(i,j,k) = value_column
+ this%decomp0_npools_vr_col(i,j,k) = value_column
end if
end do
end do
@@ -799,6 +994,32 @@ subroutine SetValues ( this, num_column, filter_column, value_column )
! Set values for the matrix solution
if(use_soil_matrixcn)then
+ do j = 1,nlevdecomp
+ do k = 1, ndecomp_pools
+ do fi = 1, num_column
+ i = filter_column(fi)
+ this%in_nacc_2d(i,j,k) = value_column
+ this%vert_up_tran_nacc(i,j,k) = value_column
+ this%vert_down_tran_nacc(i,j,k) = value_column
+ this%exit_nacc(i,j,k) = value_column
+ end do
+ end do
+ do k = 1, ndecomp_cascade_transitions
+ do fi = 1, num_column
+ i = filter_column(fi)
+ this%hori_tran_nacc(i,j,k) = value_column
+ end do
+ end do
+ end do
+ end if
+
+ if(use_soil_matrixcn)then
+ do j = 1,decomp_cascade_con%n_all_entries
+ do fi = 1, num_column
+ i = filter_column(fi)
+ this%AKXnacc%M(i,j) = value_column
+ end do
+ end do
end if
end subroutine SetValues
@@ -857,6 +1078,7 @@ subroutine Summary(this, bounds, num_allc, filter_allc, num_bgc_soilc, filter_bg
c = filter_allc(fc)
this%decomp_npools_col(c,l) = 0._r8
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_npools_col(c,l) = 0._r8
end if
end do
do j = 1, nlevdecomp
@@ -866,6 +1088,9 @@ subroutine Summary(this, bounds, num_allc, filter_allc, num_bgc_soilc, filter_bg
this%decomp_npools_col(c,l) + &
this%decomp_npools_vr_col(c,j,l) * dzsoi_decomp(j)
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_npools_col(c,l) = &
+ this%matrix_cap_decomp_npools_col(c,l) + &
+ this%matrix_cap_decomp_npools_vr_col(c,j,l) * dzsoi_decomp(j)
end if
end do
end do
diff --git a/src/utils/clmfates_interfaceMod.F90 b/src/utils/clmfates_interfaceMod.F90
index fcd5cb5230..e3e7644b90 100644
--- a/src/utils/clmfates_interfaceMod.F90
+++ b/src/utils/clmfates_interfaceMod.F90
@@ -54,12 +54,15 @@ module CLMFatesInterfaceMod
use clm_varctl , only : use_fates_cohort_age_tracking
use clm_varctl , only : use_fates_ed_st3
use clm_varctl , only : use_fates_ed_prescribed_phys
- use clm_varctl , only : use_fates_logging
+ use clm_varctl , only : fates_harvest_mode
use clm_varctl , only : use_fates_inventory_init
use clm_varctl , only : use_fates_fixed_biogeog
use clm_varctl , only : use_fates_nocomp
use clm_varctl , only : use_fates_sp
use clm_varctl , only : use_fates_luh
+ use clm_varctl , only : use_fates_lupft
+ use clm_varctl , only : use_fates_potentialveg
+ use clm_varctl , only : flandusepftdat
use clm_varctl , only : fates_seeddisp_cadence
use clm_varctl , only : fates_inventory_ctrl_filename
use clm_varctl , only : use_nitrif_denitrif
@@ -167,7 +170,6 @@ module CLMFatesInterfaceMod
use FATESFireBase , only : fates_fire_base_type
use FATESFireFactoryMod , only : no_fire, scalar_lightning, successful_ignitions,&
anthro_ignitions, anthro_suppression
- use dynSubgridControlMod , only : get_do_harvest
use dynHarvestMod , only : num_harvest_inst, harvest_varnames
use dynHarvestMod , only : harvest_units, mass_units, unitless_units
use dynHarvestMod , only : dynHarvest_interp_resolve_harvesttypes
@@ -180,7 +182,14 @@ module CLMFatesInterfaceMod
use dynFATESLandUseChangeMod, only : num_landuse_transition_vars, num_landuse_state_vars
use dynFATESLandUseChangeMod, only : landuse_transitions, landuse_states
use dynFATESLandUseChangeMod, only : landuse_transition_varnames, landuse_state_varnames
- use dynFATESLandUseChangeMod, only : dynFatesLandUseInterp
+ use dynFATESLandUseChangeMod, only : num_landuse_harvest_vars
+ use dynFATESLandUseChangeMod, only : fates_harvest_no_logging
+ use dynFATESLandUseChangeMod, only : fates_harvest_clmlanduse
+ use dynFATESLandUseChangeMod, only : fates_harvest_luh_area
+ use dynFATESLandUseChangeMod, only : fates_harvest_luh_mass
+ use dynFATESLandUseChangeMod, only : landuse_harvest
+ use dynFATESLandUseChangeMod, only : landuse_harvest_units
+ use dynFATESLandUseChangeMod, only : landuse_harvest_varnames
implicit none
@@ -273,6 +282,8 @@ module CLMFatesInterfaceMod
character(len=*), parameter, private :: sourcefile = &
__FILE__
+ integer, parameter :: num_landuse_pft_vars = 4
+
public :: CLMFatesGlobals1
public :: CLMFatesGlobals2
public :: CrossRefHistoryFields
@@ -386,6 +397,7 @@ subroutine CLMFatesGlobals2()
integer :: pass_cohort_age_tracking
integer :: pass_tree_damage
integer :: pass_use_luh
+ integer :: pass_use_potentialveg
integer :: pass_num_luh_states
integer :: pass_num_luh_transitions
@@ -483,13 +495,6 @@ subroutine CLMFatesGlobals2()
end if
call set_fates_ctrlparms('use_ed_st3',ival=pass_ed_st3)
- if(use_fates_logging) then
- pass_logging = 1
- else
- pass_logging = 0
- end if
- call set_fates_ctrlparms('use_logging',ival=pass_logging)
-
if(use_fates_ed_prescribed_phys) then
pass_ed_prescribed_phys = 1
else
@@ -511,26 +516,30 @@ subroutine CLMFatesGlobals2()
end if
call set_fates_ctrlparms('use_cohort_age_tracking',ival=pass_cohort_age_tracking)
- ! check fates logging namelist value first because hlm harvest overrides it
- if(use_fates_logging) then
- pass_logging = 1
- else
- pass_logging = 0
- end if
-
- if(get_do_harvest()) then
- pass_logging = 1
- pass_num_lu_harvest_cats = num_harvest_inst
- pass_lu_harvest = 1
- else
- pass_lu_harvest = 0
- pass_num_lu_harvest_cats = 0
+ ! FATES logging and harvest modes
+ pass_logging = 0
+ pass_lu_harvest = 0
+ pass_num_lu_harvest_cats = 0
+ if (trim(fates_harvest_mode) /= fates_harvest_no_logging) then
+ pass_logging = 1 ! Time driven logging, without landuse harvest
+ ! CLM landuse timeseries driven harvest rates
+ if (trim(fates_harvest_mode) == fates_harvest_clmlanduse) then
+ pass_num_lu_harvest_cats = num_harvest_inst
+ pass_lu_harvest = 1
+
+ ! LUH2 landuse timeseries driven harvest rates
+ else if (trim(fates_harvest_mode)== fates_harvest_luh_area .or. &
+ trim(fates_harvest_mode)== fates_harvest_luh_mass) then
+ pass_lu_harvest = 1
+ pass_num_lu_harvest_cats = num_landuse_harvest_vars
+ end if
end if
call set_fates_ctrlparms('use_lu_harvest',ival=pass_lu_harvest)
call set_fates_ctrlparms('num_lu_harvest_cats',ival=pass_num_lu_harvest_cats)
call set_fates_ctrlparms('use_logging',ival=pass_logging)
+ ! FATES landuse modes
if(use_fates_luh) then
pass_use_luh = 1
pass_num_luh_states = num_landuse_state_vars
@@ -540,10 +549,18 @@ subroutine CLMFatesGlobals2()
pass_num_luh_states = 0
pass_num_luh_transitions = 0
end if
+
call set_fates_ctrlparms('use_luh2',ival=pass_use_luh)
call set_fates_ctrlparms('num_luh2_states',ival=pass_num_luh_states)
call set_fates_ctrlparms('num_luh2_transitions',ival=pass_num_luh_transitions)
+ if ( use_fates_potentialveg ) then
+ pass_use_potentialveg = 1
+ else
+ pass_use_potentialveg = 0
+ end if
+ call set_fates_ctrlparms('use_fates_potentialveg',ival=pass_use_potentialveg)
+
if(use_fates_inventory_init) then
pass_inventory_init = 1
else
@@ -675,7 +692,7 @@ end subroutine CLMFatesTimesteps
! ====================================================================================
- subroutine init(this, bounds_proc )
+ subroutine init(this, bounds_proc, flandusepftdat)
! ---------------------------------------------------------------------------------
! This initializes the hlm_fates_interface_type
@@ -704,6 +721,7 @@ subroutine init(this, bounds_proc )
! Input Arguments
class(hlm_fates_interface_type), intent(inout) :: this
type(bounds_type),intent(in) :: bounds_proc
+ character(len=*), intent(in) :: flandusepftdat
! local variables
integer :: nclumps ! Number of threads
@@ -721,6 +739,9 @@ subroutine init(this, bounds_proc )
integer :: ndecomp
integer :: numg
+ real(r8), allocatable :: landuse_pft_map(:,:,:)
+ real(r8), allocatable :: landuse_bareground(:)
+
! Initialize the FATES communicators with the HLM
! This involves to stages
! 1) allocate the vectors
@@ -753,6 +774,13 @@ subroutine init(this, bounds_proc )
write(iulog,*) 'clm_fates%init(): allocating for ',nclumps,' threads'
end if
+ ! Retrieve the landuse x pft static data if the file is present
+ if (use_fates_fixed_biogeog .and. use_fates_luh) then
+ call GetLandusePFTData(bounds_proc, flandusepftdat, landuse_pft_map, landuse_bareground)
+ end if
+
+ nclumps = get_proc_clumps()
+
allocate(copy_fates_var(bounds_proc%begc:bounds_proc%endc))
copy_fates_var(:) = .false.
@@ -857,18 +885,26 @@ subroutine init(this, bounds_proc )
this%fates(nc)%sites(s)%lat = grc%latdeg(g)
this%fates(nc)%sites(s)%lon = grc%londeg(g)
- this%fates(nc)%bc_in(s)%pft_areafrac(:)=0._r8
- ! initialize static layers for reduced complexity FATES versions from HLM
- ! maybe make this into a subroutine of it's own later.
- do m = surfpft_lb,surfpft_ub
- ft = m - surfpft_lb
- this%fates(nc)%bc_in(s)%pft_areafrac(ft)=wt_nat_patch(g,m)
- end do
+ ! Transfer the landuse x pft data to fates via bc_in if file is given
+ if (use_fates_fixed_biogeog) then
+ if (use_fates_luh) then
+ this%fates(nc)%bc_in(s)%pft_areafrac_lu(:,1:num_landuse_pft_vars) = landuse_pft_map(g,:,1:num_landuse_pft_vars)
+ this%fates(nc)%bc_in(s)%baregroundfrac = landuse_bareground(g)
+ else
+ ! initialize static layers for reduced complexity FATES versions from HLM
+ ! maybe make this into a subroutine of it's own later.
+ this%fates(nc)%bc_in(s)%pft_areafrac(:)=0._r8
+ do m = surfpft_lb,surfpft_ub
+ ft = m - surfpft_lb
+ this%fates(nc)%bc_in(s)%pft_areafrac(ft)=wt_nat_patch(g,m)
+ end do
- if (abs(sum(this%fates(nc)%bc_in(s)%pft_areafrac(surfpft_lb:surfpft_ub)) - 1.0_r8) > sum_to_1_tol) then
- write(iulog,*) 'pft_area error in interfc ', s, sum(this%fates(nc)%bc_in(s)%pft_areafrac(:)) - 1.0_r8
- call endrun(msg=errMsg(sourcefile, __LINE__))
- end if
+ if (abs(sum(this%fates(nc)%bc_in(s)%pft_areafrac(surfpft_lb:surfpft_ub)) - 1.0_r8) > sum_to_1_tol) then
+ write(iulog,*) 'pft_area error in interfc ', s, sum(this%fates(nc)%bc_in(s) %pft_areafrac(:)) - 1.0_r8
+ call endrun(msg=errMsg(sourcefile, __LINE__))
+ end if
+ end if
+ end if
end do !site
! Initialize site-level static quantities dictated by the HLM
@@ -910,6 +946,12 @@ subroutine init(this, bounds_proc )
! Fire data to send to FATES
call create_fates_fire_data_method( this%fates_fire_data_method )
+ ! deallocate the local landuse x pft array
+ if (use_fates_fixed_biogeog .and. use_fates_luh) then
+ deallocate(landuse_pft_map)
+ deallocate(landuse_bareground)
+ end if
+
call t_stopf('fates_init')
end subroutine init
@@ -1026,7 +1068,8 @@ subroutine dynamics_driv(this, nc, bounds_clump, &
! Set the FATES global time and date variables
call GetAndSetTime
- if (get_do_harvest()) then
+ ! Get harvest rates for CLM landuse timeseries driven rates
+ if (trim(fates_harvest_mode) == fates_harvest_clmlanduse) then
call dynHarvest_interp_resolve_harvesttypes(bounds_clump, &
harvest_rates=harvest_rates(begg:endg,1:num_harvest_inst), &
after_start_of_harvest_ts=after_start_of_harvest_ts)
@@ -1152,7 +1195,7 @@ subroutine dynamics_driv(this, nc, bounds_clump, &
! for now there is one veg column per gridcell, so store all harvest data in each site
! this will eventually change
! today's hlm harvest flag needs to be set no matter what
- if (get_do_harvest()) then
+ if (trim(fates_harvest_mode) == fates_harvest_clmlanduse) then
if (after_start_of_harvest_ts) then
this%fates(nc)%bc_in(s)%hlm_harvest_rates(1:num_harvest_inst) = harvest_rates(g,1:num_harvest_inst)
else
@@ -1170,6 +1213,12 @@ subroutine dynamics_driv(this, nc, bounds_clump, &
write(iulog,*) harvest_units
call endrun(msg=errMsg(sourcefile, __LINE__))
end if
+
+ else if (trim(fates_harvest_mode) == fates_harvest_luh_area .or. &
+ trim(fates_harvest_mode) == fates_harvest_luh_mass) then
+ this%fates(nc)%bc_in(s)%hlm_harvest_rates = landuse_harvest(:,g)
+ this%fates(nc)%bc_in(s)%hlm_harvest_catnames = landuse_harvest_varnames
+ this%fates(nc)%bc_in(s)%hlm_harvest_units = landuse_harvest_units
endif
if (use_fates_luh) then
@@ -2132,6 +2181,13 @@ subroutine init_coldstart(this, waterstatebulk_inst, waterdiagnosticbulk_inst, &
this%fates(nc)%bc_in(s)%hlm_luh_state_names = landuse_state_varnames
this%fates(nc)%bc_in(s)%hlm_luh_transitions = landuse_transitions(:,g)
this%fates(nc)%bc_in(s)%hlm_luh_transition_names = landuse_transition_varnames
+
+ if (trim(fates_harvest_mode) == fates_harvest_luh_area .or. &
+ trim(fates_harvest_mode) == fates_harvest_luh_mass) then
+ this%fates(nc)%bc_in(s)%hlm_harvest_rates = landuse_harvest(:,g)
+ this%fates(nc)%bc_in(s)%hlm_harvest_catnames = landuse_harvest_varnames
+ this%fates(nc)%bc_in(s)%hlm_harvest_units = landuse_harvest_units
+ end if
end if
end do
@@ -3755,6 +3811,112 @@ subroutine GetAndSetTime()
end subroutine GetAndSetTime
+ ! ======================================================================================
+
+ subroutine GetLandusePFTData(bounds, landuse_pft_file, landuse_pft_map, landuse_bareground)
+
+ ! !DESCRIPTION:
+ ! Read in static landuse x pft file
+
+ ! !USES:
+ use fileutils , only : getfil
+ use ncdio_pio , only : file_desc_t, ncd_io, ncd_inqdlen
+ use ncdio_pio , only : ncd_pio_openfile, ncd_pio_closefile
+ use decompMod , only : BOUNDS_LEVEL_PROC
+ use clm_varcon, only : grlnd
+ use FatesConstantsMod, only : fates_unset_r8
+
+
+ ! !ARGUMENTS:
+ type(bounds_type), intent(in) :: bounds ! proc-level bounds
+ character(len=*) , intent(in) :: landuse_pft_file ! name of file containing static landuse x pft information
+ real(r8), allocatable, intent(inout) :: landuse_pft_map(:,:,:)
+ real(r8), allocatable, intent(inout) :: landuse_bareground(:)
+
+ ! !LOCAL VARIABLES
+ integer :: varnum ! variable number
+ integer :: dimid, dimlen ! dimension id number and length
+ integer :: ier ! error id
+ character(len=256) :: locfn ! local file name
+ type(file_desc_t) :: ncid ! netcdf id
+ real(r8), pointer :: arraylocal(:,:) ! local array for reading fraction data
+ real(r8), pointer :: arraylocal_bareground(:) ! local array for reading bareground data
+ logical :: readvar ! true => variable is on dataset
+ !character(len=16), parameter :: grlnd = 'lndgrid' ! name of lndgrid
+
+ integer, parameter :: dim_landuse_pft = 14
+
+ ! Land use name arrays
+ character(len=10), parameter :: landuse_pft_map_varnames(num_landuse_pft_vars) = &
+ [character(len=10) :: 'frac_primr','frac_secnd','frac_pastr','frac_range'] !need to move 'frac_surf' to a different variable
+
+ character(len=*), parameter :: subname = 'GetLandusePFTData'
+
+ !-----------------------------------------------------------------------
+
+ ! Check to see if the landuse file name has been provided
+ ! Note: getfile checks this as well
+ if (masterproc) then
+ write(iulog,*) 'Attempting to read landuse x pft data .....'
+ if (landuse_pft_file == ' ') then
+ write(iulog,*)'landuse_pft_file must be specified'
+ call endrun(msg=errMsg(__FILE__, __LINE__))
+ endif
+ endif
+
+ ! Initialize the landuse x pft arrays and initialize to unset
+ allocate(landuse_pft_map(bounds%begg:bounds%endg,dim_landuse_pft,num_landuse_pft_vars),stat=ier)
+ if (ier /= 0) then
+ call endrun(msg=' allocation error for landuse_pft_map'//errMsg(__FILE__, __LINE__))
+ end if
+ landuse_pft_map = fates_unset_r8
+
+ allocate(landuse_bareground(bounds%begg:bounds%endg),stat=ier)
+ if (ier /= 0) then
+ call endrun(msg=' allocation error for landuse_bareground'//errMsg(__FILE__, __LINE__))
+ end if
+ landuse_bareground = fates_unset_r8
+
+
+ ! Get the local filename and open the file
+ call getfil(landuse_pft_file, locfn, 0)
+ call ncd_pio_openfile (ncid, trim(locfn), 0)
+
+ ! Check that natpft dimension on the file matches the target array dimensions
+ call ncd_inqdlen(ncid, dimid, dimlen, 'natpft')
+ if (dimlen /= dim_landuse_pft) then
+ write(iulog,*) 'natpft dimensions on the landuse x pft file do not match target array size'
+ call endrun(msg=errMsg(__FILE__, __LINE__))
+ end if
+
+ ! Allocate a temporary array since ncdio expects a pointer
+ allocate(arraylocal(bounds%begg:bounds%endg,dim_landuse_pft))
+ allocate(arraylocal_bareground(bounds%begg:bounds%endg))
+
+ ! Read the landuse x pft data from file
+ do varnum = 1, num_landuse_pft_vars
+ call ncd_io(ncid=ncid, varname=landuse_pft_map_varnames(varnum), flag='read', &
+ data=arraylocal, dim1name=grlnd, readvar=readvar)
+ if (.not. readvar) &
+ call endrun(msg='ERROR: '//trim(landuse_pft_map_varnames(varnum))// &
+ ' NOT on landuse x pft file'//errMsg(__FILE__, __LINE__))
+ landuse_pft_map(bounds%begg:bounds%endg,:,varnum) = arraylocal(bounds%begg:bounds%endg,:)
+ end do
+
+ ! Read the bareground data from file. This is per gridcell only.
+ call ncd_io(ncid=ncid, varname='frac_brgnd', flag='read', &
+ data=arraylocal_bareground, dim1name=grlnd, readvar=readvar)
+ if (.not. readvar) call endrun(msg='ERROR: frac_brgnd NOT on landuse x pft file'//errMsg(__FILE__, __LINE__))
+ landuse_bareground(bounds%begg:bounds%endg) = arraylocal_bareground(bounds%begg:bounds%endg)
+
+ ! Deallocate the temporary local array point and close the file
+ deallocate(arraylocal)
+ deallocate(arraylocal_bareground)
+ call ncd_pio_closefile(ncid)
+
+ end subroutine GetLandusePFTData
+
+
!-----------------------------------------------------------------------
end module CLMFatesInterfaceMod
diff --git a/tools/contrib/tweak_latlons.py b/tools/contrib/tweak_latlons.py
new file mode 100644
index 0000000000..2bae06d229
--- /dev/null
+++ b/tools/contrib/tweak_latlons.py
@@ -0,0 +1,269 @@
+"""
+'Tweak' the latitude and longitude coordinates to avoid ambiguous nearest neighbors
+"""
+import os
+import sys
+import contextlib
+import argparse
+import numpy as np
+import xarray as xr
+from netCDF4 import Dataset # pylint: disable=no-name-in-module
+
+# -- add python/ctsm to path (needed if we want to run this stand-alone)
+_CTSM_PYTHON = os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir, os.pardir, "python")
+sys.path.insert(1, _CTSM_PYTHON)
+# pylint: disable=wrong-import-position
+from ctsm.mesh_maker import main as mesh_maker
+
+COORD_LIST = ["lat", "lon"]
+COORD_DATATYPE = np.float64
+
+def get_tweak(ds_in, coord_str, init_tweak):
+ """
+ Get the tweak that will be applied to all datasets' lat/lon coordinates
+ """
+ da = ds_in[coord_str]
+ coord2_orig = da.values.astype(COORD_DATATYPE)
+ coord2 = coord2_orig
+ tweak = init_tweak
+ coord2 += tweak
+
+ # This is necessary if precision is lower than float64
+ max_tweak = 1e-2
+ while np.any(coord2 == da.values):
+ tweak *= 10
+ if tweak > max_tweak:
+ raise RuntimeError(f"Tweaking by +{max_tweak} failed to 'take'")
+ coord2 = coord2_orig
+ coord2 += tweak
+ return tweak
+
+def apply_tweak(ds_in, coord_str, tweak):
+ # Apply tweak
+ da = ds_in[coord_str]
+ coord2 = da.values.astype(COORD_DATATYPE)
+ coord2 += tweak
+ if np.any(coord2 == da.values):
+ raise RuntimeError('Tweak didn''t "take"')
+ coord_tweak = np.full_like(coord2, tweak)
+
+ # Ensure that no value is above maximum in input data. This is needed for mesh_maker to work.
+ max_coord = np.max(da.values)
+ where_toohigh = np.where(coord2 > max_coord)
+ Ntoohigh = len(where_toohigh[0])
+ if Ntoohigh != 1:
+ raise RuntimeError(
+ f"Expected 1 coordinate value too high; got {Ntoohigh}"
+ )
+ coord2[where_toohigh] = max_coord
+ coord_tweak[where_toohigh] = max_coord
+
+ # Convert to DataArray
+ new_coords_dict = {coord_str: coord2}
+ da2 = xr.DataArray(
+ data=coord2,
+ coords=new_coords_dict,
+ dims=da.dims,
+ attrs=da.attrs,
+ )
+
+ # Replace coordinate in dataset
+ ds_in[coord_str] = da2
+
+ # Add a variable with the amount of the tweak
+ tweak_attrs = {}
+ if "standard_name" in da.attrs:
+ coord_name = da.attrs["standard_name"]
+ elif "long_name" in da.attrs:
+ coord_name = da.attrs["long_name"].replace("coordinate_", "")
+ else:
+ coord_name = coord_str
+ tweak_attrs["standard_name"] = coord_name + "_tweak"
+ tweak_attrs[
+ "long_name"
+ ] = f"Amount {coord_name} was shifted to avoid ambiguous nearest neighbors"
+ if "units" in da.attrs:
+ tweak_attrs["units"] = da.attrs["units"]
+ da_tweak = xr.DataArray(
+ data=coord_tweak,
+ coords=new_coords_dict,
+ dims=da.dims,
+ attrs=tweak_attrs,
+ )
+ tweak_name = coord_str + "_tweak"
+ ds_in[tweak_name] = da_tweak
+
+ return ds_in
+
+def check(ds, f0_base, ds2, f_base, var):
+ if not np.array_equal(ds[var].values, ds2[var].values):
+ if not np.array_equal(ds[var].shape, ds2[var].shape):
+ msg = f"{var} shapes differ b/w {f0_base} ({ds[var].shape}) and {f_base} ({ds2[var].shape})"
+ raise RuntimeError(msg)
+ max_diff = np.max(np.abs(ds[var].values - ds2[var].values))
+ msg = f"{var}s differ between {f0_base} and {f_base}; max = {max_diff}"
+ type0 = type(ds[var].values[0])
+ type2 = type(ds2[var].values[0])
+ if type0 != type2:
+ msg += f"\nTypes also differ: {type0} vs. {type2}"
+ raise RuntimeError(msg)
+
+@contextlib.contextmanager
+def redirect_argv(arglist):
+ """
+ Preserve actual arg list while giving a new one to mesh_maker
+ """
+ argv_tmp = sys.argv[:]
+ sys.argv = arglist
+ yield
+ sys.argv = argv_tmp
+
+def main(input_files, mesh_file_in, output_files):
+ """
+ Apply tweak to all files
+ """
+
+ # Set up
+ tweak_dict = {}
+ for coord in COORD_LIST:
+ tweak_dict[coord] = -np.inf
+ mesh_file_out = output_files[-1]
+ output_files = output_files[:-1]
+
+ # Get tweaks
+ for file_in in input_files:
+ ds = xr.open_dataset(file_in)
+ for coord in COORD_LIST:
+ this_tweak = get_tweak(ds, coord, init_tweak=1e-6)
+ if this_tweak > tweak_dict[coord]:
+ tweak_dict[coord] = this_tweak
+ for coord in COORD_LIST:
+ print(f"Tweaking {coord} by {tweak_dict[coord]}")
+ print(" ")
+
+ # Apply tweaks
+ for i, file_in in enumerate(input_files):
+ ds = xr.open_dataset(file_in)
+
+ for coord in COORD_LIST:
+ ds = apply_tweak(ds, coord, tweak_dict[coord])
+
+ # Set up for save
+ file_out = output_files[i]
+ with Dataset(file_in, "r") as netcdf_file:
+ netcdf_format = netcdf_file.data_model
+
+ # Make output dir, if needed
+ output_dir = os.path.dirname(file_out)
+ if not os.path.exists(output_dir):
+ os.makedirs(output_dir)
+
+ # Save
+ print(f"Saving {file_out}")
+ ds.to_netcdf(file_out, format=netcdf_format)
+ print("Done")
+
+
+ # Ensure all files got the same tweaks
+ ds = xr.open_dataset(output_files[0])
+ f0_base = os.path.basename(output_files[0])
+ for file_out in output_files[1:]:
+ ds2 = xr.open_dataset(file_out)
+ f_base = os.path.basename(file_out)
+ for coord in COORD_LIST:
+ check(ds, f0_base, ds2, f_base, coord)
+ check(ds, f0_base, ds2, f_base, coord + "_tweak")
+
+
+ # Save new mesh file
+ mesh_maker_args = [
+ "mesh_maker",
+ "--input",
+ output_files[0],
+ "--output",
+ mesh_file_out,
+ "--lat",
+ "lat",
+ "--lon",
+ "lon",
+ "--overwrite",
+ ]
+ print(f"Saving {mesh_file_out}...")
+ with redirect_argv(mesh_maker_args):
+ mesh_maker()
+
+ # Change format, if needed
+ with Dataset(mesh_file_in, "r") as netcdf_file:
+ netcdf_format_in = netcdf_file.data_model
+ with Dataset(mesh_file_out, "r") as netcdf_file:
+ netcdf_format_out = netcdf_file.data_model
+ if netcdf_format_in != netcdf_format_out:
+ mesh_file_out_tmp = mesh_file_out + ".tmp"
+ os.rename(mesh_file_out, mesh_file_out_tmp)
+ ds = xr.open_dataset(mesh_file_out_tmp)
+ ds.to_netcdf(mesh_file_out, format=netcdf_format_in)
+ os.remove(mesh_file_out_tmp)
+
+ print("Done")
+
+
+
+
+if __name__ == "__main__":
+ ###############################
+ ### Process input arguments ###
+ ###############################
+ parser = argparse.ArgumentParser(
+ description="'Tweak' the latitude and longitude coordinates to avoid ambiguous nearest neighbors",
+ )
+
+ # Required
+ parser.add_argument(
+ "-i",
+ "--input-files",
+ help="Comma-separated stream files whose coordinates need tweaking",
+ required=True,
+ )
+ parser.add_argument(
+ "-m",
+ "--mesh-file",
+ help="Mesh file associated with input files",
+ required=True,
+ )
+
+ # Optional
+ parser.add_argument(
+ "--overwrite",
+ help="Overwrite any existing output files",
+ action="store_true",
+ default=False,
+ )
+ default_output_dir = os.getcwd()
+ parser.add_argument(
+ "-o",
+ "--output-dir",
+ help=f"Directory where output files should be saved. Default is current working directory: {default_output_dir}",
+ default=default_output_dir,
+ )
+
+ # Get arguments
+ args = parser.parse_args(sys.argv[1:])
+
+ # Check/process input and output files
+ _input_files = args.input_files.split(",")
+ _output_files = []
+ for file in _input_files + [args.mesh_file]:
+ if not os.path.exists(file):
+ raise FileNotFoundError(f"File not found: {file}")
+
+ filename, ext = os.path.splitext(os.path.basename(file))
+ output_file = os.path.join(
+ args.output_dir, filename + ".tweaked_latlons" + ext
+ )
+ if os.path.exists(output_file) and not args.overwrite:
+ raise FileExistsError(
+ f"Output file exists but --overwrite not specified: {output_file}"
+ )
+ _output_files.append(output_file)
+
+ main(_input_files, args.mesh_file, _output_files)
diff --git a/tools/crop_calendars/generate_gdd20_baseline b/tools/crop_calendars/generate_gdd20_baseline
new file mode 100755
index 0000000000..a0238c8d0f
--- /dev/null
+++ b/tools/crop_calendars/generate_gdd20_baseline
@@ -0,0 +1,19 @@
+#!/usr/bin/env python3
+"""
+For description and instructions, please see README.
+"""
+
+import os
+import sys
+
+_CTSM_PYTHON = os.path.join(os.path.dirname(os.path.realpath(__file__)),
+ os.pardir,
+ os.pardir,
+ 'python')
+sys.path.insert(1, _CTSM_PYTHON)
+
+from ctsm.crop_calendars.generate_gdd20_baseline import main
+
+if __name__ == "__main__":
+ main()
+
diff --git a/tools/mksurfdata_esmf/Makefile b/tools/mksurfdata_esmf/Makefile
index d8bacdc5dd..c344843d06 100644
--- a/tools/mksurfdata_esmf/Makefile
+++ b/tools/mksurfdata_esmf/Makefile
@@ -54,7 +54,10 @@ SUBSETDATA_POINT_URBAN = $(SUBSETDATA_POINT) --include-nonveg
# Subset data sites...
SUBSETDATA_1X1_BRAZIL := --lat -7 --lon -55 --site 1x1_brazil
SUBSETDATA_1X1_NUMAIA := --lat 40.6878 --lon 267.0228 --site 1x1_numaIA
-SUBSETDATA_1X1_SMALL := --lat 40.6878 --lon 267.0228 --site 1x1_smallvilleIA \
+SUBSETDATA_1X1_SMALL_IA := --lat 40.6878 --lon 267.0228 --site 1x1_smallvilleIA \
+ --dompft 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 \
+ --pctpft 6.5 1.5 1.6 1.7 1.8 1.9 1.5 1.6 1.7 1.8 1.9 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5
+SUBSETDATA_1X1_SMALL_BR := --lat -12.9952 --lon 305.3233 --site 1x1_cidadinhoBR \
--dompft 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 \
--pctpft 6.5 1.5 1.6 1.7 1.8 1.9 1.5 1.6 1.7 1.8 1.9 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5
# NOTE: The 1850 smallvilleIA site is constructed to start with 100% natural vegetation, so we can test transition to crops
@@ -112,6 +115,7 @@ all-subset : \
1x1-smallville-present \
1x1-smallville-1850 \
1x1-smallville-transient \
+ 1x1-cidadinho-present \
urban
DEBUG:
@@ -239,7 +243,7 @@ crop-global-hist-ne30 : FORCE
$(SUBSETDATA_POINT_ALLLU) --create-surface $(SUBSETDATA_1X1_NUMAIA)
1x1-smallville-present : FORCE
- $(SUBSETDATA_POINT) --create-surface $(SUBSETDATA_1X1_SMALL)
+ $(SUBSETDATA_POINT) --create-surface $(SUBSETDATA_1X1_SMALL_IA)
# Note that the smallville 1850 dataset is entirely natural vegetation. This
# facilitates testing a transient case that starts with no crop, and then later
@@ -254,6 +258,9 @@ crop-global-hist-ne30 : FORCE
$(SUBSETDATA_POINT) --create-landuse $(SUBSETDATA_1X1_SMALLTRANSIENT)
../modify_input_files/modify_smallville.sh
+1x1-cidadinho-present : FORCE
+ $(SUBSETDATA_POINT) --create-surface $(SUBSETDATA_1X1_SMALL_BR)
+
#
# Crop with future scenarios
#