Feb 22, 2016 - IMPORTANT NOTE: To make the proposal a more formal standard, the content of this page has been migrated to GitHub, please follow this link.
The documentation below is no longer updated.
--------- snapshot Feb 22, 2016 ---------
Following the successful discussion that we had a few year's ago on conventions for storing unstructured grid data in netCDF files which eventually led to the UGRID conventions, I would like to propose a simple convention for documenting staggered data on structured grids that is consistent with the UGRID conventions. My proposal, which I will refer to as SGRID convention, is described below.
The link http://bit.ly/sgrid_cf points to this page.
The CF-conventions are widely used for storing and distributing environmental / earth sciences / climate data. The CF-conventions use a data perspective: every data value points to the latitude and longitude at which that value has been defined; the combination of latitude and longitude bounds and cell methods attributes can be used to define spatially averaged rather than point values. This is all great for the distribution of (interpolated) data for general visualization and spatial data processing, but it doesn't capture the relationship of the variables as computed by a numerical model (such as Arakawa staggering). Many models use staggered grids (using finite differences, or finite volume approach) or use a finite element approach of which the correct meaning may not be captured easily by simple cell methods descriptors. This becomes a problem if you don't want to just look at the big picture of the model results, but also at the details at the grid resolution e.g. what is the exact meaning of a flux on the output file in discrete terms? Can we verify the mass balance? Can the data be used for restarting the model? Correctly handling the staggered data has always been a crucial element of the Delft3D post-processing tools. In the UGRID conventions, we have defined the (unstructured) grid as a separate entity on the file which consists of nodes and connections of nodes defining edges, faces, and volumes. For a structured (staggered) grid we are currently lacking a consistent convention. Although one could store structured grid data using UGRID conventions, some fundamental aspects such as distinction between grid directions would be lost. In this context I propose the lightweight SGRID conventions to define the core aspects of a structured staggered grid without trying to capture the details of finite element formulations. This proposal serves merely the purpose of getting the conventions for structured grids on par with those for unstructured grids.
Consistent with the UGRID conventions we use the following terms for points, lines, and cells that make up a grid.
A point, a coordinate pair or triplet: the most basic element of the topology (also known as "vertex").
A line or curve bounded by two nodes.
A plane or surface enclosed by a set of edges. In a Cartesian 2D model, you might refer to this as a "cell" or "square".
A volume enclosed by a set of faces.
In the UGRID conventions the focus is on describing the topology of the mesh (connectivity of the nodes, edges, faces, and volumes as appropriate). The topology of a structured grid is inherently defined; the focus for the SGRID conventions is therefore on the numbering used. Still we need to distinguish between 2D and 3D grids (1D conventions may be defined consistently).
Required topology attributes
face_dimension1:node_dimension1 (padding:type1) face_dimension2:node_dimension2 (padding:type2)
|edge1_dimensions||node_dimension1 face_dimension2:node_dimension2 (padding:type2)|
|edge2_dimensions||face_dimension1:node_dimension1 (padding:type1) node_dimension2|
where the padding type may be one of the four literal strings: "none", "low", "high", or "both" depending on whether the face_dimension is one shorter than the corresponding node_dimension (padding:none), one longer than the corresponding node_dimension (padding:both), or of equal length with one extra value stored on the low or high end of the dimension (see the figure below). The edge1_dimensions and edge2_dimensions attributes may be used to define separate dimensions for the edges (see the ROMS example below), but by default the edge dimensions are assumed to be consistent with the dimensions used by the edges and faces respectively. The optional vertical_dimensions attribute may be used to specify the names of the dimensions for the layers and layer interfaces respectively using the same syntax: layer_dimension:layer_interface_dimension (padding:type).
- The numbering of the edges corresponds to the order of the dimensions in the dimensions attributes. The order of the dimensions listed here does not change since these are specified as a string. The actual order of dimensions in the netCDF API (and hence in the dump generated by different tools) depends on the programming language used. Hence, the order of the dimensions listed here may differ from the order of the dimensions in the data definition.
Figure 1: illustrating the formulations used for expressing the relationship between face/edge and node dimensions. Please note that the numbering of the faces and nodes can be adjusted using face(face) and node(node) coordinate variables.
Required topology attributes
node_dimension1 node_dimension2 node_dimension3
face_dimension1:node_dimension1 (padding:type1) face_dimension2:node_dimension2 (padding:type2) face_dimension3:node_dimension3 (padding:type3)
|edge1_dimensions||face_dimension1:node_dimension1 (padding:type1) node_dimension2 node_dimension3|
|edge2_dimensions||node_dimension1 face_dimension2:node_dimension2 (padding:type2) node_dimension3|
|edge3_dimensions||node_dimension1 node_dimension2 face_dimension3:node_dimension3 (padding:type3)|
|face1_dimensions||node_dimension1 face_dimension2:node_dimension2 (padding:type2) face_dimension3:node_dimension3 (padding:type3)|
|face2_dimensions||face_dimension1:node_dimension1 (padding:type1) node_dimension2 face_dimension3:node_dimension3 (padding:type3)|
|face3_dimensions||face_dimension1:node_dimension1 (padding:type1) face_dimension2:node_dimension2 (padding:type2) node_dimension3|
|edge <i> _coordinates|
|face <i> _coordinates|
- The edge1, edge2, and edge3 are in a 3D grid aligned to the dimensions1, 2, and 3 respectively, whereas the edge1 and edge2 are in a 2D grid perpendicular to the dimensions 1 and 2 respectively. The face1, face2, and face3 play that role in the 3D grid.
- The 3d grid option should not be used be used for layered grids, such as typical ocean and atmosphere models. Use the 2d grid with vertical dimensions instead. This allows 2D quantities (such as surface quantities) and 3D quantities to be linked to the same mesh.
The use of the attributes to associate a data variable with a specific grid and stagger location is copied from the UGRID conventions: To map the variable onto the topology of the underlying grid, two new attributes have been introduced. First, the attribute
grid points to the grid_topology variable containing the meta-data attributes of the grid on which the variable has been defined. Second, the attribute
location points to the (stagger) location within the grid at which the variable is defined.
Delft3D uses an Arikawa C-grid with the water level (pressure) computed in the cell centres, and the normal velocities at the cell edges. This example shows the use of asymmetric padding (at the low end of the horizontal coordinate indices there is an extra line of face/mid-point values). In the vertical there is no padding, so the number of layer interfaces is one more than the number of layers. The integer coodinate variables KMAX and KMAX1 are used to indicate that layer interfaces are numbered 0 to KMAX whereas all other indices use the default numbering from 1 to the maximum value.
The edge_dimension attributes are not needed.
ROMS uses also a C-grid, but it uses on the output file different dimensions for each staggered location. In this case we need all attributes defined above including the edge <i> _dimension attributes..
WRF (ARW version)
The WRF-ARW also uses a C-grid. Again the model results can best be captured by a 2D grid.
It might be interesting to verify the result for WRF-NMM since that model uses an E-grid, but I couldn't find an example file.