Refactor boundary condition interface structure #1477
Refactor boundary condition interface structure #1477glemieux wants to merge 332 commits intoNGEET:mainfrom
Conversation
Technically we don't really need a subgrid_indices array for the patch-side currently.
…o the api registry type This will help next development steps in which the update of certain variables will be conducted prior to others
…ncy for the soil level
Moved to the interfaceparameter module
These are now handled in Update automatically
| type(fates_interface_variable_type), allocatable :: fates_vars(:) | ||
|
|
||
| ! Array of keys associated with the interface variables | ||
| character(len=48), allocatable, private :: key(:) |
There was a problem hiding this comment.
bump this up in case we want long keys in the future?
| ! Is registry have a FATES patch that exists? | ||
| logical, private :: active | ||
|
|
||
| ! Container array of interface variables indexed by key |
There was a problem hiding this comment.
Do the indices of hlm_vars and fates_vars have correspondence with each other? If so, lets note that here in the description
| integer :: num_api_vars_update_init_dims ! number of variables dimensions needed during initialization | ||
| integer :: num_api_vars_update_init ! number of variables that update only at initialization | ||
| integer :: num_api_vars_update_daily ! number of variables that update daily | ||
| integer :: num_api_vars_update_timestep ! number of variables that update on the model timestep |
There was a problem hiding this comment.
We have variables that need to update at different times during the model time-step. If these transfers need to happen at different times, how can we group them into one "timestep" group?
| currentPatch => currentSite%youngest_patch | ||
| do while(associated(currentPatch)) | ||
|
|
||
| if (currentPatch%nocomp_pft_label .ne. nocomp_bareground) then |
There was a problem hiding this comment.
Was this needed for consistency, speed, removing spurious behavior?
There was a problem hiding this comment.
This was for spurious behavior, but might actually be defunct code that should be removed per recent development. I'll double check this.
| currentPatch => this%sites(s)%oldest_patch | ||
| do while (associated(currentPatch)) | ||
|
|
||
| if (currentPatch%nocomp_pft_label .ne. nocomp_bareground) then |
There was a problem hiding this comment.
I think one of our plans was to get rid of these conditionals by implementing that refactor that removes bareground patches before this, right? Are we punting on that?
There was a problem hiding this comment.
For now. We need this in place until we remove the code that instantiates a fates bareground patch, which is a more significant refactor. That said, we'll need to deal with it during the future multi-column fates pull request.
There was a problem hiding this comment.
I'll add a comment above the check noting this.
| do r = 1, this%npatches | ||
|
|
||
| ! Get the gridcell index | ||
| g = this%registry(r)%GetGridcellIndex() |
There was a problem hiding this comment.
I think technically, we match our fates sites with land-units now right? ELM could have multiple topo-units, each with a natural vegetation land-unit that we would want to match with. Matching at the LU level in CLM would also work.
| subroutine SetLastState(this, last_state) | ||
|
|
||
| ! This procedure sets the last state logical metadata for the calling interface variable |
There was a problem hiding this comment.
I'm not following (yet) how or why the is_last logic is used in practice. maybe some further details on that would be helpful here.
| ! Update the litter flux counters not including the total flux counter | ||
| if (key == hlm_fates_litter_carbon_cellulose .or. & | ||
| key == hlm_fates_litter_carbon_labile .or. & | ||
| key == hlm_fates_litter_carbon_lignin .or. & | ||
| key == hlm_fates_litter_nitrogen_cellulose .or. & | ||
| key == hlm_fates_litter_nitrogen_labile .or. & | ||
| key == hlm_fates_litter_nitrogen_lignin .or. & | ||
| key == hlm_fates_litter_phosphorus_cellulose .or. & | ||
| key == hlm_fates_litter_phosphorus_labile .or. & | ||
| key == hlm_fates_litter_phosphorus_lignin) then | ||
| this%num_api_vars_litter_flux= this%num_api_vars_litter_flux + 1 | ||
| end if |
There was a problem hiding this comment.
I guess an alternative, which might be easier to maintain, would be to make an 'is_litter_flux' or something like that boolean flag for all interface variables rather than enumerating all the variables here?
| ! Litter flux update | ||
| if (this%key(index) == hlm_fates_litter_carbon_cellulose .or. & | ||
| this%key(index) == hlm_fates_litter_nitrogen_cellulose .or. & | ||
| this%key(index) == hlm_fates_litter_phosphorus_cellulose .or. & | ||
| this%key(index) == hlm_fates_litter_carbon_labile .or. & | ||
| this%key(index) == hlm_fates_litter_nitrogen_labile .or. & | ||
| this%key(index) == hlm_fates_litter_phosphorus_labile .or. & | ||
| this%key(index) == hlm_fates_litter_carbon_lignin .or. & | ||
| this%key(index) == hlm_fates_litter_nitrogen_lignin .or. & | ||
| this%key(index) == hlm_fates_litter_phosphorus_lignin) then | ||
| count_litter_flux = count_litter_flux + 1 | ||
| this%filter_litter_flux(count_litter_flux) = index | ||
| end if |
There was a problem hiding this comment.
similar comment to the above -- having a boolean flag attached to the variables might be easier to maintain than enumerating them here?
| use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=) | ||
| use PRTGenericMod , only : prt_cnp_flex_allom_hyp | ||
| use FatesInterfaceVariableTypeMod, only : fates_interface_variable_type | ||
| use FatesInterfaceParametersMod |
There was a problem hiding this comment.
I think I agree that it makes sense to do an unlimited use statement rather than enumerating every possible interface variable name in the list of only variables, which might get quite long, but I guess the risk is that a reader of the code sees all the string indices in DefineInterfaceRegistry and it isn't obvious where those all come from. So I wonder if it would make sense to only have the open-ended use statement in that subroutine and restrict it to use only the integer parameters throughout the rest of the module?
There was a problem hiding this comment.
an alternative might be to give the string keys names something that is more obvious what they are, like fates_interface_var_longname?
Refactors testing directory Also makes a minor error message update to the quadratic solver
Initial refactor of the FATES interface design
Description:
This pull request refactors the HLM-FATES interface design as an initial step towards enabling "dynamic multi-column" FATES runs for NGEE-Arctic cross cut task 4. In this regard, this redesign is intended to address design assumptions in which all FATES patches on a given site are associated with a single column. Given that this redesign will touch on a large amount of code (on both sides), this PR is intended as a minimum-viable case that introduces the new design setup and only refactors a subset of boundary condition variables to prove the concept.
Given the scope of the undertaking, the refactor is also used as an opportunity to introduce a standard method of passing variable data across the HLM-FATES interface and introducing a common vocabulary for associated variables. The intent is to minimize the amount of necessary shared code between FATES and the HLM.
This pull request must be coordinated with E3SM-Project/E3SM#7482 and ESCOMP/CTSM#3705.
For more details, wee NGEET/fates-users-guide#109 for updates to the developer's guide section detail the interface design document (work in progress)
Collaborators:
@rgknox @ckoven
Expectation of Answer Changes:
Checklist
If this is your first time contributing, please read the CONTRIBUTING document.
All checklist items must be checked to enable merging this pull request:
Contributor
Integrator
If satellite phenology regressions are not b4b, please hold merge and notify the FATES development team.
Documentation
Test Results:
CTSM (or) E3SM (specify which) test hash-tag:
CTSM (or) E3SM (specify which) baseline hash-tag:
FATES baseline hash-tag:
Test Output: