Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

alternative way to adjust area issues in FATES twostream #1310

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions biogeochem/EDCanopyStructureMod.F90
jennykowalcz marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -2274,6 +2274,13 @@ subroutine UpdateCohortLAI(currentCohort, canopy_layer_tlai, total_canopy_area)

! Number of actual vegetation layers in this cohort's crown
currentCohort%nv = count((currentCohort%treelai+currentCohort%treesai) .gt. dlower_vai(:)) + 1

if( currentCohort%nv .ne. minloc(dlower_vai, DIM=1, MASK=(dlower_vai>(currentCohort%treelai+currentCohort%treesai))) ) then
write(fates_log(),*) 'We use two methods of finding maximum leaf layers, and they are not equivalent'
write(fates_log(),*) 'count method:',currentCohort%nv
write(fates_log(),*) 'minloc method:',minloc(dlower_vai, DIM=1, MASK=(dlower_vai>(currentCohort%treelai+currentCohort%treesai)))
call endrun(msg=errMsg(sourcefile, __LINE__))
end if

end subroutine UpdateCohortLAI

Expand Down
51 changes: 39 additions & 12 deletions radiation/FatesTwoStreamUtilsMod.F90
jennykowalcz marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,20 @@ subroutine FatesConstructRadElements(site,fcansno_pa,coszen_pa)
integer :: max_elements ! Maximum number of scattering elements on the site
integer :: n_scr ! The size of the scratch arrays
logical :: allocate_scratch ! Whether to re-allocate the scratch arrays
integer :: icolmax ! Column index for each layer with largest are footprint
jennykowalcz marked this conversation as resolved.
Show resolved Hide resolved
real(r8) :: areamax ! The area footprint of the largest column

! its possible that there is more horizontal area taken up by the cohorts
! than there is ground, which is simply a result numerical and algorithmic
! imprecision in the rest of FATES. If this is true, then we need
! to somehow force the total area of our scattering elements to be exactly
! 1 and not slightly more. One way is to just chop off some area of the
! largest scattering element (simple way), the other is to chop off that
! area but also increase the LAI+SAI. The latter is conservative, but
! could create indexing problems when transfering fluxes back into FATES arrays

logical, parameter :: do_simple_area_correct = .true.


! These parameters are not used yet
!real(r8) :: max_vai_diff_per_elem ! The maximum vai difference in any element
Expand Down Expand Up @@ -119,6 +133,13 @@ subroutine FatesConstructRadElements(site,fcansno_pa,coszen_pa)
! an air element is needed for all the non
! occupied space, even if the canopy_open_frac
! is zero.
! If the area of the elements does not match
! the area of the canopy space within 1.e-7_r8
! then we either add the space in the form of air
! or we compress the space by literally squeezing
! the elements (which consequently increases their
! LAI and SAI to conserve area)


if(patch%total_canopy_area>nearzero)then
canopy_frac(:) = 0._r8
Expand Down Expand Up @@ -230,24 +251,30 @@ subroutine FatesConstructRadElements(site,fcansno_pa,coszen_pa)
end if

! If the layer is overfull, remove some from area from
! the first element that is 10x larger than the threshold
! the element with the largest footprint

if_overfull: if( (canopy_frac(ican)-1._r8)>area_err_thresh ) then

! First find the element with the largest footprint
icolmax = -1
areamax = 0
do icol = 1,n_col(ican)
if(twostr%scelg(ican,icol)%area > 10._r8*(canopy_frac(ican)-1._r8))then
area_ratio = (twostr%scelg(ican,icol)%area + (1._r8-canopy_frac(ican)))/twostr%scelg(ican,icol)%area
twostr%scelg(ican,icol)%area = twostr%scelg(ican,icol)%area * area_ratio
twostr%scelg(ican,icol)%lai = twostr%scelg(ican,icol)%lai / area_ratio
twostr%scelg(ican,icol)%sai = twostr%scelg(ican,icol)%sai / area_ratio
canopy_frac(ican) = 1.0_r8
exit if_overfull
if(twostr%scelg(ican,icol)%area>areamax) then
icolmax = icol
areamax = twostr%scelg(ican,icol)%area
end if
end do

!write(fates_log(),*) 'overfull areas'
!twostr%cosz = coszen_pa(ifp)
! call twostr%Dump(1,lat=site%lat,lon=site%lon)
! call endrun(msg=errMsg(sourcefile, __LINE__))
! Test out a simpler way to correct area errors
if(do_simple_area_correct) then
twostr%scelg(ican,icolmax)%area = twostr%scelg(ican,icolmax)%area - (canopy_frac(ican)-1._r8)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The canopy_frac(ican) here is going to be greater than 1 at this point in the code correct? Is it possible that the value of canopy_frac(ican)-1._r8 could be greater than area? If so we might end up with a negative final area and should have a limiter against this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The area being used here is from the element that has the largest area of the group. The group sums to 1. In a worst case scenario, lets say we had 1000 cohorts all sharing one layer, then the area of the largest element would be no less than 0.001. So in this case, the error would have to be larger than 0.001. Therefore, I don't think this should be a problem, but it shouldn't hurt to add in a check and complain/fail gracefully if this does happen.

Copy link
Contributor Author

@rgknox rgknox Feb 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added in a check. I put it behind a debug for now. I can run some tests to see if they trigger, and then set the debug flags back to false so that they don't slow down the run. Note that we really should not have layers that are that overfull, this is because we try to make the cohorts fit correctly during the ppa demotion/promotion scheme. These methods here try to make the area convergence tolerance even tighter, so that it doesn't introduce energy balance errors into the model.

else
area_ratio = (twostr%scelg(ican,icolmax)%area + (1._r8-canopy_frac(ican)))/twostr%scelg(ican,icolmax)%area
twostr%scelg(ican,icolmax)%area = twostr%scelg(ican,icolmax)%area * area_ratio
twostr%scelg(ican,icolmax)%lai = twostr%scelg(ican,icolmax)%lai / area_ratio
twostr%scelg(ican,icolmax)%sai = twostr%scelg(ican,icolmax)%sai / area_ratio
end if

end if if_overfull

end do
Expand Down