Background
In preparation for migration from MAPL v2 to MAPL v3, the Surface GridComp
and its children need to be cleaned up to:
- Minimize the footprint of v3-specific changes
- Support concurrent maintenance of v2 and v3 branches during the lengthy
validation period
- Isolate and minimize use of
MAPL_LocStream (which will be replaced by
ESMF_Mesh / ESMF_XGrid in v3)
This issue documents the analysis and proposed refactoring plan for developer
review before work begins.
Component Inventory
The Surface GridComp lives under:
GEOSsurface_GridComp/
GEOS_SurfaceGridComp.F90 (~10,925 lines — main orchestrator)
Shared/
SurfParams.F90
StieglitzSnow.F90
OASIMalbedoMod.f
GEOSlake_GridComp/
GEOS_LakeGridComp.F90
GEOSland_GridComp/
GEOS_LandGridComp.F90 (~1,762 lines)
GEOScatch_GridComp/
GEOS_CatchGridComp.F90
GEOScatchCN_GridComp/
GEOS_CatchCNGridComp.F90
GEOScatchCNCLM40_GridComp/GEOS_CatchCNCLM40GridComp.F90
GEOScatchCNCLM45_GridComp/GEOS_CatchCNCLM45GridComp.F90
GEOSigni_GridComp/
GEOS_IgniGridComp.F90
GEOSroute_GridComp/
GEOS_RouteGridComp.F90 (under active development — not in scope)
GEOSvegdyn_GridComp/
GEOS_VegdynGridComp.F90
GEOSlandice_GridComp/
GEOS_LandIceGridComp.F90
GEOSsaltwater_GridComp/
GEOS_SaltWaterGridComp.F90
GEOS_OpenWaterGridComp.F90
GEOS_SimpleSeaiceGridComp.F90
GEOS_SeaiceInterfaceGridComp.F90
GEOS_CICE4ColumnPhysGridComp.F90
GEOS_ObioImportsGridComp.F90
Child GridComp registrations (via MAPL_AddChild):
GEOS_SurfaceGridComp → SALTWATER, LAKE, LANDICE, LAND
GEOS_LandGridComp → VEGDYN, CATCH (or CATCHCN array), IGNI
GEOS_SaltWaterGridComp → SEAICETHERMO (one of three options), OPENWATER, OBIOIMPORTS (conditional)
Key Findings from Analysis
1. Scale of LocStream usage
| File |
LocStream usages |
GEOS_SurfaceGridComp.F90 |
344 MAPL_LocStreamTransform calls + LocStreamCreate/LocStreamCreateXform in Initialize |
GEOS_SeaiceInterfaceGridComp.F90 |
A2O/O2A MAPL_LocStreamXform objects held in ESMF private state |
GEOS_CatchGridComp.F90 |
4 MAPL_LocStreamGet calls (tile geometry) |
GEOS_CatchCNCLM40/45GridComp.F90 |
2 each |
GEOS_LakeGridComp.F90, GEOS_LandGridComp.F90, GEOS_SaltWaterGridComp.F90 |
1–2 each |
GEOS_RouteGridComp.F90 |
Several (out of scope) |
No raw ESMF_LocStream, ESMF_Mesh, or ESMF_XGrid usage exists anywhere —
all spatial mapping goes through MAPL abstractions.
2. Spec declaration volume
| File |
Import specs |
Export specs |
Internal specs |
GEOS_SurfaceGridComp.F90 |
43 |
296 |
~12 |
GEOS_LandGridComp.F90 |
— |
424 (duplicated for LSM_CHOICE 1 vs 2/3) |
— |
| Other children |
varies |
varies |
varies |
Total across the tree: estimated 2,500+ hand-written spec calls.
3. Code structure issues
GEOS_SurfaceGridComp.F90 is ~10,925 lines containing SetServices specs,
Initialize, Run1, Run2, DOTYPE (~1,385 lines), a ~3,000-line diagnostic
transform block, and 6 helper subroutines — all in one file
- The
DOTYPE subroutine (per-child Run2 dispatch) and DOCDS (per-child Run1)
are structurally parallel but written separately
- The Run2 diagnostic block has ~150 near-identical
if(associated(VAR)) call MAPL_LocStreamTransform(...) blocks with no
data-driven loop
- Fire danger output appears 3 times (instantaneous / daily / daily-with-suffix)
as manually duplicated blocks
- Run1 and Run2 share identical boilerplate preambles (
ESMF_GridCompGet,
MAPL_GetObjectFromGC, MAPL_Get)
4. Legacy patterns
| Pattern |
Location |
use MAPL_Mod, use MAPL_Constants |
GEOS_RouteGridComp.F90 |
use MAPL_BaseMod |
catch_incr.F90 |
use MAPL_ExceptionHandling |
dbg_cnlsm_offline.F90, SurfParams.F90 |
VERIFY_(STATUS) macro (~2,228 uses) |
GEOS_SurfaceGridComp.F90 (mixed with newer _RC) |
Manual ESMF_UserCompSetInternalState for T_SURFACE_STATE |
GEOS_SurfaceGridComp.F90 — predates MAPL internal state management |
5. AQUA_PLANET compile-time flag
AQUA_PLANET (#ifdef) appears only in GEOS_SurfaceGridComp.F90 (4 occurrences,
3 logical blocks). It is compile-time because NUM_CHILDREN is a Fortran
parameter used to size static arrays XFORM_IN(NUM_CHILDREN) and
XFORM_OUT(NUM_CHILDREN). Once those arrays are moved out of the main module
(see Phase 2 below), the constraint disappears and AQUA_PLANET can become a
runtime .rc key.
Proposed Refactoring Plan
The overarching constraints are:
SetServices, Initialize, Run*, and Finalize remain in the main
GridComp module as thin wrappers; most MAPL API calls stay in the main body
MAPL_LocStreamTransform (and related LocStream APIs) are isolated behind a
wrapper module so that the v3 swap touches only that module
- The ROUTE GridComp is not touched (under active development)
Phase 1 — ACG Migration (Highest Priority, Start Here)
Convert all MAPL_AddImportSpec / MAPL_AddExportSpec / MAPL_AddInternalSpec
calls to ACG registry files using the v2 ACG generator (no 3g flag).
GWD GridComp (GWD_StateSpecs.rc) is the established reference example.
Create <Name>_StateSpecs.rc for each component. In each CMakeLists.txt:
mapl_acg(${this} <Name>_StateSpecs.rc
IMPORT_SPECS EXPORT_SPECS INTERNAL_SPECS GET_POINTERS DECLARE_POINTERS)
In each .F90, replace the spec-declaration block in SetServices with:
! Any logical expressions needed for COND columns must be established here,
! before the #include lines (e.g., LSM_CHOICE, DO_CICE_THERMO, etc.)
#include "<Name>_Import___.h"
#include "<Name>_Export___.h"
#include "<Name>_Internal___.h"
Special cases:
- Conditional specs (CICE-only, CatchCN-only, fire-danger, GOSWIM aerosol-in-snow)
map to the COND column in the ACG schema. The required logical expressions
must be computed before the #include lines.
GEOS_LandGridComp's CASE(1) vs CASE(2,3) duplication collapses — specs
that differ by LSM choice carry an appropriate COND entry (e.g., LSM_CHOICE == 1)
- Internal specs (Run1→Run2 bridge fields: CT, CQ, CM, CN, TS, QS, etc.) go in
category: INTERNAL
Components to convert (each gets its own _StateSpecs.rc):
| Component |
File |
| Surface |
GEOS_SurfaceGridComp.F90 |
| Land |
GEOS_LandGridComp.F90 |
| Lake |
GEOS_LakeGridComp.F90 |
| LandIce |
GEOS_LandIceGridComp.F90 |
| SaltWater |
GEOS_SaltWaterGridComp.F90 |
| OpenWater |
GEOS_OpenWaterGridComp.F90 |
| SimpleSeaice |
GEOS_SimpleSeaiceGridComp.F90 |
| CICE4ColumnPhys |
GEOS_CICE4ColumnPhysGridComp.F90 |
| SeaiceInterface |
GEOS_SeaiceInterfaceGridComp.F90 |
| ObioImports |
GEOS_ObioImportsGridComp.F90 |
| Catch |
GEOS_CatchGridComp.F90 |
| CatchCN |
GEOS_CatchCNGridComp.F90 |
| CatchCNCLM40 |
GEOS_CatchCNCLM40GridComp.F90 |
| CatchCNCLM45 |
GEOS_CatchCNCLM45GridComp.F90 |
| Vegdyn |
GEOS_VegdynGridComp.F90 |
| Igni |
GEOS_IgniGridComp.F90 |
Estimated reduction: ~2,500+ lines of boilerplate removed across the tree.
Phase 2 — LocStream Isolation
Create GEOSsurface_GridComp/Shared/GEOS_SurfaceTransform.F90 — a new utility
module. After this phase, MAPL_LocStreamTransform and related MAPL LocStream
APIs never appear directly in any GridComp .F90. The v3 migration then becomes
a change confined to this one module.
module GEOS_SurfaceTransformMod
use MAPL
implicit none
private
! Opaque transform state.
! v2 implementation: wraps MAPL_LocStreamXFORM
! v3 implementation: will wrap ESMF_XGrid weights
type, public :: SurfaceXFORM
private
type(MAPL_LocStreamXFORM) :: xform_in
type(MAPL_LocStreamXFORM) :: xform_out
end type
public :: SurfaceTransformInit ! Initialize per-child transforms (Initialize phase)
public :: ScatterToTiles ! Atm grid → tile space (1D fields)
public :: GatherFromTiles ! Tile space → atm grid (1D fields)
public :: ScatterUngridded ! Atm grid → tile space (with ungridded dim)
public :: GatherUngridded ! Tile space → atm grid (with ungridded dim)
public :: GetTileFractions ! FROCEAN, FRLAND, FRLAKE, FRLANDICE
public :: GetTileGeometry ! NT_GLOBAL, TILEGRID for child GridComps
public :: ScatterAtmToOcean ! A2O transform (for SeaiceInterface)
public :: GatherOceanToAtm ! O2A transform (for SeaiceInterface)
end module
The helper routines currently at the bottom of GEOS_SurfaceGridComp.F90
(MKTILE_1D, MKTILE_UNGRIDDED, FILLIN_TILE*, FILLOUT_TILE*) are
transform helpers and move here as well.
Changes in GEOS_SurfaceGridComp.F90:
T_SURFACE_STATE loses fixed-size XFORM_IN(NUM_CHILDREN) /
XFORM_OUT(NUM_CHILDREN); gains type(SurfaceXFORM), allocatable :: XFORM(:)
(now allocatable — removes the parameter constraint on NUM_CHILDREN)
- All 344
MAPL_LocStreamTransform calls → ScatterToTiles / GatherFromTiles
- The Initialize LocStream setup block →
SurfaceTransformInit
- Fractional area block →
GetTileFractions
Changes in GEOS_SeaiceInterfaceGridComp.F90:
MAPL_LocStreamXform pointers in ESMF private state → type(SurfaceXFORM)
- A2O/O2A transform calls →
ScatterAtmToOcean / GatherOceanToAtm
Changes in child GridComps (Lake, Catch, CatchCNCLM40/45, etc.):
MAPL_Get(..., LocStream=) + MAPL_LocStreamGet(..., TILEGRID=) →
GetTileGeometry(GC, NT_GLOBAL, TILEGRID, RC=STATUS)
v3 migration path: Only GEOS_SurfaceTransform.F90 changes. Each wrapper's
body swaps from MAPL_LocStreamTransform to the appropriate ESMF_XGrid /
ESMF_Mesh regrid call.
Phase 3 — Structural Decomposition of GEOS_SurfaceGridComp.F90
SetServices, Initialize, Run*, and Finalize remain in the main module
as thin wrappers. Large computational blocks move to new files in Shared/.
| New File |
Extracted Content |
Approx Lines |
GEOS_SurfaceChildRun.F90 |
SurfaceChildRun1 (ex-DOCDS, ~280 ln) + SurfaceChildRun2 (ex-DOTYPE, ~1,385 ln) |
~1,700 |
GEOS_SurfaceDiagnostics.F90 |
WriteSurfaceDiagnostics — the ~3,000-line tile→grid transform block in Run2 |
~3,000 |
GEOS_SurfaceLayerDiag.F90 |
ComputeSurfaceLayerDiag — MO/Louis surface layer quantities (U10M, T2M, Q2M, USTAR, …) |
~300 |
After Phases 1 + 3, GEOS_SurfaceGridComp.F90 shrinks from ~10,925 lines to
roughly 2,000–3,000 lines of clean orchestration code.
Example of what Run2 becomes:
subroutine Run2(GC, IM, EX, CLOCK, RC)
call GetSurfaceRunState(GC, MAPL, LOCSTREAM, GIM, GEX, XFORM, RC=STATUS)
! scatter key atmospheric inputs to tile space
call SurfaceChildRun2(NUM_CHILDREN, GCS, GIM, GEX, LOCSTREAM, XFORM, RC=STATUS)
call WriteSurfaceDiagnostics(LOCSTREAM, GIM, GEX, RC=STATUS)
call ComputeSurfaceLayerDiag(CT, CQ, SPEED, TA, TS, QS, ..., RC=STATUS)
end subroutine
Phase 4 — Modernize Error Handling and Module Imports
Do this after Phase 1, before Phases 2 and 3 to avoid conflicts with
structural changes. All steps are mechanical / scriptable.
4a. Replace all VERIFY_(STATUS) with _VERIFY(STATUS) throughout all
Surface GridComp files (~2,228 instances in GEOS_SurfaceGridComp.F90 alone).
4b. Consolidate legacy sub-module USE statements:
| File |
Replace |
With |
GEOS_RouteGridComp.F90 |
use MAPL_Mod + use MAPL_Constants |
use MAPL |
catch_incr.F90 |
use MAPL_BaseMod |
use MAPL |
dbg_cnlsm_offline.F90 |
use MAPL_ExceptionHandling |
use MAPL |
SurfParams.F90 |
use MAPL_ExceptionHandling |
use MAPL |
4c. After Phase 2: Remove the ESMF_UserCompSetInternalState /
ESMF_UserCompGetInternalState pattern for T_SURFACE_STATE. The XFORM arrays
will have moved to GEOS_SurfaceTransform.F90. The remaining members of
T_SURFACE_STATE (e.g., RoutingType) continue as an ESMF private state
derived type; a module variable is an acceptable intermediate step.
Phase 5 — Eliminate Remaining Code Duplication
5a. Collapse the fire-danger diagnostic triple-block into a loop over suffixes:
character(len=8), parameter :: FDI_SUFFIX(3) = [' ','_DAILY ','_DAILY_']
character(len=5), parameter :: FDI_FIELD(7) = ['FFMC ','DMC ','DC ','ISI ','BUI ','FWI ','DSR ']
! single nested loop replaces ~60 lines of copy-paste blocks
5b. Audit aerosol deposition arrays for consistent loop patterns.
5c. Extract the shared Run1/Run2 preamble (ESMF_GridCompGet /
MAPL_GetObjectFromGC / MAPL_Get sequence, duplicated verbatim) into a
GetSurfaceRunState(GC, ...) utility subroutine.
Phase 6 — AQUA_PLANET Runtime Conversion (After Phase 2)
AQUA_PLANET is compile-time only because NUM_CHILDREN must be a Fortran
parameter to size XFORM_IN(NUM_CHILDREN) / XFORM_OUT(NUM_CHILDREN).
Phase 2 makes those arrays allocatable, removing the constraint.
- Add to
GEOS_SurfaceGridComp.rc:
AQUA_PLANET: 0 # 0 = full surface model; 1 = ocean-only aqua planet
NUM_CHILDREN, CHILD_MASK, and XFORM(:) become runtime-allocated
- Replace the 3
#ifdef / #ifndef AQUA_PLANET blocks with
if (AQUA_PLANET == 1) runtime conditionals
- Remove any
-DAQUA_PLANET compile flag from the build system
Recommended Execution Sequence
Phase 1 (ACG — parallelizable per component)
↓
Phase 4a (VERIFY_ → _VERIFY, scripted)
Phase 4b (use MAPL sub-module cleanup)
↓
Phase 2 (LocStream isolation → GEOS_SurfaceTransform.F90)
↓
Phase 4c (T_SURFACE_STATE cleanup) ← can run concurrently
Phase 6 (AQUA_PLANET → runtime) ← can run concurrently
↓
Phase 3 (structural decomposition)
↓
Phase 5 (duplication cleanup)
Phases within the same row have no dependency on each other and can proceed
concurrently on separate branches/PRs.
Open Questions for Developers
GEOS_ObioImportsGridComp — Is this component a candidate for
removal or restructuring, or should it be migrated as-is?
T_SURFACE_STATE successor — After Phase 2, the remaining members
of this derived type are just RoutingType. Should this persist as a
named ESMF private state, or be absorbed differently?
- ACG
COND column for GEOS_LandGridComp — The CASE(1) vs CASE(2,3)
split currently determines which export specs are registered. What is the
correct variable name / expression available at spec-declaration time that
should appear in the COND column?
Background
In preparation for migration from MAPL v2 to MAPL v3, the Surface GridComp
and its children need to be cleaned up to:
validation period
MAPL_LocStream(which will be replaced byESMF_Mesh/ESMF_XGridin v3)This issue documents the analysis and proposed refactoring plan for developer
review before work begins.
Component Inventory
The Surface GridComp lives under:
Child GridComp registrations (via
MAPL_AddChild):GEOS_SurfaceGridComp→ SALTWATER, LAKE, LANDICE, LANDGEOS_LandGridComp→ VEGDYN, CATCH (or CATCHCN array), IGNIGEOS_SaltWaterGridComp→ SEAICETHERMO (one of three options), OPENWATER, OBIOIMPORTS (conditional)Key Findings from Analysis
1. Scale of LocStream usage
GEOS_SurfaceGridComp.F90MAPL_LocStreamTransformcalls +LocStreamCreate/LocStreamCreateXformin InitializeGEOS_SeaiceInterfaceGridComp.F90MAPL_LocStreamXformobjects held in ESMF private stateGEOS_CatchGridComp.F90MAPL_LocStreamGetcalls (tile geometry)GEOS_CatchCNCLM40/45GridComp.F90GEOS_LakeGridComp.F90,GEOS_LandGridComp.F90,GEOS_SaltWaterGridComp.F90GEOS_RouteGridComp.F90No raw
ESMF_LocStream,ESMF_Mesh, orESMF_XGridusage exists anywhere —all spatial mapping goes through MAPL abstractions.
2. Spec declaration volume
GEOS_SurfaceGridComp.F90GEOS_LandGridComp.F90Total across the tree: estimated 2,500+ hand-written spec calls.
3. Code structure issues
GEOS_SurfaceGridComp.F90is ~10,925 lines containing SetServices specs,Initialize, Run1, Run2, DOTYPE (~1,385 lines), a ~3,000-line diagnostic
transform block, and 6 helper subroutines — all in one file
DOTYPEsubroutine (per-child Run2 dispatch) andDOCDS(per-child Run1)are structurally parallel but written separately
if(associated(VAR)) call MAPL_LocStreamTransform(...)blocks with nodata-driven loop
as manually duplicated blocks
ESMF_GridCompGet,MAPL_GetObjectFromGC,MAPL_Get)4. Legacy patterns
use MAPL_Mod,use MAPL_ConstantsGEOS_RouteGridComp.F90use MAPL_BaseModcatch_incr.F90use MAPL_ExceptionHandlingdbg_cnlsm_offline.F90,SurfParams.F90VERIFY_(STATUS)macro (~2,228 uses)GEOS_SurfaceGridComp.F90(mixed with newer_RC)ESMF_UserCompSetInternalStateforT_SURFACE_STATEGEOS_SurfaceGridComp.F90— predates MAPL internal state management5.
AQUA_PLANETcompile-time flagAQUA_PLANET(#ifdef) appears only inGEOS_SurfaceGridComp.F90(4 occurrences,3 logical blocks). It is compile-time because
NUM_CHILDRENis a Fortranparameterused to size static arraysXFORM_IN(NUM_CHILDREN)andXFORM_OUT(NUM_CHILDREN). Once those arrays are moved out of the main module(see Phase 2 below), the constraint disappears and
AQUA_PLANETcan become aruntime
.rckey.Proposed Refactoring Plan
The overarching constraints are:
SetServices,Initialize,Run*, andFinalizeremain in the mainGridComp module as thin wrappers; most MAPL API calls stay in the main body
MAPL_LocStreamTransform(and related LocStream APIs) are isolated behind awrapper module so that the v3 swap touches only that module
Phase 1 — ACG Migration (Highest Priority, Start Here)
Convert all
MAPL_AddImportSpec/MAPL_AddExportSpec/MAPL_AddInternalSpeccalls to ACG registry files using the v2 ACG generator (no
3gflag).GWD GridComp (
GWD_StateSpecs.rc) is the established reference example.Create
<Name>_StateSpecs.rcfor each component. In eachCMakeLists.txt:In each
.F90, replace the spec-declaration block inSetServiceswith:Special cases:
map to the
CONDcolumn in the ACG schema. The required logical expressionsmust be computed before the
#includelines.GEOS_LandGridComp'sCASE(1)vsCASE(2,3)duplication collapses — specsthat differ by LSM choice carry an appropriate
CONDentry (e.g.,LSM_CHOICE == 1)category: INTERNALComponents to convert (each gets its own
_StateSpecs.rc):GEOS_SurfaceGridComp.F90GEOS_LandGridComp.F90GEOS_LakeGridComp.F90GEOS_LandIceGridComp.F90GEOS_SaltWaterGridComp.F90GEOS_OpenWaterGridComp.F90GEOS_SimpleSeaiceGridComp.F90GEOS_CICE4ColumnPhysGridComp.F90GEOS_SeaiceInterfaceGridComp.F90GEOS_ObioImportsGridComp.F90GEOS_CatchGridComp.F90GEOS_CatchCNGridComp.F90GEOS_CatchCNCLM40GridComp.F90GEOS_CatchCNCLM45GridComp.F90GEOS_VegdynGridComp.F90GEOS_IgniGridComp.F90Estimated reduction: ~2,500+ lines of boilerplate removed across the tree.
Phase 2 — LocStream Isolation
Create
GEOSsurface_GridComp/Shared/GEOS_SurfaceTransform.F90— a new utilitymodule. After this phase,
MAPL_LocStreamTransformand related MAPL LocStreamAPIs never appear directly in any GridComp
.F90. The v3 migration then becomesa change confined to this one module.
The helper routines currently at the bottom of
GEOS_SurfaceGridComp.F90(
MKTILE_1D,MKTILE_UNGRIDDED,FILLIN_TILE*,FILLOUT_TILE*) aretransform helpers and move here as well.
Changes in
GEOS_SurfaceGridComp.F90:T_SURFACE_STATEloses fixed-sizeXFORM_IN(NUM_CHILDREN)/XFORM_OUT(NUM_CHILDREN); gainstype(SurfaceXFORM), allocatable :: XFORM(:)(now allocatable — removes the
parameterconstraint onNUM_CHILDREN)MAPL_LocStreamTransformcalls →ScatterToTiles/GatherFromTilesSurfaceTransformInitGetTileFractionsChanges in
GEOS_SeaiceInterfaceGridComp.F90:MAPL_LocStreamXformpointers in ESMF private state →type(SurfaceXFORM)ScatterAtmToOcean/GatherOceanToAtmChanges in child GridComps (Lake, Catch, CatchCNCLM40/45, etc.):
MAPL_Get(..., LocStream=)+MAPL_LocStreamGet(..., TILEGRID=)→GetTileGeometry(GC, NT_GLOBAL, TILEGRID, RC=STATUS)v3 migration path: Only
GEOS_SurfaceTransform.F90changes. Each wrapper'sbody swaps from
MAPL_LocStreamTransformto the appropriateESMF_XGrid/ESMF_Meshregrid call.Phase 3 — Structural Decomposition of
GEOS_SurfaceGridComp.F90SetServices,Initialize,Run*, andFinalizeremain in the main moduleas thin wrappers. Large computational blocks move to new files in
Shared/.GEOS_SurfaceChildRun.F90SurfaceChildRun1(ex-DOCDS, ~280 ln) +SurfaceChildRun2(ex-DOTYPE, ~1,385 ln)GEOS_SurfaceDiagnostics.F90WriteSurfaceDiagnostics— the ~3,000-line tile→grid transform block in Run2GEOS_SurfaceLayerDiag.F90ComputeSurfaceLayerDiag— MO/Louis surface layer quantities (U10M, T2M, Q2M, USTAR, …)After Phases 1 + 3,
GEOS_SurfaceGridComp.F90shrinks from ~10,925 lines toroughly 2,000–3,000 lines of clean orchestration code.
Example of what
Run2becomes:Phase 4 — Modernize Error Handling and Module Imports
Do this after Phase 1, before Phases 2 and 3 to avoid conflicts with
structural changes. All steps are mechanical / scriptable.
4a. Replace all
VERIFY_(STATUS)with_VERIFY(STATUS)throughout allSurface GridComp files (~2,228 instances in
GEOS_SurfaceGridComp.F90alone).4b. Consolidate legacy sub-module
USEstatements:GEOS_RouteGridComp.F90use MAPL_Mod+use MAPL_Constantsuse MAPLcatch_incr.F90use MAPL_BaseModuse MAPLdbg_cnlsm_offline.F90use MAPL_ExceptionHandlinguse MAPLSurfParams.F90use MAPL_ExceptionHandlinguse MAPL4c. After Phase 2: Remove the
ESMF_UserCompSetInternalState/ESMF_UserCompGetInternalStatepattern forT_SURFACE_STATE. The XFORM arrayswill have moved to
GEOS_SurfaceTransform.F90. The remaining members ofT_SURFACE_STATE(e.g.,RoutingType) continue as an ESMF private statederived type; a module variable is an acceptable intermediate step.
Phase 5 — Eliminate Remaining Code Duplication
5a. Collapse the fire-danger diagnostic triple-block into a loop over suffixes:
5b. Audit aerosol deposition arrays for consistent loop patterns.
5c. Extract the shared Run1/Run2 preamble (
ESMF_GridCompGet/MAPL_GetObjectFromGC/MAPL_Getsequence, duplicated verbatim) into aGetSurfaceRunState(GC, ...)utility subroutine.Phase 6 —
AQUA_PLANETRuntime Conversion (After Phase 2)AQUA_PLANETis compile-time only becauseNUM_CHILDRENmust be a Fortranparameterto sizeXFORM_IN(NUM_CHILDREN)/XFORM_OUT(NUM_CHILDREN).Phase 2 makes those arrays allocatable, removing the constraint.
GEOS_SurfaceGridComp.rc:NUM_CHILDREN,CHILD_MASK, andXFORM(:)become runtime-allocated#ifdef/#ifndef AQUA_PLANETblocks withif (AQUA_PLANET == 1)runtime conditionals-DAQUA_PLANETcompile flag from the build systemRecommended Execution Sequence
Phases within the same row have no dependency on each other and can proceed
concurrently on separate branches/PRs.
Open Questions for Developers
GEOS_ObioImportsGridComp— Is this component a candidate forremoval or restructuring, or should it be migrated as-is?
T_SURFACE_STATEsuccessor — After Phase 2, the remaining membersof this derived type are just
RoutingType. Should this persist as anamed ESMF private state, or be absorbed differently?
CONDcolumn forGEOS_LandGridComp— TheCASE(1)vsCASE(2,3)split currently determines which export specs are registered. What is the
correct variable name / expression available at spec-declaration time that
should appear in the
CONDcolumn?