Skip to content

Commit

Permalink
Merge tag 'ctsm5.2.016' into dustcontrolincmeps
Browse files Browse the repository at this point in the history
 Enable new crop calendars for clm60 compsets

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
  • Loading branch information
ekluzek committed Jul 29, 2024
2 parents 0f9fee7 + 95fc92a commit 0c527dd
Show file tree
Hide file tree
Showing 53 changed files with 2,421 additions and 321 deletions.
2 changes: 2 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ d866510188d26d51bcd6d37239283db690af7e82
0dcd0a3c1abcaffe5529f8d79a6bc34734b195c7
e096358c832ab292ddfd22dd5878826c7c788968
475831f0fb0e31e97f630eac4e078c886558b61c
fd5f177131d63d39e79a13918390bdfb642d781e
# Ran SystemTests and python/ctsm through black python formatter
5364ad66eaceb55dde2d3d598fe4ce37ac83a93c
8056ae649c1b37f5e10aaaac79005d6e3a8b2380
Expand All @@ -49,3 +50,4 @@ aa04d1f7d86cc2503b98b7e2b2d84dbfff6c316b
665cf86102e09b4c4c5a140700676dca23bc55a9
1a49e547ba3c48fa483f9ae81a8f05adcd6b888c
045d90f1d80f713eb3ae0ac58f6c2352937f1eb0
753fda3ff0147837231a73c9c728dd9ce47b5997
146 changes: 116 additions & 30 deletions bld/CLMBuildNamelist.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1904,9 +1904,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.");
}
}

Expand Down Expand Up @@ -4223,52 +4224,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 ( $generate_crop_gdds eq '.true.' ) {
if ( $use_mxmat eq '.true.' ) {

# 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 ( &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")
}
}
}

Expand Down
39 changes: 34 additions & 5 deletions bld/namelist_files/namelist_defaults_ctsm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1909,6 +1909,8 @@ lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_ne3np4.pg3_hist_1850_78pfts_c240216.nc
lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_C96_hist_1850_78pfts_c240216.nc</fsurdat>
<fsurdat hgrid="1x1_smallvilleIA" sim_year="1850" >
lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_smallvilleIA_hist_1850_78pfts_c240221.nc</fsurdat>
<fsurdat hgrid="1x1_cidadinhoBR" sim_year="2000" >
lnd/clm2/surfdata_esmf/surfdata_1x1_cidadinhoBR_hist_2000_78pfts_c240613.nc</fsurdat>
<fsurdat hgrid="1x1_brazil" sim_year="1850">
lnd/clm2/surfdata_esmf/ctsm5.2.0/surfdata_1x1_brazil_hist_1850_78pfts_c240221.nc</fsurdat>

Expand Down Expand Up @@ -1980,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</flanduse_timeseries>


<!-- Note that this transient file only goes up to year 1855.
<!-- Note that these transient files only go up to year 1855.
This is sufficient for testing purposes, but could cause problems if you try to run beyond 1855. -->
<flanduse_timeseries hgrid="1x1_smallvilleIA" sim_year_range="1850-2000"
>lnd/clm2/surfdata_esmf/ctsm5.2.0/landuse.timeseries_1x1_smallvilleIA_SSP2-4.5_1850-1855_78pfts_c240221.nc</flanduse_timeseries>

<!-- Cidadinho test site has no transient data. -->
<flanduse_timeseries hgrid="1x1_cidadinhoBR" sim_year_range="1850-2000"></flanduse_timeseries>

<!-- Future scenarios - landuse time series files with crop on -->

<!-- SSP1-RCP2.6 - relative to {csmdata}) -->
Expand Down Expand Up @@ -2192,10 +2197,34 @@ lnd/clm2/surfdata_esmf/NEON/surfdata_1x1_NEON_TOOL_hist_78pfts_CMIP6_simyr2000_c
<lai_mapalgo hgrid="1x1_asphaltjungleNJ" >nn</lai_mapalgo>
<lai_mapalgo hgrid="5x5_amazon" >nn</lai_mapalgo>

<!-- crop calendar streams namelist defaults -->
<stream_year_first_cropcal >1850</stream_year_first_cropcal>
<stream_year_last_cropcal >2100</stream_year_last_cropcal>
<model_year_align_cropcal >1850</model_year_align_cropcal>
<!-- crop calendars: default settings -->
<cropcals_rx>.false.</cropcals_rx>
<cropcals_rx_adapt>.true.</cropcals_rx_adapt>
<cropcals_rx_adapt phys="clm4_5">.false.</cropcals_rx_adapt>
<cropcals_rx_adapt phys="clm5_0">.false.</cropcals_rx_adapt>
<cropcals_rx_adapt phys="clm5_1">.false.</cropcals_rx_adapt>
<stream_gdd20_seasons>.false.</stream_gdd20_seasons>
<flush_gdd20>.false.</flush_gdd20>
<stream_year_first_cropcal_swindows >2000</stream_year_first_cropcal_swindows>
<stream_year_last_cropcal_swindows >2000</stream_year_last_cropcal_swindows>
<model_year_align_cropcal_swindows >2000</model_year_align_cropcal_swindows>
<stream_year_first_cropcal_cultivar_gdds >2000</stream_year_first_cropcal_cultivar_gdds>
<stream_year_last_cropcal_cultivar_gdds >2000</stream_year_last_cropcal_cultivar_gdds>
<model_year_align_cropcal_cultivar_gdds >2000</model_year_align_cropcal_cultivar_gdds>

<!-- crop calendars: default input files -->
<stream_fldFileName_swindow_start cropcals_rx=".true.">lnd/clm2/cropdata/calendars/processed/swindow_starts_ggcmi_crop_calendar_phase3_v1.01.2000-2000.20231005_145103.tweaked_latlons.nc</stream_fldFileName_swindow_start>
<stream_fldFileName_swindow_end cropcals_rx=".true.">lnd/clm2/cropdata/calendars/processed/swindow_ends_ggcmi_crop_calendar_phase3_v1.01.2000-2000.20231005_145103.tweaked_latlons.nc</stream_fldFileName_swindow_end>
<stream_fldfilename_cultivar_gdds cropcals_rx=".true.">lnd/clm2/cropdata/calendars/processed/gdds_20230829_161011.tweaked_latlons.nc</stream_fldfilename_cultivar_gdds>
<stream_meshfile_cropcal cropcals_rx=".true.">lnd/clm2/cropdata/calendars/processed/360x720_120830_ESMFmesh_c20210507_cdf5.tweaked_latlons.nc</stream_meshfile_cropcal>
<stream_fldFileName_swindow_start cropcals_rx_adapt=".true.">lnd/clm2/cropdata/calendars/processed/swindow_starts_ggcmi_crop_calendar_phase3_v1.01.2000-2000.20231005_145103.tweaked_latlons.nc</stream_fldFileName_swindow_start>
<stream_fldFileName_swindow_end cropcals_rx_adapt=".true.">lnd/clm2/cropdata/calendars/processed/swindow_ends_ggcmi_crop_calendar_phase3_v1.01.2000-2000.20231005_145103.tweaked_latlons.nc</stream_fldFileName_swindow_end>
<stream_fldfilename_cultivar_gdds cropcals_rx_adapt=".true.">lnd/clm2/cropdata/calendars/processed/gdds_20230829_161011.tweaked_latlons.nc</stream_fldfilename_cultivar_gdds>
<stream_fldFileName_gdd20_baseline cropcals_rx_adapt=".true." stream_gdd20_seasons=".false.">lnd/clm2/cropdata/calendars/processed/20230714_cropcals_pr2_1deg.actually2deg.1980-2009.from_GDDB20.interpd_halfdeg.tweaked_latlons.nc</stream_fldFileName_gdd20_baseline>
<stream_fldFileName_gdd20_baseline cropcals_rx_adapt=".true." stream_gdd20_seasons=".true.">lnd/clm2/cropdata/calendars/processed/gdd20bl.copied_from.gdds_20230829_161011.v2.tweaked_latlons.nc</stream_fldFileName_gdd20_baseline>
<stream_fldFileName_gdd20_season_start stream_gdd20_seasons=".true.">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_gdd20_season_start>
<stream_fldFileName_gdd20_season_end stream_gdd20_seasons=".true.">lnd/clm2/cropdata/calendars/processed/hdates_ggcmi_crop_calendar_phase3_v1.01_nninterp-hcru_hcru_mt13.2000-2000.20230728_165845.tweaked_latlons.nc</stream_fldFileName_gdd20_season_end>
<stream_meshfile_cropcal cropcals_rx_adapt=".true.">lnd/clm2/cropdata/calendars/processed/360x720_120830_ESMFmesh_c20210507_cdf5.tweaked_latlons.nc</stream_meshfile_cropcal>

<!-- lightning streams namelist defaults -->

Expand Down
2 changes: 2 additions & 0 deletions bld/namelist_files/namelist_defaults_overall.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ determine default values for namelists.
<res sitespf_pt="1x1_urbanc_alpha" >1x1_urbanc_alpha</res>
<res sitespf_pt="1x1_numaIA" >1x1_numaIA</res>
<res sitespf_pt="1x1_smallvilleIA" >1x1_smallvilleIA</res>
<res sitespf_pt="1x1_cidadinhoBR" >1x1_cidadinhoBR</res>

<!-- Default simulation year -->
<sim_year>2000</sim_year>
Expand Down Expand Up @@ -110,6 +111,7 @@ determine default values for namelists.
<mask hgrid="1x1_urbanc_alpha" >test</mask>
<mask hgrid="1x1_numaIA" >navy</mask>
<mask hgrid="1x1_smallvilleIA" >test</mask>
<mask hgrid="1x1_cidadinhoBR" >test</mask>
<mask >gx1v7</mask>

<!-- Default glacier model options -->
Expand Down
Loading

0 comments on commit 0c527dd

Please sign in to comment.