[WIP] Add NVP (Non-Vascular Plant) Layer in CTSM#3927
Conversation
… nvp layer (lower bound -11).
…lation when NVP layer is present.
…instead of the bulk tinc.
…now / exposed-NVP / exposed bare-soil).
…and eflx_lh_grnd calculation.
…lyr(p,0) (snow buried) parts.
… for energy flux (with frac_h2osfc) and solar radiation (implicit)
The description of subroutine NVPColdStartIce() suggests that it is intended to set the NVP layer (0) moisture content to be 100% ice, within the pore space available. However, before this commit, it was setting both liquid AND ICE content to zero. This led to 0/0 later in the code.
| do c = bounds%begc, bounds%endc | ||
| if (col%nvp_layer_active(c) .and. col%dz(c,0) > 0._r8) then | ||
| max_ice_nvp = watsat_nvp * denice * col%dz(c,0) | ||
| waterstate_inst%h2osoi_ice_col(c,0) = max_ice_nvp |
There was a problem hiding this comment.
I will change this to be frozen only if temperature is ≤ freezing. That would be consistent with WaterStateType%InitCold().
Some text in the subroutine description suggests this is handled elsewhere, but it's cryptic, and I don't understand it. It would be easier to understand if this subroutine chose liquid or frozen itself. (Make sure to update the subroutine description!)
269a477 to
e4b973e
Compare
| end do | ||
|
|
||
| ! [PORTED by Hui Tang: transfer NVP Beer's law absorptance from bc_out to surfalb_inst] | ||
| ! fabd_nvp_col/fabi_nvp_col are col-level; average equally over all patches in the site. |
There was a problem hiding this comment.
average equally over all patches in the site
Why? I would have thought these should be weighted by the area of the column on each patch.
| nvp_frac_sum = nvp_frac_sum + this%fates(nc)%bc_out(s)%nvp_frac_pa(ifp) | ||
| end do | ||
| if (nvp_frac_sum > 1.e-5_r8) then | ||
| surfalb_inst%alb_nvp_gnd_col(c) = surfalb_inst%alb_nvp_gnd_col(c) / nvp_frac_sum |
There was a problem hiding this comment.
Shouldn't the case of small nvp_frac_sum be handled?
|
It looks like you're never passing the nvp-specific if (trim(fates_stomatal_model) == 'ballberry1987') then
pass_stomatal_model = 1
else if (trim(fates_stomatal_model) == 'medlyn2011') then
pass_stomatal_model = 2
end if
call set_fates_ctrlparms('stomatal_model',ival=pass_stomatal_model)Is that intentional? There are, after all, parts of the FATES PR (e.g.) that look for the |
Description:
This PR introduces a physically explicit representation of non-vascular plants (NVP; e.g., moss and lichen) in CTSM–FATES and its biophysical effect by assigning them to a dedicated vertical layer in CTSM, and a NVP PFT in FATES. The core architectural decision is to use layer 0 of the soil-snow layer structure to accommodate NVP and its growth (i.e., changes in height) when it is present. This layer integrates consistently into CLM’s radiation (under snow), thermal, and hydrology schemes, while coupling to FATES (NGEET/fates#1556) for canopy radiation (without snow) and photosynthesis (see the following call graph).
Note: The implementation is not fully ready yet and is still open for discussion.
Key implementation details in CLM:
NVPWaterBalance_Column.Collaborators:
@rosiealice
Expectation of Answer Changes:
This PR is expected to produce answer changes when NVP is active and NVP layer is present:
No answer changes are expected when NVP is disabled.
Description of generative AI usage
Claude code has been used for porting changes into the new CTSM version and designing the overall structure. The call graph is also generated by Claude code.
Any User Interface Changes (namelist or namelist defaults changes): Yes.
Does this create a need to change or add documentation? Yes