MAPL State Filter - GEOS-ESM/MAPL GitHub Wiki

Introduction

Starting with MAPL v2.56.0 a new procedure is available StateFilterItem.

The basic idea is that the user can provide

  1. An ESMF State
  2. An ESMF config
  3. an item name which is a field in the state.

It returns an allocatable array that has been evaluated according to a rule provided in the config. The rule is evaluated using the same expression syntax available in ExtData (and History).

API

This is Fortran subroutine with the following API which is overloaded for 2D and 3D R4 Fields.

   interface StateFilterItem
      procedure StateFilter_R4_2D
      procedure StateFilter_R4_3D
   end interface

   subroutine StateFilter_R4_2D(state, config, itemName, array, rc)
      type(ESMF_State), intent(inout) :: state
      type(ESMF_Config), intent(inout) :: config
      character(len=*), intent(in) :: itemName
      real(REAL32), allocatable, intent(out) :: array(:,:)
      integer, optional, intent(out) :: rc

   subroutine StateFilter_R4_3D(state, config, itemName, array, rc)
      type(ESMF_State), intent(inout) :: state
      type(ESMF_Config), intent(inout) :: config
      character(len=*), intent(in) :: itemName
      real(REAL32), allocatable, intent(out) :: array(:,:,:)
      integer, optional, intent(out) :: rc

Rules

The procedure looks inside the provided Config for a key/value pair for the itemName with the following syntax

FILTER.itemName: rule

For example, suppose you had the following rule:

Filter.foo: @+bar

This says, take field foo from the state and add field bar, add them element-wise, and return the result in a Fortran allocatable array.

Or consider this example:

Filter.foo: @*2

This says take field foo from the state, multiple each element by 2 and returns the result in a Fortran allocatable array.

Or consider this example:

Filter.foo: "regionmask(@,region_mask;2,5)"

This says take field foo from the state, take field region_mask from the state and mask each element out of foo where region_mask is not 2 or 5. Return the result in a Fortran allocatable. Array.

Notice in all the examples the @ in the rule is replaced with the itemName.

Finally if no rule for an itemName is found there are 2 options.

You can provide a default like so

Filter.@: rule

It will use the rule for any field.

If no default is found, it just returns the contents of the field named itemName in an allocatable Fortran array.

Using StateFilterItem with the ACG (Automatic Code Generator)

  1. Add a column called FILTER to the column names in your spec file.
  2. For any row for which you want to use the FILTER feature, put true.
  3. For the other rows, make sure to leave the FILTER column blank (spaces between the | symbols).
  4. Make sure that you have declared a config called CF in the scope (procedure) where the "declare pointer" and "get pointers" files are included.

If you look at the include files the ACG generates, you will notice the declarations for filtered variables are allocatable arrays and the procedure calls to get the variables are different. That's what it should be.

Here is an example of a spec file:

schema_version: 2.0.0
component: ACG
category: IMPORT

#----------------------------------------------------------------------
 NAME | UNITS | DIMS | VLOC | FILTER | CONDITION | LONG_NAME

#----------------------------------------------------------------------
 ZLE  | m     | z    | E    | TRUE   | 1>0       | geopotential_height
 T    | K     | xy   | N    | TRUE   |           | air_temperature
 PLE  | Pa    | xyz  | E    |        |           | air_pressure

In the row starting PLE, the FILTER column is empty. For that row, ACG will generate the standard code to declare and get the pointer. In the other two rows, the FILTER column has TRUE. For those rows, the declarations and procedures to get the variables will take on the new form to support filtering.