diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 9074b8368b..45895c4a58 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -3325,12 +3325,12 @@ sub setup_logic_supplemental_nitrogen { if ( $nl_flags->{'bgc_mode'} ne "sp" && $nl_flags->{'bgc_mode'} ne "fates" && &value_is_true($nl_flags->{'use_crop'}) ) { # If this is non-fates, non-sp and crop is active add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, - 'suplnitro', 'use_cn'=>$nl_flags->{'use_cn'}, 'use_crop'=>$nl_flags->{'use_crop'}); + 'suplnitro', 'use_cn'=>$nl_flags->{'use_cn'}, 'use_crop'=>$nl_flags->{'use_crop'}); } elsif ( $nl_flags->{'bgc_mode'} eq "fates" && not &value_is_true( $nl_flags->{'use_fates_sp'}) ) { # Or... if its fates but not fates-sp add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, - 'suplnitro', 'fates_parteh_mode'=>$nl->get_value('fates_parteh_mode')); + 'suplnitro', 'fates_parteh_mode'=>remove_leading_and_trailing_quotes($nl->get_value('fates_parteh_mode'))); } # # Error checking for suplnitro @@ -3351,15 +3351,15 @@ sub setup_logic_supplemental_nitrogen { } my $parteh_mode = $nl->get_value('fates_parteh_mode'); - if ( ($parteh_mode == 1) && ($suplnitro !~ /ALL/) ) { + if ( ($parteh_mode =~ /carbon_only/i) && ($suplnitro !~ /ALL/i) ) { $log->fatal_error("supplemental Nitrogen (suplnitro) is NOT set to ALL, FATES is on, " . - "and fates_parteh_mode is 1, so Nitrogen is not active; " . + "and fates_parteh_mode = $parteh_mode, so Nitrogen is not active; " . "change suplnitro back to ALL"); } - if ( ($parteh_mode == 2) && &value_is_true( $nl_flags->{'use_fates_sp'}) ) { + if ( ($parteh_mode =~ /carbon_nitrogen/i) && &value_is_true( $nl_flags->{'use_fates_sp'}) ) { $log->fatal_error("FATES is on, " . - "FATES-SP is active, but fates_parteh_mode is 2, so Nitrogen is active; " . - "change fates_parteh_mode to 1 or do not use FATES-SP"); + "FATES-SP is active, but fates_parteh_mode = $parteh_mode, so Nitrogen is active; " . + "change fates_parteh_mode to carbon_only or do not use FATES-SP"); } } } diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index 1a2ac0df50..23e85bdf33 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -2675,7 +2675,7 @@ lnd/clm2/surfdata_esmf/NEON/ctsm5.4.0/surfdata_1x1_NEON_TOOL_hist_2000_78pfts_c2 .true. .true. .false. -1 +carbon_only 0 .true. .true. @@ -2687,7 +2687,7 @@ lnd/clm2/surfdata_esmf/NEON/ctsm5.4.0/surfdata_1x1_NEON_TOOL_hist_2000_78pfts_c2 NONE -ALL +ALL diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 93666366df..1e708b5474 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -713,8 +713,8 @@ Toggle to turn on the FATES model Functionally Assembled Terrestrial Ecosystem Simulator (FATES) - + Switch deciding which nutrient model to use in FATES. (Only relevant if FATES is on) diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2/user_nl_clm index 679f025b60..cf614522ec 100644 --- a/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2/user_nl_clm @@ -1,4 +1,4 @@ -fates_parteh_mode = 2 +fates_parteh_mode = 'carbon_nitrogen' hist_fincl1 = 'FATES_L2FR','FATES_L2FR_CANOPY_REC_PF','FATES_L2FR_USTORY_REC_PF', 'FATES_NH4UPTAKE_SZPF','FATES_NO3UPTAKE_SZPF','FATES_NEFFLUX_SZPF', 'FATES_NDEMAND_SZPF','FATES_NFIX_SYM_SZPF','FATES_NH4UPTAKE','FATES_NO3UPTAKE', diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2_synthN/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2_synthN/user_nl_clm index 679f025b60..cf614522ec 100644 --- a/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2_synthN/user_nl_clm +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdPRT2_synthN/user_nl_clm @@ -1,4 +1,4 @@ -fates_parteh_mode = 2 +fates_parteh_mode = 'carbon_nitrogen' hist_fincl1 = 'FATES_L2FR','FATES_L2FR_CANOPY_REC_PF','FATES_L2FR_USTORY_REC_PF', 'FATES_NH4UPTAKE_SZPF','FATES_NO3UPTAKE_SZPF','FATES_NEFFLUX_SZPF', 'FATES_NDEMAND_SZPF','FATES_NFIX_SYM_SZPF','FATES_NH4UPTAKE','FATES_NO3UPTAKE', diff --git a/src/main/clm_varctl.F90 b/src/main/clm_varctl.F90 index efeee0d7e7..accbf2a0e8 100644 --- a/src/main/clm_varctl.F90 +++ b/src/main/clm_varctl.F90 @@ -324,9 +324,16 @@ module clm_varctl integer, public :: fates_seeddisp_cadence = iundef ! 0 => no seed dispersal ! 1, 2, 3 => daily, monthly, or yearly dispersal - integer, public :: fates_parteh_mode = -9 ! = 1 indicated by fates_c_only is carbon only - ! = 2 indicated by fates_cnp is C+N+P, though clm cannot enable phosphorus yet, so clm needs fates_cnp_prescribed_puptake > 1 (recommended value 10) in the fates paramfile - ! no others enabled + character(len=256), public :: fates_parteh_mode = '' ! FATES Plant Allocation Reactions and Transport Hypotheses + ! = carbon_only : Cycle carbon in FATES only + ! = carbon_nitrogen: Cycle both carbon and nitrogen + ! in FATES. FATES will cycle phosphorus as well, + ! to do this, FATES will generate synthetic uptake + ! conditions to make sure that phosphorus is saturated + ! in the plant stores + ! so clm needs fates_cnp_prescribed_puptake > 1 + ! (recommended value 10) in the fates paramfile + integer, public :: fates_spitfire_mode = 0 ! 0 for no fire; 1 for constant ignitions; ! > 1 for external data (lightning and/or anthropogenic ignitions) diff --git a/src/main/clm_varpar.F90 b/src/main/clm_varpar.F90 index 9ac4b197a0..676cdeefcc 100644 --- a/src/main/clm_varpar.F90 +++ b/src/main/clm_varpar.F90 @@ -53,8 +53,16 @@ module clm_varpar integer, public, parameter :: mxpft = 78 ! maximum number of PFT's for any mode; integer, public, parameter :: mxsowings = 1 ! maximum number of crop growing seasons to begin in any year; integer, public :: mxharvests ! maximum number of crop harvests in any year - ! (allows for multiple harvests in a calendar year in case harvest occurs near + ! (allows for multiple harvests in a calendar + ! year in case harvest occurs near ! beginning/end of year); + + ! These strings define the clm-fates coupling, i.e. which chemical species + ! are cycled between the two, see corresponding values for fates_parteh_mode: + ! bld/namelist_files/namelist_definition_ctsm.xml + character(len=256), public, parameter :: clmfates_carbon_only = 'carbon_only' + character(len=256), public, parameter :: clmfates_carbon_nitrogen = 'carbon_nitrogen' + ! FIX(RF,032414) might we set some of these automatically from reading pft-physiology? integer, public, parameter :: nlayer = 3 ! number of VIC soil layer --Added by AWang integer, public :: nlayert ! number of VIC soil layer + 3 lower thermal layers diff --git a/src/main/controlMod.F90 b/src/main/controlMod.F90 index dd33f0dc9c..c72fc122d3 100644 --- a/src/main/controlMod.F90 +++ b/src/main/controlMod.F90 @@ -20,6 +20,8 @@ module controlMod use decompInitMod , only: clump_pproc use clm_varcon , only: h2osno_max use clm_varpar , only: maxpatch_glc, numrad, nlevsno + use clm_varpar , only: clmfates_carbon_only + use clm_varpar , only: clmfates_carbon_nitrogen use fileutils , only: getavu, relavu, get_filename use histFileMod , only: max_tapes, max_namlen use histFileMod , only: hist_empty_htapes, hist_dov2xy, hist_avgflag_pertape, hist_type1d_pertape @@ -51,7 +53,7 @@ module controlMod use CanopyFluxesMod , only: CanopyFluxesReadNML use shr_drydep_mod , only: n_drydep use clm_varctl - use PRTGenericMod, only : fates_cnp, fates_c_only + ! ! !PUBLIC TYPES: implicit none @@ -492,19 +494,19 @@ subroutine control_init(dtime) use_fates_bgc = .true. end if - if (fates_parteh_mode == fates_c_only .and. suplnitro == suplnNon)then - write(iulog,*) ' When fates_parteh_mode == fates_c_only,' + if (trim(fates_parteh_mode) == trim(clmfates_carbon_only) .and. suplnitro == suplnNon)then + write(iulog,*) ' When fates_parteh_mode == carbon_only,' write(iulog,*) ' you must have supplemental nitrogen turned on, there will be' write(iulog,*) ' no nitrogen dynamics with the plants, and therefore no' write(iulog,*) ' meaningful limitations to nitrogen.' - call endrun(msg=' ERROR: fates_parteh_mode=fates_c_only must have suplnitro set to suplnAll.'//& + call endrun(msg=' ERROR: fates_parteh_mode=carbon_only must have suplnitro set to suplnAll.'//& errMsg(sourcefile, __LINE__)) end if - if (fates_parteh_mode == fates_cnp .and. use_fates_sp )then - write(iulog,*) ' When fates_parteh_mode == fates_cnp,' + if (trim(fates_parteh_mode) == trim(clmfates_carbon_nitrogen) .and. use_fates_sp )then + write(iulog,*) ' When fates_parteh_mode == carbon_nirogen,' write(iulog,*) ' you must have use_fates_bgc and not use_fates_sp.' - write(iulog,*) ' When you have use_fates_sp, then fates_parteh_mode should equal fates_c_only.' - call endrun(msg=' ERROR: fates_parteh_mode=fates_cnp and use_fates_sp are inconsistent.'//& + write(iulog,*) ' When you have use_fates_sp, then fates_parteh_mode should equal carbon_only.' + call endrun(msg=' ERROR: fates_parteh_mode=carbon_nitrogen and use_fates_sp are inconsistent.'//& errMsg(sourcefile, __LINE__)) end if @@ -856,7 +858,7 @@ subroutine control_spmd() call mpi_bcast (flandusepftdat, len(flandusepftdat) , MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (use_fates_managed_fire, 1, MPI_LOGICAL, 0, mpicom, ier) - call mpi_bcast (fates_parteh_mode, 1, MPI_INTEGER, 0, mpicom, ier) + call mpi_bcast (fates_parteh_mode, len(fates_parteh_mode), MPI_CHARACTER, 0, mpicom, ier) call mpi_bcast (fates_seeddisp_cadence, 1, MPI_INTEGER, 0, mpicom, ier) call mpi_bcast (fates_history_dimlevel, 2, MPI_INTEGER, 0, mpicom, ier) diff --git a/src/soilbiogeochem/SoilBiogeochemCompetitionMod.F90 b/src/soilbiogeochem/SoilBiogeochemCompetitionMod.F90 index 607cdc93b4..a8a7c5366e 100644 --- a/src/soilbiogeochem/SoilBiogeochemCompetitionMod.F90 +++ b/src/soilbiogeochem/SoilBiogeochemCompetitionMod.F90 @@ -176,8 +176,8 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu soilbiogeochem_nitrogenflux_inst,canopystate_inst, clm_fates) ! ! !USES: - use PRTGenericMod, only : fates_cnp use clm_varctl , only: fates_parteh_mode, allocate_carbon_only, iulog + use clm_varpar , only: clmfates_carbon_only,clmfates_carbon_nitrogen use clm_varpar , only: nlevdecomp, ndecomp_cascade_transitions use clm_varpar , only: i_cop_mic, i_oli_mic use clm_varcon , only: nitrif_n2o_loss_frac @@ -345,7 +345,7 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu do j = 1, nlevdecomp plant_ndemand_vr(c,j) = 0._r8 - if (fates_parteh_mode == fates_cnp) then + if (trim(fates_parteh_mode) == trim(clmfates_carbon_nitrogen)) then do f = 1, n_pcomp ft = clm_fates%fates(ci)%bc_out(s)%ft_index(f) @@ -612,7 +612,7 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu do j = 1, nlevdecomp plant_ndemand_vr(c,j) = 0._r8 - if (fates_parteh_mode == fates_cnp) then + if (trim(fates_parteh_mode) == trim(clmfates_carbon_nitrogen))then do f = 1, n_pcomp ft = clm_fates%fates(ci)%bc_out(s)%ft_index(f) @@ -1094,7 +1094,8 @@ subroutine SoilBiogeochemCompetition (bounds, num_bgc_soilc, filter_bgc_soilc,nu s = clm_fates%f2hmap(ci)%hsites(c) n_pcomp = clm_fates%fates(ci)%bc_out(s)%num_plant_comps - ! if fates_parteh_mode /= fates_cnp then plant_ndemand = 0 and this if-statement gets skipped + ! if fates_parteh_mode /= clmfates_carbon_nitrogen then + ! plant_ndemand = 0 and this if-statement gets skipped if ( plant_ndemand(c) > tiny(plant_ndemand(c)) ) then do f = 1, n_pcomp ft = clm_fates%fates(ci)%bc_out(s)%ft_index(f) diff --git a/src/utils/clmfates_interfaceMod.F90 b/src/utils/clmfates_interfaceMod.F90 index f086b24cb6..dab361a894 100644 --- a/src/utils/clmfates_interfaceMod.F90 +++ b/src/utils/clmfates_interfaceMod.F90 @@ -46,7 +46,7 @@ module CLMFatesInterfaceMod use CNProductsMod , only : cn_products_type use clm_varctl , only : iulog use clm_varctl , only : fates_parteh_mode - use PRTGenericMod , only : fates_cnp + use PRTGenericMod , only : carbon_only,carbon_nitrogen_phosphorus use clm_varctl , only : use_fates use clm_varctl , only : fates_spitfire_mode use clm_varctl , only : use_fates_managed_fire @@ -93,6 +93,8 @@ module CLMFatesInterfaceMod use clm_varpar , only : nlevdecomp use clm_varpar , only : nlevdecomp_full use clm_varpar , only : nlevsoi + use clm_varpar , only : clmfates_carbon_only + use clm_varpar , only : clmfates_carbon_nitrogen use PhotosynthesisMod , only : photosyns_type use atm2lndType , only : atm2lnd_type use SurfaceAlbedoType , only : surfalb_type @@ -314,6 +316,7 @@ subroutine CLMFatesGlobals1(surf_numpft,surf_numcft,maxsoil_patches) integer :: pass_use_sp integer :: pass_masterproc integer :: pass_use_luh2 + integer :: pass_parteh_mode logical :: verbose_output call t_startf('fates_globals1') @@ -364,8 +367,24 @@ subroutine CLMFatesGlobals1(surf_numpft,surf_numcft,maxsoil_patches) end if call set_fates_ctrlparms('use_luh2',ival=pass_use_luh2) - - call set_fates_ctrlparms('parteh_mode',ival=fates_parteh_mode) + if(trim(fates_parteh_mode)==trim(clmfates_carbon_only))then + pass_parteh_mode = carbon_only + elseif(trim(fates_parteh_mode)==trim(clmfates_carbon_nitrogen))then + ! FATES has NO carbon_nitrogen mode. It cycles + ! either carbon alone, or carbon with both nutrients + ! If we want to couple nitrogen, we tell FATES + ! to use synthetic uptake conditions for phosphorus, which + ! most likely will be ample so that P stores in plants + ! are saturated and non-limiting + pass_parteh_mode = carbon_nitrogen_phosphorus + else + write(iulog,*) 'FATES coupling mode must be either' + write(iulog,*) trim(clmfates_carbon_only),' or ' + write(iulog,*) trim(clmfates_carbon_nitrogen) + write(iulog,*) 'you specified: ',trim(fates_parteh_mode) + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if + call set_fates_ctrlparms('parteh_mode',ival=pass_parteh_mode) end if @@ -2809,7 +2828,7 @@ subroutine wrap_WoodProducts(this, bounds_clump, num_soilc, filter_soilc, & this%fates(ci)%bc_out(s)%hrv_deadstemc_to_prod100c ! If N cycling is on - if (fates_parteh_mode == fates_cnp) then + if ( trim(fates_parteh_mode)==trim(clmfates_carbon_nitrogen) ) then n_products_inst%hrv_deadstem_to_prod10_grc(g) = & n_products_inst%hrv_deadstem_to_prod10_grc(g) + &