Skip to content
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Added support for river routing.

### Changed

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ esma_add_library(${this}
SRCS GEOS_LdasGridComp.F90
SUBCOMPONENTS ${alldirs}
SUBDIRS LDAS_Shared
DEPENDENCIES GEOSland_GridComp GEOSlandice_GridComp makebcs MAPL
DEPENDENCIES GEOSland_GridComp GEOSlandice_GridComp GEOSroute_GridComp makebcs MAPL
INCLUDES ${INC_ESMF})

esma_add_subdirectory(GEOSldas_App)
54 changes: 49 additions & 5 deletions GEOS_LdasGridComp.F90
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module GEOS_LdasGridCompMod
use GEOS_EnsGridCompMod, only: EnsSetServices => SetServices
use GEOS_LandAssimGridCompMod, only: LandAssimSetServices => SetServices
use GEOS_LandiceGridCompMod, only: LandiceSetServices => SetServices
use GEOS_RouteGridCompMod, only: RouteSetServices => SetServices

use LDAS_TileCoordType, only: tile_coord_type , T_TILECOORD_STATE, TILECOORD_WRAP
use LDAS_TileCoordType, only: grid_def_type, io_grid_def_type, operator (==)
Expand Down Expand Up @@ -51,6 +52,7 @@ module GEOS_LdasGridCompMod
! All children
integer,allocatable :: LAND(:)
integer,allocatable :: LANDICE(:)
integer,allocatable :: ROUTE(:)
integer,allocatable :: LANDPERT(:)
integer,allocatable :: METFORCE(:)
integer :: ENSAVG, LANDASSIM
Expand All @@ -62,6 +64,7 @@ module GEOS_LdasGridCompMod
logical :: ensemble_forcing ! switch between deterministic and ensemble forcing
logical :: with_landice ! true if landice tiles requested by config
logical :: with_land ! true if land tiles requested by config
integer :: RUN_ROUTE ! 1/2 if run river-routine grid comp without/with reservoirs,

contains

Expand Down Expand Up @@ -143,13 +146,15 @@ subroutine SetServices(gc, rc)
!create ensemble children
call MAPL_GetObjectFromGC(gc, MAPL, rc=status)
VERIFY_(status)
call MAPL_GetResource ( MAPL, NUM_ENSEMBLE, Label="NUM_LDAS_ENSEMBLE:", DEFAULT=1, RC=STATUS)
call MAPL_GetResource ( MAPL, NUM_ENSEMBLE, Label="NUM_LDAS_ENSEMBLE:", DEFAULT=1, RC=STATUS)
VERIFY_(STATUS)
call MAPL_GetResource ( MAPL, ens_id_width, Label="ENS_ID_WIDTH:", DEFAULT=0, RC=STATUS)
call MAPL_GetResource ( MAPL, ens_id_width, Label="ENS_ID_WIDTH:", DEFAULT=0, RC=STATUS)
VERIFY_(STATUS)
call MAPL_GetResource ( MAPL, FIRST_ENS_ID, Label="FIRST_ENS_ID:", DEFAULT=0, RC=STATUS)
call MAPL_GetResource ( MAPL, RUN_ROUTE, Label="RUN_ROUTE:", DEFAULT=0, RC=STATUS)
VERIFY_(STATUS)
call MAPL_GetResource ( MAPL, FIRST_ENS_ID, Label="FIRST_ENS_ID:", DEFAULT=0, RC=STATUS)
VERIFY_(STATUS)
call MAPL_GetResource ( MAPL, ENS_FORCING_STR, Label="ENSEMBLE_FORCING:", DEFAULT="NO", RC=STATUS)
call MAPL_GetResource ( MAPL, ENS_FORCING_STR, Label="ENSEMBLE_FORCING:", DEFAULT="NO", RC=STATUS)
VERIFY_(STATUS)
ENS_FORCING_STR = ESMF_UtilStringUpperCase(ENS_FORCING_STR, rc=STATUS)
VERIFY_(STATUS)
Expand All @@ -174,6 +179,10 @@ subroutine SetServices(gc, rc)
if (any(tile_types == MAPL_LAND )) with_land = .true.
! if (any(tile_types == MAPL_LAKE )) with_lake = .true.

if (NUM_ENSEMBLE>1) then
_ASSERT( .not. (with_landice .or. RUN_ROUTE>0), "Landice and route not supported in ensemble mode.")
endif

call MAPL_GetResource ( MAPL, LAND_ASSIM_STR, Label="LAND_ASSIM:", DEFAULT="NO", RC=STATUS)
VERIFY_(STATUS)
LAND_ASSIM_STR = ESMF_UtilStringUpperCase(LAND_ASSIM_STR, rc=STATUS)
Expand Down Expand Up @@ -205,7 +214,10 @@ subroutine SetServices(gc, rc)

if (with_land) allocate(LAND( NUM_ENSEMBLE),LANDPERT(NUM_ENSEMBLE))
if (with_landice) allocate(LANDICE(NUM_ENSEMBLE))

if (RUN_ROUTE >= 1) then
_ASSERT( with_land, "RUNOFF must be from the export of land_gridcomp for now.")
allocate(ROUTE(NUM_ENSEMBLE))
endif
! ens_id_with = 2 + number of digits = total number of chars in ensid_string ("_eXXXX")
!
! Assert ens_id_width<=2+9 so number of digits remains single-digit and "I1" can be
Expand Down Expand Up @@ -253,6 +265,12 @@ subroutine SetServices(gc, rc)
LANDICE(i) = MAPL_AddChild(gc, name=childname, ss=LandiceSetServices, rc=status)
VERIFY_(status)
endif

if (RUN_ROUTE >= 1) then
childname='ROUTE'//trim(ensid_string)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@weiyuan-jiang, @zyj8881357 : This line suggests that the routing model could be set up with LDAS in ensemble mode. The same seems to be true for the landice model (see preceding block). However, the ensemble GridComp appears to be exclusively in the (non-glaciated) land tile space. Since the land, landice, and routing GridComps each work in different tile spaces, do we need to overhaul the ensemble GridComp to make the ensemble functionality work for routing and/or landice? I wonder how long it might take to do that. In the meantime, we could perhaps add a "stop" if NUM_ENSEMBLE>1 .and. (with_landice .or. RUN_ROUTE>0); that is, turn off the ensemble functionality unless the simulation includes only land tiles. Please advise, thanks

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"stop if NUM_ENSEMBLE>1 .and. (with_landice .or. RUN_ROUTE>0)" has been added.

ROUTE(i) = MAPL_AddChild(gc, name=childname, ss=RouteSetServices, rc=status)
VERIFY_(status)
endif
enddo

if (with_land) then
Expand Down Expand Up @@ -302,6 +320,17 @@ subroutine SetServices(gc, rc)
rc = status &
)
VERIFY_(status)

IF(RUN_ROUTE >= 1) THEN
call MAPL_AddConnectivity ( &
GC ,&
SHORT_NAME = (/'RUNOFF '/) ,& ! RUNOFF = total runoff = surface runoff + baseflow
SRC_ID = LAND(I) ,&
DST_ID = ROUTE(I) ,&
RC=STATUS )
VERIFY_(STATUS)
ENDIF

enddo

if(land_assim .or. mwRTM) then
Expand Down Expand Up @@ -788,6 +817,13 @@ subroutine Initialize(gc, import, export, clock, rc)
call MAPL_Set(CHILD_MAPL, LocStream=landice_locstream, rc=status)
VERIFY_(status)
endif

if (RUN_ROUTE >= 1) then
call MAPL_GetObjectFromGC(gcs(ROUTE(i)), CHILD_MAPL, rc=status)
VERIFY_(status) ! CHILD = ens_avg
call MAPL_Set(CHILD_MAPL, LocStream=land_locstream, rc=status)
VERIFY_(status)
endif

enddo

Expand Down Expand Up @@ -1016,6 +1052,14 @@ subroutine Run(gc, import, export, clock, rc)
call MAPL_TimerOff(MAPL, gcnames(igc))
endif ! with_land_ice

if ( RUN_ROUTE >= 1 ) then
igc = ROUTE(i)
call MAPL_TimerOn(MAPL, gcnames(igc))
call ESMF_GridCompRun(gcs(igc), importState=gim(igc), exportState=gex(igc), clock=clock, phase=1, userRC=status)
VERIFY_(status)
call MAPL_TimerOff(MAPL, gcnames(igc))
endif ! river-routine

if (with_land) then
! ApplyPrognPert - moved: now before calculating ensemble average that is picked up by land analysis and HISTORY; reichle 28 May 2020
igc = LANDPERT(i)
Expand Down
14 changes: 14 additions & 0 deletions GEOSldas_App/GEOSldas_HIST.rc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ COLLECTIONS:
# 'const_2d_lnd_Nx'
# 'tavg24_2d_glc_Nx'
# 'tavg24_1d_glc_Nt'
# 'tavg24_1d_route'
::

# --------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -580,4 +581,17 @@ EASEv2_M36.LM: 1
'WESNBOT' , 'LANDICE' ,
'WESNEXT' , 'LANDICE' ,
::

tavg24_1d_route.descr: 'Catchment-space,Daily,Time-Averaged,Single-level,Runoff Routing Diagnostics',
tavg24_1d_route.nbits: 12,
tavg24_1d_route.template: '%y4%m2%d2_%h2%n2z.nc4',
tavg24_1d_route.archive: '%c/Y%y4',
tavg24_1d_route.format: 'CFIO',
tavg24_1d_route.mode: 'time-averaged',
tavg24_1d_route.frequency: 240000,
tavg24_1d_route.ref_time: 000000,
tavg24_1d_route.fields: 'QSFLOW' , 'ROUTE' ,
'QOUTFLOW' , 'ROUTE' ,
'QRES' , 'ROUTE' ,
::
# ========================== EOF ==============================================================
Loading
Loading