-
Notifications
You must be signed in to change notification settings - Fork 9
Add river routing module #1143
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
base: develop
Are you sure you want to change the base?
Add river routing module #1143
Conversation
…t in GEOSgcm_GridComp/GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSland_GridComp/GEOSroute_GridComp
…ent (GEOS_RouteGridComp.F90)
|
I have reviewed the branch and fixed several issues. It can now produce results that are nearly identical to those from my original branch (the remaining differences are likely due to numerical precision). In addition, I have updated the pre-processing script for the routing model so that it generates the files cellarea.nc and river_input.nc, which are used in make_bcs. |
|
This PR is being prevented from merging because you have added one of our blocking labels: Contingent - DNA, Needs Lead Approval, Contingent -- Do Not Approve. You'll need to remove it before this PR can be merged. |
|
I just discussed the pfaf_index with @tclune and I am ok with the change |
…m:GEOS-ESM/GEOSgcm_GridComp into feature/wjiang/Routing_GEOSroute_on_yujin
|
CI build fails because it requires GEOS-ESM/MAPL#4000 |
…ation, vertical alignment)
gmao-rreichle
left a comment
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.
@zyj8881357, see inline comments below.
GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSroute_GridComp/CMakeLists.txt
Outdated
Show resolved
Hide resolved
...GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSroute_GridComp/GEOS_RouteGridComp.F90
Show resolved
Hide resolved
...GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSroute_GridComp/GEOS_RouteGridComp.F90
Outdated
Show resolved
Hide resolved
...GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSroute_GridComp/GEOS_RouteGridComp.F90
Outdated
Show resolved
Hide resolved
...agcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSroute_GridComp/routing_model.F90
Outdated
Show resolved
Hide resolved
| REAL, INTENT(OUT), DIMENSION (NCAT) :: QSFLOW,QOUTFLOW | ||
|
|
||
| REAL, PARAMETER :: K_SIMPLE = 0.111902, K_RES_MAX = 0.8 ! m1_r2com_c1 | ||
| REAL, PARAMETER :: CUR_AVG = 1.4 |
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.
Some of these parameter constants are defined in multiple places. E.g., 'cur_avg' is defined in at least three different files. We need to find way to define these constants only once. This may require fine-tuning the CMakeLists.txt file such that a build does the Routing GridComp before it does the Utils/Raster stuff. Then we should be able to connect the constants via "use" statements.
Note that some of the parameter constants used in the routing model may also be defined in Catchment (e.g., the total number of Pfafstetter catchments). This may require some thought and reorganization of the constants across GridComps
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.
After removing the linear model, only two parameters (ie, M and mm) are shared between the routing_model.F90 and the pre-processing package. I have modified the CMakeLists.txt of the pre-processing package to let it read the M and mm from the routing_model.F90.
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.
The total number of Pfafstetter catchments is still defined in multiple places across the Routing code, and it's also defined in Land/Shared:
GEOSland_GridComp/Shared/catch_constants.f90: INTEGER, PARAMETER, PUBLIC :: CATCH_N_PFAFS = 291284 ! # of Pfafstetter hydrological catchments (global)
Utils/Raster/preproc/routing_model/constant.f90: integer,parameter :: nc=291284 ! Total number of catchments
Utils/Raster/preproc/routing_model/get_Qr_clmt.f90: integer, parameter :: nc = 291284 ! Total number of catchments
Utils/Raster/preproc/routing/routing_constant.f90: integer,parameter :: nc = 291284 ! number of catchments in land
Ultimately, we'll probably need a new total number of Pfafstetter catchments that includes both land and landice, and that number probably needs to be defined in Surface/Shared. For now, though, the multiple definitions of "nc" in the Routing code can be cleaned up.
GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/Utils/Raster/makebcs/pfaf_frac.F90
Outdated
Show resolved
Hide resolved
|
|
||
| implicit none | ||
|
|
||
| logical, parameter :: use_res = .True. |
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.
What exactly does this logical turn on/off? The entire "reservoir" module? Or just a portion of it? Needs more explanation. Also, it may be better to make this a runtime config input via RUN_ROUTE. We could have something like:
RUN_ROUTE = 0 : no routing
RUN_ROUTE = 1 : hydro geometry routing without reservoir model
RUN_ROUTE = 2 : linear routing without reservoir model
RUN_ROUTE = 3 : hydro geometry routing with reservoir model
etc
This approach is flexible and extensible, and it puts the documentation into one place (GEOS_SurfaceGridComp.rc).
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 agree with this. This will be addressed later when we finish the "Move Routing GC from Land GC to Surface GC".
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.
Didn't @weiyuan-jiang already complete "Move Routing GC from Land GC to Surface GC"? There was a commit to that effect, but the box in the task list wasn't checked. So not sure about the status of this..
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 just confirmed with @weiyuan-jiang that this is done
...agcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSroute_GridComp/routing_model.F90
Outdated
Show resolved
Hide resolved
| endif | ||
| call MAPL_CommsBcast(layout, tmp_real, n_pfaf_g, MAPL_Root, status) | ||
| allocate(route%areacat(n_pfaf_local), source = tmp_real(minCatch:maxCatch)) | ||
| route%areacat=route%areacat*1.e6 |
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.
The seem to be "hidden" unit changes for some of the parameter inputs. The parameters should probably be included in the restart file, so this section is likely to change. In any case, if the units of the parameters in the nc4 file are different from the units of the parameters as they are used in the calculations, it's best to be very explicit about it
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 will address this when moving the river parameters to restart file.
|
Thanks for the comments! I will modify the code accordingly.
…On Mon, Dec 8, 2025 at 4:16 PM Rolf Reichle ***@***.***> wrote:
***@***.**** commented on this pull request.
@zyj8881357 <https://github.com/zyj8881357>, see inline comments below.
------------------------------
In
GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSroute_GridComp/CMakeLists.txt
<#1143 (comment)>
:
> @@ -0,0 +1,11 @@
+esma_set_this ()
+
+set (srcs
+ GEOS_RouteGridComp.F90
+ routing_model.F90
+ reservoir.F90
+ )
+
+esma_add_library (${this} SRCS ${srcs} DEPENDENCIES MAPL GEOS_LandShared ESMF::ESMF NetCDF::NetCDF_Fortran)
+
+install(PROGRAMS build_rivernetwork.py DESTINATION bin)
Is the file build_rivernetwork.py used in the running of the routing
model? Based on the name, it looks to be something that may belong in
Utils/Raster ( make_bcs or preproc). Or it may be obsolete. Probably needs
cleaning up
------------------------------
In
GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSroute_GridComp/GEOS_RouteGridComp.F90
<#1143 (comment)>
:
> + UNITS = 'm+3 s-1' ,&
+ SHORT_NAME = 'QINFLOW' ,&
+ DIMS = MAPL_DimsTileOnly ,&
+ VLOCATION = MAPL_VLocationNone ,&
+ _RC )
+
+ call MAPL_AddExportSpec(GC, &
+ LONG_NAME = 'transfer_of_river_water_to_downstream_catchments' ,&
+ UNITS = 'm+3 s-1' ,&
+ SHORT_NAME = 'QOUTFLOW' ,&
+ DIMS = MAPL_DimsTileOnly ,&
+ VLOCATION = MAPL_VLocationNone ,&
+ _RC )
+
+ call MAPL_AddExportSpec(GC, &
+ LONG_NAME = 'reservoir_discharge' ,&
Please double-check that my edit to the LONG_NAME is correct. (It was just
'qres' before.)
------------------------------
In
GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSroute_GridComp/GEOS_RouteGridComp.F90
<#1143 (comment)>
:
> + ! Call reservoir module
+
+ call res%calc( QOUTFLOW_ACT, QRES_ACT, WRES, real(route_dt), _RC)
+ QOUT_CAT = QOUTFLOW_ACT
+ where(res%active_res==1) QOUT_CAT=QRES_ACT
+ allocate(QINFLOW_LOCAL(n_pfaf_local))
+ call exchange_water(QOUT_CAT, QINFLOW_LOCAL, _RC)
+ WRIVER = WRIVER + QINFLOW_LOCAL*real(route_dt)
+
+ ! Check balance if needed
+ !call check_balance(route,n_pfaf_local,nt_local,runoff_acc,WRIVER_ACT,WSTREAM_ACT,WTOT_BEFORE,RUNOFF_ACT,QINFLOW_LOCAL,QOUT_CAT,FirstTime,yr_s,mon_s)
+
+ ! Update accumulated variables for output
+ nstep_per_day = 86400/route_dt
+
+ route%wriver_acc = route%wriver_acc + WRIVER /real(nstep_per_day)
I can't figure out the '_acc' variables. Are these needed for the core
computations of the routing model? Or are they just needed for output? If
they are just for output, why can't we use MAPL functionality to create
time averages?
Also, I don't understand why the number of routing time steps per day is
used here. Is there are hardwired daily time step somewhere? Don't WRIVER,
WSTREAM, etc evolve at ROUTE_DT?
------------------------------
In
GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSroute_GridComp/GEOS_RouteGridComp.F90
<#1143 (comment)>
:
> + VERIFY_(STATUS)
+ ArrayPtr = route%runoff_acc(:)
+ call ESMF_FieldSMM(srcField=route%field_src, dstField=route%Field, &
+ routeHandle=route%routeHandle, rc=rc)
+ call ESMF_FieldGet(route%field, farrayPtr=arrayPtr, rc=status)
+ VERIFY_(STATUS)
+ RUNOFF_ACT = arrayPtr * route%areacat/1000.
+
+
+ ! Prepares to conduct routing model
+ allocate (AREACAT_ACT (n_pfaf_local))
+ allocate (LENGSC_ACT (n_pfaf_local))
+ allocate (QSFLOW_ACT (n_pfaf_local))
+ allocate (QOUTFLOW_ACT(n_pfaf_local),QRES_ACT(n_pfaf_local),QOUT_CAT(n_pfaf_local))
+
+ QRES_ACT=0.
What are the '_ACT' variables? What does "ACT" stand for? Are these
variables related to the '_acc' variables? See comment below.
------------------------------
In
GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSroute_GridComp/routing_model.F90
<#1143 (comment)>
:
> @@ -0,0 +1,254 @@
+MODULE routing_model
+
+ IMPLICIT NONE
+
+ private
+
+ public :: river_routing_lin, river_routing_hyd, SEARCH_DNST, ROUTE_DT
+
+ integer, parameter :: ROUTE_DT = 3600
In GEOS_SurfaceGridComp.rc there is a routing time step "RRM_DT". Why
hardwire ROUTE_DT here ?
------------------------------
In
GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSroute_GridComp/routing_model.F90
<#1143 (comment)>
:
> + IMPLICIT NONE
+
+ INTEGER, INTENT(IN) :: NCAT
+ REAL, INTENT(IN), DIMENSION (NCAT) :: Qrunf0,llc_ori,lstr
+ REAL, INTENT(IN), DIMENSION (NCAT) :: qstr_clmt0,qri_clmt0,qin_clmt0
+ REAL, INTENT(IN), DIMENSION (NCAT) :: K, Kstr0
+ REAL, INTENT(INOUT),DIMENSION (NCAT) :: Ws0,Wr0
+ REAL, INTENT(OUT), DIMENSION (NCAT) :: Qs,Qout
+
+
+
+ real, parameter :: small = 1.e-20
+ real, parameter :: fac_kstr = 0.01 ! Factor for local stream scaling
+ real, parameter :: M = 0.45 ! Parameter in hydraulic geometry formula
+ real, parameter :: mm = 0.35 ! Parameter in hydraulic geometry formula
+ real, parameter :: rho = 1000. ! Density of liquid water [kg/m3]
Physics constants should be from MAPL. There is MAPL_RHOWTR in
MAPL/shared/Constants/PhysicalConstants.F90 . A generic "use MAPL"
statement at the top of the file should make this available, although not
sure if that's the recommended way to link to MAPL constants.
------------------------------
In
GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSroute_GridComp/routing_model.F90
<#1143 (comment)>
:
> + !**** QOUTFLOW = TRANSFER OF RIVER WATER TO THE DOWNSTREAM CATCHMENT [m^3/s]
+
+ SUBROUTINE RIVER_ROUTING_LIN ( &
+ NCAT, &
+ RUNCATCH,AREACAT,LENGSC, &
+ WSTREAM,WRIVER, &
+ QSFLOW,QOUTFLOW)
+
+ IMPLICIT NONE
+ INTEGER, INTENT(IN) :: NCAT
+ REAL, INTENT(IN), DIMENSION (NCAT) :: RUNCATCH,AREACAT,LENGSC
+ REAL, INTENT(INOUT),DIMENSION (NCAT) :: WSTREAM, WRIVER
+ REAL, INTENT(OUT), DIMENSION (NCAT) :: QSFLOW,QOUTFLOW
+
+ REAL, PARAMETER :: K_SIMPLE = 0.111902, K_RES_MAX = 0.8 ! m1_r2com_c1
+ REAL, PARAMETER :: CUR_AVG = 1.4
Some of these parameter constants are defined in multiple places. E.g.,
'cur_avg' is defined in at least three different files. We need to find way
to define these constants only once. This may require fine-tuning the
CMakeLists.txt file such that a build does the Routing GridComp before it
does the Utils/Raster stuff. Then we should be able to connect the
constants via "use" statements.
Note that some of the parameter constants used in the routing model may
also be defined in Catchment (e.g., the total number of Pfafstetter
catchments). This may require some thought and reorganization of the
constants across GridComps
------------------------------
In
GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/Utils/Raster/makebcs/pfaf_frac.F90
<#1143 (comment)>
:
> + integer, allocatable, dimension(:) :: tid, catid, lati_tile, loni_tile
+ real*8, allocatable, dimension(:) :: lon_left, lon_right, lat_bottom, lat_top, latc,lonc
+ integer,allocatable,dimension(:,:) :: map_tile
+
+ real,allocatable,dimension(:) :: area_cat, pfaf_frac(:)
+ real,allocatable,dimension(:,:) :: frac,frac_tile
+ integer,allocatable,dimension(:) :: nsub_tile
+ integer,allocatable ::csub(:,:),flag2(:,:), tile_id(:), pfaf_index(:)
+ type(NetCDF4_FileFormatter) :: formatter
+ type (FileMetadata) :: meta
+ type(Variable) :: v
+ integer :: nc_ease, nr_ease
+ real :: tmp_lat, tmp_lon
+
+ ! Define file path for input routing data:
+ character(len=256) :: pfafData_file = "/discover/nobackup/projects/gmao/bcs_shared/make_bcs_inputs/land/topo/v1/SRTM-TopoData/SRTM_PfafData.nc" !"input/CatchIndex.nc"
There are about half a dozen hard-coded
"/discover/nobackup/.../bcs_shared/" paths across the routing files in
Utils/Raster. This should be centralized by defining a "BCS_PATH"
somewhere. Assuming the F90 executables are run from python, we can define
BCS_PATH in python and then make "BCS_PATH" a runtime input (command line
arg) for the fortran executable.
------------------------------
In
GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSroute_GridComp/GEOS_RouteGridComp.F90
<#1143 (comment)>
:
> +! IMPORTS : RUNOFF \\
+
+! !USES:
+
+ use ESMF
+ use MAPL_Mod
+ use MAPL_ConstantsMod
+ use ROUTING_MODEL, ONLY: river_routing_lin, river_routing_hyd, ROUTE_DT
+ use reservoirMod, ONLY: RES_STATE, Reservoir
+ use catch_constants, ONLY: N_pfaf_g => CATCH_N_PFAFS
+
+ use, intrinsic :: iso_c_binding
+
+ implicit none
+
+ logical, parameter :: use_res = .True.
What exactly does this logical turn on/off? The entire "reservoir" module?
Or just a portion of it? Needs more explanation. Also, it may be better to
make this a runtime config input via RUN_ROUTE. We could have something
like:
RUN_ROUTE = 0 : no routing
RUN_ROUTE = 1 : hydro geometry routing without reservoir model
RUN_ROUTE = 2 : linear routing without reservoir model
RUN_ROUTE = 3 : hydro geometry routing with reservoir model
etc
This approach is flexible and extensible, and it puts the documentation
into one place (GEOS_SurfaceGridComp.rc).
------------------------------
In
GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSroute_GridComp/routing_model.F90
<#1143 (comment)>
:
> + !**** RUNCATCH = RUNOFF PRODUCED BY LAND SURFACE MODEL IN THE CATCHMENT [m^3/s]
+ !**** AREACAT = AREA OF CATCHMENT [km^2]
+ !**** LENGSC = LENGTHSCALE OF CATCHMENT FOR RIVER CALCULATION [km]
+ ! Note: We assume LENGSC for stream to river calculation as AREACAT/LENGSC
+
+ ! Routing Model Prognostics
+ ! -------------------------
+ !**** WSTREAM = AMOUNT OF WATER IN "LOCAL STREAM" [m^3]
+ !**** WRIVER = AMOUNT OF WATER IN RIVER [m^3]
+
+ ! Routing Model Diagnostics
+ ! -------------------------
+ !**** QSFLOW = TRANSFER OF MOISTURE FROM STREAM VARIABLE TO RIVER VARIABLE [m^3/s]
+ !**** QOUTFLOW = TRANSFER OF RIVER WATER TO THE DOWNSTREAM CATCHMENT [m^3/s]
+
+ SUBROUTINE RIVER_ROUTING_LIN ( &
Currently, this subroutine is not used and could be deleted.
Alternatively, maybe offer the use of the linear routing model as one
option of RUN_ROUTE. See comment on. "use_res" in GEOSroute_GridComp.F90.
------------------------------
In
GEOSagcm_GridComp/GEOSphysics_GridComp/GEOSsurface_GridComp/GEOSroute_GridComp/GEOS_RouteGridComp.F90
<#1143 (comment)>
:
> + route%maxCatch = maxCatch
+
+ call MAPL_GetResource (MAPL, RIVER_INPUT_FILE, label = 'RIVER_INPUT_FILE:', default = '../input/river_input.nc', RC=STATUS )
+ if (MAPL_AM_I_Root()) then
+ call formatter%open(RIVER_INPUT_FILE, PFIO_READ, _RC)
+ endif
+ allocate(tmp_real(n_pfaf_g))
+ allocate(tmp_int(n_pfaf_g))
+
+ ! read areacat
+ if (MAPL_AM_I_Root()) then
+ call formatter%get_var('area_catch', tmp_real(:), _RC)
+ endif
+ call MAPL_CommsBcast(layout, tmp_real, n_pfaf_g, MAPL_Root, status)
+ allocate(route%areacat(n_pfaf_local), source = tmp_real(minCatch:maxCatch))
+ route%areacat=route%areacat*1.e6
The seem to be "hidden" unit changes for some of the parameter inputs. The
parameters should probably be included in the restart file, so this section
is likely to change. In any case, if the units of the parameters in the nc4
file are different from the units of the parameters as they are used in the
calculations, it's best to be very explicit about it
—
Reply to this email directly, view it on GitHub
<#1143 (review)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AHZKGWUTCN7OKDJ6T7WFK6T4AXTETAVCNFSM6AAAAACD4ZP2O6VHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZTKNJTHA4TQMZRGU>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Add river routing module for offline land modeling (GEOSldas). Replaces #1023
Left for future PRs:
Related PRs:
Testing:
List of tasks that remain to be addressed (in no particular order):
@YujiN, I am trying to bring back some codes in develop branch. The develop branch is not working as it is but I believe it would be more efficient. The runoff and the other variables are distributed as needed, which is way more efficient than allgatherV.