.. DRAFT .. DRAFT ..

Status : First Draft


Hopefully, this can evolve into an agreed final form by the time of the next UGRID release. Contirbutions are welcome.

Conformance rules for UGRID Conventions v1.x

This information is intended to follow the practice established by the CF conformance pages, as attached to the CF conventions.

In that spirit, this is likewise “intended to be a concise summary” of the main convention, and “if there are any discrepancies … the conventions document is the ultimate authority.”

Each reference statement is provided with a short code : “Rxxx” for requirements and “Axxx” for advisory recommendations, in the manner of the Flake8 error and warning codes, and the PyCodeStyle ones.
Future editions will maintain these reference numbers, but possibly add new ones. They can be used as definitive references by a conformance-checker utility. 10

This version is consistent with :


Preamble : Terms and Definitions

  • A mesh variable is a variable with a cf_role attribute of "mesh_topology". 2
  • A varlist is a string attribute consisting of a space-separated list of variable names
    • these must be names of variables existing in the same dataset : this is implicit in all uses
  • A coordinate attribute of a mesh is a varlist with one of the following names 2 4
    • node_coordinates
    • edge_coordinates
    • face_coordinates
  • A connectivity attribute of a mesh is a varlist with one of the following names 2 4
    • edge_node_connectivity
    • face_node_connectivity
    • face_edge_connectivity
    • edge_face_connectivity
    • face_face_connectivity
    • boundary_node_connectivity
  • A mesh coordinate is a variable listed in a coordinate attribute of a mesh
  • A mesh connectivity is a variable listed in a connectivity attribute of a mesh 2
  • A mesh is the parent mesh of those mesh coordinates or mesh connectivities which are included in any of its coordinate or connectivity attributes : This defines the “parent mesh” of any mesh coordinate or mesh connectivity. 1
  • The parent mesh of a location index set is that named in its mesh attribute
  • the element dimensions of a mesh are those indexing its elements (i.e. nodes, edges or faces), or mesh boundaries, within any of its mesh coordinates and mesh connectivities.
    • the node dimension is the single dimension of the node coordinates (should all be the same)
    • if there is an edge_node_connectivity, then there is an edge dimension (see below for how this is determined)
    • if there is a face_node_connectivity, then there is a face dimension (see below for how this is determined)
    • if there is a boundary_node_connectivity, then there is a boundary dimension (see below for how this is determined)
  • the element dimension of a mesh connectivity or mesh coordinate is that one of its dimensions which is an element dimension of its parent mesh. N.B. there can only be one : see R201 / R304
  • A location index set is a variable with a cf_role attribute of "location_index_set" 2
  • A mesh data variable is a CF data variable with either a mesh or a location_index_set attribute.

Mesh variables

Mesh variable requirements

For any mesh variable ..

  • R101 it must have a cf_role attribute,
    • R102 with the value "mesh_topology"
  • R103 it must have a topology_dimension attribute,
    • R104 whose value is an integer between 0 and 2. 4 5
  • all mesh connectivity and coordinate attributes must be varlists, that is ..
    • R105 they are strings consisting of space-separated, valid netcdf variable names, and
    • R106 the variables named all exist in the dataset
  • R107 all mesh connectivity attributes must contain a single variable name
  • R108 all elements of all mesh coordinate attributes must be valid mesh coordinates
  • R109 all mesh connectivity attributes must be valid mesh connectivities
  • R110 it must have a node_coordinates attribute
  • an edge_node_connectivity attribute ..
    • R111 must not be present, if topology_dimension is 0. 5
    • R112 must be present, if topology_dimension is 1.
  • R113 a face_node_connectivity attribute must be present if and only if topology_dimension is 2
  • R114 a boundary_node_connectivity attribute may be present, only if topology_dimension is 2 6
  • if the mesh has an edge_node_connectivity, then it has an edge dimension, which
    • either is given by the edge_dimension attribute, if there is one, in which case
      • R115 edge_dimension must be the name of a dataset dimension
    • or, if there is no edge_dimension attribute, the edge dimension is the first dimension of the edge_node_connectivity
    • when an edge dimension exists ..
      • R116 if any edge connectivity has the edge dimension as its second dimension, (instead of its first), then the mesh must have an edge_dimension attribute
  • if the mesh has a face_node_connectivity, then it has a face dimension, which ..
    • either is given by the face_dimension attribute, if there is one, in which case
      • R117 face_dimension must be the name of a dataset dimension
    • or, if there is no face_dimension attribute, the edge dimension is the first dimension of the face_node_connectivity
    • when a face dimension exists ..
      • R118 if any face connectivity has the face dimension as its second dimension, (instead of its first), then the mesh must have a face_dimension attribute
  • if the mesh has a boundary_node_connectivity, then it has a boundary dimension, which is the first dimension of the boundary_node_connectivity variable 7
  • R119 a face_face_connectivity attribute may only exist if the mesh has a face dimension
  • R120 a face_edge_connectivity attribute may only exist if the mesh has both a face dimension and an edge dimension
  • R121 an edge_face_connectivity attribute may only exist if the mesh has both a face dimension and an edge dimension
  • R122 a face_dimension attribute may only exist if the mesh has a face dimension
  • R123 an edge_dimension attribute may only exist if the mesh has an edge dimension

Mesh variable recommendations

  • A101 it should have no dimensions
  • A102 it should not have a standard_name attribute
  • A103 it should not have a units attribute
  • A104 it should not share any of its element dimensions with other meshes 11
  • A105 if it has multiple element dimensions, they should all be different
  • A106 it should not have any attributes ending in “_connectivity”, “_coordinates” or “_dimension” which are not valid UGRID terms 12

Mesh coordinate variables

For any mesh coordinate variable ..

Mesh coordinate variable requirements

  • R201 it must map a single dimension
    • R202 which is the appropriate element dimension of the parent mesh
  • R203 any bounds attribute must refer to a suitable CF bounds variable matching its own properties and dimensions

Mesh coordinate variable recommendations

  • A201 it should have one and only one parent mesh 1
  • A202 it should have a floating-point data type
  • A203 it should have a standard_name attribute which is a valid CF standard-name
    (see : CF conformance section 3.3)
  • A204 it should have a units attribute which is a valid CF unit
    (see CF conformance section 3.1)
  • if it has a bounds attribute, then
    • A205 the data values of the bounds variable should match those calculated from the relevant UGRID element coordinates and connectivities 8
  • A206 if its location is ‘node’, then it should not have a bounds attribute.

Mesh connectivity variables

Mesh connectivity variable requirements

For any mesh connectivity variable ..

  • R301 it must have a cf_role attribute, which
    • R302 is a valid connectivity attribute name, and
    • R303 matches its referring connectivity attribute in the parent mesh
  • R304 it must exactly have two dimensions, of which
    • R305 one is an element dimension of its parent mesh, and
    • R306 the other is not an element dimension
  • R307 its element dimension must be that of the first location named in its cf_role 13
  • R308 if it has a cf_role 13 of edge_node_connectivity or boundary_node_connectivity, then its non-element dimension must have length 2
  • R309 any start_index attribute must have one of the values (0, 1).
  • R310 if it has a cf_role of edge_node_connectivity or boundary_node_connectivity, then it must not contain any ‘missing’ indices
  • R311 if it has a cf_role of face_node_connectivity, then each face index must contain at least 3 non-‘missing’ indices

Mesh connectivity variable recommendations

  • A301 it should have one and only one parent mesh 1
  • A302 it should have an integer type
  • A303 any start_index attribute should have an integer type
  • A304 if it has a cf_role of edge_node_connectivity or boundary_node_connectivity, then it should not have a _FillValue attribute
  • A305 if it contains any “missing” indices, then it should have a _FillValue attribute :
    I.E. it does not rely on a netcdf “default fill-value”
  • if there is a _FillValue attribute, then
    • A306 it should have the same type as the connectivity variable itself, and
    • A307 it should have a negative value
  • A308 all its non-missing values should be valid indices into the relevant dimension of the parent mesh, i.e. the second location named in the cf_role 3 8.

Location index set variables

For any location index set variable ..

Location index set variable requirements

  • R401 it must have a cf_role attribute with the value "location_index_set"
  • R402 it must have a mesh attribute, which is a string containing the name of a valid mesh variable in the dataset
  • R403 it must have a location attribute, which is one of face, edge or node, and
    • R404 the corresponding location must exist in the parent mesh
  • R405 it must have a single dimension
  • R406 any start_index attribute must have one of the values (0, 1).

Location index set variable recommendations

  • A401 it should have an integer type
  • A402 it should not contain any missing points
  • A403 it should not have a _FillValue attribute
  • A404 the length of its single dimension should be less than or equal to the corresponding element dimension of its parent mesh
  • A405 its values should all be distinct, and
    • A406 they should all be valid indexes into the relevant element dimension of its parent mesh 3 8
  • A407 any start_index attribute should have an integer type

Mesh data variables

Mesh data variable requirements

  • if there is a mesh attribute
    • R501 there must be no location_index_set attribute
    • R502 the mesh must be the name of a valid mesh variable in the dataset
    • R503 there must be a location attribute,
      • R504 which is one of face, edge or node, and
      • R505 the corresponding dimension must exist in the parent mesh
  • if there is a location_index_set attribute
    • R506 there must be no mesh attribute
    • R507 there must be no location attribute
    • R508 the location_index_set must name a valid location index set variable in the dataset
  • its dimensions ..
    • R509 must contain one and only one mesh element dimension, which
    • R510 is the appropriate element dimension of its mesh and location, as given by it’s own mesh and location properties, or by those of its location_index_set

Other

Other recommendations

  • A901 all dataset contents (dimension, variables and their attributes) should also be CF compliant – see: CF conventions.
  • A902 there should be a global Conventions attribute,
    • A903 which contains a string section of the form UGRID-<X.Y>, where “<X.Y>” is an appropriate release version of the UGRID conventions. 9
  • A904 no netcdf variable should have a cf_role equal to any of the values defined here, unless it is one of the UGRID variable types defined here to use one
    – i.e. a mesh, location index set or connectivity variable
  • A905 no dataset variable should have a cf_role which is not either one of the valid terms described here, or one of the CF-defined cf_role values 14

  1. From the given definitions, any mesh connectivity or -coordinate must logically have a parent mesh. We intend that it should always have exactly and only one. 

  2. for correctness testing (only), we may broaden the definitions of these items in order to detect some obvious errors. For example, we will attempt to check as a mesh variable any variable that either has a cf_role of mesh_topology or is named in the mesh attribute of a data variable or location index set variable. 

  3. “valid” element indices are values within the range of the corresponding element dimension of the parent mesh, allowing for any start_index offset. 

  4. For now at least, we exclude mention of full-3d meshes, whose status is currently in question : cf. this GitHub discussion, as this would add considerable complexity here. 

  5. For now, we allow 0-d meshes (those with nodes only). Though, this is not explicitly mentioned in the UGRID v1.0 pages. 

  6. It is not supported to have boundaries in a 1-D mesh (I.E. one with only edges), though this is not logically impossible. If a specific need arises, this could change in future. 

  7. Since there is no provision for a boundary_dimension attribute, the boundary dimension is always the first dimension of a boundary_node_connectivity, and its second dimension must always be 2 (i.e. it cannot be transposed). If a specific need arises, this could change in future. 

  8. Requirements on values of variables may not always be practical to check, since this requires loading all of their data. 

  9. The form of the global Conventions attribute is determined by the CF conformance pages, section 2.6.1. However, the definition of UGRID release numbers is not yet finalised. 

  10. Providing stable statement references allows conformance statements to evolve without invalidating earlier versions of a checker program. We also provide a linkable web anchor for each one. 

  11. if a mesh does not share any element dimensions with other meshes, it follows that it also will not share any element coordinates or connectivities with other meshes. 

  12. invalid ‘lookalike’ attributes, which are not defined by UGRID, include such as : “node_face_connectivity”, “boundary_coordinates”, “boundary_dimension” or “node_dimension”. 

  13. for checking purposes, the identity of a connectivity is actually defined by the referring attribute in the parent mesh. However, if the connectivity is correctly formed, then its cf_role value will always be the same as this – cf:R303

  14. in the present latest CF version the only cf_role terms defined are the discrete-geometry types : timeseries_id, profile_id and trajectory_id