GECC files have three sections:
GEOPEN3()
(if necessary, depending
upon decisions that need to be made (below))
to open or create GECC files, GEDESC3()
to retrieve a
file's geometric specification, and various utility methods to
perform other geometry-related tasks. Existing I/O API
routines READ3()
, WRITE3()
,
INTERP3()
, and DDTVAR3()
would be
extended for GECC-file data access, storage, and retrieval. The
resulting API will be callable from at least Fortran 77 and 90, C,
and C++. GECC-files offer direct support for polygon-based data
such as is found in emissions (e.g., area sources) and in
GIS-related coverages, without biasing the representation by
artificial triangulation or reticulation, and without the extra
storage overhead which would also ensue.
One aspect that deserves attention is dealing with the existing built-in I/O API layer structure: unless this is over-ridden, the geometry will automatically have a layer structure given by the built-in layer structure. One could argue that it would be simpler to ignore the 3-dimensional-cell description aspect and use purely the layer structure to extend the geometry to the vertical dimension. This would be sufficient for the vast majority of GIS-related geospatial data applications; however, it would fail to support data with irregular or only partially-layered vertical structures (like ocean models or irregular three-dimensional geological structures for ground water modeling) which would be significant at a later date. The recommendation is to do the fully three-dimensional cell-complex geometry descriptions and to support the I/O API layer structure, with the interpretation that when the number of layers is nontrivial and the number of higher-dimensional cells is zero (no 3-cells, etc.), then the generic I/O API layer structure is responsible for the vertical structure (giving "prismic geometry" for which all horizontal cross-sections are identical as a result). This would be useful, for example, for emissions point-source plume rise for which there is a vertical structure, but only at the vertices (there being no edges, faces, nor 3-cells). The one ambiguous interpretation problem is dealing with the case of a fully three-dimensional cell complex that also has a nontrivial vertical layer structure. Options are to:
All edges, faces, and cells are oriented, as is required to do line, surface, and volume integrals (and to make the relationships among them correct -- Green's, Stokes', Gauss' Theorems, etc.). This orientedness shows up in the boundary relations:
<starting-node,ending-node>
of nodes.
There are additional geometric-utility routines that might be desirable, including routines for at least the following tasks:
PARMS3.EXT
and parms3.h
:
GEODAT3
as a file type, to indicate a GECC-file.
GESKEL0
to indicate inGDESC3.EXT
(etc., below) that the corresponding variable in GECC-file lives on the 0-skeleton of the GECC.
GESKEL1
to indicate that the corresponding variable in GECC-file lives on the 1-skeleton of the GECC.
GESKEL2
to indicate that the corresponding variable in GECC-file lives on the 2-skeleton of the GECC.
GESKEL3
to indicate that the corresponding variable in GECC-file lives on the 3-skeleton of the GECC.
GDESC3
either in include file
FDESC3.EXT
or in new
include file
GDESC3.EXT
(tbd, below), and new
typedef
IOAPI_GDesc3
and its memory-layout-compatible definition as a
struct in
iodecl3.h
. Fields in this
COMMON or struct include
One reason this should be in a new COMMON is to ensure that bad attempts at configuration, with incompatible INCLUDE-files and/or libraries, will either fail to compile or fail to link, instead of having obscure and difficult-to-debug run-time failures.NVERT3D
the number of elements in the 0-skeleton (the set of nodes/vertices).
NEDGE3D
the number of elements in the set of edges
NFACE3D
the number of elements in the set of faces
NCELL3D
the number of elements in the set of cells
N2BDY3D
the number of nonzero entries in the (sparse) faces::edges boundary relation.
N3BDY3D
the number of nonzero entries in the (sparse) cells::faces boundary relation.
VSKEL3D(MXVARS3)
Token valueGESKEL[0-3]
to indicate which skeleton each variable lives on.
VSTEP3D(MXVARS3)
Token value 0 orTSTEP3D
to indicate that a variable is time independent or time stepped. See (below).
NEDGES, NFACES, NCELLS, N2BDY,
and
N3BDY
are the numbers of edges, faces,
cells, size of the sparse face::edge boundary relation,
and size of the cell::face boundary relation,
respectively) :
EDGEBDY(2,NEDGES)
is anINTEGER
array containing the vertex subscripts for the starting and ending nodes of each edge. Note that in this case there are always exactly two boundary vertices for each edge.
FACEDEX(NFACES)
is anINTEGER
array containing the number of boundary-edges for each face.
FACEBDY(N2BDY)
is anINTEGER
array containing the plus or minus the edge subscripts (according to whether the edge occurs with positive orientation or negative orientation within the boundary) for the boundary-edges of the faces, in serialized consecutive order:FACEBDY(1:FACEDEX(1))
contains the boundary edges for the first face,FACEBDY(FACEDEX(1)+1:FACEDEX(1)+FACEDEX(2))
the boundary edges for the second face, etc.
CELLDEX(NCELLS)
has the same role for the cell::face boundary relation thatFACEDEX
does for the face::edge boundary relation.
CELLBDY(N3BDY)
has the same role for the cell::face boundary relation thatFACEBDY
does for the face::edge boundary relation.
GEOPEN3()
and
geopen3c()
are the
Fortran and routines used instead of
OPEN3()
to open/create
GECC-files. It has extra arguments for the boundary
relations (and possibly for the node-position variables,
depending upon decisions described
below).
COMMON GDESC3
or the extra
IOAPI_GDesc3
-pointer argument
must be correctly filled in, if the mode of opening is
"new", "unknown", or "truncate"
and thus may require file creation or consistency
checking.
NOTE: For GEODAT3 files which
already exist, one may also use
OPEN3()
or
open3c()
to open them
in modes FSREAD3, FSRDWR3.
Fortran and C Usages:
LOGICAL FUNCTION GEOPEN3( FNAME, & EDGEBDY, & FACEDEX, FACEBDY, & CELLDEX, CELLBDY, & FSTATUS, PGNAME ) CHARACTER*(*) FNAME INTEGER EDGEBDY( 2, NEDGE3D ) INTEGER FACEDEX( NFACE3D ) INTEGER FACEBDY( N2BDY3D ) INTEGER CELLDEX( NCELL3D ) INTEGER CELLBDY( N3BDY3D ) INTEGER FSTATUS ! FSREAD3, FSRDWR3, FSUNKN3, etc. CHARACTER*(*) PGNAME ... int geopen3c( const char * FNAME, const IOAPI_Bdesc3 * bdesc , const IOAPI_Cdesc3 * cdesc , const IOAPI_GEdesc3 * gdesc , const int EDGEBDY[][2], const int FACEDEX[], const int FACEBDY[], const int CELLDEX[], const int CELLBDY[], int STATUS, const char * PNAME ) ;
GEDESC3()
and
gedesc3c()
return
as arguments sparse-matrix arrays containing the boundary
relations (and possibly the node-positions, depending
upon decisions described below)
for the geometry from the file header. It is the
responsibility of the caller to allocate these arrays
before the call.
Fortran and C Usages:
LOGICAL FUNCTION GEDESC3( FNAME, & EDGEBDY, & FACEDEX, FACEBDY, & CELLDEX, CELLBDY ) CHARACTER*(*) FNAME INTEGER EDGEBDY( 2, NEDGE3D ) INTEGER FACEDEX( NFACE3D ) INTEGER FACEBDY( N2BDY3D ) INTEGER CELLDEX( NCELL3D ) INTEGER CELLBDY( N3BDY3D ) ... int gedesc3c( const char * FNAME, int EDGEBDY[][2], int FACEDEX[], int FACEBDY[], int CELLDEX[], int CELLBDY[] ) ;
DESC3()
fills in the
COMMONs in both FDESC3.EXT
and GDESC3.EXT
.
There is an issue here about the C routine
desc3c()
, because this
would need both FDESC-pointer and GDESC3-pointer
arguments, changing the routine's signature...
this probably means that we need an extra C routine
for the GECC-file description-task
;-(
GEDESC3
COMMON into the existing
FDESC3.EXT
include-file, or not?
My inclination is to say that it should be put
into the same INCLUDE file, simplifying the API
for the modelers that use it, particularly since
it is used for exactly the same purpose, and in the
same OPEN3()
and DESC3()
calls as that file.
(Almost certainly this would cause extra netCDF fill-overhead and probably break the internal paradigm of some of our visualization tools; just the choice of "this is time independent" versus "this uses the file's time step" on a variable-by-variable basis would be relatively clean to implement and use, would not incur extra netCDF overhead, and not break vis tools.)
GEOPEN3()
call?
I favor the choice of allowing individual variables to be either time-stepped with the file-specified time step, or time-independent: this deals cleanly with the situation of cleanly allowing 2-dimensional GECCs to require only two node-position variables, whereas 3-dimensional GECCs need three. It also cleanly handles the question: "What are the units for the node position variables". At the same time, it allows both easy implementation and additional flexibility which may prove useful to support additional time-independent attributes of GECCs.
Time-independent topology where only the (node) positions change, but the sets of nodes, faces, edges, and cells, and the boundary relations among them are time-independent. For this case,INTERP3()
make sense as an I/O API call. This choice can be implemented by simply allowing the node-position variables to be either time-stepped or time independent, as the user selects at file-creation time.Time-dependent topology in which the entire geometry can change from time step to time step (and for which the modeler reading data must first make a geometry inquiry, then allocate appropriate buffers, and finally read data into them. The write-operation also requires a separate call, for which both the geometry and the data are arguments. Note that
INTERP3()
does not make sense as an I/O API call in this case, because there is no topology on which to define it.I recommend that we not implement this option at first; if we later decide that it is necessary, then we should implement it as an additional and different file type (Time Stepped Cell Complex, or TSCC files?), using similar data structures and employing the lessons learned with the time-independent topology GECC files.
Examples of these might include routines to compute:
PARMS3.EXT
and
parms3.h
:
new parameters
GEODAT3
: new file type token
parameter "geospatial-element cell
complex"
GESKEL0
: new
description-token parameter"variable
lives on the 0-skeleton in a GEODAT3-file"
GESKEL1
: new
description-token parameter"variable
lives on the 1-skeleton in a GEODAT3-file"
GESKEL2
: new
description-token parameter"variable
lives on the 2-skeleton in a GEODAT3-file"
GESKEL3
: new
description-token parameter"variable
lives on the 3-skeleton in a GEODAT3-file"
FDESC3.EXT
and
fdesc3.h
:: new
COMMON GDESC3
with data structures to
use describing/defining GEODAT3-files:
NVERT3D
: number of vertices
in the geomety of the cell complex.
NEDGE3D
: number of edges
in the geomety of the cell complex.
NFACE3D
: number of faces
in the geomety of the cell complex.
NCELL3D
: number of 3-cells
in the geomety of the cell complex.
N2BDY3D
: number of elements
in the face::edge boundary relation of the cell
complex.
N3BDY3D
: number of elements
in the cell::face boundary relation of the cell
complex.
VSKEL3D( MXVARS3 )
: skeleton
on which each variable "lives":
values are token parameters GESKEL[0-3]
VSTEP3D( MXVARS3 )
:
per-variable time step. Should be either
zero or TSTEP3D
.
typedef struct{...} IOAPI_GEdesc3
to
provide a data structure definition to use for
GEODAT3 geometry for use by C programs.
IODECL3.EXT
and
iodecl3.h
: new
public I/O API routines declared:
GEDESC3()
GEOPEN3()
STATE3.EXT
: new
COMMON GSTATE3
with data structures to
use accessing/managing GEODAT3-files:
NVERT( MXFILE3 )
: number of vertices
in the geomety of the cell complex.
NEDGE( MXFILE3 )
: number of edges
in the geomety of the cell complex.
NFACE( MXFILE3 )
: number of faces
in the geomety of the cell complex.
NCELL( MXFILE3 )
: number of 3-cells
in the geomety of the cell complex.
N2BDY( MXFILE3 )
: number of elements
in the face::edge boundary relation of the cell
complex.
N3BDY( MXFILE3 )
: number of elements
in the cell::face boundary relation of the cell
complex.
VSKEL( MXVARS3, MXFILE3 )
: skeleton
on which each variable "lives":
values are token parameters GESKEL[0-3]
VSTEP( MXVARS3, MXFILE3 )
:
per-variable time step. Should be either
zero or TSTEP3D
.
GINDX( 5, MXFILE3 )
:
netCDF ID's for the private variables
used to implement the boundary relations.
The following Fortran routines are affected:
DDTVAR3
: support
for GEODAT3 file operation.
DESC3
: support for
GEODAT geometry descriptions.
INIT3
: changes in
internal state-variable initializations.
INTERP3
: support
for GEODAT3 file operation.
READ3
: support
for GEODAT3 file operation.
WRITE3
: support
for GEODAT3 file operation.
CHECK3
: support
for GEODAT3 file operation.
CRTFIL3
INTERP3V
OPNFIL3
OPNKF
RDBUF3
UPDTVIR3
WRBUF3
WRGEODAT
RDGEODAT
The following C bindings are affected:
geopen3c()
:
C wrapper around public Fortran GEOPEN3(), used to open
files of type GEODAT3.
gedesc3c()
:
C wrapper around public Fortran GEDESC3() used to return
GECC geometry specification (boundary relations, etc.) for
files of type GEODAT3.
desc3c()
: desc3c()
, thus breaking existing C code that
depends upon it? Otherwise, we need to invent a new
routine that does this task specifically for GEODAT3
files.
Others?
: The entire
remainder of the C bindings should be unaffected, by
virtue of properly modular design and implementation.
Extensions of existing analysis and visualization tools:
GECC-related geometric utility routines:
STATUS::
!! TBD -- open issue !!
GECC-related geometric tool/support programs:
STATUS::
!! TBD -- open issue !!