eCLM-ParFlow: Couple surface water and route all layer-1 water fluxes to ParFlow - #147
Merged
Merged
Conversation
This was referenced Sep 24, 2026
Member
- impervious urban runoff left the domain as river runoff without entering ParFlow - route it into ParFlow layer 1 - zeroed qflx_surf/qflx_qrgwl and write it to qflx_drain as for every other coupled column
- h2osfc from eCLM use ponding computed by ParFlow, adapt frach2osfc accordingly - Infiltration passes all surface input minus soil and surface-water evaporation to ParFlow without the eCLM qinmax capacity - account layer-1 water change (RenewCondensation, CombineSnowLayers), store pfl_top_sync after the sync and add the layer-1 mass change to qflx_parflow - remove qflx_h2osfc_to_ice (ponded water frozen into snow) from the ParFlow source term - route snow-capping liquid qflx_snwcp_liq to ParFlow layer 1 instead of qflx_qrgwl - SnowWater: liquid taken from soil layer 1 is taken from qflx_top_soil - smp_l set to 0 for saturated/ponded cells (pfl_psi > 0) instead of keeping the previous value
- replace pfl_top_sync by the flux accumulator qflx_pfl_top_col in waterflux_inst - RenewCondensation: dew is passed to ParFlow via qflx_pfl_top instead of added to h2osoi_liq; the soil-ice change from dew/sublimation is added to qflx_pfl_top - CombineSnowLayers: when snow water goes to soil layer, it is passed to ParFlow via qflx_pfl_top instead of added to h2osoi_liq - ParFlowDrainage adds qflx_pfl_top to qflx_parflow
s-poll
force-pushed
the
dev-runoff-olf
branch
from
September 29, 2026 19:29
f01d4d8 to
711c006
Compare
Member
Author
|
I rebased the branch as it was cleaner. In addition I changed the logic for changes for h2osoi update within eCLM. Instead of using a flux based on the mass deficit in eCLM, the flux is now directly catched in the corresponding functions (RenewCondensation, CombineSnowLayers). @kvrigor : please review, thank you. |
kvrigor
requested changes
Sep 30, 2026
-change preprocessor statements - rename liq_from_soil to snowliq_to_soil
kvrigor
approved these changes
Oct 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Solves 136.
Summary
Couple surface water and route all layer-1 water fluxes to ParFlow assuming direct infiltration. The ParFlow computational costs increase by about 10-15%, but the loss of water mass (in EUR-12) without this change is about 50-100mm per year on average.
Issue
ParFlow solves soil water and overland flow, but eCLM still partly behaved as if it did:
Text below is drafted by AI based on my analysis:
Changes
All changes are inside
#ifdef COUP_OAS_PFL.h2osfcfrom ParFlow (clm_driver.F90,clm_drv_init): for soil and crop columns,h2osfc = max(0, pfl_psi(c,1)), the ponding depth of ParFlow's top cell. It is set right afterpfl_psiis received, soFracH2OSfc, the energy routines andInfiltrationall see ParFlow's current state. eCLM's surface-water physics are unchanged in form.Infiltration(SoilHydrologyMod.F90): in coupled mode, the full surface input minus soil and surface-water evaporation is passed to ParFlow. Noqinmaxcap, no separateh2osfcbookkeeping, andqflx_h2osfc_surf = 0.SoilWaterMovementMod.F90,WaterStateType.F90,ParFlowDrainage):soilwater_parflowstorespfl_top_sync = liq(1) + ice(1)right after the sync.ParFlowDrainageadds(liq(1) + ice(1) − pfl_top_sync) / dtimeto the layer-1 source term. This one term covers every later writer (RenewCondensation,CombineSnowLayers) with eCLM's own weights and caps. eCLM keeps the ice phase, so after the next receiveliq = pfl_total − icegives the correct phase split.ParFlowDrainage:−qflx_h2osfc_to_ice: ponded water that froze into snow+qflx_snwcp_liq: snow-capping liquid, which previously went to the river;qflx_qrgwlis now 0SnowWater(SnowHydrologyMod.F90): liquid taken from soil layer 1 to refill a negative bottom snow layer is added toqflx_top_soil, so it is taken from ParFlow.smp_l: set to 0 wherepfl_psi > 0.ParFlowDrainagenow takeswaterstate_inst(HydrologyDrainageMod.F90).Snow-capping ice still goes to the river as ice, as a stand-in for glacier flow.
Verification
EUR-12, spun-up restarts, January and July 2018. Each month ran 3 days with hourly output and 1 day with output at every timestep. The baseline was built from the same commit with the same toolchain; the only difference between the two binaries is this patch.
Switch and identity
QH2OSFC ≡ 0in both months.H2OSFCwith ParFlow ponding rose from 0.02 to 0.96.h2osfc = max(0, pfl_psi(c,1))is reproducedWater budget
Per gridcell and step:
R = inputs − ET − ice runoff − Δ(canopy + snow) − Σ QPARFLOW.(mean |R| in mm/s)
QPARFLOW. This PR doesn't change those columns.Physics (July, domain means)
FH2OSFC > 0.9on 3.7% of cells, up from 0%.FH2OSFC > 0.9).Computational costs
Known limitations
h2osfcis reset from ParFlow every step whilet_h2osfcis kept, so the heat content of the surface-water layer can jump between steps.t_h2osfcandFGRhave not been checked yet.