From fe08e916b238d3d28cbbae694bc0c999106b4fc5 Mon Sep 17 00:00:00 2001 From: Charlie Koven Date: Thu, 18 Jan 2018 12:23:11 -0800 Subject: [PATCH 01/10] fixed bug in which patch and cohort numbers were overestimated by one --- main/FatesHistoryInterfaceMod.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main/FatesHistoryInterfaceMod.F90 b/main/FatesHistoryInterfaceMod.F90 index 79e63357ca..33899517f5 100644 --- a/main/FatesHistoryInterfaceMod.F90 +++ b/main/FatesHistoryInterfaceMod.F90 @@ -2578,12 +2578,12 @@ subroutine define_history_vars(this, initialize_variables) ! Site level counting variables call this%set_history_var(vname='ED_NPATCHES', units='none', & long='Total number of ED patches per site', use_default='active', & - avgflag='A', vtype=site_r8, hlms='CLM:ALM', flushval=1.0_r8, upfreq=1, & + avgflag='A', vtype=site_r8, hlms='CLM:ALM', flushval=0.0_r8, upfreq=1, & ivar=ivar, initialize=initialize_variables, index = ih_npatches_si) call this%set_history_var(vname='ED_NCOHORTS', units='none', & long='Total number of ED cohorts per site', use_default='active', & - avgflag='A', vtype=site_r8, hlms='CLM:ALM', flushval=1.0_r8, upfreq=1, & + avgflag='A', vtype=site_r8, hlms='CLM:ALM', flushval=0.0_r8, upfreq=1, & ivar=ivar, initialize=initialize_variables, index = ih_ncohorts_si) ! Patch variables From 05620557c5e384c19fa7a28d81a3882b30c5c619 Mon Sep 17 00:00:00 2001 From: ckoven Date: Mon, 22 Jan 2018 20:15:38 -0700 Subject: [PATCH 02/10] added logic and parameter to force fusion of old patches --- biogeochem/EDPatchDynamicsMod.F90 | 71 +++++++++++++++++++------------ 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index 051baf689a..738d4ea95a 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -1322,6 +1322,10 @@ subroutine fuse_patches( csite, bc_in ) integer :: nopatches !number of patches presently in gridcell integer :: iterate !switch of patch reduction iteration scheme. 1 to keep going, 0 to stop integer :: fuse_flag !do patches get fused (1) or not (0). + ! + ! parameters + real(r8), parameter :: patch_fusion_tolerance_relaxation_increment = 1.1_r8 + real(r8), parameter :: max_age_of_second_oldest_patch = 200._r8 ! age in years above which to combine all patches !--------------------------------------------------------------------- !maxpatch = 4 @@ -1372,33 +1376,44 @@ subroutine fuse_patches( csite, bc_in ) fuse_flag = 1 !the default is to fuse the patches if(currentPatch%patchno /= tpp%patchno) then !these should be the same patch - !---------------------------------------------------------------------! - ! Calculate the difference criteria for each pft and dbh class ! - !---------------------------------------------------------------------! - do ft = 1,numpft ! loop over pfts - do z = 1,n_dbh_bins ! loop over hgt bins - !is there biomass in this category? - if(currentPatch%pft_agb_profile(ft,z) > 0.0_r8.or.tpp%pft_agb_profile(ft,z) > 0.0_r8)then - norm = abs(currentPatch%pft_agb_profile(ft,z) - tpp%pft_agb_profile(ft,z))/(0.5_r8*& - &(currentPatch%pft_agb_profile(ft,z) + tpp%pft_agb_profile(ft,z))) - !---------------------------------------------------------------------! - ! Look for differences in profile biomass, above the minimum biomass ! - !---------------------------------------------------------------------! - - if(norm > profiletol)then - !looking for differences between profile density. - if(currentPatch%pft_agb_profile(ft,z) > NTOL.or.tpp%pft_agb_profile(ft,z) > NTOL)then - fuse_flag = 0 !do not fuse - keep apart. - endif - endif ! profile tol - endif ! NTOL - enddo !ht bins - enddo ! PFT - - !---------------------------------------------------------------------! - ! Call the patch fusion routine if there is a meaningful difference ! - ! any of the pft x height categories ! - !---------------------------------------------------------------------! + !----------------------------------------------------------------------------------- + ! check to see if both patches are older than the age at which we force them to fuse + !----------------------------------------------------------------------------------- + + if ( tpp%age .le. max_age_of_second_oldest_patch .or. & + currentPatch%age .le. max_age_of_second_oldest_patch ) then + + !---------------------------------------------------------------------! + ! Calculate the difference criteria for each pft and dbh class ! + !---------------------------------------------------------------------! + do ft = 1,numpft ! loop over pfts + do z = 1,n_dbh_bins ! loop over hgt bins + !is there biomass in this category? + if(currentPatch%pft_agb_profile(ft,z) > 0.0_r8.or.tpp%pft_agb_profile(ft,z) > 0.0_r8)then + + norm = abs(currentPatch%pft_agb_profile(ft,z) - tpp%pft_agb_profile(ft,z))/(0.5_r8*& + &(currentPatch%pft_agb_profile(ft,z) + tpp%pft_agb_profile(ft,z))) + + !---------------------------------------------------------------------! + ! Look for differences in profile biomass, above the minimum biomass ! + !---------------------------------------------------------------------! + + if(norm > profiletol)then + !looking for differences between profile density. + if(currentPatch%pft_agb_profile(ft,z) > NTOL.or.tpp%pft_agb_profile(ft,z) > NTOL)then + fuse_flag = 0 !do not fuse - keep apart. + endif + endif ! profile tol + endif ! NTOL + enddo !ht bins + enddo ! PFT + + endif ! maxage + !-------------------------------------------------------------------------! + ! Call the patch fusion routine if there is not a meaningful difference ! + ! any of the pft x height categories ! + ! or both are older than forced fusion age ! + !-------------------------------------------------------------------------! if(fuse_flag == 1)then tmpptr => currentPatch%older @@ -1434,7 +1449,7 @@ subroutine fuse_patches( csite, bc_in ) if(nopatches > maxpatch)then iterate = 1 - profiletol = profiletol * 1.1_r8 + profiletol = profiletol * patch_fusion_tolerance_relaxation_increment !---------------------------------------------------------------------! ! Making profile tolerance larger means that more fusion will happen ! From 798fd29bb16c8b100c76cdb3b0e36a7805a026fa Mon Sep 17 00:00:00 2001 From: ckoven Date: Tue, 23 Jan 2018 10:31:43 -0700 Subject: [PATCH 03/10] changed bin spacing for patch fusion comparisons to resolve smaller trees better --- biogeochem/EDPatchDynamicsMod.F90 | 15 +++++---------- main/EDTypesMod.F90 | 8 +++++--- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index 738d4ea95a..d3a1253649 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -7,7 +7,7 @@ module EDPatchDynamicsMod use FatesInterfaceMod , only : hlm_freq_day use EDPftvarcon , only : EDPftvarcon_inst use EDCohortDynamicsMod , only : fuse_cohorts, sort_cohorts, insert_cohort - use EDtypesMod , only : ncwd, n_dbh_bins, ntol, area, dbhmax + use EDtypesMod , only : ncwd, n_dbh_bins, ntol, area, patchfusion_dbhbin_loweredges use EDTypesMod , only : maxPatchesPerSite use EDTypesMod , only : ed_site_type, ed_patch_type, ed_cohort_type use EDTypesMod , only : min_patch_area @@ -1767,20 +1767,15 @@ subroutine patch_pft_size_profile(cp_pnt) currentPatch => cp_pnt - delta_dbh = (DBHMAX/N_DBH_BINS) - currentPatch%pft_agb_profile(:,:) = 0.0_r8 do j = 1,N_DBH_BINS - if (j == 1) then - mind(j) = 0.0_r8 - maxd(j) = delta_dbh - else if (j == N_DBH_BINS) then - mind(j) = (j-1) * delta_dbh + if (j == N_DBH_BINS) then + mind(j) = patchfusion_dbhbin_loweredges(j-1) maxd(j) = gigantictrees else - mind(j) = (j-1) * delta_dbh - maxd(j) = (j)*delta_dbh + mind(j) = patchfusion_dbhbin_loweredges(j-1) + maxd(j) = patchfusion_dbhbin_loweredges(j) endif enddo diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index 05e0775205..383097c072 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -82,12 +82,14 @@ module EDTypesMod real(r8), parameter :: fire_threshold = 50.0_r8 ! threshold for fires that spread or go out. KWm-2 (Pyne 1986) ! PATCH FUSION + integer , parameter :: N_DBH_BINS = 6 ! no. of dbh bins used when comparing patches + real(r8), parameter :: patchfusion_dbhbin_loweredges(N_DBH_BINS) = & + (/0._r8, 5._r8, 20._r8, 50._r8, 100._r8, 150._r8/) ! array of bin lower edges for comparing patches + + ! COHORT FUSION real(r8), parameter :: NTOL = 0.05_r8 ! min plant density for hgt bin to be used in height profile comparisons real(r8), parameter :: HITEMAX = 30.0_r8 ! max dbh value used in hgt profile comparison - real(r8), parameter :: DBHMAX = 150.0_r8 ! max dbh value used in hgt profile comparison integer , parameter :: N_HITE_BINS = 60 ! no. of hite bins used to distribute LAI - integer , parameter :: N_DBH_BINS = 5 ! no. of dbh bins used when comparing patches - real(r8), parameter :: min_npm2 = 1.0E-8_r8 ! minimum cohort number density per m2 before termination real(r8), parameter :: min_patch_area = 0.001_r8 ! smallest allowable patch area before termination From b7ad51b83061b1b82119c7f0545091c684353067 Mon Sep 17 00:00:00 2001 From: ckoven Date: Tue, 23 Jan 2018 15:03:24 -0700 Subject: [PATCH 04/10] reduced min biomass threshold for patch fusino logic to 5 gC/m2 --- main/EDTypesMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index 383097c072..e9220251aa 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -82,12 +82,12 @@ module EDTypesMod real(r8), parameter :: fire_threshold = 50.0_r8 ! threshold for fires that spread or go out. KWm-2 (Pyne 1986) ! PATCH FUSION + real(r8), parameter :: NTOL = 0.005_r8 ! min biomass (kg / m2 patch area) below which to force-fuse patches integer , parameter :: N_DBH_BINS = 6 ! no. of dbh bins used when comparing patches real(r8), parameter :: patchfusion_dbhbin_loweredges(N_DBH_BINS) = & (/0._r8, 5._r8, 20._r8, 50._r8, 100._r8, 150._r8/) ! array of bin lower edges for comparing patches ! COHORT FUSION - real(r8), parameter :: NTOL = 0.05_r8 ! min plant density for hgt bin to be used in height profile comparisons real(r8), parameter :: HITEMAX = 30.0_r8 ! max dbh value used in hgt profile comparison integer , parameter :: N_HITE_BINS = 60 ! no. of hite bins used to distribute LAI From f5a7dc7caaa8401d90511ce89db29d174d010cd0 Mon Sep 17 00:00:00 2001 From: ckoven Date: Tue, 23 Jan 2018 21:43:28 -0700 Subject: [PATCH 05/10] some cleanup and addition of comments for patch fusion criteria --- biogeochem/EDPatchDynamicsMod.F90 | 52 ++++++++++++++++++++++--------- main/EDTypesMod.F90 | 3 ++ 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index d3a1253649..bcf2eb8c29 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -1307,6 +1307,8 @@ subroutine fuse_patches( csite, bc_in ) ! ! !USES: use EDParamsMod , only : ED_val_patch_fusion_tol + use EDTypesMod , only : patch_fusion_tolerance_relaxation_increment + use EDTypesMod , only : max_age_of_second_oldest_patch ! ! !ARGUMENTS: type(ed_site_type), intent(inout), target :: csite @@ -1318,19 +1320,12 @@ subroutine fuse_patches( csite, bc_in ) integer :: ft,z !counters for pft and height class real(r8) :: norm !normalized difference between biomass profiles real(r8) :: profiletol !tolerance of patch fusion routine. Starts off high and is reduced if there are too many patches. - integer :: maxpatch !maximum number of allowed patches. FIX-RF. These should be namelist variables. integer :: nopatches !number of patches presently in gridcell integer :: iterate !switch of patch reduction iteration scheme. 1 to keep going, 0 to stop integer :: fuse_flag !do patches get fused (1) or not (0). ! - ! parameters - real(r8), parameter :: patch_fusion_tolerance_relaxation_increment = 1.1_r8 - real(r8), parameter :: max_age_of_second_oldest_patch = 200._r8 ! age in years above which to combine all patches !--------------------------------------------------------------------- - !maxpatch = 4 - maxpatch = maxPatchesPerSite - currentSite => csite profiletol = ED_val_patch_fusion_tol @@ -1347,7 +1342,7 @@ subroutine fuse_patches( csite, bc_in ) iterate = 1 !---------------------------------------------------------------------! - ! Keep doing this until nopatches >= maxpatch ! + ! Keep doing this until nopatches >= maxPatchesPerSite ! !---------------------------------------------------------------------! do while(iterate == 1) @@ -1373,7 +1368,17 @@ subroutine fuse_patches( csite, bc_in ) endif if(associated(tpp).and.associated(currentPatch))then - fuse_flag = 1 !the default is to fuse the patches + + !-------------------------------------------------------------------------------------------- + ! The default is to fuse the patches, unless some criteria is met which keeps them separated. + ! there are multiple criteria which all need to be met to keep them distinct: + ! (a) one of them is younger than the max age at which we force fusion. + ! (b) for at least one pft x size class, where there is biomass in at least one patch, + ! and the normalized differenve between the patches exceeds a threshold, and + ! (c) there is more than a threshold (tiny) amount of biomass in at least one of the patches + !-------------------------------------------------------------------------------------------- + + fuse_flag = 1 if(currentPatch%patchno /= tpp%patchno) then !these should be the same patch !----------------------------------------------------------------------------------- @@ -1386,11 +1391,20 @@ subroutine fuse_patches( csite, bc_in ) !---------------------------------------------------------------------! ! Calculate the difference criteria for each pft and dbh class ! !---------------------------------------------------------------------! + do ft = 1,numpft ! loop over pfts do z = 1,n_dbh_bins ! loop over hgt bins + + !---------------------------------- !is there biomass in this category? + !---------------------------------- + if(currentPatch%pft_agb_profile(ft,z) > 0.0_r8.or.tpp%pft_agb_profile(ft,z) > 0.0_r8)then + !------------------------------------------------------------------------------------- + ! what is the relative difference in biomass i nthis category between the two patches? + !------------------------------------------------------------------------------------- + norm = abs(currentPatch%pft_agb_profile(ft,z) - tpp%pft_agb_profile(ft,z))/(0.5_r8*& &(currentPatch%pft_agb_profile(ft,z) + tpp%pft_agb_profile(ft,z))) @@ -1399,16 +1413,24 @@ subroutine fuse_patches( csite, bc_in ) !---------------------------------------------------------------------! if(norm > profiletol)then - !looking for differences between profile density. + + !--------------------------------------------------------------------------------------------------------- + ! the next bit of logic forces fusion of two patches which both have tiny biomass densities. without this, + ! fates gives a bunch of really young patches which all have almost no biomass and so don't need to be + ! distinguished from each other. but if NTOL is too big, it takes too long for the youngest patch to build + ! up enough biomass to be its own distinct entity, which leads to large oscillations in the patch dynamics + ! and dependent variables. + !--------------------------------------------------------------------------------------------------------- + if(currentPatch%pft_agb_profile(ft,z) > NTOL.or.tpp%pft_agb_profile(ft,z) > NTOL)then fuse_flag = 0 !do not fuse - keep apart. - endif + endif ! biomass .gt. NTOL endif ! profile tol - endif ! NTOL + endif ! biomass .gt. 0 enddo !ht bins enddo ! PFT - endif ! maxage + !-------------------------------------------------------------------------! ! Call the patch fusion routine if there is not a meaningful difference ! ! any of the pft x height categories ! @@ -1447,7 +1469,7 @@ subroutine fuse_patches( csite, bc_in ) currentPatch => currentPatch%older enddo - if(nopatches > maxpatch)then + if(nopatches > maxPatchesPerSite)then iterate = 1 profiletol = profiletol * patch_fusion_tolerance_relaxation_increment @@ -1458,7 +1480,7 @@ subroutine fuse_patches( csite, bc_in ) iterate = 0 endif - enddo !do while nopatches>maxpatch + enddo !do while nopatches>maxPatchesPerSite end subroutine fuse_patches diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index e9220251aa..ecc86f0c9c 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -86,11 +86,14 @@ module EDTypesMod integer , parameter :: N_DBH_BINS = 6 ! no. of dbh bins used when comparing patches real(r8), parameter :: patchfusion_dbhbin_loweredges(N_DBH_BINS) = & (/0._r8, 5._r8, 20._r8, 50._r8, 100._r8, 150._r8/) ! array of bin lower edges for comparing patches + real(r8), parameter :: patch_fusion_tolerance_relaxation_increment = 1.1_r8 ! amount by which to increment patch fusion threshold + real(r8), parameter :: max_age_of_second_oldest_patch = 200._r8 ! age in years above which to combine all patches ! COHORT FUSION real(r8), parameter :: HITEMAX = 30.0_r8 ! max dbh value used in hgt profile comparison integer , parameter :: N_HITE_BINS = 60 ! no. of hite bins used to distribute LAI + ! COHORT TERMINATION real(r8), parameter :: min_npm2 = 1.0E-8_r8 ! minimum cohort number density per m2 before termination real(r8), parameter :: min_patch_area = 0.001_r8 ! smallest allowable patch area before termination real(r8), parameter :: min_nppatch = 1.0E-11_r8 ! minimum number of cohorts per patch (min_npm2*min_patch_area) From 77bc142e4bcea7f9fec0e6b756197940f04fb844 Mon Sep 17 00:00:00 2001 From: ckoven Date: Wed, 24 Jan 2018 09:37:07 -0700 Subject: [PATCH 06/10] reordered patch fusion logic to sum min biomass over PFT,Z and took out of those loops --- biogeochem/EDPatchDynamicsMod.F90 | 74 ++++++++++++++++--------------- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index bcf2eb8c29..db72291927 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -1372,10 +1372,10 @@ subroutine fuse_patches( csite, bc_in ) !-------------------------------------------------------------------------------------------- ! The default is to fuse the patches, unless some criteria is met which keeps them separated. ! there are multiple criteria which all need to be met to keep them distinct: - ! (a) one of them is younger than the max age at which we force fusion. - ! (b) for at least one pft x size class, where there is biomass in at least one patch, - ! and the normalized differenve between the patches exceeds a threshold, and - ! (c) there is more than a threshold (tiny) amount of biomass in at least one of the patches + ! (a) one of them is younger than the max age at which we force fusion; + ! (b) there is more than a threshold (tiny) amount of biomass in at least one of the patches; + ! (c) for at least one pft x size class, where there is biomass in that class in at least one patch, + ! and the normalized difference between the patches exceeds a threshold. !-------------------------------------------------------------------------------------------- fuse_flag = 1 @@ -1388,47 +1388,51 @@ subroutine fuse_patches( csite, bc_in ) if ( tpp%age .le. max_age_of_second_oldest_patch .or. & currentPatch%age .le. max_age_of_second_oldest_patch ) then - !---------------------------------------------------------------------! - ! Calculate the difference criteria for each pft and dbh class ! - !---------------------------------------------------------------------! + + !--------------------------------------------------------------------------------------------------------- + ! the next bit of logic forces fusion of two patches which both have tiny biomass densities. without this, + ! fates gives a bunch of really young patches which all have almost no biomass and so don't need to be + ! distinguished from each other. but if NTOL is too big, it takes too long for the youngest patch to build + ! up enough biomass to be its own distinct entity, which leads to large oscillations in the patch dynamics + ! and dependent variables. + !--------------------------------------------------------------------------------------------------------- + + if(sum(currentPatch%pft_agb_profile(:,:)) > NTOL .or. & + sum(tpp%pft_agb_profile(:,:)) > NTOL ) then - do ft = 1,numpft ! loop over pfts - do z = 1,n_dbh_bins ! loop over hgt bins + !---------------------------------------------------------------------! + ! Calculate the difference criteria for each pft and dbh class ! + !---------------------------------------------------------------------! - !---------------------------------- - !is there biomass in this category? - !---------------------------------- + do ft = 1,numpft ! loop over pfts + do z = 1,n_dbh_bins ! loop over hgt bins - if(currentPatch%pft_agb_profile(ft,z) > 0.0_r8.or.tpp%pft_agb_profile(ft,z) > 0.0_r8)then + !---------------------------------- + !is there biomass in this category? + !---------------------------------- - !------------------------------------------------------------------------------------- - ! what is the relative difference in biomass i nthis category between the two patches? - !------------------------------------------------------------------------------------- + if(currentPatch%pft_agb_profile(ft,z) > 0.0_r8.or.tpp%pft_agb_profile(ft,z) > 0.0_r8)then - norm = abs(currentPatch%pft_agb_profile(ft,z) - tpp%pft_agb_profile(ft,z))/(0.5_r8*& - &(currentPatch%pft_agb_profile(ft,z) + tpp%pft_agb_profile(ft,z))) + !------------------------------------------------------------------------------------- + ! what is the relative difference in biomass i nthis category between the two patches? + !------------------------------------------------------------------------------------- - !---------------------------------------------------------------------! - ! Look for differences in profile biomass, above the minimum biomass ! - !---------------------------------------------------------------------! + norm = abs(currentPatch%pft_agb_profile(ft,z) - tpp%pft_agb_profile(ft,z))/(0.5_r8*& + &(currentPatch%pft_agb_profile(ft,z) + tpp%pft_agb_profile(ft,z))) - if(norm > profiletol)then + !---------------------------------------------------------------------! + ! Look for differences in profile biomass, above the minimum biomass ! + !---------------------------------------------------------------------! - !--------------------------------------------------------------------------------------------------------- - ! the next bit of logic forces fusion of two patches which both have tiny biomass densities. without this, - ! fates gives a bunch of really young patches which all have almost no biomass and so don't need to be - ! distinguished from each other. but if NTOL is too big, it takes too long for the youngest patch to build - ! up enough biomass to be its own distinct entity, which leads to large oscillations in the patch dynamics - ! and dependent variables. - !--------------------------------------------------------------------------------------------------------- + if(norm > profiletol)then - if(currentPatch%pft_agb_profile(ft,z) > NTOL.or.tpp%pft_agb_profile(ft,z) > NTOL)then fuse_flag = 0 !do not fuse - keep apart. - endif ! biomass .gt. NTOL - endif ! profile tol - endif ! biomass .gt. 0 - enddo !ht bins - enddo ! PFT + + endif ! profile tol + endif ! biomass(ft,z) .gt. 0 + enddo !ht bins + enddo ! PFT + endif ! sum(biomass(:,:) .gt. NTOL endif ! maxage !-------------------------------------------------------------------------! From c8a76db47dbb5697da7e6f5829aaecd33b0177c5 Mon Sep 17 00:00:00 2001 From: ckoven Date: Wed, 24 Jan 2018 20:42:26 -0700 Subject: [PATCH 07/10] bugfix to dbhbinedges_indexing --- biogeochem/EDPatchDynamicsMod.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index db72291927..ef2ea36ef9 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -1797,11 +1797,11 @@ subroutine patch_pft_size_profile(cp_pnt) do j = 1,N_DBH_BINS if (j == N_DBH_BINS) then - mind(j) = patchfusion_dbhbin_loweredges(j-1) + mind(j) = patchfusion_dbhbin_loweredges(j) maxd(j) = gigantictrees else - mind(j) = patchfusion_dbhbin_loweredges(j-1) - maxd(j) = patchfusion_dbhbin_loweredges(j) + mind(j) = patchfusion_dbhbin_loweredges(j) + maxd(j) = patchfusion_dbhbin_loweredges(j+1) endif enddo From 89eecbdfd1a00f4f6797114c117663da237d0ed2 Mon Sep 17 00:00:00 2001 From: ckoven Date: Mon, 5 Mar 2018 18:17:02 -0700 Subject: [PATCH 08/10] fixed some line length issues --- biogeochem/EDPatchDynamicsMod.F90 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index e89df3705d..0da91d8877 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -118,7 +118,8 @@ subroutine disturbance_rates( site_in, bc_in) call mortality_rates(currentCohort,bc_in,cmort,hmort,bmort,frmort) currentCohort%dmort = cmort+hmort+bmort+frmort - call carea_allom(currentCohort%dbh,currentCohort%n,site_in%spread,currentCohort%pft,currentCohort%c_area) + call carea_allom(currentCohort%dbh,currentCohort%n,site_in%spread,currentCohort%pft, & + currentCohort%c_area) ! Initialize diagnostic mortality rates currentCohort%cmort = cmort @@ -1425,13 +1426,15 @@ subroutine fuse_patches( csite, bc_in ) !is there biomass in this category? !---------------------------------- - if(currentPatch%pft_agb_profile(ft,z) > 0.0_r8.or.tpp%pft_agb_profile(ft,z) > 0.0_r8)then + if(currentPatch%pft_agb_profile(ft,z) > 0.0_r8 .or. & + tpp%pft_agb_profile(ft,z) > 0.0_r8)then !------------------------------------------------------------------------------------- ! what is the relative difference in biomass i nthis category between the two patches? !------------------------------------------------------------------------------------- - norm = abs(currentPatch%pft_agb_profile(ft,z) - tpp%pft_agb_profile(ft,z))/(0.5_r8*& + norm = abs(currentPatch%pft_agb_profile(ft,z) - & + tpp%pft_agb_profile(ft,z))/(0.5_r8 * & &(currentPatch%pft_agb_profile(ft,z) + tpp%pft_agb_profile(ft,z))) !---------------------------------------------------------------------! From 8ddcec3f267ae74cbc7e2676293aa5aaeb912548 Mon Sep 17 00:00:00 2001 From: ckoven Date: Wed, 7 Mar 2018 15:29:37 -0700 Subject: [PATCH 09/10] changed NTOL to force_patchfuse_min_biomass --- biogeochem/EDPatchDynamicsMod.F90 | 15 ++++++++------- main/EDTypesMod.F90 | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index 0da91d8877..15a2b0aed4 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -7,7 +7,8 @@ module EDPatchDynamicsMod use FatesInterfaceMod , only : hlm_freq_day use EDPftvarcon , only : EDPftvarcon_inst use EDCohortDynamicsMod , only : fuse_cohorts, sort_cohorts, insert_cohort - use EDtypesMod , only : ncwd, n_dbh_bins, ntol, area, patchfusion_dbhbin_loweredges + use EDtypesMod , only : ncwd, n_dbh_bins, area, patchfusion_dbhbin_loweredges + use EDtypesMod , only : force_patchfuse_min_biomass use EDTypesMod , only : maxPatchesPerSite use EDTypesMod , only : ed_site_type, ed_patch_type, ed_cohort_type use EDTypesMod , only : min_patch_area @@ -1407,13 +1408,13 @@ subroutine fuse_patches( csite, bc_in ) !--------------------------------------------------------------------------------------------------------- ! the next bit of logic forces fusion of two patches which both have tiny biomass densities. without this, ! fates gives a bunch of really young patches which all have almost no biomass and so don't need to be - ! distinguished from each other. but if NTOL is too big, it takes too long for the youngest patch to build - ! up enough biomass to be its own distinct entity, which leads to large oscillations in the patch dynamics - ! and dependent variables. + ! distinguished from each other. but if force_patchfuse_min_biomass is too big, it takes too long for the + ! youngest patch to build up enough biomass to be its own distinct entity, which leads to large oscillations + ! in the patch dynamics and dependent variables. !--------------------------------------------------------------------------------------------------------- - if(sum(currentPatch%pft_agb_profile(:,:)) > NTOL .or. & - sum(tpp%pft_agb_profile(:,:)) > NTOL ) then + if(sum(currentPatch%pft_agb_profile(:,:)) > force_patchfuse_min_biomass .or. & + sum(tpp%pft_agb_profile(:,:)) > force_patchfuse_min_biomass ) then !---------------------------------------------------------------------! ! Calculate the difference criteria for each pft and dbh class ! @@ -1449,7 +1450,7 @@ subroutine fuse_patches( csite, bc_in ) endif ! biomass(ft,z) .gt. 0 enddo !ht bins enddo ! PFT - endif ! sum(biomass(:,:) .gt. NTOL + endif ! sum(biomass(:,:) .gt. force_patchfuse_min_biomass endif ! maxage !-------------------------------------------------------------------------! diff --git a/main/EDTypesMod.F90 b/main/EDTypesMod.F90 index 45e3ea1ea3..fafce06313 100644 --- a/main/EDTypesMod.F90 +++ b/main/EDTypesMod.F90 @@ -81,7 +81,7 @@ module EDTypesMod real(r8), parameter :: fire_threshold = 50.0_r8 ! threshold for fires that spread or go out. KWm-2 (Pyne 1986) ! PATCH FUSION - real(r8), parameter :: NTOL = 0.005_r8 ! min biomass (kg / m2 patch area) below which to force-fuse patches + real(r8), parameter :: force_patchfuse_min_biomass = 0.005_r8 ! min biomass (kg / m2 patch area) below which to force-fuse patches integer , parameter :: N_DBH_BINS = 6 ! no. of dbh bins used when comparing patches real(r8), parameter :: patchfusion_dbhbin_loweredges(N_DBH_BINS) = & (/0._r8, 5._r8, 20._r8, 50._r8, 100._r8, 150._r8/) ! array of bin lower edges for comparing patches From 3d08f7ccad7f4cd956eceeba2bea6f16819ff4f0 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 12 Apr 2018 12:31:51 -0600 Subject: [PATCH 10/10] Remove unneeded setting of variable --- biogeochem/EDPatchDynamicsMod.F90 | 2 -- 1 file changed, 2 deletions(-) diff --git a/biogeochem/EDPatchDynamicsMod.F90 b/biogeochem/EDPatchDynamicsMod.F90 index 477d5d0e6f..1beffb2acc 100644 --- a/biogeochem/EDPatchDynamicsMod.F90 +++ b/biogeochem/EDPatchDynamicsMod.F90 @@ -1345,8 +1345,6 @@ subroutine fuse_patches( csite, bc_in ) ! !--------------------------------------------------------------------- - maxpatch = maxPatchesPerSite - currentSite => csite profiletol = ED_val_patch_fusion_tol