diff --git a/Externals_CLM.cfg b/Externals_CLM.cfg index c540fe8b0c..14ba14d8b4 100644 --- a/Externals_CLM.cfg +++ b/Externals_CLM.cfg @@ -2,7 +2,7 @@ local_path = src/fates protocol = git repo_url = https://github.com/NGEET/fates -tag = sci.1.67.1_api.27.0.0 +tag = sci.1.67.2_api.27.0.0 required = True [externals_description] diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 54a6aea7e4..72c3b1b74a 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -3890,8 +3890,7 @@ sub setup_logic_lai_streams { if ( &value_is_true($nl_flags->{'use_crop'}) && &value_is_true($nl->get_value('use_lai_streams')) ) { $log->fatal_error("turning use_lai_streams on is incompatable with use_crop set to true."); } - if ( $nl_flags->{'bgc_mode'} eq "sp" ) { - + if ( $nl_flags->{'bgc_mode'} eq "sp" || ($nl_flags->{'bgc_mode'} eq "fates" && &value_is_true($nl->get_value('use_fates_sp')) )) { if ( &value_is_true($nl->get_value('use_lai_streams')) ) { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'use_lai_streams'); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'lai_mapalgo', @@ -3917,15 +3916,20 @@ sub setup_logic_lai_streams { } } } else { - # If bgc is CN/CNDV then make sure none of the LAI settings are set - if ( defined($nl->get_value('stream_year_first_lai')) || - defined($nl->get_value('stream_year_last_lai')) || - defined($nl->get_value('model_year_align_lai')) || - defined($nl->get_value('lai_tintalgo' )) || + # If bgc is BGC/BGCDV then make sure none of the LAI settings are set + if ( &value_is_true($nl->get_value('use_lai_streams'))) { + $log->fatal_error("When not in SP mode use_lai_streams cannot be .true.\n" . + "(eg. don't use this option with BGC or non-SP FATES), \n" . + "Update compset to use SP)"); + } + if ( defined($nl->get_value('stream_year_first_lai')) || + defined($nl->get_value('stream_year_last_lai')) || + defined($nl->get_value('model_year_align_lai')) || + defined($nl->get_value('lai_tintalgo' )) || defined($nl->get_value('stream_fldfilename_lai')) ) { - $log->fatal_error("When bgc is NOT SP none of the following can be set: stream_year_first_lai,\n" . + $log->fatal_error("When not in SP mode none of the following can be set: stream_year_first_lai,\n" . "stream_year_last_lai, model_year_align_lai, lai_tintalgo nor\n" . - "stream_fldfilename_lai (eg. don't use this option with BGC,CN,CNDV nor BGDCV)."); + "stream_fldfilename_lai (eg. don't use this option with BGC or FATES-SP)."); } } } diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index bbf991a7a7..da4201d68f 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -163,7 +163,7 @@ sub cat_and_create_namelistinfile { # # Figure out number of tests that will run # -my $ntests = 1992; +my $ntests = 1999; if ( defined($opts{'compare'}) ) { $ntests += 1353; @@ -1226,6 +1226,26 @@ sub cat_and_create_namelistinfile { 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", + }, ); foreach my $key ( keys(%failtest) ) { print( "$key\n" ); diff --git a/cime_config/config_compsets.xml b/cime_config/config_compsets.xml index 61931c94ba..aaa5c68394 100644 --- a/cime_config/config_compsets.xml +++ b/cime_config/config_compsets.xml @@ -205,6 +205,10 @@ I2000Clm45BgcCropQianRs 2000_DATM%QIA_CLM45%BGC-CROP_SICE_SOCN_SROF_SGLC_SWAV + + I2000Clm50FatesQian + 2000_DATM%QIA_CLM50%FATES_SICE_SOCN_MOSART_SGLC_SWAV + I2000Clm50BgcCruRs diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 34fd70f4df..beb5d178f9 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -2324,17 +2324,16 @@ - diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdSatPhen_prescribed/README b/cime_config/testdefs/testmods_dirs/clm/FatesColdSatPhen_prescribed/README deleted file mode 100644 index a1c8f04632..0000000000 --- a/cime_config/testdefs/testmods_dirs/clm/FatesColdSatPhen_prescribed/README +++ /dev/null @@ -1,3 +0,0 @@ -This testmod currently does NOT work, because of issue #1722 - -See https://github.com/ESCOMP/CTSM/issues/1722 diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdSatPhen_prescribed/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/FatesColdSatPhen_prescribed/include_user_mods index d111d05911..33ca1de12e 100644 --- a/cime_config/testdefs/testmods_dirs/clm/FatesColdSatPhen_prescribed/include_user_mods +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdSatPhen_prescribed/include_user_mods @@ -1,2 +1 @@ ../FatesColdSatPhen -../prescribed diff --git a/cime_config/testdefs/testmods_dirs/clm/FatesColdSatPhen_prescribed/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/FatesColdSatPhen_prescribed/user_nl_clm new file mode 100644 index 0000000000..59a4137be7 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/FatesColdSatPhen_prescribed/user_nl_clm @@ -0,0 +1,3 @@ +use_lai_streams = .true. +lai_tintalgo = 'lower' ! set time interpolation to use lower value, so can compare more directly to input dataset + \ No newline at end of file diff --git a/cime_config/testdefs/testmods_dirs/clm/datm_bias_correct_cruv7/user_nl_clm b/cime_config/testdefs/testmods_dirs/clm/datm_bias_correct_cruv7/user_nl_clm deleted file mode 100644 index c7cfe279ee..0000000000 --- a/cime_config/testdefs/testmods_dirs/clm/datm_bias_correct_cruv7/user_nl_clm +++ /dev/null @@ -1 +0,0 @@ -use_lai_streams = .true. diff --git a/doc/ChangeLog b/doc/ChangeLog index 0a9515ff93..955f071933 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,4 +1,70 @@ =============================================================== +Tag name: ctsm5.1.dev140 +Originator(s): afoster (Adrianna Foster) +Date: Tue Sep 12 14:47:06 MDT 2023 +One-line Summary: add lai_streams capability for FATES + +Purpose and description of changes +---------------------------------- + +Removed checks in clm_driver and CLMBuildNamelist.pm so that now FATES can run when use_lai_streams=.true. + +I also had to modify the init in cpl/share_esmf/laiStreamMod to allocate the g_to_ig array in the lai_init method (rather than in the lai_advance method. This was required because SatellitePhenology is called in clim_initializedMod in FATES cases (here). This happens before lai_advance is ever called so at that point the g_to_ig array was not yet allocated. Moving the allocation/initialization to the lai_init method fixes this. + +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.) + + +[ ] clm5_1 + +[ ] clm5_0 + +[ ] ctsm5_0-nwp + +[ ] clm4_5 + +Bugs fixed or introduced +------------------------ + +CTSM issues fixed (include CTSM Issue #): #1722 - Should be able to use lai streams with FATES-SP mode + +Notes of particular relevance for developers: +--------------------------------------------- + +build-namelist tests (if CLMBuildNamelist.pm has changed): added tests to make sure use_lai_streams failed correctly + +Changes to tests or testing: Added a test for lai_streams with FATES + +Testing summary: +---------------- + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + cheyenne ---- OK + izumi ------- OK + + fates tests: (give name of baseline if different from CTSM tagname, normally fates baselines are fates--) + cheyenne ---- OK + izumi ------- OK + + +Answer changes +-------------- + +Changes answers relative to baseline: None + +Other details +------------- + +List any externals directories updated (cime, rtm, mosart, cism, fates, etc.): fates + +Pull Requests that document the changes (include PR ids): #2054 +(https://github.com/ESCOMP/ctsm/pull) + +=============================================================== +=============================================================== Tag name: ctsm5.1.dev139 Originator(s): slevis (Samuel Levis) Date: Fri Aug 25 16:47:45 MDT 2023 diff --git a/doc/ChangeSum b/doc/ChangeSum index 4ac0f90f5e..5ca9ceab70 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,5 +1,6 @@ Tag Who Date Summary ============================================================================================================================ + ctsm5.1.dev140 afoster 09/12/2023 add lai_streams capability for FATES ctsm5.1.dev139 slevis 08/28/2023 Fix problems uncovered by nag -nan tests ctsm5.1.dev138 slevis 08/25/2023 Refactor max_patch_per_col and maxsoil_patches loops ctsm5.1.dev137 slevis 08/23/2023 Surface roughness modifications diff --git a/src/cpl/share_esmf/laiStreamMod.F90 b/src/cpl/share_esmf/laiStreamMod.F90 index 3966488e0b..3e4074fbde 100644 --- a/src/cpl/share_esmf/laiStreamMod.F90 +++ b/src/cpl/share_esmf/laiStreamMod.F90 @@ -54,7 +54,7 @@ subroutine lai_init(bounds) type(bounds_type), intent(in) :: bounds ! bounds ! ! !LOCAL VARIABLES: - integer :: i,n ! index + integer :: i,n, ig, g ! index integer :: stream_year_first_lai ! first year in Lai stream to use integer :: stream_year_last_lai ! last year in Lai stream to use integer :: model_year_align_lai ! align stream_year_first_lai with @@ -151,6 +151,15 @@ subroutine lai_init(bounds) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) then call ESMF_Finalize(endflag=ESMF_END_ABORT) end if + + if ( .not. allocated(g_to_ig) )then + allocate (g_to_ig(bounds%begg:bounds%endg) ) + ig = 0 + do g = bounds%begg,bounds%endg + ig = ig+1 + g_to_ig(g) = ig + end do + end if end subroutine lai_init diff --git a/src/main/clm_driver.F90 b/src/main/clm_driver.F90 index 2bcf2ab396..1b9803f63d 100644 --- a/src/main/clm_driver.F90 +++ b/src/main/clm_driver.F90 @@ -225,7 +225,7 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate, ro ! Specified phenology ! Done in SP mode, FATES-SP mode and also when dry-deposition is active ! ============================================================================ - + if (use_cn) then ! For dry-deposition need to call CLMSP so that mlaidiff is obtained ! NOTE: This is also true of FATES below @@ -264,7 +264,7 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate, ro end if end if - + ! ================================================================================== ! Determine decomp vertical profiles ! @@ -468,8 +468,8 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate, ro ! When LAI streams are being used ! NOTE: This call needs to happen outside loops over nclumps (as streams are not threadsafe) - if ((.not. use_cn) .and. (.not. use_fates) .and. (doalb) .and. use_lai_streams) then - call lai_advance( bounds_proc ) + if (doalb .and. use_lai_streams) then + call lai_advance(bounds_proc) endif ! When crop calendar streams are being used diff --git a/src/main/clm_initializeMod.F90 b/src/main/clm_initializeMod.F90 index ab91c0d3f2..077a25b796 100644 --- a/src/main/clm_initializeMod.F90 +++ b/src/main/clm_initializeMod.F90 @@ -691,7 +691,7 @@ subroutine initialize2(ni,nj) elseif ( use_fates_sp ) then call interpMonthlyVeg(bounds_proc, canopystate_inst) end if - + ! Determine gridcell averaged properties to send to atm if (nsrest == nsrStartup) then call t_startf('init_map2gc') @@ -727,7 +727,6 @@ subroutine initialize2(ni,nj) !$OMP PARALLEL DO PRIVATE (nc, bounds_clump) do nc = 1,nclumps call get_clump_bounds(nc, bounds_clump) - ! FATES satellite phenology mode needs to include all active and inactive patch-level soil ! filters due to the translation between the hlm pfts and the fates pfts. ! E.g. in FATES, an active PFT vector of 1, 0, 0, 0, 1, 0, 1, 0 would be mapped into @@ -740,11 +739,12 @@ subroutine initialize2(ni,nj) end do !$OMP END PARALLEL DO end if + call clm_fates%init_coldstart(water_inst%waterstatebulk_inst, & water_inst%waterdiagnosticbulk_inst, canopystate_inst, & soilstate_inst, soilbiogeochem_carbonflux_inst) end if - + ! topo_glc_mec was allocated in initialize1, but needed to be kept around through ! initialize2 because it is used to initialize other variables; now it can be deallocated deallocate(topo_glc_mec, fert_cft, irrig_method) diff --git a/src/main/clm_varcon.F90 b/src/main/clm_varcon.F90 index 4b0bbe160d..e45f5c440e 100644 --- a/src/main/clm_varcon.F90 +++ b/src/main/clm_varcon.F90 @@ -90,6 +90,7 @@ module clm_varcon integer, public, parameter :: fun_period = 1 ! A FUN parameter, and probably needs to be changed for testing real(r8),public, parameter :: smallValue = 1.e-12_r8 ! A small values used by FUN + real(r8),public, parameter :: sum_to_1_tol = 1.e-13_r8 ! error tolerance ! ------------------------------------------------------------------------ ! Special value flags diff --git a/src/main/controlMod.F90 b/src/main/controlMod.F90 index edc760a072..e55c57edb7 100644 --- a/src/main/controlMod.F90 +++ b/src/main/controlMod.F90 @@ -491,6 +491,14 @@ subroutine control_init(dtime) end if + ! Check compatibility with use_lai_streams + if (use_lai_streams) then + if ((use_fates .and. .not. use_fates_sp) .or. use_cn) then + call endrun(msg=' ERROR: cannot use LAI streams unless in SP mode (use_cn = .false. or use_fates_sp=.true.).'//& + errMsg(sourcefile, __LINE__)) + end if + end if + ! If nfix_timeconst is equal to the junk default value, then it was not specified ! by the user namelist and we need to assign it the correct default value. If the ! user specified it in the namelist, we leave it alone. diff --git a/src/main/surfrdUtilsMod.F90 b/src/main/surfrdUtilsMod.F90 index d84b829310..6b581a59c1 100644 --- a/src/main/surfrdUtilsMod.F90 +++ b/src/main/surfrdUtilsMod.F90 @@ -7,6 +7,7 @@ module surfrdUtilsMod ! !USES: #include "shr_assert.h" use shr_kind_mod , only : r8 => shr_kind_r8 + use clm_varcon , only : sum_to_1_tol use clm_varctl , only : iulog,use_fates use abortutils , only : endrun use shr_log_mod , only : errMsg => shr_log_errMsg @@ -51,7 +52,6 @@ subroutine check_sums_equal_1(arr, lb, name, caller, ier, sumto) logical :: found integer :: nl integer :: nindx - real(r8), parameter :: eps = 1.e-13_r8 real(r8), allocatable :: TotalSum(:) integer :: ub ! upper bound of the first dimension of arr !----------------------------------------------------------------------- @@ -64,7 +64,7 @@ subroutine check_sums_equal_1(arr, lb, name, caller, ier, sumto) found = .false. do nl = lb, ub - if (abs(sum(arr(nl,:)) - TotalSum(nl)) > eps) then + if (abs(sum(arr(nl,:)) - TotalSum(nl)) > sum_to_1_tol) then found = .true. nindx = nl exit diff --git a/src/utils/clmfates_interfaceMod.F90 b/src/utils/clmfates_interfaceMod.F90 index 4dc1faacd1..e7e31b854a 100644 --- a/src/utils/clmfates_interfaceMod.F90 +++ b/src/utils/clmfates_interfaceMod.F90 @@ -68,6 +68,7 @@ module CLMFatesInterfaceMod use clm_varcon , only : spval use clm_varcon , only : denice use clm_varcon , only : ispval + use clm_varcon , only : sum_to_1_tol use clm_varpar , only : surfpft_lb,surfpft_ub use clm_varpar , only : numrad use clm_varpar , only : ivis @@ -715,10 +716,10 @@ subroutine init(this, bounds_proc ) this%fates(nc)%bc_in(s)%pft_areafrac(ft)=wt_nat_patch(g,m) end do - if(abs(sum(this%fates(nc)%bc_in(s)%pft_areafrac(surfpft_lb:surfpft_ub))-1.0_r8).gt.1.0e-9)then - write(iulog,*) 'pft_area error in interfc ',s, sum(this%fates(nc)%bc_in(s)%pft_areafrac(:))-1.0_r8 + if (abs(sum(this%fates(nc)%bc_in(s)%pft_areafrac(surfpft_lb:surfpft_ub)) - 1.0_r8) > sum_to_1_tol) then + write(iulog,*) 'pft_area error in interfc ', s, sum(this%fates(nc)%bc_in(s)%pft_areafrac(:)) - 1.0_r8 call endrun(msg=errMsg(sourcefile, __LINE__)) - endif + end if end do !site ! Initialize site-level static quantities dictated by the HLM