-
Notifications
You must be signed in to change notification settings - Fork 105
Canopy trimming subroutine optimization update #623
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
Canopy trimming subroutine optimization update #623
Conversation
|
Note that the code partially addresses issue #377 by setting the optimum value to be less than one: https://github.com/NGEET/fates/pull/623/files#diff-b2580903c042bbb143bb267a7b882e3fR632-R635 |
|
Regression tests on cheyenne all expected PASS:
|
|
100 year BCI acre comparison plots. These runs were done with the standard fates variable outputs; I can add more to the plots if necessary. |
|
@glemieux @ckoven is it possible that bfr_per_bleaf is uninitialized in some cases? I'm looking to see if that is possible, but maybe you can strike that for me: https://github.com/NGEET/fates/pull/623/files#diff-b2580903c042bbb143bb267a7b882e3fR479 |
|
ok, I see that it is only used inside the same conditional where it is set. nvm |
|
I think you had been bringing this point up before @glemieux . I see here: that we are kind-of re-constructing the wheel on calculating the actual SLA at the layer of interest. I think we discussed if this PR should try to tidy this stuff up, and build some functions that can be used consistently in different places so there is no repeated code that could diverge. I still think it is fine to put this in another change-set, but just wanted to acknowledge it here |
|
This is kind of a weird clause: https://github.com/NGEET/fates/pull/623/files#diff-b2580903c042bbb143bb267a7b882e3fR579 It seems the intention here is really to filter out new plants. I think "isnew" might be more appropriate... Although, I think this routine comes after the daily growth happens, so at that point no plants are new. So this clause only rejects plants that have not incremented their height growth yet. Still don't know why we do that...? |
| if (nnu_clai_a(1,1) > 1) then | ||
|
|
||
| ! Compute the optimum size of the work array | ||
| lwork = -1 ! Ask sgels to compute optimal number of entries for work |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
checked through the lapack dgels description. Verified that nnu_cla_b is not overwritten when work dne 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we add some documentation here describing the arguments that dgels is expecting, etc, like what we have for the lapack dgesv call here: https://github.com/NGEET/fates/blob/master/biogeophys/FatesPlantHydraulicsMod.F90#L4812?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually i see now that's what is going on in the code starting at line 400 above... sorry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At @rgknox suggestion I am writing up a technote to help describe the setup: https://github.com/glemieux/fates-jupyter/blob/develop/leaf-flutter/pr623-linear-solver.ipynb
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also like the idea of some comments in line. Something that would explain what variables are equated to the matrix terms: ie Y = X * b, and how the X and Y terms are manipulated into arguments of dgels()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Roger that. I'll flesh out the comments in that part.
| end if | ||
|
|
||
| ! Check leaf cost against the yearly net uptake for that cohort leaf layer | ||
| if (currentCohort%year_net_uptake(z) < currentCohort%leaf_cost) then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@glemieux , why do we allow wholesale trimming of the leaf layer in these conditions? I thought the idea was to let the regression identify the intersection point and just go with that value. It looks like the regression would also over-write whatever was calculated here, so it seems unnecessary right? Also, does the final solution adhere to the trim-limit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question: we do this in case we have less than nll leaf layers to work with for a given cohort. In that case I just decided to let it stay with the old trimming methodology, baring some other rationale. There are two thoughts I had on this:
- I wasn't sure what we should do if we have a cohort with just one leaf layer come in to the routine, i.e.
nv = 1. Presumably that would be for a new cohort so maybe we'd want to just leave it at the default starting trim fraction? - Right now
nllis somewhat randomly hard coded to4for all cohorts regardless of number of leaf layer,nv. I was thinking that there might be 'better' optimum intercepts if thenlllayer is greater for cohorts with more leaf layers (up to a point). That said, I could make the value ofnlldependent onnvso that we'd never have to use the old method except fornv = 1. Alternatively, I just set this tonll = 2and call it a day.
Roger that. I started working up a branch for another PR a couple weeks ago: https://github.com/glemieux/fates/blob/9e04bf7434b7c06fd5138dc2801755a6c7d85624/biogeochem/FatesAllometryMod.F90#L2213-L2278 |
Yeah, my assumption was that we wanted to make sure that we weren't trimming new plants coming in. @rgknox |
|
Checking if the cohorts height is greater than the minimum should achieve the same effect as filtering on the "%isnew" flag. The only situation it would not, and this could be meaningful, is this logic will filter out plants that have not grown in size yet because they have insufficient carbon balance (even though they , yet these are the plants that would potentially benefit from optimizing their allocation. I think we should at least create an issue of this. |
Created issue #645 |
|
@rgknox @ckoven I have an alternate branch with the adjustments to the The results comparing the two versions are pretty much spot on in the acre outputs: https://github.com/glemieux/fates-jupyter/blob/develop/leaf-flutter/acre-output/100year-cumulativelaitest_plots.pdf. Interestingly the |
|
@rgknox I've added some more comments at your suggestion. Would you give me your feedback when you get a chance? |
|
All PASS: |
Description:
This PR updates the
trim_canopysubroutine to resolve #383 (LAI oscillation issue). The update approaches the issue by circumventing the use of a trim increment. Currently, the subroutine compares theleaf_costagainst thenet_uptakefor all leaf layers within a cohort and decreases or increases that cohort'scanopy_trimvalue by a fixed parameter defined increment. This can result in trimming values that appear bang back and forth around some median value.@ckoven hypothesized that a better method would be to determine the 'optimum' cumulative LAI for the whole cohort based on the cumulative LAI versus the "net-net" uptake (leaf cost subtracted from the net uptake per leaf layer). The optimum in this case being the LAI associated with a zero net-net uptake. This optimum LAI can then be used to compute the fractional
canopy_trimvalue.The optimum cumulative LAI is computed by forming a least squares linear fit from the last
nlllayers of a given cohort and using thedgelsroutine from lapack to solve. If the minimum number of leaf layers is not presenttrim_canopyreverts back to using the original trim increment method.Note issue #638 was generated in the course of testing this PR. The calculations of
optimum_laimemcan not be evaluated in the context of the largertrim_canopyimplementation.Collaborators:
@ckoven @rgknox
Expectation of Answer Changes:
Yes, there will be changes to the trimming per cohort and as such LAI and related values will be different.
Checklist:
Test Results:
CTSM (or) E3SM (specify which) test hash-tag: 242d6d14
CTSM (or) E3SM (specify which) baseline hash-tag: 242d6d14
FATES baseline hash-tag: 320a8fc
Test Output:
Regression tests: All expected PASS
ACRE comparison for 30 year BCI site run