Actual source code: dmpleximpl.h

petsc-master 2021-01-18
Report Typos and Errors
  1: #if !defined(_PLEXIMPL_H)
  2: #define _PLEXIMPL_H

  4: #include <petscmat.h>
  5: #include <petscdmplex.h>
  6: #include <petscbt.h>
  7: #include <petscsf.h>
  8: #include <petsc/private/dmimpl.h>

 10: PETSC_EXTERN PetscLogEvent DMPLEX_Interpolate;
 11: PETSC_EXTERN PetscLogEvent DMPLEX_Partition;
 12: PETSC_EXTERN PetscLogEvent DMPLEX_PartSelf;
 13: PETSC_EXTERN PetscLogEvent DMPLEX_PartLabelInvert;
 14: PETSC_EXTERN PetscLogEvent DMPLEX_PartLabelCreateSF;
 15: PETSC_EXTERN PetscLogEvent DMPLEX_PartStratSF;
 16: PETSC_EXTERN PetscLogEvent DMPLEX_CreatePointSF;
 17: PETSC_EXTERN PetscLogEvent DMPLEX_Distribute;
 18: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeCones;
 19: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeLabels;
 20: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeSF;
 21: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeOverlap;
 22: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeField;
 23: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeData;
 24: PETSC_EXTERN PetscLogEvent DMPLEX_Migrate;
 25: PETSC_EXTERN PetscLogEvent DMPLEX_InterpolateSF;
 26: PETSC_EXTERN PetscLogEvent DMPLEX_GlobalToNaturalBegin;
 27: PETSC_EXTERN PetscLogEvent DMPLEX_GlobalToNaturalEnd;
 28: PETSC_EXTERN PetscLogEvent DMPLEX_NaturalToGlobalBegin;
 29: PETSC_EXTERN PetscLogEvent DMPLEX_NaturalToGlobalEnd;
 30: PETSC_EXTERN PetscLogEvent DMPLEX_Stratify;
 31: PETSC_EXTERN PetscLogEvent DMPLEX_Symmetrize;
 32: PETSC_EXTERN PetscLogEvent DMPLEX_Preallocate;
 33: PETSC_EXTERN PetscLogEvent DMPLEX_ResidualFEM;
 34: PETSC_EXTERN PetscLogEvent DMPLEX_JacobianFEM;
 35: PETSC_EXTERN PetscLogEvent DMPLEX_InterpolatorFEM;
 36: PETSC_EXTERN PetscLogEvent DMPLEX_InjectorFEM;
 37: PETSC_EXTERN PetscLogEvent DMPLEX_IntegralFEM;
 38: PETSC_EXTERN PetscLogEvent DMPLEX_CreateGmsh;
 39: PETSC_EXTERN PetscLogEvent DMPLEX_RebalanceSharedPoints;
 40: PETSC_EXTERN PetscLogEvent DMPLEX_CreateFromFile;
 41: PETSC_EXTERN PetscLogEvent DMPLEX_BuildFromCellList;
 42: PETSC_EXTERN PetscLogEvent DMPLEX_BuildCoordinatesFromCellList;
 43: PETSC_EXTERN PetscLogEvent DMPLEX_LocatePoints;

 45: typedef struct _DMPlexCellRefinerOps *DMPlexCellRefinerOps;
 46: struct _DMPlexCellRefinerOps {
 47:   PetscErrorCode (*refine)(DMPlexCellRefiner, DMPolytopeType, PetscInt, PetscInt *, PetscInt *, DMPolytopeType *[], PetscInt *[], PetscInt *[], PetscInt *[]);
 48:   PetscErrorCode (*mapsubcells)(DMPlexCellRefiner, DMPolytopeType, PetscInt, PetscInt, DMPolytopeType, PetscInt, PetscInt, PetscInt *, PetscInt *);
 49:   PetscErrorCode (*getaffinetransforms)(DMPlexCellRefiner, DMPolytopeType, PetscInt *, PetscReal *[], PetscReal *[], PetscReal *[]);
 50:   PetscErrorCode (*getaffinefacetransforms)(DMPlexCellRefiner, DMPolytopeType, PetscInt *, PetscReal *[], PetscReal *[], PetscReal *[], PetscReal *[]);
 51:   PetscErrorCode (*getcellvertices)(DMPlexCellRefiner, DMPolytopeType, PetscInt *, PetscReal *[]);
 52:   PetscErrorCode (*getsubcellvertices)(DMPlexCellRefiner, DMPolytopeType, DMPolytopeType, PetscInt, PetscInt *, PetscInt *[]);
 53:   PetscErrorCode (*mapcoords)(DMPlexCellRefiner, DMPolytopeType, DMPolytopeType, PetscInt, PetscInt, PetscInt, const PetscScalar[], PetscScalar[]);
 54:   PetscErrorCode (*setup)(DMPlexCellRefiner);
 55:   PetscErrorCode (*destroy)(DMPlexCellRefiner);
 56: };

 58: typedef struct _n_PlexGeneratorFunctionList *PlexGeneratorFunctionList;
 59: struct _n_PlexGeneratorFunctionList {
 60:   PetscErrorCode    (*generate)(DM, PetscBool, DM*);
 61:   PetscErrorCode    (*refine)(DM, PetscReal*, DM*);
 62:   PetscErrorCode    (*adaptlabel)(DM, DMLabel, DM*);
 63:   char              *name;
 64:   PetscInt          dim;
 65:   PlexGeneratorFunctionList next;
 66: };

 68: struct _p_DMPlexCellRefiner {
 69:   PETSCHEADER(struct _DMPlexCellRefinerOps);
 70:   DM                    dm;          /* The original DM */
 71:   PetscBool             setupcalled;
 72:   DMPlexCellRefinerType type;
 73:   DMLabel               refineType;  /* The refinement type of each point, since there are multiple ways to refine a cell */
 74:   PetscInt              *ctOrder;    /* [i] = ct: An array with cell types in depth order */
 75:   PetscInt              *ctOrderInv; /* [ct] = i: An array with the ordinal numbers for each cell type */
 76:   PetscInt              *ctStart;    /* [ct]: The number for the first cell of each polytope type in the original mesh */
 77:   PetscInt              *ctStartNew; /* [ctNew]: The number for the first cell of each polytope type in the new mesh */
 78:   PetscInt              *offset;     /* [ct/rt][ctNew]: The offset in the new point numbering of a point of type ctNew produced from an old point of type ct or refine type rt */
 79:   PetscFE               *coordFE;    /* Finite element for each cell type, used for localized coordinate interpolation */
 80:   PetscFEGeom           **refGeom;   /* Geometry of the reference cell for each cell type */
 81:   DMLabel               adaptLabel;  /* Optional label indicating cells to be refined */
 82:   void                  *data;       /* refiner private data */
 83: };

 85: /* Utility struct to store the contents of a Fluent file in memory */
 86: typedef struct {
 87:   int          index;    /* Type of section */
 88:   unsigned int zoneID;
 89:   unsigned int first;
 90:   unsigned int last;
 91:   int          type;
 92:   int          nd;       /* Either ND or element-type */
 93:   void        *data;
 94: } FluentSection;

 96: struct _PetscGridHash {
 97:   PetscInt     dim;
 98:   PetscReal    lower[3];    /* The lower-left corner */
 99:   PetscReal    upper[3];    /* The upper-right corner */
100:   PetscReal    extent[3];   /* The box size */
101:   PetscReal    h[3];        /* The subbox size */
102:   PetscInt     n[3];        /* The number of subboxes */
103:   PetscSection cellSection; /* Offsets for cells in each subbox*/
104:   IS           cells;       /* List of cells in each subbox */
105:   DMLabel      cellsSparse; /* Sparse storage for cell map */
106: };

108: /* Point Numbering in Plex:

110:    Points are numbered contiguously by stratum. Strate are organized as follows:

112:    First Stratum:  Cells [height 0]
113:    Second Stratum: Vertices [depth 0]
114:    Third Stratum:  Faces [height 1]
115:    Fourth Stratum: Edges [depth 1]

117:    We do this so that the numbering of a cell-vertex mesh does not change after interpolation. Within a given stratum,
118:    we allow additional segregation of by cell type.
119: */
120: typedef struct {
121:   PetscInt             refct;

123:   PetscSection         coneSection;       /* Layout of cones (inedges for DAG) */
124:   PetscInt             maxConeSize;       /* Cached for fast lookup */
125:   PetscInt            *cones;             /* Cone for each point */
126:   PetscInt            *coneOrientations;  /* Orientation of each cone point, means cone traveral should start on point 'o', and if negative start on -(o+1) and go in reverse */
127:   PetscSection         supportSection;    /* Layout of cones (inedges for DAG) */
128:   PetscInt             maxSupportSize;    /* Cached for fast lookup */
129:   PetscInt            *supports;          /* Cone for each point */
130:   PetscBool            refinementUniform; /* Flag for uniform cell refinement */
131:   PetscReal            refinementLimit;   /* Maximum volume for refined cell */
132:   PetscErrorCode     (*refinementFunc)(const PetscReal [], PetscReal *); /* Function giving the maximum volume for refined cell */
133:   PetscInt             overlap;           /* Overlap of the partitions as passed to DMPlexDistribute() or DMPlexDistributeOverlap() */
134:   DMPlexInterpolatedFlag interpolated;
135:   DMPlexInterpolatedFlag interpolatedCollective;

137:   PetscInt            *facesTmp;          /* Work space for faces operation */

139:   /* Hierarchy */
140:   DMPlexCellRefinerType cellRefiner;       /* Strategy for refining cells */
141:   PetscBool             regularRefinement; /* This flag signals that we are a regular refinement of coarseMesh */

143:   /* Generation */
144:   char                *tetgenOpts;
145:   char                *triangleOpts;
146:   PetscPartitioner     partitioner;
147:   PetscBool            partitionBalance;  /* Evenly divide partition overlap when distributing */
148:   PetscBool            remeshBd;

150:   /* Submesh */
151:   DMLabel              subpointMap;       /* Label each original mesh point in the submesh with its depth, subpoint are the implicit numbering */
152:   IS                   subpointIS;        /* IS holding point number in the enclosing mesh of every point in the submesh chart */
153:   PetscObjectState     subpointState;     /* The state of subpointMap when the subpointIS was last created */

155:   /* Labels and numbering */
156:   PetscObjectState     depthState;        /* State of depth label, so that we can determine if a user changes it */
157:   PetscObjectState     celltypeState;     /* State of celltype label, so that we can determine if a user changes it */
158:   IS                   globalVertexNumbers;
159:   IS                   globalCellNumbers;

161:   /* Constraints */
162:   PetscSection         anchorSection;      /* maps constrained points to anchor points */
163:   IS                   anchorIS;           /* anchors indexed by the above section */
164:   PetscErrorCode     (*createanchors)(DM); /* automatically compute anchors (probably from tree constraints) */
165:   PetscErrorCode     (*computeanchormatrix)(DM,PetscSection,PetscSection,Mat);

167:   /* Tree: automatically construct constraints for hierarchically non-conforming meshes */
168:   PetscSection         parentSection;     /* dof == 1 if point has parent */
169:   PetscInt            *parents;           /* point to parent */
170:   PetscInt            *childIDs;          /* point to child ID */
171:   PetscSection         childSection;      /* inverse of parent section */
172:   PetscInt            *children;          /* point to children */
173:   DM                   referenceTree;     /* reference tree to which child ID's refer */
174:   PetscErrorCode      (*getchildsymmetry)(DM,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt*,PetscInt*);

176:   /* MATIS support */
177:   PetscSection         subdomainSection;

179:   /* Adjacency */
180:   PetscBool            useAnchors;        /* Replace constrained points with their anchors in adjacency lists */
181:   PetscErrorCode      (*useradjacency)(DM,PetscInt,PetscInt*,PetscInt[],void*); /* User callback for adjacency */
182:   void                *useradjacencyctx;  /* User context for callback */

184:   /* Projection */
185:   PetscInt             maxProjectionHeight; /* maximum height of cells used in DMPlexProject functions */
186:   PetscInt             activePoint;         /* current active point in iteration */

188:   /* Output */
189:   PetscInt             vtkCellHeight;            /* The height of cells for output, default is 0 */
190:   PetscReal            scale[NUM_PETSC_UNITS];   /* The scale for each SI unit */

192:   /* Geometry */
193:   PetscReal            minradius;         /* Minimum distance from cell centroid to face */
194:   PetscBool            useHashLocation;   /* Use grid hashing for point location */
195:   PetscGridHash        lbox;              /* Local box for searching */
196:   void               (*coordFunc)(PetscInt, PetscInt, PetscInt, /* Function used to remap newly introduced vertices */
197:                                   const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
198:                                   const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[],
199:                                   PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]);

201:   /* Neighbors */
202:   PetscMPIInt*         neighbors;

204:   /* Debugging */
205:   PetscBool            printSetValues;
206:   PetscInt             printFEM;
207:   PetscInt             printL2;
208:   PetscReal            printTol;
209: } DM_Plex;

211: PETSC_EXTERN PetscErrorCode DMPlexVTKWriteAll_VTU(DM,PetscViewer);
212: PETSC_EXTERN PetscErrorCode VecView_Plex_Local(Vec,PetscViewer);
213: PETSC_EXTERN PetscErrorCode VecView_Plex_Native(Vec,PetscViewer);
214: PETSC_EXTERN PetscErrorCode VecView_Plex(Vec,PetscViewer);
215: PETSC_EXTERN PetscErrorCode VecLoad_Plex_Local(Vec,PetscViewer);
216: PETSC_EXTERN PetscErrorCode VecLoad_Plex_Native(Vec,PetscViewer);
217: PETSC_EXTERN PetscErrorCode VecLoad_Plex(Vec,PetscViewer);
218: PETSC_INTERN PetscErrorCode DMPlexGetFieldType_Internal(DM, PetscSection, PetscInt, PetscInt *, PetscInt *, PetscViewerVTKFieldType *);
219: PETSC_INTERN PetscErrorCode DMPlexView_GLVis(DM,PetscViewer);
220: PETSC_INTERN PetscErrorCode DMSetUpGLVisViewer_Plex(PetscObject,PetscViewer);
221: #if defined(PETSC_HAVE_HDF5)
222: PETSC_EXTERN PetscErrorCode VecView_Plex_Local_HDF5(Vec, PetscViewer);
223: PETSC_EXTERN PetscErrorCode VecView_Plex_HDF5(Vec, PetscViewer);
224: PETSC_EXTERN PetscErrorCode VecLoad_Plex_HDF5(Vec, PetscViewer);
225: PETSC_EXTERN PetscErrorCode VecView_Plex_HDF5_Native(Vec, PetscViewer);
226: PETSC_EXTERN PetscErrorCode VecLoad_Plex_HDF5_Native(Vec, PetscViewer);
227: PETSC_EXTERN PetscErrorCode DMPlexView_HDF5(DM, PetscViewer);
228: PETSC_EXTERN PetscErrorCode DMPlexLoad_HDF5(DM, PetscViewer);
229: #endif

231: PETSC_INTERN PetscErrorCode DMPlexVecGetClosureAtDepth_Internal(DM, PetscSection, Vec, PetscInt, PetscInt, PetscInt *, PetscScalar *[]);
232: PETSC_INTERN PetscErrorCode DMPlexClosurePoints_Private(DM,PetscInt,const PetscInt[],IS*);
233: PETSC_INTERN PetscErrorCode DMSetFromOptions_NonRefinement_Plex(PetscOptionItems *, DM);
234: PETSC_INTERN PetscErrorCode DMCoarsen_Plex(DM, MPI_Comm, DM *);
235: PETSC_INTERN PetscErrorCode DMCoarsenHierarchy_Plex(DM, PetscInt, DM []);
236: PETSC_INTERN PetscErrorCode DMRefine_Plex(DM, MPI_Comm, DM *);
237: PETSC_INTERN PetscErrorCode DMRefineHierarchy_Plex(DM, PetscInt, DM []);
238: PETSC_INTERN PetscErrorCode DMAdaptLabel_Plex(DM, DMLabel, DM *);
239: PETSC_INTERN PetscErrorCode DMAdaptMetric_Plex(DM, Vec, DMLabel, DM *);
240: PETSC_INTERN PetscErrorCode DMPlexInsertBoundaryValues_Plex(DM, PetscBool, Vec, PetscReal, Vec, Vec, Vec);
241: PETSC_INTERN PetscErrorCode DMPlexInsertTimeDerivativeBoundaryValues_Plex(DM, PetscBool, Vec, PetscReal, Vec, Vec, Vec);
242: PETSC_INTERN PetscErrorCode DMProjectFunctionLocal_Plex(DM,PetscReal,PetscErrorCode(**)(PetscInt,PetscReal,const PetscReal[],PetscInt,PetscScalar *,void *),void **,InsertMode,Vec);
243: PETSC_INTERN PetscErrorCode DMProjectFunctionLabelLocal_Plex(DM,PetscReal,DMLabel,PetscInt,const PetscInt[],PetscInt,const PetscInt[],PetscErrorCode(**)(PetscInt,PetscReal,const PetscReal[],PetscInt,PetscScalar *,void *),void **,InsertMode,Vec);
244: PETSC_INTERN PetscErrorCode DMProjectFieldLocal_Plex(DM,PetscReal,Vec,void (**)(PetscInt,PetscInt,PetscInt,const PetscInt[],const PetscInt[],const PetscScalar[],const PetscScalar[],const PetscScalar[],const PetscInt[],const PetscInt[],const PetscScalar[],const PetscScalar[],const PetscScalar[],PetscReal,const PetscReal[],PetscInt,const PetscScalar[],PetscScalar[]),InsertMode,Vec);
245: PETSC_INTERN PetscErrorCode DMProjectFieldLabelLocal_Plex(DM,PetscReal,DMLabel,PetscInt,const PetscInt[],PetscInt,const PetscInt[],Vec,void (**)(PetscInt,PetscInt,PetscInt,const PetscInt[],const PetscInt[],const PetscScalar[],const PetscScalar[],const PetscScalar[],const PetscInt[],const PetscInt[],const PetscScalar[],const PetscScalar[],const PetscScalar[],PetscReal,const PetscReal[],PetscInt,const PetscScalar[],PetscScalar[]),InsertMode,Vec);
246: PETSC_INTERN PetscErrorCode DMProjectBdFieldLabelLocal_Plex(DM,PetscReal,DMLabel,PetscInt,const PetscInt[],PetscInt,const PetscInt[],Vec,void (**)(PetscInt,PetscInt,PetscInt,const PetscInt[],const PetscInt[],const PetscScalar[],const PetscScalar[],const PetscScalar[],const PetscInt[],const PetscInt[],const PetscScalar[],const PetscScalar[],const PetscScalar[],PetscReal,const PetscReal[],const PetscReal[],PetscInt,const PetscScalar[],PetscScalar[]),InsertMode,Vec);
247: PETSC_INTERN PetscErrorCode DMComputeL2Diff_Plex(DM,PetscReal,PetscErrorCode(**)(PetscInt,PetscReal,const PetscReal[],PetscInt,PetscScalar *,void *),void **,Vec,PetscReal *);
248: PETSC_INTERN PetscErrorCode DMComputeL2GradientDiff_Plex(DM,PetscReal,PetscErrorCode(**)(PetscInt,PetscReal,const PetscReal[], const PetscReal[],PetscInt,PetscScalar *,void *),void **,Vec,const PetscReal [],PetscReal *);
249: PETSC_INTERN PetscErrorCode DMComputeL2FieldDiff_Plex(DM,PetscReal,PetscErrorCode(**)(PetscInt,PetscReal,const PetscReal[],PetscInt,PetscScalar *,void *),void **,Vec,PetscReal *);
250: PETSC_INTERN PetscErrorCode DMLocatePoints_Plex(DM, Vec, DMPointLocationType, PetscSF);

252: PETSC_INTERN PetscErrorCode DMPlexLoadLabels_HDF5_Internal(DM, PetscViewer);
253: PETSC_INTERN PetscErrorCode DMPlexView_HDF5_Internal(DM, PetscViewer);
254: PETSC_INTERN PetscErrorCode DMPlexLoad_HDF5_Internal(DM, PetscViewer);
255: PETSC_INTERN PetscErrorCode DMPlexLoad_HDF5_Xdmf_Internal(DM, PetscViewer);
256: PETSC_INTERN PetscErrorCode VecView_Plex_HDF5_Internal(Vec, PetscViewer);
257: PETSC_INTERN PetscErrorCode VecView_Plex_HDF5_Native_Internal(Vec, PetscViewer);
258: PETSC_INTERN PetscErrorCode VecView_Plex_Local_HDF5_Internal(Vec, PetscViewer);
259: PETSC_INTERN PetscErrorCode VecLoad_Plex_HDF5_Internal(Vec, PetscViewer);
260: PETSC_INTERN PetscErrorCode VecLoad_Plex_HDF5_Native_Internal(Vec, PetscViewer);
261: /* TODO Make these INTERN */
262: PETSC_EXTERN PetscErrorCode DMPlexView_ExodusII_Internal(DM, int, PetscInt);
263: PETSC_EXTERN PetscErrorCode VecViewPlex_ExodusII_Nodal_Internal(Vec, int, int);
264: PETSC_EXTERN PetscErrorCode VecLoadPlex_ExodusII_Nodal_Internal(Vec, int, int);
265: PETSC_EXTERN PetscErrorCode VecViewPlex_ExodusII_Zonal_Internal(Vec, int, int);
266: PETSC_EXTERN PetscErrorCode VecLoadPlex_ExodusII_Zonal_Internal(Vec, int, int);
267: PETSC_INTERN PetscErrorCode DMPlexVTKGetCellType_Internal(DM,PetscInt,PetscInt,PetscInt*);
268: PETSC_INTERN PetscErrorCode DMPlexGetAdjacency_Internal(DM,PetscInt,PetscBool,PetscBool,PetscBool,PetscInt*,PetscInt*[]);
269: PETSC_INTERN PetscErrorCode DMPlexGetRawFaces_Internal(DM,DMPolytopeType,const PetscInt[],PetscInt*,const DMPolytopeType*[],const PetscInt*[],const PetscInt*[]);
270: PETSC_INTERN PetscErrorCode DMPlexRestoreRawFaces_Internal(DM,DMPolytopeType,const PetscInt[],PetscInt*,const DMPolytopeType*[],const PetscInt*[],const PetscInt*[]);
271: PETSC_INTERN PetscErrorCode CellRefinerInCellTest_Internal(DMPolytopeType, const PetscReal[], PetscBool *);
272: PETSC_INTERN PetscErrorCode DMPlexCellRefinerAdaptLabel(DM, DMLabel, DM *);
273: PETSC_INTERN PetscErrorCode DMPlexComputeCellType_Internal(DM, PetscInt, PetscInt, DMPolytopeType *);
274: PETSC_INTERN PetscErrorCode DMPlexCreateCellTypeOrder_Internal(DMPolytopeType, PetscInt *[], PetscInt *[]);
275: PETSC_INTERN PetscErrorCode DMPlexVecSetFieldClosure_Internal(DM, PetscSection, Vec, PetscBool[], PetscInt, PetscInt, const PetscInt[], DMLabel, PetscInt, const PetscScalar[], InsertMode);
276: PETSC_INTERN PetscErrorCode DMPlexProjectConstraints_Internal(DM, Vec, Vec);
277: PETSC_EXTERN PetscErrorCode DMPlexCreateReferenceTree_SetTree(DM, PetscSection, PetscInt[], PetscInt[]);
278: PETSC_EXTERN PetscErrorCode DMPlexCreateReferenceTree_Union(DM,DM,const char *,DM*);
279: PETSC_EXTERN PetscErrorCode DMPlexComputeInterpolatorTree(DM,DM,PetscSF,PetscInt *,Mat);
280: PETSC_EXTERN PetscErrorCode DMPlexComputeInjectorTree(DM,DM,PetscSF,PetscInt *,Mat);
281: PETSC_EXTERN PetscErrorCode DMPlexAnchorsModifyMat(DM,PetscSection,PetscInt,PetscInt,const PetscInt[],const PetscInt ***,const PetscScalar[],PetscInt*,PetscInt*,PetscInt*[],PetscScalar*[],PetscInt[],PetscBool);
282: PETSC_EXTERN PetscErrorCode indicesPoint_private(PetscSection,PetscInt,PetscInt,PetscInt *,PetscBool,PetscInt,PetscInt []);
283: PETSC_EXTERN PetscErrorCode indicesPointFields_private(PetscSection,PetscInt,PetscInt,PetscInt [],PetscBool,PetscInt,PetscInt []);
284: PETSC_INTERN PetscErrorCode DMPlexLocatePoint_Internal(DM,PetscInt,const PetscScalar [],PetscInt,PetscInt *);
285: /* these two are PETSC_EXTERN just because of src/dm/impls/plex/tests/ex18.c */
286: PETSC_EXTERN PetscErrorCode DMPlexOrientCell_Internal(DM,PetscInt,PetscInt,PetscBool);
287: PETSC_EXTERN PetscErrorCode DMPlexOrientInterface_Internal(DM);

289: /* Applications may use this function */
290: PETSC_EXTERN PetscErrorCode DMPlexCreateNumbering_Plex(DM, PetscInt, PetscInt, PetscInt, PetscInt *, PetscSF, IS *);

292: PETSC_INTERN PetscErrorCode DMPlexCreateCellNumbering_Internal(DM, PetscBool, IS *);
293: PETSC_INTERN PetscErrorCode DMPlexCreateVertexNumbering_Internal(DM, PetscBool, IS *);
294: PETSC_INTERN PetscErrorCode DMPlexRefine_Internal(DM, DMLabel, DM *);
295: PETSC_INTERN PetscErrorCode DMPlexCoarsen_Internal(DM, DMLabel, DM *);
296: PETSC_INTERN PetscErrorCode DMCreateMatrix_Plex(DM, Mat*);

298: PETSC_INTERN PetscErrorCode DMPlexGetOverlap_Plex(DM, PetscInt *);

300: /* invert dihedral symmetry: return a^-1,
301:  * using the representation described in
302:  * DMPlexGetConeOrientation() */
303: PETSC_STATIC_INLINE PetscInt DihedralInvert(PetscInt N, PetscInt a)
304: {
305:   return (a <= 0) ? a : (N - a);
306: }

308: /* invert dihedral symmetry: return b * a,
309:  * using the representation described in
310:  * DMPlexGetConeOrientation() */
311: PETSC_STATIC_INLINE PetscInt DihedralCompose(PetscInt N, PetscInt a, PetscInt b)
312: {
313:   if (!N) return 0;
314:   return  (a >= 0) ?
315:          ((b >= 0) ? ((a + b) % N) : -(((a - b - 1) % N) + 1)) :
316:          ((b >= 0) ? -(((N - b - a - 1) % N) + 1) : ((N + b - a) % N));
317: }

319: /* swap dihedral symmetries: return b * a^-1,
320:  * using the representation described in
321:  * DMPlexGetConeOrientation() */
322: PETSC_STATIC_INLINE PetscInt DihedralSwap(PetscInt N, PetscInt a, PetscInt b)
323: {
324:   return DihedralCompose(N,DihedralInvert(N,a),b);
325: }

327: PETSC_EXTERN PetscErrorCode DMPlexComputeResidual_Internal(DM, IS , PetscReal, Vec, Vec, PetscReal, Vec, void *);
328: PETSC_EXTERN PetscErrorCode DMPlexComputeResidual_Hybrid_Internal(DM, IS , PetscReal, Vec, Vec, PetscReal, Vec, void *);
329: PETSC_EXTERN PetscErrorCode DMPlexComputeJacobian_Internal(DM, IS, PetscReal, PetscReal, Vec, Vec, Mat, Mat, void *);
330: PETSC_EXTERN PetscErrorCode DMPlexComputeJacobian_Hybrid_Internal(DM, IS, PetscReal, PetscReal, Vec, Vec, Mat, Mat, void *);
331: PETSC_EXTERN PetscErrorCode DMPlexReconstructGradients_Internal(DM, PetscFV, PetscInt, PetscInt, Vec, Vec, Vec, Vec);

333: /* Matvec with A in row-major storage, x and y can be aliased */
334: PETSC_STATIC_INLINE void DMPlex_Mult2D_Internal(const PetscScalar A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
335: {
336:   PetscScalar z[2];
337:   z[0] = x[0]; z[1] = x[ldx];
338:   y[0]   = A[0]*z[0] + A[1]*z[1];
339:   y[ldx] = A[2]*z[0] + A[3]*z[1];
340:   (void)PetscLogFlops(6.0);
341: }
342: PETSC_STATIC_INLINE void DMPlex_Mult3D_Internal(const PetscScalar A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
343: {
344:   PetscScalar z[3];
345:   z[0] = x[0]; z[1] = x[ldx]; z[2] = x[ldx*2];
346:   y[0]     = A[0]*z[0] + A[1]*z[1] + A[2]*z[2];
347:   y[ldx]   = A[3]*z[0] + A[4]*z[1] + A[5]*z[2];
348:   y[ldx*2] = A[6]*z[0] + A[7]*z[1] + A[8]*z[2];
349:   (void)PetscLogFlops(15.0);
350: }
351: PETSC_STATIC_INLINE void DMPlex_MultTranspose2D_Internal(const PetscScalar A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
352: {
353:   PetscScalar z[2];
354:   z[0] = x[0]; z[1] = x[ldx];
355:   y[0]   = A[0]*z[0] + A[2]*z[1];
356:   y[ldx] = A[1]*z[0] + A[3]*z[1];
357:   (void)PetscLogFlops(6.0);
358: }
359: PETSC_STATIC_INLINE void DMPlex_MultTranspose3D_Internal(const PetscScalar A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
360: {
361:   PetscScalar z[3];
362:   z[0] = x[0]; z[1] = x[ldx]; z[2] = x[ldx*2];
363:   y[0]     = A[0]*z[0] + A[3]*z[1] + A[6]*z[2];
364:   y[ldx]   = A[1]*z[0] + A[4]*z[1] + A[7]*z[2];
365:   y[ldx*2] = A[2]*z[0] + A[5]*z[1] + A[8]*z[2];
366:   (void)PetscLogFlops(15.0);
367: }
368: PETSC_STATIC_INLINE void DMPlex_Mult2DReal_Internal(const PetscReal A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
369: {
370:   PetscScalar z[2];
371:   z[0] = x[0]; z[1] = x[ldx];
372:   y[0]   = A[0]*z[0] + A[1]*z[1];
373:   y[ldx] = A[2]*z[0] + A[3]*z[1];
374:   (void)PetscLogFlops(6.0);
375: }
376: PETSC_STATIC_INLINE void DMPlex_Mult3DReal_Internal(const PetscReal A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
377: {
378:   PetscScalar z[3];
379:   z[0] = x[0]; z[1] = x[ldx]; z[2] = x[ldx*2];
380:   y[0]     = A[0]*z[0] + A[1]*z[1] + A[2]*z[2];
381:   y[ldx]   = A[3]*z[0] + A[4]*z[1] + A[5]*z[2];
382:   y[ldx*2] = A[6]*z[0] + A[7]*z[1] + A[8]*z[2];
383:   (void)PetscLogFlops(15.0);
384: }
385: PETSC_STATIC_INLINE void DMPlex_MultTransposeReal_Internal(const PetscReal A[], PetscInt m, PetscInt n, PetscInt ldx, const PetscScalar x[], PetscScalar y[])
386: {
387:   PetscScalar z[3];
388:   PetscInt    i, j;
389:   for (i = 0; i < m; ++i) z[i] = x[i*ldx];
390:   for (j = 0; j < n; ++j) {
391:     const PetscInt l = j*ldx;
392:     y[l] = 0;
393:     for (i = 0; i < m; ++i) {
394:       y[l] += A[j*n+i]*z[i];
395:     }
396:   }
397:   (void)PetscLogFlops(2*m*n);
398: }
399: PETSC_STATIC_INLINE void DMPlex_MultTranspose2DReal_Internal(const PetscReal A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
400: {
401:   PetscScalar z[2];
402:   z[0] = x[0]; z[1] = x[ldx];
403:   y[0]   = A[0]*z[0] + A[2]*z[1];
404:   y[ldx] = A[1]*z[0] + A[3]*z[1];
405:   (void)PetscLogFlops(6.0);
406: }
407: PETSC_STATIC_INLINE void DMPlex_MultTranspose3DReal_Internal(const PetscReal A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
408: {
409:   PetscScalar z[3];
410:   z[0] = x[0]; z[1] = x[ldx]; z[2] = x[ldx*2];
411:   y[0]     = A[0]*z[0] + A[3]*z[1] + A[6]*z[2];
412:   y[ldx]   = A[1]*z[0] + A[4]*z[1] + A[7]*z[2];
413:   y[ldx*2] = A[2]*z[0] + A[5]*z[1] + A[8]*z[2];
414:   (void)PetscLogFlops(15.0);
415: }

417: PETSC_STATIC_INLINE void DMPlex_MatMult2D_Internal(const PetscScalar A[], PetscInt n, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
418: {
419:   PetscInt j;
420:   for (j = 0; j < n; ++j) {
421:     PetscScalar z[2];
422:     z[0] = B[0+j]; z[1] = B[1*ldb+j];
423:     DMPlex_Mult2D_Internal(A, 1, z, z);
424:     C[0+j] = z[0]; C[1*ldb+j] = z[1];
425:   }
426:   (void)PetscLogFlops(8.0*n);
427: }
428: PETSC_STATIC_INLINE void DMPlex_MatMult3D_Internal(const PetscScalar A[], PetscInt n, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
429: {
430:   PetscInt j;
431:   for (j = 0; j < n; ++j) {
432:     PetscScalar z[3];
433:     z[0] = B[0+j]; z[1] = B[1*ldb+j]; z[2] = B[2*ldb+j];
434:     DMPlex_Mult3D_Internal(A, 1, z, z);
435:     C[0+j] = z[0]; C[1*ldb+j] = z[1]; C[2*ldb+j] = z[2];
436:   }
437:   (void)PetscLogFlops(8.0*n);
438: }
439: PETSC_STATIC_INLINE void DMPlex_MatMultTranspose2D_Internal(const PetscScalar A[], PetscInt n, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
440: {
441:   PetscInt j;
442:   for (j = 0; j < n; ++j) {
443:     PetscScalar z[2];
444:     z[0] = B[0+j]; z[1] = B[1*ldb+j];
445:     DMPlex_MultTranspose2D_Internal(A, 1, z, z);
446:     C[0+j] = z[0]; C[1*ldb+j] = z[1];
447:   }
448:   (void)PetscLogFlops(8.0*n);
449: }
450: PETSC_STATIC_INLINE void DMPlex_MatMultTranspose3D_Internal(const PetscScalar A[], PetscInt n, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
451: {
452:   PetscInt j;
453:   for (j = 0; j < n; ++j) {
454:     PetscScalar z[3];
455:     z[0] = B[0+j]; z[1] = B[1*ldb+j]; z[2] = B[2*ldb+j];
456:     DMPlex_MultTranspose3D_Internal(A, 1, z, z);
457:     C[0+j] = z[0]; C[1*ldb+j] = z[1]; C[2*ldb+j] = z[2];
458:   }
459:   (void)PetscLogFlops(8.0*n);
460: }

462: PETSC_STATIC_INLINE void DMPlex_MatMultLeft2D_Internal(const PetscScalar A[], PetscInt m, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
463: {
464:   PetscInt j;
465:   for (j = 0; j < m; ++j) {
466:     DMPlex_MultTranspose2D_Internal(A, 1, &B[j*ldb], &C[j*ldb]);
467:   }
468:   (void)PetscLogFlops(8.0*m);
469: }
470: PETSC_STATIC_INLINE void DMPlex_MatMultLeft3D_Internal(const PetscScalar A[], PetscInt m, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
471: {
472:   PetscInt j;
473:   for (j = 0; j < m; ++j) {
474:     DMPlex_MultTranspose3D_Internal(A, 1, &B[j*ldb], &C[j*ldb]);
475:   }
476:   (void)PetscLogFlops(8.0*m);
477: }
478: PETSC_STATIC_INLINE void DMPlex_MatMultTransposeLeft2D_Internal(const PetscScalar A[], PetscInt m, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
479: {
480:   PetscInt j;
481:   for (j = 0; j < m; ++j) {
482:     DMPlex_Mult2D_Internal(A, 1, &B[j*ldb], &C[j*ldb]);
483:   }
484:   (void)PetscLogFlops(8.0*m);
485: }
486: PETSC_STATIC_INLINE void DMPlex_MatMultTransposeLeft3D_Internal(const PetscScalar A[], PetscInt m, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
487: {
488:   PetscInt j;
489:   for (j = 0; j < m; ++j) {
490:     DMPlex_Mult3D_Internal(A, 1, &B[j*ldb], &C[j*ldb]);
491:   }
492:   (void)PetscLogFlops(8.0*m);
493: }

495: PETSC_STATIC_INLINE void DMPlex_PTAP2DReal_Internal(const PetscReal P[], const PetscScalar A[], PetscScalar C[])
496: {
497:   PetscScalar out[4];
498:   PetscInt i, j, k, l;
499:   for (i = 0; i < 2; ++i) {
500:     for (j = 0; j < 2; ++j) {
501:       out[i*2+j] = 0.;
502:       for (k = 0; k < 2; ++k) {
503:         for (l = 0; l < 2; ++l) {
504:           out[i*2+j] += P[k*2+i]*A[k*2+l]*P[l*2+j];
505:         }
506:       }
507:     }
508:   }
509:   for (i = 0; i < 2*2; ++i) C[i] = out[i];
510:   (void)PetscLogFlops(48.0);
511: }
512: PETSC_STATIC_INLINE void DMPlex_PTAP3DReal_Internal(const PetscReal P[], const PetscScalar A[], PetscScalar C[])
513: {
514:   PetscScalar out[9];
515:   PetscInt i, j, k, l;
516:   for (i = 0; i < 3; ++i) {
517:     for (j = 0; j < 3; ++j) {
518:       out[i*2+j] = 0.;
519:       for (k = 0; k < 3; ++k) {
520:         for (l = 0; l < 3; ++l) {
521:           out[i*2+j] += P[k*2+i]*A[k*2+l]*P[l*2+j];
522:         }
523:       }
524:     }
525:   }
526:   for (i = 0; i < 2*2; ++i) C[i] = out[i];
527:   (void)PetscLogFlops(243.0);
528: }
529: /* TODO Fix for aliasing of A and C */
530: PETSC_STATIC_INLINE void DMPlex_PTAPReal_Internal(const PetscReal P[], PetscInt m, PetscInt n, const PetscScalar A[], PetscScalar C[])
531: {
532:   PetscInt i, j, k, l;
533:   for (i = 0; i < n; ++i) {
534:     for (j = 0; j < n; ++j) {
535:       C[i*n+j] = 0.;
536:       for (k = 0; k < m; ++k) {
537:         for (l = 0; l < m; ++l) {
538:           C[i*n+j] += P[k*n+i]*A[k*m+l]*P[l*n+j];
539:         }
540:       }
541:     }
542:   }
543:   (void)PetscLogFlops(243.0);
544: }

546: PETSC_STATIC_INLINE void DMPlex_Transpose2D_Internal(PetscScalar A[])
547: {
548:   PetscScalar tmp;
549:   tmp = A[1]; A[1] = A[2]; A[2] = tmp;
550: }
551: PETSC_STATIC_INLINE void DMPlex_Transpose3D_Internal(PetscScalar A[])
552: {
553:   PetscScalar tmp;
554:   tmp = A[1]; A[1] = A[3]; A[3] = tmp;
555:   tmp = A[2]; A[2] = A[6]; A[6] = tmp;
556:   tmp = A[5]; A[5] = A[7]; A[7] = tmp;
557: }

559: PETSC_STATIC_INLINE void DMPlex_Invert2D_Internal(PetscReal invJ[], PetscReal J[], PetscReal detJ)
560: {
561:   const PetscReal invDet = 1.0/detJ;

563:   invJ[0] =  invDet*J[3];
564:   invJ[1] = -invDet*J[1];
565:   invJ[2] = -invDet*J[2];
566:   invJ[3] =  invDet*J[0];
567:   (void)PetscLogFlops(5.0);
568: }

570: PETSC_STATIC_INLINE void DMPlex_Invert3D_Internal(PetscReal invJ[], PetscReal J[], PetscReal detJ)
571: {
572:   const PetscReal invDet = 1.0/detJ;

574:   invJ[0*3+0] = invDet*(J[1*3+1]*J[2*3+2] - J[1*3+2]*J[2*3+1]);
575:   invJ[0*3+1] = invDet*(J[0*3+2]*J[2*3+1] - J[0*3+1]*J[2*3+2]);
576:   invJ[0*3+2] = invDet*(J[0*3+1]*J[1*3+2] - J[0*3+2]*J[1*3+1]);
577:   invJ[1*3+0] = invDet*(J[1*3+2]*J[2*3+0] - J[1*3+0]*J[2*3+2]);
578:   invJ[1*3+1] = invDet*(J[0*3+0]*J[2*3+2] - J[0*3+2]*J[2*3+0]);
579:   invJ[1*3+2] = invDet*(J[0*3+2]*J[1*3+0] - J[0*3+0]*J[1*3+2]);
580:   invJ[2*3+0] = invDet*(J[1*3+0]*J[2*3+1] - J[1*3+1]*J[2*3+0]);
581:   invJ[2*3+1] = invDet*(J[0*3+1]*J[2*3+0] - J[0*3+0]*J[2*3+1]);
582:   invJ[2*3+2] = invDet*(J[0*3+0]*J[1*3+1] - J[0*3+1]*J[1*3+0]);
583:   (void)PetscLogFlops(37.0);
584: }

586: PETSC_STATIC_INLINE void DMPlex_Det2D_Internal(PetscReal *detJ, const PetscReal J[])
587: {
588:   *detJ = J[0]*J[3] - J[1]*J[2];
589:   (void)PetscLogFlops(3.0);
590: }

592: PETSC_STATIC_INLINE void DMPlex_Det3D_Internal(PetscReal *detJ, const PetscReal J[])
593: {
594:   *detJ = (J[0*3+0]*(J[1*3+1]*J[2*3+2] - J[1*3+2]*J[2*3+1]) +
595:            J[0*3+1]*(J[1*3+2]*J[2*3+0] - J[1*3+0]*J[2*3+2]) +
596:            J[0*3+2]*(J[1*3+0]*J[2*3+1] - J[1*3+1]*J[2*3+0]));
597:   (void)PetscLogFlops(12.0);
598: }

600: PETSC_STATIC_INLINE void DMPlex_Det2D_Scalar_Internal(PetscReal *detJ, const PetscScalar J[])
601: {
602:   *detJ = PetscRealPart(J[0])*PetscRealPart(J[3]) - PetscRealPart(J[1])*PetscRealPart(J[2]);
603:   (void)PetscLogFlops(3.0);
604: }

606: PETSC_STATIC_INLINE void DMPlex_Det3D_Scalar_Internal(PetscReal *detJ, const PetscScalar J[])
607: {
608:   *detJ = (PetscRealPart(J[0*3+0])*(PetscRealPart(J[1*3+1])*PetscRealPart(J[2*3+2]) - PetscRealPart(J[1*3+2])*PetscRealPart(J[2*3+1])) +
609:            PetscRealPart(J[0*3+1])*(PetscRealPart(J[1*3+2])*PetscRealPart(J[2*3+0]) - PetscRealPart(J[1*3+0])*PetscRealPart(J[2*3+2])) +
610:            PetscRealPart(J[0*3+2])*(PetscRealPart(J[1*3+0])*PetscRealPart(J[2*3+1]) - PetscRealPart(J[1*3+1])*PetscRealPart(J[2*3+0])));
611:   (void)PetscLogFlops(12.0);
612: }

614: PETSC_STATIC_INLINE void DMPlex_WaxpyD_Internal(PetscInt dim, PetscReal a, const PetscReal *x, const PetscReal *y, PetscReal *w) {PetscInt d; for (d = 0; d < dim; ++d) w[d] = a*x[d] + y[d];}

616: PETSC_STATIC_INLINE PetscReal DMPlex_DotD_Internal(PetscInt dim, const PetscScalar *x, const PetscReal *y) {PetscReal sum = 0.0; PetscInt d; for (d = 0; d < dim; ++d) sum += PetscRealPart(x[d])*y[d]; return sum;}

618: PETSC_STATIC_INLINE PetscReal DMPlex_DotRealD_Internal(PetscInt dim, const PetscReal *x, const PetscReal *y) {PetscReal sum = 0.0; PetscInt d; for (d = 0; d < dim; ++d) sum += x[d]*y[d]; return sum;}

620: PETSC_STATIC_INLINE PetscReal DMPlex_NormD_Internal(PetscInt dim, const PetscReal *x) {PetscReal sum = 0.0; PetscInt d; for (d = 0; d < dim; ++d) sum += x[d]*x[d]; return PetscSqrtReal(sum);}

622: PETSC_STATIC_INLINE PetscReal DMPlex_DistD_Internal(PetscInt dim, const PetscScalar *x, const PetscScalar *y) {PetscReal sum = 0.0; PetscInt d; for (d = 0; d < dim; ++d) sum += PetscRealPart(PetscConj(x[d] - y[d])*(x[d] - y[d])); return PetscSqrtReal(sum);}

624: PETSC_STATIC_INLINE PetscErrorCode DMPlexFixFaceOrientations_Translate_Private(PetscInt ornt, PetscInt *start, PetscBool *reverse)
625: {
627:   *reverse = (ornt < 0) ? PETSC_TRUE : PETSC_FALSE;
628:   *start = *reverse ? -(ornt+1) : ornt;
629:   return(0);
630: }

632: PETSC_STATIC_INLINE PetscErrorCode DMPlexFixFaceOrientations_Combine_Private(PetscInt coneSize, PetscInt origStart, PetscBool origReverse, PetscInt rotateStart, PetscBool rotateReverse, PetscInt *newStart, PetscBool *newReverse)
633: {
635:   *newReverse = (origReverse == rotateReverse) ? PETSC_FALSE : PETSC_TRUE;
636:   *newStart = rotateReverse ? (coneSize + rotateStart - origStart) : (coneSize + origStart - rotateStart);
637:   *newStart %= coneSize;
638:   return(0);
639: }

641: PETSC_STATIC_INLINE PetscErrorCode DMPlexFixFaceOrientations_TranslateBack_Private(PetscInt coneSize, PetscInt start, PetscBool reverse, PetscInt *ornt)
642: {
644:   if (coneSize < 3) {
645:     /* edges just get flipped if start == 1 regardless direction */
646:     *ornt = start ? -2 : 0;
647:   } else {
648:     *ornt = reverse ? -(start+1) : start;
649:   }
650:   return(0);
651: }

653: PETSC_STATIC_INLINE PetscErrorCode DMPlexFixFaceOrientations_Permute_Private(PetscInt n, const PetscInt arr[], PetscInt start, PetscBool reverse, PetscInt newarr[])
654: {
655:   PetscInt i;

658:   if (reverse) {for (i=0; i<n; i++) newarr[i] = arr[(n+start-i)%n];}
659:   else         {for (i=0; i<n; i++) newarr[i] = arr[(start+i)%n];}
660:   return(0);
661: }

663: PETSC_INTERN PetscErrorCode DMPlexGetPointDualSpaceFEM(DM,PetscInt,PetscInt,PetscDualSpace *);
664: PETSC_INTERN PetscErrorCode DMPlexGetIndicesPoint_Internal(PetscSection,PetscBool,PetscInt,PetscInt,PetscInt *,PetscBool,const PetscInt[],const PetscInt[],PetscInt[]);
665: PETSC_INTERN PetscErrorCode DMPlexGetIndicesPointFields_Internal(PetscSection,PetscBool,PetscInt,PetscInt,PetscInt[],PetscBool,const PetscInt***,PetscInt,const PetscInt[],PetscInt[]);
666: PETSC_INTERN PetscErrorCode DMPlexGetCompressedClosure(DM, PetscSection, PetscInt, PetscInt *, PetscInt **, PetscSection *, IS *, const PetscInt **);
667: PETSC_INTERN PetscErrorCode DMPlexRestoreCompressedClosure(DM, PetscSection, PetscInt, PetscInt *, PetscInt **, PetscSection *, IS *, const PetscInt **);

669: PETSC_EXTERN PetscErrorCode DMSNESGetFEGeom(DMField, IS, PetscQuadrature, PetscBool, PetscFEGeom **);
670: PETSC_EXTERN PetscErrorCode DMSNESRestoreFEGeom(DMField, IS, PetscQuadrature, PetscBool, PetscFEGeom **);
671: PETSC_EXTERN PetscErrorCode DMPlexComputeResidual_Patch_Internal(DM, PetscSection, IS, PetscReal, Vec, Vec, Vec, void *);
672: PETSC_EXTERN PetscErrorCode DMPlexComputeJacobian_Patch_Internal(DM, PetscSection, PetscSection, IS, PetscReal, PetscReal, Vec, Vec, Mat, Mat, void *);
673: PETSC_INTERN PetscErrorCode DMCreateSubDomainDM_Plex(DM,DMLabel,PetscInt,IS*,DM*);
674: PETSC_INTERN PetscErrorCode DMPlexBasisTransformPoint_Internal(DM, DM, Vec, PetscInt, PetscBool[], PetscBool, PetscScalar *);
675: PETSC_EXTERN PetscErrorCode DMPlexBasisTransformPointTensor_Internal(DM, DM, Vec, PetscInt, PetscBool, PetscInt, PetscScalar *);
676: PETSC_INTERN PetscErrorCode DMPlexBasisTransformApplyReal_Internal(DM, const PetscReal[], PetscBool, PetscInt, const PetscReal *, PetscReal *, void *);
677: PETSC_INTERN PetscErrorCode DMPlexBasisTransformApply_Internal(DM, const PetscReal[], PetscBool, PetscInt, const PetscScalar *, PetscScalar *, void *);
678: PETSC_INTERN PetscErrorCode DMCreateNeumannOverlap_Plex(DM, IS*, Mat*, PetscErrorCode (**)(Mat, PetscReal, Vec, Vec, PetscReal, IS, void*), void **);

680: #endif /* _PLEXIMPL_H */