diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index c2d23ce962..c6a613d449 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -97,7 +97,7 @@ 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. @@ -521,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 @@ -1041,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."); } } @@ -1762,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 # @@ -2335,7 +2336,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 ) { @@ -2676,8 +2677,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); @@ -3220,7 +3221,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 # @@ -3727,10 +3727,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'}, @@ -4025,50 +4025,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_mode'=>$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"); + } + } } } @@ -4661,8 +4676,8 @@ sub setup_logic_fates { 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"); } @@ -5066,7 +5081,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 5f336dabf8..3594fe5c38 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -2488,8 +2488,6 @@ 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 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_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 50b9f8272d..9cbcc5e692 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -1698,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 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 e8c198501a..5bccb3b77c 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 = 3314; +my $ntests = 3329; if ( defined($opts{'compare'}) ) { - $ntests += 2052; + $ntests += 1999; } plan( tests=>$ntests ); @@ -499,427 +499,342 @@ 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", }, "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 .", @@ -999,340 +914,284 @@ sub cat_and_create_namelistinfile { }, "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=>"fates_harvest_mode='event_code'", - GLC_TWO_WAY_COUPLING=>"FALSE", 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", }, "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.", - GLC_TWO_WAY_COUPLING=>"FALSE", 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", - GLC_TWO_WAY_COUPLING=>"FALSE", 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", - GLC_TWO_WAY_COUPLING=>"FALSE", phys=>"clm5_0", }, "useFATESHARVEST3WOLUH" =>{ options=>"-bgc fates -envxml_dir . -no-megan", namelst=>"use_fates_luh=F,fates_harvest_mode='luhdata_area'", - GLC_TWO_WAY_COUPLING=>"FALSE", phys=>"clm5_0", }, "useFATESLUPFTWOLUH" =>{ options=>"-bgc fates -envxml_dir . -no-megan", namelst=>"use_fates_lupft=T,use_fates_luh=F", - GLC_TWO_WAY_COUPLING=>"FALSE", phys=>"clm5_0", }, "useFATESLUPFTWONOCOMP" =>{ options=>"-bgc fates -envxml_dir . -no-megan", namelst=>"use_fates_lupft=T,use_fates_nocomp=F", - GLC_TWO_WAY_COUPLING=>"FALSE", phys=>"clm5_0", }, "useFATESLUPFTWOFBG" =>{ options=>"-bgc fates -envxml_dir . -no-megan", namelst=>"use_fates_lupft=T,use_fates_fixedbiogeog=F", - GLC_TWO_WAY_COUPLING=>"FALSE", 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", }, "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) ) { @@ -1340,7 +1199,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" ); @@ -1357,52 +1222,42 @@ 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", }, "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", }, ); @@ -1677,7 +1532,11 @@ sub cat_and_create_namelistinfile { # Check for crop resolutions my @crop1850_res = ( "1x1_smallvilleIA", "1x1_cidadinhoBR" ); foreach my $res ( @crop1850_res ) { - $options = "-bgc bgc -crop -res $res -use_case 1850_control -envxml_dir ."; + 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" ); @@ -1726,7 +1585,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", 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/config_component.xml b/cime_config/config_component.xml index a7e2a898aa..3c48e16651 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -166,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 diff --git a/doc/ChangeLog b/doc/ChangeLog index 79d640242d..aeb7b2972f 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,4 +1,125 @@ =============================================================== +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 diff --git a/doc/ChangeSum b/doc/ChangeSum index 382e5cf7cb..15a67bcf04 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,5 +1,6 @@ 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. 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/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/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/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/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/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/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/main/clm_varctl.F90 b/src/main/clm_varctl.F90 index 2556626d79..73d528fbc5 100644 --- a/src/main/clm_varctl.F90 +++ b/src/main/clm_varctl.F90 @@ -276,11 +276,6 @@ 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 !---------------------------------------------------------- diff --git a/src/main/controlMod.F90 b/src/main/controlMod.F90 index c5c5bd9f64..787b827605 100644 --- a/src/main/controlMod.F90 +++ b/src/main/controlMod.F90 @@ -213,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