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):

NDnet binary format
fieldtypesizecomment
dummyint(4B) 1 for FORTRAN compatibility
tagchar(1B)16identifies the file type. Value : "NDNETWORK"
dummyint(4B) 1
dummyint(4B) 1
ndimsint(4B)1number of dimensions of the embedding space
ndims_netint(4B)1ndims spanned by the network (=ndims by default)
dummyint(4B) 1
dummyint(4B) 1
commentchar(1B)80a comment on the file (string)
periodicityint(4B)1 0=non periodic, if p^th bit is set, boundary are periodic along dimension p
isSimpComplexint(4B)1 1 if network is made of simplices (must be 1 for DisPerSE)
x0double(8B)ndimsorigin of bounding box
deltadouble(8B)ndimssize of bounding box
index_sizeint(4B)1size of NDNET_UINT integer format in Bytes
cumindex_sizeint(4B)1size of NDNET_IDCUMT integer format in Bytes
dummy_extchar(1B)152dummy data reserved for future extensions
nvertexNDNET_UINT1number of vertices
dummyint(4B) 1
dummyint(4B) 1
v_coordsfloat(4B)ndims×nvertexcoordinates of the vertices [X0,Y0, ...]
dummyint(4B) 1
dummyint(4B) 1
nfacesNDNET_UINTndims+1number of cells of each type (N0,N1,...)
dummyint(4B) 1
dummyint(4B) 1
haveVertexFromFaceint(4B)ndims+1are n-cells explicitly defined ? (0=no, 1=yes)
dummyint(4B) 1
*** next 3 lines are repeated for each (ndims+1) possible cells type , only if haveVertexFromFace[n] is true.
dummyint(4B) 1
f_vertexIndex[n]NDNET_UINT(n+1)×nfaces[n]list of (n+1) vertex indices for each n-cell
dummyint(4B) 1
dummyint(4B) 1
haveFaceFromVertexint(4B)ndims+1are n-cells in the co-boundary of each vertex explicitly defined ? (0=no, 1=yes)
dummyint(4B) 1
*** next 6 lines are repeated for each (ndims+1) possible cells type, only if haveFaceFromVertex[n] is true.
dummyint(4B) 1
numFaceIndexCum[n]NDNET_IDCUMTnvertex+1cumulative count of n-cells on vertices co-boundary
dummyint(4B) 1
dummyint(4B) 1
v_faceIndex[n]NDNET_UINTnumFaceIndexCum[n]list of n-cells on the co-boundary of each vertex (vertex i have numFaceIndexCum[n][i+1]-numFaceIndexCum[n][i] of them)
dummyint(4B) 1
dummyint(4B) 1
haveFaceFromFaceint(4B)(ndims+1)^2are n-cells in the co-boundary of each k-cell explicitly defined ? (0=no, 1=yes)
dummyint(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 :)
dummyint(4B) 1
haveVFlagsint(4B)1 1 if vertex flags are defined
dummyint(4B) 1
*** next 3 lines are skipped if haveVFlags=0
dummyint(4B) 1
v_flaguchar(1B)nvertex value of the flags for vertices
dummyint(4B) 1
dummyint(4B) 1
haveFFlagsint(4B)ndims+1 1 if flags are defined for n-cells
dummyint(4B) 1
*** next 3 lines are repeated for each n-cell such that haveFFlags[n]=1
dummyint(4B) 1
f_flag[n]uchar(1B)nfaces[n] value of the flags for n-cells
dummyint(4B) 1
dummyint(4B) 1
ndataint(4B)1 total number of additional fields
dummyint(4B) 1
*** next 7 lines are repeated for each additional field (×ndata)
dummyint(4B) 1
typeint(4B)1 the type of cells (0=vertex, n = n-simplex)
namechar(1B)255 name of the supplementary data
dummyint(4B) 1
dummyint(4B) 1
datadouble(8B)N data associated to cells or vertices. N is nfaces[n] or nvertex depending on the type value.
dummyint(4B) 1