@@ -12,6 +12,7 @@ module EDPatchDynamicsMod
1212 use EDTypesMod , only : maxPatchesPerSite
1313 use EDTypesMod , only : ed_site_type, ed_patch_type, ed_cohort_type
1414 use EDTypesMod , only : min_patch_area
15+ use EDTypesMod , only : min_patch_area_forced
1516 use EDTypesMod , only : nclmax
1617 use EDTypesMod , only : maxpft
1718 use EDTypesMod , only : dtype_ifall
@@ -1537,7 +1538,7 @@ subroutine fuse_patches( csite, bc_in )
15371538 ! Keep doing this until nopatches >= maxPatchesPerSite !
15381539 !- --------------------------------------------------------------------!
15391540
1540- do while (iterate == 1 )
1541+ do while (iterate == 1 .and. nopatches > 1 )
15411542 !- --------------------------------------------------------------------!
15421543 ! Calculate the biomass profile of each patch !
15431544 !- --------------------------------------------------------------------!
@@ -1555,10 +1556,6 @@ subroutine fuse_patches( csite, bc_in )
15551556 tpp = > currentSite% youngest_patch
15561557 do while (associated (tpp))
15571558
1558- if (.not. associated (currentPatch))then
1559- write (fates_log(),* ) ' ED: issue with currentPatch'
1560- endif
1561-
15621559 if (associated (tpp).and. associated (currentPatch))then
15631560
15641561 !- -------------------------------------------------------------------------------------------
@@ -1878,16 +1875,28 @@ subroutine terminate_patches(currentSite)
18781875 type (ed_patch_type), pointer :: currentPatch
18791876 type (ed_patch_type), pointer :: olderPatch
18801877 type (ed_patch_type), pointer :: youngerPatch
1878+ integer , parameter :: max_cycles = 10 ! After 10 loops through
1879+ ! You should had fused
1880+ integer :: count_cycles
18811881
18821882 real (r8 ) areatot ! variable for checking whether the total patch area is wrong.
18831883 !- --------------------------------------------------------------------
18841884
1885+ count_cycles = 0
1886+
18851887 currentPatch = > currentSite% youngest_patch
18861888 do while (associated (currentPatch))
18871889
18881890 if (currentPatch% area <= min_patch_area)then
18891891
1890- if ( .not. associated (currentPatch,currentSite% youngest_patch) ) then
1892+ ! Even if the patch area is small, avoid fusing it into its neighbor
1893+ ! if it is the youngest of all patches. We do this in attempts to maintain
1894+ ! a discrete patch for very young patches
1895+ ! However, if the patch to be fused is excessivlely small, then fuse
1896+ ! at all costs. If it is not fused, it will make
1897+
1898+ if ( .not. associated (currentPatch,currentSite% youngest_patch) .or. &
1899+ currentPatch% area <= min_patch_area_forced ) then
18911900
18921901 if (associated (currentPatch% older) )then
18931902
@@ -1908,12 +1917,12 @@ subroutine terminate_patches(currentSite)
19081917 ! This logic checks to make sure that the younger patch is not the youngest
19091918 ! patch. As mentioned earlier, we try not to fuse it.
19101919
1911- elseif ( .not. associated (currentPatch% younger,currentSite % youngest_patch ) ) then
1920+ elseif ( associated (currentPatch% younger) ) then
19121921
19131922 if (debug) &
19141923 write (fates_log(),* ) ' fusing to younger patch because oldest one is too small' , &
19151924 currentPatch% area
1916-
1925+
19171926 youngerPatch = > currentPatch% younger
19181927 call fuse_2_patches(currentSite, youngerPatch, currentPatch)
19191928
@@ -1922,22 +1931,44 @@ subroutine terminate_patches(currentSite)
19221931 endif
19231932 endif
19241933 endif
1925-
1926- currentPatch = > currentPatch% older
19271934
1935+ ! It is possible that an incredibly small patch just fused into another incredibly
1936+ ! small patch, resulting in an incredibly small patch. It is also possible that this
1937+ ! resulting incredibly small patch is the oldest patch. If this was true than
1938+ ! we would had been at the end of the loop, and left with an incredibly small patch.
1939+ ! Think this is impossible? No, this really happens, especially when we have fires.
1940+ ! So, we don't move forward until we have merged enough area into this thing.
1941+
1942+ if (currentPatch% area > min_patch_area_forced)then
1943+ currentPatch = > currentPatch% older
1944+ count_cycles = 0
1945+ else
1946+ count_cycles = count_cycles + 1
1947+ end if
1948+
1949+ if (count_cycles > max_cycles) then
1950+ write (fates_log(),* ) ' FATES is having difficulties fusing very small patches.'
1951+ write (fates_log(),* ) ' It is possible that a either a secondary or primary'
1952+ write (fates_log(),* ) ' patch has become the only patch of its kind, and it is'
1953+ write (fates_log(),* ) ' is very very small. You can test your luck by'
1954+ write (fates_log(),* ) ' disabling the endrun statement following this message.'
1955+ write (fates_log(),* ) ' FATES may or may not continue to operate within error'
1956+ write (fates_log(),* ) ' tolerances, but will generate another fail if it does not.'
1957+ call endrun(msg= errMsg(sourcefile, __LINE__))
1958+
1959+ ! Note to user. If you DO decide to remove the end-run above this line
1960+ ! Make sure that you keep the pointer below this line, or you will get
1961+ ! an infinite loop.
1962+ currentPatch = > currentPatch% older
1963+ count_cycles = 0
1964+ end if
1965+
19281966 enddo
19291967
19301968 ! check area is not exceeded
1931- areatot = 0._r8
1932- currentPatch = > currentSite% oldest_patch
1933- do while (associated (currentPatch))
1934- areatot = areatot + currentPatch% area
1935- currentPatch = > currentPatch% younger
1936- if ((areatot- area) > 0.0000001_r8 )then
1937- write (fates_log(),* ) ' ED: areatot too large. end terminate' , areatot
1938- endif
1939- enddo
1969+ call check_patch_area( currentSite )
19401970
1971+ return
19411972 end subroutine terminate_patches
19421973
19431974 ! =====================================================================================
0 commit comments