This is the native binary format of DisPerSE. Functions for reading and writing NDnet format in C can be found within the file ${DISPERSE_SRC}/src/C/NDnetwork.c
(see functions Load_NDnetwork and Save_NDnetwork). The format may seem relatively complex, but most of it is actually optional and not used in disperse (only simplicial complexes are used in DisPerSE). To create DisPerSE input files, it is only necessary to define the highest dimensional n-simplices as a list of (n+1) vertices (see also function CreateNetwork).
Note: The scalar function whose MS-complex is computed by mse can be stored as an additional data field
named 'field_value' (case sensitive).
Warning: in the following, for legacy reasons, the terms n-face and n-cell are used indifferently to designate polygons of dimension n (which are always simplexes in DisPerSE).
When using the C functions from Disperse, data is loaded into the following C structure which is close to the actual structure of the file (see file ${DISPERSE_SRC}/src/C/NDnetwork.h
):
typedef struct { int type; // the cell-type char name[255]; // name of the field double *data; // value for each of the nfaces[n] n-cells } NDnetwork_Data;
// NDnetwork_SupData is not used in disperse ... typedef struct { int type; char name[255]; int datasize; char datatype[255];// a string to identity how data should be casted void *data; } NDnetwork_SupData;
typedef struct { char comment[80]; int periodicity; int ndims; // the number of spatial dimensions int ndims_net; // number of dimension of the network itself (e.g. 2 for a sphere embedded in 3D) int isSimpComplex; // 1 if network is a simplicial complex (always true in disperse) double *x0; // origin of the bounding box double *delta; // size of the bounding box int indexSize; // size of NDNET_UINT type in Bytes int cumIndexSize; // size of NDNET_IDCUMT type in Bytes char dummy[160-4*2]; // dummy data reserved for future extensions NDNET_UINT nvertex; // total number of vertices float *v_coord; //vertices coodinates (X_0,Y_0,Z_0,X_1,Y_1,...,Z_nvertex-1) NDNET_UINT *nfaces; // number of cells of a given type t is given by nfaces[t] int *haveVertexFromFace; // haveVertexFromFace[n] is 1 if we have an explicit definition of the n-cells (at least one type of cell must be defined). NDNET_IDCUMT **f_numVertexIndexCum;// cumulative number of vertice in the t-cells, NULL when cells are simplexes (isSimpComplex=1) NDNET_UINT **f_vertexIndex; // list of vertices defining the n-cells is stored in f_vertexIndex[n], all vertices being enumerated for each cell (the indices of the vertices in the kth n-cell start at f_vertexIndex[n][(n+1)*k] ) // see also macro NUM_VERTEX_IN_FACE(net,type,face) and VERTEX_IN_FACE(net,type,face) //This may be computed internally within DisPerSE but does not need to be defined explicitely int *haveFaceFromVertex; // haveFaceFromVertex[n] is 1 if we have an explicit list of all the n-cells that contain each vertex (used to navigate within the network) NDNET_IDCUMT **v_numFaceIndexCum; // cumulative number of t-cells a vertex v belongs to NDNET_UINT **v_faceIndex; // indices of the t-cells in the co-boundary of v ( the list of n-cells of vertex k starts at v_faceIndex[n][net->v_numFaceIndexCum[n][k]] and ends at v_faceIndex[n][net->v_numFaceIndexCum[n][k+1]] ) // see also macro NUM_FACE_IN_VERTEX(net,type,vertex) and FACE_IN_VERTEX(net,type,vertex) // This can become extremely memory heavy ... NOT used in DisPerSE int **haveFaceFromFace; // haveFaceFromFace[k][n] is 1 if we have an explicit list of all the n-cells that have a boundary/co-boundary relation with each k-cell (used to navigate within the network) NDNET_IDCUMT ***f_numFaceIndexCum; // cumulative number of n-cells having a boundary / co-boundary relation with each k-cell: f_numFaceIndexCum[k][n] NDNET_UINT ***f_faceIndex; // indices of the cells (similar to v_faceIndex) // see also macro NUM_FACE_IN_FACE(net,ref_type,ref_face,type) and FACE_IN_FACE(net,ref_type,ref_face,type) int haveVFlags; // do we have flags associated to each vertex ? int *haveFFlags; // do we have flags associated to each n-cell ? unsigned char *v_flag; // nvertex flag values (1 for each vertex) or NULL unsigned char **f_flag; // nfaces[n] flag values (1 of each n-cell) or NULL int ndata; // number of additional data fields. NDnetwork_Data *data; // array of all additionnal data (data in total) int nsupData; NDnetwork_SupData *supData; } NDnetwork;
The NDnet binary format is organized as follows (blocks are delimited by dummy variables indicating the size of the blocks for FORTRAN compatibility, but they are ignored in C):
field | type | size | comment |
dummy | int(4B) | 1 | for FORTRAN compatibility |
tag | char(1B) | 16 | identifies the file type. Value : "NDNETWORK" |
dummy | int(4B) | 1 | |
dummy | int(4B) | 1 | |
ndims | int(4B) | 1 | number of dimensions of the embedding space |
ndims_net | int(4B) | 1 | ndims spanned by the network (=ndims by default) |
dummy | int(4B) | 1 | |
dummy | int(4B) | 1 | |
comment | char(1B) | 80 | a comment on the file (string) |
periodicity | int(4B) | 1 | 0=non periodic, if p^th bit is set, boundary are periodic along dimension p |
isSimpComplex | int(4B) | 1 | 1 if network is made of simplices (must be 1 for DisPerSE) |
x0 | double(8B) | ndims | origin of bounding box |
delta | double(8B) | ndims | size of bounding box |
index_size | int(4B) | 1 | size of NDNET_UINT integer format in Bytes |
cumindex_size | int(4B) | 1 | size of NDNET_IDCUMT integer format in Bytes |
dummy_ext | char(1B) | 152 | dummy data reserved for future extensions |
nvertex | NDNET_UINT | 1 | number of vertices |
dummy | int(4B) | 1 | |
dummy | int(4B) | 1 | |
v_coords | float(4B) | ndims×nvertex | coordinates of the vertices [X0,Y0, ...] |
dummy | int(4B) | 1 | |
dummy | int(4B) | 1 | |
nfaces | NDNET_UINT | ndims+1 | number of cells of each type (N0,N1,...) |
dummy | int(4B) | 1 | |
dummy | int(4B) | 1 | |
haveVertexFromFace | int(4B) | ndims+1 | are n-cells explicitly defined ? (0=no, 1=yes) |
dummy | int(4B) | 1 | |
* | * | * | next 3 lines are repeated for each (ndims+1) possible cells type , only if haveVertexFromFace[n] is true. |
dummy | int(4B) | 1 | |
f_vertexIndex[n] | NDNET_UINT | (n+1)×nfaces[n] | list of (n+1) vertex indices for each n-cell |
dummy | int(4B) | 1 | |
dummy | int(4B) | 1 | |
haveFaceFromVertex | int(4B) | ndims+1 | are n-cells in the co-boundary of each vertex explicitly defined ? (0=no, 1=yes) |
dummy | int(4B) | 1 | |
* | * | * | next 6 lines are repeated for each (ndims+1) possible cells type, only if haveFaceFromVertex[n] is true. |
dummy | int(4B) | 1 | |
numFaceIndexCum[n] | NDNET_IDCUMT | nvertex+1 | cumulative count of n-cells on vertices co-boundary |
dummy | int(4B) | 1 | |
dummy | int(4B) | 1 | |
v_faceIndex[n] | NDNET_UINT | numFaceIndexCum[n] | list of n-cells on the co-boundary of each vertex (vertex i have numFaceIndexCum[n][i+1]-numFaceIndexCum[n][i] of them) |
dummy | int(4B) | 1 | |
dummy | int(4B) | 1 | |
haveFaceFromFace | int(4B) | (ndims+1)^2 | are n-cells in the co-boundary of each k-cell explicitly defined ? (0=no, 1=yes) |
dummy | int(4B) | 1 | |
* | * | * | This section describes boundary relation between n-cells and k-cells. It is usually empty in DisPerSE (see NDnetwork.c for details) so SKIP IT :) |
dummy | int(4B) | 1 | |
haveVFlags | int(4B) | 1 | 1 if vertex flags are defined |
dummy | int(4B) | 1 | |
* | * | * | next 3 lines are skipped if haveVFlags=0 |
dummy | int(4B) | 1 | |
v_flag | uchar(1B) | nvertex | value of the flags for vertices |
dummy | int(4B) | 1 | |
dummy | int(4B) | 1 | |
haveFFlags | int(4B) | ndims+1 | 1 if flags are defined for n-cells |
dummy | int(4B) | 1 | |
* | * | * | next 3 lines are repeated for each n-cell such that haveFFlags[n]=1 |
dummy | int(4B) | 1 | |
f_flag[n] | uchar(1B) | nfaces[n] | value of the flags for n-cells |
dummy | int(4B) | 1 | |
dummy | int(4B) | 1 | |
ndata | int(4B) | 1 | total number of additional fields |
dummy | int(4B) | 1 | |
* | * | * | next 7 lines are repeated for each additional field (×ndata) |
dummy | int(4B) | 1 | |
type | int(4B) | 1 | the type of cells (0=vertex, n = n-simplex) |
name | char(1B) | 255 | name of the supplementary data |
dummy | int(4B) | 1 | |
dummy | int(4B) | 1 | |
data | double(8B) | N | data associated to cells or vertices. N is nfaces[n] or nvertex depending on the type value. |
dummy | int(4B) | 1 |