/* $Id: meshimpl.h,v 1.12 2000/10/17 13:48:54 knepley Exp $ */
/*
  This file includes the definition of structures used in PETSc for 
  meshes. This should not be included in users' code.
*/

#ifndef __MESHIMPL_H
#define __MESHIMPL_H

#include "petscsles.h"
#include "mesh.h"

struct _MeshOps {
      /* Generic Operations */
  int (*setup)(Mesh),
      (*setfromoptions)(Mesh),
      (*view)(Mesh, PetscViewer),
      (*copy)(Mesh, Mesh),
      (*duplicate)(Mesh, Mesh *),
      (*destroy)(Mesh),
      /* Mesh-Specific Operations */
      (*partition)(Mesh),
      (*coarsen)(Mesh, PointFunction, Mesh *),
      (*refine)(Mesh, PointFunction, Mesh *),
      (*resetnodes)(Mesh, PetscTruth),
      (*savemesh)(Mesh),
      (*restoremesh)(Mesh),
      /* Mesh Query Functions */
      (*updateboundingbox)(Mesh),
      (*isdistorted)(Mesh, PetscTruth *),
      /* Mesh Boundary Query Functions */
      (*getboundarysize)(Mesh, int, int *),
      (*getboundaryindex)(Mesh, int, int *),
      (*getboundarystart)(Mesh, int, PetscTruth, int *),
      (*getboundarynext)(Mesh, int, PetscTruth, int *),
      (*getactiveboundary)(Mesh, int*),
      /* Mesh Node Query Functions */
      (*getnodeboundary)(Mesh, int, int *),
      (*nodeisvertex)(Mesh, int, PetscTruth *),
      (*getnodecoords)(Mesh, int, double *, double *, double *),
      (*setnodecoords)(Mesh, int, double, double, double),
      (*getnodecoordssaved)(Mesh, int, double *, double *, double *),
      (*nearestnode)(Mesh, double, double, double, PetscTruth, int *),
      (*getnodesupport)(Mesh, int, int, int *, int **),
      /* Mesh Element Query Functions */
      (*getelemneighbor)(Mesh, int, int, int *),
      (*locatepoint)(Mesh, double, double, double, int *),
      /* Mesh Embedding Query Functions */
      (*getnodefromelement)(Mesh, int, int, int *),
      (*getnodefromedge)(Mesh, int, int, int *),
      /* CSR Support Functions */
      (*createlocalcsr)(Mesh, int *, int *, int **, int **, double **, int, int *, PetscTruth),
      (*createfullcsr)(Mesh, PetscTruth, int *, int *, int **, int **),
      (*createdualcsr)(Mesh, int **, int **, int **, int);
};

struct _Mesh {
  PETSCHEADER(struct _MeshOps)
  int        dim;                             /* Dimension of the mesh: 1, 2 or 3 */
  PetscTruth setupcalled;                     /* Flag for mesh setup */
  void      *data;                            /* Holds implementation-specific information */
  void      *usr;                             /* An optional user-context */

  /* Domain information */
  double     startX, startY, startZ;          /* Start of mesh bounding box, in periodic meshes these are input */
  double     endX,   endY,   endZ;            /* End   of mesh bounding box, in periodic meshes these are input */
  double     sizeX,  sizeY,  sizeZ;           /* Size  of mesh bounding box */
  double     locStartX, locStartY, locStartZ; /* Start of local mesh bounding box, in periodic meshes these are input */
  double     locEndX,   locEndY,   locEndZ;   /* End   of local mesh bounding box, in periodic meshes these are input */
  double     locSizeX,  locSizeY,  locSizeZ;  /* Size  of local mesh bounding box */
  PetscTruth isPeriodic;                      /* Flag for periodic meshes */
  PetscTruth isPeriodicDim[3];                /* Flag for periodicity in a certain dimension */

  /* Mesh boundary information */
  MeshBoundary2D *bdCtx;                      /* Boundary of the mesh */
  MeshBoundary2D *bdCtxNew;                   /* Boundary used for reforming */

  /* Mesh generator information */
  AO         nodeOrdering;                    /* A reordering of the nodes after they are output from the mesh generator */

  /* Mesh information */
  int        numBd;                           /* B:     Number of closed boundaries */
  int        numVertices;                     /* V:     Number of points in the mesh */
  int        numNodes;                        /* N:     Number of discretization points, V for linear elems, V+E for quadratic elems */
  int        numBdNodes;                      /* NB:    Number of boundary nodes */
  int        numEdges;                        /* E:     Number of edges in the mesh */
  int        numBdEdges;                      /* EB:    Number of boundary edges in the mesh */
  int        numFaces;                        /* F:     Number of triangles in the mesh */
  int        numBdFaces;                      /* FB:    Number of boundary faces in the mesh */
  int        numCells;                        /* C:     Number of volume elements in the mesh */
  int        numHoles;                        /* H:     Number of holes */
  int        numCorners;                      /* C':    Number of nodes on a face, 3 for a linear element, 6  for a quadratic element */
  int        numCellCorners;                  /* C*:    Number of nodes on a cell, 4 for a linear element, 10 for a quadratic element */
  int        maxDegree;                       /* MD:    The maximum degree of a vertex */
  double    *holes;                           /* [dH]:  List of hole coordinates */

  /* Iterator Constructs */
  int        activeBd;                        /* Canonical number of boundary being iterated over */
  int        activeBdOld;                     /* Canonical number of last boundary being iterated over */
  int        activeBdNode;                    /* Current boundary node in the iteration */
  int        activeBdNodeClass;               /* Class of current boundary node in the iteration (e.g. vertex or midnode) */

  /* Quality limits */
  PetscReal  maxAspectRatio;                  /* The largest allowable aspect ratio = (length of longest side)^2/(2 area) */

  /* Partitioning support */
  Partition  part;                            /* A partition of the mesh */
  int        partitioned;                     /* Flag for application of the current partition */

  /* Coarsening support */
  AO         coarseMap;                       /* Map of nodes to nodes in a finer mesh */

  /* Graphics support */
  int        highlightElement;                /* This local element will be highlighted in a display of the mesh */

  /* Support calculations */
  int       *support;                         /* [MD]: A preallocated array to hold the support of a vertex */
  PetscTruth supportTaken;                    /*       The support pointer has been taken */

  /* Movement support */
  PetscTruth isMoving;                        /* Flag for moving mesh */
};

/*-------------------------------------------------------------------------------------------------------------------*/

struct _PartitionOps {
      /* Generic Operations */
  int (*setup)(Partition),
      (*setfromoptions)(Partition),
      (*view)(Partition, PetscViewer),
      (*copy)(Partition, Partition),
      (*duplicate)(Partition,  Partition *),
      (*destroy)(Partition),
      /* Partition-Specific Operations */
      (*ghostnodeexchange)(Partition, InsertMode, ScatterMode, int *, int *),
      /* Node Query Functions */
      (*gettotalnodes)(Partition, int *),
      (*getstartnode)(Partition, int *),
      (*getendnode)(Partition, int *),
      (*getnumnodes)(Partition, int *),
      (*getnumoverlapnodes)(Partition, int *),
      (*globaltolocalnodeindex)(Partition, int, int *),
      (*localtoglobalnodeindex)(Partition, int, int *),
      (*globaltoghostnodeindex)(Partition, int, int *, int *),
      (*ghosttoglobalnodeindex)(Partition, int, int *, int *),
      (*getnodeordering)(Partition, AO *),
      /* Face Query Functions */
      (*gettotalfaces)(Partition, int *),
      (*getstartface)(Partition, int *),
      (*getendface)(Partition, int *),
      (*getnumfaces)(Partition, int *),
      (*getnumoverlapfaces)(Partition, int *),
      (*globaltolocalfaceindex)(Partition, int, int *),
      (*localtoglobalfaceindex)(Partition, int, int *),
      (*getfaceordering)(Partition, AO *),
      /* Edge Query Functions */
      (*gettotaledges)(Partition, int *),
      (*getstartedge)(Partition, int *),
      (*getendedge)(Partition, int *),
      (*getnumedges)(Partition, int *),
      (*getnumoverlapedges)(Partition, int *),
      (*globaltolocaledgeindex)(Partition, int, int *),
      (*localtoglobaledgeindex)(Partition, int, int *),
      (*getedgeordering)(Partition, AO *);
};

struct _Partition {
  PETSCHEADER(struct _PartitionOps)
  Mesh       mesh;                 /*        The mesh which was partitioned */
  int        setupcalled;          /*        The flag for partition setup */
  void      *data;                 /*        This holds implementation-specific information */
  int        numProcs;             /*        The number of processors in the communicator */
  int        rank;                 /*        The rank of this processor */
  /* Partitioning order */
  PetscTruth isElementPartitioned; /*        The flag indicating that the nodes have been partitioned */
  /* Element variables */
  AO         ordering;             /*        The reordering which implements the partition */
  int        numLocElements;       /*  LE:   The number of local elements */
  int        numElements;          /*   E:   The global number of elements */
  int        numOverlapElements;   /* LE+NG: The number of local + ghost elements */
  int       *firstElement;         /* [P+1]: The first element in each domain */
  int       *ghostElements;        /* [NG]:  The global number of each ghost element */
  int       *ghostElementProcs;    /* [NG]:  The domain of each ghost element */
};

#endif /* __MESHIMPL_H */
