diff --git a/.circleci/config.yml b/.circleci/config.yml index af6a78c5..9ac91ca2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -22,6 +22,4 @@ workflows: repo: GEOSldas checkout_fixture: true mepodevelop: false - # This is needed due to the LDAS BRIDGE workflow - checkout_if_exists: false persist_workspace: false # Needs to be true to run fv3/gcm experiment, costs extra diff --git a/.github/workflows/push-to-develop.yml b/.github/workflows/push-to-develop.yml index ebbd3109..3ce6a02e 100644 --- a/.github/workflows/push-to-develop.yml +++ b/.github/workflows/push-to-develop.yml @@ -8,14 +8,15 @@ on: jobs: pull_request: name: Create Pull Request + if: github.repository_owner == 'GEOS-ESM' runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v7 with: fetch-depth: 0 - name: Run the action - uses: devops-infra/action-pull-request@v0.5.5 + uses: devops-infra/action-pull-request@v1 with: github_token: ${{ secrets.GITHUB_TOKEN }} source_branch: develop diff --git a/.github/workflows/validate_yaml_files.yml b/.github/workflows/validate_yaml_files.yml index 449db6e6..be70981f 100644 --- a/.github/workflows/validate_yaml_files.yml +++ b/.github/workflows/validate_yaml_files.yml @@ -15,7 +15,7 @@ jobs: validate-YAML: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - id: yaml-lint name: yaml-lint uses: ibiqlik/action-yamllint@v3 @@ -24,7 +24,7 @@ jobs: format: colored config_file: .yamllint.yml - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 if: always() with: name: yamllint-logfile diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 20796af2..c5995106 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -11,123 +11,36 @@ on: - "**.perl" - ".github/CODEOWNERS" - ".circleci/config.yml" + workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/develop' }} jobs: - build_ldas_ifort: - name: Build GEOSldas with ifort - if: "!contains(github.event.pull_request.labels.*.name, '0 diff trivial')" - runs-on: ubuntu-24.04 - container: - image: gmao/ubuntu24-geos-env:v7.33.0-intelmpi_2021.13-ifort_2021.13 - - env: - OMPI_ALLOW_RUN_AS_ROOT: 1 - OMPI_ALLOW_RUN_AS_ROOT_CONFIRM: 1 - OMPI_MCA_btl_vader_single_copy_mechanism: none - - steps: - # https://github.com/orgs/community/discussions/25678#discussioncomment-5242449 - - name: Delete huge unnecessary tools folder - run: rm -rf /opt/hostedtoolcache - - - name: Checkout LDAS - uses: actions/checkout@v4 - with: - fetch-depth: 1 - filter: blob:none - repository: GEOS-ESM/GEOSldas - - - name: Set all directories as git safe - run: | - git config --global --add safe.directory '*' - - - name: Versions etc. - run: | - ifort --version - mpirun --version - echo $BASEDIR - - - name: Mepo clone external repos - run: | - mepo clone --partial blobless - mepo status - - - name: Debug PR branch - run: echo "PR is coming from ${{ github.event.pull_request.head.ref }}" - - - name: Update other branches - if: ${{ github.event.pull_request.head.ref != 'main' && github.event.pull_request.head.ref != 'develop' }} - run: | - mepo checkout-if-exists ${GITHUB_HEAD_REF} - mepo status - - - name: CMake - run: | - cmake -B build -S . --install-prefix=${pwd}/install -DCMAKE_Fortran_COMPILER=ifort -DCMAKE_BUILD_TYPE=Debug -DMPIEXEC_PREFLAGS='--oversubscribe' -DUSE_F2PY=OFF - - - name: Build - run: | - cmake --build build -j 4 - cmake --install build - - - build_ldas_gfortran: - name: Build GEOSldas with gfortran - if: "!contains(github.event.pull_request.labels.*.name, '0 diff trivial')" - runs-on: ubuntu-24.04 - container: - image: gmao/ubuntu24-geos-env-mkl:v7.33.0-openmpi_5.0.5-gcc_14.2.0 - - env: - OMPI_ALLOW_RUN_AS_ROOT: 1 - OMPI_ALLOW_RUN_AS_ROOT_CONFIRM: 1 - OMPI_MCA_btl_vader_single_copy_mechanism: none - - steps: - # https://github.com/orgs/community/discussions/25678#discussioncomment-5242449 - - name: Delete huge unnecessary tools folder - run: rm -rf /opt/hostedtoolcache - - - name: Checkout LDAS - uses: actions/checkout@v4 - with: - fetch-depth: 1 - filter: blob:none - repository: GEOS-ESM/GEOSldas - - - name: Set all directories as git safe - run: | - git config --global --add safe.directory '*' - - - name: Versions etc. - run: | - gfortran --version - mpirun --version - echo $BASEDIR - - - name: Mepo clone external repos - run: | - mepo clone --partial blobless - mepo status - - - name: Debug PR branch - run: echo "PR is coming from ${{ github.event.pull_request.head.ref }}" - - - name: Update other branches - if: ${{ github.event.pull_request.head.ref != 'main' && github.event.pull_request.head.ref != 'develop' }} - run: | - mepo checkout-if-exists ${GITHUB_HEAD_REF} - mepo status - - - name: CMake - run: | - cmake -B build -S . --install-prefix=${pwd}/install -DCMAKE_Fortran_COMPILER=gfortran -DCMAKE_BUILD_TYPE=Debug -DMPIEXEC_PREFLAGS='--oversubscribe' -DUSE_F2PY=OFF - - - name: Build - run: | - cmake --build build -j 4 - cmake --install build + build_ldas: + strategy: + fail-fast: false + matrix: + compiler: [ifort, gfortran-15, ifx] + build-type: [Debug] + uses: GEOS-ESM/CI-workflows/.github/workflows/geosgcm_build_tests.yml@project/geosgcm + with: + compiler: ${{ matrix.compiler }} + cmake-build-type: ${{ matrix.build-type }} + fixture-repo: GEOS-ESM/GEOSldas + run-mepo-develop: false + + # We cannot currently test with spack because spack does not build the + # HDF4 Fortran interface, which is required for the GEOSldas. + ####################################################################################### + # spack_build: # + # uses: GEOS-ESM/CI-workflows/.github/workflows/spack_gcc_build.yml@project/geosgcm # + # secrets: # + # BUILDCACHE_USERNAME: ${{ secrets.BUILDCACHE_USERNAME }} # + # BUILDCACHE_TOKEN: ${{ secrets.BUILDCACHE_TOKEN }} # + # with: # + # fixture-repo: GEOS-ESM/GEOSldas # + # run-mepo-develop: false # + # load-fms: true # + ####################################################################################### diff --git a/CHANGELOG.md b/CHANGELOG.md index 81a111d2..969914d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Added functionality to simulate lake tiles. - Added assimilation of surface soil moisture observations from H-SAF ASCAT H121 CDR v8 and H139 ICDR netcdf products (MetOp-A/B/C). - Added peatland QC for sfds and sfmc observations. - Added ObsFcstAna postprocessing support for NetCDF4 diagnostics, with fallback to legacy binary ObsFcstAna files. @@ -30,6 +31,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Clarified scope and constraints of RESTART=1 and RESTART=2. - Added RESTART=3 (formerly RESTART=G, which had been removed). - Cleaned up RESTART=M. +- Updated Landice ("glc") HISTORY Collection to that of M21C plus key ISSM outputs. +- Updated CI. + ### Fixed diff --git a/CMakeLists.txt b/CMakeLists.txt index 2cd58b9c..48baf88a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ esma_add_library(${this} SRCS GEOS_LdasGridComp.F90 SUBCOMPONENTS ${alldirs} SUBDIRS LDAS_Shared - DEPENDENCIES GEOSland_GridComp GEOSlandice_GridComp GEOSroute_GridComp makebcs MAPL + DEPENDENCIES GEOSland_GridComp GEOSlake_GridComp GEOSlandice_GridComp GEOSroute_GridComp makebcs MAPL INCLUDES ${INC_ESMF}) esma_add_subdirectory(GEOSldas_App) diff --git a/GEOS_LdasGridComp.F90 b/GEOS_LdasGridComp.F90 index f4109127..d16b83e1 100644 --- a/GEOS_LdasGridComp.F90 +++ b/GEOS_LdasGridComp.F90 @@ -9,33 +9,37 @@ module GEOS_LdasGridCompMod use ESMF use MAPL - use GEOS_MetforceGridCompMod, only: MetforceSetServices => SetServices - use GEOS_LandGridCompMod, only: LandSetServices => SetServices - use GEOS_LandPertGridCompMod, only: LandPertSetServices => SetServices - use GEOS_LandAssimGridCompMod, only: LandAssimSetServices => SetServices - use GEOS_LandiceGridCompMod, only: LandiceSetServices => SetServices - use GEOS_RouteGridCompMod, only: RouteSetServices => SetServices + use GEOS_MetforceGridCompMod, only: MetforceSetServices => SetServices + use GEOS_LandGridCompMod, only: LandSetServices => SetServices + use GEOS_LandPertGridCompMod, only: LandPertSetServices => SetServices + use GEOS_LandAssimGridCompMod, only: LandAssimSetServices => SetServices + use GEOS_LandiceGridCompMod, only: LandiceSetServices => SetServices + use GEOS_RouteGridCompMod, only: RouteSetServices => SetServices + use GEOS_LakeGridCompMod, only: LakeSetServices => SetServices use GEOS_MetforceAvgGridCompMod, only: MetforceAvgSetServices => SetServices - use GEOS_LandAvgGridCompMod, only: LandAvgSetServices => SetServices - use GEOS_LandiceAvgGridCompMod,only: LandiceAvgSetServices=> SetServices - use GEOS_RouteAvgGridCompMod, only: RouteAvgSetServices => 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 (==) - use LDAS_TileCoordRoutines, only: get_minExtent_grid, get_ij_ind_from_latlon, io_domain_files - use LDAS_ConvertMod, only: esmf2ldas - use LDAS_PertRoutinesMod, only: get_pert_grid - use LDAS_ensdrv_functions, only: get_io_filename - use LDAS_DateTimeMod, only: date_time_type - use LDAS_ensdrv_mpi, only: MPI_tile_coord_type, MPI_grid_def_type - use LDAS_ensdrv_mpi, only: init_MPI_types,mpicomm,numprocs,myid - use LDAS_ensdrv_mpi, only: root_proc - use LDAS_ensdrv_Globals, only: logunit,logit,root_logit,echo_clsm_ensdrv_glob_param, get_ensid_string - use catch_constants, only: echo_catch_constants - use StieglitzSnow, only: StieglitzSnow_echo_constants - use SurfParams, only: SurfParams_init - use mapl_StateMerge_mod, only: StateMerge + use GEOS_LandAvgGridCompMod, only: LandAvgSetServices => SetServices + use GEOS_LakeAvgGridCompMod, only: LakeAvgSetServices => SetServices + use GEOS_LandiceAvgGridCompMod, only: LandiceAvgSetServices => SetServices + use GEOS_RouteAvgGridCompMod, only: RouteAvgSetServices => 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 (==) + use LDAS_TileCoordRoutines, only: get_minExtent_grid, get_ij_ind_from_latlon, io_domain_files + use LDAS_ConvertMod, only: esmf2ldas + use LDAS_PertRoutinesMod, only: get_pert_grid + use LDAS_ensdrv_functions, only: get_io_filename + use LDAS_DateTimeMod, only: date_time_type + use LDAS_ensdrv_mpi, only: MPI_tile_coord_type, MPI_grid_def_type + use LDAS_ensdrv_mpi, only: init_MPI_types,mpicomm,numprocs,myid + use LDAS_ensdrv_mpi, only: root_proc + use LDAS_ensdrv_Globals, only: logunit,logit,root_logit,echo_clsm_ensdrv_glob_param, get_ensid_string + + use catch_constants, only: echo_catch_constants + use StieglitzSnow, only: StieglitzSnow_echo_constants + use SurfParams, only: SurfParams_init + use mapl_StateMerge_mod, only: StateMerge + implicit none private @@ -45,9 +49,8 @@ module GEOS_LdasGridCompMod public SetServices ! !DESCRIPTION: This gridded component (GC) combines the GridComps: - ! METFORCE, LAND, LANDPERT, METFORCEAVG, LANDAVG, ROUTEAVG, LANDICEAVG, and LANDASSIM + ! METFORCE, LAND, LANDPERT, METFORCEAVG, LANDAVG, ROUTEAVG, LAKEAVG, LANDICEAVG, and LANDASSIM ! into a new composite LDAS GricComp. - ! Include later: LAKE, LANDICE(?), SALTWATER(?) !EOP @@ -55,19 +58,21 @@ module GEOS_LdasGridCompMod ! All children integer,allocatable :: LAND(:) + integer,allocatable :: LAKE(:) integer,allocatable :: LANDICE(:) integer,allocatable :: ROUTE(:) integer,allocatable :: LANDPERT(:) integer,allocatable :: METFORCE(:) integer :: LANDASSIM - integer :: METFORCEAVG, LANDAVG, ROUTEAVG, LANDICEAVG + integer :: METFORCEAVG, LANDAVG, ROUTEAVG, LAKEAVG, LANDICEAVG ! other global variables - integer :: NUM_ENSEMBLE ! number of land ensemble members + integer :: NUM_ENSEMBLE ! number of land,landpert, and route ensemble members (lake & landice have only 1 member for now) logical :: land_assim logical :: mwRTM logical :: ensemble_forcing ! switch between deterministic and ensemble forcing logical :: with_landice ! true if landice tiles requested by config + logical :: with_lake ! true if lake tiles requested by config logical :: with_land ! true if land tiles requested by config integer :: RUN_ROUTE ! 0:, no river routing, 1: routing w/o reservoirs, 2: routing w/ reservoirs @@ -178,12 +183,12 @@ subroutine SetServices(gc, rc) with_landice = .false. with_land = .false. -! with_lake = .false. + with_lake = .false. if (any(tile_types == MAPL_LANDICE)) with_landice = .true. if (any(tile_types == MAPL_LAND )) with_land = .true. -! if (any(tile_types == MAPL_LAKE )) with_lake = .true. - + if (any(tile_types == MAPL_LAKE )) with_lake = .true. + 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) @@ -213,10 +218,11 @@ subroutine SetServices(gc, rc) allocate(METFORCE(1)) endif - if (with_land) allocate(LAND( NUM_ENSEMBLE),LANDPERT(NUM_ENSEMBLE)) - if (with_landice) allocate(LANDICE(NUM_ENSEMBLE)) + if (with_land) allocate(LAND( NUM_ENSEMBLE), LANDPERT(NUM_ENSEMBLE)) + if (with_lake) allocate(LAKE( 1 ) ) ! for now, only 1 ens member of landice + if (with_landice) allocate(LANDICE(1 ) ) ! for now, only 1 ens member of lake if (RUN_ROUTE >= 1) then - _ASSERT( with_land, "RUNOFF must be from the export of land_gridcomp for now.") + _ASSERT( with_land, "RUNOFF requires exports from land_gridcomp (but not yet from lake or landice, for now).") allocate(ROUTE(NUM_ENSEMBLE)) endif ! ens_id_with = 2 + number of digits = total number of chars in ensid_string ("_eXXXX") @@ -252,26 +258,32 @@ subroutine SetServices(gc, rc) call get_ensid_string(ensid_string, ens_id, ens_id_width, NUM_ENSEMBLE) if (with_land) then - childname='LANDPERT'//trim(ensid_string) + childname = 'LANDPERT'//trim(ensid_string) LANDPERT(i) = MAPL_AddChild(gc, name=childname, ss=LandPertSetServices, rc=status) VERIFY_(status) - - childname='LAND'//trim(ensid_string) - LAND(i) = MAPL_AddChild(gc, name=childname, ss=LandSetServices, rc=status) + + childname = 'LAND' //trim(ensid_string) + LAND(i) = MAPL_AddChild(gc, name=childname, ss=LandSetServices, rc=status) + VERIFY_(status) + endif + + if (with_lake .and. i==1) then ! for now, only 1 ens member of lake + childname = 'LAKE' //trim(ensid_string) + LAKE(i) = MAPL_AddChild(gc, name=childname, ss=LakeSetServices, rc=status) VERIFY_(status) - endif + endif - if (with_landice .and. i == 1) then - childname='LANDICE'//trim(ensid_string) - LANDICE(i) = MAPL_AddChild(gc, name=childname, ss=LandiceSetServices, rc=status) + if (with_landice .and. i==1) then ! for now, only 1 ens member of landice + childname = 'LANDICE' //trim(ensid_string) + LANDICE(i) = MAPL_AddChild(gc, name=childname, ss=LandiceSetServices, rc=status) VERIFY_(status) endif if (RUN_ROUTE >= 1) then - childname='ROUTE'//trim(ensid_string) - ROUTE(i) = MAPL_AddChild(gc, name=childname, ss=RouteSetServices, rc=status) - VERIFY_(status) - endif + childname = 'ROUTE' //trim(ensid_string) + ROUTE(i) = MAPL_AddChild(gc, name=childname, ss=RouteSetServices, rc=status) + VERIFY_(status) + endif enddo if (with_land) then @@ -356,6 +368,10 @@ subroutine SetServices(gc, rc) LANDAVG = MAPL_AddChild(gc, name='LANDAVG', ss=LandAvgSetServices, rc=status) VERIFY_(status) endif + if (with_lake) then + LAKEAVG = MAPL_AddChild(gc, name='LAKEAVG', ss=LakeAvgSetServices, rc=status) + VERIFY_(status) + endif if (with_landice) then LANDICEAVG = MAPL_AddChild(gc, name='LANDICEAVG', ss=LandiceAvgSetServices, rc=status) VERIFY_(status) @@ -416,6 +432,7 @@ subroutine Initialize(gc, import, export, clock, rc) ! MAPL variables type(MAPL_LocStream) :: surf_locstream type(MAPL_LocStream) :: land_locstream + type(MAPL_LocStream) :: lake_locstream type(MAPL_LocStream) :: landice_locstream type(MAPL_LocStream) :: force_locstream type(MAPL_MetaComp), pointer :: MAPL=>null() ! GC's MAPL obj @@ -606,51 +623,61 @@ subroutine Initialize(gc, import, export, clock, rc) call MAPL_Get(MAPL, GCS=gcs, GCNAMES=gcnames, rc=status) VERIFY_(status) - ! Create LAND's locstreams as subset of Surface locstream + ! Create component locstreams as subsets of Surface locstream ! and add it to the children's MAPL objects + ! build the active forcing tile mask in tile-file order: LAND -> LAKE -> LANDICE allocate(mask(0)) if (with_land) then - call MAPL_LocStreamCreate( & - land_locstream, & - surf_locstream, & - name=gcnames(LAND(1)), & - mask=[MAPL_LAND], & - rc=status & + call MAPL_LocStreamCreate( & + land_locstream, & + surf_locstream, & + name=gcnames(LAND(1)), & + mask=[MAPL_LAND], & + rc=status & ) VERIFY_(status) mask =[mask,MAPL_LAND] endif - + if (with_lake) then + call MAPL_LocStreamCreate( & + lake_locstream, & + surf_locstream, & + name=gcnames(LAKE(1)), & + mask=[MAPL_LAKE], & + rc=status ) + VERIFY_(status) + mask = [mask, MAPL_LAKE] + endif if (with_landice) then - call MAPL_LocStreamCreate( & - landice_locstream, & - surf_locstream, & - name=gcnames(LANDICE(1)), & - mask=[MAPL_LANDICE], & - rc=status & - ) + call MAPL_LocStreamCreate( & + landice_locstream, & + surf_locstream, & + name=gcnames(LANDICE(1)), & + mask=[MAPL_LANDICE], & + rc=status & + ) VERIFY_(status) mask = [mask, MAPL_LANDICE] endif - - call MAPL_LocStreamCreate( & - force_locstream, & - surf_locstream, & - name=gcnames(METFORCE(1)), & - mask=mask, & - rc=status & - ) + + call MAPL_LocStreamCreate( & + force_locstream, & + surf_locstream, & + name=gcnames(METFORCE(1)), & + mask=mask, & + rc=status & + ) VERIFY_(status) call MAPL_TimerOff(MAPL, "-LocStreamCreate") ! Convert LAND's LocStream to LDAS' tile_coord and save it in the GridComp ! -get-tile-information-from-land's-locstream- - call MAPL_LocStreamGet( & - force_locstream, & - NT_LOCAL=local_nt, & - LOCAL_ID=local_id, & - rc=status & - ) + call MAPL_LocStreamGet( & + force_locstream, & + NT_LOCAL=local_nt, & + LOCAL_ID=local_id, & + rc=status & + ) VERIFY_(status) ! -get-component's-internal-state- @@ -789,70 +816,83 @@ subroutine Initialize(gc, import, export, clock, rc) enddo do i = 1,NUM_ENSEMBLE + if (with_land) then - call MAPL_GetObjectFromGC(gcs(LAND(i)), CHILD_MAPL, rc=status) + call MAPL_GetObjectFromGC(gcs(LAND(i)), CHILD_MAPL, rc=status) VERIFY_(status) - call MAPL_Set(CHILD_MAPL, LocStream=land_locstream, rc=status) + call MAPL_Set(CHILD_MAPL, LocStream=land_locstream, rc=status) VERIFY_(status) call MAPL_GetObjectFromGC(gcs(LANDPERT(i)), CHILD_MAPL, rc=status) VERIFY_(status) ! CHILD = LANDPERT - call MAPL_Set(CHILD_MAPL, LocStream=land_locstream, rc=status) + call MAPL_Set(CHILD_MAPL, LocStream=land_locstream, rc=status) VERIFY_(status) - + ! Add LAND's tile_coord to children's GridComps - call ESMF_UserCompSetInternalState(gcs(LAND(i)), 'TILE_COORD', tcwrap, status) + call ESMF_UserCompSetInternalState(gcs(LAND(i)), 'TILE_COORD', tcwrap, status) VERIFY_(status) call ESMF_UserCompSetInternalState(gcs(LANDPERT(i)), 'TILE_COORD', tcwrap, status) VERIFY_(status) endif - if (with_landice .and. i == 1) then - call MAPL_GetObjectFromGC(gcs(LANDICE(i)), CHILD_MAPL, rc=status) + if (with_lake .and. i==1) then ! for now, only 1 ens member of lake + call MAPL_GetObjectFromGC(gcs(LAKE(i)), CHILD_MAPL, rc=status) VERIFY_(status) - call MAPL_Set(CHILD_MAPL, LocStream=landice_locstream, rc=status) + call MAPL_Set(CHILD_MAPL, LocStream=lake_locstream, rc=status) VERIFY_(status) - endif + if (with_landice .and. i==1) then ! for now, only 1 ens member of landice + call MAPL_GetObjectFromGC(gcs(LANDICE(i)), CHILD_MAPL, rc=status) + VERIFY_(status) + 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) + call MAPL_GetObjectFromGC(gcs(ROUTE(i)), CHILD_MAPL, rc=status) VERIFY_(status) - call MAPL_Set(CHILD_MAPL, LocStream=land_locstream, rc=status) + call MAPL_Set(CHILD_MAPL, LocStream=land_locstream, rc=status) VERIFY_(status) endif enddo if (land_assim .or. mwRTM ) then - call MAPL_GetObjectFromGC(gcs(LANDASSIM), CHILD_MAPL, rc=status) + call MAPL_GetObjectFromGC( gcs(LANDASSIM), CHILD_MAPL, rc=status) VERIFY_(status) - call MAPL_Set(CHILD_MAPL, LocStream=land_locstream, rc=status) + call MAPL_Set( CHILD_MAPL, LocStream=land_locstream, rc=status) VERIFY_(status) call ESMF_UserCompSetInternalState(gcs(LANDASSIM), 'TILE_COORD', tcwrap, status) VERIFY_(status) endif - - call MAPL_GetObjectFromGC(gcs(METFORCEAVG), CHILD_MAPL, rc=status) + + call MAPL_GetObjectFromGC( gcs(METFORCEAVG), CHILD_MAPL, rc=status) VERIFY_(status) ! only land_locstream is averaged. - call MAPL_Set(CHILD_MAPL, LocStream=land_locstream, rc=status) + call MAPL_Set( CHILD_MAPL, LocStream=land_locstream, rc=status) VERIFY_(status) - + if ( with_land) then - call MAPL_GetObjectFromGC(gcs(LANDAVG), CHILD_MAPL, rc=status) + call MAPL_GetObjectFromGC( gcs(LANDAVG), CHILD_MAPL, rc=status) + VERIFY_(status) ! CHILD = ens_avg + call MAPL_Set( CHILD_MAPL, LocStream=land_locstream, rc=status) + VERIFY_(status) + endif + if ( with_lake) then + call MAPL_GetObjectFromGC( gcs(LAKEAVG), CHILD_MAPL, rc=status) VERIFY_(status) ! CHILD = ens_avg - call MAPL_Set(CHILD_MAPL, LocStream=land_locstream, rc=status) + call MAPL_Set( CHILD_MAPL, LocStream=lake_locstream, rc=status) VERIFY_(status) endif if ( with_landice) then - call MAPL_GetObjectFromGC(gcs(LANDICEAVG), CHILD_MAPL, rc=status) + call MAPL_GetObjectFromGC( gcs(LANDICEAVG), CHILD_MAPL, rc=status) VERIFY_(status) ! CHILD = ens_avg - call MAPL_Set(CHILD_MAPL, LocStream=landice_locstream, rc=status) + call MAPL_Set( CHILD_MAPL, LocStream=landice_locstream, rc=status) VERIFY_(status) endif - + !if ( RUN_ROUTE >= 1) then ! ! not necessary. Route Avg has its own pfaf_locstream ! call MAPL_GetObjectFromGC(gcs(ROUTEAVG), CHILD_MAPL, rc=status) @@ -976,7 +1016,7 @@ subroutine Run(gc, import, export, clock, rc) VERIFY_(status) end if - !phase2 initialization ( executed once) + !phase 2: initialization ( executed once) !adjust mean of perturbed forcing or Progn if (with_land) then do i = 1,NUM_ENSEMBLE @@ -986,7 +1026,7 @@ subroutine Run(gc, import, export, clock, rc) VERIFY_(status) call MAPL_TimerOff(MAPL, gcnames(igc)) enddo - + ! Run children GridComps (in order) ! Generate raw perturbed force and progn do i = 1,NUM_ENSEMBLE @@ -997,19 +1037,19 @@ subroutine Run(gc, import, export, clock, rc) call MAPL_TimerOff(MAPL, gcnames(igc)) enddo endif ! with_land - + do i = 1, NUM_ENSEMBLE igc = METFORCE(i) - call MAPL_TimerOn(MAPL, gcnames(igc)) - call ESMF_GridCompRun(gcs(igc), importState=gim(igc), exportState=gex(igc), clock=clock, phase=1, userRC=status) + 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)) + call MAPL_TimerOff( MAPL, gcnames(igc)) ! exit after i=1 if using deterministic forcing if (.not. ensemble_forcing) exit enddo ! distribute surface met forcing (export forcing to imports of land, landpert, and landice) - do i = 1, NUM_ENSEMBLE + do i = 1,NUM_ENSEMBLE k = 1 if (ensemble_forcing) k = i igc = METFORCE(k) @@ -1022,10 +1062,14 @@ subroutine Run(gc, import, export, clock, rc) VERIFY_(status) endif - if (with_landice .and. i ==1 ) then + if (with_landice .and. i==1) then ! for now, only 1 ens member of lake call ESMF_GridCompRun(gcs(igc), importState=gex(igc), exportState=gim(LANDICE(i)), clock=clock, phase=4, userRC=status) VERIFY_(status) endif + if (with_lake .and. i==1) then ! for now, only 1 ens member of landice + call ESMF_GridCompRun(gcs(igc), importState=gex(igc), exportState=gim(LAKE(i)), clock=clock, phase=5, userRC=status) + VERIFY_(status) + endif call MAPL_TimerOff(MAPL, gcnames(igc)) enddo @@ -1051,31 +1095,43 @@ subroutine Run(gc, import, export, clock, rc) ! Run the land model igc = LAND(i) call MAPL_TimerOn(MAPL, gcnames(igc)) - call ESMF_GridCompRun(gcs(igc), importState=gim(igc), exportState=gex(igc), clock=clock, phase=1, userRC=status) + call ESMF_GridCompRun(gcs(igc), importState=gim(igc), exportState=gex(igc), clock=clock, phase=1, userRC=status) VERIFY_(status) - call ESMF_GridCompRun(gcs(igc), importState=gim(igc), exportState=gex(igc), clock=clock, phase=2, userRC=status) + call ESMF_GridCompRun(gcs(igc), importState=gim(igc), exportState=gex(igc), clock=clock, phase=2, userRC=status) VERIFY_(status) call MAPL_TimerOff(MAPL, gcnames(igc)) endif ! with_land - if (with_landice .and. i ==1 ) then + if (with_landice .and. i==1) then ! for now, only 1 ens member of landice igc = LANDICE(i) call MAPL_TimerOn(MAPL, gcnames(igc)) - call ESMF_GridCompRun(gcs(igc), importState=gim(igc), exportState=gex(igc), clock=clock, phase=1, userRC=status) + call ESMF_GridCompRun(gcs(igc), importState=gim(igc), exportState=gex(igc), clock=clock, phase=1, userRC=status) VERIFY_(status) - call ESMF_GridCompRun(gcs(igc), importState=gim(igc), exportState=gex(igc), clock=clock, phase=2, userRC=status) + call ESMF_GridCompRun(gcs(igc), importState=gim(igc), exportState=gex(igc), clock=clock, phase=2, userRC=status) VERIFY_(status) - call ESMF_GridCompRun(gcs(LANDICEAVG), importState=gex(igc), exportState=gex(LANDICEAVG), clock=clock, userRC=status) + call ESMF_GridCompRun(gcs(LANDICEAVG), importState=gex(igc), exportState=gex(LANDICEAVG), clock=clock, userRC=status) VERIFY_(status) call MAPL_TimerOff(MAPL, gcnames(igc)) endif ! with_land_ice + if (with_lake .and. i==1) then ! for now, only 1 ens member of lake + igc = LAKE(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 ESMF_GridCompRun(gcs(igc), importState=gim(igc), exportState=gex(igc), clock=clock, phase=2, userRC=status) + VERIFY_(status) + call ESMF_GridCompRun(gcs(LAKEAVG), importState=gex(igc), exportState=gex(LAKEAVG), clock=clock, userRC=status) + VERIFY_(status) + call MAPL_TimerOff(MAPL, gcnames(igc)) + endif ! with_lake + 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) + call ESMF_GridCompRun(gcs(igc), importState=gim(igc), exportState=gex(igc), clock=clock, phase=1, userRC=status) VERIFY_(status) - call ESMF_GridCompRun(gcs(ROUTEAVG), importState=gex(igc), exportState=gex(ROUTEAVG), clock=clock, userRC=status) + call ESMF_GridCompRun(gcs(ROUTEAVG), importState=gex(igc), exportState=gex(ROUTEAVG), clock=clock, userRC=status) VERIFY_(status) call MAPL_TimerOff(MAPL, gcnames(igc)) endif ! river-routine @@ -1134,7 +1190,7 @@ subroutine Run(gc, import, export, clock, rc) VERIFY_(status) call ESMF_StateDestroy(merged_Import, noGarbage=.true., _RC) - do i = 1, NUM_ENSEMBLE + do i = 1,NUM_ENSEMBLE ! Extract updated exports from "cat_progn" call ESMF_GridCompRun(gcs(igc), importState=gim(igc), exportState=gex(LAND(i)), clock=clock, phase=2, userRC=status) VERIFY_(status) diff --git a/GEOSensavg_GridComp/CMakeLists.txt b/GEOSensavg_GridComp/CMakeLists.txt index 1e220351..7476b7e6 100644 --- a/GEOSensavg_GridComp/CMakeLists.txt +++ b/GEOSensavg_GridComp/CMakeLists.txt @@ -3,11 +3,12 @@ esma_set_this () set (SRCS GEOS_MetforceAvgGridComp.F90 GEOS_LandiceAvgGridComp.F90 - GEOS_LandAvgGridComp.F90 + GEOS_LakeAvgGridComp.F90 + GEOS_LandAvgGridComp.F90 GEOS_RouteAvgGridComp.F90 ) esma_add_library(${this} SRCS ${SRCS} - DEPENDENCIES GEOSland_GridComp GEOSlandice_GridComp GEOSroute_GridComp GEOS_LdasShared MAPL + DEPENDENCIES GEOSland_GridComp GEOSlake_GridComp GEOSlandice_GridComp GEOSroute_GridComp GEOS_LdasShared MAPL INCLUDES ${INC_ESMF}) diff --git a/GEOSensavg_GridComp/GEOS_LakeAvgGridComp.F90 b/GEOSensavg_GridComp/GEOS_LakeAvgGridComp.F90 new file mode 100644 index 00000000..388fde67 --- /dev/null +++ b/GEOSensavg_GridComp/GEOS_LakeAvgGridComp.F90 @@ -0,0 +1,353 @@ +#include "MAPL_Generic.h" + +module GEOS_LakeAvgGridCompMod + + use ESMF + use MAPL_Mod + + implicit none + + private + + public :: SetServices + + integer :: NUM_ENSEMBLE_LAKE = 1 + integer :: collect_lake_counter + +contains + + subroutine SetServices(gc, rc) + type(ESMF_GridComp), intent(inout) :: gc ! gridded component + integer, optional :: rc ! return code + + integer :: status + character(len=ESMF_MAXSTR) :: Iam + character(len=ESMF_MAXSTR) :: comp_name + + ! Get my name and setup traceback handle + Iam = 'SetServices' + call ESMF_GridCompGet(gc, name=comp_name, rc=status) + VERIFY_(status) + Iam = trim(comp_name) // "::" // Iam + + call MAPL_GridCompSetEntryPoint( & + gc, & + ESMF_METHOD_INITIALIZE, & + Initialize, & + rc=status & + ) + VERIFY_(status) + + call MAPL_GridCompSetEntryPoint( & + gc, & + ESMF_METHOD_RUN, & + RUN, & + rc=status & + ) + VERIFY_(status) + + call MAPL_GridCompSetEntryPoint( & + gc, & + ESMF_METHOD_FINALIZE, & + Finalize, & + rc=status & + ) + VERIFY_(status) + + ! subset of exports from Lake GridComp, with *updated* long_name attributes + + call MAPL_AddExportSpec(GC, & + LONG_NAME = 'total_evaporation_lake' ,& + UNITS = 'kg m-2 s-1' ,& + SHORT_NAME = 'EVAPOUT' ,& + DIMS = MAPL_DimsTileOnly ,& + VLOCATION = MAPL_VLocationNone ,& + RC=STATUS ) + VERIFY_(STATUS) + + call MAPL_AddExportSpec(GC, & + LONG_NAME = 'runoff_total_flux_lake' ,& + UNITS = 'kg m-2 s-1' ,& + SHORT_NAME = 'RUNOFF' ,& + DIMS = MAPL_DimsTileOnly ,& + VLOCATION = MAPL_VLocationNone ,& + RC=STATUS ) + VERIFY_(STATUS) + + call MAPL_AddExportSpec(GC, & + LONG_NAME = 'sensible_heat_flux_lake' ,& + UNITS = 'W m-2' ,& + SHORT_NAME = 'SHOUT' ,& + DIMS = MAPL_DimsTileOnly ,& + VLOCATION = MAPL_VLocationNone ,& + RC=STATUS ) + VERIFY_(STATUS) + + call MAPL_AddExportSpec(GC ,& + LONG_NAME = 'net_longwave_flux_lake' ,& + UNITS = 'W m-2' ,& + SHORT_NAME = 'LWNDSRF' ,& + DIMS = MAPL_DimsTileOnly ,& + VLOCATION = MAPL_VLocationNone ,& + RC=STATUS ) + VERIFY_(STATUS) + + call MAPL_AddExportSpec(GC ,& + LONG_NAME = 'net_shortwave_flux_lake' ,& + UNITS = 'W m-2' ,& + SHORT_NAME = 'SWNDSRF' ,& + DIMS = MAPL_DimsTileOnly ,& + VLOCATION = MAPL_VLocationNone ,& + RC=STATUS ) + VERIFY_(STATUS) + + call MAPL_AddExportSpec(GC, & + LONG_NAME = 'latent_heat_flux_lake' ,& + UNITS = 'W m-2' ,& + SHORT_NAME = 'HLATN' ,& + DIMS = MAPL_DimsTileOnly ,& + VLOCATION = MAPL_VLocationNone ,& + RC=STATUS ) + VERIFY_(STATUS) + + call MAPL_AddExportSpec(GC, & + LONG_NAME = 'surface_temperature_lake', & + UNITS = 'K', & + SHORT_NAME = 'TST', & + DIMS = MAPL_DimsTileOnly, & + VLOCATION = MAPL_VLocationNone, & + RC=STATUS ) + VERIFY_(STATUS) + + call MAPL_AddExportSpec(GC, & + LONG_NAME = 'surface_specific_humidity_lake', & + UNITS = 'kg kg-1', & + SHORT_NAME = 'QST', & + DIMS = MAPL_DimsTileOnly, & + VLOCATION = MAPL_VLocationNone, & + RC=STATUS ) + VERIFY_(STATUS) + + + ! Set profiling timers + call MAPL_TimerAdd(gc, name="Initialize", rc=status) + VERIFY_(status) + call MAPL_TimerAdd(gc, name="Collect_lake", rc=status) + VERIFY_(status) + + ! Call SetServices for children + call MAPL_GenericSetServices(gc, rc=status) + VERIFY_(status) + ! End + RETURN_(ESMF_SUCCESS) + + end subroutine SetServices + + ! ------------------------------------------------------------------------------------------- + + subroutine Initialize(gc, import, export, clock, rc) + + type(ESMF_GridComp), intent(inout) :: gc ! Gridded component + type(ESMF_State), intent(inout) :: import ! Import state + type(ESMF_State), intent(inout) :: export ! Export state + type(ESMF_Clock), intent(inout) :: clock ! The clock + integer, optional, intent( out) :: rc ! Error code + + ! ErrLog variables + integer :: status + character(len=ESMF_MAXSTR) :: Iam + character(len=ESMF_MAXSTR) :: comp_name + + ! MAPL variables + type(MAPL_MetaComp), pointer :: MAPL=>null() + + ! Get component's name and setup traceback handle + call ESMF_GridCompget(gc, name=comp_name, rc=status) + VERIFY_(status) + Iam = trim(comp_name) // "::Initialize" + + call MAPL_GetObjectFromGC(gc, MAPL, rc=status) + VERIFY_(status) + + ! Turn timers on + call MAPL_TimerOn(MAPL, "TOTAL") + call MAPL_TimerOn(MAPL, "Initialize") + + !call MAPL_GetResource ( MAPL, NUM_ENSEMBLE, Label="NUM_LDAS_ENSEMBLE:", DEFAULT=1, RC=STATUS) + !VERIFY_(STATUS) + + collect_lake_counter = 0 + + call MAPL_GenericInitialize(gc, import, export, clock, rc=status) + VERIFY_(status) + + call MAPL_TimerOff(MAPL, "Initialize") + call MAPL_TimerOff(MAPL, "TOTAL") + + RETURN_(ESMF_SUCCESS) + + end subroutine Initialize + + ! ------------------------------------------------------------------------------------------- + + subroutine RUN (gc, import, export, clock, rc) + + type(ESMF_GridComp), intent(inout) :: gc ! Gridded component + type(ESMF_State), intent(inout) :: import ! Import state + type(ESMF_State), intent(inout) :: export ! Export state + type(ESMF_Clock), intent(inout) :: clock ! The clock + integer, optional, intent( out) :: rc ! Error code + + ! ErrLog variables + integer :: status + character(len=ESMF_MAXSTR) :: Iam + character(len=ESMF_MAXSTR) :: comp_name + + ! MAPL variables + type(MAPL_MetaComp), pointer :: MAPL=>null() ! MAPL obj + + ! Pointers to imports (1D tile fields) + + real, pointer :: EVAPOUT( :) => null() + real, pointer :: RUNOFF( :) => null() + real, pointer :: SHOUT( :) => null() + real, pointer :: LWNDSRF( :) => null() + real, pointer :: SWNDSRF( :) => null() + real, pointer :: HLATN( :) => null() + real, pointer :: TST( :) => null() + real, pointer :: QST( :) => null() + + ! Pointers to exports ( 1D tile fields) + + real, pointer :: EVAPOUT_enavg(:) => null() + real, pointer :: RUNOFF_enavg( :) => null() + real, pointer :: SHOUT_enavg( :) => null() + real, pointer :: LWNDSRF_enavg(:) => null() + real, pointer :: SWNDSRF_enavg(:) => null() + real, pointer :: HLATN_enavg( :) => null() + real, pointer :: TST_enavg( :) => null() + real, pointer :: QST_enavg( :) => null() + + ! Get my name and setup traceback handle + call ESMF_GridCompget(gc, name=comp_name, rc=status) + VERIFY_(status) + Iam = trim(comp_name) // "::Run_lake_ens_averaging" + + call MAPL_GetObjectFromGC(gc, MAPL, rc=status) + VERIFY_(status) + + ! Turn timers on + call MAPL_TimerOn(MAPL, "TOTAL") + call MAPL_TimerOn(MAPL, "Collect_lake") + + ! Get import pointers (1d fields) + + call MAPL_GetPointer(import, EVAPOUT, 'EVAPOUT', _RC) + call MAPL_GetPointer(import, RUNOFF , 'RUNOFF' , _RC) + call MAPL_GetPointer(import, SHOUT , 'SHOUT' , _RC) + call MAPL_GetPointer(import, LWNDSRF, 'LWNDSRF', _RC) + call MAPL_GetPointer(import, SWNDSRF, 'SWNDSRF', _RC) + call MAPL_GetPointer(import, HLATN , 'HLATN' , _RC) + call MAPL_GetPointer(import, TST , 'TST' , _RC) + call MAPL_GetPointer(import, QST , 'QST' , _RC) + + ! Get export pointers (1d fields) + + call MAPL_GetPointer(export, EVAPOUT_enavg, 'EVAPOUT', _RC) + call MAPL_GetPointer(export, RUNOFF_enavg , 'RUNOFF' , _RC) + call MAPL_GetPointer(export, SHOUT_enavg , 'SHOUT' , _RC) + call MAPL_GetPointer(export, LWNDSRF_enavg, 'LWNDSRF', _RC) + call MAPL_GetPointer(export, SWNDSRF_enavg, 'SWNDSRF', _RC) + call MAPL_GetPointer(export, HLATN_enavg , 'HLATN' , _RC) + call MAPL_GetPointer(export, TST_enavg , 'TST' , _RC) + call MAPL_GetPointer(export, QST_enavg , 'QST' , _RC) + + ! On first ensemble member: zero the export accumulators + + if (collect_lake_counter == 0) then + + if (associated(EVAPOUT_enavg)) EVAPOUT_enavg = 0.0 + if (associated(RUNOFF_enavg )) RUNOFF_enavg = 0.0 + if (associated(SHOUT_enavg )) SHOUT_enavg = 0.0 + if (associated(LWNDSRF_enavg)) LWNDSRF_enavg = 0.0 + if (associated(SWNDSRF_enavg)) SWNDSRF_enavg = 0.0 + if (associated(HLATN_enavg )) HLATN_enavg = 0.0 + if (associated(TST_enavg )) TST_enavg = 0.0 + if (associated(QST_enavg )) QST_enavg = 0.0 + + endif + + ! Accumulate ensemble members (1d fields) + + if (associated(EVAPOUT_enavg) .and. associated(EVAPOUT)) EVAPOUT_enavg = EVAPOUT_enavg + EVAPOUT + if (associated(RUNOFF_enavg) .and. associated(RUNOFF)) RUNOFF_enavg = RUNOFF_enavg + RUNOFF + if (associated(SHOUT_enavg) .and. associated(SHOUT)) SHOUT_enavg = SHOUT_enavg + SHOUT + if (associated(LWNDSRF_enavg) .and. associated(LWNDSRF)) LWNDSRF_enavg = LWNDSRF_enavg + LWNDSRF + if (associated(SWNDSRF_enavg) .and. associated(SWNDSRF)) SWNDSRF_enavg = SWNDSRF_enavg + SWNDSRF + if (associated(HLATN_enavg) .and. associated(HLATN)) HLATN_enavg = HLATN_enavg + HLATN + if (associated(TST_enavg) .and. associated(TST)) TST_enavg = TST_enavg + TST + if (associated(QST_enavg) .and. associated(QST)) QST_enavg = QST_enavg + QST + + collect_lake_counter = collect_lake_counter + 1 ! increment ens member counter + + if (collect_lake_counter == NUM_ENSEMBLE_LAKE) then + + ! reset ens member counter and normalize + + collect_lake_counter = 0 + + ! Divide by NUM_ENSEMBLE_LAKE (1d fields) + + if (associated(EVAPOUT_enavg)) EVAPOUT_enavg = EVAPOUT_enavg / NUM_ENSEMBLE_LAKE + if (associated(RUNOFF_enavg )) RUNOFF_enavg = RUNOFF_enavg / NUM_ENSEMBLE_LAKE + if (associated(SHOUT_enavg )) SHOUT_enavg = SHOUT_enavg / NUM_ENSEMBLE_LAKE + if (associated(LWNDSRF_enavg)) LWNDSRF_enavg = LWNDSRF_enavg / NUM_ENSEMBLE_LAKE + if (associated(SWNDSRF_enavg)) SWNDSRF_enavg = SWNDSRF_enavg / NUM_ENSEMBLE_LAKE + if (associated(HLATN_enavg )) HLATN_enavg = HLATN_enavg / NUM_ENSEMBLE_LAKE + if (associated(TST_enavg )) TST_enavg = TST_enavg / NUM_ENSEMBLE_LAKE + if (associated(QST_enavg )) QST_enavg = QST_enavg / NUM_ENSEMBLE_LAKE + + endif + + call MAPL_TimerOff(MAPL, "Collect_lake") + call MAPL_TimerOff(MAPL, "TOTAL") + + RETURN_(ESMF_SUCCESS) + + end subroutine RUN + + ! ------------------------------------------------------------------------------------------- + + subroutine Finalize(gc, import, export, clock, rc) + + type(ESMF_GridComp), intent(inout) :: gc ! Gridded component + type(ESMF_State), intent(inout) :: import ! Import state + type(ESMF_State), intent(inout) :: export ! Export state + type(ESMF_Clock), intent(inout) :: clock ! The clock + integer, optional, intent( out) :: rc ! Error code + + ! ErrLog variables + integer :: status + character(len=ESMF_MAXSTR) :: Iam + character(len=ESMF_MAXSTR) :: comp_name + + ! Local variables + type(MAPL_MetaComp), pointer :: MAPL=>null() ! MAPL obj + + ! Get component's name and setup traceback handle + call ESMF_GridCompget(gc, name=comp_name, rc=status) + VERIFY_(status) + Iam = trim(comp_name) // "::Finalize" + + ! Call Finalize for every child + call MAPL_GenericFinalize(gc, import, export, clock, rc=status) + VERIFY_(status) + + ! End + RETURN_(ESMF_SUCCESS) + + end subroutine Finalize + +end module GEOS_LakeAvgGridCompMod + +! ======================= EOF ================================================================================ diff --git a/GEOSensavg_GridComp/GEOS_LandAvgGridComp.F90 b/GEOSensavg_GridComp/GEOS_LandAvgGridComp.F90 index 9eec1d97..3fa0909b 100644 --- a/GEOSensavg_GridComp/GEOS_LandAvgGridComp.F90 +++ b/GEOSensavg_GridComp/GEOS_LandAvgGridComp.F90 @@ -1667,6 +1667,7 @@ subroutine SetServices(gc, rc) end subroutine SetServices + ! ------------------------------------------------------------------------------------------- subroutine Initialize(gc, import, export, clock, rc) type(ESMF_GridComp), intent(inout) :: gc ! Gridded component @@ -3074,37 +3075,37 @@ subroutine Collect_land_ens(gc, import, export, clock, rc) collect_land_counter = collect_land_counter + 1 !collect catch_progn - catch_progn(:,collect_land_counter)%tc1 = TC(:,1) - catch_progn(:,collect_land_counter)%tc2 = TC(:,2) - catch_progn(:,collect_land_counter)%tc4 = TC(:,3) + catch_progn(:,collect_land_counter)%tc1 = TC( :,1) + catch_progn(:,collect_land_counter)%tc2 = TC( :,2) + catch_progn(:,collect_land_counter)%tc4 = TC( :,3) - catch_progn(:,collect_land_counter)%qa1 = QC(:,1) - catch_progn(:,collect_land_counter)%qa2 = QC(:,2) - catch_progn(:,collect_land_counter)%qa4 = QC(:,3) + catch_progn(:,collect_land_counter)%qa1 = QC( :,1) + catch_progn(:,collect_land_counter)%qa2 = QC( :,2) + catch_progn(:,collect_land_counter)%qa4 = QC( :,3) - catch_progn(:,collect_land_counter)%capac = CAPAC(:) - catch_progn(:,collect_land_counter)%catdef = catdef(:) - catch_progn(:,collect_land_counter)%rzexc = rzexc(:) - catch_progn(:,collect_land_counter)%srfexc = srfexc(:) + catch_progn(:,collect_land_counter)%capac = CAPAC( :) + catch_progn(:,collect_land_counter)%catdef = catdef( :) + catch_progn(:,collect_land_counter)%rzexc = rzexc( :) + catch_progn(:,collect_land_counter)%srfexc = srfexc( :) - catch_progn(:,collect_land_counter)%ght(1) = GHTCNT1(:) - catch_progn(:,collect_land_counter)%ght(2) = GHTCNT2(:) - catch_progn(:,collect_land_counter)%ght(3) = GHTCNT3(:) - catch_progn(:,collect_land_counter)%ght(4) = GHTCNT4(:) - catch_progn(:,collect_land_counter)%ght(5) = GHTCNT5(:) - catch_progn(:,collect_land_counter)%ght(6) = GHTCNT6(:) + catch_progn(:,collect_land_counter)%ght(1) = GHTCNT1( :) + catch_progn(:,collect_land_counter)%ght(2) = GHTCNT2( :) + catch_progn(:,collect_land_counter)%ght(3) = GHTCNT3( :) + catch_progn(:,collect_land_counter)%ght(4) = GHTCNT4( :) + catch_progn(:,collect_land_counter)%ght(5) = GHTCNT5( :) + catch_progn(:,collect_land_counter)%ght(6) = GHTCNT6( :) - catch_progn(:,collect_land_counter)%wesn(1) = WESNN1(:) - catch_progn(:,collect_land_counter)%wesn(2) = WESNN2(:) - catch_progn(:,collect_land_counter)%wesn(3) = WESNN3(:) + catch_progn(:,collect_land_counter)%wesn(1) = WESNN1( :) + catch_progn(:,collect_land_counter)%wesn(2) = WESNN2( :) + catch_progn(:,collect_land_counter)%wesn(3) = WESNN3( :) catch_progn(:,collect_land_counter)%htsn(1) = HTSNNN1(:) catch_progn(:,collect_land_counter)%htsn(2) = HTSNNN2(:) catch_progn(:,collect_land_counter)%htsn(3) = HTSNNN3(:) - catch_progn(:,collect_land_counter)%sndz(1) = SNDZN1(:) - catch_progn(:,collect_land_counter)%sndz(2) = SNDZN2(:) - catch_progn(:,collect_land_counter)%sndz(3) = SNDZN3(:) + catch_progn(:,collect_land_counter)%sndz(1) = SNDZN1( :) + catch_progn(:,collect_land_counter)%sndz(2) = SNDZN2( :) + catch_progn(:,collect_land_counter)%sndz(3) = SNDZN3( :) if(collect_land_counter == NUM_ENSEMBLE) then diff --git a/GEOSensavg_GridComp/GEOS_LandiceAvgGridComp.F90 b/GEOSensavg_GridComp/GEOS_LandiceAvgGridComp.F90 index 1e35b0df..c13a0b07 100644 --- a/GEOSensavg_GridComp/GEOS_LandiceAvgGridComp.F90 +++ b/GEOSensavg_GridComp/GEOS_LandiceAvgGridComp.F90 @@ -21,19 +21,31 @@ module GEOS_LandiceAvgGridCompMod contains subroutine SetServices(gc, rc) + type(ESMF_GridComp), intent(inout) :: gc ! gridded component integer, optional :: rc ! return code integer :: status character(len=ESMF_MAXSTR) :: Iam character(len=ESMF_MAXSTR) :: comp_name + + type(MAPL_MetaComp), pointer :: MAPL + integer :: DO_ISSM ! ISSM flag ! Get my name and setup traceback handle Iam = 'SetServices' call ESMF_GridCompGet(gc, name=comp_name, rc=status) VERIFY_(status) Iam = trim(comp_name) // "::" // Iam - + + ! Get internal MAPL_Generic state and query for DO_ISSM: + + call MAPL_GetObjectFromGC ( GC, MAPL, RC=STATUS) + VERIFY_(STATUS) + call MAPL_GetResource (MAPL, DO_ISSM, label='DO_ISSM:', DEFAULT=0, __RC__ ) + + ! Set entry points + call MAPL_GridCompSetEntryPoint( & gc, & ESMF_METHOD_INITIALIZE, & @@ -58,7 +70,45 @@ subroutine SetServices(gc, rc) ) VERIFY_(status) -! export landice + ! exports of landice + + call MAPL_AddExportSpec(GC, & + SHORT_NAME = 'ICESMB', & + LONG_NAME = 'ice_surface_mass_balance', & + UNITS = 'kg m-2 s-1', & + DIMS = MAPL_DimsTileOnly, & + VLOCATION = MAPL_VLocationNone, & + RC=STATUS ) + VERIFY_(STATUS) + + if (DO_ISSM==1) then + call MAPL_AddExportSpec(GC, & + SHORT_NAME = 'ICESURF', & + LONG_NAME = 'ice_surface_elevation', & + UNITS = 'm', & + DIMS = MAPL_DimsTileOnly, & + VLOCATION = MAPL_VLocationNone, & + RC=STATUS ) + VERIFY_(STATUS) + + call MAPL_AddExportSpec(GC, & + SHORT_NAME = 'ICEVEL', & + LONG_NAME = 'ice_flow_speed', & + UNITS = 'm s-1', & + DIMS = MAPL_DimsTileOnly, & + VLOCATION = MAPL_VLocationNone, & + RC=STATUS ) + VERIFY_(STATUS) + + call MAPL_AddExportSpec(GC, & + SHORT_NAME = 'ICETHICK', & + LONG_NAME = 'ice_thickness', & + UNITS = 'm', & + DIMS = MAPL_DimsTileOnly, & + VLOCATION = MAPL_VLocationNone, & + RC=STATUS ) + VERIFY_(STATUS) + end if call MAPL_AddExportSpec(GC, & LONG_NAME = 'surface_emissivity' ,& @@ -796,16 +846,21 @@ subroutine RUN (gc, import, export, clock, rc) type(ESMF_State), intent(inout) :: export ! Export state type(ESMF_Clock), intent(inout) :: clock ! The clock integer, optional, intent( out) :: rc ! Error code - ! ErrLog variables integer :: status character(len=ESMF_MAXSTR) :: Iam character(len=ESMF_MAXSTR) :: comp_name + integer :: DO_ISSM ! ISSM flag ! MAPL variables type(MAPL_MetaComp), pointer :: MAPL=>null() ! MAPL obj ! Pointers to imports (1D tile fields) + + real, pointer :: ICESMB(:)=>null() + real, pointer :: ICESURF(:)=>null() + real, pointer :: ICETHICK(:)=>null() + real, pointer :: ICEVEL(:)=>null() real, pointer :: EMIS(:)=>null() real, pointer :: ALBVR(:)=>null() real, pointer :: ALBVF(:)=>null() @@ -893,6 +948,11 @@ subroutine RUN (gc, import, export, clock, rc) real, pointer :: WESNREPAR(:,:)=>null() ! Pointers to exports ( 1D tile fields) + + real, pointer :: ICESMB_enavg(:)=>null() + real, pointer :: ICESURF_enavg(:)=>null() + real, pointer :: ICETHICK_enavg(:)=>null() + real, pointer :: ICEVEL_enavg(:)=>null() real, pointer :: EMIS_enavg(:)=>null() real, pointer :: ALBVR_enavg(:)=>null() real, pointer :: ALBVF_enavg(:)=>null() @@ -986,12 +1046,19 @@ subroutine RUN (gc, import, export, clock, rc) call MAPL_GetObjectFromGC(gc, MAPL, rc=status) VERIFY_(status) + call MAPL_GetResource(MAPL, DO_ISSM, label='DO_ISSM:', DEFAULT=0, __RC__) ! Turn timers on call MAPL_TimerOn(MAPL, "TOTAL") call MAPL_TimerOn(MAPL, "Collect_landice") ! Get import pointers (1d fields) + call MAPL_GetPointer(import, ICESMB , 'ICESMB' , _RC) + if (DO_ISSM == 1) then + call MAPL_GetPointer(import, ICESURF, 'ICESURF', _RC) + call MAPL_GetPointer(import, ICETHICK, 'ICETHICK', _RC) + call MAPL_GetPointer(import, ICEVEL, 'ICEVEL', _RC) + endif call MAPL_GetPointer(import, EMIS, 'EMIS', _RC) call MAPL_GetPointer(import, ALBVR, 'ALBVR', _RC) call MAPL_GetPointer(import, ALBVF, 'ALBVF', _RC) @@ -1079,6 +1146,12 @@ subroutine RUN (gc, import, export, clock, rc) call MAPL_GetPointer(import, WESNREPAR, 'WESNREPAR', _RC) ! Get export pointers (1d fields) + call MAPL_GetPointer(export, ICESMB_enavg, 'ICESMB' , _RC) + if (DO_ISSM == 1) then + call MAPL_GetPointer(export, ICESURF_enavg, 'ICESURF', _RC) + call MAPL_GetPointer(export, ICETHICK_enavg, 'ICETHICK', _RC) + call MAPL_GetPointer(export, ICEVEL_enavg, 'ICEVEL', _RC) + endif call MAPL_GetPointer(export, EMIS_enavg, 'EMIS', _RC) call MAPL_GetPointer(export, ALBVR_enavg, 'ALBVR', _RC) call MAPL_GetPointer(export, ALBVF_enavg, 'ALBVF', _RC) @@ -1167,6 +1240,11 @@ subroutine RUN (gc, import, export, clock, rc) ! On first ensemble member: zero the export accumulators if (collect_landice_counter == 0) then + + if (associated(ICESMB_enavg )) ICESMB_enavg = 0.0 + if (associated(ICESURF_enavg )) ICESURF_enavg = 0.0 + if (associated(ICETHICK_enavg)) ICETHICK_enavg = 0.0 + if (associated(ICEVEL_enavg )) ICEVEL_enavg = 0.0 if (associated(EMIS_enavg)) EMIS_enavg = 0.0 if (associated(ALBVR_enavg)) ALBVR_enavg = 0.0 if (associated(ALBVF_enavg)) ALBVF_enavg = 0.0 @@ -1253,91 +1331,97 @@ subroutine RUN (gc, import, export, clock, rc) endif ! Accumulate ensemble members (1d fields) - if (associated(EMIS_enavg)) EMIS_enavg = EMIS_enavg + EMIS - if (associated(ALBVR_enavg)) ALBVR_enavg = ALBVR_enavg + ALBVR - if (associated(ALBVF_enavg)) ALBVF_enavg = ALBVF_enavg + ALBVF - if (associated(ALBNR_enavg)) ALBNR_enavg = ALBNR_enavg + ALBNR - if (associated(ALBNF_enavg)) ALBNF_enavg = ALBNF_enavg + ALBNF - if (associated(TST_enavg)) TST_enavg = TST_enavg + TST - if (associated(LST_enavg)) LST_enavg = LST_enavg + LST - if (associated(QST_enavg)) QST_enavg = QST_enavg + QST - if (associated(TH_enavg)) TH_enavg = TH_enavg + TH - if (associated(QH_enavg)) QH_enavg = QH_enavg + QH - if (associated(DELTS_enavg)) DELTS_enavg = DELTS_enavg + DELTS - if (associated(DELQS_enavg)) DELQS_enavg = DELQS_enavg + DELQS - if (associated(CHT_enavg)) CHT_enavg = CHT_enavg + CHT - if (associated(CMT_enavg)) CMT_enavg = CMT_enavg + CMT - if (associated(CQT_enavg)) CQT_enavg = CQT_enavg + CQT - if (associated(CNT_enavg)) CNT_enavg = CNT_enavg + CNT - if (associated(RIT_enavg)) RIT_enavg = RIT_enavg + RIT - if (associated(ACCUM_enavg)) ACCUM_enavg = ACCUM_enavg + ACCUM - if (associated(EVPICE_GL_enavg)) EVPICE_GL_enavg = EVPICE_GL_enavg + EVPICE_GL - if (associated(SUBLIM_enavg)) SUBLIM_enavg = SUBLIM_enavg + SUBLIM - if (associated(SNOMAS_GL_enavg)) SNOMAS_GL_enavg = SNOMAS_GL_enavg + SNOMAS_GL - if (associated(SNOWMASS_enavg)) SNOWMASS_enavg = SNOWMASS_enavg + SNOWMASS - if (associated(SNOWDP_GL_enavg)) SNOWDP_GL_enavg = SNOWDP_GL_enavg + SNOWDP_GL - if (associated(ASNOW_GL_enavg)) ASNOW_GL_enavg = ASNOW_GL_enavg + ASNOW_GL - if (associated(WESNEXT_enavg)) WESNEXT_enavg = WESNEXT_enavg + WESNEXT - if (associated(WESNSC_enavg)) WESNSC_enavg = WESNSC_enavg + WESNSC - if (associated(SNDZSC_enavg)) SNDZSC_enavg = SNDZSC_enavg + SNDZSC - if (associated(WESNPREC_enavg)) WESNPREC_enavg = WESNPREC_enavg + WESNPREC - if (associated(SNDZPREC_enavg)) SNDZPREC_enavg = SNDZPREC_enavg + SNDZPREC - if (associated(SNDZ1PERC_enavg)) SNDZ1PERC_enavg = SNDZ1PERC_enavg + SNDZ1PERC - if (associated(WESNBOT_enavg)) WESNBOT_enavg = WESNBOT_enavg + WESNBOT - if (associated(RAINRFZ_enavg)) RAINRFZ_enavg = RAINRFZ_enavg + RAINRFZ - if (associated(SMELT_enavg)) SMELT_enavg = SMELT_enavg + SMELT - if (associated(IMELT_enavg)) IMELT_enavg = IMELT_enavg + IMELT - if (associated(SNOWALB_enavg)) SNOWALB_enavg = SNOWALB_enavg + SNOWALB - if (associated(SNICEALB_enavg)) SNICEALB_enavg = SNICEALB_enavg + SNICEALB - if (associated(MELTWTR_enavg)) MELTWTR_enavg = MELTWTR_enavg + MELTWTR - if (associated(MELTWTRCONT_enavg)) MELTWTRCONT_enavg = MELTWTRCONT_enavg + MELTWTRCONT - if (associated(LWC_enavg)) LWC_enavg = LWC_enavg + LWC - if (associated(RUNOFF_enavg)) RUNOFF_enavg = RUNOFF_enavg + RUNOFF - if (associated(GUST_enavg)) GUST_enavg = GUST_enavg + GUST - if (associated(VENT_enavg)) VENT_enavg = VENT_enavg + VENT - if (associated(Z0_enavg)) Z0_enavg = Z0_enavg + Z0 - if (associated(Z0H_enavg)) Z0H_enavg = Z0H_enavg + Z0H - if (associated(MOT2M_enavg)) MOT2M_enavg = MOT2M_enavg + MOT2M - if (associated(MOQ2M_enavg)) MOQ2M_enavg = MOQ2M_enavg + MOQ2M - if (associated(MOU2M_enavg)) MOU2M_enavg = MOU2M_enavg + MOU2M - if (associated(MOV2M_enavg)) MOV2M_enavg = MOV2M_enavg + MOV2M - if (associated(MOT10M_enavg)) MOT10M_enavg = MOT10M_enavg + MOT10M - if (associated(MOQ10M_enavg)) MOQ10M_enavg = MOQ10M_enavg + MOQ10M - if (associated(MOU10M_enavg)) MOU10M_enavg = MOU10M_enavg + MOU10M - if (associated(MOV10M_enavg)) MOV10M_enavg = MOV10M_enavg + MOV10M - if (associated(MOU50M_enavg)) MOU50M_enavg = MOU50M_enavg + MOU50M - if (associated(MOV50M_enavg)) MOV50M_enavg = MOV50M_enavg + MOV50M - if (associated(EVAPOUT_enavg)) EVAPOUT_enavg = EVAPOUT_enavg + EVAPOUT - if (associated(SHOUT_enavg)) SHOUT_enavg = SHOUT_enavg + SHOUT - if (associated(HLWUP_enavg)) HLWUP_enavg = HLWUP_enavg + HLWUP - if (associated(LWNDSRF_enavg)) LWNDSRF_enavg = LWNDSRF_enavg + LWNDSRF - if (associated(SWNDSRF_enavg)) SWNDSRF_enavg = SWNDSRF_enavg + SWNDSRF - if (associated(HLATN_enavg)) HLATN_enavg = HLATN_enavg + HLATN - if (associated(DNICFLX_enavg)) DNICFLX_enavg = DNICFLX_enavg + DNICFLX - if (associated(GHSNOW_enavg)) GHSNOW_enavg = GHSNOW_enavg + GHSNOW - if (associated(GHTSKIN_enavg)) GHTSKIN_enavg = GHTSKIN_enavg + GHTSKIN - if (associated(ITY_enavg)) ITY_enavg = ITY_enavg + ITY - if (associated(RMELTDU001_enavg)) RMELTDU001_enavg = RMELTDU001_enavg + RMELTDU001 - if (associated(RMELTDU002_enavg)) RMELTDU002_enavg = RMELTDU002_enavg + RMELTDU002 - if (associated(RMELTDU003_enavg)) RMELTDU003_enavg = RMELTDU003_enavg + RMELTDU003 - if (associated(RMELTDU004_enavg)) RMELTDU004_enavg = RMELTDU004_enavg + RMELTDU004 - if (associated(RMELTDU005_enavg)) RMELTDU005_enavg = RMELTDU005_enavg + RMELTDU005 - if (associated(RMELTBC001_enavg)) RMELTBC001_enavg = RMELTBC001_enavg + RMELTBC001 - if (associated(RMELTBC002_enavg)) RMELTBC002_enavg = RMELTBC002_enavg + RMELTBC002 - if (associated(RMELTOC001_enavg)) RMELTOC001_enavg = RMELTOC001_enavg + RMELTOC001 - if (associated(RMELTOC002_enavg)) RMELTOC002_enavg = RMELTOC002_enavg + RMELTOC002 + + if (associated(ICESMB_enavg) .and. associated(ICESMB)) ICESMB_enavg = ICESMB_enavg + ICESMB + if (associated(ICESURF_enavg) .and. associated(ICESURF)) ICESURF_enavg = ICESURF_enavg + ICESURF + if (associated(ICETHICK_enavg) .and. associated(ICETHICK)) ICETHICK_enavg = ICETHICK_enavg + ICETHICK + if (associated(ICEVEL_enavg) .and. associated(ICEVEL)) ICEVEL_enavg = ICEVEL_enavg + ICEVEL + if (associated(EMIS_enavg) .and. associated(EMIS)) EMIS_enavg = EMIS_enavg + EMIS + if (associated(ALBVR_enavg) .and. associated(ALBVR)) ALBVR_enavg = ALBVR_enavg + ALBVR + if (associated(ALBVF_enavg) .and. associated(ALBVF)) ALBVF_enavg = ALBVF_enavg + ALBVF + if (associated(ALBNR_enavg) .and. associated(ALBNR)) ALBNR_enavg = ALBNR_enavg + ALBNR + if (associated(ALBNF_enavg) .and. associated(ALBNF)) ALBNF_enavg = ALBNF_enavg + ALBNF + if (associated(TST_enavg) .and. associated(TST)) TST_enavg = TST_enavg + TST + if (associated(LST_enavg) .and. associated(LST)) LST_enavg = LST_enavg + LST + if (associated(QST_enavg) .and. associated(QST)) QST_enavg = QST_enavg + QST + if (associated(TH_enavg) .and. associated(TH)) TH_enavg = TH_enavg + TH + if (associated(QH_enavg) .and. associated(QH)) QH_enavg = QH_enavg + QH + if (associated(DELTS_enavg) .and. associated(DELTS)) DELTS_enavg = DELTS_enavg + DELTS + if (associated(DELQS_enavg) .and. associated(DELQS)) DELQS_enavg = DELQS_enavg + DELQS + if (associated(CHT_enavg) .and. associated(CHT)) CHT_enavg = CHT_enavg + CHT + if (associated(CMT_enavg) .and. associated(CMT)) CMT_enavg = CMT_enavg + CMT + if (associated(CQT_enavg) .and. associated(CQT)) CQT_enavg = CQT_enavg + CQT + if (associated(CNT_enavg) .and. associated(CNT)) CNT_enavg = CNT_enavg + CNT + if (associated(RIT_enavg) .and. associated(RIT)) RIT_enavg = RIT_enavg + RIT + if (associated(ACCUM_enavg) .and. associated(ACCUM)) ACCUM_enavg = ACCUM_enavg + ACCUM + if (associated(EVPICE_GL_enavg) .and. associated(EVPICE_GL)) EVPICE_GL_enavg = EVPICE_GL_enavg + EVPICE_GL + if (associated(SUBLIM_enavg) .and. associated(SUBLIM)) SUBLIM_enavg = SUBLIM_enavg + SUBLIM + if (associated(SNOMAS_GL_enavg) .and. associated(SNOMAS_GL)) SNOMAS_GL_enavg = SNOMAS_GL_enavg + SNOMAS_GL + if (associated(SNOWMASS_enavg) .and. associated(SNOWMASS)) SNOWMASS_enavg = SNOWMASS_enavg + SNOWMASS + if (associated(SNOWDP_GL_enavg) .and. associated(SNOWDP_GL)) SNOWDP_GL_enavg = SNOWDP_GL_enavg + SNOWDP_GL + if (associated(ASNOW_GL_enavg) .and. associated(ASNOW_GL)) ASNOW_GL_enavg = ASNOW_GL_enavg + ASNOW_GL + if (associated(WESNEXT_enavg) .and. associated(WESNEXT)) WESNEXT_enavg = WESNEXT_enavg + WESNEXT + if (associated(WESNSC_enavg) .and. associated(WESNSC)) WESNSC_enavg = WESNSC_enavg + WESNSC + if (associated(SNDZSC_enavg) .and. associated(SNDZSC)) SNDZSC_enavg = SNDZSC_enavg + SNDZSC + if (associated(WESNPREC_enavg) .and. associated(WESNPREC)) WESNPREC_enavg = WESNPREC_enavg + WESNPREC + if (associated(SNDZPREC_enavg) .and. associated(SNDZPREC)) SNDZPREC_enavg = SNDZPREC_enavg + SNDZPREC + if (associated(SNDZ1PERC_enavg) .and. associated(SNDZ1PERC)) SNDZ1PERC_enavg = SNDZ1PERC_enavg + SNDZ1PERC + if (associated(WESNBOT_enavg) .and. associated(WESNBOT)) WESNBOT_enavg = WESNBOT_enavg + WESNBOT + if (associated(RAINRFZ_enavg) .and. associated(RAINRFZ)) RAINRFZ_enavg = RAINRFZ_enavg + RAINRFZ + if (associated(SMELT_enavg) .and. associated(SMELT)) SMELT_enavg = SMELT_enavg + SMELT + if (associated(IMELT_enavg) .and. associated(IMELT)) IMELT_enavg = IMELT_enavg + IMELT + if (associated(SNOWALB_enavg) .and. associated(SNOWALB)) SNOWALB_enavg = SNOWALB_enavg + SNOWALB + if (associated(SNICEALB_enavg) .and. associated(SNICEALB)) SNICEALB_enavg = SNICEALB_enavg + SNICEALB + if (associated(MELTWTR_enavg) .and. associated(MELTWTR)) MELTWTR_enavg = MELTWTR_enavg + MELTWTR + if (associated(MELTWTRCONT_enavg) .and. associated(MELTWTRCONT)) MELTWTRCONT_enavg = MELTWTRCONT_enavg + MELTWTRCONT + if (associated(LWC_enavg) .and. associated(LWC)) LWC_enavg = LWC_enavg + LWC + if (associated(RUNOFF_enavg) .and. associated(RUNOFF)) RUNOFF_enavg = RUNOFF_enavg + RUNOFF + if (associated(GUST_enavg) .and. associated(GUST)) GUST_enavg = GUST_enavg + GUST + if (associated(VENT_enavg) .and. associated(VENT)) VENT_enavg = VENT_enavg + VENT + if (associated(Z0_enavg) .and. associated(Z0)) Z0_enavg = Z0_enavg + Z0 + if (associated(Z0H_enavg) .and. associated(Z0H)) Z0H_enavg = Z0H_enavg + Z0H + if (associated(MOT2M_enavg) .and. associated(MOT2M)) MOT2M_enavg = MOT2M_enavg + MOT2M + if (associated(MOQ2M_enavg) .and. associated(MOQ2M)) MOQ2M_enavg = MOQ2M_enavg + MOQ2M + if (associated(MOU2M_enavg) .and. associated(MOU2M)) MOU2M_enavg = MOU2M_enavg + MOU2M + if (associated(MOV2M_enavg) .and. associated(MOV2M)) MOV2M_enavg = MOV2M_enavg + MOV2M + if (associated(MOT10M_enavg) .and. associated(MOT10M)) MOT10M_enavg = MOT10M_enavg + MOT10M + if (associated(MOQ10M_enavg) .and. associated(MOQ10M)) MOQ10M_enavg = MOQ10M_enavg + MOQ10M + if (associated(MOU10M_enavg) .and. associated(MOU10M)) MOU10M_enavg = MOU10M_enavg + MOU10M + if (associated(MOV10M_enavg) .and. associated(MOV10M)) MOV10M_enavg = MOV10M_enavg + MOV10M + if (associated(MOU50M_enavg) .and. associated(MOU50M)) MOU50M_enavg = MOU50M_enavg + MOU50M + if (associated(MOV50M_enavg) .and. associated(MOV50M)) MOV50M_enavg = MOV50M_enavg + MOV50M + if (associated(EVAPOUT_enavg) .and. associated(EVAPOUT)) EVAPOUT_enavg = EVAPOUT_enavg + EVAPOUT + if (associated(SHOUT_enavg) .and. associated(SHOUT)) SHOUT_enavg = SHOUT_enavg + SHOUT + if (associated(HLWUP_enavg) .and. associated(HLWUP)) HLWUP_enavg = HLWUP_enavg + HLWUP + if (associated(LWNDSRF_enavg) .and. associated(LWNDSRF)) LWNDSRF_enavg = LWNDSRF_enavg + LWNDSRF + if (associated(SWNDSRF_enavg) .and. associated(SWNDSRF)) SWNDSRF_enavg = SWNDSRF_enavg + SWNDSRF + if (associated(HLATN_enavg) .and. associated(HLATN)) HLATN_enavg = HLATN_enavg + HLATN + if (associated(DNICFLX_enavg) .and. associated(DNICFLX)) DNICFLX_enavg = DNICFLX_enavg + DNICFLX + if (associated(GHSNOW_enavg) .and. associated(GHSNOW)) GHSNOW_enavg = GHSNOW_enavg + GHSNOW + if (associated(GHTSKIN_enavg) .and. associated(GHTSKIN)) GHTSKIN_enavg = GHTSKIN_enavg + GHTSKIN + if (associated(ITY_enavg) .and. associated(ITY)) ITY_enavg = ITY_enavg + ITY + if (associated(RMELTDU001_enavg) .and. associated(RMELTDU001)) RMELTDU001_enavg = RMELTDU001_enavg + RMELTDU001 + if (associated(RMELTDU002_enavg) .and. associated(RMELTDU002)) RMELTDU002_enavg = RMELTDU002_enavg + RMELTDU002 + if (associated(RMELTDU003_enavg) .and. associated(RMELTDU003)) RMELTDU003_enavg = RMELTDU003_enavg + RMELTDU003 + if (associated(RMELTDU004_enavg) .and. associated(RMELTDU004)) RMELTDU004_enavg = RMELTDU004_enavg + RMELTDU004 + if (associated(RMELTDU005_enavg) .and. associated(RMELTDU005)) RMELTDU005_enavg = RMELTDU005_enavg + RMELTDU005 + if (associated(RMELTBC001_enavg) .and. associated(RMELTBC001)) RMELTBC001_enavg = RMELTBC001_enavg + RMELTBC001 + if (associated(RMELTBC002_enavg) .and. associated(RMELTBC002)) RMELTBC002_enavg = RMELTBC002_enavg + RMELTBC002 + if (associated(RMELTOC001_enavg) .and. associated(RMELTOC001)) RMELTOC001_enavg = RMELTOC001_enavg + RMELTOC001 + if (associated(RMELTOC002_enavg) .and. associated(RMELTOC002)) RMELTOC002_enavg = RMELTOC002_enavg + RMELTOC002 ! Accumulate ensemble members (multi-dimensional fields) - if (associated(RHOSNOW_enavg)) RHOSNOW_enavg = RHOSNOW_enavg + RHOSNOW - if (associated(TSNOW_enavg)) TSNOW_enavg = TSNOW_enavg + TSNOW - if (associated(TICE0_enavg)) TICE0_enavg = TICE0_enavg + TICE0 - if (associated(WSNOW_enavg)) WSNOW_enavg = WSNOW_enavg + WSNOW - if (associated(ZSNOW_enavg)) ZSNOW_enavg = ZSNOW_enavg + ZSNOW - if (associated(DRHOS0_enavg)) DRHOS0_enavg = DRHOS0_enavg + DRHOS0 - if (associated(WESNEX_enavg)) WESNEX_enavg = WESNEX_enavg + WESNEX - if (associated(WESNPERC_enavg)) WESNPERC_enavg = WESNPERC_enavg + WESNPERC - if (associated(WESNDENS_enavg)) WESNDENS_enavg = WESNDENS_enavg + WESNDENS - if (associated(WESNREPAR_enavg)) WESNREPAR_enavg = WESNREPAR_enavg + WESNREPAR + + if (associated(RHOSNOW_enavg) .and. associated(RHOSNOW)) RHOSNOW_enavg = RHOSNOW_enavg + RHOSNOW + if (associated(TSNOW_enavg) .and. associated(TSNOW)) TSNOW_enavg = TSNOW_enavg + TSNOW + if (associated(TICE0_enavg) .and. associated(TICE0)) TICE0_enavg = TICE0_enavg + TICE0 + if (associated(WSNOW_enavg) .and. associated(WSNOW)) WSNOW_enavg = WSNOW_enavg + WSNOW + if (associated(ZSNOW_enavg) .and. associated(ZSNOW)) ZSNOW_enavg = ZSNOW_enavg + ZSNOW + if (associated(DRHOS0_enavg) .and. associated(DRHOS0)) DRHOS0_enavg = DRHOS0_enavg + DRHOS0 + if (associated(WESNEX_enavg) .and. associated(WESNEX)) WESNEX_enavg = WESNEX_enavg + WESNEX + if (associated(WESNPERC_enavg) .and. associated(WESNPERC)) WESNPERC_enavg = WESNPERC_enavg + WESNPERC + if (associated(WESNDENS_enavg) .and. associated(WESNDENS)) WESNDENS_enavg = WESNDENS_enavg + WESNDENS + if (associated(WESNREPAR_enavg) .and. associated(WESNREPAR)) WESNREPAR_enavg = WESNREPAR_enavg + WESNREPAR collect_landice_counter = collect_landice_counter + 1 @@ -1345,6 +1429,11 @@ subroutine RUN (gc, import, export, clock, rc) collect_landice_counter = 0 ! Divide by NUM_ENSEMBLE_LANDICE (1d fields) + + if (associated(ICESMB_enavg )) ICESMB_enavg = ICESMB_enavg / NUM_ENSEMBLE_LANDICE + if (associated(ICESURF_enavg )) ICESURF_enavg = ICESURF_enavg / NUM_ENSEMBLE_LANDICE + if (associated(ICETHICK_enavg)) ICETHICK_enavg = ICETHICK_enavg / NUM_ENSEMBLE_LANDICE + if (associated(ICEVEL_enavg )) ICEVEL_enavg = ICEVEL_enavg / NUM_ENSEMBLE_LANDICE if (associated(EMIS_enavg)) EMIS_enavg = EMIS_enavg / NUM_ENSEMBLE_LANDICE if (associated(ALBVR_enavg)) ALBVR_enavg = ALBVR_enavg / NUM_ENSEMBLE_LANDICE if (associated(ALBVF_enavg)) ALBVF_enavg = ALBVF_enavg / NUM_ENSEMBLE_LANDICE diff --git a/GEOSldas_App/GEOSldas_HIST.rc b/GEOSldas_App/GEOSldas_HIST.rc index dab8c269..882c97fc 100644 --- a/GEOSldas_App/GEOSldas_HIST.rc +++ b/GEOSldas_App/GEOSldas_HIST.rc @@ -22,8 +22,10 @@ COLLECTIONS: # 'inst3_2d_lndfcstana_Nx' # 'const_1d_lnd_Nt' # 'const_2d_lnd_Nx' -# 'tavg24_2d_glc_Nx' +# 'tavg24_1d_lake_Nt' +# 'tavg24_2d_lake_Nx' # 'tavg24_1d_glc_Nt' +# 'tavg24_2d_glc_Nx' # 'tavg24_1d_issm_Nt' # 'tavg24_1d_route' :: @@ -513,7 +515,45 @@ EASEv2_M36.LM: 1 'TPSURF_ANA_ENSSTD' , 'LANDASSIM' , 'TSURF_ANA_ENSSTD' , 'TP1_ANA_ENSSTD' , 'LANDASSIM' , 'TSOIL1_ANA_ENSSTD' :: - + + tavg24_2d_lake_Nx.descr: '2d,Daily,Time-Averaged,Single-Level,Lake Diagnostics', + tavg24_2d_lake_Nx.nbits: 12, + tavg24_2d_lake_Nx.template: '%y4%m2%d2_%h2%n2z.nc4' , + tavg24_2d_lake_Nx.mode: 'time-averaged' , + tavg24_2d_lake_Nx.frequency: 240000 , + tavg24_2d_lake_Nx.ref_time: 000000 , + tavg24_2d_lake_Nx.format: 'CFIO' , + tavg24_2d_lake_Nx.regrid_exch: '../input/tile.data' , + tavg24_2d_lake_Nx.regrid_name: 'GRIDNAME' , + tavg24_2d_lake_Nx.grid_label: PC720x361-DC , # comment this line out for cube face output + tavg24_2d_lake_Nx.deflate: 1, + tavg24_2d_lake_Nx.fields: 'EVAPOUT' , 'LAKE' , 'EVAPLAKE' , + 'RUNOFF' , 'LAKE' , 'RUNOFFTOTLAKE' , + 'SHOUT' , 'LAKE' , 'SHLAKE' , + 'HLATN' , 'LAKE' , 'LHLAKE' , + 'LWNDSRF' , 'LAKE' , 'LWNDLAKE' , + 'SWNDSRF' , 'LAKE' , 'SWNDLAKE' , + 'TST' , 'LAKE' , 'TSURFLAKE' , + 'QST' , 'LAKE' , 'QSURFLAKE' , + :: + + tavg24_1d_lake_Nt.descr: 'Tile-space,Daily,Time-Averaged,Single-level,Lake Diagnostics', + tavg24_1d_lake_Nt.nbits: 12, + tavg24_1d_lake_Nt.template: '%y4%m2%d2_%h2%n2z.nc4' , + tavg24_1d_lake_Nt.mode: 'time-averaged' , + tavg24_1d_lake_Nt.format: 'CFIO', + tavg24_1d_lake_Nt.frequency: 240000 , + tavg24_1d_lake_Nt.ref_time: 000000 , + tavg24_1d_lake_Nt.fields: 'EVAPOUT' , 'LAKE' , 'EVAPLAKE' , + 'RUNOFF' , 'LAKE' , 'RUNOFFTOTLAKE' , + 'SHOUT' , 'LAKE' , 'SHLAKE' , + 'HLATN' , 'LAKE' , 'LHLAKE' , + 'LWNDSRF' , 'LAKE' , 'LWNDLAKE' , + 'SWNDSRF' , 'LAKE' , 'SWNDLAKE' , + 'TST' , 'LAKE' , 'TSURFLAKE' , + 'QST' , 'LAKE' , 'QSURFLAKE' , + :: + tavg24_2d_glc_Nx.descr: '2d,Daily,Time-Averaged,Single-Level,Land Ice Diagnostics', tavg24_2d_glc_Nx.nbits: 12, tavg24_2d_glc_Nx.template: '%y4%m2%d2_%h2%n2z.nc4' , @@ -525,41 +565,36 @@ EASEv2_M36.LM: 1 tavg24_2d_glc_Nx.regrid_name: 'GRIDNAME' , tavg24_2d_glc_Nx.grid_label: PC720x361-DC , #comment this line out for cube face output tavg24_2d_glc_Nx.deflate: 1, - tavg24_2d_glc_Nx.fields: 'ACCUM' , 'LANDICE' , - 'ALBVR' , 'LANDICE' , 'ALBVR_GL' , - 'ALBVF' , 'LANDICE' , 'ALBVF_GL' , - 'ALBNR' , 'LANDICE' , 'ALBNR_GL' , - 'ALBNF' , 'LANDICE' , 'ALBNF_GL' , - 'ASNOW_GL' , 'LANDICE' , - 'DELTS' , 'LANDICE' , - 'ICESMB' , 'LANDICE' , ->>>HIST_ISSM<<< 'ICESURF' , 'LANDICE' , ->>>HIST_ISSM<<< 'ICETHICK' , 'LANDICE' , ->>>HIST_ISSM<<< 'ICEVEL' , 'LANDICE' , - 'DNICFLX' , 'LANDICE' , - 'EVAPOUT' , 'LANDICE' , - 'QH' , 'LANDICE' , - 'GHTSKIN' , 'LANDICE' , 'GHTSKIN_GL' , - 'HLATN' , 'LANDICE' , - 'HLWUP' , 'LANDICE' , 'HLWUP_GL' , - 'IMELT' , 'LANDICE' , - 'LWNDSRF' , 'LANDICE' , - 'MELTWTR' , 'LANDICE' , - 'MELTWTRCONT' , 'LANDICE' , - 'RUNOFF' , 'LANDICE' , 'RUNOFF_GL' , - 'SHOUT' , 'LANDICE' , - 'SMELT' , 'LANDICE' , - 'SNICEALB' , 'LANDICE' , - 'SNOMAS_GL' , 'LANDICE' , - 'SNOWALB' , 'LANDICE' , - 'SNOWDP_GL' , 'LANDICE' , - 'SWNDSRF' , 'LANDICE' , - 'TST' , 'LANDICE' , - 'WESNBOT' , 'LANDICE' , - 'WESNEXT' , 'LANDICE' , - 'WESNPERC' , 'LANDICE' , - 'WESNPREC' , 'LANDICE' , - :: + tavg24_2d_glc_Nx.fields: 'SNOWDP_GL' , 'LANDICE' , 'SNOWDPGLC' , + 'SNOMAS_GL' , 'LANDICE' , 'SNOMASGLC' , + 'ASNOW_GL' , 'LANDICE' , 'ASNOWGLC' , + 'RUNOFF' , 'LANDICE' , 'RUNOFFTOTGLC' , + 'WESNSC' , 'LANDICE' , + 'WESNEXT' , 'LANDICE' , + 'SNICEALB' , 'LANDICE' , +# Additional variables + 'ALBNF' , 'LANDICE' , 'REFLNIRDFGLC' , + 'ALBVF' , 'LANDICE' , 'REFLVISDFGLC' , + 'EMIS' , 'LANDICE' , 'EMISGLC' , + 'EVAPOUT' , 'LANDICE' , 'EVAPGLC' , + 'GHTSKIN' , 'LANDICE' , 'GHTFLUXGLC' , + 'IMELT' , 'LANDICE' , + 'MELTWTR' , 'LANDICE' , + 'MELTWTRCONT' , 'LANDICE' , + 'RAINRFZ' , 'LANDICE' , + 'SMELT' , 'LANDICE' , + 'SNOWALB' , 'LANDICE' , + 'WESNBOT' , 'LANDICE' , + 'TST' , 'LANDICE' , 'TSKINGLC' , + 'HLATN' , 'LANDICE' , 'LHGLC' , + 'SHOUT' , 'LANDICE' , 'SHGLC' , + 'LWNDSRF' , 'LANDICE' , 'LWNDGLC' , + 'SWNDSRF' , 'LANDICE' , 'SWNDGLC' , + 'ICESMB' , 'LANDICE' , +>>>HIST_ISSM<<< 'ICESURF' , 'LANDICE' , +>>>HIST_ISSM<<< 'ICETHICK' , 'LANDICE' , +>>>HIST_ISSM<<< 'ICEVEL' , 'LANDICE' , + :: tavg24_1d_glc_Nt.descr: 'Tile-space,Daily,Time-Averaged,Single-level,Land Ice Diagnostics', tavg24_1d_glc_Nt.nbits: 12, @@ -568,24 +603,35 @@ EASEv2_M36.LM: 1 tavg24_1d_glc_Nt.format: 'CFIO', tavg24_1d_glc_Nt.frequency: 240000 , tavg24_1d_glc_Nt.ref_time: 000000 , - tavg24_1d_glc_Nt.fields: 'ASNOW_GL' , 'LANDICE' , - 'DELTS' , 'LANDICE' , - 'EVAPOUT' , 'LANDICE' , - 'GHTSKIN' , 'LANDICE' , 'GHTSKIN_GL' , - 'HLATN' , 'LANDICE' , - 'HLWUP' , 'LANDICE' , 'HLWUP_GL' , - 'LWNDSRF' , 'LANDICE' , - 'MELTWTR' , 'LANDICE' , - 'MELTWTRCONT' , 'LANDICE' , - 'RUNOFF' , 'LANDICE' , 'RUNOFF_GL' , - 'SHOUT' , 'LANDICE' , - 'SNOMAS_GL' , 'LANDICE' , - 'SNOWDP_GL' , 'LANDICE' , - 'SWNDSRF' , 'LANDICE' , - 'TST' , 'LANDICE' , - 'WESNBOT' , 'LANDICE' , - 'WESNEXT' , 'LANDICE' , - :: + tavg24_1d_glc_Nt.fields: 'SNOWDP_GL' , 'LANDICE' , 'SNOWDPGLC' , + 'SNOMAS_GL' , 'LANDICE' , 'SNOMASGLC' , + 'ASNOW_GL' , 'LANDICE' , 'ASNOWGLC' , + 'RUNOFF' , 'LANDICE' , 'RUNOFFTOTGLC' , + 'WESNSC' , 'LANDICE' , + 'WESNEXT' , 'LANDICE' , + 'SNICEALB' , 'LANDICE' , + 'ALBNF' , 'LANDICE' , 'REFLNIRDFGLC' , + 'ALBVF' , 'LANDICE' , 'REFLVISDFGLC' , + 'EMIS' , 'LANDICE' , 'EMISGLC' , + 'EVAPOUT' , 'LANDICE' , 'EVAPGLC' , + 'GHTSKIN' , 'LANDICE' , 'GHTFLUXGLC' , + 'IMELT' , 'LANDICE' , + 'MELTWTR' , 'LANDICE' , + 'MELTWTRCONT' , 'LANDICE' , + 'RAINRFZ' , 'LANDICE' , + 'SMELT' , 'LANDICE' , + 'SNOWALB' , 'LANDICE' , + 'WESNBOT' , 'LANDICE' , + 'TST' , 'LANDICE' , 'TSKINGLC' , + 'HLATN' , 'LANDICE' , 'LHGLC' , + 'SHOUT' , 'LANDICE' , 'SHGLC' , + 'LWNDSRF' , 'LANDICE' , 'LWNDGLC' , + 'SWNDSRF' , 'LANDICE' , 'SWNDGLC' , + 'ICESMB' , 'LANDICE' , +>>>HIST_ISSM<<< 'ICESURF' , 'LANDICE' , +>>>HIST_ISSM<<< 'ICETHICK' , 'LANDICE' , +>>>HIST_ISSM<<< 'ICEVEL' , 'LANDICE' , + :: tavg24_1d_route.descr: 'Catchment-space,Daily,Time-Averaged,Single-level,Runoff Routing Diagnostics', tavg24_1d_route.nbits: 12, diff --git a/GEOSldas_App/GEOSldas_LDAS.rc b/GEOSldas_App/GEOSldas_LDAS.rc index 8ca6018c..e1ffb1d5 100644 --- a/GEOSldas_App/GEOSldas_LDAS.rc +++ b/GEOSldas_App/GEOSldas_LDAS.rc @@ -44,10 +44,10 @@ LSM_CHOICE: 1 # # land : 100 (non-glaciated land) # landice : 20 ( glaciated land) -# lake : 19 [not yet implemented] +# lake : 19 ( lakes) # # For example, include land and landice tiles as follows: -# TILE_TYPES: 100 20 +# TILE_TYPES: 100 19 20 # TILE_TYPES: 100 diff --git a/GEOSldas_App/ldas.py b/GEOSldas_App/ldas.py index 08b8456d..ab20ef33 100644 --- a/GEOSldas_App/ldas.py +++ b/GEOSldas_App/ldas.py @@ -104,6 +104,7 @@ def __init__(self, cmdLineArgs): self.bcs_dir_landiceshared = '' self.tile_types = '' self.with_land = False + self.with_lake = False self.with_landice = False self.run_route = 0 self.with_issm = False @@ -232,10 +233,14 @@ def __init__(self, cmdLineArgs): self.tile_types = self.ExeInputs.get('TILE_TYPES',"100").split() if "100" in self.tile_types : - self.with_land = True - assert int(self.ExeInputs['LSM_CHOICE']) <= 2, "\nLSM_CHOICE=3 (Catchment-CN4.5) is no longer supported. Please set LSM_CHOICE to 1 (Catchment) or 2 (Catchment-CN4.0)" - if "20" in self.tile_types : - self.with_landice = True + self.with_land = True + assert int(self.ExeInputs['LSM_CHOICE']) <= 2, "\nLSM_CHOICE=3 (Catchment-CN4.5) is no longer supported. Please set LSM_CHOICE to 1 (Catchment) or 2 (Catchment-CN4.0)" + + if "19" in self.tile_types : + self.with_lake = True + + if "20" in self.tile_types : + self.with_landice = True if self.with_landice == True: if int(self.ExeInputs.get('DO_ISSM'))==1: @@ -445,11 +450,16 @@ def __init__(self, cmdLineArgs): landpertRstFile=self.in_rstdir+'/'+tmpFile if ( os.path.isfile(landpertRstFile)) : self.has_geos_pert = True + + if self.with_lake: + tmpFile=self.ExeInputs['RESTART_ID']+'.lake_internal_rst.'+y4m2d2_h2m2 + lakeRstFile=self.in_rstdir+'/'+tmpFile + assert os.path.isfile(lakeRstFile), 'lake_internal_rst file [%s] does not exist!' %(lakeRstFile) if self.with_landice: - tmpFile=self.ExeInputs['RESTART_ID']+'.landice_internal_rst.'+y4m2d2_h2m2 - landiceRstFile=self.in_rstdir+'/'+tmpFile - assert os.path.isfile(landiceRstFile), 'landice_internal_rst file [%s] does not exist!' %(landiceRstFile) + tmpFile=self.ExeInputs['RESTART_ID']+'.landice_internal_rst.'+y4m2d2_h2m2 + landiceRstFile=self.in_rstdir+'/'+tmpFile + assert os.path.isfile(landiceRstFile), 'landice_internal_rst file [%s] does not exist!' %(landiceRstFile) if self.run_route > 0: tmpFile=self.ExeInputs['RESTART_ID']+'.route_internal_rst.'+y4m2d2_h2m2 @@ -884,7 +894,7 @@ def createLnRstBc(self) : self.has_landassim_seed = True mk_outdir = self.exphome+'/'+exp_id+'/mk_restarts/' - if (RESTART_str in ['2', 'M'] and (self.with_land or self.with_landice)): + if (RESTART_str in ['2', 'M'] and (self.with_land or self.with_lake or self.with_landice)): bcs_path = self.ExeInputs['BCS_PATH'] while bcs_path[-1] == '/' : bcs_path = bcs_path[0:-1] bc_base = os.path.dirname(bcs_path) @@ -922,25 +932,27 @@ def createLnRstBc(self) : if self.with_land: catch_obj = catchANDcn(config_obj = config) catch_obj.remap() - if self.with_landice: - config['output']['surface']['remap_water'] = True - config['input']['surface']['zoom'] = '2' - landice_obj = other_restarts(config_obj = config) - landice_obj.remap() + if self.with_lake or self.with_landice: + config['output']['surface']['remap_water'] = True + config['input']['surface']['zoom'] = '2' + other_rst_obj = other_restarts(config_obj = config) + other_rst_obj.remap() #for ens in self.ensdirs : catchRstFile0 = '' vegdynRstFile0 = '' + lakeRstFile0 = '' landiceRstFile0 = '' issmRstFile0 = '' for iens in range(self.nens) : ensdir = self.ensdirs[iens] ensid = self.ensids[iens] - myCatchRst = myRstDir+'/'+self.catch +ensid +'_internal_rst' - myLandiceRst = myRstDir+'/'+ 'landice' +ensid +'_internal_rst' - myIssmRst = myRstDir+'/'+ 'issm' +ensid +'_internal_rst' - myVegRst = myRstDir+'/'+ 'vegdyn'+ensid +'_internal_rst' + myCatchRst = myRstDir+'/'+ self.catch +ensid +'_internal_rst' + myLakeRst = myRstDir+'/'+ 'lake' +ensid +'_internal_rst' + myLandiceRst = myRstDir+'/'+ 'landice' +ensid +'_internal_rst' + myIssmRst = myRstDir+'/'+ 'issm' +ensid +'_internal_rst' + myVegRst = myRstDir+'/'+ 'vegdyn' +ensid +'_internal_rst' myPertRst = myRstDir+'/'+ 'landpert' +ensid +'_internal_rst' myRouteRst = myRstDir+'/'+ 'route' +ensid +'_internal_rst' @@ -996,6 +1008,31 @@ def createLnRstBc(self) : else : vegdynRstFile = vegdynRstFile0 + lakeRstFile = '' + if self.with_lake : + if RESTART_str in ['1', '3'] : + lakeRstFile = rstpath+ensdir +'/'+ y4m2+'/'+self.ExeInputs['RESTART_ID']+'.'+'lake_internal_rst.'+y4m2d2_h2m2 + + if RESTART_str in ['2', 'M']: + lakeRstFile = glob.glob(self.exphome+'/'+exp_id+'/mk_restarts/*'+'lake_internal_rst.'+YYYYMMDD+'*')[0] + + if os.path.isfile(lakeRstFile) : + lakeLocal = self.rstdir+ensdir +'/'+ y4m2+'/'+self.ExeInputs['EXP_ID']+'.lake_internal_rst.'+y4m2d2_h2m2 + + if self.isZoomIn : + print ("Creating zoom-in of lake restart file... \n") + cmd=self.bindir + '/preprocess_ldas.x zoomin_lakerst '+ lakeRstFile +' ' + lakeLocal + ' '+ tmp_f2g_file.name + print ("cmd: " + cmd) + sp.call(shlex.split(cmd)) + else : + shutil.copy(lakeRstFile,lakeLocal) + + lakeRstFile = lakeLocal + if '0000' in ensdir : + lakeRstFile0 = lakeRstFile + else : + lakeRstFile = lakeRstFile0 + landiceRstFile = '' issmRstFile = '' if self.with_landice : @@ -1076,15 +1113,19 @@ def createLnRstBc(self) : os.symlink(catchRstFile, myCatchRst) os.symlink(vegdynRstFile, myVegRst) - if self.with_landice : - print("link landice restart: " + myLandiceRst) - os.symlink(landiceRstFile, myLandiceRst) + if self.with_lake and iens == 0: + print("link lake restart: " + myLakeRst) + os.symlink(lakeRstFile, myLakeRst) + + if self.with_landice and iens == 0: + print("link landice restart: " + myLandiceRst) + os.symlink(landiceRstFile, myLandiceRst) if self.run_route > 0 : print("link route restart: " + myRouteRst) os.symlink(routeRstFile, myRouteRst) - if self.with_issm: + if self.with_issm and iens == 0: if RESTART_str in ['1', '3']: print("link issm restart: " + myIssmRst) os.symlink(issmRstFile, myIssmRst) @@ -1348,6 +1389,10 @@ def createRCFiles(self): rstval.append(self.catch) rstval.append('vegdyn') + if self.with_lake: + rstkey.append('LAKE') + rstval.append('lake') + if self.with_landice: rstkey.append('LANDICE') rstval.append('landice') diff --git a/GEOSldas_App/lenkf_j_template.py b/GEOSldas_App/lenkf_j_template.py index bd17e805..f5778f84 100644 --- a/GEOSldas_App/lenkf_j_template.py +++ b/GEOSldas_App/lenkf_j_template.py @@ -727,7 +727,8 @@ set THISDIR = $EXPDIR/output/$EXPDOMAIN/rs/$ENSDIR/Y${{eYEAR}}/M${{eMON}}/ if (! -e $THISDIR ) mkdir -p $THISDIR - set rstfs = (${{LANDMODEL}} 'landice' 'route' 'issm') + set rstfs = (${{LANDMODEL}} 'lake' 'landice' 'route' 'issm') + foreach rstf ( $rstfs ) if (-f ${{rstf}}${{ENSID}}_internal_checkpoint ) then set tmp_file = $EXPDIR/output/$EXPDOMAIN/rs/$ENSDIR/Y${{eYEAR}}/M${{eMON}}/${{EXPID}}.${{rstf}}_internal_rst.${{eYEAR}}${{eMON}}${{eDAY}}_${{eHour}}${{eMin}} diff --git a/GEOSldas_App/preprocess_ldas.F90 b/GEOSldas_App/preprocess_ldas.F90 index 67e3e9ef..6abffea3 100644 --- a/GEOSldas_App/preprocess_ldas.F90 +++ b/GEOSldas_App/preprocess_ldas.F90 @@ -118,6 +118,13 @@ program main call createZoominRestart(f2g_file, orig_catch, new_catch, 100) + else if (trim(option) == "zoomin_lakerst") then + orig_r = trim(arg1) + new_r = trim(arg2) + f2g_file = trim(arg3) + + call createZoominRestart(f2g_file, orig_r, new_r, 19) + else if (trim(option) == "zoomin_landicerst") then orig_r = trim(arg1) diff --git a/GEOSldas_App/process_hist.csh b/GEOSldas_App/process_hist.csh index 91a59777..24879767 100644 --- a/GEOSldas_App/process_hist.csh +++ b/GEOSldas_App/process_hist.csh @@ -75,12 +75,19 @@ else sed -i 's/>>>HIST_ISSM<< 1) then set GridComp = LANDAVG - sed -i 's|VEGDYN|'VEGDYN_e0000'|g' $HISTRC + sed -i "s|'VEGDYN'|'VEGDYN_e0000'|g" $HISTRC sed -i "s|'ROUTE'|'ROUTEAVG'|g" $HISTRC + sed -i "s|'LAKE'|'LAKE_e0000'|g" $HISTRC + sed -i "s|'LANDICE'|'LANDICE_e0000'|g" $HISTRC + sed -i "s|'ISSM'|'ISSM_e0000'|g" $HISTRC endif # fill in source 'GridComp' information for output variables diff --git a/GEOSmetforce_GridComp/GEOS_MetforceGridComp.F90 b/GEOSmetforce_GridComp/GEOS_MetforceGridComp.F90 index 2dc99129..5d31b5cf 100644 --- a/GEOSmetforce_GridComp/GEOS_MetforceGridComp.F90 +++ b/GEOSmetforce_GridComp/GEOS_MetforceGridComp.F90 @@ -32,8 +32,6 @@ module GEOS_MetforceGridCompMod private - real, parameter :: daylen = 86400. - ! !PUBLIC MEMBER FUNCTIONS: public :: SetServices @@ -70,25 +68,48 @@ module GEOS_MetforceGridCompMod type(T_METFORCE_STATE), pointer :: ptr=>null() end type METFORCE_WRAP - integer, parameter :: k_force = 12 - integer, parameter :: k_aerosol = 18 - integer, parameter :: k_landice = 15 - character(len=7), dimension(k_force) :: export_name = ['Tair ', 'Qair ', 'Psurf ', & - 'Rainf_C', 'Snowf ', 'LWdown ', & - 'PARdrct', 'PARdffs', 'Wind ', & - 'RefH ', 'Rainf ', 'SWdown '] - character(len=4), dimension(k_aerosol) :: aerosol_name = [ & - 'DUDP', 'DUSV', 'DUWT', 'DUSD', 'BCDP', 'BCSV', & - 'BCWT', 'BCSD', 'OCDP', 'OCSV', 'OCWT', 'OCSD', & - 'SUDP', 'SUSV', 'SUWT', 'SUSD', 'SSDP', 'SSSV' ] - character(len=11), dimension(k_landice) :: landice_name = ['TA ', 'QA ', 'PS ', & - 'PCU ', 'SNO ', 'LWDNSRF ', & - 'DRPAR ', 'DFPAR ', 'UU ', & - 'DZ ', 'DRNIR ', 'DFNIR ', & - 'DRUVR ', 'DFUVR ', 'PLS '] - integer :: NUM_LAND_TILE, NUM_LANDICE_TILE - contains - + ! -------------------------- + ! + ! variables needed for DistributeForcingTo[Land,Landpert,Landice,Lake]: + + integer :: NUM_LAND_TILE, NUM_LAKE_TILE, NUM_LANDICE_TILE + + integer, parameter :: k_export = 12 + integer, parameter :: k_landpert = k_export + integer, parameter :: k_landice_lake = 10 + integer, parameter :: k_aerosol = 18 + + ! export_name is vector of field names of type metforce; these fields are read from files + ! and mapped to tile space by LDAS_GetForcing(), then interpolated in time by LDAS_TInterpForcing(): + + character(len=7), parameter, dimension(k_export ) :: export_name = [ & + 'Tair ', 'Qair ', 'Psurf ', & + 'Rainf_C', 'Snowf ', 'LWdown ', & + 'PARdrct', 'PARdffs', 'Wind ', & + 'RefH ', 'Rainf ', 'SWdown '] + + ! names of forcing variables in Landice and Lake GridComps that match elements 1:10 of export_name; + ! remainder of variables done explicitly inside DistributeForcingTo[Landice,Lake] + + character(len=7), parameter, dimension(k_landice_lake) :: landice_lake_name = [ & + 'TA ', 'QA ', 'PS ', & + 'PCU ', 'SNO ', 'LWDNSRF', & + 'DRPAR ', 'DFPAR ', 'UU ', & + 'DZ '] + + ! names of forcing variables in Landpert GridComp match export_name for all elements: + + character(len=7), parameter, dimension(k_landpert ) :: landpert_name = export_name + + ! names of aerosol forcing variables: + + character(len=4), parameter, dimension(k_aerosol ) :: aerosol_name = [ & + 'DUDP', 'DUSV', 'DUWT', 'DUSD', 'BCDP', 'BCSV', & + 'BCWT', 'BCSD', 'OCDP', 'OCSV', 'OCWT', 'OCSD', & + 'SUDP', 'SUSV', 'SUWT', 'SUSD', 'SSDP', 'SSSV' ] + +contains + !BOP ! !IROTUINE: SetServices -- Set ESMF services for this component @@ -133,7 +154,7 @@ subroutine SetServices(gc, rc) ) VERIFY_(status) - ! phase 1 get forcing + ! phase 1: get forcing call MAPL_GridCompSetEntryPoint( & gc, & ESMF_METHOD_RUN, & @@ -141,6 +162,7 @@ subroutine SetServices(gc, rc) rc=status & ) VERIFY_(status) + ! phase 2: to land call MAPL_GridCompSetEntryPoint( & gc, & @@ -168,6 +190,15 @@ subroutine SetServices(gc, rc) ) VERIFY_(status) + ! phase 5: to lake + call MAPL_GridCompSetEntryPoint( & + gc, & + ESMF_METHOD_RUN, & + DistributeForcingToLake, & + rc=status & + ) + VERIFY_(status) + call MAPL_GridCompSetEntryPoint( & gc, & ESMF_METHOD_FINALIZE, & @@ -662,6 +693,7 @@ subroutine Initialize(gc, import, export, clock, rc) VERIFY_(status) NUM_LAND_TILE = count(tiletype == MAPL_LAND) + NUM_LAKE_TILE = count(tiletype == MAPL_LAKE) NUM_LANDICE_TILE = count(tiletype == MAPL_LANDICE) call MAPL_GetResource(MAPL, grid_type,Label="GEOSldas.GRID_TYPE:",RC=STATUS) @@ -793,13 +825,16 @@ subroutine Initialize(gc, import, export, clock, rc) end subroutine Initialize - + ! ------------------------------------------------------------------------ + !BOP ! !IROTUINE: Run_GetForcing - a wrapper around Rolf's get_forcing() ! !INTERFACE: + ! run method phase 1: + subroutine Run(gc, import, export, clock, rc) ! !ARGUMENTS: @@ -855,6 +890,7 @@ subroutine Run(gc, import, export, clock, rc) logical :: MERRA_file_specs, S2S3_file_specs logical :: backward_looking_fluxes integer :: AEROSOL_DEPOSITION + ! Export pointers real, pointer :: Tair(:)=>null() real, pointer :: Qair(:)=>null() @@ -922,7 +958,7 @@ subroutine Run(gc, import, export, clock, rc) internal => wrap%ptr call MAPL_GetResource ( MAPL, AEROSOL_DEPOSITION, Label="AEROSOL_DEPOSITION:", & - DEFAULT=1, RC=STATUS) + DEFAULT=0, RC=STATUS) ! Get number of tiles, tile lats/lons from LocStream call MAPL_Get(MAPL, LocStream=locstream) @@ -1174,21 +1210,19 @@ subroutine Run(gc, import, export, clock, rc) ! Set exports - Tair = mfDataNtp%Tair - Qair = mfDataNtp%Qair - Psurf = mfDataNtp%Psurf - Rainf_C = mfDataNtp%Rainf_C - Rainf = mfDataNtp%Rainf - Snowf = mfDataNtp%Snowf - ! *daylen convert [kg/m2/s] into [kg/m2/day] - !RainfSnowf= (Rainf+Snowf)*daylen - RainfSnowf= Rainf+Snowf - LWdown = mfDataNtp%LWdown - SWdown = mfDataNtp%SWdown - PARdrct = mfDataNtp%PARdrct - PARdffs = mfDataNtp%PARdffs - Wind = mfDataNtp%Wind - RefH = mfDataNtp%RefH + Tair = mfDataNtp%Tair + Qair = mfDataNtp%Qair + Psurf = mfDataNtp%Psurf + Rainf_C = mfDataNtp%Rainf_C + Rainf = mfDataNtp%Rainf + Snowf = mfDataNtp%Snowf + RainfSnowf = Rainf+Snowf + LWdown = mfDataNtp%LWdown + SWdown = mfDataNtp%SWdown + PARdrct = mfDataNtp%PARdrct + PARdffs = mfDataNtp%PARdffs + Wind = mfDataNtp%Wind + RefH = mfDataNtp%RefH if(AEROSOL_DEPOSITION /=0) then @@ -1276,7 +1310,14 @@ subroutine Run(gc, import, export, clock, rc) end subroutine Run + ! -------------------------------------------------------------------------- + ! + ! run method phase 2: + subroutine DistributeForcingToLand(gc, export, land_import, clock, rc) + + ! distribute those forcing variables to Land that Land does not receive from Landpert + ! (variables that could be perturbed are sent to Land via Landpert) type(ESMF_GridComp), intent(inout) :: gc ! Gridded component type(ESMF_State), intent(inout) :: export ! Export state @@ -1284,33 +1325,53 @@ subroutine DistributeForcingToLand(gc, export, land_import, clock, rc) type(ESMF_Clock), intent(inout) :: clock ! The clock integer, optional, intent( out) :: rc ! Error code - real, pointer :: out1d(:), in1d(:) - real, pointer :: out2d(:,:), in2d(:,:) - integer :: k, AEROSOL_DEPOSITION, status - type(MAPL_MetaComp), pointer :: MAPL - character(len=ESMF_MAXSTR) :: Iam + integer :: k, i1, i2, AEROSOL_DEPOSITION, status + real, pointer :: out1d(: ), in1d(: ) + real, pointer :: out2d(:,:), in2d(:,:) ! for aerosol forcing + type(MAPL_MetaComp), pointer :: MAPL ! for aerosol forcing + + character(len=ESMF_MAXSTR) :: Iam Iam = "metForce::DistributeForcingToLand" + if (NUM_LAND_TILE == 0) then + RETURN_(ESMF_SUCCESS) + endif + + ! Hardwired active forcing tile-space order is LAND -> LAKE -> LANDICE + i1 = 1 + i2 = NUM_LAND_TILE + + ! fill aerosol forcing (if needed) call MAPL_GetObjectFromGC(gc, MAPL, _RC) - call MAPL_GetResource ( MAPL, AEROSOL_DEPOSITION, Label="AEROSOL_DEPOSITION:", DEFAULT=1, _RC) + call MAPL_GetResource ( MAPL, AEROSOL_DEPOSITION, Label="AEROSOL_DEPOSITION:", DEFAULT=0, _RC) if(AEROSOL_DEPOSITION /=0) then do k = 1, k_aerosol call MAPL_GetPointer(export, out2d, aerosol_name(k), _RC) call MAPL_GetPointer(land_import, in2d, aerosol_name(k), _RC) - in2d(:,:) = out2d(1:NUM_LAND_TILE, :) + + ! Hardwired active forcing tile-space order is LAND -> LAKE -> LANDICE. + in2d(:,:) = out2d(i1:i2, :) enddo endif + ! fill surface pressure and lowest-model-layer height + call MAPL_GetPointer(export, out1d, 'Psurf', _RC) - call MAPL_GetPointer(land_import, in1d, 'PS', _RC) + call MAPL_GetPointer(land_import, in1d, 'PS', _RC) in1d = out1d(1:NUM_LAND_TILE) + call MAPL_GetPointer(export, out1d, 'RefH', _RC) - call MAPL_GetPointer(land_import, in1d, 'DZ', _RC) + call MAPL_GetPointer(land_import, in1d, 'DZ', _RC) in1d = out1d(1:NUM_LAND_TILE) + RETURN_(ESMF_SUCCESS) end subroutine DistributeForcingToLand + ! -------------------------------------------------------------------------- + ! + ! run method phase 3: + subroutine DistributeForcingToLandPert(gc, export, landpert_import, clock, rc) type(ESMF_GridComp), intent(inout) :: gc ! Gridded component @@ -1319,91 +1380,200 @@ subroutine DistributeForcingToLandPert(gc, export, landpert_import, clock, rc) type(ESMF_Clock), intent(inout) :: clock ! The clock integer, optional, intent( out) :: rc ! Error code - real, pointer :: out1d(:), in1d(:) - integer :: k, status - character(len=ESMF_MAXSTR) :: Iam + integer :: k, i1, i2, status + real, pointer :: out1d(:), in1d(:) + + character(len=ESMF_MAXSTR) :: Iam Iam = "metForce::DistributeForcingToLandPert" + + if (NUM_LAND_TILE == 0) then + RETURN_(ESMF_SUCCESS) + endif + + ! Hardwired active forcing tile-space order is LAND -> LAKE -> LANDICE + i1 = 1 + i2 = NUM_LAND_TILE - do k = 1, k_force - call MAPL_GetPointer(export, out1d, trim(export_name(k)), _RC) - call MAPL_GetPointer(landpert_import, in1d, trim(export_name(k)), _RC) - in1d = out1d(1:NUM_LAND_TILE) + ! fill forcing imports of Landpert GridComp (same as variables in "export_name"): + ! + ! Tair, Qair, Psurf, Rainf_C, Snowf, LWdown , PARdrct, PARdffs, Wind, RefH, Rainf, SWdown + + do k = 1, k_landpert + call MAPL_GetPointer(export, out1d, trim(export_name( k)), _RC) + call MAPL_GetPointer(landpert_import, in1d, trim(landpert_name(k)), _RC) + in1d = out1d(i1:i2) enddo + RETURN_(ESMF_SUCCESS) end subroutine DistributeForcingToLandPert + ! -------------------------------------------------------------------------- + ! + ! run method phase 4: + subroutine DistributeForcingToLandIce(gc, export, landice_import, clock, rc) - + + ! same as DistributeForcingToLake() except for aerosols and number/indices of tiles + type(ESMF_GridComp), intent(inout) :: gc ! Gridded component type(ESMF_State), intent(inout) :: export ! Export state type(ESMF_State), intent(inout) :: landice_import ! Import state type(ESMF_Clock), intent(inout) :: clock ! The clock integer, optional, intent( out) :: rc ! Error code - integer :: k, i1, i2, AEROSOL_DEPOSITION, status - real, pointer :: out1d(:), in1d(:), tmp(:) - real, pointer :: out2d(:,:), in2d(:,:) - real, allocatable :: tmpreal(:) - type(MAPL_MetaComp), pointer :: MAPL - character(len=ESMF_MAXSTR) :: Iam + integer :: k, i1, i2, AEROSOL_DEPOSITION, status + real, pointer :: out1d(: ), in1d(: ), tmp(:) + real, pointer :: out2d(:,:), in2d(:,:) ! for aerosol forcing + real, allocatable :: tmpreal(:) + type(MAPL_MetaComp), pointer :: MAPL ! for aerosol forcing + + character(len=ESMF_MAXSTR) :: Iam Iam = "metForce::DistributeForcingToLandice" if (NUM_LANDICE_TILE == 0) then - RETURN_(ESMF_SUCCESS) + RETURN_(ESMF_SUCCESS) endif - i1 = NUM_LAND_TILE + 1 - i2 = NUM_LAND_TILE + NUM_LANDICE_TILE - ! Get MAPL obj + ! Hardwired active forcing tile-space order is LAND -> LAKE -> LANDICE + i1 = NUM_LAND_TILE + NUM_LAKE_TILE + 1 + i2 = NUM_LAND_TILE + NUM_LAKE_TILE + NUM_LANDICE_TILE + + ! fill aerosol forcing (if needed) call MAPL_GetObjectFromGC(gc, MAPL, _RC) - call MAPL_GetResource ( MAPL, AEROSOL_DEPOSITION, Label="AEROSOL_DEPOSITION:", DEFAULT=1, _RC) + call MAPL_GetResource ( MAPL, AEROSOL_DEPOSITION, Label="AEROSOL_DEPOSITION:", DEFAULT=0, _RC) if(AEROSOL_DEPOSITION /=0) then do k = 1, k_aerosol call MAPL_GetPointer(export, out2d, aerosol_name(k), _RC) call MAPL_GetPointer(landice_import, in2d, aerosol_name(k), _RC) in2d(:,:) = out2d(i1:i2, :) - VERIFY_(status) enddo endif - - do k = 1, k_force - 2 - call MAPL_GetPointer(export, out1d, trim(export_name(k)), _RC) - call MAPL_GetPointer(landice_import, in1d, trim(landice_name(k)), _RC) + + ! fill forcing imports of Landice GridComp with matching export_name + ! + ! connect: Tair, Qair, Psurf, Rainf_C, Snowf, LWdown , PARdrct, PARdffs, Wind, RefH [export_name(1:10)] + ! to: TA , QA , PS , PCU , SNO , LWDNSRF, DRPAR , DFPAR , UU , DZ [landice_lake_name] + + do k = 1, k_landice_lake + call MAPL_GetPointer(export, out1d, trim(export_name( k)), _RC) + call MAPL_GetPointer(landice_import, in1d, trim(landice_lake_name(k)), _RC) in1d = out1d(i1:i2) enddo - call MAPL_GetPointer(export, out1d, 'Wind', _RC) - call MAPL_GetPointer(landice_import, in1d, 'UWINDLMTILE', _RC) + ! fill more forcing imports of Landice GridComp + + call MAPL_GetPointer( export, out1d, 'Wind', _RC) + call MAPL_GetPointer( landice_import, in1d, 'UWINDLMTILE', _RC) ! UWINDLMTILE = Wind in1d = out1d(i1:i2) - call MAPL_GetPointer(landice_import, in1d, 'VWINDLMTILE', _RC) + call MAPL_GetPointer( landice_import, in1d, 'VWINDLMTILE', _RC) ! VWINDLMTILE = 0. in1d = 0. - call MAPL_GetPointer(export, out1d, 'Rainf', _RC) - call MAPL_GetPointer(export, tmp, 'Rainf_C', _RC) - call MAPL_GetPointer(landice_import, in1d, 'PLS', _RC) - in1d = out1d(i1:i2) - tmp(i1:i2) - + call MAPL_GetPointer( export, out1d, 'Rainf', _RC) + call MAPL_GetPointer( export, tmp, 'Rainf_C', _RC) + call MAPL_GetPointer( landice_import, in1d, 'PLS', _RC) + in1d = out1d(i1:i2) - tmp(i1:i2) ! PLS = Rainf - Rainf_C + allocate(tmpreal(NUM_LANDICE_TILE), stat=status) - call MAPL_GetPointer(export, out1d, 'SWdown', _RC) + VERIFY_(status) + + call MAPL_GetPointer( export, out1d, 'SWdown', _RC) tmpreal = 0.5* out1d(i1:i2) - call MAPL_GetPointer(landice_import, in1d, 'DRNIR', _RC) + call MAPL_GetPointer( landice_import, in1d, 'DRNIR', _RC) ! DRNIR = 0.5*0.5*SWdown in1d = 0.5 * tmpreal - call MAPL_GetPointer(landice_import, in1d, 'DFNIR', _RC) + call MAPL_GetPointer( landice_import, in1d, 'DFNIR', _RC) ! DFNIR = 0.5*0.5*SWdown in1d = 0.5 * tmpreal - call MAPL_GetPointer(export, out1d, 'PARdrct', _RC) - call MAPL_GetPointer(landice_import, in1d, 'DRUVR', _RC) - in1d = 0.5* tmpreal - out1d(i1:i2) - call MAPL_GetPointer(export, out1d, 'PARdffs', _RC) - call MAPL_GetPointer(landice_import, in1d, 'DFUVR', _RC) + call MAPL_GetPointer( export, out1d, 'PARdrct', _RC) + call MAPL_GetPointer( landice_import, in1d, 'DRUVR', _RC) + in1d = 0.5* tmpreal - out1d(i1:i2) ! DRUVR = 0.5*SWdown - PARdrct + call MAPL_GetPointer( export, out1d, 'PARdffs', _RC) + call MAPL_GetPointer( landice_import, in1d, 'DFUVR', _RC) ! DFUVR = 0.5*SWdown - PARdffs in1d = 0.5* tmpreal - out1d(i1:i2) + deallocate(tmpreal) RETURN_(ESMF_SUCCESS) end subroutine DistributeForcingToLandIce + ! -------------------------------------------------------------------------- + ! + ! run method phase 5: + + subroutine DistributeForcingToLake(gc, export, lake_import, clock, rc) + + ! same as DistributeForcingToLandice() except for aerosols and number/indices of tiles + + type(ESMF_GridComp), intent(inout) :: gc ! Gridded component + type(ESMF_State), intent(inout) :: export ! Export state + type(ESMF_State), intent(inout) :: lake_import ! Import state + type(ESMF_Clock), intent(inout) :: clock ! The clock + integer, optional, intent( out) :: rc ! Error code + + integer :: k, i1, i2, status + real, pointer :: out1d(:), in1d(:), tmp(:) + real, allocatable :: tmpreal(:) + + character(len=ESMF_MAXSTR) :: Iam + Iam = "metForce::DistributeForcingToLake" + + if (NUM_LAKE_TILE == 0) then + RETURN_(ESMF_SUCCESS) + endif + + ! Hardwired active forcing tile-space order is LAND -> LAKE -> LANDICE + i1 = NUM_LAND_TILE + 1 + i2 = NUM_LAND_TILE + NUM_LAKE_TILE + + ! fill forcing imports of Lake GridComp with matching export_name + ! + ! connect: Tair, Qair, Psurf, Rainf_C, Snowf, LWdown , PARdrct, PARdffs, Wind, RefH [export_name(1:10)] + ! to: TA , QA , PS , PCU , SNO , LWDNSRF, DRPAR , DFPAR , UU , DZ [landice_lake_name] + + do k = 1, k_landice_lake + call MAPL_GetPointer(export, out1d, trim(export_name( k)), _RC) + call MAPL_GetPointer(lake_import, in1d, trim(landice_lake_name(k)), _RC) + in1d = out1d(i1:i2) + enddo + + ! fill more forcing imports of Lake GridComp + + call MAPL_GetPointer( export, out1d, 'Wind', _RC) + call MAPL_GetPointer( lake_import, in1d, 'UWINDLMTILE', _RC) ! UWINDLMTILE = Wind + in1d = out1d(i1:i2) + call MAPL_GetPointer( lake_import, in1d, 'VWINDLMTILE', _RC) ! VWINDLMTILE = 0. + in1d = 0. + + call MAPL_GetPointer( export, out1d, 'Rainf', _RC) + call MAPL_GetPointer( export, tmp, 'Rainf_C', _RC) + call MAPL_GetPointer( lake_import, in1d, 'PLS', _RC) + in1d = out1d(i1:i2) - tmp(i1:i2) ! PLS = Rainf - Rainf_C + + allocate(tmpreal(NUM_LAKE_TILE), stat=status) + VERIFY_(status) + + call MAPL_GetPointer( export, out1d, 'SWdown', _RC) + tmpreal = 0.5* out1d(i1:i2) + call MAPL_GetPointer( lake_import, in1d, 'DRNIR', _RC) ! DRNIR = 0.5*0.5*SWdown + in1d = 0.5 * tmpreal + call MAPL_GetPointer( lake_import, in1d, 'DFNIR', _RC) ! DFNIR = 0.5*0.5*SWdown + in1d = 0.5 * tmpreal + + call MAPL_GetPointer( export, out1d, 'PARdrct', _RC) + call MAPL_GetPointer( lake_import, in1d, 'DRUVR', _RC) + in1d = 0.5* tmpreal - out1d(i1:i2) ! DRUVR = 0.5*SWdown - PARdrct + call MAPL_GetPointer( export, out1d, 'PARdffs', _RC) + call MAPL_GetPointer( lake_import, in1d, 'DFUVR', _RC) ! DFUVR = 0.5*SWdown - PARdffs + in1d = 0.5* tmpreal - out1d(i1:i2) + deallocate(tmpreal) + + RETURN_(ESMF_SUCCESS) + + end subroutine DistributeForcingToLake + + ! -------------------------------------------------------------------------- + !BOP ! !IROTUINE: Finalize -- Finalize method for LDAS GridComp