Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix cam dust emiss control #2699

Merged
merged 25 commits into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7d8d0f6
Add failing tests for running with dust set by CAM so LND_SETS_DUST_E…
ekluzek Aug 14, 2024
a590ca7
When LND_SETS_DUST_EMIS_DRV_FLDS is FALSE read in CAM drv_flds_in nam…
ekluzek Aug 15, 2024
733cf99
Add missing cmeps drv_flds_in variables fixing #2170
ekluzek Aug 15, 2024
3f3541b
Current drv_flds_in file from CAM for a FHIST case, including some fi…
ekluzek Aug 15, 2024
6268e59
Add megan and drydep settings as per a cam6_4_015 SMS_Ln9.f19_f19_mg1…
ekluzek Aug 16, 2024
e9b629d
Simplify the validation checking for megan specifier as the expressio…
ekluzek Aug 16, 2024
53a1874
CAM_SETS_DRV_FLDS tests don't need to have drv_flds_in settings to be…
ekluzek Aug 21, 2024
717f957
Get working with bringing in CAM drv_flds_in
ekluzek Aug 21, 2024
786252b
Merge remote-tracking branch 'escomp/b4b-dev' into fix_cam_dust_emiss…
ekluzek Aug 21, 2024
406edd4
Add some comments about some of this being temporary and point to the…
ekluzek Aug 22, 2024
fa7f8f5
Fix bug in setting of init_interp_attributes that should have been fo…
ekluzek Aug 22, 2024
796bd83
Get the megan_spec checker working for identifying bad characters in …
ekluzek Aug 22, 2024
b2d7edf
Duplicate a bunch of XML so that the namelist unit tester works for a…
ekluzek Aug 22, 2024
be5d1d6
Change fatal error to warning for megan_specifier
ekluzek Aug 22, 2024
a5a15ed
Correct test number and remove fail tests that are now allowed to hap…
ekluzek Aug 22, 2024
ae4d423
Merge remote-tracking branch 'escomp/b4b-dev' into fix_cam_dust_emiss…
ekluzek Aug 22, 2024
b35320a
Also include the mizuRoute expected fails list
ekluzek Dec 8, 2021
463e85d
Add bit from SLIM that includes what parts FAIL when reporting summar…
ekluzek Jan 20, 2022
8fbfcc0
Add an extra tab
ekluzek Jan 25, 2022
0d1a867
Make a little subroutine to check the expected fails
ekluzek Aug 26, 2024
cd6a94b
Report on the expected fails for tests
ekluzek Aug 26, 2024
c5aeec6
Add some more notes about -drydep, -fire_emis, -no-megan options opti…
ekluzek Aug 27, 2024
46a09d9
Update some of the documentation around the -drydep, -fire_emis and -…
ekluzek Aug 27, 2024
9a44188
Update documentation around the drv_flds_in testing namelists and com…
ekluzek Aug 27, 2024
d8377a8
Merge remote-tracking branch 'escomp/b4b-dev' into fix_cam_dust_emiss…
ekluzek Aug 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 87 additions & 84 deletions bld/CLMBuildNamelist.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1449,7 +1449,7 @@ sub setup_cmdl_vichydro {

sub process_namelist_commandline_namelist {
# Process the commandline '-namelist' arg.
my ($opts, $definition, $nl, $envxml_ref) = @_;
my ($opts, $definition, $nl, $envxml_ref, %settings) = @_;

if (defined $opts->{'namelist'}) {
# Parse commandline namelist
Expand All @@ -1470,6 +1470,32 @@ sub process_namelist_commandline_namelist {
}
}

sub process_namelist_infile {
my ($definition, $nl, $envxml_ref, $infile, %settings) = @_;

# Make sure a valid file was found
if ( -f "$infile" ) {
# Otherwise abort as a valid file doesn't exist
} else {
$log->fatal_error("input namelist file does NOT exist $infile.\n $@");
}
# Parse namelist input from the next file
my $nl_infile = Build::Namelist->new($infile);

# Validate input namelist -- trap exceptions
my $nl_infile_valid;
eval { $nl_infile_valid = $definition->validate($nl_infile); };
if ($@) {
$log->fatal_error("Invalid namelist variable in '-infile' $infile.\n $@");
}
# Go through all variables and expand any XML env settings in them
expand_xml_variables_in_namelist( $nl_infile_valid, $envxml_ref );

# Merge input values into namelist. Previously specified values have higher precedence
# and are not overwritten.
$nl->merge_nl($nl_infile_valid, %settings);
}

#-------------------------------------------------------------------------------

sub process_namelist_commandline_infile {
Expand All @@ -1479,27 +1505,7 @@ sub process_namelist_commandline_infile {
if (defined $opts->{'infile'}) {
my @infiles = split( /,/, $opts->{'infile'} );
foreach my $infile ( @infiles ) {
# Make sure a valid file was found
if ( -f "$infile" ) {
# Otherwise abort as a valid file doesn't exist
} else {
$log->fatal_error("input namelist file does NOT exist $infile.\n $@");
}
# Parse namelist input from the next file
my $nl_infile = Build::Namelist->new($infile);

# Validate input namelist -- trap exceptions
my $nl_infile_valid;
eval { $nl_infile_valid = $definition->validate($nl_infile); };
if ($@) {
$log->fatal_error("Invalid namelist variable in '-infile' $infile.\n $@");
}
# Go through all variables and expand any XML env settings in them
expand_xml_variables_in_namelist( $nl_infile_valid, $envxml_ref );

# Merge input values into namelist. Previously specified values have higher precedence
# and are not overwritten.
$nl->merge_nl($nl_infile_valid);
process_namelist_infile( $definition, $nl, $envxml_ref, $infile );
}
}
}
Expand Down Expand Up @@ -1750,25 +1756,29 @@ sub process_namelist_inline_logic {
##################################
setup_logic_lightning_streams($opts, $nl_flags, $definition, $defaults, $nl);

#################################
# namelist group: drydep_inparm #
#################################
setup_logic_dry_deposition($opts, $nl_flags, $definition, $defaults, $nl);

#################################
# namelist group: fire_emis_nl #
#################################
setup_logic_fire_emis($opts, $nl_flags, $definition, $defaults, $nl);

######################################
############################################################################################
# namelist options for dust emissions
######################################
# NOTE: This MUST be done before other drv_flds_in settings (megan, drydep, fire_emis etc.)
############################################################################################
setup_logic_dust_emis($opts, $nl_flags, $definition, $defaults, $nl, $envxml_ref);
setup_logic_prigent_roughness($opts, $nl_flags, $definition, $defaults, $nl);

#################################
# namelist group: megan_emis_nl #
#################################
#####################################
# namelist group: drydep_inparm #
# NOTE: After setup_logic_dust_emis #
#####################################
setup_logic_dry_deposition($opts, $nl_flags, $definition, $defaults, $nl);

#####################################
# namelist group: fire_emis_nl #
# NOTE: After setup_logic_dust_emis #
#####################################
setup_logic_fire_emis($opts, $nl_flags, $definition, $defaults, $nl);

#####################################
# namelist group: megan_emis_nl #
# NOTE: After setup_logic_dust_emis #
#####################################
setup_logic_megan($opts, $nl_flags, $definition, $defaults, $nl);

##################################
Expand Down Expand Up @@ -3992,17 +4002,18 @@ sub setup_logic_lightning_streams {
sub setup_logic_dry_deposition {
my ($opts, $nl_flags, $definition, $defaults, $nl) = @_;

my @list = ( "drydep_list", "dep_data_file");
if ($opts->{'drydep'} ) {
if ( &value_is_true( $nl_flags->{'use_fates'}) && not &value_is_true( $nl_flags->{'use_fates_sp'}) ) {
$log->warning("DryDeposition can NOT be on when FATES is also on unless FATES-SP mode is on.\n" .
" Use the '--no-drydep' option when '-bgc fates' is activated");
}
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'drydep_list');
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'dep_data_file');
} else {
if ( defined($nl->get_value('drydep_list')) ) {
$log->fatal_error("drydep_list defined, but drydep option NOT set");
}
}
if ( &value_is_true( $nl_flags->{'use_fates'}) && not &value_is_true( $nl_flags->{'use_fates_sp'}) ) {
foreach my $var ( @list ) {
if ( defined($nl->get_value($var)) ) {
$log->warning("DryDeposition $var is being set and can NOT be on when FATES is also on unless FATES-SP mode is on.\n" .
" Use the '--no-drydep' option when '-bgc fates' is activated");
}
}
}
}

Expand All @@ -4011,20 +4022,20 @@ sub setup_logic_dry_deposition {
sub setup_logic_fire_emis {
my ($opts, $nl_flags, $definition, $defaults, $nl) = @_;

my @list = ( "fire_emis_eleveated", "fire_emis_factors_file", "fire_emis_specifier");

if ($opts->{'fire_emis'} ) {
if ( &value_is_true( $nl_flags->{'use_fates'} ) ) {
$log->warning("Fire emission can NOT be on when FATES is also on.\n" .
" DON'T use the '-fire_emis' option when '-bgc fates' is activated");
}
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fire_emis_factors_file');
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'fire_emis_specifier');
} else {
if ( defined($nl->get_value('fire_emis_elevated')) ||
defined($nl->get_value('fire_emis_factors_file')) ||
defined($nl->get_value('fire_emis_specifier')) ) {
$log->fatal_error("fire_emission setting defined: fire_emis_elevated, fire_emis_factors_file, or fire_emis_specifier, but fire_emis option NOT set");
}
}
foreach my $var ( @list ) {
if ( defined($nl->get_value($var)) ) {
if ( &value_is_true( $nl_flags->{'use_fates'} ) ) {
$log->warning("Fire emission option $var can NOT be on when FATES is also on.\n" .
" DON'T use the '--fire_emis' option when '--bgc fates' is activated");
}
}
}
}

#-------------------------------------------------------------------------------
Expand All @@ -4034,6 +4045,8 @@ sub setup_logic_dust_emis {
my ($opts, $nl_flags, $definition, $defaults, $nl, $envxml_ref) = @_;

# Only set dust emission settings -- if not connected to CAM
# Longer term plan is to remove this logic and have CTSM just set it and for CAM to use what CLM decides
# See: https://github.com/ESCOMP/CTSM/issues/2713
my $lnd_sets_dust = logical_to_fortran($envxml_ref->{'LND_SETS_DUST_EMIS_DRV_FLDS'});
if ( &value_is_true( $lnd_sets_dust)) {

Expand Down Expand Up @@ -4086,6 +4099,14 @@ sub setup_logic_dust_emis {
" connected to CAM as CAM should set them");
}
}
# Now process the CAM drv_flds_in to get the dust settings
# This requires that the CAM drv_flds_in namelist be created BEFORE CLM
# and that the path below NOT be changed. Hence, there's some fragility here
# to future changes.
my $infile = $opts->{'envxml_dir'} . "/Buildconf/camconf/drv_flds_in";
$log->verbose_message("Read in the drv_flds_in file generated by CAM's build-namelist");
# When merging the CAM namelist in -- die with an error if there's a conflict between CAM and CLM
process_namelist_infile( $definition, $nl, $envxml_ref, $infile, 'die_on_conflict'=>1 );
}
}

Expand All @@ -4106,17 +4127,15 @@ sub setup_logic_megan {
}

if ($nl_flags->{'megan'} ) {
if ( &value_is_true( $nl_flags->{'use_fates'} ) ) {
$log->warning("MEGAN can NOT be on when FATES is also on.\n" .
" Use the '-no-megan' option when '-bgc fates' is activated");
}
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'megan_specifier');
check_megan_spec( $opts, $nl, $definition );
add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'megan_factors_file');
} else {
if ( defined($nl->get_value('megan_specifier')) ||
}
if ( defined($nl->get_value('megan_specifier')) ||
defined($nl->get_value('megan_factors_file')) ) {
$log->fatal_error("megan_specifier or megan_factors_file defined, but megan option NOT set");
check_megan_spec( $opts, $nl, $definition );
if ( &value_is_true( $nl_flags->{'use_fates'} ) ) {
$log->warning("MEGAN can NOT be on when FATES is also on.\n" .
" Use the '-no-megan' option when '-bgc fates' is activated");
}
}
}
Expand Down Expand Up @@ -5643,27 +5662,11 @@ sub check_megan_spec {

my $megan_spec = $nl->get_value('megan_specifier');
my @megan_spec_list = split( /\s*,\s*/, $megan_spec );
foreach $megan_spec ( @megan_spec_list ) {
if ( $megan_spec =~ /^['"]+[A-Za-z0-9]+\s*\=\s*([\sA-Za-z0-9+_-]+)["']+$/ ) {
my $megan_list = $1;
my @megan_cmpds = split( /\s*\+\s*/, $megan_list );
my $var = "megan_cmpds";
my $warn = 0;
foreach my $megan_cmpd ( @megan_cmpds ) {
if ( ! $definition->is_valid_value( $var, $megan_cmpd, 'noquotes'=>1 ) ) {
$log->warning("megan_compound $megan_cmpd NOT found in list" );
$warn++;
}
}
if ( $warn > 0 ) {
my @valid_values = $definition->get_valid_values( $var, 'noquotes'=>1 );
$log->warning("list of megan compounds includes:\n" .
"@valid_values\n" .
"Does your megan_factors_file include more compounds?\n" .
"If NOT your simulation will fail." );
}
} else {
$log->fatal_error("Bad format for megan_specifier = $megan_spec");
foreach my $spec ( @megan_spec_list ) {
$megan_spec = remove_leading_and_trailing_quotes($spec);
# Do simple validation of the expressions to just check for valid characters
if ( $megan_spec !~ /^([\s=A-Za-z0-9_\+\.\*\(\)-]+)$/ ) {
$log->warning("Bad format for megan_specifier = $megan_spec");
}
}
}
Expand Down
48 changes: 44 additions & 4 deletions bld/namelist_files/namelist_defaults_ctsm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1059,12 +1059,12 @@ attributes from the config_cache.xml file (with keys converted to upper-case).
>hgrid=1.9x2.5 maxpft=17 mask=gx1v7 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
</init_interp_attributes>

<init_interp_attributes sim_year="1979" use_cndv=".false." use_fates=".false." lnd_tuning_mode="clm6_0_cam7.0"
<init_interp_attributes sim_year="1979" use_cndv=".false." use_fates=".false." lnd_tuning_mode="clm5_0_cam7.0"
hgrid="ne0np4.ARCTIC.ne30x4" use_cn=".false." maxpft="17"
>hgrid=ne0np4.ARCTIC.ne30x4 maxpft=17 mask=tx0.1v2 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
</init_interp_attributes>

<init_interp_attributes sim_year="1979" use_cndv=".false." use_fates=".false." lnd_tuning_mode="clm6_0_cam7.0"
<init_interp_attributes sim_year="1979" use_cndv=".false." use_fates=".false." lnd_tuning_mode="clm5_0_cam7.0"
hgrid="ne0np4.ARCTICGRIS.ne30x8" use_cn=".false." maxpft="17"
>hgrid=ne0np4.ARCTICGRIS.ne30x8 maxpft=17 mask=tx0.1v2 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
</init_interp_attributes>
Expand Down Expand Up @@ -1144,6 +1144,26 @@ attributes from the config_cache.xml file (with keys converted to upper-case).
>hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
</init_interp_attributes>

<init_interp_attributes sim_year="1979" use_cndv=".false." use_fates=".false." lnd_tuning_mode="clm5_0_cam6.0"
hgrid="0.9x1.25" use_cn=".false." maxpft="17"
>hgrid=0.9x1.25 maxpft=17 mask=gx1v7 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
</init_interp_attributes>

<init_interp_attributes sim_year="1979" use_cndv=".false." use_fates=".false." lnd_tuning_mode="clm5_0_cam6.0"
hgrid="1.9x2.5" use_cn=".false." maxpft="17"
>hgrid=1.9x2.5 maxpft=17 mask=gx1v7 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
</init_interp_attributes>

<init_interp_attributes sim_year="1979" use_cndv=".false." use_fates=".false." lnd_tuning_mode="clm5_0_cam6.0"
hgrid="ne0np4.ARCTIC.ne30x4" use_cn=".false." maxpft="17"
>hgrid=ne0np4.ARCTIC.ne30x4 maxpft=17 mask=tx0.1v2 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
</init_interp_attributes>

<init_interp_attributes sim_year="1979" use_cndv=".false." use_fates=".false." lnd_tuning_mode="clm5_0_cam6.0"
hgrid="ne0np4.ARCTICGRIS.ne30x8" use_cn=".false." maxpft="17"
>hgrid=ne0np4.ARCTICGRIS.ne30x8 maxpft=17 mask=tx0.1v2 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
</init_interp_attributes>

<!-- clm5_1 physics -->
<init_interp_attributes sim_year="2000" use_cndv=".false." use_fates=".false." lnd_tuning_mode="clm5_1_cam6.0"
>hgrid=0.9x1.25 maxpft=79 mask=gx1v7 use_cn=.true. use_crop=.true. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
Expand Down Expand Up @@ -1193,12 +1213,12 @@ attributes from the config_cache.xml file (with keys converted to upper-case).


<!-- If an exact match for these grids and start years -->
<init_interp_attributes sim_year="1979" use_cndv=".false." use_fates=".false." lnd_tuning_mode="clm5_0_cam6.0"
<init_interp_attributes sim_year="1979" use_cndv=".false." use_fates=".false." lnd_tuning_mode="clm6_0_cam6.0"
hgrid="0.9x1.25" use_cn=".false." maxpft="17"
>hgrid=0.9x1.25 maxpft=17 mask=gx1v7 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
</init_interp_attributes>

<init_interp_attributes sim_year="1979" use_cndv=".false." use_fates=".false." lnd_tuning_mode="clm5_0_cam6.0"
<init_interp_attributes sim_year="1979" use_cndv=".false." use_fates=".false." lnd_tuning_mode="clm6_0_cam6.0"
hgrid="1.9x2.5" use_cn=".false." maxpft="17"
>hgrid=1.9x2.5 maxpft=17 mask=gx1v7 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
</init_interp_attributes>
Expand All @@ -1213,6 +1233,26 @@ attributes from the config_cache.xml file (with keys converted to upper-case).
>hgrid=ne0np4.ARCTICGRIS.ne30x8 maxpft=17 mask=tx0.1v2 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
</init_interp_attributes>

<init_interp_attributes sim_year="1979" use_cndv=".false." use_fates=".false." lnd_tuning_mode="clm6_0_cam7.0"
hgrid="0.9x1.25" use_cn=".false." maxpft="17"
>hgrid=0.9x1.25 maxpft=17 mask=gx1v7 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
</init_interp_attributes>

<init_interp_attributes sim_year="1979" use_cndv=".false." use_fates=".false." lnd_tuning_mode="clm6_0_cam7.0"
hgrid="1.9x2.5" use_cn=".false." maxpft="17"
>hgrid=1.9x2.5 maxpft=17 mask=gx1v7 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
</init_interp_attributes>

<init_interp_attributes sim_year="1979" use_cndv=".false." use_fates=".false." lnd_tuning_mode="clm6_0_cam7.0"
hgrid="ne0np4.ARCTIC.ne30x4" use_cn=".false." maxpft="17"
>hgrid=ne0np4.ARCTIC.ne30x4 maxpft=17 mask=tx0.1v2 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
</init_interp_attributes>

<init_interp_attributes sim_year="1979" use_cndv=".false." use_fates=".false." lnd_tuning_mode="clm6_0_cam7.0"
hgrid="ne0np4.ARCTICGRIS.ne30x8" use_cn=".false." maxpft="17"
>hgrid=ne0np4.ARCTICGRIS.ne30x8 maxpft=17 mask=tx0.1v2 use_cn=.false. use_crop=.false. irrigate=.true. glc_nec=10 do_transient_pfts=.false.
</init_interp_attributes>

<!-- 2003 -->
<init_interp_attributes sim_year="2003" use_cndv=".false." use_fates=".false." lnd_tuning_mode="clm5_0_cam6.0"
hgrid="1.9x2.5" use_cn=".false." maxpft="17"
Expand Down
27 changes: 27 additions & 0 deletions bld/namelist_files/namelist_definition_drv_flds.xml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@
List of fluxes needed by the CARMA model, from CLM to CAM.
</entry>

<!-- ======================================================================================== -->
<!-- DUST Emission fields -->
<!-- ======================================================================================== -->

<entry id="dust_emis_method" type="char*80" category="dust_emissions"
group="dust_emis_inparm" valid_values="Zender_2003,Leung_2023" >
Which dust emission method is going to be used. Either the Zender 2003 scheme or the Leung 2023 scheme.
Expand All @@ -136,4 +140,27 @@
(only used when dust_emis_method is Zender_2003)
</entry>

<!-- ======================================================================================== -->
<!-- Ozone to surface -->
<!-- ======================================================================================== -->

<entry id="atm_ozone_frequency" type="char*64" category="ozone_coupling"
group="ozone_coupling_nl" valid_values="subdaily,multiday_average">
Frequency of surface ozone field passed from CAM to surface components.
Surface ozone is passed every coupling interval, but this namelist flag
indicates whether the timestep-level values are interpolated from a
coarser temporal resolution.
Default: set by CAM
</entry>

<!-- ======================================================================================== -->
<!-- Lightning -->
<!-- ======================================================================================== -->

<entry id="atm_provides_lightning" type="logical" category="lightning_coupling"
group="lightning_coupling_nl" valid_values="">
If TRUE atmosphere model will provide prognosed lightning flash frequency.
(NOTE: NOT CONNECTED INTO CTSM YET)
</entry>

</namelist_definition>
Loading
Loading