Actual source code: dmpleximpl.h
1: #pragma once
3: #include <petscmat.h>
4: #include <petscdmplex.h>
5: #include <petscdmplextransform.h>
6: #include <petscbt.h>
7: #include <petscsf.h>
8: #include <petsc/private/dmimpl.h>
10: #if PetscDefined(HAVE_EXODUSII)
11: #include <exodusII.h>
12: #endif
14: PETSC_INTERN PetscBool Plexcite;
15: PETSC_INTERN const char PlexCitation[];
17: PETSC_EXTERN PetscLogEvent DMPLEX_Interpolate;
18: PETSC_EXTERN PetscLogEvent DMPLEX_Partition;
19: PETSC_EXTERN PetscLogEvent DMPLEX_PartSelf;
20: PETSC_EXTERN PetscLogEvent DMPLEX_PartLabelInvert;
21: PETSC_EXTERN PetscLogEvent DMPLEX_PartLabelCreateSF;
22: PETSC_EXTERN PetscLogEvent DMPLEX_PartStratSF;
23: PETSC_EXTERN PetscLogEvent DMPLEX_CreatePointSF;
24: PETSC_EXTERN PetscLogEvent DMPLEX_Distribute;
25: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeMultistage;
26: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeCones;
27: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeLabels;
28: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeSF;
29: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeOverlap;
30: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeField;
31: PETSC_EXTERN PetscLogEvent DMPLEX_DistributeData;
32: PETSC_EXTERN PetscLogEvent DMPLEX_Migrate;
33: PETSC_EXTERN PetscLogEvent DMPLEX_InterpolateSF;
34: PETSC_EXTERN PetscLogEvent DMPLEX_GlobalToNaturalBegin;
35: PETSC_EXTERN PetscLogEvent DMPLEX_GlobalToNaturalEnd;
36: PETSC_EXTERN PetscLogEvent DMPLEX_NaturalToGlobalBegin;
37: PETSC_EXTERN PetscLogEvent DMPLEX_NaturalToGlobalEnd;
38: PETSC_EXTERN PetscLogEvent DMPLEX_Stratify;
39: PETSC_EXTERN PetscLogEvent DMPLEX_Symmetrize;
40: PETSC_EXTERN PetscLogEvent DMPLEX_Preallocate;
41: PETSC_EXTERN PetscLogEvent DMPLEX_ResidualFEM;
42: PETSC_EXTERN PetscLogEvent DMPLEX_JacobianFEM;
43: PETSC_EXTERN PetscLogEvent DMPLEX_InterpolatorFEM;
44: PETSC_EXTERN PetscLogEvent DMPLEX_InjectorFEM;
45: PETSC_EXTERN PetscLogEvent DMPLEX_IntegralFEM;
46: PETSC_EXTERN PetscLogEvent DMPLEX_CreateGmsh;
47: PETSC_EXTERN PetscLogEvent DMPLEX_CreateBoxSFC;
48: PETSC_EXTERN PetscLogEvent DMPLEX_RebalanceSharedPoints;
49: PETSC_EXTERN PetscLogEvent DMPLEX_CreateFromFile;
50: PETSC_EXTERN PetscLogEvent DMPLEX_CreateFromOptions;
51: PETSC_EXTERN PetscLogEvent DMPLEX_BuildFromCellList;
52: PETSC_EXTERN PetscLogEvent DMPLEX_BuildCoordinatesFromCellList;
53: PETSC_EXTERN PetscLogEvent DMPLEX_LocatePoints;
54: PETSC_EXTERN PetscLogEvent DMPLEX_TopologyView;
55: PETSC_EXTERN PetscLogEvent DMPLEX_DistributionView;
56: PETSC_EXTERN PetscLogEvent DMPLEX_LabelsView;
57: PETSC_EXTERN PetscLogEvent DMPLEX_CoordinatesView;
58: PETSC_EXTERN PetscLogEvent DMPLEX_SectionView;
59: PETSC_EXTERN PetscLogEvent DMPLEX_GlobalVectorView;
60: PETSC_EXTERN PetscLogEvent DMPLEX_LocalVectorView;
61: PETSC_EXTERN PetscLogEvent DMPLEX_TopologyLoad;
62: PETSC_EXTERN PetscLogEvent DMPLEX_DistributionLoad;
63: PETSC_EXTERN PetscLogEvent DMPLEX_LabelsLoad;
64: PETSC_EXTERN PetscLogEvent DMPLEX_CoordinatesLoad;
65: PETSC_EXTERN PetscLogEvent DMPLEX_SectionLoad;
66: PETSC_EXTERN PetscLogEvent DMPLEX_GlobalVectorLoad;
67: PETSC_EXTERN PetscLogEvent DMPLEX_LocalVectorLoad;
68: PETSC_EXTERN PetscLogEvent DMPLEX_MetricEnforceSPD;
69: PETSC_EXTERN PetscLogEvent DMPLEX_MetricNormalize;
70: PETSC_EXTERN PetscLogEvent DMPLEX_MetricAverage;
71: PETSC_EXTERN PetscLogEvent DMPLEX_MetricIntersection;
72: PETSC_EXTERN PetscLogEvent DMPLEX_Generate;
73: PETSC_EXTERN PetscLogEvent DMPLEX_GetLocalOffsets;
75: PETSC_EXTERN PetscLogEvent DMPLEX_RebalBuildGraph;
76: PETSC_EXTERN PetscLogEvent DMPLEX_RebalRewriteSF;
77: PETSC_EXTERN PetscLogEvent DMPLEX_RebalGatherGraph;
78: PETSC_EXTERN PetscLogEvent DMPLEX_RebalPartition;
79: PETSC_EXTERN PetscLogEvent DMPLEX_RebalScatterPart;
80: PETSC_EXTERN PetscLogEvent DMPLEX_Uninterpolate;
82: struct _n_PetscGridHash {
83: PetscInt dim;
84: PetscReal lower[3]; /* The lower-left corner */
85: PetscReal upper[3]; /* The upper-right corner */
86: PetscReal extent[3]; /* The box size */
87: PetscReal h[3]; /* The subbox size */
88: PetscInt n[3]; /* The number of subboxes */
89: PetscSection cellSection; /* Offsets for cells in each subbox*/
90: IS cells; /* List of cells in each subbox */
91: DMLabel cellsSparse; /* Sparse storage for cell map */
92: };
94: typedef struct {
95: PetscBool isotropic; /* Is the metric isotropic? */
96: PetscBool uniform; /* Is the metric uniform? */
97: PetscBool restrictAnisotropyFirst; /* Should anisotropy or normalization come first? */
98: PetscBool noInsert; /* Should node insertion/deletion be turned off? */
99: PetscBool noSwap; /* Should facet swapping be turned off? */
100: PetscBool noMove; /* Should node movement be turned off? */
101: PetscBool noSurf; /* Should surface modification be turned off? */
102: PetscReal h_min, h_max; /* Minimum/maximum tolerated metric magnitudes */
103: PetscReal a_max; /* Maximum tolerated anisotropy */
104: PetscReal targetComplexity; /* Target metric complexity */
105: PetscReal p; /* Degree for L-p normalization methods */
106: PetscReal gradationFactor; /* Maximum tolerated length ratio for adjacent edges */
107: PetscReal hausdorffNumber; /* Max. distance between piecewise linear representation of boundary and reconstructed ideal boundary */
108: PetscInt numIter; /* Number of ParMmg mesh adaptation iterations */
109: PetscInt verbosity; /* Level of verbosity for remesher (-1 = no output, 10 = maximum) */
110: } DMPlexMetricCtx;
112: /* Point Numbering in Plex:
114: Points are numbered contiguously by stratum. Strate are organized as follows:
116: First Stratum: Cells [height 0]
117: Second Stratum: Vertices [depth 0]
118: Third Stratum: Faces [height 1]
119: Fourth Stratum: Edges [depth 1]
121: We do this so that the numbering of a cell-vertex mesh does not change after interpolation. Within a given stratum,
122: we allow additional segregation of by cell type.
123: */
124: typedef struct {
125: PetscInt refct;
127: PetscSection coneSection; /* Layout of cones (inedges for DAG) */
128: PetscInt *cones; /* Cone for each point */
129: PetscInt *coneOrientations; /* Orientation of each cone point, means cone traversal should start on point 'o', and if negative start on -(o+1) and go in reverse */
130: PetscSection supportSection; /* Layout of cones (inedges for DAG) */
131: PetscInt *supports; /* Cone for each point */
133: struct { // DMPolytopeType is an enum (usually size 4), but this needs frequent access
134: uint8_t value_as_uint8; // in a struct to guard for stronger typing
135: } *cellTypes;
137: /* Transformation */
138: DMPlexTransform tr; /* Type of transform used to define an ephemeral mesh */
139: char *transformType; /* Type of transform for uniform cell refinement */
140: PetscBool refinementUniform; /* Flag for uniform cell refinement */
141: PetscReal refinementLimit; /* Maximum volume for refined cell */
142: PetscErrorCode (*refinementFunc)(const PetscReal[], PetscReal *); /* Function giving the maximum volume for refined cell */
144: /* Interpolation */
145: DMPlexInterpolatedFlag interpolated;
146: DMPlexInterpolatedFlag interpolatedCollective;
147: PetscBool interpolatePreferTensor; // When different orderings exist, prefer the tensor order
149: /* Ordering */
150: DMReorderDefaultFlag reorderDefault; /* Reorder the DM by default */
152: /* Distribution */
153: PetscBool distDefault; /* Distribute the DM by default */
154: PetscInt overlap; /* Overlap of the partitions as passed to DMPlexDistribute() or DMPlexDistributeOverlap() */
155: PetscInt numOvLabels; /* The number of labels used for candidate overlap points */
156: DMLabel ovLabels[16]; /* Labels used for candidate overlap points */
157: PetscInt ovValues[16]; /* Label values used for candidate overlap points */
158: PetscInt numOvExLabels; /* The number of labels used for exclusion */
159: DMLabel ovExLabels[16]; /* Labels used to exclude points from the overlap */
160: PetscInt ovExValues[16]; /* Label values used to exclude points from the overlap */
161: char *distributionName; /* Name of the specific parallel distribution of the DM */
162: MPI_Comm nonempty_comm; /* Communicator used for visualization when some processes do not have cells */
164: /* Hierarchy */
165: PetscBool regularRefinement; /* This flag signals that we are a regular refinement of coarseMesh */
167: /* Generation */
168: char *tetgenOpts; // COmmand line options for Tetgen
169: PetscReal tetgenRadiusEdgeBound; // Maximum tetgen radius-edge ratio
170: PetscReal tetgenDihedralBound; // Minimum tetgen dihedral angle
171: char *triangleOpts; // Comand line options for Triangle
172: PetscReal triangleAngBound; // Minimum triangle angle
173: PetscPartitioner partitioner; // Partitioner object
174: PetscBool partitionBalance; // Evenly divide partition overlap when distributing
175: PetscBool remeshBd;
177: /* Submesh */
178: DMLabel subpointMap; /* Label each original mesh point in the submesh with its depth, subpoint are the implicit numbering */
179: IS subpointIS; /* IS holding point number in the enclosing mesh of every point in the submesh chart */
180: PetscObjectState subpointState; /* The state of subpointMap when the subpointIS was last created */
182: /* Labels and numbering */
183: PetscObjectState depthState; /* State of depth label, so that we can determine if a user changes it */
184: PetscObjectState celltypeState; /* State of celltype label, so that we can determine if a user changes it */
185: IS globalVertexNumbers;
186: IS globalCellNumbers;
188: /* Constraints */
189: PetscSection anchorSection; /* maps constrained points to anchor points */
190: IS anchorIS; /* anchors indexed by the above section */
191: PetscErrorCode (*createanchors)(DM); /* automatically compute anchors (probably from tree constraints) */
192: PetscErrorCode (*computeanchormatrix)(DM, PetscSection, PetscSection, Mat);
194: /* Tree: automatically construct constraints for hierarchically non-conforming meshes */
195: PetscSection parentSection; /* dof == 1 if point has parent */
196: PetscInt *parents; /* point to parent */
197: PetscInt *childIDs; /* point to child ID */
198: PetscSection childSection; /* inverse of parent section */
199: PetscInt *children; /* point to children */
200: DM referenceTree; /* reference tree to which child ID's refer */
201: PetscErrorCode (*getchildsymmetry)(DM, PetscInt, PetscInt, PetscInt, PetscInt, PetscInt, PetscInt *, PetscInt *);
203: /* MATIS support */
204: PetscSection subdomainSection;
206: /* Adjacency */
207: PetscBool useAnchors; /* Replace constrained points with their anchors in adjacency lists */
208: PetscErrorCode (*useradjacency)(DM, PetscInt, PetscInt *, PetscInt[], void *); /* User callback for adjacency */
209: void *useradjacencyctx; /* User context for callback */
211: // Periodicity
212: struct {
213: // Specified by the user
214: PetscInt num_face_sfs; // number of face_sfs
215: PetscSF *face_sfs; // root(donor faces) <-- leaf(local faces)
216: PetscScalar (*transform)[4][4]; // geometric transform
217: // Created eagerly (depends on points)
218: PetscSF composed_sf; // root(non-periodic global points) <-- leaf(local points)
219: IS *periodic_points;
220: } periodic;
222: /* Projection */
223: PetscInt maxProjectionHeight; /* maximum height of cells used in DMPlexProject functions */
224: PetscInt activePoint; /* current active point in iteration */
226: /* Output */
227: PetscInt vtkCellHeight; /* The height of cells for output, default is 0 */
228: PetscReal scale[NUM_PETSC_UNITS]; /* The scale for each SI unit */
230: /* Geometry */
231: PetscReal minradius; /* Minimum distance from cell centroid to face */
232: PetscBool useHashLocation; /* Use grid hashing for point location */
233: PetscGridHash lbox; /* Local box for searching */
234: PetscPointFn *coordFunc; /* Function used to remap newly introduced vertices */
236: /* Neighbors */
237: PetscMPIInt *neighbors;
239: /* Metric */
240: DMPlexMetricCtx *metricCtx;
242: /* FEM */
243: PetscBool useCeed; /* This should convert to a registration system when there are more FEM backends */
244: PetscBool useMatClPerm; /* Use the closure permutation when assembling matrices */
246: /* CAD */
247: PetscBool ignoreModel; /* If TRUE, Plex refinement will skip Snap-To-Geometry feature ignoring attached CAD geometry information */
249: // Transforms
250: PetscBool saveTransform; // Flag to save transform, if this mesh was produced by a transform
251: DMPlexTransform transform; // Transform producing this mesh (note that this will hold on to the original mesh too)
253: /* Debugging */
254: PetscBool printSetValues;
255: PetscInt printAdj;
256: PetscInt printFEM;
257: PetscInt printFVM;
258: PetscInt printL2;
259: PetscInt printOrient;
260: PetscInt printLocate;
261: PetscInt printProject;
262: PetscInt printCohesive;
263: PetscReal printTol;
264: } DM_Plex;
266: PETSC_INTERN PetscErrorCode DMPlexCopy_Internal(DM, PetscBool, PetscBool, DM);
267: PETSC_INTERN PetscErrorCode DMPlexReplace_Internal(DM, DM *);
268: PETSC_INTERN PetscErrorCode DMPlexCopyEGADSInfo_Internal(DM, DM);
270: PETSC_INTERN PetscErrorCode DMPlexVTKWriteAll_VTU(DM, PetscViewer);
271: PETSC_INTERN PetscErrorCode VecView_Plex_Local(Vec, PetscViewer);
272: PETSC_INTERN PetscErrorCode VecView_Plex_Native(Vec, PetscViewer);
273: PETSC_INTERN PetscErrorCode VecView_Plex(Vec, PetscViewer);
274: PETSC_INTERN PetscErrorCode VecLoad_Plex_Local(Vec, PetscViewer);
275: PETSC_INTERN PetscErrorCode VecLoad_Plex_Native(Vec, PetscViewer);
276: PETSC_INTERN PetscErrorCode VecLoad_Plex(Vec, PetscViewer);
277: PETSC_INTERN PetscErrorCode DMPlexGetFieldType_Internal(DM, PetscSection, PetscInt, PetscInt *, PetscInt *, PetscViewerVTKFieldType *);
278: PETSC_INTERN PetscErrorCode DMPlexGetFieldTypes_Internal(DM, PetscSection, PetscInt, PetscInt *, PetscInt **, PetscInt **, PetscViewerVTKFieldType **);
279: PETSC_INTERN PetscErrorCode DMPlexRestoreFieldTypes_Internal(DM, PetscSection, PetscInt, PetscInt *, PetscInt **, PetscInt **, PetscViewerVTKFieldType **);
280: PETSC_INTERN PetscErrorCode DMPlexView_GLVis(DM, PetscViewer);
281: PETSC_INTERN PetscErrorCode DMSetUpGLVisViewer_Plex(PetscObject, PetscViewer);
282: #if PetscDefined(HAVE_HDF5)
283: PETSC_INTERN PetscErrorCode DMPlexTopologyView_HDF5_Internal(DM, IS, PetscViewer);
284: PETSC_INTERN PetscErrorCode DMPlexCoordinatesView_HDF5_Internal(DM, PetscViewer);
285: PETSC_INTERN PetscErrorCode DMPlexLabelsView_HDF5_Internal(DM, IS, PetscViewer);
286: PETSC_INTERN PetscErrorCode DMPlexSectionView_HDF5_Internal(DM, PetscViewer, DM);
287: PETSC_INTERN PetscErrorCode DMPlexGlobalVectorView_HDF5_Internal(DM, PetscViewer, DM, Vec);
288: PETSC_INTERN PetscErrorCode DMPlexLocalVectorView_HDF5_Internal(DM, PetscViewer, DM, Vec);
289: PETSC_INTERN PetscErrorCode DMPlexTopologyLoad_HDF5_Internal(DM, PetscViewer, PetscSF *);
290: PETSC_INTERN PetscErrorCode DMPlexCoordinatesLoad_HDF5_Internal(DM, PetscViewer, PetscSF);
291: PETSC_INTERN PetscErrorCode DMPlexLabelsLoad_HDF5_Internal(DM, PetscViewer, PetscSF);
292: PETSC_INTERN PetscErrorCode DMPlexSectionLoad_HDF5_Internal(DM, PetscViewer, DM, PetscSF, PetscSF *, PetscSF *);
293: PETSC_INTERN PetscErrorCode DMPlexVecLoad_HDF5_Internal(DM, PetscViewer, DM, PetscSF, Vec);
294: PETSC_INTERN PetscErrorCode DMPlexView_HDF5_Internal(DM, PetscViewer);
295: PETSC_INTERN PetscErrorCode DMPlexLoad_HDF5_Internal(DM, PetscViewer);
296: PETSC_INTERN PetscErrorCode DMPlexLoad_HDF5_Xdmf_Internal(DM, PetscViewer);
297: PETSC_INTERN PetscErrorCode VecView_Plex_HDF5_Internal(Vec, PetscViewer);
298: PETSC_INTERN PetscErrorCode VecView_Plex_HDF5_Native_Internal(Vec, PetscViewer);
299: PETSC_INTERN PetscErrorCode VecView_Plex_Local_HDF5_Internal(Vec, PetscViewer);
300: PETSC_INTERN PetscErrorCode VecLoad_Plex_HDF5_Internal(Vec, PetscViewer);
301: PETSC_INTERN PetscErrorCode VecLoad_Plex_HDF5_Native_Internal(Vec, PetscViewer);
302: #endif
303: PETSC_EXTERN PetscErrorCode VecView_Plex_Local_CGNS(Vec, PetscViewer);
304: #if PetscDefined(HAVE_CGNS)
305: PETSC_EXTERN PetscErrorCode VecLoad_Plex_CGNS_Internal(Vec, PetscViewer);
306: #endif
308: PETSC_INTERN PetscErrorCode DMPlexClosurePoints_Private(DM, PetscInt, const PetscInt[], IS *);
309: PETSC_INTERN PetscErrorCode DMSetFromOptions_NonRefinement_Plex(DM, PetscOptionItems);
310: PETSC_INTERN PetscErrorCode DMSetFromOptions_Overlap_Plex(DM, PetscOptionItems, PetscInt *);
311: PETSC_INTERN PetscErrorCode DMCoarsen_Plex(DM, MPI_Comm, DM *);
312: PETSC_INTERN PetscErrorCode DMCoarsenHierarchy_Plex(DM, PetscInt, DM[]);
313: PETSC_INTERN PetscErrorCode DMRefine_Plex(DM, MPI_Comm, DM *);
314: PETSC_INTERN PetscErrorCode DMRefineHierarchy_Plex(DM, PetscInt, DM[]);
315: PETSC_INTERN PetscErrorCode DMAdaptLabel_Plex(DM, Vec, DMLabel, DMLabel, DM *);
316: PETSC_INTERN PetscErrorCode DMExtrude_Plex(DM, PetscInt, DM *);
317: PETSC_INTERN PetscErrorCode DMPlexInsertBoundaryValues_Plex(DM, PetscBool, Vec, PetscReal, Vec, Vec, Vec);
318: PETSC_INTERN PetscErrorCode DMPlexInsertTimeDerivativeBoundaryValues_Plex(DM, PetscBool, Vec, PetscReal, Vec, Vec, Vec);
319: PETSC_INTERN PetscErrorCode DMPlexInsertBounds_Plex(DM, PetscBool, PetscReal, Vec);
320: PETSC_INTERN PetscErrorCode DMProjectFunctionLocal_Plex(DM, PetscReal, PetscErrorCode (**)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), void **, InsertMode, Vec);
321: 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);
322: 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);
323: 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);
324: 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);
325: PETSC_INTERN PetscErrorCode DMComputeL2Diff_Plex(DM, PetscReal, PetscErrorCode (**)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), void **, Vec, PetscReal *);
326: PETSC_INTERN PetscErrorCode DMComputeL2GradientDiff_Plex(DM, PetscReal, PetscErrorCode (**)(PetscInt, PetscReal, const PetscReal[], const PetscReal[], PetscInt, PetscScalar *, void *), void **, Vec, const PetscReal[], PetscReal *);
327: PETSC_INTERN PetscErrorCode DMComputeL2FieldDiff_Plex(DM, PetscReal, PetscErrorCode (**)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), void **, Vec, PetscReal *);
328: PETSC_INTERN PetscErrorCode DMLocatePoints_Plex(DM, Vec, DMPointLocationType, PetscSF);
330: #if PetscDefined(HAVE_EXODUSII)
331: PETSC_INTERN PetscErrorCode DMView_PlexExodusII(DM, PetscViewer);
332: PETSC_INTERN PetscErrorCode VecView_PlexExodusII_Internal(Vec, PetscViewer);
333: PETSC_INTERN PetscErrorCode VecLoad_PlexExodusII_Internal(Vec, PetscViewer);
334: #endif
335: PETSC_INTERN PetscErrorCode DMView_PlexCGNS(DM, PetscViewer);
336: PETSC_INTERN PetscErrorCode DMPlexCreateCGNSFromFile_Internal(MPI_Comm, const char *, PetscBool, DM *);
337: PETSC_INTERN PetscErrorCode DMPlexCreateCGNS_Internal_Serial(MPI_Comm, PetscInt, PetscBool, DM *);
338: PETSC_INTERN PetscErrorCode DMPlexCreateCGNS_Internal_Parallel(MPI_Comm, PetscInt, PetscBool, DM *);
339: PETSC_INTERN PetscErrorCode DMPlexVTKGetCellType_Internal(DM, PetscInt, PetscInt, PetscInt *);
340: PETSC_INTERN PetscErrorCode DMPlexGetAdjacency_Internal(DM, PetscInt, PetscBool, PetscBool, PetscBool, PetscInt *, PetscInt *[]);
341: PETSC_INTERN PetscErrorCode DMPlexGetMaxAdjacencySize_Internal(DM, PetscBool, PetscInt *);
342: PETSC_INTERN PetscErrorCode DMPlexGetRawFaces_Internal(DM, DMPolytopeType, const PetscInt[], PetscInt *, const DMPolytopeType *[], const PetscInt *[], const PetscInt *[]);
343: PETSC_INTERN PetscErrorCode DMPlexRestoreRawFaces_Internal(DM, DMPolytopeType, const PetscInt[], PetscInt *, const DMPolytopeType *[], const PetscInt *[], const PetscInt *[]);
344: PETSC_INTERN PetscErrorCode DMPlexComputeCellType_Internal(DM, PetscInt, PetscInt, DMPolytopeType *);
345: PETSC_INTERN PetscErrorCode DMPlexVecSetFieldClosure_Internal(DM, PetscSection, Vec, PetscBool[], PetscInt, PetscInt, const PetscInt[], DMLabel, PetscInt, const PetscScalar[], InsertMode);
346: PETSC_EXTERN PetscErrorCode DMPlexCreateReferenceTree_SetTree(DM, PetscSection, PetscInt[], PetscInt[]);
347: PETSC_EXTERN PetscErrorCode DMPlexCreateReferenceTree_Union(DM, DM, const char *, DM *);
348: PETSC_EXTERN PetscErrorCode DMPlexComputeInterpolatorTree(DM, DM, PetscSF, PetscInt *, Mat);
349: PETSC_EXTERN PetscErrorCode DMPlexComputeInjectorTree(DM, DM, PetscSF, PetscInt *, Mat);
350: PETSC_INTERN PetscErrorCode DMPlexAnchorsModifyMat(DM, PetscSection, PetscInt, PetscInt, const PetscInt[], const PetscInt ***, const PetscScalar[], PetscInt *, PetscInt *, PetscInt *[], PetscScalar *[], PetscInt[], PetscBool);
351: PETSC_INTERN PetscErrorCode DMPlexAnchorsModifyMat_Internal(DM, PetscSection, PetscInt, PetscInt, const PetscInt[], const PetscInt ***, PetscInt, PetscInt, const PetscScalar[], PetscInt *, PetscInt *, PetscInt *[], PetscScalar *[], PetscInt[], PetscBool, PetscBool);
352: PETSC_INTERN PetscErrorCode DMPlexAnchorsGetSubMatModification(DM, PetscSection, PetscInt, PetscInt, const PetscInt[], const PetscInt ***, PetscInt *, PetscInt *, PetscInt *[], PetscInt[], PetscScalar *[]);
353: PETSC_INTERN PetscErrorCode DMPlexLocatePoint_Internal(DM, PetscInt, const PetscScalar[], PetscInt, PetscInt *);
354: /* this is PETSC_EXTERN just because of src/dm/impls/plex/tests/ex18.c */
355: PETSC_EXTERN PetscErrorCode DMPlexOrientInterface_Internal(DM);
356: PETSC_INTERN PetscErrorCode DMPlexOrientCells_Internal(DM, IS, IS);
358: /* Applications may use this function */
359: PETSC_EXTERN PetscErrorCode DMPlexCreateNumbering_Plex(DM, PetscInt, PetscInt, PetscInt, PetscInt *, PetscSF, IS *);
361: PETSC_INTERN PetscErrorCode DMPlexInterpolateInPlace_Internal(DM);
362: PETSC_INTERN PetscErrorCode DMPlexCreateBoxMesh_Tensor_SFC_Internal(DM, PetscInt, const PetscInt[], const PetscReal[], const PetscReal[], const DMBoundaryType[], PetscBool);
363: PETSC_INTERN PetscErrorCode DMPlexMigrateIsoperiodicFaceSF_Internal(DM, DM, PetscSF);
364: PETSC_INTERN PetscErrorCode DMPlexCurveTypeResolve_Internal(MPI_Comm, DMPlexCurveType, PetscBool *);
365: PETSC_INTERN PetscErrorCode DMPlexGetCellOrderingByCurve_Internal(DM, DMPlexCurveType, PetscInt, PetscInt, PetscInt[]);
366: PETSC_INTERN PetscErrorCode DMPlexCreateVertexNumbering_Internal(DM, PetscBool, IS *);
367: PETSC_INTERN PetscErrorCode DMPlexRefine_Internal(DM, Vec, DMLabel, DMLabel, DM *);
368: PETSC_INTERN PetscErrorCode DMPlexCoarsen_Internal(DM, Vec, DMLabel, DMLabel, DM *);
369: PETSC_INTERN PetscErrorCode DMCreateMatrix_Plex(DM, Mat *);
371: PETSC_INTERN PetscErrorCode DMPlexGetOverlap_Plex(DM, PetscInt *);
372: PETSC_INTERN PetscErrorCode DMPlexSetOverlap_Plex(DM, DM, PetscInt);
373: PETSC_INTERN PetscErrorCode DMPlexDistributeGetDefault_Plex(DM, PetscBool *);
374: PETSC_INTERN PetscErrorCode DMPlexDistributeSetDefault_Plex(DM, PetscBool);
375: PETSC_INTERN PetscErrorCode DMPlexReorderGetDefault_Plex(DM, DMReorderDefaultFlag *);
376: PETSC_INTERN PetscErrorCode DMPlexReorderSetDefault_Plex(DM, DMReorderDefaultFlag);
377: PETSC_INTERN PetscErrorCode DMPlexGetUseCeed_Plex(DM, PetscBool *);
378: PETSC_INTERN PetscErrorCode DMPlexSetUseCeed_Plex(DM, PetscBool);
379: PETSC_INTERN PetscErrorCode DMReorderSectionGetDefault_Plex(DM, DMReorderDefaultFlag *);
380: PETSC_INTERN PetscErrorCode DMReorderSectionSetDefault_Plex(DM, DMReorderDefaultFlag);
381: PETSC_INTERN PetscErrorCode DMReorderSectionGetType_Plex(DM, MatOrderingType *);
382: PETSC_INTERN PetscErrorCode DMReorderSectionSetType_Plex(DM, MatOrderingType);
384: #if 1
385: static inline PetscInt DihedralInvert(PetscInt N, PetscInt a)
386: {
387: return (a <= 0) ? a : (N - a);
388: }
390: static inline PetscInt DihedralCompose(PetscInt N, PetscInt a, PetscInt b)
391: {
392: if (!N) return 0;
393: return (a >= 0) ? ((b >= 0) ? ((a + b) % N) : -(((a - b - 1) % N) + 1)) : ((b >= 0) ? -(((N - b - a - 1) % N) + 1) : ((N + b - a) % N));
394: }
396: static inline PetscInt DihedralSwap(PetscInt N, PetscInt a, PetscInt b)
397: {
398: return DihedralCompose(N, DihedralInvert(N, a), b);
399: }
400: #else
401: /* TODO
402: This is a reimplementation of the tensor dihedral symmetries using the new orientations.
403: These should be turned on when we convert to new-style orientations in p4est.
404: */
405: /* invert dihedral symmetry: return a^-1,
406: * using the representation described in
407: * DMPlexGetConeOrientation() */
408: static inline PetscInt DihedralInvert(PetscInt N, PetscInt a)
409: {
410: switch (N) {
411: case 0:
412: return 0;
413: case 2:
414: return DMPolytopeTypeComposeOrientationInv(DM_POLYTOPE_SEGMENT, 0, a);
415: case 4:
416: return DMPolytopeTypeComposeOrientationInv(DM_POLYTOPE_QUADRILATERAL, 0, a);
417: case 8:
418: return DMPolytopeTypeComposeOrientationInv(DM_POLYTOPE_HEXAHEDRON, 0, a);
419: default:
420: SETERRABORT(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid celltype for DihedralInvert()");
421: }
422: return 0;
423: }
425: /* compose dihedral symmetry: return b * a,
426: * using the representation described in
427: * DMPlexGetConeOrientation() */
428: static inline PetscInt DihedralCompose(PetscInt N, PetscInt a, PetscInt b)
429: {
430: switch (N) {
431: case 0:
432: return 0;
433: case 2:
434: return DMPolytopeTypeComposeOrientationInv(DM_POLYTOPE_SEGMENT, b, a);
435: case 4:
436: return DMPolytopeTypeComposeOrientationInv(DM_POLYTOPE_QUADRILATERAL, b, a);
437: case 8:
438: return DMPolytopeTypeComposeOrientationInv(DM_POLYTOPE_HEXAHEDRON, b, a);
439: default:
440: SETERRABORT(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid celltype for DihedralCompose()");
441: }
442: return 0;
443: }
445: /* swap dihedral symmetries: return b * a^-1,
446: * using the representation described in
447: * DMPlexGetConeOrientation() */
448: static inline PetscInt DihedralSwap(PetscInt N, PetscInt a, PetscInt b)
449: {
450: switch (N) {
451: case 0:
452: return 0;
453: case 2:
454: return DMPolytopeTypeComposeOrientationInv(DM_POLYTOPE_SEGMENT, b, a);
455: case 4:
456: return DMPolytopeTypeComposeOrientationInv(DM_POLYTOPE_QUADRILATERAL, b, a);
457: case 8:
458: return DMPolytopeTypeComposeOrientationInv(DM_POLYTOPE_HEXAHEDRON, b, a);
459: default:
460: SETERRABORT(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid celltype for DihedralCompose()");
461: }
462: return 0;
463: }
464: #endif
465: PETSC_INTERN PetscInt DMPolytopeConvertNewOrientation_Internal(DMPolytopeType, PetscInt);
466: PETSC_INTERN PetscInt DMPolytopeConvertOldOrientation_Internal(DMPolytopeType, PetscInt);
467: PETSC_INTERN PetscErrorCode DMPlexConvertOldOrientations_Internal(DM);
469: PETSC_SINGLE_LIBRARY_VISIBILITY_INTERNAL PetscErrorCode DMPlexComputeIntegral_Internal(DM, Vec, PetscInt, PetscInt, PetscScalar *, void *);
470: PETSC_INTERN PetscErrorCode DMPlexReconstructGradients_Internal(DM, PetscFV, PetscInt, PetscInt, Vec, Vec, Vec, Vec);
472: /* Matvec with A in row-major storage, x and y can be aliased */
473: static inline void DMPlex_Mult2D_Internal(const PetscScalar A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
474: {
475: const PetscScalar z[2] = {x[0 * ldx], x[1 * ldx]};
476: y[0 * ldx] = A[0] * z[0] + A[1] * z[1];
477: y[1 * ldx] = A[2] * z[0] + A[3] * z[1];
478: (void)PetscLogFlops(6.0);
479: }
480: static inline void DMPlex_Mult3D_Internal(const PetscScalar A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
481: {
482: const PetscScalar z[3] = {x[0 * ldx], x[1 * ldx], x[2 * ldx]};
483: y[0 * ldx] = A[0] * z[0] + A[1] * z[1] + A[2] * z[2];
484: y[1 * ldx] = A[3] * z[0] + A[4] * z[1] + A[5] * z[2];
485: y[2 * ldx] = A[6] * z[0] + A[7] * z[1] + A[8] * z[2];
486: (void)PetscLogFlops(15.0);
487: }
488: static inline void DMPlex_MultTranspose2D_Internal(const PetscScalar A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
489: {
490: const PetscScalar z[2] = {x[0 * ldx], x[1 * ldx]};
491: y[0 * ldx] = A[0] * z[0] + A[2] * z[1];
492: y[1 * ldx] = A[1] * z[0] + A[3] * z[1];
493: (void)PetscLogFlops(6.0);
494: }
495: static inline void DMPlex_MultTranspose3D_Internal(const PetscScalar A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
496: {
497: const PetscScalar z[3] = {x[0 * ldx], x[1 * ldx], x[2 * ldx]};
498: y[0 * ldx] = PetscConj(A[0]) * z[0] + PetscConj(A[3]) * z[1] + PetscConj(A[6]) * z[2];
499: y[1 * ldx] = PetscConj(A[1]) * z[0] + PetscConj(A[4]) * z[1] + PetscConj(A[7]) * z[2];
500: y[2 * ldx] = PetscConj(A[2]) * z[0] + PetscConj(A[5]) * z[1] + PetscConj(A[8]) * z[2];
501: (void)PetscLogFlops(15.0);
502: }
503: static inline void DMPlex_Mult2DReal_Internal(const PetscReal A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
504: {
505: const PetscScalar z[2] = {x[0 * ldx], x[1 * ldx]};
506: y[0 * ldx] = A[0] * z[0] + A[1] * z[1];
507: y[1 * ldx] = A[2] * z[0] + A[3] * z[1];
508: (void)PetscLogFlops(6.0);
509: }
510: static inline void DMPlex_Mult3DReal_Internal(const PetscReal A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
511: {
512: const PetscScalar z[3] = {x[0 * ldx], x[1 * ldx], x[2 * ldx]};
513: y[0 * ldx] = A[0] * z[0] + A[1] * z[1] + A[2] * z[2];
514: y[1 * ldx] = A[3] * z[0] + A[4] * z[1] + A[5] * z[2];
515: y[2 * ldx] = A[6] * z[0] + A[7] * z[1] + A[8] * z[2];
516: (void)PetscLogFlops(15.0);
517: }
518: static inline void DMPlex_MultAdd2DReal_Internal(const PetscReal A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
519: {
520: const PetscScalar z[2] = {x[0 * ldx], x[1 * ldx]};
521: y[0 * ldx] += A[0] * z[0] + A[1] * z[1];
522: y[1 * ldx] += A[2] * z[0] + A[3] * z[1];
523: (void)PetscLogFlops(6.0);
524: }
525: static inline void DMPlex_MultAdd3DReal_Internal(const PetscReal A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
526: {
527: const PetscScalar z[3] = {x[0 * ldx], x[1 * ldx], x[2 * ldx]};
528: y[0 * ldx] += A[0] * z[0] + A[1] * z[1] + A[2] * z[2];
529: y[1 * ldx] += A[3] * z[0] + A[4] * z[1] + A[5] * z[2];
530: y[2 * ldx] += A[6] * z[0] + A[7] * z[1] + A[8] * z[2];
531: (void)PetscLogFlops(15.0);
532: }
533: /*
534: A: packed, row-major m x n array
535: x: length m array
536: y: length n arra
537: ldx: the stride in x and y
539: A[i,j] = A[i * n + j]
540: A^T[j,i] = A[i,j]
541: */
542: static inline void DMPlex_MultTransposeReal_Internal(const PetscReal A[], PetscInt m, PetscInt n, PetscInt ldx, const PetscScalar x[], PetscScalar y[])
543: {
544: PetscScalar z[3];
545: PetscInt i, j;
546: for (i = 0; i < m; ++i) z[i] = x[i * ldx];
547: for (j = 0; j < n; ++j) {
548: const PetscInt l = j * ldx;
549: y[l] = 0;
550: for (i = 0; i < m; ++i) y[l] += A[i * n + j] * z[i];
551: }
552: (void)PetscLogFlops(2 * m * n);
553: }
554: static inline void DMPlex_MultTranspose2DReal_Internal(const PetscReal A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
555: {
556: const PetscScalar z[2] = {x[0 * ldx], x[1 * ldx]};
557: y[0 * ldx] = A[0] * z[0] + A[2] * z[1];
558: y[1 * ldx] = A[1] * z[0] + A[3] * z[1];
559: (void)PetscLogFlops(6.0);
560: }
561: static inline void DMPlex_MultTranspose3DReal_Internal(const PetscReal A[], PetscInt ldx, const PetscScalar x[], PetscScalar y[])
562: {
563: const PetscScalar z[3] = {x[0 * ldx], x[1 * ldx], x[2 * ldx]};
564: y[0 * ldx] = A[0] * z[0] + A[3] * z[1] + A[6] * z[2];
565: y[1 * ldx] = A[1] * z[0] + A[4] * z[1] + A[7] * z[2];
566: y[2 * ldx] = A[2] * z[0] + A[5] * z[1] + A[8] * z[2];
567: (void)PetscLogFlops(15.0);
568: }
570: static inline void DMPlex_MatMult2D_Internal(const PetscScalar A[], PetscInt n, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
571: {
572: #define PLEX_DIM__ 2
573: PetscScalar z[PLEX_DIM__];
574: for (PetscInt j = 0; j < n; ++j) {
575: for (int d = 0; d < PLEX_DIM__; ++d) z[d] = B[d * ldb + j];
576: DMPlex_Mult2D_Internal(A, 1, z, z);
577: for (int d = 0; d < PLEX_DIM__; ++d) C[d * ldb + j] = z[d];
578: }
579: (void)PetscLogFlops(8.0 * n);
580: #undef PLEX_DIM__
581: }
582: static inline void DMPlex_MatMult3D_Internal(const PetscScalar A[], PetscInt n, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
583: {
584: #define PLEX_DIM__ 3
585: PetscScalar z[PLEX_DIM__];
586: for (PetscInt j = 0; j < n; ++j) {
587: for (int d = 0; d < PLEX_DIM__; ++d) z[d] = B[d * ldb + j];
588: DMPlex_Mult3D_Internal(A, 1, z, z);
589: for (int d = 0; d < PLEX_DIM__; ++d) C[d * ldb + j] = z[d];
590: }
591: (void)PetscLogFlops(8.0 * n);
592: #undef PLEX_DIM__
593: }
594: static inline void DMPlex_MatMultTranspose2D_Internal(const PetscScalar A[], PetscInt n, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
595: {
596: #define PLEX_DIM__ 2
597: PetscScalar z[PLEX_DIM__];
598: for (PetscInt j = 0; j < n; ++j) {
599: for (int d = 0; d < PLEX_DIM__; ++d) z[d] = B[d * ldb + j];
600: DMPlex_MultTranspose2D_Internal(A, 1, z, z);
601: for (int d = 0; d < PLEX_DIM__; ++d) C[d * ldb + j] = z[d];
602: }
603: (void)PetscLogFlops(8.0 * n);
604: #undef PLEX_DIM__
605: }
606: static inline void DMPlex_MatMultTranspose3D_Internal(const PetscScalar A[], PetscInt n, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
607: {
608: #define PLEX_DIM__ 3
609: PetscScalar z[PLEX_DIM__];
610: for (PetscInt j = 0; j < n; ++j) {
611: for (int d = 0; d < PLEX_DIM__; ++d) z[d] = B[d * ldb + j];
612: DMPlex_MultTranspose3D_Internal(A, 1, z, z);
613: for (int d = 0; d < PLEX_DIM__; ++d) C[d * ldb + j] = z[d];
614: }
615: (void)PetscLogFlops(8.0 * n);
616: #undef PLEX_DIM__
617: }
619: static inline void DMPlex_MatMultLeft2D_Internal(const PetscScalar A[], PetscInt m, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
620: {
621: for (PetscInt j = 0; j < m; ++j) DMPlex_MultTranspose2D_Internal(A, 1, &B[j * ldb], &C[j * ldb]);
622: (void)PetscLogFlops(8.0 * m);
623: }
624: static inline void DMPlex_MatMultLeft3D_Internal(const PetscScalar A[], PetscInt m, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
625: {
626: for (PetscInt j = 0; j < m; ++j) DMPlex_MultTranspose3D_Internal(A, 1, &B[j * ldb], &C[j * ldb]);
627: (void)PetscLogFlops(8.0 * m);
628: }
629: static inline void DMPlex_MatMultTransposeLeft2D_Internal(const PetscScalar A[], PetscInt m, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
630: {
631: for (PetscInt j = 0; j < m; ++j) DMPlex_Mult2D_Internal(A, 1, &B[j * ldb], &C[j * ldb]);
632: (void)PetscLogFlops(8.0 * m);
633: }
634: static inline void DMPlex_MatMultTransposeLeft3D_Internal(const PetscScalar A[], PetscInt m, PetscInt ldb, const PetscScalar B[], PetscScalar C[])
635: {
636: for (PetscInt j = 0; j < m; ++j) DMPlex_Mult3D_Internal(A, 1, &B[j * ldb], &C[j * ldb]);
637: (void)PetscLogFlops(8.0 * m);
638: }
640: static inline void DMPlex_PTAP2DReal_Internal(const PetscReal P[], const PetscScalar A[], PetscScalar C[])
641: {
642: PetscScalar out[4];
643: PetscInt i, j, k, l;
644: for (i = 0; i < 2; ++i) {
645: for (j = 0; j < 2; ++j) {
646: out[i * 2 + j] = 0.;
647: for (k = 0; k < 2; ++k) {
648: for (l = 0; l < 2; ++l) out[i * 2 + j] += P[k * 2 + i] * A[k * 2 + l] * P[l * 2 + j];
649: }
650: }
651: }
652: for (i = 0; i < 2 * 2; ++i) C[i] = out[i];
653: (void)PetscLogFlops(48.0);
654: }
655: static inline void DMPlex_PTAP3DReal_Internal(const PetscReal P[], const PetscScalar A[], PetscScalar C[])
656: {
657: PetscScalar out[9];
658: PetscInt i, j, k, l;
659: for (i = 0; i < 3; ++i) {
660: for (j = 0; j < 3; ++j) {
661: out[i * 3 + j] = 0.;
662: for (k = 0; k < 3; ++k) {
663: for (l = 0; l < 3; ++l) out[i * 3 + j] += P[k * 3 + i] * A[k * 3 + l] * P[l * 3 + j];
664: }
665: }
666: }
667: for (i = 0; i < 2 * 2; ++i) C[i] = out[i];
668: (void)PetscLogFlops(243.0);
669: }
670: /* TODO Fix for aliasing of A and C */
671: static inline void DMPlex_PTAPReal_Internal(const PetscReal P[], PetscInt m, PetscInt n, const PetscScalar A[], PetscScalar C[])
672: {
673: PetscInt i, j, k, l;
674: for (i = 0; i < n; ++i) {
675: for (j = 0; j < n; ++j) {
676: C[i * n + j] = 0.;
677: for (k = 0; k < m; ++k) {
678: for (l = 0; l < m; ++l) C[i * n + j] += P[k * n + i] * A[k * m + l] * P[l * n + j];
679: }
680: }
681: }
682: (void)PetscLogFlops(243.0);
683: }
685: static inline void DMPlex_Transpose2D_Internal(PetscScalar A[])
686: {
687: PetscScalar tmp;
688: tmp = A[1];
689: A[1] = A[2];
690: A[2] = tmp;
691: }
692: static inline void DMPlex_Transpose3D_Internal(PetscScalar A[])
693: {
694: PetscScalar tmp;
695: tmp = A[1];
696: A[1] = A[3];
697: A[3] = tmp;
698: tmp = A[2];
699: A[2] = A[6];
700: A[6] = tmp;
701: tmp = A[5];
702: A[5] = A[7];
703: A[7] = tmp;
704: }
706: static inline void DMPlex_Invert2D_Internal(PetscReal invJ[], PetscReal J[], PetscReal detJ)
707: {
708: // Allow zero volume cells
709: const PetscReal invDet = detJ == 0 ? 1.0 : (PetscReal)1.0 / detJ;
711: invJ[0] = invDet * J[3];
712: invJ[1] = -invDet * J[1];
713: invJ[2] = -invDet * J[2];
714: invJ[3] = invDet * J[0];
715: (void)PetscLogFlops(5.0);
716: }
718: static inline void DMPlex_Invert3D_Internal(PetscReal invJ[], PetscReal J[], PetscReal detJ)
719: {
720: // Allow zero volume cells
721: const PetscReal invDet = detJ == 0 ? 1.0 : (PetscReal)1.0 / detJ;
723: invJ[0 * 3 + 0] = invDet * (J[1 * 3 + 1] * J[2 * 3 + 2] - J[1 * 3 + 2] * J[2 * 3 + 1]);
724: invJ[0 * 3 + 1] = invDet * (J[0 * 3 + 2] * J[2 * 3 + 1] - J[0 * 3 + 1] * J[2 * 3 + 2]);
725: invJ[0 * 3 + 2] = invDet * (J[0 * 3 + 1] * J[1 * 3 + 2] - J[0 * 3 + 2] * J[1 * 3 + 1]);
726: invJ[1 * 3 + 0] = invDet * (J[1 * 3 + 2] * J[2 * 3 + 0] - J[1 * 3 + 0] * J[2 * 3 + 2]);
727: invJ[1 * 3 + 1] = invDet * (J[0 * 3 + 0] * J[2 * 3 + 2] - J[0 * 3 + 2] * J[2 * 3 + 0]);
728: invJ[1 * 3 + 2] = invDet * (J[0 * 3 + 2] * J[1 * 3 + 0] - J[0 * 3 + 0] * J[1 * 3 + 2]);
729: invJ[2 * 3 + 0] = invDet * (J[1 * 3 + 0] * J[2 * 3 + 1] - J[1 * 3 + 1] * J[2 * 3 + 0]);
730: invJ[2 * 3 + 1] = invDet * (J[0 * 3 + 1] * J[2 * 3 + 0] - J[0 * 3 + 0] * J[2 * 3 + 1]);
731: invJ[2 * 3 + 2] = invDet * (J[0 * 3 + 0] * J[1 * 3 + 1] - J[0 * 3 + 1] * J[1 * 3 + 0]);
732: (void)PetscLogFlops(37.0);
733: }
735: static inline void DMPlex_Det2D_Internal(PetscReal *detJ, const PetscReal J[])
736: {
737: *detJ = J[0] * J[3] - J[1] * J[2];
738: (void)PetscLogFlops(3.0);
739: }
741: static inline void DMPlex_Det3D_Internal(PetscReal *detJ, const PetscReal J[])
742: {
743: *detJ = (J[0 * 3 + 0] * (J[1 * 3 + 1] * J[2 * 3 + 2] - J[1 * 3 + 2] * J[2 * 3 + 1]) + J[0 * 3 + 1] * (J[1 * 3 + 2] * J[2 * 3 + 0] - J[1 * 3 + 0] * J[2 * 3 + 2]) + J[0 * 3 + 2] * (J[1 * 3 + 0] * J[2 * 3 + 1] - J[1 * 3 + 1] * J[2 * 3 + 0]));
744: (void)PetscLogFlops(12.0);
745: }
747: static inline void DMPlex_Det2D_Scalar_Internal(PetscReal *detJ, const PetscScalar J[])
748: {
749: *detJ = PetscRealPart(J[0]) * PetscRealPart(J[3]) - PetscRealPart(J[1]) * PetscRealPart(J[2]);
750: (void)PetscLogFlops(3.0);
751: }
753: static inline void DMPlex_Det3D_Scalar_Internal(PetscReal *detJ, const PetscScalar J[])
754: {
755: *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])) + 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])) + 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])));
756: (void)PetscLogFlops(12.0);
757: }
759: static inline void DMPlex_WaxpyD_Internal(PetscInt dim, PetscReal a, const PetscReal *x, const PetscReal *y, PetscReal *w)
760: {
761: PetscInt d;
762: for (d = 0; d < dim; ++d) w[d] = a * x[d] + y[d];
763: }
765: static inline PetscReal DMPlex_DotD_Internal(PetscInt dim, const PetscScalar *x, const PetscReal *y)
766: {
767: PetscReal sum = 0.0;
768: PetscInt d;
769: for (d = 0; d < dim; ++d) sum += PetscRealPart(x[d]) * y[d];
770: return sum;
771: }
773: static inline PetscReal DMPlex_DotRealD_Internal(PetscInt dim, const PetscReal *x, const PetscReal *y)
774: {
775: PetscReal sum = 0.0;
776: PetscInt d;
777: for (d = 0; d < dim; ++d) sum += x[d] * y[d];
778: return sum;
779: }
781: static inline PetscReal DMPlex_NormD_Internal(PetscInt dim, const PetscReal *x)
782: {
783: PetscReal sum = 0.0;
784: PetscInt d;
785: for (d = 0; d < dim; ++d) sum += x[d] * x[d];
786: return PetscSqrtReal(sum);
787: }
789: static inline PetscReal DMPlex_DistD_Internal(PetscInt dim, const PetscScalar *x, const PetscScalar *y)
790: {
791: PetscReal sum = 0.0;
792: PetscInt d;
793: for (d = 0; d < dim; ++d) sum += PetscRealPart(PetscConj(x[d] - y[d]) * (x[d] - y[d]));
794: return PetscSqrtReal(sum);
795: }
797: static inline PetscReal DMPlex_DistRealD_Internal(PetscInt dim, const PetscReal *x, const PetscReal *y)
798: {
799: PetscReal sum = 0.0;
800: PetscInt d;
801: for (d = 0; d < dim; ++d) sum += (x[d] - y[d]) * (x[d] - y[d]);
802: return PetscSqrtReal(sum);
803: }
805: PETSC_INTERN PetscErrorCode DMPlexGetPointDualSpaceFEM(DM, PetscInt, PetscInt, PetscDualSpace *);
806: PETSC_INTERN PetscErrorCode DMPlexGetIndicesPoint_Internal(PetscSection, PetscBool, PetscInt, PetscInt, PetscInt *, PetscBool, const PetscInt[], const PetscInt[], PetscInt[]);
807: PETSC_INTERN PetscErrorCode DMPlexGetIndicesPointFields_Internal(PetscSection, PetscBool, PetscInt, PetscInt, PetscInt[], PetscBool, const PetscInt ***, PetscInt, const PetscInt[], PetscInt[]);
808: PETSC_INTERN PetscErrorCode DMPlexGetTransitiveClosure_Internal(DM, PetscInt, PetscInt, PetscBool, PetscInt *, PetscInt *[]);
809: PETSC_INTERN PetscErrorCode DMPlexMatSetClosure_Internal(DM, PetscSection, PetscSection, PetscBool, Mat, PetscInt, const PetscScalar[], InsertMode);
811: PETSC_SINGLE_LIBRARY_VISIBILITY_INTERNAL PetscErrorCode DMPlexGetAllCells_Internal(DM, IS *);
812: PETSC_INTERN PetscErrorCode DMPlexGetAllFaces_Internal(DM, IS *);
813: PETSC_EXTERN PetscErrorCode DMSNESGetFEGeom(DMField, IS, PetscQuadrature, PetscFEGeomMode, PetscFEGeom **);
814: PETSC_EXTERN PetscErrorCode DMSNESRestoreFEGeom(DMField, IS, PetscQuadrature, PetscBool, PetscFEGeom **);
815: PETSC_SINGLE_LIBRARY_VISIBILITY_INTERNAL PetscErrorCode DMPlexComputeResidual_Patch_Internal(DM, PetscSection, IS, PetscReal, Vec, Vec, Vec, void *);
816: PETSC_SINGLE_LIBRARY_VISIBILITY_INTERNAL PetscErrorCode DMPlexComputeJacobian_Patch_Internal(DM, PetscSection, PetscSection, IS, PetscReal, PetscReal, Vec, Vec, Mat, Mat, void *);
817: PETSC_INTERN PetscErrorCode DMCreateSubDomainDM_Plex(DM, DMLabel, PetscInt, IS *, DM *);
818: PETSC_INTERN PetscErrorCode DMPlexBasisTransformPoint_Internal(DM, DM, Vec, PetscInt, PetscBool[], PetscBool, PetscScalar *);
819: PETSC_INTERN PetscErrorCode DMPlexBasisTransformPointTensor_Internal(DM, DM, Vec, PetscInt, PetscBool, PetscInt, PetscScalar *);
820: PETSC_INTERN PetscErrorCode DMPlexBasisTransformApplyReal_Internal(DM, const PetscReal[], PetscBool, PetscInt, const PetscReal *, PetscReal *, void *);
821: PETSC_INTERN PetscErrorCode DMPlexBasisTransformApply_Internal(DM, const PetscReal[], PetscBool, PetscInt, const PetscScalar *, PetscScalar *, void *);
822: PETSC_INTERN PetscErrorCode DMCreateNeumannOverlap_Plex(DM, IS *, Mat *, PetscErrorCode (**)(Mat, PetscReal, Vec, Vec, PetscReal, IS, void *), void **);
823: PETSC_INTERN PetscErrorCode DMPlexMarkBoundaryFaces_Internal(DM, PetscInt, PetscInt, DMLabel, PetscBool);
824: PETSC_INTERN PetscErrorCode DMPlexDistributeOverlap_Internal(DM, PetscInt, MPI_Comm, const char *, PetscSF *, DM *);
826: PETSC_INTERN PetscErrorCode DMPlexInterpolateFaces_Internal(DM, PetscInt, DM);
828: PETSC_INTERN PetscErrorCode DMPlexMarkSubmesh_Interpolated(DM, DMLabel, PetscInt, PetscBool, PetscBool, DMLabel, DM);
830: PETSC_INTERN PetscErrorCode DMPeriodicCoordinateSetUp_Internal(DM);
832: /* Functions in the vtable */
833: PETSC_INTERN PetscErrorCode DMCreateInterpolation_Plex(DM dmCoarse, DM dmFine, Mat *interpolation, Vec *scaling);
834: PETSC_INTERN PetscErrorCode DMCreateInjection_Plex(DM dmCoarse, DM dmFine, Mat *mat);
835: PETSC_INTERN PetscErrorCode DMCreateMassMatrix_Plex(DM dmCoarse, DM dmFine, Mat *mat);
836: PETSC_INTERN PetscErrorCode DMCreateMassMatrixLumped_Plex(DM, Vec *, Vec *);
837: PETSC_INTERN PetscErrorCode DMCreateGradientMatrix_Plex(DM dmCoarse, DM dmFine, Mat *mat);
838: PETSC_INTERN PetscErrorCode DMCreateLocalSection_Plex(DM dm);
839: PETSC_INTERN PetscErrorCode DMCreateDefaultConstraints_Plex(DM dm);
840: PETSC_INTERN PetscErrorCode DMCreateMatrix_Plex(DM dm, Mat *J);
841: PETSC_INTERN PetscErrorCode DMCreateCoordinateDM_Plex(DM dm, DM *cdm);
842: PETSC_INTERN PetscErrorCode DMCreateCellCoordinateDM_Plex(DM dm, DM *cdm);
843: PETSC_INTERN PetscErrorCode DMCreateCoordinateField_Plex(DM dm, DMField *field);
844: PETSC_INTERN PetscErrorCode DMClone_Plex(DM dm, DM *newdm);
845: PETSC_INTERN PetscErrorCode DMSetUp_Plex(DM dm);
846: PETSC_INTERN PetscErrorCode DMDestroy_Plex(DM dm);
847: PETSC_INTERN PetscErrorCode DMView_Plex(DM dm, PetscViewer viewer);
848: PETSC_INTERN PetscErrorCode DMLoad_Plex(DM dm, PetscViewer viewer);
849: PETSC_INTERN PetscErrorCode DMCreateSubDM_Plex(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm);
850: PETSC_INTERN PetscErrorCode DMCreateSuperDM_Plex(DM dms[], PetscInt len, IS **is, DM *superdm);
851: PETSC_INTERN PetscErrorCode DMCreateDomainDecompositionScatters_Plex(DM, PetscInt, DM *, VecScatter **, VecScatter **, VecScatter **);
852: PETSC_INTERN PetscErrorCode DMCreateDomainDecomposition_Plex(DM, PetscInt *, char ***, IS **, IS **, DM **);
853: PETSC_INTERN PetscErrorCode DMCreateSectionPermutation_Plex(DM dm, IS *permutation, PetscBT *blockStarts);
854: PETSC_INTERN PetscErrorCode DMPlexCellUnsplitVertices_Internal(DM, PetscInt, DMPolytopeType, PetscInt *);
856: // Coordinate mapping functions
857: PETSC_INTERN void coordMap_identity(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[]);
858: PETSC_INTERN void coordMap_rotate(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[]);
859: PETSC_INTERN void coordMap_shear(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[]);
860: PETSC_INTERN void coordMap_flare(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[]);
861: PETSC_INTERN void coordMap_annulus(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[]);
862: PETSC_INTERN void coordMap_shell(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[]);
863: PETSC_INTERN void coordMap_sinusoid(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[]);
864: PETSC_INTERN void coordMap_torus(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[]);
866: PETSC_INTERN PetscErrorCode DMSnapToGeomModel_EGADS(DM, PetscInt, PetscInt, const PetscScalar[], PetscScalar[]);
868: // FIXME: DM with Attached CAD Models (STEP, IGES, BRep, EGADS, EGADSlite)
870: // Coordinate <-> Reference mapping functions
871: PETSC_INTERN PetscErrorCode DMPlexCoordinatesToReference_FE(DM, PetscFE, PetscInt, PetscInt, const PetscReal[], PetscReal[], Vec, PetscInt, PetscInt, PetscInt, PetscReal *);
872: PETSC_INTERN PetscErrorCode DMPlexReferenceToCoordinates_FE(DM, PetscFE, PetscInt, PetscInt, const PetscReal[], PetscReal[], Vec, PetscInt, PetscInt);