xref: /petsc/include/petscdm.h (revision eee954682a6abb1a7ac141dbd0723ecb4ff6b1e5)
1 /*
2       Objects to manage the interactions between the mesh data structures and the algebraic objects
3 */
4 #if !defined(PETSCDM_H)
5 #define PETSCDM_H
6 #include <petscmat.h>
7 #include <petscdmtypes.h>
8 #include <petscfetypes.h>
9 #include <petscdstypes.h>
10 #include <petscdmlabel.h>
11 
12 PETSC_EXTERN PetscErrorCode DMInitializePackage(void);
13 
14 PETSC_EXTERN PetscClassId DM_CLASSID;
15 PETSC_EXTERN PetscClassId DMLABEL_CLASSID;
16 
17 #define DMLOCATEPOINT_POINT_NOT_FOUND -367
18 
19 /*J
20     DMType - String with the name of a PETSc DM
21 
22    Level: beginner
23 
24 .seealso: DMSetType(), DM
25 J*/
26 typedef const char* DMType;
27 #define DMDA        "da"
28 #define DMCOMPOSITE "composite"
29 #define DMSLICED    "sliced"
30 #define DMSHELL     "shell"
31 #define DMPLEX      "plex"
32 #define DMREDUNDANT "redundant"
33 #define DMPATCH     "patch"
34 #define DMMOAB      "moab"
35 #define DMNETWORK   "network"
36 #define DMFOREST    "forest"
37 #define DMP4EST     "p4est"
38 #define DMP8EST     "p8est"
39 #define DMSWARM     "swarm"
40 #define DMPRODUCT   "product"
41 #define DMSTAG      "stag"
42 
43 PETSC_EXTERN const char *const DMBoundaryTypes[];
44 PETSC_EXTERN const char *const DMBoundaryConditionTypes[];
45 PETSC_EXTERN PetscFunctionList DMList;
46 PETSC_EXTERN DMGeneratorFunctionList DMGenerateList;
47 PETSC_EXTERN PetscErrorCode DMCreate(MPI_Comm,DM*);
48 PETSC_EXTERN PetscErrorCode DMClone(DM,DM*);
49 PETSC_EXTERN PetscErrorCode DMSetType(DM, DMType);
50 PETSC_EXTERN PetscErrorCode DMGetType(DM, DMType *);
51 PETSC_EXTERN PetscErrorCode DMRegister(const char[],PetscErrorCode (*)(DM));
52 PETSC_EXTERN PetscErrorCode DMRegisterDestroy(void);
53 
54 PETSC_EXTERN PetscErrorCode DMView(DM,PetscViewer);
55 PETSC_EXTERN PetscErrorCode DMLoad(DM,PetscViewer);
56 PETSC_EXTERN PetscErrorCode DMDestroy(DM*);
57 PETSC_EXTERN PetscErrorCode DMCreateGlobalVector(DM,Vec*);
58 PETSC_EXTERN PetscErrorCode DMCreateLocalVector(DM,Vec*);
59 PETSC_EXTERN PetscErrorCode DMGetLocalVector(DM,Vec *);
60 PETSC_EXTERN PetscErrorCode DMRestoreLocalVector(DM,Vec *);
61 PETSC_EXTERN PetscErrorCode DMGetGlobalVector(DM,Vec *);
62 PETSC_EXTERN PetscErrorCode DMRestoreGlobalVector(DM,Vec *);
63 PETSC_EXTERN PetscErrorCode DMClearGlobalVectors(DM);
64 PETSC_EXTERN PetscErrorCode DMClearLocalVectors(DM);
65 PETSC_EXTERN PetscErrorCode DMHasNamedGlobalVector(DM,const char*,PetscBool*);
66 PETSC_EXTERN PetscErrorCode DMGetNamedGlobalVector(DM,const char*,Vec*);
67 PETSC_EXTERN PetscErrorCode DMRestoreNamedGlobalVector(DM,const char*,Vec*);
68 PETSC_EXTERN PetscErrorCode DMHasNamedLocalVector(DM,const char*,PetscBool*);
69 PETSC_EXTERN PetscErrorCode DMGetNamedLocalVector(DM,const char*,Vec*);
70 PETSC_EXTERN PetscErrorCode DMRestoreNamedLocalVector(DM,const char*,Vec*);
71 PETSC_EXTERN PetscErrorCode DMGetLocalToGlobalMapping(DM,ISLocalToGlobalMapping*);
72 PETSC_EXTERN PetscErrorCode DMCreateFieldIS(DM,PetscInt*,char***,IS**);
73 PETSC_EXTERN PetscErrorCode DMGetBlockSize(DM,PetscInt*);
74 PETSC_EXTERN PetscErrorCode DMCreateColoring(DM,ISColoringType,ISColoring*);
75 PETSC_EXTERN PetscErrorCode DMCreateMatrix(DM,Mat*);
76 PETSC_EXTERN PetscErrorCode DMSetMatrixPreallocateOnly(DM,PetscBool);
77 PETSC_EXTERN PetscErrorCode DMSetMatrixStructureOnly(DM,PetscBool);
78 PETSC_EXTERN PetscErrorCode DMCreateInterpolation(DM,DM,Mat*,Vec*);
79 PETSC_EXTERN PetscErrorCode DMCreateRestriction(DM,DM,Mat*);
80 PETSC_EXTERN PetscErrorCode DMCreateInjection(DM,DM,Mat*);
81 PETSC_EXTERN PetscErrorCode DMCreateMassMatrix(DM,DM,Mat*);
82 PETSC_EXTERN PetscErrorCode DMCreateMassMatrixLumped(DM,Vec*);
83 PETSC_EXTERN PetscErrorCode DMGetWorkArray(DM,PetscInt,MPI_Datatype,void*);
84 PETSC_EXTERN PetscErrorCode DMRestoreWorkArray(DM,PetscInt,MPI_Datatype,void*);
85 PETSC_EXTERN PetscErrorCode DMRefine(DM,MPI_Comm,DM*);
86 PETSC_EXTERN PetscErrorCode DMCoarsen(DM,MPI_Comm,DM*);
87 PETSC_EXTERN PetscErrorCode DMGetCoarseDM(DM,DM*);
88 PETSC_EXTERN PetscErrorCode DMSetCoarseDM(DM,DM);
89 PETSC_EXTERN PetscErrorCode DMGetFineDM(DM,DM*);
90 PETSC_EXTERN PetscErrorCode DMSetFineDM(DM,DM);
91 PETSC_EXTERN PetscErrorCode DMRefineHierarchy(DM,PetscInt,DM[]);
92 PETSC_EXTERN PetscErrorCode DMCoarsenHierarchy(DM,PetscInt,DM[]);
93 PETSC_EXTERN PetscErrorCode DMCoarsenHookAdd(DM,PetscErrorCode (*)(DM,DM,void*),PetscErrorCode (*)(DM,Mat,Vec,Mat,DM,void*),void*);
94 PETSC_EXTERN PetscErrorCode DMCoarsenHookRemove(DM,PetscErrorCode (*)(DM,DM,void*),PetscErrorCode (*)(DM,Mat,Vec,Mat,DM,void*),void*);
95 PETSC_EXTERN PetscErrorCode DMRefineHookAdd(DM,PetscErrorCode (*)(DM,DM,void*),PetscErrorCode (*)(DM,Mat,DM,void*),void*);
96 PETSC_EXTERN PetscErrorCode DMRefineHookRemove(DM,PetscErrorCode (*)(DM,DM,void*),PetscErrorCode (*)(DM,Mat,DM,void*),void*);
97 PETSC_EXTERN PetscErrorCode DMRestrict(DM,Mat,Vec,Mat,DM);
98 PETSC_EXTERN PetscErrorCode DMInterpolate(DM,Mat,DM);
99 PETSC_EXTERN PetscErrorCode DMInterpolateSolution(DM,DM,Mat,Vec,Vec);
100 PETSC_EXTERN PetscErrorCode DMExtrude(DM,PetscInt,DM*);
101 PETSC_EXTERN PetscErrorCode DMSetFromOptions(DM);
102 PETSC_EXTERN PetscErrorCode DMViewFromOptions(DM,PetscObject,const char[]);
103 
104 PETSC_EXTERN PetscErrorCode DMGenerate(DM, const char [], PetscBool , DM *);
105 PETSC_EXTERN PetscErrorCode DMGenerateRegister(const char[],PetscErrorCode (*)(DM,PetscBool,DM*),PetscErrorCode (*)(DM,PetscReal*,DM*),PetscErrorCode (*)(DM,Vec,DMLabel,DMLabel,DM*),PetscInt);
106 PETSC_EXTERN PetscErrorCode DMGenerateRegisterAll(void);
107 PETSC_EXTERN PetscErrorCode DMGenerateRegisterDestroy(void);
108 PETSC_EXTERN PetscErrorCode DMAdaptLabel(DM,DMLabel,DM*);
109 PETSC_EXTERN PetscErrorCode DMAdaptMetric(DM, Vec, DMLabel, DMLabel, DM *);
110 
111 PETSC_EXTERN PetscErrorCode DMSetUp(DM);
112 PETSC_EXTERN PetscErrorCode DMCreateInterpolationScale(DM,DM,Mat,Vec*);
113 PETSC_EXTERN PETSC_DEPRECATED_FUNCTION("Use DMDACreateAggregates() or DMCreateRestriction() (since version 3.12)") PetscErrorCode DMCreateAggregates(DM,DM,Mat*);
114 PETSC_EXTERN PetscErrorCode DMGlobalToLocalHookAdd(DM,PetscErrorCode (*)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*)(DM,Vec,InsertMode,Vec,void*),void*);
115 PETSC_EXTERN PetscErrorCode DMLocalToGlobalHookAdd(DM,PetscErrorCode (*)(DM,Vec,InsertMode,Vec,void*),PetscErrorCode (*)(DM,Vec,InsertMode,Vec,void*),void*);
116 PETSC_EXTERN PetscErrorCode DMGlobalToLocal(DM,Vec,InsertMode,Vec);
117 PETSC_EXTERN PetscErrorCode DMGlobalToLocalBegin(DM,Vec,InsertMode,Vec);
118 PETSC_EXTERN PetscErrorCode DMGlobalToLocalEnd(DM,Vec,InsertMode,Vec);
119 PETSC_EXTERN PetscErrorCode DMLocalToGlobal(DM,Vec,InsertMode,Vec);
120 PETSC_EXTERN PetscErrorCode DMLocalToGlobalBegin(DM,Vec,InsertMode,Vec);
121 PETSC_EXTERN PetscErrorCode DMLocalToGlobalEnd(DM,Vec,InsertMode,Vec);
122 PETSC_EXTERN PetscErrorCode DMLocalToLocalBegin(DM,Vec,InsertMode,Vec);
123 PETSC_EXTERN PetscErrorCode DMLocalToLocalEnd(DM,Vec,InsertMode,Vec);
124 PETSC_EXTERN PetscErrorCode DMConvert(DM,DMType,DM*);
125 
126 /* Topology support */
127 PETSC_EXTERN PetscErrorCode DMGetDimension(DM,PetscInt*);
128 PETSC_EXTERN PetscErrorCode DMSetDimension(DM,PetscInt);
129 PETSC_EXTERN PetscErrorCode DMGetDimPoints(DM,PetscInt,PetscInt*,PetscInt*);
130 PETSC_EXTERN PetscErrorCode DMGetUseNatural(DM,PetscBool*);
131 PETSC_EXTERN PetscErrorCode DMSetUseNatural(DM,PetscBool);
132 
133 /* Coordinate support */
134 PETSC_EXTERN PetscErrorCode DMGetCoordinateDM(DM,DM*);
135 PETSC_EXTERN PetscErrorCode DMSetCoordinateDM(DM,DM);
136 PETSC_EXTERN PetscErrorCode DMGetCoordinateDim(DM,PetscInt*);
137 PETSC_EXTERN PetscErrorCode DMSetCoordinateDim(DM,PetscInt);
138 PETSC_EXTERN PetscErrorCode DMGetCoordinateSection(DM,PetscSection*);
139 PETSC_EXTERN PetscErrorCode DMSetCoordinateSection(DM,PetscInt,PetscSection);
140 PETSC_EXTERN PetscErrorCode DMGetCoordinates(DM,Vec*);
141 PETSC_EXTERN PetscErrorCode DMSetCoordinates(DM,Vec);
142 PETSC_EXTERN PetscErrorCode DMGetCoordinatesLocal(DM,Vec*);
143 PETSC_EXTERN PetscErrorCode DMGetCoordinatesLocalSetUp(DM);
144 PETSC_EXTERN PetscErrorCode DMGetCoordinatesLocalNoncollective(DM,Vec*);
145 PETSC_EXTERN PetscErrorCode DMGetCoordinatesLocalTuple(DM,IS,PetscSection*,Vec*);
146 PETSC_EXTERN PetscErrorCode DMSetCoordinatesLocal(DM,Vec);
147 PETSC_EXTERN PetscErrorCode DMLocatePoints(DM,Vec,DMPointLocationType,PetscSF*);
148 PETSC_EXTERN PetscErrorCode DMGetPeriodicity(DM,PetscBool*,const PetscReal**,const PetscReal**,const DMBoundaryType**);
149 PETSC_EXTERN PetscErrorCode DMSetPeriodicity(DM,PetscBool,const PetscReal[],const PetscReal[],const DMBoundaryType[]);
150 PETSC_EXTERN PetscErrorCode DMLocalizeCoordinate(DM, const PetscScalar[], PetscBool, PetscScalar[]);
151 PETSC_EXTERN PetscErrorCode DMLocalizeCoordinates(DM);
152 PETSC_EXTERN PetscErrorCode DMGetCoordinatesLocalized(DM,PetscBool*);
153 PETSC_EXTERN PetscErrorCode DMGetCoordinatesLocalizedLocal(DM,PetscBool*);
154 PETSC_EXTERN PetscErrorCode DMGetNeighbors(DM,PetscInt*,const PetscMPIInt**);
155 PETSC_EXTERN PetscErrorCode DMGetCoordinateField(DM,DMField*);
156 PETSC_EXTERN PetscErrorCode DMSetCoordinateField(DM,DMField);
157 PETSC_EXTERN PetscErrorCode DMGetBoundingBox(DM,PetscReal[],PetscReal[]);
158 PETSC_EXTERN PetscErrorCode DMGetLocalBoundingBox(DM,PetscReal[],PetscReal[]);
159 PETSC_EXTERN PetscErrorCode DMProjectCoordinates(DM,PetscFE);
160 
161 /* block hook interface */
162 PETSC_EXTERN PetscErrorCode DMSubDomainHookAdd(DM,PetscErrorCode (*)(DM,DM,void*),PetscErrorCode (*)(DM,VecScatter,VecScatter,DM,void*),void*);
163 PETSC_EXTERN PetscErrorCode DMSubDomainHookRemove(DM,PetscErrorCode (*)(DM,DM,void*),PetscErrorCode (*)(DM,VecScatter,VecScatter,DM,void*),void*);
164 PETSC_EXTERN PetscErrorCode DMSubDomainRestrict(DM,VecScatter,VecScatter,DM);
165 
166 PETSC_EXTERN PetscErrorCode DMSetOptionsPrefix(DM,const char []);
167 PETSC_EXTERN PetscErrorCode DMAppendOptionsPrefix(DM,const char []);
168 PETSC_EXTERN PetscErrorCode DMGetOptionsPrefix(DM,const char*[]);
169 PETSC_EXTERN PetscErrorCode DMSetVecType(DM,VecType);
170 PETSC_EXTERN PetscErrorCode DMGetVecType(DM,VecType*);
171 PETSC_EXTERN PetscErrorCode DMSetMatType(DM,MatType);
172 PETSC_EXTERN PetscErrorCode DMGetMatType(DM,MatType*);
173 PETSC_EXTERN PetscErrorCode DMSetISColoringType(DM,ISColoringType);
174 PETSC_EXTERN PetscErrorCode DMGetISColoringType(DM,ISColoringType*);
175 PETSC_EXTERN PetscErrorCode DMSetApplicationContext(DM,void*);
176 PETSC_EXTERN PetscErrorCode DMSetApplicationContextDestroy(DM,PetscErrorCode (*)(void**));
177 PETSC_EXTERN PetscErrorCode DMGetApplicationContext(DM,void*);
178 PETSC_EXTERN PetscErrorCode DMSetVariableBounds(DM,PetscErrorCode (*)(DM,Vec,Vec));
179 PETSC_EXTERN PetscErrorCode DMHasVariableBounds(DM,PetscBool *);
180 PETSC_EXTERN PetscErrorCode DMHasColoring(DM,PetscBool *);
181 PETSC_EXTERN PetscErrorCode DMHasCreateRestriction(DM,PetscBool *);
182 PETSC_EXTERN PetscErrorCode DMHasCreateInjection(DM,PetscBool *);
183 PETSC_EXTERN PetscErrorCode DMComputeVariableBounds(DM,Vec,Vec);
184 
185 PETSC_EXTERN PetscErrorCode DMCreateSubDM(DM, PetscInt, const PetscInt[], IS *, DM *);
186 PETSC_EXTERN PetscErrorCode DMCreateSuperDM(DM[], PetscInt, IS **, DM *);
187 PETSC_EXTERN PetscErrorCode DMCreateSectionSubDM(DM,PetscInt,const PetscInt[],IS*,DM*);
188 PETSC_EXTERN PetscErrorCode DMCreateSectionSuperDM(DM[],PetscInt,IS**,DM*);
189 PETSC_EXTERN PetscErrorCode DMCreateFieldDecomposition(DM,PetscInt*,char***,IS**,DM**);
190 PETSC_EXTERN PetscErrorCode DMCreateDomainDecomposition(DM,PetscInt*,char***,IS**,IS**,DM**);
191 PETSC_EXTERN PetscErrorCode DMCreateDomainDecompositionScatters(DM,PetscInt,DM*,VecScatter**,VecScatter**,VecScatter**);
192 
193 PETSC_EXTERN PetscErrorCode DMGetRefineLevel(DM,PetscInt*);
194 PETSC_EXTERN PetscErrorCode DMSetRefineLevel(DM,PetscInt);
195 PETSC_EXTERN PetscErrorCode DMGetCoarsenLevel(DM,PetscInt*);
196 PETSC_EXTERN PetscErrorCode DMSetCoarsenLevel(DM,PetscInt);
197 PETSC_EXTERN PetscErrorCode DMFinalizePackage(void);
198 
199 PETSC_EXTERN PetscErrorCode VecGetDM(Vec, DM*);
200 PETSC_EXTERN PetscErrorCode VecSetDM(Vec, DM);
201 PETSC_EXTERN PetscErrorCode MatGetDM(Mat, DM*);
202 PETSC_EXTERN PetscErrorCode MatSetDM(Mat, DM);
203 PETSC_EXTERN PetscErrorCode MatFDColoringUseDM(Mat,MatFDColoring);
204 
205 typedef struct NLF_DAAD* NLF;
206 
207 #define DM_FILE_CLASSID 1211221
208 
209 /* FEM support */
210 PETSC_EXTERN PetscErrorCode DMPrintCellVector(PetscInt, const char [], PetscInt, const PetscScalar []);
211 PETSC_EXTERN PetscErrorCode DMPrintCellMatrix(PetscInt, const char [], PetscInt, PetscInt, const PetscScalar []);
212 PETSC_EXTERN PetscErrorCode DMPrintLocalVec(DM, const char [], PetscReal, Vec);
213 
214 PETSC_EXTERN PetscErrorCode DMSetNullSpaceConstructor(DM, PetscInt, PetscErrorCode (*)(DM, PetscInt, PetscInt, MatNullSpace *));
215 PETSC_EXTERN PetscErrorCode DMGetNullSpaceConstructor(DM, PetscInt, PetscErrorCode (**)(DM, PetscInt, PetscInt, MatNullSpace *));
216 PETSC_EXTERN PetscErrorCode DMSetNearNullSpaceConstructor(DM, PetscInt, PetscErrorCode (*)(DM, PetscInt, PetscInt, MatNullSpace *));
217 PETSC_EXTERN PetscErrorCode DMGetNearNullSpaceConstructor(DM, PetscInt, PetscErrorCode (**)(DM, PetscInt, PetscInt, MatNullSpace *));
218 
219 PETSC_EXTERN PetscErrorCode DMGetSection(DM, PetscSection *); /* Use DMGetLocalSection() in new code (since v3.12) */
220 PETSC_EXTERN PetscErrorCode DMSetSection(DM, PetscSection);   /* Use DMSetLocalSection() in new code (since v3.12) */
221 PETSC_EXTERN PetscErrorCode DMGetLocalSection(DM, PetscSection *);
222 PETSC_EXTERN PetscErrorCode DMSetLocalSection(DM, PetscSection);
223 PETSC_EXTERN PetscErrorCode DMGetGlobalSection(DM, PetscSection *);
224 PETSC_EXTERN PetscErrorCode DMSetGlobalSection(DM, PetscSection);
225 PETSC_STATIC_INLINE PETSC_DEPRECATED_FUNCTION("Use DMGetSection() (since v3.9)") PetscErrorCode DMGetDefaultSection(DM dm, PetscSection *s) {return DMGetSection(dm,s);}
226 PETSC_STATIC_INLINE PETSC_DEPRECATED_FUNCTION("Use DMSetSection() (since v3.9)") PetscErrorCode DMSetDefaultSection(DM dm, PetscSection s) {return DMSetSection(dm,s);}
227 PETSC_STATIC_INLINE PETSC_DEPRECATED_FUNCTION("Use DMGetGlobalSection() (since v3.9)") PetscErrorCode DMGetDefaultGlobalSection(DM dm, PetscSection *s) {return DMGetGlobalSection(dm,s);}
228 PETSC_STATIC_INLINE PETSC_DEPRECATED_FUNCTION("Use DMSetGlobalSection() (since v3.9)") PetscErrorCode DMSetDefaultGlobalSection(DM dm, PetscSection s) {return DMSetGlobalSection(dm,s);}
229 
230 PETSC_EXTERN PetscErrorCode DMGetSectionSF(DM, PetscSF*);
231 PETSC_EXTERN PetscErrorCode DMSetSectionSF(DM, PetscSF);
232 PETSC_EXTERN PetscErrorCode DMCreateSectionSF(DM, PetscSection, PetscSection);
233 PETSC_STATIC_INLINE PETSC_DEPRECATED_FUNCTION("Use DMGetSectionSF() (since v3.12)") PetscErrorCode DMGetDefaultSF(DM dm, PetscSF *s) {return DMGetSectionSF(dm,s);}
234 PETSC_STATIC_INLINE PETSC_DEPRECATED_FUNCTION("Use DMSetSectionSF() (since v3.12)") PetscErrorCode DMSetDefaultSF(DM dm, PetscSF s) {return DMSetSectionSF(dm,s);}
235 PETSC_STATIC_INLINE PETSC_DEPRECATED_FUNCTION("Use DMCreateSectionSF() (since v3.12)") PetscErrorCode DMCreateDefaultSF(DM dm, PetscSection l, PetscSection g) {return DMCreateSectionSF(dm,l,g);}
236 PETSC_EXTERN PetscErrorCode DMGetPointSF(DM, PetscSF *);
237 PETSC_EXTERN PetscErrorCode DMSetPointSF(DM, PetscSF);
238 PETSC_EXTERN PetscErrorCode DMGetNaturalSF(DM, PetscSF *);
239 PETSC_EXTERN PetscErrorCode DMSetNaturalSF(DM, PetscSF);
240 
241 PETSC_EXTERN PetscErrorCode DMGetDefaultConstraints(DM, PetscSection *, Mat *);
242 PETSC_EXTERN PetscErrorCode DMSetDefaultConstraints(DM, PetscSection, Mat);
243 
244 PETSC_EXTERN PetscErrorCode DMGetOutputDM(DM, DM *);
245 PETSC_EXTERN PetscErrorCode DMGetOutputSequenceNumber(DM, PetscInt *, PetscReal *);
246 PETSC_EXTERN PetscErrorCode DMSetOutputSequenceNumber(DM, PetscInt, PetscReal);
247 PETSC_EXTERN PetscErrorCode DMOutputSequenceLoad(DM, PetscViewer, const char *, PetscInt, PetscReal *);
248 
249 PETSC_EXTERN PetscErrorCode DMGetNumFields(DM, PetscInt *);
250 PETSC_EXTERN PetscErrorCode DMSetNumFields(DM, PetscInt);
251 PETSC_EXTERN PetscErrorCode DMGetField(DM, PetscInt, DMLabel *, PetscObject *);
252 PETSC_EXTERN PetscErrorCode DMSetField(DM, PetscInt, DMLabel, PetscObject);
253 PETSC_EXTERN PetscErrorCode DMAddField(DM, DMLabel, PetscObject);
254 PETSC_EXTERN PetscErrorCode DMSetFieldAvoidTensor(DM, PetscInt, PetscBool);
255 PETSC_EXTERN PetscErrorCode DMGetFieldAvoidTensor(DM, PetscInt, PetscBool *);
256 PETSC_EXTERN PetscErrorCode DMClearFields(DM);
257 PETSC_EXTERN PetscErrorCode DMCopyFields(DM, DM);
258 PETSC_EXTERN PetscErrorCode DMGetAdjacency(DM, PetscInt, PetscBool *, PetscBool *);
259 PETSC_EXTERN PetscErrorCode DMSetAdjacency(DM, PetscInt, PetscBool, PetscBool);
260 PETSC_EXTERN PetscErrorCode DMGetBasicAdjacency(DM, PetscBool *, PetscBool *);
261 PETSC_EXTERN PetscErrorCode DMSetBasicAdjacency(DM, PetscBool, PetscBool);
262 
263 PETSC_EXTERN PetscErrorCode DMGetNumDS(DM, PetscInt *);
264 PETSC_EXTERN PetscErrorCode DMGetDS(DM, PetscDS *);
265 PETSC_EXTERN PetscErrorCode DMGetCellDS(DM, PetscInt, PetscDS *);
266 PETSC_EXTERN PetscErrorCode DMGetRegionDS(DM, DMLabel, IS *, PetscDS *);
267 PETSC_EXTERN PetscErrorCode DMSetRegionDS(DM, DMLabel, IS, PetscDS);
268 PETSC_EXTERN PetscErrorCode DMGetRegionNumDS(DM, PetscInt, DMLabel *, IS *, PetscDS *);
269 PETSC_EXTERN PetscErrorCode DMSetRegionNumDS(DM, PetscInt, DMLabel, IS, PetscDS);
270 PETSC_EXTERN PetscErrorCode DMFindRegionNum(DM, PetscDS, PetscInt *);
271 PETSC_EXTERN PetscErrorCode DMCreateDS(DM);
272 PETSC_EXTERN PetscErrorCode DMClearDS(DM);
273 PETSC_EXTERN PetscErrorCode DMCopyDS(DM, DM);
274 PETSC_EXTERN PetscErrorCode DMCopyDisc(DM, DM);
275 PETSC_EXTERN PetscErrorCode DMComputeExactSolution(DM, PetscReal, Vec, Vec);
276 PETSC_EXTERN PetscErrorCode DMGetNumAuxiliaryVec(DM, PetscInt *);
277 PETSC_EXTERN PetscErrorCode DMGetAuxiliaryVec(DM, DMLabel, PetscInt, Vec *);
278 PETSC_EXTERN PetscErrorCode DMSetAuxiliaryVec(DM, DMLabel, PetscInt, Vec);
279 PETSC_EXTERN PetscErrorCode DMGetAuxiliaryLabels(DM, DMLabel[], PetscInt[]);
280 PETSC_EXTERN PetscErrorCode DMCopyAuxiliaryVec(DM, DM);
281 
282 /*MC
283   DMInterpolationInfo - Structure for holding information about interpolation on a mesh
284 
285   Level: intermediate
286 
287   Synopsis:
288     comm   - The communicator
289     dim    - The spatial dimension of points
290     nInput - The number of input points
291     points - The input point coordinates
292     cells  - The cell containing each point
293     n      - The number of local points
294     coords - The point coordinates
295     dof    - The number of components to interpolate
296 
297 .seealso: DMInterpolationCreate(), DMInterpolationEvaluate(), DMInterpolationAddPoints()
298 M*/
299 struct _DMInterpolationInfo {
300   MPI_Comm   comm;
301   PetscInt   dim;    /*1 The spatial dimension of points */
302   PetscInt   nInput; /* The number of input points */
303   PetscReal *points; /* The input point coordinates */
304   PetscInt  *cells;  /* The cell containing each point */
305   PetscInt   n;      /* The number of local points */
306   Vec        coords; /* The point coordinates */
307   PetscInt   dof;    /* The number of components to interpolate */
308 };
309 typedef struct _DMInterpolationInfo *DMInterpolationInfo;
310 
311 PETSC_EXTERN PetscErrorCode DMInterpolationCreate(MPI_Comm, DMInterpolationInfo *);
312 PETSC_EXTERN PetscErrorCode DMInterpolationSetDim(DMInterpolationInfo, PetscInt);
313 PETSC_EXTERN PetscErrorCode DMInterpolationGetDim(DMInterpolationInfo, PetscInt *);
314 PETSC_EXTERN PetscErrorCode DMInterpolationSetDof(DMInterpolationInfo, PetscInt);
315 PETSC_EXTERN PetscErrorCode DMInterpolationGetDof(DMInterpolationInfo, PetscInt *);
316 PETSC_EXTERN PetscErrorCode DMInterpolationAddPoints(DMInterpolationInfo, PetscInt, PetscReal[]);
317 PETSC_EXTERN PetscErrorCode DMInterpolationSetUp(DMInterpolationInfo, DM, PetscBool, PetscBool);
318 PETSC_EXTERN PetscErrorCode DMInterpolationGetCoordinates(DMInterpolationInfo, Vec *);
319 PETSC_EXTERN PetscErrorCode DMInterpolationGetVector(DMInterpolationInfo, Vec *);
320 PETSC_EXTERN PetscErrorCode DMInterpolationRestoreVector(DMInterpolationInfo, Vec *);
321 PETSC_EXTERN PetscErrorCode DMInterpolationEvaluate(DMInterpolationInfo, DM, Vec, Vec);
322 PETSC_EXTERN PetscErrorCode DMInterpolationDestroy(DMInterpolationInfo *);
323 
324 PETSC_EXTERN PetscErrorCode DMCreateLabel(DM, const char []);
325 PETSC_EXTERN PetscErrorCode DMGetLabelValue(DM, const char[], PetscInt, PetscInt *);
326 PETSC_EXTERN PetscErrorCode DMSetLabelValue(DM, const char[], PetscInt, PetscInt);
327 PETSC_EXTERN PetscErrorCode DMClearLabelValue(DM, const char[], PetscInt, PetscInt);
328 PETSC_EXTERN PetscErrorCode DMGetLabelSize(DM, const char[], PetscInt *);
329 PETSC_EXTERN PetscErrorCode DMGetLabelIdIS(DM, const char[], IS *);
330 PETSC_EXTERN PetscErrorCode DMGetStratumSize(DM, const char [], PetscInt, PetscInt *);
331 PETSC_EXTERN PetscErrorCode DMGetStratumIS(DM, const char [], PetscInt, IS *);
332 PETSC_EXTERN PetscErrorCode DMSetStratumIS(DM, const char [], PetscInt, IS);
333 PETSC_EXTERN PetscErrorCode DMClearLabelStratum(DM, const char[], PetscInt);
334 PETSC_EXTERN PetscErrorCode DMGetLabelOutput(DM, const char[], PetscBool *);
335 PETSC_EXTERN PetscErrorCode DMSetLabelOutput(DM, const char[], PetscBool);
336 PETSC_EXTERN PetscErrorCode DMGetFirstLabeledPoint(DM, DM, DMLabel, PetscInt, const PetscInt *, PetscInt, PetscInt *, PetscDS *);
337 
338 /*E
339    DMCopyLabelsMode - Determines how DMCopyLabels() behaves when there is a DMLabel in the source and destination DMs with the same name
340 
341    Level: advanced
342 
343 $ DM_COPY_LABELS_REPLACE  - replace label in destination by label from source
344 $ DM_COPY_LABELS_KEEP     - keep destination label
345 $ DM_COPY_LABELS_FAIL     - throw error
346 
347 E*/
348 typedef enum {DM_COPY_LABELS_REPLACE, DM_COPY_LABELS_KEEP, DM_COPY_LABELS_FAIL} DMCopyLabelsMode;
349 PETSC_EXTERN const char *const DMCopyLabelsModes[];
350 
351 PETSC_EXTERN PetscErrorCode DMGetNumLabels(DM, PetscInt *);
352 PETSC_EXTERN PetscErrorCode DMGetLabelName(DM, PetscInt, const char **);
353 PETSC_EXTERN PetscErrorCode DMHasLabel(DM, const char [], PetscBool *);
354 PETSC_EXTERN PetscErrorCode DMGetLabel(DM, const char *, DMLabel *);
355 PETSC_EXTERN PetscErrorCode DMSetLabel(DM, DMLabel);
356 PETSC_EXTERN PetscErrorCode DMGetLabelByNum(DM, PetscInt, DMLabel *);
357 PETSC_EXTERN PetscErrorCode DMAddLabel(DM, DMLabel);
358 PETSC_EXTERN PetscErrorCode DMRemoveLabel(DM, const char [], DMLabel *);
359 PETSC_EXTERN PetscErrorCode DMRemoveLabelBySelf(DM, DMLabel *, PetscBool);
360 PETSC_EXTERN PetscErrorCode DMCopyLabels(DM, DM, PetscCopyMode, PetscBool, DMCopyLabelsMode emode);
361 PETSC_EXTERN PetscErrorCode DMCompareLabels(DM, DM, PetscBool *, char **);
362 
363 PETSC_EXTERN PetscErrorCode DMAddBoundary(DM, DMBoundaryConditionType, const char[], DMLabel, PetscInt, const PetscInt[], PetscInt, PetscInt, const PetscInt[], void (*)(void), void (*)(void), void *, PetscInt *);
364 PETSC_EXTERN PetscErrorCode DMIsBoundaryPoint(DM, PetscInt, PetscBool *);
365 
366 PETSC_EXTERN PetscErrorCode DMProjectFunction(DM,PetscReal,PetscErrorCode(**)(PetscInt,PetscReal,const PetscReal[],PetscInt,PetscScalar *,void *),void**,InsertMode,Vec);
367 PETSC_EXTERN PetscErrorCode DMProjectFunctionLocal(DM,PetscReal,PetscErrorCode(**)(PetscInt,PetscReal,const PetscReal[],PetscInt,PetscScalar *,void *),void**,InsertMode,Vec);
368 PETSC_EXTERN PetscErrorCode DMProjectFunctionLabel(DM, PetscReal, DMLabel, PetscInt, const PetscInt[], PetscInt, const PetscInt[], PetscErrorCode (**)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *), void **, InsertMode, Vec);
369 PETSC_EXTERN PetscErrorCode DMProjectFunctionLabelLocal(DM,PetscReal,DMLabel,PetscInt,const PetscInt[],PetscInt,const PetscInt[],PetscErrorCode(**)(PetscInt,PetscReal,const PetscReal[],PetscInt,PetscScalar *,void *),void **,InsertMode,Vec);
370 PETSC_EXTERN PetscErrorCode DMProjectFieldLocal(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);
371 PETSC_EXTERN PetscErrorCode DMProjectFieldLabelLocal(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);
372 PETSC_EXTERN PetscErrorCode DMProjectBdFieldLabelLocal(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);
373 PETSC_EXTERN PetscErrorCode DMComputeL2Diff(DM,PetscReal,PetscErrorCode(**)(PetscInt,PetscReal,const PetscReal[],PetscInt,PetscScalar *,void *),void **,Vec,PetscReal *);
374 PETSC_EXTERN PetscErrorCode DMComputeL2GradientDiff(DM, PetscReal, PetscErrorCode (**)(PetscInt, PetscReal, const PetscReal [], const PetscReal [], PetscInt, PetscScalar *, void *), void **, Vec, const PetscReal [], PetscReal *);
375 PETSC_EXTERN PetscErrorCode DMComputeL2FieldDiff(DM,PetscReal,PetscErrorCode(**)(PetscInt,PetscReal,const PetscReal[],PetscInt,PetscScalar *,void *),void **,Vec,PetscReal *);
376 PETSC_EXTERN PetscErrorCode DMComputeError(DM, Vec, PetscReal[], Vec *);
377 PETSC_EXTERN PetscErrorCode DMHasBasisTransform(DM,PetscBool*);
378 PETSC_EXTERN PetscErrorCode DMCopyTransform(DM, DM);
379 
380 PETSC_EXTERN PetscErrorCode DMGetCompatibility(DM,DM,PetscBool*,PetscBool*);
381 
382 PETSC_EXTERN PetscErrorCode DMMonitorSet(DM, PetscErrorCode (*)(DM, void *), void *, PetscErrorCode (*)(void**));
383 PETSC_EXTERN PetscErrorCode DMMonitorCancel(DM);
384 PETSC_EXTERN PetscErrorCode DMMonitorSetFromOptions(DM, const char[], const char[], const char[], PetscErrorCode (*)(DM, void *), PetscErrorCode (*)(DM, PetscViewerAndFormat *), PetscBool *);
385 PETSC_EXTERN PetscErrorCode DMMonitor(DM);
386 
387 PETSC_STATIC_INLINE PetscInt DMPolytopeTypeGetDim(DMPolytopeType ct)
388 {
389   switch (ct) {
390     case DM_POLYTOPE_POINT:
391       return 0;
392     case DM_POLYTOPE_SEGMENT:
393     case DM_POLYTOPE_POINT_PRISM_TENSOR:
394       return 1;
395     case DM_POLYTOPE_TRIANGLE:
396     case DM_POLYTOPE_QUADRILATERAL:
397     case DM_POLYTOPE_SEG_PRISM_TENSOR:
398       return 2;
399     case DM_POLYTOPE_TETRAHEDRON:
400     case DM_POLYTOPE_HEXAHEDRON:
401     case DM_POLYTOPE_TRI_PRISM:
402     case DM_POLYTOPE_TRI_PRISM_TENSOR:
403     case DM_POLYTOPE_QUAD_PRISM_TENSOR:
404     case DM_POLYTOPE_PYRAMID:
405       return 3;
406     default: return -1;
407   }
408 }
409 
410 PETSC_STATIC_INLINE PetscInt DMPolytopeTypeGetConeSize(DMPolytopeType ct)
411 {
412   switch (ct) {
413     case DM_POLYTOPE_POINT:              return 0;
414     case DM_POLYTOPE_SEGMENT:            return 2;
415     case DM_POLYTOPE_POINT_PRISM_TENSOR: return 2;
416     case DM_POLYTOPE_TRIANGLE:           return 3;
417     case DM_POLYTOPE_QUADRILATERAL:      return 4;
418     case DM_POLYTOPE_SEG_PRISM_TENSOR:   return 4;
419     case DM_POLYTOPE_TETRAHEDRON:        return 4;
420     case DM_POLYTOPE_HEXAHEDRON:         return 6;
421     case DM_POLYTOPE_TRI_PRISM:          return 5;
422     case DM_POLYTOPE_TRI_PRISM_TENSOR:   return 5;
423     case DM_POLYTOPE_QUAD_PRISM_TENSOR:  return 6;
424     case DM_POLYTOPE_PYRAMID:            return 5;
425     default: return -1;
426   }
427 }
428 
429 PETSC_STATIC_INLINE PetscInt DMPolytopeTypeGetNumVertices(DMPolytopeType ct)
430 {
431   switch (ct) {
432     case DM_POLYTOPE_POINT:              return 1;
433     case DM_POLYTOPE_SEGMENT:            return 2;
434     case DM_POLYTOPE_POINT_PRISM_TENSOR: return 2;
435     case DM_POLYTOPE_TRIANGLE:           return 3;
436     case DM_POLYTOPE_QUADRILATERAL:      return 4;
437     case DM_POLYTOPE_SEG_PRISM_TENSOR:   return 4;
438     case DM_POLYTOPE_TETRAHEDRON:        return 4;
439     case DM_POLYTOPE_HEXAHEDRON:         return 8;
440     case DM_POLYTOPE_TRI_PRISM:          return 6;
441     case DM_POLYTOPE_TRI_PRISM_TENSOR:   return 6;
442     case DM_POLYTOPE_QUAD_PRISM_TENSOR:  return 8;
443     case DM_POLYTOPE_PYRAMID:            return 5;
444     default: return -1;
445   }
446 }
447 
448 PETSC_STATIC_INLINE DMPolytopeType DMPolytopeTypeSimpleShape(PetscInt dim, PetscBool simplex)
449 {
450   return dim == 0 ? DM_POLYTOPE_POINT :
451         (dim == 1 ? DM_POLYTOPE_SEGMENT :
452         (dim == 2 ? (simplex ? DM_POLYTOPE_TRIANGLE : DM_POLYTOPE_QUADRILATERAL) :
453         (dim == 3 ? (simplex ? DM_POLYTOPE_TETRAHEDRON : DM_POLYTOPE_HEXAHEDRON) : DM_POLYTOPE_UNKNOWN)));
454 }
455 
456 PETSC_STATIC_INLINE PetscInt DMPolytopeTypeGetNumArrangments(DMPolytopeType ct)
457 {
458   switch (ct) {
459     case DM_POLYTOPE_POINT:              return 1;
460     case DM_POLYTOPE_SEGMENT:            return 2;
461     case DM_POLYTOPE_POINT_PRISM_TENSOR: return 2;
462     case DM_POLYTOPE_TRIANGLE:           return 6;
463     case DM_POLYTOPE_QUADRILATERAL:      return 8;
464     case DM_POLYTOPE_SEG_PRISM_TENSOR:   return 4;
465     case DM_POLYTOPE_TETRAHEDRON:        return 24;
466     case DM_POLYTOPE_HEXAHEDRON:         return 48;
467     case DM_POLYTOPE_TRI_PRISM:          return 12;
468     case DM_POLYTOPE_TRI_PRISM_TENSOR:   return 12;
469     case DM_POLYTOPE_QUAD_PRISM_TENSOR:  return 16;
470     case DM_POLYTOPE_PYRAMID:            return 8;
471     default: return -1;
472   }
473 }
474 
475 /* An arrangement is a face order combined with an orientation for each face */
476 PETSC_STATIC_INLINE const PetscInt *DMPolytopeTypeGetArrangment(DMPolytopeType ct, PetscInt o)
477 {
478   static const PetscInt pntArr[1*2] = {0, 0};
479   /* a: swap */
480   static const PetscInt segArr[2*2*2] = {
481     1, 0,  0, 0, /* -1: a */
482     0, 0,  1, 0, /*  0: e */};
483   /* a: swap first two
484      b: swap last two */
485   static const PetscInt triArr[6*3*2] = {
486     0, -1,  2, -1,  1, -1, /* -3: b */
487     2, -1,  1, -1,  0, -1, /* -2: aba */
488     1, -1,  0, -1,  2, -1, /* -1: a */
489     0,  0,  1,  0,  2,  0, /*  0: identity */
490     1,  0,  2,  0,  0,  0, /*  1: ba */
491     2,  0,  0,  0,  1,  0, /*  2: ab */};
492   /* a: forward cyclic permutation
493      b: swap first and last pairs */
494   static const PetscInt quadArr[8*4*2] = {
495     1, -1,  0, -1,  3, -1,  2, -1, /* -4: b */
496     0, -1,  3, -1,  2, -1,  1, -1, /* -3: b a^3 = a b */
497     3, -1,  2, -1,  1, -1,  0, -1, /* -2: b a^2 = a^2 b */
498     2, -1,  1, -1,  0, -1,  3, -1, /* -1: b a   = a^3 b */
499     0,  0,  1,  0,  2,  0,  3,  0, /*  0: identity */
500     1,  0,  2,  0,  3,  0,  0,  0, /*  1: a */
501     2,  0,  3,  0,  0,  0,  1,  0, /*  2: a^2 */
502     3,  0,  0,  0,  1,  0,  2,  0, /*  3: a^3 */};
503   /* r: rotate 180
504      b: swap top and bottom segments */
505   static const PetscInt tsegArr[4*4*2] = {
506     1, -1,  0, -1,  3, -1,  2, -1, /* -2: r b */
507     0, -1,  1, -1,  3,  0,  2,  0, /* -1: r */
508     0,  0,  1,  0,  2,  0,  3,  0, /*  0: identity */
509     1,  0,  0,  0,  2, -1,  3, -1, /*  1: b */};
510   /* https://en.wikiversity.org/wiki/Symmetric_group_S4 */
511   static const PetscInt tetArr[24*4*2] = {
512     3, -2,  2, -3,  0, -1,  1, -1, /* -12: (1324)   p22 */
513     3, -1,  1, -3,  2, -1,  0, -1, /* -11: (14)     p21 */
514     3, -3,  0, -3,  1, -1,  2, -1, /* -10: (1234)   p18 */
515     2, -1,  3, -1,  1, -3,  0, -2, /*  -9: (1423)   p17 */
516     2, -3,  0, -1,  3, -2,  1, -3, /*  -8: (1342)   p13 */
517     2, -2,  1, -2,  0, -2,  3, -2, /*  -7: (24)     p14 */
518     1, -2,  0, -2,  2, -2,  3, -1, /*  -6: (34)     p6  */
519     1, -1,  3, -3,  0, -3,  2, -2, /*  -5: (1243)   p10 */
520     1, -3,  2, -1,  3, -1,  0, -3, /*  -4: (1432)   p9  */
521     0, -3,  1, -1,  3, -3,  2, -3, /*  -3: (12)     p1  */
522     0, -2,  2, -2,  1, -2,  3, -3, /*  -2: (23)     p2  */
523     0, -1,  3, -2,  2, -3,  1, -2, /*  -1: (13)     p5  */
524     0,  0,  1,  0,  2,  0,  3,  0, /*   0: ()       p0  */
525     0,  1,  3,  1,  1,  2,  2,  0, /*   1: (123)    p4  */
526     0,  2,  2,  1,  3,  0,  1,  2, /*   2: (132)    p3  */
527     1,  2,  0,  1,  3,  1,  2,  2, /*   3: (12)(34) p7  */
528     1,  0,  2,  0,  0,  0,  3,  1, /*   4: (243)    p8  */
529     1,  1,  3,  2,  2,  2,  0,  0, /*   5: (143)    p11 */
530     2,  1,  3,  0,  0,  2,  1,  0, /*   6: (13)(24) p16 */
531     2,  2,  1,  1,  3,  2,  0,  2, /*   7: (142)    p15 */
532     2,  0,  0,  0,  1,  0,  3,  2, /*   8: (234)    p12 */
533     3,  2,  2,  2,  1,  1,  0,  1, /*   9: (14)(23) p23 */
534     3,  0,  0,  2,  2,  1,  1,  1, /*  10: (134)    p19 */
535     3,  1,  1,  2,  0,  1,  2,  1  /*  11: (124)    p20 */};
536   /* Each rotation determines a permutation of the four diagonals, and this defines the isomorphism with S_4 */
537   static const PetscInt hexArr[48*6*2] = {
538     2, -3,  3, -2,  4, -2,  5, -3,  1, -3,  0, -1, /* -24: reflect bottom and use -3 on top */
539     4, -2,  5, -2,  0, -1,  1, -4,  3, -2,  2, -3, /* -23: reflect bottom and use -3 on top */
540     5, -3,  4, -1,  1, -2,  0, -3,  3, -4,  2, -1, /* -22: reflect bottom and use -3 on top */
541     3, -1,  2, -4,  4, -4,  5, -1,  0, -4,  1, -4, /* -21: reflect bottom and use -3 on top */
542     3, -3,  2, -2,  5, -1,  4, -4,  1, -1,  0, -3, /* -20: reflect bottom and use -3 on top */
543     4, -4,  5, -4,  1, -4,  0, -1,  2, -4,  3, -1, /* -19: reflect bottom and use -3 on top */
544     2, -1,  3, -4,  5, -3,  4, -2,  0, -2,  1, -2, /* -18: reflect bottom and use -3 on top */
545     5, -1,  4, -3,  0, -3,  1, -2,  2, -2,  3, -3, /* -17: reflect bottom and use -3 on top */
546     4, -3,  5, -1,  3, -2,  2, -4,  1, -4,  0, -4, /* -16: reflect bottom and use -3 on top */
547     5, -4,  4, -4,  3, -4,  2, -2,  0, -3,  1, -1, /* -15: reflect bottom and use -3 on top */
548     3, -4,  2, -1,  1, -1,  0, -4,  4, -4,  5, -4, /* -14: reflect bottom and use -3 on top */
549     2, -2,  3, -3,  0, -2,  1, -3,  4, -2,  5, -2, /* -13: reflect bottom and use -3 on top */
550     1, -3,  0, -1,  4, -1,  5, -4,  3, -1,  2, -4, /* -12: reflect bottom and use -3 on top */
551     1, -1,  0, -3,  5, -4,  4, -1,  2, -1,  3, -4, /* -11: reflect bottom and use -3 on top */
552     5, -2,  4, -2,  2, -2,  3, -4,  1, -2,  0, -2, /* -10: reflect bottom and use -3 on top */
553     1, -2,  0, -2,  2, -1,  3, -1,  4, -1,  5, -3, /*  -9: reflect bottom and use -3 on top */
554     4, -1,  5, -3,  2, -4,  3, -2,  0, -1,  1, -3, /*  -8: reflect bottom and use -3 on top */
555     3, -2,  2, -3,  0, -4,  1, -1,  5, -1,  4, -3, /*  -7: reflect bottom and use -3 on top */
556     1, -4,  0, -4,  3, -1,  2, -1,  5, -4,  4, -4, /*  -6: reflect bottom and use -3 on top */
557     2, -4,  3, -1,  1, -3,  0, -2,  5, -3,  4, -1, /*  -5: reflect bottom and use -3 on top */
558     0, -4,  1, -4,  4, -3,  5, -2,  2, -3,  3, -2, /*  -4: reflect bottom and use -3 on top */
559     0, -3,  1, -1,  3, -3,  2, -3,  4, -3,  5, -1, /*  -3: reflect bottom and use -3 on top */
560     0, -2,  1, -2,  5, -2,  4, -3,  3, -3,  2, -2, /*  -2: reflect bottom and use -3 on top */
561     0, -1,  1, -3,  2, -3,  3, -3,  5, -2,  4, -2, /*  -1: reflect bottom and use -3 on top */
562     0,  0,  1,  0,  2,  0,  3,  0,  4,  0,  5,  0, /*   0: identity */
563     0,  1,  1,  3,  5,  3,  4,  0,  2,  0,  3,  1, /*   1: 90  rotation about z */
564     0,  2,  1,  2,  3,  0,  2,  0,  5,  3,  4,  1, /*   2: 180 rotation about z */
565     0,  3,  1,  1,  4,  0,  5,  3,  3,  0,  2,  1, /*   3: 270 rotation about z */
566     2,  3,  3,  2,  1,  0,  0,  3,  4,  3,  5,  1, /*   4: 90  rotation about x */
567     1,  3,  0,  1,  3,  2,  2,  2,  4,  2,  5,  2, /*   5: 180 rotation about x */
568     3,  1,  2,  0,  0,  1,  1,  2,  4,  1,  5,  3, /*   6: 270 rotation about x */
569     4,  0,  5,  0,  2,  1,  3,  3,  1,  1,  0,  3, /*   7: 90  rotation about y */
570     1,  1,  0,  3,  2,  2,  3,  2,  5,  1,  4,  3, /*   8: 180 rotation about y */
571     5,  1,  4,  3,  2,  3,  3,  1,  0,  0,  1,  0, /*   9: 270 rotation about y */
572     1,  0,  0,  0,  5,  1,  4,  2,  3,  2,  2,  3, /*  10: 180 rotation about x+y */
573     1,  2,  0,  2,  4,  2,  5,  1,  2,  2,  3,  3, /*  11: 180 rotation about x-y */
574     2,  1,  3,  0,  0,  3,  1,  0,  5,  0,  4,  0, /*  12: 180 rotation about y+z */
575     3,  3,  2,  2,  1,  2,  0,  1,  5,  2,  4,  2, /*  13: 180 rotation about y-z */
576     5,  3,  4,  1,  3,  1,  2,  3,  1,  3,  0,  1, /*  14: 180 rotation about z+x */
577     4,  2,  5,  2,  3,  3,  2,  1,  0,  2,  1,  2, /*  15: 180 rotation about z-x */
578     5,  0,  4,  0,  0,  0,  1,  3,  3,  1,  2,  0, /*  16: 120 rotation about x+y+z (v0v6) */
579     2,  0,  3,  1,  5,  0,  4,  3,  1,  0,  0,  0, /*  17: 240 rotation about x+y+z (v0v6) */
580     4,  3,  5,  1,  1,  1,  0,  2,  3,  3,  2,  2, /*  18: 120 rotation about x+y-z (v4v2) */
581     3,  2,  2,  3,  5,  2,  4,  1,  0,  1,  1,  3, /*  19: 240 rotation about x+y-z (v4v2) */
582     3,  0,  2,  1,  4,  1,  5,  2,  1,  2,  0,  2, /*  20: 120 rotation about x-y+z (v1v5) */
583     5,  2,  4,  2,  1,  3,  0,  0,  2,  3,  3,  2, /*  21: 240 rotation about x-y+z (v1v5) */
584     4,  1,  5,  3,  0,  2,  1,  1,  2,  1,  3,  0, /*  22: 120 rotation about x-y-z (v7v3) */
585     2,  2,  3,  3,  4,  3,  5,  0,  0,  3,  1,  1, /*  23: 240 rotation about x-y-z (v7v3) */
586   };
587   static const PetscInt tripArr[12*5*2] = {
588     1, -3,  0, -1,  3, -1,  4, -1,  2, -1, /* -6: reflect bottom and top */
589     1, -1,  0, -3,  4, -1,  2, -1,  3, -1, /* -5: reflect bottom and top */
590     1, -2,  0, -2,  2, -1,  3, -1,  4, -1, /* -4: reflect bottom and top */
591     0, -3,  1, -1,  3, -3,  2, -3,  4, -3, /* -3: reflect bottom and top */
592     0, -2,  1, -2,  4, -3,  3, -3,  2, -3, /* -2: reflect bottom and top */
593     0, -1,  1, -3,  2, -3,  4, -3,  3, -3, /* -1: reflect bottom and top */
594     0,  0,  1,  0,  2,  0,  3,  0,  4,  0, /*  0: identity */
595     0,  1,  1,  2,  4,  0,  2,  0,  3,  0, /*  1: 120 rotation about z */
596     0,  2,  1,  1,  3,  0,  4,  0,  2,  0, /*  2: 240 rotation about z */
597     1,  1,  0,  2,  2,  2,  4,  2,  3,  2, /*  3: 180 rotation about y of 0 */
598     1,  0,  0,  0,  4,  2,  3,  2,  2,  2, /*  4: 180 rotation about y of 1 */
599     1,  2,  0,  1,  3,  2,  2,  2,  4,  2, /*  5: 180 rotation about y of 2 */
600   };
601   /* a: rotate 120 about z
602      b: swap top and bottom segments
603      r: reflect */
604   static const PetscInt ttriArr[12*5*2] = {
605     1, -3,  0, -3,  2, -2,  4, -2,  3, -2, /* -6: r b a^2 */
606     1, -2,  0, -2,  4, -2,  3, -2,  2, -2, /* -5: r b a */
607     1, -1,  0, -1,  3, -2,  2, -2,  4, -2, /* -4: r b */
608     0, -3,  1, -3,  2, -1,  4, -1,  3, -1, /* -3: r a^2 */
609     0, -2,  1, -2,  4, -1,  3, -1,  2, -1, /* -2: r a */
610     0, -1,  1, -1,  3, -1,  2, -1,  4, -1, /* -1: r */
611     0,  0,  1,  0,  2,  0,  3,  0,  4,  0, /*  0: identity */
612     0,  1,  1,  1,  3,  0,  4,  0,  2,  0, /*  1: a */
613     0,  2,  1,  2,  4,  0,  2,  0,  3,  0, /*  2: a^2 */
614     1,  0,  0,  0,  2,  1,  3,  1,  4,  1, /*  3: b */
615     1,  1,  0,  1,  3,  1,  4,  1,  2,  1, /*  4: b a */
616     1,  2,  0,  2,  4,  1,  2,  1,  3,  1, /*  5: b a^2 */
617   };
618   /* a: rotate 90 about z
619      b: swap top and bottom segments
620      r: reflect */
621   static const PetscInt tquadArr[16*6*2] = {
622     1, -4,  0, -4,  3, -2,  2, -2,  5, -2,  4, -2, /* -8: r b a^3 */
623     1, -3,  0, -3,  2, -2,  5, -2,  4, -2,  3, -2, /* -7: r b a^2 */
624     1, -2,  0, -2,  5, -2,  4, -2,  3, -2,  2, -2, /* -6: r b a */
625     1, -1,  0, -1,  4, -2,  3, -2,  2, -2,  5, -2, /* -5: r b */
626     0, -4,  1, -4,  3, -1,  2, -1,  5, -1,  4, -1, /* -4: r a^3 */
627     0, -3,  1, -3,  2, -1,  5, -1,  4, -1,  3, -1, /* -3: r a^2 */
628     0, -2,  1, -2,  5, -1,  4, -1,  3, -1,  2, -1, /* -2: r a */
629     0, -1,  1, -1,  4, -1,  3, -1,  2, -1,  5, -1, /* -1: r */
630     0,  0,  1,  0,  2,  0,  3,  0,  4,  0,  5,  0, /*  0: identity */
631     0,  1,  1,  1,  3,  0,  4,  0,  5,  0,  2,  0, /*  1: a */
632     0,  2,  1,  2,  4,  0,  5,  0,  2,  0,  3,  0, /*  2: a^2 */
633     0,  3,  1,  3,  5,  0,  2,  0,  3,  0,  4,  0, /*  3: a^3 */
634     1,  0,  0,  0,  2,  1,  3,  1,  4,  1,  5,  1, /*  4: b */
635     1,  1,  0,  1,  3,  1,  4,  1,  5,  1,  2,  1, /*  5: b a */
636     1,  2,  0,  2,  4,  1,  5,  1,  2,  1,  3,  1, /*  6: b a^2 */
637     1,  3,  0,  3,  5,  1,  2,  1,  3,  1,  4,  1, /*  7: b a^3 */
638   };
639   static const PetscInt pyrArr[8*5*2] = {
640     0, -4,  2, -3,  1, -3,  4, -3,  3, -3, /* -4: Reflect bottom face */
641     0, -3,  3, -3,  2, -3,  1, -3,  4, -3, /* -3: Reflect bottom face */
642     0, -2,  4, -3,  3, -3,  2, -3,  1, -3, /* -2: Reflect bottom face */
643     0, -1,  1, -3,  4, -3,  3, -3,  2, -3, /* -1: Reflect bottom face */
644     0,  0,  1,  0,  2,  0,  3,  0,  4,  0, /*  0: identity */
645     0,  1,  4,  0,  1,  0,  2,  0,  3,  0, /*  1:  90 rotation about z */
646     0,  2,  3,  0,  4,  0,  1,  0,  2,  0, /*  2: 180 rotation about z */
647     0,  3,  2,  0,  3,  0,  4,  0,  1,  0, /*  3: 270 rotation about z */
648   };
649   switch (ct) {
650     case DM_POLYTOPE_POINT:              return pntArr;
651     case DM_POLYTOPE_SEGMENT:            return &segArr[(o+1)*2*2];
652     case DM_POLYTOPE_POINT_PRISM_TENSOR: return &segArr[(o+1)*2*2];
653     case DM_POLYTOPE_TRIANGLE:           return &triArr[(o+3)*3*2];
654     case DM_POLYTOPE_QUADRILATERAL:      return &quadArr[(o+4)*4*2];
655     case DM_POLYTOPE_SEG_PRISM_TENSOR:   return &tsegArr[(o+2)*4*2];
656     case DM_POLYTOPE_TETRAHEDRON:        return &tetArr[(o+12)*4*2];
657     case DM_POLYTOPE_HEXAHEDRON:         return &hexArr[(o+24)*6*2];
658     case DM_POLYTOPE_TRI_PRISM:          return &tripArr[(o+6)*5*2];
659     case DM_POLYTOPE_TRI_PRISM_TENSOR:   return &ttriArr[(o+6)*5*2];
660     case DM_POLYTOPE_QUAD_PRISM_TENSOR:  return &tquadArr[(o+8)*6*2];
661     case DM_POLYTOPE_PYRAMID:            return &pyrArr[(o+4)*5*2];
662     default: return NULL;
663   }
664 }
665 
666 /* A vertex arrangment is a vertex order */
667 PETSC_STATIC_INLINE const PetscInt *DMPolytopeTypeGetVertexArrangment(DMPolytopeType ct, PetscInt o)
668 {
669   static const PetscInt pntVerts[1]    = {0};
670   static const PetscInt segVerts[2*2]  = {
671     1, 0,
672     0, 1};
673   static const PetscInt triVerts[6*3]  = {
674     1, 0, 2,
675     0, 2, 1,
676     2, 1, 0,
677     0, 1, 2,
678     1, 2, 0,
679     2, 0, 1};
680   static const PetscInt quadVerts[8*4]  = {
681     2, 1, 0, 3,
682     1, 0, 3, 2,
683     0, 3, 2, 1,
684     3, 2, 1, 0,
685     0, 1, 2, 3,
686     1, 2, 3, 0,
687     2, 3, 0, 1,
688     3, 0, 1, 2};
689   static const PetscInt tsegVerts[4*4]  = {
690     3, 2, 1, 0,
691     1, 0, 3, 2,
692     0, 1, 2, 3,
693     2, 3, 0, 1};
694   static const PetscInt tetVerts[24*4] = {
695     2, 3, 1, 0, /* -12: (1324)   p22 */
696     3, 1, 2, 0, /* -11: (14)     p21 */
697     1, 2, 3, 0, /* -10: (1234)   p18 */
698     3, 2, 0, 1, /*  -9: (1423)   p17 */
699     2, 0, 3, 1, /*  -8: (1342)   p13 */
700     0, 3, 2, 1, /*  -7: (24)     p14 */
701     0, 1, 3, 2, /*  -6: (34)     p6  */
702     1, 3, 0, 2, /*  -5: (1243)   p10 */
703     3, 0, 1, 2, /*  -4: (1432    p9  */
704     1, 0, 2, 3, /*  -3: (12)     p1  */
705     0, 2, 1, 3, /*  -2: (23)     p2  */
706     2, 1, 0, 3, /*  -1: (13)     p5  */
707     0, 1, 2, 3, /*   0: ()       p0  */
708     1, 2, 0, 3, /*   1: (123)    p4  */
709     2, 0, 1, 3, /*   2: (132)    p3  */
710     1, 0, 3, 2, /*   3: (12)(34) p7  */
711     0, 3, 1, 2, /*   4: (243)    p8  */
712     3, 1, 0, 2, /*   5: (143)    p11 */
713     2, 3, 0, 1, /*   6: (13)(24) p16 */
714     3, 0, 2, 1, /*   7: (142)    p15 */
715     0, 2, 3, 1, /*   8: (234)    p12 */
716     3, 2, 1, 0, /*   9: (14)(23) p23 */
717     2, 1, 3, 0, /*  10: (134)    p19 */
718     1, 3, 2, 0  /*  11: (124)    p20 */};
719   static const PetscInt hexVerts[48*8] = {
720     3,  0,  4,  5,  2,  6,  7,  1, /* -24: reflected 23 */
721     3,  5,  6,  2,  0,  1,  7,  4, /* -23: reflected 22 */
722     4,  0,  1,  7,  5,  6,  2,  3, /* -22: reflected 21 */
723     6,  7,  1,  2,  5,  3,  0,  4, /* -21: reflected 20 */
724     1,  2,  6,  7,  0,  4,  5,  3, /* -20: reflected 19 */
725     6,  2,  3,  5,  7,  4,  0,  1, /* -19: reflected 18 */
726     4,  5,  3,  0,  7,  1,  2,  6, /* -18: reflected 17 */
727     1,  7,  4,  0,  2,  3,  5,  6, /* -17: reflected 16 */
728     2,  3,  5,  6,  1,  7,  4,  0, /* -16: reflected 15 */
729     7,  4,  0,  1,  6,  2,  3,  5, /* -15: reflected 14 */
730     7,  1,  2,  6,  4,  5,  3,  0, /* -14: reflected 13 */
731     0,  4,  5,  3,  1,  2,  6,  7, /* -13: reflected 12 */
732     5,  4,  7,  6,  3,  2,  1,  0, /* -12: reflected 11 */
733     7,  6,  5,  4,  1,  0,  3,  2, /* -11: reflected 10 */
734     0,  1,  7,  4,  3,  5,  6,  2, /* -10: reflected  9 */
735     4,  7,  6,  5,  0,  3,  2,  1, /*  -9: reflected  8 */
736     5,  6,  2,  3,  4,  0,  1,  7, /*  -8: reflected  7 */
737     2,  6,  7,  1,  3,  0,  4,  5, /*  -7: reflected  6 */
738     6,  5,  4,  7,  2,  1,  0,  3, /*  -6: reflected  5 */
739     5,  3,  0,  4,  6,  7,  1,  2, /*  -5: reflected  4 */
740     2,  1,  0,  3,  6,  5,  4,  7, /*  -4: reflected  3 */
741     1,  0,  3,  2,  7,  6,  5,  4, /*  -3: reflected  2 */
742     0,  3,  2,  1,  4,  7,  6,  5, /*  -2: reflected  1 */
743     3,  2,  1,  0,  5,  4,  7,  6, /*  -1: reflected  0 */
744     0,  1,  2,  3,  4,  5,  6,  7, /*   0: identity */
745     1,  2,  3,  0,  7,  4,  5,  6, /*   1: 90  rotation about z */
746     2,  3,  0,  1,  6,  7,  4,  5, /*   2: 180 rotation about z */
747     3,  0,  1,  2,  5,  6,  7,  4, /*   3: 270 rotation about z */
748     4,  0,  3,  5,  7,  6,  2,  1, /*   4: 90  rotation about x */
749     7,  4,  5,  6,  1,  2,  3,  0, /*   5: 180 rotation about x */
750     1,  7,  6,  2,  0,  3,  5,  4, /*   6: 270 rotation about x */
751     3,  2,  6,  5,  0,  4,  7,  1, /*   7: 90  rotation about y */
752     5,  6,  7,  4,  3,  0,  1,  2, /*   8: 180 rotation about y */
753     4,  7,  1,  0,  5,  3,  2,  6, /*   9: 270 rotation about y */
754     4,  5,  6,  7,  0,  1,  2,  3, /*  10: 180 rotation about x+y */
755     6,  7,  4,  5,  2,  3,  0,  1, /*  11: 180 rotation about x-y */
756     3,  5,  4,  0,  2,  1,  7,  6, /*  12: 180 rotation about y+z */
757     6,  2,  1,  7,  5,  4,  0,  3, /*  13: 180 rotation about y-z */
758     1,  0,  4,  7,  2,  6,  5,  3, /*  14: 180 rotation about z+x */
759     6,  5,  3,  2,  7,  1,  0,  4, /*  15: 180 rotation about z-x */
760     0,  4,  7,  1,  3,  2,  6,  5, /*  16: 120 rotation about x+y+z (v0v6) */
761     0,  3,  5,  4,  1,  7,  6,  2, /*  17: 240 rotation about x+y+z (v0v6) */
762     5,  3,  2,  6,  4,  7,  1,  0, /*  18: 120 rotation about x+y-z (v4v2) */
763     7,  6,  2,  1,  4,  0,  3,  5, /*  19: 240 rotation about x+y-z (v4v2) */
764     2,  1,  7,  6,  3,  5,  4,  0, /*  20: 120 rotation about x-y+z (v1v5) */
765     7,  1,  0,  4,  6,  5,  3,  2, /*  21: 240 rotation about x-y+z (v1v5) */
766     2,  6,  5,  3,  1,  0,  4,  7, /*  22: 120 rotation about x-y-z (v7v3) */
767     5,  4,  0,  3,  6,  2,  1,  7, /*  23: 240 rotation about x-y-z (v7v3) */
768   };
769   static const PetscInt tripVerts[12*6] = {
770     4,  3,  5,  2,  1,  0, /* -6: reflect bottom and top */
771     5,  4,  3,  1,  0,  2, /* -5: reflect bottom and top */
772     3,  5,  4,  0,  2,  1, /* -4: reflect bottom and top */
773     1,  0,  2,  5,  4,  3, /* -3: reflect bottom and top */
774     0,  2,  1,  3,  5,  4, /* -2: reflect bottom and top */
775     2,  1,  0,  4,  3,  5, /* -1: reflect bottom and top */
776     0,  1,  2,  3,  4,  5, /*  0: identity */
777     1,  2,  0,  5,  3,  4, /*  1: 120 rotation about z */
778     2,  0,  1,  4,  5,  3, /*  2: 240 rotation about z */
779     4,  5,  3,  2,  0,  1, /*  3: 180 rotation about y of 0 */
780     3,  4,  5,  0,  1,  2, /*  4: 180 rotation about y of 1 */
781     5,  3,  4,  1,  2,  0, /*  5: 180 rotation about y of 2 */
782   };
783   static const PetscInt ttriVerts[12*6] = {
784     4,  3,  5,  1,  0,  2, /* -6: r b a^2 */
785     3,  5,  4,  0,  2,  1, /* -5: r b a */
786     5,  4,  3,  2,  1,  0, /* -4: r b */
787     1,  0,  2,  4,  3,  5, /* -3: r a^2 */
788     0,  2,  1,  3,  5,  4, /* -2: r a */
789     2,  1,  0,  5,  4,  3, /* -1: r */
790     0,  1,  2,  3,  4,  5, /*  0: identity */
791     1,  2,  0,  4,  5,  3, /*  1: a */
792     2,  0,  1,  5,  3,  4, /*  2: a^2 */
793     3,  4,  5,  0,  1,  2, /*  3: b */
794     4,  5,  3,  1,  2,  0, /*  4: b a */
795     5,  3,  4,  2,  0,  1, /*  5: b a^2 */
796   };
797   /* a: rotate 90 about z
798      b: swap top and bottom segments
799      r: reflect */
800   static const PetscInt tquadVerts[16*8] = {
801     6,  5,  4,  7,  2,  1,  0,  3, /* -8: r b a^3 */
802     5,  4,  7,  6,  1,  0,  3,  2, /* -7: r b a^2 */
803     4,  7,  6,  5,  0,  3,  2,  1, /* -6: r b a */
804     7,  6,  5,  4,  3,  2,  1,  0, /* -5: r b */
805     2,  1,  0,  3,  6,  5,  4,  7, /* -4: r a^3 */
806     1,  0,  3,  2,  5,  4,  7,  6, /* -3: r a^2 */
807     0,  3,  2,  1,  4,  7,  6,  5, /* -2: r a */
808     3,  2,  1,  0,  7,  6,  5,  4, /* -1: r */
809     0,  1,  2,  3,  4,  5,  6,  7, /*  0: identity */
810     1,  2,  3,  0,  5,  6,  7,  4, /*  1: a */
811     2,  3,  0,  1,  6,  7,  4,  5, /*  2: a^2 */
812     3,  0,  1,  2,  7,  4,  5,  6, /*  3: a^3 */
813     4,  5,  6,  7,  0,  1,  2,  3, /*  4: b */
814     5,  6,  7,  4,  1,  2,  3,  0, /*  5: b a */
815     6,  7,  4,  5,  2,  3,  0,  1, /*  6: b a^2 */
816     7,  4,  5,  6,  3,  0,  1,  2, /*  7: b a^3 */
817   };
818   static const PetscInt pyrVerts[8*5] = {
819     2,  1,  0,  3,  4, /* -4: Reflect bottom face */
820     1,  0,  3,  2,  4, /* -3: Reflect bottom face */
821     0,  3,  2,  1,  4, /* -2: Reflect bottom face */
822     3,  2,  1,  0,  4, /* -1: Reflect bottom face */
823     0,  1,  2,  3,  4, /*  0: identity */
824     1,  2,  3,  0,  4, /*  1:  90 rotation about z */
825     2,  3,  0,  1,  4, /*  2: 180 rotation about z */
826     3,  0,  1,  2,  4, /*  3: 270 rotation about z */
827   };
828   switch (ct) {
829     case DM_POLYTOPE_POINT:              return pntVerts;
830     case DM_POLYTOPE_SEGMENT:            return &segVerts[(o+1)*2];
831     case DM_POLYTOPE_POINT_PRISM_TENSOR: return &segVerts[(o+1)*2];
832     case DM_POLYTOPE_TRIANGLE:           return &triVerts[(o+3)*3];
833     case DM_POLYTOPE_QUADRILATERAL:      return &quadVerts[(o+4)*4];
834     case DM_POLYTOPE_SEG_PRISM_TENSOR:   return &tsegVerts[(o+2)*4];
835     case DM_POLYTOPE_TETRAHEDRON:        return &tetVerts[(o+12)*4];
836     case DM_POLYTOPE_HEXAHEDRON:         return &hexVerts[(o+24)*8];
837     case DM_POLYTOPE_TRI_PRISM:          return &tripVerts[(o+6)*6];
838     case DM_POLYTOPE_TRI_PRISM_TENSOR:   return &ttriVerts[(o+6)*6];
839     case DM_POLYTOPE_QUAD_PRISM_TENSOR:  return &tquadVerts[(o+8)*8];
840     case DM_POLYTOPE_PYRAMID:            return &pyrVerts[(o+4)*5];
841     default: return NULL;
842   }
843 }
844 
845 /* This is orientation o1 acting on orientation o2 */
846 PETSC_STATIC_INLINE PetscInt DMPolytopeTypeComposeOrientation(DMPolytopeType ct, PetscInt o1, PetscInt o2)
847 {
848   static const PetscInt segMult[2*2] = {
849      0, -1,
850     -1,  0};
851   static const PetscInt triMult[6*6] = {
852      0,  2,  1, -3, -1, -2,
853      1,  0,  2, -2, -3, -1,
854      2,  1,  0, -1, -2, -3,
855     -3, -2, -1,  0,  1,  2,
856     -2, -1, -3,  1,  2,  0,
857     -1, -3, -2,  2,  0,  1};
858   static const PetscInt quadMult[8*8] = {
859      0,  3,  2,  1, -4, -1, -2, -3,
860      1,  0,  3,  2, -3, -4, -1, -2,
861      2,  1,  0,  3, -2, -3, -4, -1,
862      3,  2,  1,  0, -1, -2, -3, -4,
863     -4, -3, -2, -1,  0,  1,  2,  3,
864     -3, -2, -1, -4,  1,  2,  3,  0,
865     -2, -1, -4, -3,  2,  3,  0,  1,
866     -1, -4, -3, -2,  3,  0,  1,  2};
867   static const PetscInt tsegMult[4*4] = {
868      0,  1, -2, -1,
869      1,  0, -1, -2,
870     -2, -1,  0,  1,
871     -1, -2,  1,  0};
872   static const PetscInt tetMult[24*24] = {
873     3, 2, 7, 0, 5, 10, 9, 8, 1, 6, 11, 4, -12, -7, -5, -9, -10, -2, -6, -1, -11, -3, -4, -8,
874     4, 0, 8, 1, 3, 11, 10, 6, 2, 7, 9, 5, -11, -9, -4, -8, -12, -1, -5, -3, -10, -2, -6, -7,
875     5, 1, 6, 2, 4, 9, 11, 7, 0, 8, 10, 3, -10, -8, -6, -7, -11, -3, -4, -2, -12, -1, -5, -9,
876     0, 8, 4, 3, 11, 1, 6, 2, 10, 9, 5, 7, -9, -4, -11, -12, -1, -8, -3, -10, -5, -6, -7, -2,
877     1, 6, 5, 4, 9, 2, 7, 0, 11, 10, 3, 8, -8, -6, -10, -11, -3, -7, -2, -12, -4, -5, -9, -1,
878     2, 7, 3, 5, 10, 0, 8, 1, 9, 11, 4, 6, -7, -5, -12, -10, -2, -9, -1, -11, -6, -4, -8, -3,
879     6, 5, 1, 9, 2, 4, 0, 11, 7, 3, 8, 10, -6, -10, -8, -3, -7, -11, -12, -4, -2, -9, -1, -5,
880     7, 3, 2, 10, 0, 5, 1, 9, 8, 4, 6, 11, -5, -12, -7, -2, -9, -10, -11, -6, -1, -8, -3, -4,
881     8, 4, 0, 11, 1, 3, 2, 10, 6, 5, 7, 9, -4, -11, -9, -1, -8, -12, -10, -5, -3, -7, -2, -6,
882     9, 11, 10, 6, 8, 7, 3, 5, 4, 0, 2, 1, -3, -1, -2, -6, -4, -5, -9, -7, -8, -12, -10, -11,
883     10, 9, 11, 7, 6, 8, 4, 3, 5, 1, 0, 2, -2, -3, -1, -5, -6, -4, -8, -9, -7, -11, -12, -10,
884     11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12,
885     -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
886     -11, -10, -12, -8, -7, -9, -5, -4, -6, -2, -1, -3, 1, 2, 0, 4, 5, 3, 7, 8, 6, 10, 11, 9,
887     -10, -12, -11, -7, -9, -8, -4, -6, -5, -1, -3, -2, 2, 0, 1, 5, 3, 4, 8, 6, 7, 11, 9, 10,
888     -9, -5, -1, -12, -2, -4, -3, -11, -7, -6, -8, -10, 3, 10, 8, 0, 7, 11, 9, 4, 2, 6, 1, 5,
889     -8, -4, -3, -11, -1, -6, -2, -10, -9, -5, -7, -12, 4, 11, 6, 1, 8, 9, 10, 5, 0, 7, 2, 3,
890     -7, -6, -2, -10, -3, -5, -1, -12, -8, -4, -9, -11, 5, 9, 7, 2, 6, 10, 11, 3, 1, 8, 0, 4,
891     -3, -8, -4, -6, -11, -1, -9, -2, -10, -12, -5, -7, 6, 4, 11, 9, 1, 8, 0, 10, 5, 3, 7, 2,
892     -2, -7, -6, -5, -10, -3, -8, -1, -12, -11, -4, -9, 7, 5, 9, 10, 2, 6, 1, 11, 3, 4, 8, 0,
893     -1, -9, -5, -4, -12, -2, -7, -3, -11, -10, -6, -8, 8, 3, 10, 11, 0, 7, 2, 9, 4, 5, 6, 1,
894     -6, -2, -7, -3, -5, -10, -12, -8, -1, -9, -11, -4, 9, 7, 5, 6, 10, 2, 3, 1, 11, 0, 4, 8,
895     -5, -1, -9, -2, -4, -12, -11, -7, -3, -8, -10, -6, 10, 8, 3, 7, 11, 0, 4, 2, 9, 1, 5, 6,
896     -4, -3, -8, -1, -6, -11, -10, -9, -2, -7, -12, -5, 11, 6, 4, 8, 9, 1, 5, 0, 10, 2, 3, 7,
897     };
898   static const PetscInt hexMult[48*48] = {
899     18, 2, 5, 22, 21, 8, 16, 0, 13, 6, 11, 3, 15, 9, 4, 23, 12, 1, 19, 10, 7, 20, 14, 17, -24, -10, -20, -16, -12, -21, -4, -5, -18, -13, -15, -8, -2, -11, -14, -7, -3, -22, -6, -17, -19, -9, -1, -23,
900     8, 20, 19, 2, 5, 23, 0, 17, 11, 1, 15, 7, 13, 4, 10, 18, 3, 14, 21, 9, 12, 22, 6, 16, -23, -13, -17, -7, -8, -19, -16, -12, -22, -2, -14, -5, -10, -15, -11, -4, -20, -9, -21, -3, -6, -18, -24, -1,
901     2, 17, 23, 8, 0, 19, 5, 20, 1, 11, 9, 14, 12, 6, 3, 16, 10, 7, 22, 15, 13, 21, 4, 18, -22, -14, -19, -5, -15, -17, -10, -2, -23, -12, -13, -7, -16, -8, -4, -11, -24, -3, -18, -9, -1, -21, -20, -6,
902     21, 5, 2, 16, 18, 0, 22, 8, 4, 12, 3, 11, 14, 7, 13, 20, 6, 10, 17, 1, 9, 23, 15, 19, -21, -8, -18, -15, -4, -24, -12, -14, -20, -7, -16, -10, -11, -2, -5, -13, -6, -19, -3, -23, -22, -1, -9, -17,
903     16, 8, 0, 21, 22, 2, 18, 5, 12, 4, 1, 10, 9, 15, 6, 19, 13, 11, 23, 3, 14, 17, 7, 20, -20, -16, -24, -10, -2, -18, -11, -7, -21, -14, -8, -15, -12, -4, -13, -5, -9, -23, -1, -19, -17, -3, -6, -22,
904     5, 19, 20, 0, 8, 17, 2, 23, 10, 3, 7, 15, 6, 12, 11, 22, 1, 9, 16, 14, 4, 18, 13, 21, -19, -5, -22, -14, -16, -23, -8, -11, -17, -4, -7, -13, -15, -10, -12, -2, -21, -6, -20, -1, -9, -24, -18, -3,
905     22, 0, 8, 18, 16, 5, 21, 2, 6, 13, 10, 1, 7, 14, 12, 17, 4, 3, 20, 11, 15, 19, 9, 23, -18, -15, -21, -8, -11, -20, -2, -13, -24, -5, -10, -16, -4, -12, -7, -14, -1, -17, -9, -22, -23, -6, -3, -19,
906     0, 23, 17, 5, 2, 20, 8, 19, 3, 10, 14, 9, 4, 13, 1, 21, 11, 15, 18, 7, 6, 16, 12, 22, -17, -7, -23, -13, -10, -22, -15, -4, -19, -11, -5, -14, -8, -16, -2, -12, -18, -1, -24, -6, -3, -20, -21, -9,
907     10, 13, 6, 1, 11, 12, 3, 4, 8, 0, 22, 18, 19, 23, 5, 15, 2, 21, 9, 16, 17, 7, 20, 14, -16, -24, -10, -20, -23, -8, -19, -6, -15, -3, -21, -18, -22, -17, -9, -1, -14, -12, -7, -4, -11, -13, -5, -2,
908     1, 4, 12, 10, 3, 6, 11, 13, 0, 8, 16, 21, 17, 20, 2, 14, 5, 18, 7, 22, 19, 9, 23, 15, -15, -21, -8, -18, -17, -10, -22, -3, -16, -6, -24, -20, -19, -23, -1, -9, -5, -4, -13, -12, -2, -7, -14, -11,
909     14, 10, 3, 9, 7, 1, 15, 11, 17, 23, 0, 5, 16, 22, 20, 6, 19, 8, 12, 2, 21, 4, 18, 13, -14, -19, -5, -22, -3, -13, -9, -20, -7, -21, -23, -17, -6, -1, -24, -18, -12, -16, -2, -8, -10, -4, -11, -15,
910     7, 3, 10, 15, 14, 11, 9, 1, 20, 19, 5, 0, 18, 21, 17, 4, 23, 2, 13, 8, 22, 6, 16, 12, -13, -17, -7, -23, -9, -14, -3, -24, -5, -18, -22, -19, -1, -6, -20, -21, -2, -10, -12, -15, -16, -11, -4, -8,
911     13, 14, 15, 12, 4, 9, 6, 7, 21, 22, 23, 20, 2, 0, 18, 3, 16, 17, 1, 19, 8, 11, 5, 10, -12, -9, -11, -6, -21, -4, -24, -22, -2, -23, -3, -1, -20, -18, -19, -17, -16, -14, -15, -13, -5, -8, -10, -7,
912     6, 9, 7, 4, 12, 14, 13, 15, 16, 18, 17, 19, 0, 2, 22, 1, 21, 23, 3, 20, 5, 10, 8, 11, -11, -6, -12, -9, -20, -2, -18, -17, -4, -19, -1, -3, -21, -24, -23, -22, -8, -7, -10, -5, -13, -16, -15, -14,
913     3, 12, 4, 11, 1, 13, 10, 6, 2, 5, 21, 16, 23, 19, 0, 9, 8, 22, 15, 18, 20, 14, 17, 7, -10, -20, -16, -24, -22, -15, -17, -1, -8, -9, -18, -21, -23, -19, -3, -6, -13, -2, -5, -11, -4, -14, -7, -12,
914     20, 16, 18, 23, 17, 21, 19, 22, 14, 15, 4, 6, 3, 1, 7, 0, 9, 12, 2, 13, 11, 5, 10, 8, -9, -11, -6, -12, -14, -3, -13, -10, -1, -8, -2, -4, -7, -5, -16, -15, -23, -20, -22, -18, -24, -19, -17, -21,
915     11, 6, 13, 3, 10, 4, 1, 12, 5, 2, 18, 22, 20, 17, 8, 7, 0, 16, 14, 21, 23, 15, 19, 9, -8, -18, -15, -21, -19, -16, -23, -9, -10, -1, -20, -24, -17, -22, -6, -3, -7, -11, -14, -2, -12, -5, -13, -4,
916     9, 11, 1, 14, 15, 3, 7, 10, 23, 17, 2, 8, 21, 18, 19, 13, 20, 5, 4, 0, 16, 12, 22, 6, -7, -23, -13, -17, -1, -5, -6, -21, -14, -20, -19, -22, -9, -3, -18, -24, -11, -8, -4, -16, -15, -2, -12, -10,
917     19, 21, 22, 17, 23, 16, 20, 18, 9, 7, 12, 13, 1, 3, 15, 2, 14, 4, 0, 6, 10, 8, 11, 5, -6, -12, -9, -11, -7, -1, -5, -15, -3, -16, -4, -2, -14, -13, -8, -10, -19, -21, -17, -24, -18, -23, -22, -20,
918     15, 1, 11, 7, 9, 10, 14, 3, 19, 20, 8, 2, 22, 16, 23, 12, 17, 0, 6, 5, 18, 13, 21, 4, -5, -22, -14, -19, -6, -7, -1, -18, -13, -24, -17, -23, -3, -9, -21, -20, -4, -15, -11, -10, -8, -12, -2, -16,
919     4, 15, 14, 6, 13, 7, 12, 9, 18, 16, 20, 23, 5, 8, 21, 11, 22, 19, 10, 17, 0, 3, 2, 1, -4, -1, -2, -3, -24, -12, -21, -19, -11, -17, -6, -9, -18, -20, -22, -23, -15, -5, -16, -7, -14, -10, -8, -13,
920     17, 18, 16, 19, 20, 22, 23, 21, 7, 9, 6, 4, 10, 11, 14, 5, 15, 13, 8, 12, 1, 0, 3, 2, -3, -4, -1, -2, -13, -9, -14, -16, -6, -15, -12, -11, -5, -7, -10, -8, -22, -24, -23, -21, -20, -17, -19, -18,
921     12, 7, 9, 13, 6, 15, 4, 14, 22, 21, 19, 17, 8, 5, 16, 10, 18, 20, 11, 23, 2, 1, 0, 3, -2, -3, -4, -1, -18, -11, -20, -23, -12, -22, -9, -6, -24, -21, -17, -19, -10, -13, -8, -14, -7, -15, -16, -5,
922     23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17, -18, -19, -20, -21, -22, -23, -24,
923     -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
924     -13, -8, -10, -14, -7, -16, -5, -15, -23, -22, -20, -18, -9, -6, -17, -11, -19, -21, -12, -24, -3, -2, -1, -4, 1, 2, 3, 0, 17, 10, 19, 22, 11, 21, 8, 5, 23, 20, 16, 18, 9, 12, 7, 13, 6, 14, 15, 4,
925     -18, -19, -17, -20, -21, -23, -24, -22, -8, -10, -7, -5, -11, -12, -15, -6, -16, -14, -9, -13, -2, -1, -4, -3, 2, 3, 0, 1, 12, 8, 13, 15, 5, 14, 11, 10, 4, 6, 9, 7, 21, 23, 22, 20, 19, 16, 18, 17,
926     -5, -16, -15, -7, -14, -8, -13, -10, -19, -17, -21, -24, -6, -9, -22, -12, -23, -20, -11, -18, -1, -4, -3, -2, 3, 0, 1, 2, 23, 11, 20, 18, 10, 16, 5, 8, 17, 19, 21, 22, 14, 4, 15, 6, 13, 9, 7, 12,
927     -16, -2, -12, -8, -10, -11, -15, -4, -20, -21, -9, -3, -23, -17, -24, -13, -18, -1, -7, -6, -19, -14, -22, -5, 4, 21, 13, 18, 5, 6, 0, 17, 12, 23, 16, 22, 2, 8, 20, 19, 3, 14, 10, 9, 7, 11, 1, 15,
928     -20, -22, -23, -18, -24, -17, -21, -19, -10, -8, -13, -14, -2, -4, -16, -3, -15, -5, -1, -7, -11, -9, -12, -6, 5, 11, 8, 10, 6, 0, 4, 14, 2, 15, 3, 1, 13, 12, 7, 9, 18, 20, 16, 23, 17, 22, 21, 19,
929     -10, -12, -2, -15, -16, -4, -8, -11, -24, -18, -3, -9, -22, -19, -20, -14, -21, -6, -5, -1, -17, -13, -23, -7, 6, 22, 12, 16, 0, 4, 5, 20, 13, 19, 18, 21, 8, 2, 17, 23, 10, 7, 3, 15, 14, 1, 11, 9,
930     -12, -7, -14, -4, -11, -5, -2, -13, -6, -3, -19, -23, -21, -18, -9, -8, -1, -17, -15, -22, -24, -16, -20, -10, 7, 17, 14, 20, 18, 15, 22, 8, 9, 0, 19, 23, 16, 21, 5, 2, 6, 10, 13, 1, 11, 4, 12, 3,
931     -21, -17, -19, -24, -18, -22, -20, -23, -15, -16, -5, -7, -4, -2, -8, -1, -10, -13, -3, -14, -12, -6, -11, -9, 8, 10, 5, 11, 13, 2, 12, 9, 0, 7, 1, 3, 6, 4, 15, 14, 22, 19, 21, 17, 23, 18, 16, 20,
932     -4, -13, -5, -12, -2, -14, -11, -7, -3, -6, -22, -17, -24, -20, -1, -10, -9, -23, -16, -19, -21, -15, -18, -8, 9, 19, 15, 23, 21, 14, 16, 0, 7, 8, 17, 20, 22, 18, 2, 5, 12, 1, 4, 10, 3, 13, 6, 11,
933     -7, -10, -8, -5, -13, -15, -14, -16, -17, -19, -18, -20, -1, -3, -23, -2, -22, -24, -4, -21, -6, -11, -9, -12, 10, 5, 11, 8, 19, 1, 17, 16, 3, 18, 0, 2, 20, 23, 22, 21, 7, 6, 9, 4, 12, 15, 14, 13,
934     -14, -15, -16, -13, -5, -10, -7, -8, -22, -23, -24, -21, -3, -1, -19, -4, -17, -18, -2, -20, -9, -12, -6, -11, 11, 8, 10, 5, 20, 3, 23, 21, 1, 22, 2, 0, 19, 17, 18, 16, 15, 13, 14, 12, 4, 7, 9, 6,
935     -8, -4, -11, -16, -15, -12, -10, -2, -21, -20, -6, -1, -19, -22, -18, -5, -24, -3, -14, -9, -23, -7, -17, -13, 12, 16, 6, 22, 8, 13, 2, 23, 4, 17, 21, 18, 0, 5, 19, 20, 1, 9, 11, 14, 15, 10, 3, 7,
936     -15, -11, -4, -10, -8, -2, -16, -12, -18, -24, -1, -6, -17, -23, -21, -7, -20, -9, -13, -3, -22, -5, -19, -14, 13, 18, 4, 21, 2, 12, 8, 19, 6, 20, 22, 16, 5, 0, 23, 17, 11, 15, 1, 7, 9, 3, 10, 14,
937     -2, -5, -13, -11, -4, -7, -12, -14, -1, -9, -17, -22, -18, -21, -3, -15, -6, -19, -8, -23, -20, -10, -24, -16, 14, 20, 7, 17, 16, 9, 21, 2, 15, 5, 23, 19, 18, 22, 0, 8, 4, 3, 12, 11, 1, 6, 13, 10,
938     -11, -14, -7, -2, -12, -13, -4, -5, -9, -1, -23, -19, -20, -24, -6, -16, -3, -22, -10, -17, -18, -8, -21, -15, 15, 23, 9, 19, 22, 7, 18, 5, 14, 2, 20, 17, 21, 16, 8, 0, 13, 11, 6, 3, 10, 12, 4, 1,
939     -1, -24, -18, -6, -3, -21, -9, -20, -4, -11, -15, -10, -5, -14, -2, -22, -12, -16, -19, -8, -7, -17, -13, -23, 16, 6, 22, 12, 9, 21, 14, 3, 18, 10, 4, 13, 7, 15, 1, 11, 17, 0, 23, 5, 2, 19, 20, 8,
940     -23, -1, -9, -19, -17, -6, -22, -3, -7, -14, -11, -2, -8, -15, -13, -18, -5, -4, -21, -12, -16, -20, -10, -24, 17, 14, 20, 7, 10, 19, 1, 12, 23, 4, 9, 15, 3, 11, 6, 13, 0, 16, 8, 21, 22, 5, 2, 18,
941     -6, -20, -21, -1, -9, -18, -3, -24, -11, -4, -8, -16, -7, -13, -12, -23, -2, -10, -17, -15, -5, -19, -14, -22, 18, 4, 21, 13, 15, 22, 7, 10, 16, 3, 6, 12, 14, 9, 11, 1, 20, 5, 19, 0, 8, 23, 17, 2,
942     -17, -9, -1, -22, -23, -3, -19, -6, -13, -5, -2, -11, -10, -16, -7, -20, -14, -12, -24, -4, -15, -18, -8, -21, 19, 15, 23, 9, 1, 17, 10, 6, 20, 13, 7, 14, 11, 3, 12, 4, 8, 22, 0, 18, 16, 2, 5, 21,
943     -22, -6, -3, -17, -19, -1, -23, -9, -5, -13, -4, -12, -15, -8, -14, -21, -7, -11, -18, -2, -10, -24, -16, -20, 20, 7, 17, 14, 3, 23, 11, 13, 19, 6, 15, 9, 10, 1, 4, 12, 5, 18, 2, 22, 21, 0, 8, 16,
944     -3, -18, -24, -9, -1, -20, -6, -21, -2, -12, -10, -15, -13, -7, -4, -17, -11, -8, -23, -16, -14, -22, -5, -19, 21, 13, 18, 4, 14, 16, 9, 1, 22, 11, 12, 6, 15, 7, 3, 10, 23, 2, 17, 8, 0, 20, 19, 5,
945     -9, -21, -20, -3, -6, -24, -1, -18, -12, -2, -16, -8, -14, -5, -11, -19, -4, -15, -22, -10, -13, -23, -7, -17, 22, 12, 16, 6, 7, 18, 15, 11, 21, 1, 13, 4, 9, 14, 10, 3, 19, 8, 20, 2, 5, 17, 23, 0,
946     -19, -3, -6, -23, -22, -9, -17, -1, -14, -7, -12, -4, -16, -10, -5, -24, -13, -2, -20, -11, -8, -21, -15, -18, 23, 9, 19, 15, 11, 20, 3, 4, 17, 12, 14, 7, 1, 10, 13, 6, 2, 21, 5, 16, 18, 8, 0, 22,
947     };
948   static const PetscInt tripMult[12*12] = {
949     1, 0, 2, 3, 5, 4, -6, -4, -5, -2, -3, -1,
950     0, 2, 1, 4, 3, 5, -5, -6, -4, -3, -1, -2,
951     2, 1, 0, 5, 4, 3, -4, -5, -6, -1, -2, -3,
952     4, 3, 5, 0, 2, 1, -3, -1, -2, -5, -6, -4,
953     3, 5, 4, 1, 0, 2, -2, -3, -1, -6, -4, -5,
954     5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6,
955     -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5,
956     -4, -6, -5, -2, -1, -3, 1, 2, 0, 5, 3, 4,
957     -5, -4, -6, -1, -3, -2, 2, 0, 1, 4, 5, 3,
958     -3, -2, -1, -6, -5, -4, 3, 4, 5, 0, 1, 2,
959     -1, -3, -2, -5, -4, -6, 4, 5, 3, 2, 0, 1,
960     -2, -1, -3, -4, -6, -5, 5, 3, 4, 1, 2, 0,
961   };
962   static const PetscInt ttriMult[12*12] = {
963     0, 2, 1, 3, 5, 4, -6, -4, -5, -3, -1, -2,
964     1, 0, 2, 4, 3, 5, -5, -6, -4, -2, -3, -1,
965     2, 1, 0, 5, 4, 3, -4, -5, -6, -1, -2, -3,
966     3, 5, 4, 0, 2, 1, -3, -1, -2, -6, -4, -5,
967     4, 3, 5, 1, 0, 2, -2, -3, -1, -5, -6, -4,
968     5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6,
969     -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5,
970     -5, -4, -6, -2, -1, -3, 1, 2, 0, 4, 5, 3,
971     -4, -6, -5, -1, -3, -2, 2, 0, 1, 5, 3, 4,
972     -3, -2, -1, -6, -5, -4, 3, 4, 5, 0, 1, 2,
973     -2, -1, -3, -5, -4, -6, 4, 5, 3, 1, 2, 0,
974     -1, -3, -2, -4, -6, -5, 5, 3, 4, 2, 0, 1,
975   };
976   static const PetscInt tquadMult[16*16] = {
977     0, 3, 2, 1, 4, 7, 6, 5, -8, -5, -6, -7, -4, -1, -2, -3,
978     1, 0, 3, 2, 5, 4, 7, 6, -7, -8, -5, -6, -3, -4, -1, -2,
979     2, 1, 0, 3, 6, 5, 4, 7, -6, -7, -8, -5, -2, -3, -4, -1,
980     3, 2, 1, 0, 7, 6, 5, 4, -5, -6, -7, -8, -1, -2, -3, -4,
981     4, 7, 6, 5, 0, 3, 2, 1, -4, -1, -2, -3, -8, -5, -6, -7,
982     5, 4, 7, 6, 1, 0, 3, 2, -3, -4, -1, -2, -7, -8, -5, -6,
983     6, 5, 4, 7, 2, 1, 0, 3, -2, -3, -4, -1, -6, -7, -8, -5,
984     7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8,
985     -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7,
986     -7, -6, -5, -8, -3, -2, -1, -4, 1, 2, 3, 0, 5, 6, 7, 4,
987     -6, -5, -8, -7, -2, -1, -4, -3, 2, 3, 0, 1, 6, 7, 4, 5,
988     -5, -8, -7, -6, -1, -4, -3, -2, 3, 0, 1, 2, 7, 4, 5, 6,
989     -4, -3, -2, -1, -8, -7, -6, -5, 4, 5, 6, 7, 0, 1, 2, 3,
990     -3, -2, -1, -4, -7, -6, -5, -8, 5, 6, 7, 4, 1, 2, 3, 0,
991     -2, -1, -4, -3, -6, -5, -8, -7, 6, 7, 4, 5, 2, 3, 0, 1,
992     -1, -4, -3, -2, -5, -8, -7, -6, 7, 4, 5, 6, 3, 0, 1, 2,
993   };
994   static const PetscInt pyrMult[8*8] = {
995     0, 3, 2, 1, -4, -1, -2, -3,
996     1, 0, 3, 2, -3, -4, -1, -2,
997     2, 1, 0, 3, -2, -3, -4, -1,
998     3, 2, 1, 0, -1, -2, -3, -4,
999     -4, -3, -2, -1, 0, 1, 2, 3,
1000     -3, -2, -1, -4, 1, 2, 3, 0,
1001     -2, -1, -4, -3, 2, 3, 0, 1,
1002     -1, -4, -3, -2, 3, 0, 1, 2,
1003   };
1004   switch (ct) {
1005     case DM_POLYTOPE_POINT:              return 0;
1006     case DM_POLYTOPE_SEGMENT:
1007     case DM_POLYTOPE_POINT_PRISM_TENSOR: return segMult[(o1+1)*2+o2+1];
1008     case DM_POLYTOPE_TRIANGLE:           return triMult[(o1+3)*6+o2+3];
1009     case DM_POLYTOPE_QUADRILATERAL:      return quadMult[(o1+4)*8+o2+4];
1010     case DM_POLYTOPE_SEG_PRISM_TENSOR:   return tsegMult[(o1+2)*4+o2+2];
1011     case DM_POLYTOPE_TETRAHEDRON:        return tetMult[(o1+12)*24+o2+12];
1012     case DM_POLYTOPE_HEXAHEDRON:         return hexMult[(o1+24)*48+o2+24];
1013     case DM_POLYTOPE_TRI_PRISM:          return tripMult[(o1+6)*12+o2+6];
1014     case DM_POLYTOPE_TRI_PRISM_TENSOR:   return ttriMult[(o1+6)*12+o2+6];
1015     case DM_POLYTOPE_QUAD_PRISM_TENSOR:  return tquadMult[(o1+8)*16+o2+8];
1016     case DM_POLYTOPE_PYRAMID:            return pyrMult[(o1+4)*8+o2+4];
1017     default: return 0;
1018   }
1019 }
1020 
1021 /* This is orientation o1 acting on orientation o2^{-1} */
1022 PETSC_STATIC_INLINE PetscInt DMPolytopeTypeComposeOrientationInv(DMPolytopeType ct, PetscInt o1, PetscInt o2)
1023 {
1024   static const PetscInt triInv[6]    = {-3, -2, -1, 0, 2, 1};
1025   static const PetscInt quadInv[8]   = {-4, -3, -2, -1, 0, 3, 2, 1};
1026   static const PetscInt tetInv[24]   = {-9, -11, -4, -12, -5, -7, -6, -8, -10, -3, -2, -1, 0, 2, 1, 3, 8, 10, 6, 11, 4, 9, 5, 7};
1027   static const PetscInt hexInv[48]   = {-17, -18, -20, -19, -22, -21, -23, -24, -15, -16, -14, -13, -11, -12, -10, -9, -8, -5, -6, -7, -4, -3, -2, -1,
1028                                           0,   3,   2,   1,   6,   5,   4,   9,   8,   7,  10,  11,  12,  13,  14, 15, 17, 16, 19, 18, 21, 20, 23, 22};
1029   static const PetscInt tripInv[12]  = {-5, -6, -4, -3, -2, -1, 0, 2, 1, 3, 4, 5};
1030   static const PetscInt ttriInv[12]  = {-6, -5, -4, -3, -2, -1, 0, 2, 1, 3, 5, 4};
1031   static const PetscInt tquadInv[16] = {-8, -7, -6, -5, -4, -3, -2, -1, 0, 3, 2, 1, 4, 7, 6, 5};
1032   static const PetscInt pyrInv[8]    = {-4, -3, -2, -1, 0, 3, 2, 1};
1033   switch (ct) {
1034     case DM_POLYTOPE_POINT:              return 0;
1035     case DM_POLYTOPE_SEGMENT:
1036     case DM_POLYTOPE_POINT_PRISM_TENSOR: return DMPolytopeTypeComposeOrientation(ct, o1, o2);
1037     case DM_POLYTOPE_TRIANGLE:           return DMPolytopeTypeComposeOrientation(ct, o1, triInv[o2+3]);
1038     case DM_POLYTOPE_QUADRILATERAL:      return DMPolytopeTypeComposeOrientation(ct, o1, quadInv[o2+4]);
1039     case DM_POLYTOPE_SEG_PRISM_TENSOR:   return DMPolytopeTypeComposeOrientation(ct, o1, o2);
1040     case DM_POLYTOPE_TETRAHEDRON:        return DMPolytopeTypeComposeOrientation(ct, o1, tetInv[o2+12]);
1041     case DM_POLYTOPE_HEXAHEDRON:         return DMPolytopeTypeComposeOrientation(ct, o1, hexInv[o2+24]);
1042     case DM_POLYTOPE_TRI_PRISM:          return DMPolytopeTypeComposeOrientation(ct, o1, tripInv[o2+6]);
1043     case DM_POLYTOPE_TRI_PRISM_TENSOR:   return DMPolytopeTypeComposeOrientation(ct, o1, ttriInv[o2+6]);
1044     case DM_POLYTOPE_QUAD_PRISM_TENSOR:  return DMPolytopeTypeComposeOrientation(ct, o1, tquadInv[o2+8]);
1045     case DM_POLYTOPE_PYRAMID:            return DMPolytopeTypeComposeOrientation(ct, o1, pyrInv[o2+4]);
1046     default: return 0;
1047   }
1048 }
1049 
1050 PETSC_EXTERN PetscErrorCode DMPolytopeMatchOrientation(DMPolytopeType, const PetscInt[], const PetscInt[], PetscInt *, PetscBool *);
1051 PETSC_EXTERN PetscErrorCode DMPolytopeMatchVertexOrientation(DMPolytopeType, const PetscInt[], const PetscInt[], PetscInt *, PetscBool *);
1052 PETSC_EXTERN PetscErrorCode DMPolytopeGetOrientation(DMPolytopeType, const PetscInt[], const PetscInt[], PetscInt *);
1053 PETSC_EXTERN PetscErrorCode DMPolytopeGetVertexOrientation(DMPolytopeType, const PetscInt[], const PetscInt[], PetscInt *);
1054 PETSC_EXTERN PetscErrorCode DMPolytopeInCellTest(DMPolytopeType, const PetscReal[], PetscBool *);
1055 
1056 #endif
1057