University of Colorado
ESMP is the original prototype Python interface to ESMF regridding. ESMP was developed to be very similar to the ESMF Fortran interface, with the intention that it would ease the transition one to the other. The project has developed to the point where a more Pythonic interface is desired, with the same functionality offered in ESMP, this is called ESMPy.
You can get tarballs of the ESMP software, along with the appropriate ESMF version on the Download and Releases page (there are two tables, one for each).
You need Python 2.6 or higher, with ctypes and numpy. You also need a current ESMF installation, the 5.3.0 release is a good place to start. ESMP has been tested on Linux, Macintosh, and Cray systems with the GNU compilers. There is more information on ESMP dependencies and limitations in the documentation. There is more information on how to build an ESMF installation in the ESMF user's guide.
Certainly, see the tutorials.
You can get help with ESMP through the same channels as with ESMF, just write to firstname.lastname@example.org.
The ESMP_REGRIDMETHOD_CONSERVE option to ESMP_FieldRegridStore() requires that the Fields be built on the ELEMENTS of a Mesh and the center stagger location of a Grid. This is accomplished by passing 'meshloc=ESMP_MESHLOC_ELEMENT' to ESMP_FieldCreate() in the Mesh case and 'staggerloc=ESMP_STAGGERLOC_CENTER' in the Grid case. The Grid coordinates in this case need to be set on the corner stagger location, even though the Fields are built on the center stagger location.
In the case where the grids don't completely overlap (don't share the same domain) you need to use the fraction fields when computing the mass on either grid, or when computing the adjusted interpolated field values (pseudocode below). This is also an issue when masking is involved, regardless of the grid domain overlap.
This means that you need to divide the interpolated field values by the corresponding destination fractions (obtained from the ESMP_FieldRegridStore() call) at each point. Also, when computing the mass, multiply each field value by the corresponding fraction as well as the area.
for i in range(source_field.size):
source_mass = source_field[i] * source_area[i] * source_fraction[i]
for i in range(destination_field.size):
if (destination_fraction != 0):
destination_field_adjusted[i] = destination_field[i] / destination_fraction[i]
destination_mass = destination_field_adjusted[i] * destination_area[i] * destination_fraction[i]
# or you can use the non adjusted field without the fraction field
#destination_mass = destination_field[i] * destination_area[i]
The coordinates of a Grid are set by obtaining a pointer to the raw buffer data and setting the values in this buffer. The buffer is returned in column major order, as would be the case in Fortran. The pseudocode below shows how to set Grid coordinates in more detail:
[x,y] = [1,2]
gridXCorner = ESMP.ESMP_GridGetCoordPtr(grid, x, ESMP.ESMP_STAGGERLOC_CORNER)
gridYCorner = ESMP.ESMP_GridGetCoordPtr(grid, y, ESMP.ESMP_STAGGERLOC_CORNER)
p = 0
for i1 in range(exLB_corner, exUB_corner):
for i0 in range(exLB_corner, exUB_corner):
gridXCorner[p] = float(i0)*cellwidth_x + lb_x
gridYCorner[p] = float(i1)*cellwidth_y + lb_y
p = p + 1
The area of the cells of a Grid or Mesh can be retrieved and set. Areas are always retrieved with the ESMP_FieldRegridGetArea() call, which takes a Field built on the Grid or Mesh as the only argument. The area of Grid cells is set to user defined values with the ESMP_GridAddItem() and ESMP_GridGetItem() calls using the optional argument 'item=ESMP_GRIDITEM_AREA'. The Python array that is returned from this call can then be initialized to the desired area data. Mesh areas are set by specifying the Numpy array optional argument 'elementArea' to the ESMP_MeshAddElements() call.
Yes, interfaces which contain optional arguments require that keywords be used to identify the individual arguments if all optional arguments are not specified.
Interfaces with multiple return values provide several options for accessing the return data. The data is returned as a tuple, which can be accessed with standard Python tuple syntax. All of the following function calls will work in this situation:
return1, return2 = MultipleReturnValuesFunction()
_, return2 = MultipleReturnValuesFunction()
return1 = MultipleReturnValuesFunction()
Yes, the bounds of a periodic Grid, i.e. a Grid created with ESMP_GridCreate1PeriDim(), are adjusted so that the first dimension of the Grid has one less index than it would in the non-periodic case.
The 1-based (Fortran style) indexing has been gradually phased out of ESMP. As of ESMF_5_3_1_beta_snashot_02_ESMP_01 there is no longer ANY 1-based indexing, ESMP now uses completely 0-based (C style) indexing. The following list provides the snapshot at which certain pieces of ESMP functionality changed from 1- to 0-based indexing:
ESMF_5_3_1_beta_snapshot_02_ESMP_01 - 'coordDim' in ESMP_GridGetCoordPtr() specifies the dimension of the coordinates to be retrieved.
ESMF_5_3_0_beta_snapshot_42_ESMP_01 - 'elementConn' variable in ESMP_MeshAddElements() containing the indices of the locations in the nodeId array which hold the node IDs of the nodes that make up the connectivity of that element.
ESMF_5_3_0_beta_snapshot_37_ESMP_02 - return values for the ESMP_GridGetCoord() function specify the bounds of the Grid coordinates.