Repository navigation
Turbulence Analysis
All six are declared in GEOSturbulence_GridComp/GEOS_TurbulenceGridComp.F90. The three imports are at lines 562-592 and the three exports are at lines 1130-1160. They are filled in GEOS_PhysicsGridComp.F90 Initialize (about lines 2200-2420). Each bundle is a list of fields keyed by a tracer name NAME, plus a suffix.
| Bundle | Direction | Per-field key | What it holds | Source |
|---|---|---|---|---|
| TR | import | NAME |
The diffused quantity (S, U, V, Q and tracers) | Physics import S, U, V; turbulence exports TKESHOC and QT2; friendlies from Physics, Moist and Chem |
| TRG | import | NAME//'HAT' |
Effective surface (ground) value of the quantity | Surface exports/internals: SHAT, UHAT, VHAT, QHAT, THAT |
| DTG | import | NAME//'DEL' |
Change in the surface value during the step | Surface exports DELSS, DELUS, DELVS, DELQS |
| TRI | export | NAME//'IT' |
Tendency of the quantity (pressure-weighted if WeightedTendency) |
Fields are the Physics export (QVIT for Q, otherwise <NAME>IT) |
| FSTAR | export | NAME//'FLX' |
Surface flux of the quantity | Same field objects as Surface imports SH, TAUX, TAUY, EVAP |
| DFSTAR | export | NAME//'DFL' |
d(flux)/d(surface value) | Same field objects as Surface imports DSH, DFU, DFV, DEVAP |
The name mapping in Physics Initialize for S, U, V, Q is:
-
TRG:
SHAT,UHAT,VHAT,QHAT. -
DTG:
DELSS,DELUS,DELVS,DELQS. -
FSTAR:
SH,TAUX,TAUY,EVAP. -
DFSTAR:
DSH,DFU,DFV,DEVAP. - Any other tracer name maps to itself. Surface has no such field, so the pointer ends up unassociated.
- Bundle fields are shared field objects, not copies. Physics adds Surface's field into the Turbulence bundle with
ESMFL_StateGetField. Both components then see the same memory. - TRG and DTG: these come from Surface exports, so Surface writes them and Turbulence reads them.
-
FSTAR and DFSTAR: these are Turbulence exports, but the fields are Surface's own import fields (
GIM(SURF)). Turbulence writes them and Surface reads them (SH,TAUX,EVAP,DSHand so on atGEOS_SurfaceGridComp.F90:6225-6229). This is the reverse direction of the usual flow. - TRI: these fields are Physics exports, so Turbulence writes them directly into Physics export memory.
-
Unwired tracers: the turbulence default is a friendly tracer with zero surface flux. Tracers with no
HAT,FLXorDFLfield get unassociated pointers and are treated as having zero flux and no tendency. -
Terminate imports: Physics calls
MAPL_TerminateImportfor TR, TRG and DTG (GEOS_PhysicsGridComp.F90:1942). They are therefore not required from the parent and are filled internally.
-
Surface Run1 (
GEOS_PhysicsGridComp.F90:3211) produces the effective surface values.-
SHAT = cp*TH + PHIS(SurfaceGridComp:4979), so S's surface value is dry static energy. -
QHAT,THAT,UHATandVHATare divided by the exchange coefficients CQ, CT and CM (lines 4974-4977).
-
- Turbulence Run1 (line 3242) computes a preliminary solve at the unchanged surface value. It reads TR and TRG, and writes TRI, FSTAR and DFSTAR.
-
Surface Run2 (line 3356) uses FSTAR and DFSTAR to advance the land, ocean and ice surface. It exports DELSS, DELQS, DELUS and DELVS (
SurfaceGridComp:8724-8727).DELSS = cp*DTSDELQS = DQSDELUS = DELVS = 0- It also uses the flux and derivative:
EVAPO = EVAP + DEVAP*DQS,SHO = SH + DSH*DTS*cp.
- Turbulence Run2 (line 3370) corrects the solution for the surface change. It reads TR and DTG, and updates TRI, FSTAR and DFSTAR.
This is an implicit coupling in which Turbulence and Surface exchange a linearised flux.
Run1 (GEOS_TurbulenceGridComp.F90:5385-5650):
- For each TR field it reads the attributes
DiffuseLike(U, S or Q, which picks the exchange coefficients and diffusivities),FriendlyToTURBULENCEandWeightedTendency. - It gets the pointers S (TR), SOI (TRI), SRG (TRG), SF (FSTAR) and SDF (DFSTAR). Only S must exist.
- If TRG is missing, it allocates a zero-size SG, so the flux is 0.
- It does the tridiagonal solve to get the new value SX, using SG as the lower boundary condition.
- FSTAR:
SF = CX*(SG - SX(LM)). Sea spray (SH_SPRAY, LH_SPRAY) is added for S and Q. SCM options override the flux. - TRI:
SOI = (SX - S)/DT, multiplied byDPif weighted. - DFSTAR:
SDF = CX*(1 - DX(LM)).DXis the diffusion-matrix elimination factor, so this is the sensitivity of the flux to the surface value. - If the field is FRIENDLY,
S = SXis written back in place.
Run2 (lines 6162-6420):
- It does not use TRG. It uses DTG (
DSG) instead. -
SX = S + DKX*DSGat every level.DKXis the per-level sensitivity (DKS,DKQorDKV). - The tendency is incremented:
SOI += DKX*DSG/DT, timesDPif weighted. - The flux is corrected:
SF = SF + DSG*SDF. This is the linearised update of FSTAR and why DFSTAR exists. -
DPDTTRB(LM) = g*SFfor Q. - DTG is also used for the dissipation terms and the SHVC parameterisation.
-
TR is the index. Every other bundle is looked up as
NAME + suffix. The TR field list is built first, and its names are used to build the other five. - TRG and DTG are the surface state (value and increment). FSTAR and DFSTAR are the flux and its slope. TRI is the result.
- The surface state goes into Turbulence, and the flux and its slope go back to Surface. TRG and DTG carry Surface's state to Turbulence, while FSTAR and DFSTAR carry Turbulence's flux and its derivative back to Surface.
- Two-pass coupling. Pass 1 uses TRG, FSTAR and DFSTAR. Pass 2 uses DTG and DFSTAR to correct FSTAR and TRI.
-
Surface-side exports. In Surface,
SHATis an export,THAT,QHAT,UHATandVHATare internal state, andDELxSare exports. Physics treats them uniformly.
- The header comment in the turbulence file (lines 104-112) says TRG and DTG are "Used only by Run2". The code does not match.
- TRG is used only by Run1, at line 5430.
- DTG is used only by Run2, at line 6198.
- The
DiffuseLikedefault isdflt_q, which is Q, not S. The header comment says the default is'S'. - The header says "four attributes" but lists three. The attributes are
FriendlyTo[Comp],WeightedTendencyandDiffuseLike. - For the U and V momentum fields, DTG is always 0 (
DELUS = DELVS = 0). Run2 therefore does not change the U and V solution for a surface-value change, but the flux is still updated through DFSTAR.
Defined in Shared/@MAPL/base/ESMFL_Mod.F90:216-310. It copies named fields from an ESMF State into an ESMF FieldBundle. Fields not in the State become empty placeholders, and fields that need a different name become renamed references to the same data.
Signature: ESMFL_StateGetField(State, FieldName(:), Bundle, [FieldAlias(:)], [RC])
-
Stateis the source. -
FieldName(:)lists the names to look up inState. -
Bundleis the destination (INOUT). -
FieldAlias(:)optionally gives the name each field takes inside the bundle.
-
NameInState = FieldName(I).NameInBundle = FieldAlias(I)if given, otherwise the same name. - Assert that
NameInBundleis not already in the bundle. Otherwise it fails with "found in bundle". -
ESMF_StateGet(itemType=...). If the item is not anESMF_STATEITEM_FIELD(this includes a missing name), setNotInState. Otherwise fetch the Field. - If the field is in the State, call
MAPL_AllocateCoupling(stateField)(Base/Base_Base_implementation.F90:39).- If the field is not
COMPLETE(it has a grid and attributes but no memory), it reads theDIMS,VLOCATION,HALOWIDTH,PRECISION,UNGRIDDED_DIMSandDEFAULT_VALUEattributes. ThenMAPL_FieldAllocCommitallocates the array and fills it with the default value or 0. - This is how a bundle can point at memory for a field the owning component has not yet allocated, for example Surface's import fields behind FSTAR and DFSTAR.
- If the field is not
-
NeedNewField = NotInState .or. (NameInState /= NameInBundle).-
Not in State:
ESMF_FieldEmptyCreate(name=NameInBundle). This field has a name only, with no grid, array or attributes. Its status isEMPTY. -
In State, renamed:
MAPL_FieldCreate(stateField, name=...)callsMAPL_FieldCreateRename(Base_Base_implementation.F90:1206). It usesESMF_FieldCreate(..., datacopyflag=ESMF_DATACOPY_REFERENCE)and thenMAPL_FieldCopyAttributes. The new field has the same grid and the sameESMF_Array(shared memory, not a copy) and keeps the attributes. - In State, same name: the State's own Field object is added directly.
-
Not in State:
-
MAPL_FieldBundleAdd(BUNDLE, bundleField).
| Bundle | Source State | Name in State | Alias in bundle | Result |
|---|---|---|---|---|
| TRI | Physics EXPORT
|
QVIT for Q, otherwise <N>IT
|
<N>IT |
Renamed reference for Q (QVIT becomes QIT). Otherwise the State's own field. |
| TRG | GEX(SURF) |
<N>HAT |
none | The Surface export field itself. |
| DTG | GEX(SURF) |
DELSS, DELUS, DELVS, DELQS
|
<N>DEL |
Renamed reference. |
| FSTAR | GIM(SURF) |
SH, TAUX, TAUY, EVAP
|
<N>FLX |
Renamed reference to Surface's import field. |
| DFSTAR | GIM(SURF) |
DSH, DFU, DFV, DEVAP
|
<N>DFL |
Renamed reference to Surface's import field. |
- A tracer with no matching Surface field, such as
NAME//HATfor an arbitrary friendly tracer, gets anEMPTYfield in the bundle. It counts toward the bundle's field count and name list. - Nothing ever completes these fields.
MAPL_AllocateCouplingwould fail on one, because it lacks theDIMSand other attributes. - A bundle can therefore hold a mix of complete and empty fields. A tracer can be in TR and have empty companions in TRG, DTG, FSTAR or DFSTAR.
- The header comment says the routine fails when adding a dummy field to an empty bundle (no grid to borrow). I did not see that check enforced in the code. It would only fail later, if something used the field.
- All of this runs once, in Physics
Initialize, so the wiring is fixed for the run.
ESMFL_BundleGetPointerByName3 (ESMFL_Mod.F90:741-763) is the helper behind ESMFL_BundleGetPointerToData. It finds the field by name and calls ESMF_FieldGet(status=...). If the status is COMPLETE it returns the data pointer. Otherwise it does NULLIFY(ptr) and returns success. So an empty placeholder becomes a null pointer, with no error. (I read only the rank-3 variant. The rank-2 one very likely does the same.)
Turbulence then checks associated() before use.
Run1 (GEOS_TurbulenceGridComp.F90)
- S (TR):
_ASSERT(associated(S))at 5440. The quantity must exist. - SRG (TRG): if associated,
SG => SRG. Otherwiseallocate(SG(0,0))(5445-5450), meaning zero flux. It is deallocated at 5650. - SF (FSTAR): computed only
if(associated(SF))(5565). - SOI (TRI): written only
if(associated(SOI))(5600). - SDF (DFSTAR): written only
if(associated(SDF))(5646).
Run2
- DSG (DTG): the correction is guarded by
associated(DSG) .and. SCM_SL == 0at 6232, 6296, 6318 and 6413. - SOI increment: needs
associated(SOI) .and. associated(DSG)(6296). - SF update: needs
associated(SF) .and. associated(DSG)(6413).
Notes:
- The empty-field check is split across layers. The helper checks the field status, and Turbulence sees only the resulting null pointer.
- "Zero flux" applies only to the Run1 surface boundary value
SG. ForSF,SOIandSDF, the outputs are simply not produced when the pointer is null. Nothing is set to zero. - Run2 skips the correction entirely when
DSGis missing. - A null
SFfor a real tracer is treated as optional. A mis-spelled tracer or Surface field name would therefore give no flux and no error. I could not tell from the code whether this is intended. - Correction to the Wiring section above: TRI's source is the Physics
EXPORTstate, not Surface. TRG, DTG, FSTAR and DFSTAR come from Surface.
Everything below was added after the original analysis. Nothing in Part 1 was changed.
- Only the rank-3
ESMFL_BundleGetPointerByName3was read. The rank-2 variant has not been confirmed to nullify empty fields. - A misspelled tracer or Surface field name gives a null
SFand no error. Whether this is intended is unknown. - Header comment mismatches in
GEOS_TurbulenceGridComp.F90lines 104-145: TRG is Run1-only (not "Used only by Run2"); theDiffuseLikedefault isdflt_q; "four attributes" lists three. - The header says adding a dummy field to an empty bundle fails. This is not enforced in the code.
All six are declared with DATATYPE = MAPL_BundleItem.
| Bundle | Spec | Dims |
|---|---|---|
| TR | Import, 562-571 | HorzVert, center |
| TRG | Import, 574-581 | HorzOnly |
| DTG | Import, 585-592 | HorzOnly |
| TRI | Export, 1130-1137 | HorzVert |
| FSTAR | Export, 1140-1147 | HorzOnly |
| DFSTAR | Export, 1150-1157 | HorzOnly |
Local declarations: line 2928 (TR); 5244-5248 (Run1); 5798-5802 (Run2).
Iteration and access:
- 3120-3122:
ESMF_StateGet(IMPORT,'TR')thenFieldBundleGet(TR, fieldCOUNT=NTR). Only the count is used, for the aerosol PBL calculation. - Run1: TR and TRG fetched at 5323-5324; TRI, FSTAR, DFSTAR at 5343-5345. 5362 counts TR into
KM. 5368-5377 assert TRI, TRG, FSTAR, DFSTAR have the same countKM. 5395 is the by-indexFieldBundleGet(TR, K, FIELD)loop. 5426-5434 useESMFL_BundleGetPointerToDataby name (NAME,NAME//'IT','HAT','FLX','DFL'). - Run2: 5969-5974 get the bundles; 5979 and 5985 count TR and DTG; 6083 is the SHVC "S first" index get; 6162 is the main index get; 6194-6202 use
NAME//'DEL'for DTG.
Attributes read per TR field with ESMF_AttributeGet:
-
DiffuseLike: Run1 5404 (defaultdflt_q), Run2 6171 (defaultdflt_Q). -
FriendlyToTURBULENCE: Run1 5411, Run2 6178. Default false. -
WeightedTendency: Run1 5418, Run2 6185. Default false.
Extra header mismatch: the comment around 5226-5232 says WeightedTendency defaults to true, but the code defaults it to false.
Only Turbulence reads these attributes. The only other reference is GCHP-only, @geos-chem/Interfaces/GCHP/Chem_GridCompMod.F90:2055-2064, which checks that a field is not also friendly to TURBULENCE.
-
TR (2203):
ESMF_StateGet(GIM(TURBL),'TR').-
SwithDiffuseLike="S",WeightedTendency=.TRUE.(2210-2214). -
U,VwithDiffuseLike="U"(2219-2228). - Turbulence exports
TKESHOCandQT2withDiffuseLike="Q"(2231-2242).QT3is commented out. -
MAPL_GridCompGetFriendlies(GC,"TURBULENCE",BUNDLE)for Physics' ownQW(2253), then for Moist (2256) and Chem (2259). - Names are printed (2262-2270), then count and
NAMESlist are taken (2276-2285).NAMESdrives all other bundles.
-
-
TRI (2293-2307): from Physics
EXPORT,Qmapped toQVIT, alias<N>IT. -
TRG (2316-2324):
GEX(SURF),<N>HAT. -
DTG (2333-2354):
GEX(SURF),DELSS/DELUS/DELVS/DELQSfor S/U/V/Q, else the tracer name; alias<N>DEL. -
FSTAR (2363-2384):
GIM(SURF),SH/TAUX/TAUY/EVAP, else the name; alias<N>FLX. -
DFSTAR (2393-2414):
GIM(SURF),DSH/DFU/DFV/DEVAP, else the name; alias<N>DFL. -
Disconnected imports:
MAPL_TerminateImporton SURF importsSH, TAUX, TAUY, EVAP, DEWL, FRSL, DSH, DFU, DFV, DEVAP, DDEWL, DFRSL(1898-1906), and on TurbulenceTR,TRG,DTG(1942-1946). -
Run-time access: line 3174, with SYNCTQ on, Physics Run does
ESMF_StateGet(GIM(TURBL),'TR')andBundleGetPointerToData('S')to overwriteS.
FRIENDLYTO in an internal spec sets the FriendlyToTURBULENCE field attribute (MAPL_Generic.F90:6888-6915).
-
Physics:
QW,FRIENDLYTO='TURBULENCE:MOIST'(line 208). -
Turbulence:
TKH,FRIENDLYTO='TURBULENCE'(GEOS_TurbulenceGridComp.F90:2404). It is not in TR. -
Moist: all microphysics interfaces (GFDL_1M, BACM_1M, MGB2_2M, NSSL_2M, THOM_1M) set
QVtoDYNAMICS:TURBULENCE:CHEMISTRY:ANALYSIS, andQLLS, QLCN, QILS, QICNtoDYNAMICS:TURBULENCE. Depending on scheme alsoQRAIN, QSNOW, QGRAUPELandNCPL, NCPI, NRAIN, NSNOW, NGRAUPEL. SeeGEOS_GFDL_1M_InterfaceMod.F90:88-97andGEOS_MGB2_2M_InterfaceMod.F90:117-143.CLLS,CLCNare DYNAMICS-only.GEOS_GF_InterfaceMod.F90:68-70CNV_TRis not TURBULENCE. -
Chem: GOCART2G (DU, SS, SU, NI, CA, all
DYNAMICS:TURBULENCE:MOIST), MAM, ACHEM (ACHEM_GridCompMod.F90:627-716), CARMA (CARMAchem_GridCompMod.F90:231), PChem (GEOS_PChemGridComp.F90:412-474), StratChem. - GWD: none. Surface: none (self-friendly only); Surface is a data source for TRG, DTG, FSTAR and DFSTAR.
No component other than Turbulence consumes these six bundles. Unrelated friendly bundles: TRADV (Dynamics), TRANA (Analysis), MTR, MTRI, H2ORTRI, MCHEMTRI (Moist, 2425-2520), FriendlyToMOIST (Process_Library.F90:376-398).
-
MAPL_AddConnectivity(MAPL_Generic.F90:305-310): Rename (5104-5129, scalarSRC_NAME/SRC_ID/DST_NAME/DST_ID), RenameMany (5135-5158), Many (5165-5189, arraySHORT_NAME; no scalar form). Storage inVarConn.F90:37-80. -
MAPL_AddConnectivityE2E(5075-5095) is commented out of the generic interface (306); used byMAPL_StateAddExportSpecFrmChldName(3670-3692). - Wiring is
MAPL_WireComponent(~7060-7330). Sibling export to import:varIsConnectedat 7212 and 7234. Renames are supported. If specs match it does a directMAPL_Reconnect, otherwise it needs the same precision and builds a coupler. - Bundles are one VarSpec, so connections are bundle-to-bundle. Code that would skip friendly bundles is
#if 0'd out (7188-7192). - Export to export: child exports are promoted to the parent when a connection targets
import=MAPL_Self(7119-7154), matching by child short name, so renames are not applied in that pass.MAPL_AddExportSpec(..., CHILD_ID=...)is the usual route (e.g.GEOS_PhysicsGridComp.F90:1405-1425). - No connection from a component's export to its own import (
I==Jskipped). - Import to import: unsatisfied child imports are promoted to the parent under the same name, with no rename.
MAPL_TerminateImportandDoNotConnect(5194-5249;MAPL_AnyChildImportat 7165) block this. -
MAPL_GenericConnCheck(8352-8420, called at 746) fails if any connection or do-not-connect entry was never used. - Ungridded dims:
UNGRIDDED_DIMS,UNGRIDDED_NAME/UNIT/COORDSon Import/Export/Internal specs (3308-3326, 3500-3523, 3833-3861); attributes set at 6858-6866; fields are rank 4. GOCART2G uses them (DU2G_GridCompMod.F90:245,SS2G_GridCompMod.F90:169,OH_GridCompMod.F90:615).MAPL_GridCompGetFriendliessplits rank-4 fields into per-bin 3D fields (8130-8165;Base_Base_implementation.F90:3191).
TR is built at Initialize from GetFriendlies over Moist, Chem and Physics. NTR and KM come from FieldCount at run time (3122, 5362, 5979).
- Always present:
S, U, V, TKESHOC, QT2(hard-coded, 2205-2242) andQW. - Moist: about 7 base fields, plus 3 precipitation species (GFDL_1M) or up to 8 more (MGB2_2M). Depends on the runtime scheme.
- Chem: depends on enabled providers and runtime
nbins. - No fixed total was found.
Goal: eliminate all ESMF_FieldBundles for these six items and use plain ESMF_Fields with connections like other items. Added constraint: Physics must not access its children's states. Assumed: bit-for-bit results, Turbulence-only scope, other friendly bundles (TRADV, MTR and so on) left alone.
-
A. Static per-tracer specs. Rejected. Turbulence
SetServicescannot know the tracer names, which Moist and Chem fix only in their ownSetServices. -
B. Per-tracer specs plus
MAPL_AddConnectivity. Chosen, because it is the only option that satisfies the constraint. Physics collects names after the Moist and ChemSetServices, passes them to a late Turbulence registration, and wires by name. -
C. Fortran arrays of fields in an internal-state type. Least invasive and keeps bit-for-bit, but Physics
Initializestill callsESMFL_StateGetFieldonGEX(SURF),GIM(SURF),GIM(TURBL)andEXPORT. Rejected because it breaks the constraint. - D. One rank-4 ungridded field per role. Static specs, but per-tracer attributes need side arrays, friendlies are already split on collection, and copying loses zero-copy sharing. Not pursued.
-
Turbulence (
GEOS_TurbulenceGridComp.F90):- Remove the six bundle specs (562-592, 1130-1160).
-
SetServicestakes a tracer table (name,DiffuseLike,WeightedTendency,Friendly,HasSurface). Per tracer, imports<N>, plus<N>HATand<N>DELifHasSurface; exports<N>IT, plus<N>FLXand<N>DFLifHasSurface. - Run1 and Run2 (5395, 6083, 6162) and line 3122 loop over the table, not over bundles or
ESMF_AttributeGet. - Optional fields are omitted from the spec set rather than EMPTY. Use an explicit has-flag rather than relying on null pointers, because an unconnected import is allocated, not null. This is the bit-for-bit risk.
-
Physics (
GEOS_PhysicsGridComp.F90):- Call the Moist and Chem
SetServicesfirst, then collect names withMAPL_GridCompGetFriendlies(gridcomp handles, not states). Pass the list to Turbulence by gridcomp attribute, config resource or a newMAPL_MethodAddhook. - Wire with
MAPL_AddConnectivity: TRG<N>HATfrom Surface; DTGDELSS, DELUS, DELVS, DELQStoSDEL, UDEL, VDEL, QDEL; TRI viaAddExportSpecwithCHILD_IDincludingQVITtoQIT; FSTAR and DFSTAR as normal Turbulence-export to Surface-import connections (SH, TAUX, TAUY, EVAP, DSH, DFU, DFV, DEVAP). - Delete the
ESMFL_StateGetFieldblocks (2293-2414) and theTerminateImportcalls (1898-1906, 1942-1946).
- Call the Moist and Chem
-
Surface:
SHATandDELxSare already exports and its flux imports stay. No spec changes beyond the connectivity.
-
FSTAR and DFSTAR direction: a Turbulence export to a Surface import is a normal sibling connection, so this is fine and lets the Surface-side
TerminateImportgo. -
Friendly tracers are internal fields, not exports.
MAPL_AddConnectivityonly goes export to import. Decision: export the tracers (below). -
Same-component connection:
TKESHOCandQT2are Turbulence's own exports feeding its own TR. MAPL skipsI==J, so Turbulence must read its own export memory directly.QW,S,U,Vcome in as Physics imports through normal connectivity. -
In-place update:
S = SX(friendly write-back) and the SYNCTQ overwrite at 3174 need writable shared memory. A reconnected import shares the owner's memory, so it works, and Physics reachesSthrough its own import. -
MAPL_GenericConnCheck: every connection must be consumed, so connected names must match Turbulence's registered specs per scheme and bin count. - Spec ordering: registering Turbulence late changes MAPL setup order. Check the export promotion (7119-7154) and the other friendly bundles for order dependence.
- Each Moist and Chem component adds a normal export spec for every tracer whose
FriendlyTocontainsTURBULENCE, sharing memory with the internal field. A copy would break the in-place write-back. Whether MAPL supports an export aliased to an internal field is unverified. If not, the export would be pointer-assigned in the component'sInitializeorRun. - Scope: Moist (GFDL_1M, BACM_1M, MGB2_2M, NSSL_2M, THOM_1M) and Chem (GOCART2G bins, MAM, ACHEM, CARMA, StratChem, PChem). The Moist and Chem wrappers must promote their children's exports with
CHILD_ID. GOCART bins are 4D ungridded, so they need a 4D export that Turbulence splits, or per-bin exports. - Physics needs a name registry exposed through the gridcomp handle (attribute or config), not states.
- Scale: touches every Moist microphysics scheme and every Chem provider. This is the largest part.
- Memory aliasing is the main technical risk for bit-for-bit.
-
Double ownership: Dynamics and Analysis still read the same tracers as friendlies. The export must not change their
FRIENDLYTObehaviour. -
GCHP:
Chem_GridCompMod.F90:2055-2064has its own friendly handling and needs the same treatment or an exclusion.
- Prototype one tracer (
QVfrom GFDL_1M) exported, connected and read by Turbulence, and confirm the export aliases internal memory. Compare bit-for-bit. - Add the tracer table and spec loop to Turbulence and convert Run1 and Run2.
- Move the Physics wiring to
SetServiceswithAddConnectivity. - Roll out the exports to the other Moist and Chem components.
- Remove the bundle code and the
TerminateImportcalls, then run and compare against baseline.
Status: analysis only. No source files were modified.
Constraint: Physics must not access its children's states. This is a sketch from the survey findings. None of the MAPL behaviour below has been tested.
Make each bundle belong to one component, and let MAPL share it across components with ordinary connectivity. Today Physics reaches into GIM(TURBL), GEX(SURF), GIM(SURF) and EXPORT to fill the bundles. Instead, each component fills a bundle in its own state.
A bundle is a single VarSpec, so MAPL can already connect bundles (MAPL_WireComponent, ~7060-7330 in MAPL_Generic.F90):
- Sibling export to import: a direct reconnect when the specs match. The importer then holds the same bundle object.
- Unsatisfied child import: promoted to the parent import under the same name.
| Bundle | Owner fills it in its own state | Link |
|---|---|---|
| TR | Physics. It puts S, U, V (its own imports), QW (its own internal) and the Moist and Chem friendlies into a Physics-level TR bundle. |
Physics declares an import bundle TR. Turbulence's TR import is promoted to it by same-name import-to-import. |
| TRG, DTG | Surface. It exports one bundle of its own SHAT, UHAT, VHAT, QHAT fields, and one for DELSS, DELUS, DELVS, DELQS. Fields are keyed by tracer name (S, U, V, Q). |
AddConnectivity from Surface's export bundle to Turbulence's import bundle. |
| FSTAR, DFSTAR | Surface. It declares import bundles and adds its own SH, TAUX, TAUY, EVAP, DSH and so on, keyed by tracer name. |
AddConnectivity from Turbulence's export bundle to Surface's import bundle. |
| TRI | Physics. It declares a bundle of its own export fields <N>IT. |
Same as TR, via import-to-import. This means flipping TRI to an import in Turbulence, or a child-export promotion plus aliasing in Physics. |
-
Physics: touches only its own state, plus
MAPL_GridCompGetFriendlies(GCS(MOIST|CHEM))for names. That is a MAPL API call, not opening a child state. -
Surface: adds fields to its own bundles. It needs no tracer list, because only
S,U,V,Qhave surface fields. -
Turbulence: lookup changes from
NAME//'HAT'toNAMEinside a dedicated bundle. The<N>HAT/DEL/FLX/DFL/ITsuffix scheme goes away. Run1 and Run2 change a few lines each.
- No per-tracer specs, no late Turbulence registration, no changes to Moist or Chem. The tracer list stays dynamic and the friendly-tracer problem disappears.
- No export-to-same-component problem.
- Bundles keep zero-copy field sharing, so bit-for-bit should hold.
-
Bundle sharing: confirm the reconnect shares the bundle object rather than building a coupler that copies. The
#if 0'd code at 7188-7192 suggests friendly-bundle handling here is fragile. -
Initialize ordering: fields must be added before anything reads them.
GEOS_TurbulenceGridComp.F90:3122reads theTRcount, so check whether it runs in Initialize or Run. -
Missing fields: a tracer absent from
TRGmeans "not in the bundle", not an EMPTY placeholder.ESMFL_BundleGetPointerToDatamust return null for a missing name, or callers need an existence check. -
Required imports: Physics' new import bundles get promoted to the Agcm level unless handled. They need
MAPL_TerminateImportor a not-required flag, andMAPL_GenericConnCheckmust still pass. -
TRI direction: Turbulence exports TRI today. Making it an import that Physics fills with its own export fields must not break the
WeightedTendencywrite path. - Spec equality: the bundle specs on both sides must match, or MAPL inserts a coupler.
Much smaller than exporting the tracers. It touches Physics, Turbulence and Surface only, and nothing in Moist or Chem. Items 1 and 3 decide whether it works and can be checked read-only.
These are code readings of the MAPL, ESMF and GEOS source. Nothing was run. Paths are shortened to Generic (MAPL/generic/MAPL_Generic.F90), VarSpec (generic/VarSpec.F90), ESMFL (base/ESMFL_Mod.F90), Phys (GEOS_PhysicsGridComp.F90) and Turb (GEOS_TurbulenceGridComp.F90).
| # | Question | Result |
|---|---|---|
| 1 | Does bundle connection share the object? | Yes |
| 2 | When is the TR count at Turb:3122 read? |
Fine |
| 3 | What happens for a name that is not in the bundle? | Error, not null. Needs a fix. |
| 4 | What happens to an unsatisfied import bundle in Physics? | Manageable |
| 5 | Can TRI become an import? | Yes |
| 6 | Do the specs have to match? | Yes, DIMS and VLOCATION |
- The skip for friendly bundles at
Generic:7188-7192is inside#if 0, so bundle imports go through normal wiring. - If
EX_SPECS(N) == IM_SPECS(K)(Generic:7251), MAPL callsMAPL_Reconnect, with no coupler. The SHORT_NAME is temporarily swapped so names match (Generic:7244-7250). - The coupler branch (
Generic:7262-7270) runs only when the specs differ.GenericCplComp.F90has no bundle handling, andMAPL_SetVarSpecForCCskips bundle items (Generic:8315). Avoid this branch. -
MAPL_Reconnect(Generic:7684-7724) only callsMAPL_LinkCreate. The sharing happens at the root's SetServices (Generic:740-815), which copies FIELDPTR, BUNDLEPTR and STATEPTR from the lowest-label spec (Generic:808-813).MAPL_VarSpecSetBundlePtr(VarSpec:753-766) setsSPEC%SPECPtr%BUNDLE => BUNDLEPTR. Both specs then point at oneESMF_FieldBundle. -
MAPL_StateCreateFromSpecNew(Generic:6595-6618) creates the bundle if it does not exist yet, otherwise reuses the handle, then adds it to its own state. Whichever component initializes first creates it. A side effect: theRESTARTattribute is overwritten by whichever component creates its state last (Generic:6613). - Fields added after wiring are visible to both sides, because
ESMF_FieldBundleis a pointer to a shared container (ESMFESMF_FieldBundle.cppF90:108-114).MAPL_FieldBundleAdd(Base_Base_implementation.F90:2469-2525) also updates the sharedMAPL_BundleItemOrderListattribute. Caveat: this was read from ESMF source found at/home/mathomp4/ESMF_Crash, which may not be the build GEOS links. - Import-to-import promotion shares the same spec:
MAPL_VarSpecAddRefToList(StateSpecification.F90:501-) storesSPECPtr => ITEM%SPECPtr, called atGeneric:7285, withMAPL_Reconnecton duplicates (Generic:7292-7301). The parent creates its import state after the children initialize (Generic:1123,1126), so it reuses the child's bundle. A duplicate name with a non-equal spec is a hard failure (VarSpec:1540-1555). - Precedent:
AERO_DPis a Chem export bundle (GEOS_ChemGridComp.F90:473-478) connected atPhys:1683-1688to a Surface import (GEOS_SurfaceGridComp.F90:645-651), HorzOnly on both.
- It sits in the contained routine
REFRESH(Turb:2854-5207) insideRUN1(Turb:2522-5660), called atTurb:2823only when the refresh alarm rings. It is not in Initialize. Turbulence has no custom Initialize (Turb:60,266-268). - Physics Initialize calls
MAPL_GenericInitializeatPhys:2168, which initializes the children first. The bundle fill code runs afterwards (Phys:2203-2420), so Run sees filled bundles.
-
ESMFL_BundleGetPointerToData(ByName2andByName3,ESMFL:717-763) callsESMF_FieldBundleGet(BUNDLE, NAME, FIELD=...)then_VERIFY(STATUS). - Null is returned only when the field exists but is not
COMPLETE, i.e. an EMPTY placeholder (created byESMFL_StateGetField,ESMFL:272-286). - A name that is not in the bundle should give a non-success rc from ESMF's container lookup (
ESMF_FieldBundle.cppF90:2073-2078). I did not read the C++ container. - Callers
VERIFY_after each call (Run1Turb:5426-5435, Run2Turb:6194-6203), so a missing name makes Run1 and Run2 fail. - Count asserts: Run1 requires TRI, TRG, FSTAR and DFSTAR counts to equal TR's (
Turb:5368-5380,_ASSERT(KM==K)), and Run2 checks the DTG count (Turb:5985-5989). Only TR must be non-null (Turb:5439). - Consequence for Part 4: a bundle holding only S, U, V and Q needs an existence check before each lookup, and the count asserts must be relaxed.
- An import that no sibling provides and that is not do-not-connect is promoted to the parent (
Generic:7279-7289), repeating at each level up to the root. - Each state creates an empty bundle from the spec (
Generic:6595-6604). - At the root, ExtData fills only what is in its rc file. For anything else it logs "ExtData could not satisfy import" and continues (
ExtDataGridCompMod.F90:~771-773;MAPL_CapGridComp.F90:~690-712). - There is no REQUIRED attribute in
Generic.MAPL_AddImportSpecdefaultsRESTARTtoMAPL_RestartOptional(Generic:3366). Imports are only read from a restart ifIMPORT_RESTART_FILE:is set (Generic:1565-1573). -
MAPL_GenericConnCheck(Generic:8352-8420) only checks for unused CONNECT or DO_NOT_CONNECT entries. It does not check that imports are satisfied, but aTerminateImportnaming something that does not exist would fail it. - Existing pattern: Physics calls
MAPL_TerminateImport(SHORT_NAME=['TR','TRG','DTG'], CHILD=TURBL)(Phys:1941-1945) and does the same for MoistMTR(Phys:1970-1973). That adds a do-not-connect entry (Generic:5197-5217), setsPARENTIMPV=.false.(Generic:7197-7203), and stops promotion. - Rule: if Physics fills the bundle itself, add a
TerminateImport. Otherwise the spec propagates to the root and sits empty. - Not determinable from code: whether the real driver or ExtData configuration treats a stray empty root import differently.
- TRI is a Turbulence export today (
Turb:1130-1137). Turbulence writes through pointers into field data (SOI = ...atTurb:5600-5605,6296-6303,6386-6390), not withMAPL_FieldBundleAdd. - Physics Initialize adds the fields (
Phys:2293-2306) usingESMFL_StateGetField(EXPORT, ...), so each bundle field shares the array of the Physics export. A name missing from the export state gets an EMPTY field and a null pointer. It asserts the name is not already in the bundle (ESMFL:~243), so it must run once. - MAPL has no write protection on imports. Physics already writes into the Turbulence
TRimport viaESMFL_BundleGetPointerToData(BUNDLE,'S',SFORTURB)andSFORTURB = SAFMOIST(Phys:3174-3178). -
WeightedTendencyis a per-field ESMF attribute (Turb:5418,6185) that only decides whetherDPis applied when writingSOI. It is independent of direction.
-
MAPL_VarSpecEQ(VarSpec:1373-1401) comparesSHORT_NAME,DIMS,LOCATION,HALOWIDTH,PRECISION, andACCMLT_INTERVALandCOUPLE_INTERVALif both are non-zero. - It ignores LONG_NAME, UNITS, FIELD_TYPE, STAT (where
MAPL_BundleItemlives, under#if 0), RESTART and direction. - Import vs export direction does not matter, and the names match because wiring swaps them first.
- DIMS and VLOCATION must match. A mismatch (HorzVert vs HorzOnly, or Center vs None) makes
==false, which leads to the coupler branch that has no bundle support (item 1).MAPL_VarSpecSamePrecis also asserted there (Generic:7263). - For TR and TRI style bundles, both sides should use
DIMS=MAPL_DimsHorzVert, VLOCATION=MAPL_VLocationCenter(Turb:563-570,1130-1137). - The same
==applies when a child import is promoted to a parent that already has that name. A mismatch is a hard failure (VarSpec:1540-1555).
- The Part 4 verdict still holds: no changes to Moist or Chem, and the bundles keep sharing memory.
- New requirement: a "field exists" check in Turbulence before each lookup, plus relaxed count asserts, if a bundle holds only S, U, V and Q.
- Physics import bundles that Physics fills need a
TerminateImport. - Both ends of each link must use identical DIMS and VLOCATION.
- Still unverified: the ESMF shallow-copy behaviour on the real build, the C++ container error return for a missing name, and the driver or ExtData handling of stray root imports.