GEOS-ESM / MAPL

MAPL is a foundation layer of the GEOS architecture, whose original purpose is to supplement the Earth System Modeling Framework (ESMF)
https://geos-esm.github.io/MAPL/
Apache License 2.0
25 stars 18 forks source link

MAPL3 Time Accumulation/Coupling #3027

Open darianboggs opened 2 months ago

darianboggs commented 2 months ago

MAPL3 needs a module to accumulate field values in time for totals (accumulation), means (time averaging), and evaluations of functions like max and min as well as writing the results to destination fields (coupling).

In MAPL2, GenericCplComp performs these functions, but it initializes from a list of VarSpec's, not ESMF_Field's. In MAPL3, it will initialize on ESMF_Field's, and it will work on grid comps.

So, the module will integrate into the MAPL3 architecture.

darianboggs commented 2 months ago

Notes from discussion with Tom Clune

(11 Sept 2024):

this%accumulated = this%accumulated + f_in
this%counts = this%counts + where(f_in/= undef)
f_out = this%accumulated

A: E  t0 t1
B: I     t1
A:E --> B:I (accumuluation)
C

A run step 0
A clock advance
B clock advance
C clock advance  (accumulate E)

A run step 1
B run step 1
  - update imports
  - run couplers
  - C::run()     (accumulate E)
A clock advance
B clock advance
C clock advance
  - if (final step) clear accumulation
  - else accumulate E.
tclune commented 2 months ago

Minor clarification. initialize() is a specific phase and is as described above. But the Action subclass will still have a constructor and that could in principle have specs (not VarSpecs) as its inputs. I don't think it should though. My naive initial thought is that the constructor would have something like (dt_src, dt_dst, option) where option controls accum vs max vs min vs avg ...

tclune commented 2 months ago

Somehow @darianboggs reposted the original sketch rather than the updated one. I have no deleted that to avoid confusion. Sept 12 notes are shown here:

      A run step 0
        - run user method (modify E)
        - invalidate exports
        - C invalidate  (accumulate E(t=0))

      A run step 1
        - run user method (modify E)
        - invalidate exports
        - C invalidate  (accumulate E(t=1))
      B run step 1
        - update imports
        - C::run()     (use method to put result in field)
                   - total   (accum -> f_out)
               - average (accum/count -> f_out)
               - min     (accum -> f_out)
               - max     (accum -> f_out)
               And then reset
               - average (accum = 0; count = 0)
               - min     (accum = UNDEF; count = 0)
               - max     (accum = UNDEF; count = 0)

        - run user method (use I)

subroutine accum_min(f_in, accum)
   1. f_in & accum are undef
      do nothing
   2. f_in has value accum is undef
      accum = f_in
   3. f_in is undef, accum has value
      do nothing
   4. both are good
      accum = min(accum, f_in)

   where (f_in /= UNDEF)
      where (accum /= UNDEF)
         accum = min(accum, f_in)
      elsewhere
         accum = f_in
      end
   end

end subroutine
darianboggs commented 1 month ago

Need to reconcile different time steps and offsets for source and destination components

tclune commented 1 month ago

Need to reconcile different time steps and offsets for source and destination components

The issue is even broader than that. "We" need to figure out how (if?) we control the offset for components that do not run on the heartbeat. In MAPL2 I think there is an implicit assumption that at 0z all components run, and maybe that is good enough.

darianboggs commented 1 month ago

The "heartbeat" expresses an offset $\sigma_A$ and period $\tau_A$ for component/field $C_A$ / $F_A$) in terms of the fundamental timestep $\tau$. Different components (in this case single-field).

darianboggs commented 1 month ago

We want to accomodate (eventually) various cases of the heartbeats for the source, destination, and accumulation.

tclune commented 1 month ago

I think we reserve the term "heartbeat" for the model as a whole. For the other components we just refer to their timestep. @bena-nasa please correct my terminology if I'm off.

darianboggs commented 1 month ago

Update:

Given a source field S, destination field D, and coupler C:

  1. C has a field in it's internal state of the same typekind as S.
  2. the internal field of C is updated in the invalidate step of S. The update is an addition of the current value of the source field or evaluation of the min or max functions on the source field and internal field.
  3. the couple operation is performed on the internal field of C at the update step of D. The couple operation consists of any additional calculations on the internal field, exporting the internal field, "clearing" the internal field, and clearing the counters.