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