@@ -7,7 +7,8 @@ module EDPatchDynamicsMod
77 use FatesInterfaceMod , only : hlm_freq_day
88 use EDPftvarcon , only : EDPftvarcon_inst
99 use EDCohortDynamicsMod , only : fuse_cohorts, sort_cohorts, insert_cohort
10- use EDtypesMod , only : ncwd, n_dbh_bins, ntol, area, dbhmax
10+ use EDtypesMod , only : ncwd, n_dbh_bins, area, patchfusion_dbhbin_loweredges
11+ use EDtypesMod , only : force_patchfuse_min_biomass
1112 use EDTypesMod , only : maxPatchesPerSite
1213 use EDTypesMod , only : ed_site_type, ed_patch_type, ed_cohort_type
1314 use EDTypesMod , only : min_patch_area
@@ -118,7 +119,8 @@ subroutine disturbance_rates( site_in, bc_in)
118119
119120 call mortality_rates(currentCohort,bc_in,cmort,hmort,bmort,frmort)
120121 currentCohort% dmort = cmort+ hmort+ bmort+ frmort
121- call carea_allom(currentCohort% dbh,currentCohort% n,site_in% spread,currentCohort% pft,currentCohort% c_area)
122+ call carea_allom(currentCohort% dbh,currentCohort% n,site_in% spread,currentCohort% pft, &
123+ currentCohort% c_area)
122124
123125 ! Initialize diagnostic mortality rates
124126 currentCohort% cmort = cmort
@@ -1321,6 +1323,8 @@ subroutine fuse_patches( csite, bc_in )
13211323 !
13221324 ! !USES:
13231325 use EDParamsMod , only : ED_val_patch_fusion_tol
1326+ use EDTypesMod , only : patch_fusion_tolerance_relaxation_increment
1327+ use EDTypesMod , only : max_age_of_second_oldest_patch
13241328 !
13251329 ! !ARGUMENTS:
13261330 type (ed_site_type), intent (inout ), target :: csite
@@ -1332,14 +1336,12 @@ subroutine fuse_patches( csite, bc_in )
13321336 integer :: ft,z ! counters for pft and height class
13331337 real (r8 ) :: norm ! normalized difference between biomass profiles
13341338 real (r8 ) :: profiletol ! tolerance of patch fusion routine. Starts off high and is reduced if there are too many patches.
1335- integer :: maxpatch ! maximum number of allowed patches. FIX-RF. These should be namelist variables.
13361339 integer :: nopatches ! number of patches presently in gridcell
13371340 integer :: iterate ! switch of patch reduction iteration scheme. 1 to keep going, 0 to stop
13381341 integer :: fuse_flag ! do patches get fused (1) or not (0).
1342+ !
13391343 !- --------------------------------------------------------------------
13401344
1341- maxpatch = maxPatchesPerSite
1342-
13431345 currentSite = > csite
13441346
13451347 profiletol = ED_val_patch_fusion_tol
@@ -1356,7 +1358,7 @@ subroutine fuse_patches( csite, bc_in )
13561358 iterate = 1
13571359
13581360 !- --------------------------------------------------------------------!
1359- ! Keep doing this until nopatches >= maxpatch !
1361+ ! Keep doing this until nopatches >= maxPatchesPerSite !
13601362 !- --------------------------------------------------------------------!
13611363
13621364 do while (iterate == 1 )
@@ -1382,36 +1384,80 @@ subroutine fuse_patches( csite, bc_in )
13821384 endif
13831385
13841386 if (associated (tpp).and. associated (currentPatch))then
1385- fuse_flag = 1 ! the default is to fuse the patches
1387+
1388+ !- -------------------------------------------------------------------------------------------
1389+ ! The default is to fuse the patches, unless some criteria is met which keeps them separated.
1390+ ! there are multiple criteria which all need to be met to keep them distinct:
1391+ ! (a) one of them is younger than the max age at which we force fusion;
1392+ ! (b) there is more than a threshold (tiny) amount of biomass in at least one of the patches;
1393+ ! (c) for at least one pft x size class, where there is biomass in that class in at least one patch,
1394+ ! and the normalized difference between the patches exceeds a threshold.
1395+ !- -------------------------------------------------------------------------------------------
1396+
1397+ fuse_flag = 1
13861398 if (currentPatch% patchno /= tpp% patchno) then ! these should be the same patch
13871399
1388- !- --------------------------------------------------------------------!
1389- ! Calculate the difference criteria for each pft and dbh class !
1390- !- --------------------------------------------------------------------!
1391- do ft = 1 ,numpft ! loop over pfts
1392- do z = 1 ,n_dbh_bins ! loop over hgt bins
1393- ! is there biomass in this category?
1394- if (currentPatch% pft_agb_profile(ft,z) > 0.0_r8 .or. tpp% pft_agb_profile(ft,z) > 0.0_r8 )then
1395- norm = abs (currentPatch% pft_agb_profile(ft,z) - tpp% pft_agb_profile(ft,z))/ (0.5_r8 * &
1396- &(currentPatch% pft_agb_profile(ft,z) + tpp% pft_agb_profile(ft,z)))
1397- !- --------------------------------------------------------------------!
1398- ! Look for differences in profile biomass, above the minimum biomass !
1399- !- --------------------------------------------------------------------!
1400-
1401- if (norm > profiletol)then
1402- ! looking for differences between profile density.
1403- if (currentPatch% pft_agb_profile(ft,z) > NTOL.or. tpp% pft_agb_profile(ft,z) > NTOL)then
1404- fuse_flag = 0 ! do not fuse - keep apart.
1405- endif
1406- endif ! profile tol
1407- endif ! NTOL
1408- enddo ! ht bins
1409- enddo ! PFT
1410-
1411- !- --------------------------------------------------------------------!
1412- ! Call the patch fusion routine if there is a meaningful difference !
1413- ! any of the pft x height categories !
1414- !- --------------------------------------------------------------------!
1400+ !- ----------------------------------------------------------------------------------
1401+ ! check to see if both patches are older than the age at which we force them to fuse
1402+ !- ----------------------------------------------------------------------------------
1403+
1404+ if ( tpp% age .le. max_age_of_second_oldest_patch .or. &
1405+ currentPatch% age .le. max_age_of_second_oldest_patch ) then
1406+
1407+
1408+ !- --------------------------------------------------------------------------------------------------------
1409+ ! the next bit of logic forces fusion of two patches which both have tiny biomass densities. without this,
1410+ ! fates gives a bunch of really young patches which all have almost no biomass and so don't need to be
1411+ ! distinguished from each other. but if force_patchfuse_min_biomass is too big, it takes too long for the
1412+ ! youngest patch to build up enough biomass to be its own distinct entity, which leads to large oscillations
1413+ ! in the patch dynamics and dependent variables.
1414+ !- --------------------------------------------------------------------------------------------------------
1415+
1416+ if (sum (currentPatch% pft_agb_profile(:,:)) > force_patchfuse_min_biomass .or. &
1417+ sum (tpp% pft_agb_profile(:,:)) > force_patchfuse_min_biomass ) then
1418+
1419+ !- --------------------------------------------------------------------!
1420+ ! Calculate the difference criteria for each pft and dbh class !
1421+ !- --------------------------------------------------------------------!
1422+
1423+ do ft = 1 ,numpft ! loop over pfts
1424+ do z = 1 ,n_dbh_bins ! loop over hgt bins
1425+
1426+ !- ---------------------------------
1427+ ! is there biomass in this category?
1428+ !- ---------------------------------
1429+
1430+ if (currentPatch% pft_agb_profile(ft,z) > 0.0_r8 .or. &
1431+ tpp% pft_agb_profile(ft,z) > 0.0_r8 )then
1432+
1433+ !- ------------------------------------------------------------------------------------
1434+ ! what is the relative difference in biomass i nthis category between the two patches?
1435+ !- ------------------------------------------------------------------------------------
1436+
1437+ norm = abs (currentPatch% pft_agb_profile(ft,z) - &
1438+ tpp% pft_agb_profile(ft,z))/ (0.5_r8 * &
1439+ &(currentPatch% pft_agb_profile(ft,z) + tpp% pft_agb_profile(ft,z)))
1440+
1441+ !- --------------------------------------------------------------------!
1442+ ! Look for differences in profile biomass, above the minimum biomass !
1443+ !- --------------------------------------------------------------------!
1444+
1445+ if (norm > profiletol)then
1446+
1447+ fuse_flag = 0 ! do not fuse - keep apart.
1448+
1449+ endif ! profile tol
1450+ endif ! biomass(ft,z) .gt. 0
1451+ enddo ! ht bins
1452+ enddo ! PFT
1453+ endif ! sum(biomass(:,:) .gt. force_patchfuse_min_biomass
1454+ endif ! maxage
1455+
1456+ !- ------------------------------------------------------------------------!
1457+ ! Call the patch fusion routine if there is not a meaningful difference !
1458+ ! any of the pft x height categories !
1459+ ! or both are older than forced fusion age !
1460+ !- ------------------------------------------------------------------------!
14151461
14161462 if (fuse_flag == 1 )then
14171463 tmpptr = > currentPatch% older
@@ -1445,9 +1491,9 @@ subroutine fuse_patches( csite, bc_in )
14451491 currentPatch = > currentPatch% older
14461492 enddo
14471493
1448- if (nopatches > maxpatch )then
1494+ if (nopatches > maxPatchesPerSite )then
14491495 iterate = 1
1450- profiletol = profiletol * 1.1_r8
1496+ profiletol = profiletol * patch_fusion_tolerance_relaxation_increment
14511497
14521498 !- --------------------------------------------------------------------!
14531499 ! Making profile tolerance larger means that more fusion will happen !
@@ -1456,7 +1502,7 @@ subroutine fuse_patches( csite, bc_in )
14561502 iterate = 0
14571503 endif
14581504
1459- enddo ! do while nopatches>maxpatch
1505+ enddo ! do while nopatches>maxPatchesPerSite
14601506
14611507 end subroutine fuse_patches
14621508
@@ -1765,20 +1811,15 @@ subroutine patch_pft_size_profile(cp_pnt)
17651811
17661812 currentPatch = > cp_pnt
17671813
1768- delta_dbh = (DBHMAX/ N_DBH_BINS)
1769-
17701814 currentPatch% pft_agb_profile(:,:) = 0.0_r8
17711815
17721816 do j = 1 ,N_DBH_BINS
1773- if (j == 1 ) then
1774- mind(j) = 0.0_r8
1775- maxd(j) = delta_dbh
1776- else if (j == N_DBH_BINS) then
1777- mind(j) = (j-1 ) * delta_dbh
1817+ if (j == N_DBH_BINS) then
1818+ mind(j) = patchfusion_dbhbin_loweredges(j)
17781819 maxd(j) = gigantictrees
17791820 else
1780- mind(j) = (j -1 ) * delta_dbh
1781- maxd(j) = (j) * delta_dbh
1821+ mind(j) = patchfusion_dbhbin_loweredges(j)
1822+ maxd(j) = patchfusion_dbhbin_loweredges(j +1 )
17821823 endif
17831824 enddo
17841825
0 commit comments