xref: /petsc/src/dm/impls/plex/transform/interface/plextransform.c (revision 9fc2013d4d62c156699d7098aeeebb1b97746c9a)
1012bc364SMatthew G. Knepley #include <petsc/private/dmplextransformimpl.h> /*I "petscdmplextransform.h" I*/
2012bc364SMatthew G. Knepley 
3012bc364SMatthew G. Knepley #include <petsc/private/petscfeimpl.h> /* For PetscFEInterpolate_Static() */
4012bc364SMatthew G. Knepley 
5012bc364SMatthew G. Knepley PetscClassId DMPLEXTRANSFORM_CLASSID;
6012bc364SMatthew G. Knepley 
7012bc364SMatthew G. Knepley PetscFunctionList DMPlexTransformList              = NULL;
8012bc364SMatthew G. Knepley PetscBool         DMPlexTransformRegisterAllCalled = PETSC_FALSE;
9012bc364SMatthew G. Knepley 
10f7b6882eSMatthew G. Knepley PetscLogEvent DMPLEXTRANSFORM_SetUp, DMPLEXTRANSFORM_Apply, DMPLEXTRANSFORM_SetConeSizes, DMPLEXTRANSFORM_SetCones, DMPLEXTRANSFORM_CreateSF, DMPLEXTRANSFORM_CreateLabels, DMPLEXTRANSFORM_SetCoordinates;
11f7b6882eSMatthew G. Knepley 
1283b0cc01SDavid Salac /* Construct cell type order since we must loop over cell types in the same dimensional order they are stored in the plex if dm != NULL
1383b0cc01SDavid Salac         OR in standard plex ordering if dm == NULL */
DMPlexCreateCellTypeOrder_Internal(DM dm,PetscInt dim,PetscInt * ctOrder[],PetscInt * ctOrderInv[])1483b0cc01SDavid Salac static PetscErrorCode DMPlexCreateCellTypeOrder_Internal(DM dm, PetscInt dim, PetscInt *ctOrder[], PetscInt *ctOrderInv[])
15d71ae5a4SJacob Faibussowitsch {
16012bc364SMatthew G. Knepley   PetscInt *ctO, *ctOInv;
1783b0cc01SDavid Salac   PetscInt  d, c, off = 0;
1883b0cc01SDavid Salac   PetscInt  dimOrder[5] = {3, 2, 1, 0, -1};
19012bc364SMatthew G. Knepley 
20012bc364SMatthew G. Knepley   PetscFunctionBegin;
219566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(DM_NUM_POLYTOPES + 1, &ctO, DM_NUM_POLYTOPES + 1, &ctOInv));
2283b0cc01SDavid Salac   if (dm) { // Order the dimensions by their starting location
2383b0cc01SDavid Salac     PetscInt hStart[4] = {-1, -1, -1, -1};
2483b0cc01SDavid Salac     for (d = 0; d <= dim; ++d) PetscCall(DMPlexGetDepthStratum(dm, dim - d, &hStart[d], NULL));
2583b0cc01SDavid Salac     PetscCall(PetscSortIntWithArray(dim + 1, hStart, &dimOrder[3 - dim]));
2683b0cc01SDavid Salac   } else if (dim > 1) { // Standard plex ordering. dimOrder is in correct order if dim > 1
2783b0cc01SDavid Salac     off             = 4 - dim;
2883b0cc01SDavid Salac     dimOrder[off++] = 0;
29ac530a7eSPierre Jolivet     for (d = dim - 1; d > 0; --d) dimOrder[off++] = d;
3083b0cc01SDavid Salac   }
3183b0cc01SDavid Salac 
3283b0cc01SDavid Salac   off = 0;
3383b0cc01SDavid Salac   for (d = 0; d < 5; ++d) {
3483b0cc01SDavid Salac     for (c = 0; c < DM_NUM_POLYTOPES; ++c) {
3583b0cc01SDavid Salac       if (c == DM_POLYTOPE_UNKNOWN_CELL || c == DM_POLYTOPE_UNKNOWN_FACE) continue;
3683b0cc01SDavid Salac       if (DMPolytopeTypeGetDim((DMPolytopeType)c) == dimOrder[d]) ctO[off++] = c;
37012bc364SMatthew G. Knepley     }
38012bc364SMatthew G. Knepley   }
3983b0cc01SDavid Salac   for (c = 0; c < DM_NUM_POLYTOPES; ++c) {
4083b0cc01SDavid Salac     if (c == DM_POLYTOPE_UNKNOWN_CELL || c == DM_POLYTOPE_UNKNOWN_FACE) ctO[off++] = c;
41012bc364SMatthew G. Knepley   }
4283b0cc01SDavid Salac   ctO[off++] = DM_NUM_POLYTOPES;
4363a3b9bcSJacob Faibussowitsch   PetscCheck(off == DM_NUM_POLYTOPES + 1, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid offset %" PetscInt_FMT " for cell type order", off);
4483b0cc01SDavid Salac 
45ad540459SPierre Jolivet   for (c = 0; c <= DM_NUM_POLYTOPES; ++c) ctOInv[ctO[c]] = c;
4683b0cc01SDavid Salac 
47012bc364SMatthew G. Knepley   *ctOrder    = ctO;
48012bc364SMatthew G. Knepley   *ctOrderInv = ctOInv;
493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
50012bc364SMatthew G. Knepley }
51012bc364SMatthew G. Knepley 
52012bc364SMatthew G. Knepley /*@C
53012bc364SMatthew G. Knepley   DMPlexTransformRegister - Adds a new transform component implementation
54012bc364SMatthew G. Knepley 
55012bc364SMatthew G. Knepley   Not Collective
56012bc364SMatthew G. Knepley 
57012bc364SMatthew G. Knepley   Input Parameters:
58012bc364SMatthew G. Knepley + name        - The name of a new user-defined creation routine
5920f4b53cSBarry Smith - create_func - The creation routine
60012bc364SMatthew G. Knepley 
6160225df5SJacob Faibussowitsch   Example Usage:
62012bc364SMatthew G. Knepley .vb
63012bc364SMatthew G. Knepley   DMPlexTransformRegister("my_transform", MyTransformCreate);
64012bc364SMatthew G. Knepley .ve
65012bc364SMatthew G. Knepley 
66012bc364SMatthew G. Knepley   Then, your transform type can be chosen with the procedural interface via
67012bc364SMatthew G. Knepley .vb
68012bc364SMatthew G. Knepley   DMPlexTransformCreate(MPI_Comm, DMPlexTransform *);
69012bc364SMatthew G. Knepley   DMPlexTransformSetType(DMPlexTransform, "my_transform");
70012bc364SMatthew G. Knepley .ve
71012bc364SMatthew G. Knepley   or at runtime via the option
72012bc364SMatthew G. Knepley .vb
73012bc364SMatthew G. Knepley   -dm_plex_transform_type my_transform
74012bc364SMatthew G. Knepley .ve
75012bc364SMatthew G. Knepley 
76012bc364SMatthew G. Knepley   Level: advanced
77012bc364SMatthew G. Knepley 
78a1cb98faSBarry Smith   Note:
79a1cb98faSBarry Smith   `DMPlexTransformRegister()` may be called multiple times to add several user-defined transforms
80a1cb98faSBarry Smith 
811cc06b55SBarry Smith .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPlexTransformRegisterAll()`, `DMPlexTransformRegisterDestroy()`
82012bc364SMatthew G. Knepley @*/
DMPlexTransformRegister(const char name[],PetscErrorCode (* create_func)(DMPlexTransform))83d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformRegister(const char name[], PetscErrorCode (*create_func)(DMPlexTransform))
84d71ae5a4SJacob Faibussowitsch {
85012bc364SMatthew G. Knepley   PetscFunctionBegin;
869566063dSJacob Faibussowitsch   PetscCall(DMInitializePackage());
879566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&DMPlexTransformList, name, create_func));
883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
89012bc364SMatthew G. Knepley }
90012bc364SMatthew G. Knepley 
91012bc364SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMPlexTransformCreate_Filter(DMPlexTransform);
92012bc364SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMPlexTransformCreate_Regular(DMPlexTransform);
93012bc364SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMPlexTransformCreate_ToBox(DMPlexTransform);
94012bc364SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMPlexTransformCreate_Alfeld(DMPlexTransform);
95012bc364SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMPlexTransformCreate_SBR(DMPlexTransform);
96012bc364SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMPlexTransformCreate_BL(DMPlexTransform);
97a12d352dSMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMPlexTransformCreate_1D(DMPlexTransform);
98d410b0cfSMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMPlexTransformCreate_Extrude(DMPlexTransform);
99eaabba2dSMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMPlexTransformCreate_Cohesive(DMPlexTransform);
100012bc364SMatthew G. Knepley 
101012bc364SMatthew G. Knepley /*@C
102a1cb98faSBarry Smith   DMPlexTransformRegisterAll - Registers all of the transform components in the `DM` package.
103012bc364SMatthew G. Knepley 
104012bc364SMatthew G. Knepley   Not Collective
105012bc364SMatthew G. Knepley 
106012bc364SMatthew G. Knepley   Level: advanced
107012bc364SMatthew G. Knepley 
1081cc06b55SBarry Smith .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransformType`, `DMRegisterAll()`, `DMPlexTransformRegisterDestroy()`
109012bc364SMatthew G. Knepley @*/
DMPlexTransformRegisterAll(void)110d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformRegisterAll(void)
111d71ae5a4SJacob Faibussowitsch {
112012bc364SMatthew G. Knepley   PetscFunctionBegin;
1133ba16761SJacob Faibussowitsch   if (DMPlexTransformRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS);
114012bc364SMatthew G. Knepley   DMPlexTransformRegisterAllCalled = PETSC_TRUE;
115012bc364SMatthew G. Knepley 
1169566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformRegister(DMPLEXTRANSFORMFILTER, DMPlexTransformCreate_Filter));
1179566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformRegister(DMPLEXREFINEREGULAR, DMPlexTransformCreate_Regular));
1189566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformRegister(DMPLEXREFINETOBOX, DMPlexTransformCreate_ToBox));
1199566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformRegister(DMPLEXREFINEALFELD, DMPlexTransformCreate_Alfeld));
1209566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformRegister(DMPLEXREFINEBOUNDARYLAYER, DMPlexTransformCreate_BL));
1219566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformRegister(DMPLEXREFINESBR, DMPlexTransformCreate_SBR));
1229566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformRegister(DMPLEXREFINE1D, DMPlexTransformCreate_1D));
123ce78bad3SBarry Smith   PetscCall(DMPlexTransformRegister(DMPLEXEXTRUDETYPE, DMPlexTransformCreate_Extrude));
124eaabba2dSMatthew G. Knepley   PetscCall(DMPlexTransformRegister(DMPLEXCOHESIVEEXTRUDE, DMPlexTransformCreate_Cohesive));
1253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
126012bc364SMatthew G. Knepley }
127012bc364SMatthew G. Knepley 
128012bc364SMatthew G. Knepley /*@C
129a1cb98faSBarry Smith   DMPlexTransformRegisterDestroy - This function destroys the registered `DMPlexTransformType`. It is called from `PetscFinalize()`.
130012bc364SMatthew G. Knepley 
131c369401fSMatthew G. Knepley   Not collective
132c369401fSMatthew G. Knepley 
133012bc364SMatthew G. Knepley   Level: developer
134012bc364SMatthew G. Knepley 
1351cc06b55SBarry Smith .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMRegisterAll()`, `DMPlexTransformType`, `PetscInitialize()`
136012bc364SMatthew G. Knepley @*/
DMPlexTransformRegisterDestroy(void)137d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformRegisterDestroy(void)
138d71ae5a4SJacob Faibussowitsch {
139012bc364SMatthew G. Knepley   PetscFunctionBegin;
1409566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListDestroy(&DMPlexTransformList));
141012bc364SMatthew G. Knepley   DMPlexTransformRegisterAllCalled = PETSC_FALSE;
1423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
143012bc364SMatthew G. Knepley }
144012bc364SMatthew G. Knepley 
145012bc364SMatthew G. Knepley /*@
146a1cb98faSBarry Smith   DMPlexTransformCreate - Creates an empty transform object. The type can then be set with `DMPlexTransformSetType()`.
147012bc364SMatthew G. Knepley 
148012bc364SMatthew G. Knepley   Collective
149012bc364SMatthew G. Knepley 
150012bc364SMatthew G. Knepley   Input Parameter:
151012bc364SMatthew G. Knepley . comm - The communicator for the transform object
152012bc364SMatthew G. Knepley 
153012bc364SMatthew G. Knepley   Output Parameter:
15460225df5SJacob Faibussowitsch . tr - The transform object
155012bc364SMatthew G. Knepley 
156012bc364SMatthew G. Knepley   Level: beginner
157012bc364SMatthew G. Knepley 
1581cc06b55SBarry Smith .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPlexTransformType`, `DMPlexTransformSetType()`, `DMPLEXREFINEREGULAR`, `DMPLEXTRANSFORMFILTER`
159012bc364SMatthew G. Knepley @*/
DMPlexTransformCreate(MPI_Comm comm,DMPlexTransform * tr)160d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformCreate(MPI_Comm comm, DMPlexTransform *tr)
161d71ae5a4SJacob Faibussowitsch {
162012bc364SMatthew G. Knepley   DMPlexTransform t;
163012bc364SMatthew G. Knepley 
164012bc364SMatthew G. Knepley   PetscFunctionBegin;
1654f572ea9SToby Isaac   PetscAssertPointer(tr, 2);
166012bc364SMatthew G. Knepley   *tr = NULL;
1679566063dSJacob Faibussowitsch   PetscCall(DMInitializePackage());
168012bc364SMatthew G. Knepley 
1699566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(t, DMPLEXTRANSFORM_CLASSID, "DMPlexTransform", "Mesh Transform", "DMPlexTransform", comm, DMPlexTransformDestroy, DMPlexTransformView));
170012bc364SMatthew G. Knepley   t->setupcalled = PETSC_FALSE;
1719566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(DM_NUM_POLYTOPES, &t->coordFE, DM_NUM_POLYTOPES, &t->refGeom));
172012bc364SMatthew G. Knepley   *tr = t;
1733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
174012bc364SMatthew G. Knepley }
175012bc364SMatthew G. Knepley 
176cc4c1da9SBarry Smith /*@
1779f6c5813SMatthew G. Knepley   DMPlexTransformSetType - Sets the particular implementation for a transform.
178012bc364SMatthew G. Knepley 
17920f4b53cSBarry Smith   Collective
180012bc364SMatthew G. Knepley 
181012bc364SMatthew G. Knepley   Input Parameters:
182012bc364SMatthew G. Knepley + tr     - The transform
183012bc364SMatthew G. Knepley - method - The name of the transform type
184012bc364SMatthew G. Knepley 
185012bc364SMatthew G. Knepley   Options Database Key:
18620f4b53cSBarry Smith . -dm_plex_transform_type <type> - Sets the transform type; see `DMPlexTransformType`
187012bc364SMatthew G. Knepley 
188a1cb98faSBarry Smith   Level: intermediate
189a1cb98faSBarry Smith 
1901cc06b55SBarry Smith .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPlexTransformType`, `DMPlexTransformGetType()`, `DMPlexTransformCreate()`
191012bc364SMatthew G. Knepley @*/
DMPlexTransformSetType(DMPlexTransform tr,DMPlexTransformType method)192d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformSetType(DMPlexTransform tr, DMPlexTransformType method)
193d71ae5a4SJacob Faibussowitsch {
194012bc364SMatthew G. Knepley   PetscErrorCode (*r)(DMPlexTransform);
195012bc364SMatthew G. Knepley   PetscBool match;
196012bc364SMatthew G. Knepley 
197012bc364SMatthew G. Knepley   PetscFunctionBegin;
198012bc364SMatthew G. Knepley   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
1999566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)tr, method, &match));
2003ba16761SJacob Faibussowitsch   if (match) PetscFunctionReturn(PETSC_SUCCESS);
201012bc364SMatthew G. Knepley 
2029566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformRegisterAll());
2039566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(DMPlexTransformList, method, &r));
20428b400f6SJacob Faibussowitsch   PetscCheck(r, PetscObjectComm((PetscObject)tr), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DMPlexTransform type: %s", method);
205012bc364SMatthew G. Knepley 
206dbbe0bcdSBarry Smith   PetscTryTypeMethod(tr, destroy);
2079566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(tr->ops, sizeof(*tr->ops)));
2089566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)tr, method));
2099566063dSJacob Faibussowitsch   PetscCall((*r)(tr));
2103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
211012bc364SMatthew G. Knepley }
212012bc364SMatthew G. Knepley 
213cc4c1da9SBarry Smith /*@
214012bc364SMatthew G. Knepley   DMPlexTransformGetType - Gets the type name (as a string) from the transform.
215012bc364SMatthew G. Knepley 
216012bc364SMatthew G. Knepley   Not Collective
217012bc364SMatthew G. Knepley 
218012bc364SMatthew G. Knepley   Input Parameter:
219a1cb98faSBarry Smith . tr - The `DMPlexTransform`
220012bc364SMatthew G. Knepley 
221012bc364SMatthew G. Knepley   Output Parameter:
222a1cb98faSBarry Smith . type - The `DMPlexTransformType` name
223012bc364SMatthew G. Knepley 
224012bc364SMatthew G. Knepley   Level: intermediate
225012bc364SMatthew G. Knepley 
2261cc06b55SBarry Smith .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPlexTransformType`, `DMPlexTransformSetType()`, `DMPlexTransformCreate()`
227012bc364SMatthew G. Knepley @*/
DMPlexTransformGetType(DMPlexTransform tr,DMPlexTransformType * type)228d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformGetType(DMPlexTransform tr, DMPlexTransformType *type)
229d71ae5a4SJacob Faibussowitsch {
230012bc364SMatthew G. Knepley   PetscFunctionBegin;
231012bc364SMatthew G. Knepley   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
2324f572ea9SToby Isaac   PetscAssertPointer(type, 2);
2339566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformRegisterAll());
234012bc364SMatthew G. Knepley   *type = ((PetscObject)tr)->type_name;
2353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
236012bc364SMatthew G. Knepley }
237012bc364SMatthew G. Knepley 
DMPlexTransformView_Ascii(DMPlexTransform tr,PetscViewer v)238d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMPlexTransformView_Ascii(DMPlexTransform tr, PetscViewer v)
239d71ae5a4SJacob Faibussowitsch {
240012bc364SMatthew G. Knepley   PetscViewerFormat format;
241012bc364SMatthew G. Knepley 
242012bc364SMatthew G. Knepley   PetscFunctionBegin;
2439566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(v, &format));
244012bc364SMatthew G. Knepley   if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
245012bc364SMatthew G. Knepley     const PetscInt *trTypes = NULL;
246012bc364SMatthew G. Knepley     IS              trIS;
247012bc364SMatthew G. Knepley     PetscInt        cols = 8;
248012bc364SMatthew G. Knepley     PetscInt        Nrt  = 8, f, g;
249012bc364SMatthew G. Knepley 
2509f4ada15SMatthew G. Knepley     if (tr->trType) PetscCall(DMLabelView(tr->trType, v));
2519566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(v, "Source Starts\n"));
2529566063dSJacob Faibussowitsch     for (g = 0; g <= cols; ++g) PetscCall(PetscViewerASCIIPrintf(v, " %14s", DMPolytopeTypes[g]));
2539566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(v, "\n"));
25463a3b9bcSJacob Faibussowitsch     for (f = 0; f <= cols; ++f) PetscCall(PetscViewerASCIIPrintf(v, " %14" PetscInt_FMT, tr->ctStart[f]));
2559566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(v, "\n"));
2569566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(v, "Target Starts\n"));
2579566063dSJacob Faibussowitsch     for (g = 0; g <= cols; ++g) PetscCall(PetscViewerASCIIPrintf(v, " %14s", DMPolytopeTypes[g]));
2589566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(v, "\n"));
25963a3b9bcSJacob Faibussowitsch     for (f = 0; f <= cols; ++f) PetscCall(PetscViewerASCIIPrintf(v, " %14" PetscInt_FMT, tr->ctStartNew[f]));
2609566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(v, "\n"));
261012bc364SMatthew G. Knepley 
262012bc364SMatthew G. Knepley     if (tr->trType) {
2639566063dSJacob Faibussowitsch       PetscCall(DMLabelGetNumValues(tr->trType, &Nrt));
2649566063dSJacob Faibussowitsch       PetscCall(DMLabelGetValueIS(tr->trType, &trIS));
2659566063dSJacob Faibussowitsch       PetscCall(ISGetIndices(trIS, &trTypes));
266012bc364SMatthew G. Knepley     }
2679566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(v, "Offsets\n"));
2689566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(v, "     "));
26948a46eb9SPierre Jolivet     for (g = 0; g < cols; ++g) PetscCall(PetscViewerASCIIPrintf(v, " %14s", DMPolytopeTypes[g]));
2709566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(v, "\n"));
271012bc364SMatthew G. Knepley     for (f = 0; f < Nrt; ++f) {
27263a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(v, "%2" PetscInt_FMT "  |", trTypes ? trTypes[f] : f));
27348a46eb9SPierre Jolivet       for (g = 0; g < cols; ++g) PetscCall(PetscViewerASCIIPrintf(v, " %14" PetscInt_FMT, tr->offset[f * DM_NUM_POLYTOPES + g]));
2749566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(v, " |\n"));
275012bc364SMatthew G. Knepley     }
2769f4ada15SMatthew G. Knepley     if (tr->trType) {
2779f4ada15SMatthew G. Knepley       PetscCall(ISRestoreIndices(trIS, &trTypes));
2789566063dSJacob Faibussowitsch       PetscCall(ISDestroy(&trIS));
279012bc364SMatthew G. Knepley     }
280012bc364SMatthew G. Knepley   }
2813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
282012bc364SMatthew G. Knepley }
283012bc364SMatthew G. Knepley 
284ffeef943SBarry Smith /*@
285a1cb98faSBarry Smith   DMPlexTransformView - Views a `DMPlexTransform`
286012bc364SMatthew G. Knepley 
28720f4b53cSBarry Smith   Collective
288012bc364SMatthew G. Knepley 
289f1a722f8SMatthew G. Knepley   Input Parameters:
290a1cb98faSBarry Smith + tr - the `DMPlexTransform` object to view
291012bc364SMatthew G. Knepley - v  - the viewer
292012bc364SMatthew G. Knepley 
293012bc364SMatthew G. Knepley   Level: beginner
294012bc364SMatthew G. Knepley 
2951cc06b55SBarry Smith .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPlexTransformType`, `PetscViewer`, `DMPlexTransformDestroy()`, `DMPlexTransformCreate()`
296012bc364SMatthew G. Knepley @*/
DMPlexTransformView(DMPlexTransform tr,PetscViewer v)297d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformView(DMPlexTransform tr, PetscViewer v)
298d71ae5a4SJacob Faibussowitsch {
299012bc364SMatthew G. Knepley   PetscBool isascii;
300012bc364SMatthew G. Knepley 
301012bc364SMatthew G. Knepley   PetscFunctionBegin;
302012bc364SMatthew G. Knepley   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
3039566063dSJacob Faibussowitsch   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)tr), &v));
304012bc364SMatthew G. Knepley   PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2);
305012bc364SMatthew G. Knepley   PetscCheckSameComm(tr, 1, v, 2);
3069566063dSJacob Faibussowitsch   PetscCall(PetscViewerCheckWritable(v));
3079566063dSJacob Faibussowitsch   PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)tr, v));
3089566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &isascii));
3099566063dSJacob Faibussowitsch   if (isascii) PetscCall(DMPlexTransformView_Ascii(tr, v));
310dbbe0bcdSBarry Smith   PetscTryTypeMethod(tr, view, v);
3113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
312012bc364SMatthew G. Knepley }
313012bc364SMatthew G. Knepley 
314012bc364SMatthew G. Knepley /*@
31520f4b53cSBarry Smith   DMPlexTransformSetFromOptions - Sets parameters in a transform from values in the options database
316012bc364SMatthew G. Knepley 
31720f4b53cSBarry Smith   Collective
318012bc364SMatthew G. Knepley 
319012bc364SMatthew G. Knepley   Input Parameter:
320a1cb98faSBarry Smith . tr - the `DMPlexTransform` object to set options for
321012bc364SMatthew G. Knepley 
322533617b7SMatthew G. Knepley   Options Database Keys:
323533617b7SMatthew G. Knepley + -dm_plex_transform_type                      - Set the transform type, e.g. refine_regular
324533617b7SMatthew G. Knepley . -dm_plex_transform_label_match_strata        - Only label points of the same stratum as the producing point
32522d6dc08SStefano Zampini . -dm_plex_transform_label_replica_inc <inc>   - Increment for the label value to be multiplied by the replica number, so that the new label value is oldValue + r * inc
32622d6dc08SStefano Zampini . -dm_plex_transform_active <name>             - Name for active mesh label
32722d6dc08SStefano Zampini - -dm_plex_transform_active_values <v0,v1,...> - Values in the active label
328012bc364SMatthew G. Knepley 
329012bc364SMatthew G. Knepley   Level: intermediate
330012bc364SMatthew G. Knepley 
3311cc06b55SBarry Smith .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPlexTransformView()`, `DMPlexTransformCreate()`
332012bc364SMatthew G. Knepley @*/
DMPlexTransformSetFromOptions(DMPlexTransform tr)333d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformSetFromOptions(DMPlexTransform tr)
334d71ae5a4SJacob Faibussowitsch {
335e0b93839SMatthew G. Knepley   char        typeName[1024], active[PETSC_MAX_PATH_LEN];
336d410b0cfSMatthew G. Knepley   const char *defName = DMPLEXREFINEREGULAR;
337a4d5e7b4SMatthew G. Knepley   PetscBool   flg, match;
338012bc364SMatthew G. Knepley 
339012bc364SMatthew G. Knepley   PetscFunctionBegin;
340012bc364SMatthew G. Knepley   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
341d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)tr);
3429566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-dm_plex_transform_type", "DMPlexTransform", "DMPlexTransformSetType", DMPlexTransformList, defName, typeName, 1024, &flg));
3439566063dSJacob Faibussowitsch   if (flg) PetscCall(DMPlexTransformSetType(tr, typeName));
3449566063dSJacob Faibussowitsch   else if (!((PetscObject)tr)->type_name) PetscCall(DMPlexTransformSetType(tr, defName));
345a4d5e7b4SMatthew G. Knepley   PetscCall(PetscOptionsBool("-dm_plex_transform_label_match_strata", "Only label points of the same stratum as the producing point", "", tr->labelMatchStrata, &match, &flg));
346a4d5e7b4SMatthew G. Knepley   if (flg) PetscCall(DMPlexTransformSetMatchStrata(tr, match));
347533617b7SMatthew G. Knepley   PetscCall(PetscOptionsInt("-dm_plex_transform_label_replica_inc", "Increment for the label value to be multiplied by the replica number", "", tr->labelReplicaInc, &tr->labelReplicaInc, NULL));
348e0b93839SMatthew G. Knepley   PetscCall(PetscOptionsString("-dm_plex_transform_active", "Name for active mesh label", "DMPlexTransformSetActive", active, active, sizeof(active), &flg));
349e0b93839SMatthew G. Knepley   if (flg) {
350e0b93839SMatthew G. Knepley     DM       dm;
351e0b93839SMatthew G. Knepley     DMLabel  label;
35222d6dc08SStefano Zampini     PetscInt values[16];
35322d6dc08SStefano Zampini     PetscInt n = 16;
354e0b93839SMatthew G. Knepley 
355e0b93839SMatthew G. Knepley     PetscCall(DMPlexTransformGetDM(tr, &dm));
356e0b93839SMatthew G. Knepley     PetscCall(DMGetLabel(dm, active, &label));
35722d6dc08SStefano Zampini     PetscCall(PetscOptionsIntArray("-dm_plex_transform_active_values", "The label values to be active", "DMPlexTransformSetActive", values, &n, &flg));
35822d6dc08SStefano Zampini     if (flg && n) {
35922d6dc08SStefano Zampini       DMLabel newlabel;
36022d6dc08SStefano Zampini 
36122d6dc08SStefano Zampini       PetscCall(DMLabelCreate(PETSC_COMM_SELF, "Active", &newlabel));
36222d6dc08SStefano Zampini       for (PetscInt i = 0; i < n; ++i) {
36322d6dc08SStefano Zampini         IS is;
36422d6dc08SStefano Zampini 
36522d6dc08SStefano Zampini         PetscCall(DMLabelGetStratumIS(label, values[i], &is));
36622d6dc08SStefano Zampini         PetscCall(DMLabelInsertIS(newlabel, is, values[i]));
36722d6dc08SStefano Zampini         PetscCall(ISDestroy(&is));
36822d6dc08SStefano Zampini       }
36922d6dc08SStefano Zampini       PetscCall(DMPlexTransformSetActive(tr, newlabel));
37022d6dc08SStefano Zampini       PetscCall(DMLabelDestroy(&newlabel));
37122d6dc08SStefano Zampini     } else {
372e0b93839SMatthew G. Knepley       PetscCall(DMPlexTransformSetActive(tr, label));
373e0b93839SMatthew G. Knepley     }
37422d6dc08SStefano Zampini   }
375dbbe0bcdSBarry Smith   PetscTryTypeMethod(tr, setfromoptions, PetscOptionsObject);
376012bc364SMatthew G. Knepley   /* process any options handlers added with PetscObjectAddOptionsHandler() */
377dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)tr, PetscOptionsObject));
378d0609cedSBarry Smith   PetscOptionsEnd();
3793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
380012bc364SMatthew G. Knepley }
381012bc364SMatthew G. Knepley 
382cc4c1da9SBarry Smith /*@
383a1cb98faSBarry Smith   DMPlexTransformDestroy - Destroys a `DMPlexTransform`
384012bc364SMatthew G. Knepley 
38520f4b53cSBarry Smith   Collective
386012bc364SMatthew G. Knepley 
387012bc364SMatthew G. Knepley   Input Parameter:
388012bc364SMatthew G. Knepley . tr - the transform object to destroy
389012bc364SMatthew G. Knepley 
390012bc364SMatthew G. Knepley   Level: beginner
391012bc364SMatthew G. Knepley 
3921cc06b55SBarry Smith .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPlexTransformView()`, `DMPlexTransformCreate()`
393012bc364SMatthew G. Knepley @*/
DMPlexTransformDestroy(DMPlexTransform * tr)394d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformDestroy(DMPlexTransform *tr)
395d71ae5a4SJacob Faibussowitsch {
396012bc364SMatthew G. Knepley   PetscInt c;
397012bc364SMatthew G. Knepley 
398012bc364SMatthew G. Knepley   PetscFunctionBegin;
3993ba16761SJacob Faibussowitsch   if (!*tr) PetscFunctionReturn(PETSC_SUCCESS);
400f4f49eeaSPierre Jolivet   PetscValidHeaderSpecific(*tr, DMPLEXTRANSFORM_CLASSID, 1);
401f4f49eeaSPierre Jolivet   if (--((PetscObject)*tr)->refct > 0) {
4029371c9d4SSatish Balay     *tr = NULL;
4033ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
404012bc364SMatthew G. Knepley   }
4059371c9d4SSatish Balay 
406213acdd3SPierre Jolivet   PetscTryTypeMethod(*tr, destroy);
4079566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&(*tr)->dm));
4089566063dSJacob Faibussowitsch   PetscCall(DMLabelDestroy(&(*tr)->active));
4099566063dSJacob Faibussowitsch   PetscCall(DMLabelDestroy(&(*tr)->trType));
4109566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*tr)->ctOrderOld, (*tr)->ctOrderInvOld));
4119566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*tr)->ctOrderNew, (*tr)->ctOrderInvNew));
4129566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*tr)->ctStart, (*tr)->ctStartNew));
4139566063dSJacob Faibussowitsch   PetscCall(PetscFree((*tr)->offset));
4149f4ada15SMatthew G. Knepley   PetscCall(PetscFree2((*tr)->depthStart, (*tr)->depthEnd));
415012bc364SMatthew G. Knepley   for (c = 0; c < DM_NUM_POLYTOPES; ++c) {
4169566063dSJacob Faibussowitsch     PetscCall(PetscFEDestroy(&(*tr)->coordFE[c]));
4179566063dSJacob Faibussowitsch     PetscCall(PetscFEGeomDestroy(&(*tr)->refGeom[c]));
418012bc364SMatthew G. Knepley   }
419012bc364SMatthew G. Knepley   if ((*tr)->trVerts) {
420012bc364SMatthew G. Knepley     for (c = 0; c < DM_NUM_POLYTOPES; ++c) {
421012bc364SMatthew G. Knepley       DMPolytopeType *rct;
422012bc364SMatthew G. Knepley       PetscInt       *rsize, *rcone, *rornt, Nct, n, r;
423012bc364SMatthew G. Knepley 
424476787b7SMatthew G. Knepley       if (DMPolytopeTypeGetDim((DMPolytopeType)c) > 0 && c != DM_POLYTOPE_UNKNOWN_CELL && c != DM_POLYTOPE_UNKNOWN_FACE) {
425f4f49eeaSPierre Jolivet         PetscCall(DMPlexTransformCellTransform(*tr, (DMPolytopeType)c, 0, NULL, &Nct, &rct, &rsize, &rcone, &rornt));
426012bc364SMatthew G. Knepley         for (n = 0; n < Nct; ++n) {
427012bc364SMatthew G. Knepley           if (rct[n] == DM_POLYTOPE_POINT) continue;
4289566063dSJacob Faibussowitsch           for (r = 0; r < rsize[n]; ++r) PetscCall(PetscFree((*tr)->trSubVerts[c][rct[n]][r]));
4299566063dSJacob Faibussowitsch           PetscCall(PetscFree((*tr)->trSubVerts[c][rct[n]]));
430012bc364SMatthew G. Knepley         }
431012bc364SMatthew G. Knepley       }
4329566063dSJacob Faibussowitsch       PetscCall(PetscFree((*tr)->trSubVerts[c]));
4339566063dSJacob Faibussowitsch       PetscCall(PetscFree((*tr)->trVerts[c]));
434012bc364SMatthew G. Knepley     }
435012bc364SMatthew G. Knepley   }
4369566063dSJacob Faibussowitsch   PetscCall(PetscFree3((*tr)->trNv, (*tr)->trVerts, (*tr)->trSubVerts));
4379566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*tr)->coordFE, (*tr)->refGeom));
438012bc364SMatthew G. Knepley   /* We do not destroy (*dm)->data here so that we can reference count backend objects */
4399566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(tr));
4403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
441012bc364SMatthew G. Knepley }
442012bc364SMatthew G. Knepley 
DMPlexTransformCreateOffset_Internal(DMPlexTransform tr,PetscInt ctOrderOld[],PetscInt ctStart[],PetscInt ** offset)443d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMPlexTransformCreateOffset_Internal(DMPlexTransform tr, PetscInt ctOrderOld[], PetscInt ctStart[], PetscInt **offset)
444d71ae5a4SJacob Faibussowitsch {
445012bc364SMatthew G. Knepley   DMLabel  trType = tr->trType;
446012bc364SMatthew G. Knepley   PetscInt c, cN, *off;
447012bc364SMatthew G. Knepley 
448012bc364SMatthew G. Knepley   PetscFunctionBegin;
449012bc364SMatthew G. Knepley   if (trType) {
450012bc364SMatthew G. Knepley     DM              dm;
451012bc364SMatthew G. Knepley     IS              rtIS;
452012bc364SMatthew G. Knepley     const PetscInt *reftypes;
453012bc364SMatthew G. Knepley     PetscInt        Nrt, r;
454012bc364SMatthew G. Knepley 
4559566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformGetDM(tr, &dm));
4569566063dSJacob Faibussowitsch     PetscCall(DMLabelGetNumValues(trType, &Nrt));
4579566063dSJacob Faibussowitsch     PetscCall(DMLabelGetValueIS(trType, &rtIS));
4589566063dSJacob Faibussowitsch     PetscCall(ISGetIndices(rtIS, &reftypes));
4599566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(Nrt * DM_NUM_POLYTOPES, &off));
460012bc364SMatthew G. Knepley     for (r = 0; r < Nrt; ++r) {
461012bc364SMatthew G. Knepley       const PetscInt  rt = reftypes[r];
462012bc364SMatthew G. Knepley       IS              rtIS;
463012bc364SMatthew G. Knepley       const PetscInt *points;
464012bc364SMatthew G. Knepley       DMPolytopeType  ct;
4659f4ada15SMatthew G. Knepley       PetscInt        np, p;
466012bc364SMatthew G. Knepley 
4679566063dSJacob Faibussowitsch       PetscCall(DMLabelGetStratumIS(trType, rt, &rtIS));
4689f4ada15SMatthew G. Knepley       PetscCall(ISGetLocalSize(rtIS, &np));
4699566063dSJacob Faibussowitsch       PetscCall(ISGetIndices(rtIS, &points));
4709f4ada15SMatthew G. Knepley       if (!np) continue;
471012bc364SMatthew G. Knepley       p = points[0];
4729566063dSJacob Faibussowitsch       PetscCall(ISRestoreIndices(rtIS, &points));
4739566063dSJacob Faibussowitsch       PetscCall(ISDestroy(&rtIS));
4749566063dSJacob Faibussowitsch       PetscCall(DMPlexGetCellType(dm, p, &ct));
475012bc364SMatthew G. Knepley       for (cN = DM_POLYTOPE_POINT; cN < DM_NUM_POLYTOPES; ++cN) {
476012bc364SMatthew G. Knepley         const DMPolytopeType ctNew = (DMPolytopeType)cN;
477012bc364SMatthew G. Knepley         DMPolytopeType      *rct;
478012bc364SMatthew G. Knepley         PetscInt            *rsize, *cone, *ornt;
479012bc364SMatthew G. Knepley         PetscInt             Nct, n, s;
480012bc364SMatthew G. Knepley 
4819371c9d4SSatish Balay         if (DMPolytopeTypeGetDim(ct) < 0 || DMPolytopeTypeGetDim(ctNew) < 0) {
4829371c9d4SSatish Balay           off[r * DM_NUM_POLYTOPES + ctNew] = -1;
4839371c9d4SSatish Balay           break;
4849371c9d4SSatish Balay         }
485012bc364SMatthew G. Knepley         off[r * DM_NUM_POLYTOPES + ctNew] = 0;
486012bc364SMatthew G. Knepley         for (s = 0; s <= r; ++s) {
487012bc364SMatthew G. Knepley           const PetscInt st = reftypes[s];
488012bc364SMatthew G. Knepley           DMPolytopeType sct;
489012bc364SMatthew G. Knepley           PetscInt       q, qrt;
490012bc364SMatthew G. Knepley 
4919566063dSJacob Faibussowitsch           PetscCall(DMLabelGetStratumIS(trType, st, &rtIS));
4929f4ada15SMatthew G. Knepley           PetscCall(ISGetLocalSize(rtIS, &np));
4939566063dSJacob Faibussowitsch           PetscCall(ISGetIndices(rtIS, &points));
4949f4ada15SMatthew G. Knepley           if (!np) continue;
495012bc364SMatthew G. Knepley           q = points[0];
4969566063dSJacob Faibussowitsch           PetscCall(ISRestoreIndices(rtIS, &points));
4979566063dSJacob Faibussowitsch           PetscCall(ISDestroy(&rtIS));
4989566063dSJacob Faibussowitsch           PetscCall(DMPlexGetCellType(dm, q, &sct));
4999566063dSJacob Faibussowitsch           PetscCall(DMPlexTransformCellTransform(tr, sct, q, &qrt, &Nct, &rct, &rsize, &cone, &ornt));
50063a3b9bcSJacob Faibussowitsch           PetscCheck(st == qrt, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Refine type %" PetscInt_FMT " of point %" PetscInt_FMT " does not match predicted type %" PetscInt_FMT, qrt, q, st);
501012bc364SMatthew G. Knepley           if (st == rt) {
5029371c9d4SSatish Balay             for (n = 0; n < Nct; ++n)
5039371c9d4SSatish Balay               if (rct[n] == ctNew) break;
504012bc364SMatthew G. Knepley             if (n == Nct) off[r * DM_NUM_POLYTOPES + ctNew] = -1;
505012bc364SMatthew G. Knepley             break;
506012bc364SMatthew G. Knepley           }
507012bc364SMatthew G. Knepley           for (n = 0; n < Nct; ++n) {
508012bc364SMatthew G. Knepley             if (rct[n] == ctNew) {
509012bc364SMatthew G. Knepley               PetscInt sn;
510012bc364SMatthew G. Knepley 
5119566063dSJacob Faibussowitsch               PetscCall(DMLabelGetStratumSize(trType, st, &sn));
512012bc364SMatthew G. Knepley               off[r * DM_NUM_POLYTOPES + ctNew] += sn * rsize[n];
513012bc364SMatthew G. Knepley             }
514012bc364SMatthew G. Knepley           }
515012bc364SMatthew G. Knepley         }
516012bc364SMatthew G. Knepley       }
517012bc364SMatthew G. Knepley     }
5189566063dSJacob Faibussowitsch     PetscCall(ISRestoreIndices(rtIS, &reftypes));
5199566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&rtIS));
520012bc364SMatthew G. Knepley   } else {
5219566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(DM_NUM_POLYTOPES * DM_NUM_POLYTOPES, &off));
522012bc364SMatthew G. Knepley     for (c = DM_POLYTOPE_POINT; c < DM_NUM_POLYTOPES; ++c) {
523012bc364SMatthew G. Knepley       const DMPolytopeType ct = (DMPolytopeType)c;
524012bc364SMatthew G. Knepley       for (cN = DM_POLYTOPE_POINT; cN < DM_NUM_POLYTOPES; ++cN) {
525012bc364SMatthew G. Knepley         const DMPolytopeType ctNew = (DMPolytopeType)cN;
526012bc364SMatthew G. Knepley         DMPolytopeType      *rct;
527012bc364SMatthew G. Knepley         PetscInt            *rsize, *cone, *ornt;
528012bc364SMatthew G. Knepley         PetscInt             Nct, n, i;
529012bc364SMatthew G. Knepley 
530476787b7SMatthew G. Knepley         if (DMPolytopeTypeGetDim(ct) < 0 || ct == DM_POLYTOPE_UNKNOWN_CELL || ct == DM_POLYTOPE_UNKNOWN_FACE || DMPolytopeTypeGetDim(ctNew) < 0 || ctNew == DM_POLYTOPE_UNKNOWN_CELL || ctNew == DM_POLYTOPE_UNKNOWN_FACE) {
5319371c9d4SSatish Balay           off[ct * DM_NUM_POLYTOPES + ctNew] = -1;
5329371c9d4SSatish Balay           continue;
5339371c9d4SSatish Balay         }
534012bc364SMatthew G. Knepley         off[ct * DM_NUM_POLYTOPES + ctNew] = 0;
535012bc364SMatthew G. Knepley         for (i = DM_POLYTOPE_POINT; i < DM_NUM_POLYTOPES; ++i) {
536d410b0cfSMatthew G. Knepley           const DMPolytopeType ict  = (DMPolytopeType)ctOrderOld[i];
537d410b0cfSMatthew G. Knepley           const DMPolytopeType ictn = (DMPolytopeType)ctOrderOld[i + 1];
538012bc364SMatthew G. Knepley 
5399566063dSJacob Faibussowitsch           PetscCall(DMPlexTransformCellTransform(tr, ict, PETSC_DETERMINE, NULL, &Nct, &rct, &rsize, &cone, &ornt));
540012bc364SMatthew G. Knepley           if (ict == ct) {
5419371c9d4SSatish Balay             for (n = 0; n < Nct; ++n)
5429371c9d4SSatish Balay               if (rct[n] == ctNew) break;
543012bc364SMatthew G. Knepley             if (n == Nct) off[ct * DM_NUM_POLYTOPES + ctNew] = -1;
544012bc364SMatthew G. Knepley             break;
545012bc364SMatthew G. Knepley           }
5469371c9d4SSatish Balay           for (n = 0; n < Nct; ++n)
5479371c9d4SSatish Balay             if (rct[n] == ctNew) off[ct * DM_NUM_POLYTOPES + ctNew] += (ctStart[ictn] - ctStart[ict]) * rsize[n];
548012bc364SMatthew G. Knepley         }
549012bc364SMatthew G. Knepley       }
550012bc364SMatthew G. Knepley     }
551012bc364SMatthew G. Knepley   }
552012bc364SMatthew G. Knepley   *offset = off;
5533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
554012bc364SMatthew G. Knepley }
555012bc364SMatthew G. Knepley 
556c369401fSMatthew G. Knepley /*@
557c369401fSMatthew G. Knepley   DMPlexTransformSetUp - Create the tables that drive the transform
558c369401fSMatthew G. Knepley 
559c369401fSMatthew G. Knepley   Input Parameter:
560c369401fSMatthew G. Knepley . tr - The `DMPlexTransform` object
561c369401fSMatthew G. Knepley 
562c369401fSMatthew G. Knepley   Level: intermediate
563c369401fSMatthew G. Knepley 
564c369401fSMatthew G. Knepley .seealso: [](plex_transform_table), [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPlexTransformApply()`, `DMPlexTransformCreate()`
565c369401fSMatthew G. Knepley @*/
DMPlexTransformSetUp(DMPlexTransform tr)566d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformSetUp(DMPlexTransform tr)
567d71ae5a4SJacob Faibussowitsch {
568012bc364SMatthew G. Knepley   DMPolytopeType ctCell;
56983b0cc01SDavid Salac   DM             dm;
570d410b0cfSMatthew G. Knepley   PetscInt       pStart, pEnd, p, c, celldim = 0;
571012bc364SMatthew G. Knepley 
572012bc364SMatthew G. Knepley   PetscFunctionBegin;
573012bc364SMatthew G. Knepley   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
5743ba16761SJacob Faibussowitsch   if (tr->setupcalled) PetscFunctionReturn(PETSC_SUCCESS);
5759566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformGetDM(tr, &dm));
576f7b6882eSMatthew G. Knepley   PetscCall(PetscLogEventBegin(DMPLEXTRANSFORM_SetUp, tr, dm, 0, 0));
577f7b6882eSMatthew G. Knepley   PetscTryTypeMethod(tr, setup);
5787625649eSMatthew G. Knepley   PetscCall(DMSetSnapToGeomModel(dm, NULL));
5799566063dSJacob Faibussowitsch   PetscCall(DMPlexGetChart(dm, &pStart, &pEnd));
58083b0cc01SDavid Salac 
581012bc364SMatthew G. Knepley   if (pEnd > pStart) {
5827b79e06bSMatthew G. Knepley     // Ignore cells hanging off of embedded surfaces
5837b79e06bSMatthew G. Knepley     PetscInt c = pStart;
5847b79e06bSMatthew G. Knepley 
5857b79e06bSMatthew G. Knepley     ctCell = DM_POLYTOPE_FV_GHOST;
5867b79e06bSMatthew G. Knepley     while (DMPolytopeTypeGetDim(ctCell) < 0) PetscCall(DMPlexGetCellType(dm, c++, &ctCell));
587012bc364SMatthew G. Knepley   } else {
588012bc364SMatthew G. Knepley     PetscInt dim;
589012bc364SMatthew G. Knepley 
5909566063dSJacob Faibussowitsch     PetscCall(DMGetDimension(dm, &dim));
591012bc364SMatthew G. Knepley     switch (dim) {
592d71ae5a4SJacob Faibussowitsch     case 0:
593d71ae5a4SJacob Faibussowitsch       ctCell = DM_POLYTOPE_POINT;
594d71ae5a4SJacob Faibussowitsch       break;
595d71ae5a4SJacob Faibussowitsch     case 1:
596d71ae5a4SJacob Faibussowitsch       ctCell = DM_POLYTOPE_SEGMENT;
597d71ae5a4SJacob Faibussowitsch       break;
598d71ae5a4SJacob Faibussowitsch     case 2:
599d71ae5a4SJacob Faibussowitsch       ctCell = DM_POLYTOPE_TRIANGLE;
600d71ae5a4SJacob Faibussowitsch       break;
601d71ae5a4SJacob Faibussowitsch     case 3:
602d71ae5a4SJacob Faibussowitsch       ctCell = DM_POLYTOPE_TETRAHEDRON;
603d71ae5a4SJacob Faibussowitsch       break;
604d71ae5a4SJacob Faibussowitsch     default:
605d71ae5a4SJacob Faibussowitsch       ctCell = DM_POLYTOPE_UNKNOWN;
606012bc364SMatthew G. Knepley     }
607012bc364SMatthew G. Knepley   }
60883b0cc01SDavid Salac   PetscCall(DMPlexCreateCellTypeOrder_Internal(dm, DMPolytopeTypeGetDim(ctCell), &tr->ctOrderOld, &tr->ctOrderInvOld));
609d410b0cfSMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
610d410b0cfSMatthew G. Knepley     DMPolytopeType  ct;
611d410b0cfSMatthew G. Knepley     DMPolytopeType *rct;
612d410b0cfSMatthew G. Knepley     PetscInt       *rsize, *cone, *ornt;
613d410b0cfSMatthew G. Knepley     PetscInt        Nct, n;
614d410b0cfSMatthew G. Knepley 
6159566063dSJacob Faibussowitsch     PetscCall(DMPlexGetCellType(dm, p, &ct));
616476787b7SMatthew G. Knepley     PetscCheck(ct != DM_POLYTOPE_UNKNOWN && ct != DM_POLYTOPE_UNKNOWN_CELL && ct != DM_POLYTOPE_UNKNOWN_FACE, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No cell type for point %" PetscInt_FMT, p);
6179566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformCellTransform(tr, ct, p, NULL, &Nct, &rct, &rsize, &cone, &ornt));
618d410b0cfSMatthew G. Knepley     for (n = 0; n < Nct; ++n) celldim = PetscMax(celldim, DMPolytopeTypeGetDim(rct[n]));
619d410b0cfSMatthew G. Knepley   }
62083b0cc01SDavid Salac   PetscCall(DMPlexCreateCellTypeOrder_Internal(NULL, celldim, &tr->ctOrderNew, &tr->ctOrderInvNew));
621012bc364SMatthew G. Knepley   /* Construct sizes and offsets for each cell type */
622012bc364SMatthew G. Knepley   if (!tr->ctStart) {
623012bc364SMatthew G. Knepley     PetscInt *ctS, *ctSN, *ctC, *ctCN;
624012bc364SMatthew G. Knepley 
6259566063dSJacob Faibussowitsch     PetscCall(PetscCalloc2(DM_NUM_POLYTOPES + 1, &ctS, DM_NUM_POLYTOPES + 1, &ctSN));
6269566063dSJacob Faibussowitsch     PetscCall(PetscCalloc2(DM_NUM_POLYTOPES + 1, &ctC, DM_NUM_POLYTOPES + 1, &ctCN));
627012bc364SMatthew G. Knepley     for (p = pStart; p < pEnd; ++p) {
628012bc364SMatthew G. Knepley       DMPolytopeType  ct;
629012bc364SMatthew G. Knepley       DMPolytopeType *rct;
630012bc364SMatthew G. Knepley       PetscInt       *rsize, *cone, *ornt;
631012bc364SMatthew G. Knepley       PetscInt        Nct, n;
632012bc364SMatthew G. Knepley 
6339566063dSJacob Faibussowitsch       PetscCall(DMPlexGetCellType(dm, p, &ct));
634476787b7SMatthew G. Knepley       PetscCheck(ct != DM_POLYTOPE_UNKNOWN && ct != DM_POLYTOPE_UNKNOWN_CELL && ct != DM_POLYTOPE_UNKNOWN_FACE, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No cell type for point %" PetscInt_FMT, p);
635012bc364SMatthew G. Knepley       ++ctC[ct];
6369566063dSJacob Faibussowitsch       PetscCall(DMPlexTransformCellTransform(tr, ct, p, NULL, &Nct, &rct, &rsize, &cone, &ornt));
637012bc364SMatthew G. Knepley       for (n = 0; n < Nct; ++n) ctCN[rct[n]] += rsize[n];
638012bc364SMatthew G. Knepley     }
639012bc364SMatthew G. Knepley     for (c = 0; c < DM_NUM_POLYTOPES; ++c) {
640d410b0cfSMatthew G. Knepley       const PetscInt cto  = tr->ctOrderOld[c];
641d410b0cfSMatthew G. Knepley       const PetscInt cton = tr->ctOrderOld[c + 1];
642d410b0cfSMatthew G. Knepley       const PetscInt ctn  = tr->ctOrderNew[c];
643d410b0cfSMatthew G. Knepley       const PetscInt ctnn = tr->ctOrderNew[c + 1];
644012bc364SMatthew G. Knepley 
645d410b0cfSMatthew G. Knepley       ctS[cton]  = ctS[cto] + ctC[cto];
646d410b0cfSMatthew G. Knepley       ctSN[ctnn] = ctSN[ctn] + ctCN[ctn];
647012bc364SMatthew G. Knepley     }
6489566063dSJacob Faibussowitsch     PetscCall(PetscFree2(ctC, ctCN));
649012bc364SMatthew G. Knepley     tr->ctStart    = ctS;
650012bc364SMatthew G. Knepley     tr->ctStartNew = ctSN;
651012bc364SMatthew G. Knepley   }
6529566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformCreateOffset_Internal(tr, tr->ctOrderOld, tr->ctStart, &tr->offset));
6539f4ada15SMatthew G. Knepley   // Compute depth information
6549f4ada15SMatthew G. Knepley   tr->depth = -1;
6559f4ada15SMatthew G. Knepley   for (c = 0; c < DM_NUM_POLYTOPES; ++c)
6569f4ada15SMatthew G. Knepley     if (tr->ctStartNew[tr->ctOrderNew[c + 1]] > tr->ctStartNew[tr->ctOrderNew[c]]) tr->depth = PetscMax(tr->depth, DMPolytopeTypeGetDim((DMPolytopeType)tr->ctOrderNew[c]));
6579f4ada15SMatthew G. Knepley   PetscCall(PetscMalloc2(tr->depth + 1, &tr->depthStart, tr->depth + 1, &tr->depthEnd));
6589f4ada15SMatthew G. Knepley   for (PetscInt d = 0; d <= tr->depth; ++d) {
6591690c2aeSBarry Smith     tr->depthStart[d] = PETSC_INT_MAX;
6609f4ada15SMatthew G. Knepley     tr->depthEnd[d]   = -1;
6619f4ada15SMatthew G. Knepley   }
6629f4ada15SMatthew G. Knepley   for (c = 0; c < DM_NUM_POLYTOPES; ++c) {
6639f4ada15SMatthew G. Knepley     const PetscInt dep = DMPolytopeTypeGetDim((DMPolytopeType)tr->ctOrderNew[c]);
6649f4ada15SMatthew G. Knepley 
6659f4ada15SMatthew G. Knepley     if (tr->ctStartNew[tr->ctOrderNew[c + 1]] <= tr->ctStartNew[tr->ctOrderNew[c]]) continue;
6669f4ada15SMatthew G. Knepley     tr->depthStart[dep] = PetscMin(tr->depthStart[dep], tr->ctStartNew[tr->ctOrderNew[c]]);
6679f4ada15SMatthew G. Knepley     tr->depthEnd[dep]   = PetscMax(tr->depthEnd[dep], tr->ctStartNew[tr->ctOrderNew[c + 1]]);
6689f4ada15SMatthew G. Knepley   }
669012bc364SMatthew G. Knepley   tr->setupcalled = PETSC_TRUE;
670f7b6882eSMatthew G. Knepley   PetscCall(PetscLogEventEnd(DMPLEXTRANSFORM_SetUp, tr, dm, 0, 0));
6713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
672012bc364SMatthew G. Knepley }
673012bc364SMatthew G. Knepley 
674c369401fSMatthew G. Knepley /*@
675c369401fSMatthew G. Knepley   DMPlexTransformGetDM - Get the base `DM` for the transform
676c369401fSMatthew G. Knepley 
677c369401fSMatthew G. Knepley   Input Parameter:
678c369401fSMatthew G. Knepley . tr - The `DMPlexTransform` object
679c369401fSMatthew G. Knepley 
680c369401fSMatthew G. Knepley   Output Parameter:
681c369401fSMatthew G. Knepley . dm - The original `DM` which will be transformed
682c369401fSMatthew G. Knepley 
683c369401fSMatthew G. Knepley   Level: intermediate
684c369401fSMatthew G. Knepley 
685c369401fSMatthew G. Knepley .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPlexTransformSetDM()`, `DMPlexTransformApply()`, `DMPlexTransformCreate()`
686c369401fSMatthew G. Knepley @*/
DMPlexTransformGetDM(DMPlexTransform tr,DM * dm)687d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformGetDM(DMPlexTransform tr, DM *dm)
688d71ae5a4SJacob Faibussowitsch {
689012bc364SMatthew G. Knepley   PetscFunctionBegin;
690012bc364SMatthew G. Knepley   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
6914f572ea9SToby Isaac   PetscAssertPointer(dm, 2);
692012bc364SMatthew G. Knepley   *dm = tr->dm;
6933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
694012bc364SMatthew G. Knepley }
695012bc364SMatthew G. Knepley 
696c369401fSMatthew G. Knepley /*@
697c369401fSMatthew G. Knepley   DMPlexTransformSetDM - Set the base `DM` for the transform
698c369401fSMatthew G. Knepley 
699c369401fSMatthew G. Knepley   Input Parameters:
700c369401fSMatthew G. Knepley + tr - The `DMPlexTransform` object
701c369401fSMatthew G. Knepley - dm - The original `DM` which will be transformed
702c369401fSMatthew G. Knepley 
703c369401fSMatthew G. Knepley   Level: intermediate
704c369401fSMatthew G. Knepley 
705c369401fSMatthew G. Knepley   Note:
706c369401fSMatthew G. Knepley   The user does not typically call this, as it is called by `DMPlexTransformApply()`.
707c369401fSMatthew G. Knepley 
708c369401fSMatthew G. Knepley .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPlexTransformGetDM()`, `DMPlexTransformApply()`, `DMPlexTransformCreate()`
709c369401fSMatthew G. Knepley @*/
DMPlexTransformSetDM(DMPlexTransform tr,DM dm)710d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformSetDM(DMPlexTransform tr, DM dm)
711d71ae5a4SJacob Faibussowitsch {
712012bc364SMatthew G. Knepley   PetscFunctionBegin;
713012bc364SMatthew G. Knepley   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
714012bc364SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
7159566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)dm));
7169566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&tr->dm));
717012bc364SMatthew G. Knepley   tr->dm = dm;
7183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
719012bc364SMatthew G. Knepley }
720012bc364SMatthew G. Knepley 
721c369401fSMatthew G. Knepley /*@
722c369401fSMatthew G. Knepley   DMPlexTransformGetActive - Get the `DMLabel` marking the active points for the transform
723c369401fSMatthew G. Knepley 
724c369401fSMatthew G. Knepley   Input Parameter:
725c369401fSMatthew G. Knepley . tr - The `DMPlexTransform` object
726c369401fSMatthew G. Knepley 
727c369401fSMatthew G. Knepley   Output Parameter:
728c369401fSMatthew G. Knepley . active - The `DMLabel` indicating which points will be transformed
729c369401fSMatthew G. Knepley 
730c369401fSMatthew G. Knepley   Level: intermediate
731c369401fSMatthew G. Knepley 
732c369401fSMatthew G. Knepley .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPlexTransformSetActive()`, `DMPlexTransformApply()`, `DMPlexTransformCreate()`
733c369401fSMatthew G. Knepley @*/
DMPlexTransformGetActive(DMPlexTransform tr,DMLabel * active)734d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformGetActive(DMPlexTransform tr, DMLabel *active)
735d71ae5a4SJacob Faibussowitsch {
736012bc364SMatthew G. Knepley   PetscFunctionBegin;
737012bc364SMatthew G. Knepley   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
7384f572ea9SToby Isaac   PetscAssertPointer(active, 2);
739012bc364SMatthew G. Knepley   *active = tr->active;
7403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
741012bc364SMatthew G. Knepley }
742012bc364SMatthew G. Knepley 
743c369401fSMatthew G. Knepley /*@
744c369401fSMatthew G. Knepley   DMPlexTransformSetActive - Set the `DMLabel` marking the active points for the transform
745c369401fSMatthew G. Knepley 
746c369401fSMatthew G. Knepley   Input Parameters:
747c369401fSMatthew G. Knepley + tr     - The `DMPlexTransform` object
7481cbae99dSMatthew G. Knepley - active - The `DMLabel` indicating which points will be transformed
749c369401fSMatthew G. Knepley 
750c369401fSMatthew G. Knepley   Level: intermediate
751c369401fSMatthew G. Knepley 
752c369401fSMatthew G. Knepley   Note:
7531cbae99dSMatthew G. Knepley   This only applies to transforms listed in [](plex_transform_table) that operate on a subset of the mesh.
754c369401fSMatthew G. Knepley 
7551cbae99dSMatthew G. Knepley .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPlexTransformGetActive()`, `DMPlexTransformApply()`, `DMPlexTransformCreate()`
756c369401fSMatthew G. Knepley @*/
DMPlexTransformSetActive(DMPlexTransform tr,DMLabel active)757d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformSetActive(DMPlexTransform tr, DMLabel active)
758d71ae5a4SJacob Faibussowitsch {
759012bc364SMatthew G. Knepley   PetscFunctionBegin;
760012bc364SMatthew G. Knepley   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
7619f4ada15SMatthew G. Knepley   if (active) PetscValidHeaderSpecific(active, DMLABEL_CLASSID, 2);
7629566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)active));
7639566063dSJacob Faibussowitsch   PetscCall(DMLabelDestroy(&tr->active));
764012bc364SMatthew G. Knepley   tr->active = active;
7653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
766012bc364SMatthew G. Knepley }
767012bc364SMatthew G. Knepley 
7681cbae99dSMatthew G. Knepley /*@
7691cbae99dSMatthew G. Knepley   DMPlexTransformGetTransformTypes - Get the `DMLabel` marking the transform type of each point for the transform
7701cbae99dSMatthew G. Knepley 
7711cbae99dSMatthew G. Knepley   Input Parameter:
7721cbae99dSMatthew G. Knepley . tr - The `DMPlexTransform` object
7731cbae99dSMatthew G. Knepley 
7741cbae99dSMatthew G. Knepley   Output Parameter:
7751cbae99dSMatthew G. Knepley . trType - The `DMLabel` indicating the transform type for each point
7761cbae99dSMatthew G. Knepley 
7771cbae99dSMatthew G. Knepley   Level: intermediate
7781cbae99dSMatthew G. Knepley 
7791cbae99dSMatthew G. Knepley .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPlexSetTransformType()`, `DMPlexTransformGetActive()`, `DMPlexTransformApply()`, `DMPlexTransformCreate()`
7801cbae99dSMatthew G. Knepley @*/
DMPlexTransformGetTransformTypes(DMPlexTransform tr,DMLabel * trType)7811cbae99dSMatthew G. Knepley PetscErrorCode DMPlexTransformGetTransformTypes(DMPlexTransform tr, DMLabel *trType)
7821cbae99dSMatthew G. Knepley {
7831cbae99dSMatthew G. Knepley   PetscFunctionBegin;
7841cbae99dSMatthew G. Knepley   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
7851cbae99dSMatthew G. Knepley   PetscAssertPointer(trType, 2);
7861cbae99dSMatthew G. Knepley   *trType = tr->trType;
7871cbae99dSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
7881cbae99dSMatthew G. Knepley }
7891cbae99dSMatthew G. Knepley 
7901cbae99dSMatthew G. Knepley /*@
7911cbae99dSMatthew G. Knepley   DMPlexTransformSetTransformTypes - Set the `DMLabel` marking the transform type of each point for the transform
7921cbae99dSMatthew G. Knepley 
7931cbae99dSMatthew G. Knepley   Input Parameters:
7941cbae99dSMatthew G. Knepley + tr     - The `DMPlexTransform` object
7951cbae99dSMatthew G. Knepley - trType - The original `DM` which will be transformed
7961cbae99dSMatthew G. Knepley 
7971cbae99dSMatthew G. Knepley   Level: intermediate
7981cbae99dSMatthew G. Knepley 
7991cbae99dSMatthew G. Knepley .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPlexTransformGetTransformTypes()`, `DMPlexTransformGetActive())`, `DMPlexTransformApply()`, `DMPlexTransformCreate()`
8001cbae99dSMatthew G. Knepley @*/
DMPlexTransformSetTransformTypes(DMPlexTransform tr,DMLabel trType)8011cbae99dSMatthew G. Knepley PetscErrorCode DMPlexTransformSetTransformTypes(DMPlexTransform tr, DMLabel trType)
8021cbae99dSMatthew G. Knepley {
8031cbae99dSMatthew G. Knepley   PetscFunctionBegin;
8041cbae99dSMatthew G. Knepley   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
8051cbae99dSMatthew G. Knepley   if (trType) PetscValidHeaderSpecific(trType, DMLABEL_CLASSID, 2);
8061cbae99dSMatthew G. Knepley   PetscCall(PetscObjectReference((PetscObject)trType));
8071cbae99dSMatthew G. Knepley   PetscCall(DMLabelDestroy(&tr->trType));
8081cbae99dSMatthew G. Knepley   tr->trType = trType;
8091cbae99dSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
8101cbae99dSMatthew G. Knepley }
8111cbae99dSMatthew G. Knepley 
DMPlexTransformGetCoordinateFE(DMPlexTransform tr,DMPolytopeType ct,PetscFE * fe)812d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMPlexTransformGetCoordinateFE(DMPlexTransform tr, DMPolytopeType ct, PetscFE *fe)
813d71ae5a4SJacob Faibussowitsch {
814012bc364SMatthew G. Knepley   PetscFunctionBegin;
815012bc364SMatthew G. Knepley   if (!tr->coordFE[ct]) {
816012bc364SMatthew G. Knepley     PetscInt dim, cdim;
817012bc364SMatthew G. Knepley 
818cfd33b42SLisandro Dalcin     dim = DMPolytopeTypeGetDim(ct);
8199566063dSJacob Faibussowitsch     PetscCall(DMGetCoordinateDim(tr->dm, &cdim));
8209566063dSJacob Faibussowitsch     PetscCall(PetscFECreateLagrangeByCell(PETSC_COMM_SELF, dim, cdim, ct, 1, PETSC_DETERMINE, &tr->coordFE[ct]));
821012bc364SMatthew G. Knepley     {
822012bc364SMatthew G. Knepley       PetscDualSpace  dsp;
823012bc364SMatthew G. Knepley       PetscQuadrature quad;
824012bc364SMatthew G. Knepley       DM              K;
825012bc364SMatthew G. Knepley       PetscFEGeom    *cg;
826012bc364SMatthew G. Knepley       PetscScalar    *Xq;
827012bc364SMatthew G. Knepley       PetscReal      *xq, *wq;
828012bc364SMatthew G. Knepley       PetscInt        Nq, q;
829012bc364SMatthew G. Knepley 
8309566063dSJacob Faibussowitsch       PetscCall(DMPlexTransformGetCellVertices(tr, ct, &Nq, &Xq));
8319566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(Nq * cdim, &xq));
832012bc364SMatthew G. Knepley       for (q = 0; q < Nq * cdim; ++q) xq[q] = PetscRealPart(Xq[q]);
8339566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(Nq, &wq));
834012bc364SMatthew G. Knepley       for (q = 0; q < Nq; ++q) wq[q] = 1.0;
8359566063dSJacob Faibussowitsch       PetscCall(PetscQuadratureCreate(PETSC_COMM_SELF, &quad));
8369566063dSJacob Faibussowitsch       PetscCall(PetscQuadratureSetData(quad, dim, 1, Nq, xq, wq));
8379566063dSJacob Faibussowitsch       PetscCall(PetscFESetQuadrature(tr->coordFE[ct], quad));
838012bc364SMatthew G. Knepley 
8399566063dSJacob Faibussowitsch       PetscCall(PetscFEGetDualSpace(tr->coordFE[ct], &dsp));
8409566063dSJacob Faibussowitsch       PetscCall(PetscDualSpaceGetDM(dsp, &K));
841ac9d17c7SMatthew G. Knepley       PetscCall(PetscFEGeomCreate(quad, 1, cdim, PETSC_FEGEOM_BASIC, &tr->refGeom[ct]));
842012bc364SMatthew G. Knepley       cg = tr->refGeom[ct];
8439566063dSJacob Faibussowitsch       PetscCall(DMPlexComputeCellGeometryFEM(K, 0, NULL, cg->v, cg->J, cg->invJ, cg->detJ));
8449566063dSJacob Faibussowitsch       PetscCall(PetscQuadratureDestroy(&quad));
845012bc364SMatthew G. Knepley     }
846012bc364SMatthew G. Knepley   }
847012bc364SMatthew G. Knepley   *fe = tr->coordFE[ct];
8483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
849012bc364SMatthew G. Knepley }
850012bc364SMatthew G. Knepley 
DMPlexTransformSetDimensions_Internal(DMPlexTransform tr,DM dm,DM tdm)8519f4ada15SMatthew G. Knepley PetscErrorCode DMPlexTransformSetDimensions_Internal(DMPlexTransform tr, DM dm, DM tdm)
8529f4ada15SMatthew G. Knepley {
8539f4ada15SMatthew G. Knepley   PetscInt dim, cdim;
8549f4ada15SMatthew G. Knepley 
8559f4ada15SMatthew G. Knepley   PetscFunctionBegin;
8569f4ada15SMatthew G. Knepley   PetscCall(DMGetDimension(dm, &dim));
8579f4ada15SMatthew G. Knepley   PetscCall(DMSetDimension(tdm, dim));
8589f4ada15SMatthew G. Knepley   PetscCall(DMGetCoordinateDim(dm, &cdim));
8599f4ada15SMatthew G. Knepley   PetscCall(DMSetCoordinateDim(tdm, cdim));
8603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8619f4ada15SMatthew G. Knepley }
8629f4ada15SMatthew G. Knepley 
863012bc364SMatthew G. Knepley /*@
864a1cb98faSBarry Smith   DMPlexTransformSetDimensions - Set the dimensions for the transformed `DM`
865d410b0cfSMatthew G. Knepley 
866d410b0cfSMatthew G. Knepley   Input Parameters:
867a1cb98faSBarry Smith + tr - The `DMPlexTransform` object
868a1cb98faSBarry Smith - dm - The original `DM`
869d410b0cfSMatthew G. Knepley 
870d410b0cfSMatthew G. Knepley   Output Parameter:
871*81ee147aSBarry Smith . trdm - The transformed `DM`
872d410b0cfSMatthew G. Knepley 
873d410b0cfSMatthew G. Knepley   Level: advanced
874d410b0cfSMatthew G. Knepley 
8751cc06b55SBarry Smith .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPlexTransformApply()`, `DMPlexTransformCreate()`
876d410b0cfSMatthew G. Knepley @*/
DMPlexTransformSetDimensions(DMPlexTransform tr,DM dm,DM trdm)877*81ee147aSBarry Smith PetscErrorCode DMPlexTransformSetDimensions(DMPlexTransform tr, DM dm, DM trdm)
878d71ae5a4SJacob Faibussowitsch {
879d410b0cfSMatthew G. Knepley   PetscFunctionBegin;
880*81ee147aSBarry Smith   PetscUseTypeMethod(tr, setdimensions, dm, trdm);
8813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
882d410b0cfSMatthew G. Knepley }
8839f4ada15SMatthew G. Knepley 
DMPlexTransformGetChart(DMPlexTransform tr,PetscInt * pStart,PetscInt * pEnd)8849f4ada15SMatthew G. Knepley PetscErrorCode DMPlexTransformGetChart(DMPlexTransform tr, PetscInt *pStart, PetscInt *pEnd)
8859f4ada15SMatthew G. Knepley {
8869f4ada15SMatthew G. Knepley   PetscFunctionBegin;
8879f4ada15SMatthew G. Knepley   if (pStart) *pStart = 0;
8889f4ada15SMatthew G. Knepley   if (pEnd) *pEnd = tr->ctStartNew[tr->ctOrderNew[DM_NUM_POLYTOPES]];
8893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8909f4ada15SMatthew G. Knepley }
8919f4ada15SMatthew G. Knepley 
DMPlexTransformGetCellType(DMPlexTransform tr,PetscInt cell,DMPolytopeType * celltype)8929f4ada15SMatthew G. Knepley PetscErrorCode DMPlexTransformGetCellType(DMPlexTransform tr, PetscInt cell, DMPolytopeType *celltype)
8939f4ada15SMatthew G. Knepley {
8949f4ada15SMatthew G. Knepley   PetscInt ctNew;
8959f4ada15SMatthew G. Knepley 
8969f4ada15SMatthew G. Knepley   PetscFunctionBegin;
8979f4ada15SMatthew G. Knepley   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
8984f572ea9SToby Isaac   PetscAssertPointer(celltype, 3);
8999f4ada15SMatthew G. Knepley   /* TODO Can do bisection since everything is sorted */
9009f4ada15SMatthew G. Knepley   for (ctNew = DM_POLYTOPE_POINT; ctNew < DM_NUM_POLYTOPES; ++ctNew) {
9019f4ada15SMatthew G. Knepley     PetscInt ctSN = tr->ctStartNew[ctNew], ctEN = tr->ctStartNew[tr->ctOrderNew[tr->ctOrderInvNew[ctNew] + 1]];
9029f4ada15SMatthew G. Knepley 
9039f4ada15SMatthew G. Knepley     if (cell >= ctSN && cell < ctEN) break;
9049f4ada15SMatthew G. Knepley   }
9059f4ada15SMatthew G. Knepley   PetscCheck(ctNew < DM_NUM_POLYTOPES, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Point %" PetscInt_FMT " cannot be located in the transformed mesh", cell);
9069f4ada15SMatthew G. Knepley   *celltype = (DMPolytopeType)ctNew;
9073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9089f4ada15SMatthew G. Knepley }
9099f4ada15SMatthew G. Knepley 
DMPlexTransformGetCellTypeStratum(DMPlexTransform tr,DMPolytopeType celltype,PetscInt * start,PetscInt * end)9102827ebadSStefano Zampini PetscErrorCode DMPlexTransformGetCellTypeStratum(DMPlexTransform tr, DMPolytopeType celltype, PetscInt *start, PetscInt *end)
9112827ebadSStefano Zampini {
9122827ebadSStefano Zampini   PetscFunctionBegin;
9132827ebadSStefano Zampini   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
9142827ebadSStefano Zampini   if (start) *start = tr->ctStartNew[celltype];
9152827ebadSStefano Zampini   if (end) *end = tr->ctStartNew[tr->ctOrderNew[tr->ctOrderInvNew[celltype] + 1]];
9162827ebadSStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
9172827ebadSStefano Zampini }
9182827ebadSStefano Zampini 
DMPlexTransformGetDepth(DMPlexTransform tr,PetscInt * depth)9199f4ada15SMatthew G. Knepley PetscErrorCode DMPlexTransformGetDepth(DMPlexTransform tr, PetscInt *depth)
9209f4ada15SMatthew G. Knepley {
9219f4ada15SMatthew G. Knepley   PetscFunctionBegin;
9229f4ada15SMatthew G. Knepley   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
9239f4ada15SMatthew G. Knepley   *depth = tr->depth;
9243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9259f4ada15SMatthew G. Knepley }
9269f4ada15SMatthew G. Knepley 
DMPlexTransformGetDepthStratum(DMPlexTransform tr,PetscInt depth,PetscInt * start,PetscInt * end)9279f4ada15SMatthew G. Knepley PetscErrorCode DMPlexTransformGetDepthStratum(DMPlexTransform tr, PetscInt depth, PetscInt *start, PetscInt *end)
9289f4ada15SMatthew G. Knepley {
9299f4ada15SMatthew G. Knepley   PetscFunctionBegin;
9309f4ada15SMatthew G. Knepley   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
9319f4ada15SMatthew G. Knepley   if (start) *start = tr->depthStart[depth];
9329f4ada15SMatthew G. Knepley   if (end) *end = tr->depthEnd[depth];
9333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
934d410b0cfSMatthew G. Knepley }
935d410b0cfSMatthew G. Knepley 
936d410b0cfSMatthew G. Knepley /*@
937a4d5e7b4SMatthew G. Knepley   DMPlexTransformGetMatchStrata - Get the flag which determines what points get added to the transformed labels
938a4d5e7b4SMatthew G. Knepley 
939a4d5e7b4SMatthew G. Knepley   Not Collective
940a4d5e7b4SMatthew G. Knepley 
941a4d5e7b4SMatthew G. Knepley   Input Parameter:
942a4d5e7b4SMatthew G. Knepley . tr - The `DMPlexTransform`
943a4d5e7b4SMatthew G. Knepley 
944a4d5e7b4SMatthew G. Knepley   Output Parameter:
945a4d5e7b4SMatthew G. Knepley . match - If `PETSC_TRUE`, only add produced points at the same stratum as the original point to new labels
946a4d5e7b4SMatthew G. Knepley 
947a4d5e7b4SMatthew G. Knepley   Level: intermediate
948a4d5e7b4SMatthew G. Knepley 
949a4d5e7b4SMatthew G. Knepley .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPlexTransformSetMatchStrata()`, `DMPlexGetPointDepth()`
950a4d5e7b4SMatthew G. Knepley @*/
DMPlexTransformGetMatchStrata(DMPlexTransform tr,PetscBool * match)951a4d5e7b4SMatthew G. Knepley PetscErrorCode DMPlexTransformGetMatchStrata(DMPlexTransform tr, PetscBool *match)
952a4d5e7b4SMatthew G. Knepley {
953a4d5e7b4SMatthew G. Knepley   PetscFunctionBegin;
954a4d5e7b4SMatthew G. Knepley   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
955a4d5e7b4SMatthew G. Knepley   PetscAssertPointer(match, 2);
956a4d5e7b4SMatthew G. Knepley   *match = tr->labelMatchStrata;
957a4d5e7b4SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
958a4d5e7b4SMatthew G. Knepley }
959a4d5e7b4SMatthew G. Knepley 
960a4d5e7b4SMatthew G. Knepley /*@
961a4d5e7b4SMatthew G. Knepley   DMPlexTransformSetMatchStrata - Set the flag which determines what points get added to the transformed labels
962a4d5e7b4SMatthew G. Knepley 
963a4d5e7b4SMatthew G. Knepley   Not Collective
964a4d5e7b4SMatthew G. Knepley 
965a4d5e7b4SMatthew G. Knepley   Input Parameters:
966a4d5e7b4SMatthew G. Knepley + tr    - The `DMPlexTransform`
967a4d5e7b4SMatthew G. Knepley - match - If `PETSC_TRUE`, only add produced points at the same stratum as the original point to new labels
968a4d5e7b4SMatthew G. Knepley 
969a4d5e7b4SMatthew G. Knepley   Level: intermediate
970a4d5e7b4SMatthew G. Knepley 
971a4d5e7b4SMatthew G. Knepley .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPlexTransformGetMatchStrata()`, `DMPlexGetPointDepth()`
972a4d5e7b4SMatthew G. Knepley @*/
DMPlexTransformSetMatchStrata(DMPlexTransform tr,PetscBool match)973a4d5e7b4SMatthew G. Knepley PetscErrorCode DMPlexTransformSetMatchStrata(DMPlexTransform tr, PetscBool match)
974a4d5e7b4SMatthew G. Knepley {
975a4d5e7b4SMatthew G. Knepley   PetscFunctionBegin;
976a4d5e7b4SMatthew G. Knepley   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
977a4d5e7b4SMatthew G. Knepley   tr->labelMatchStrata = match;
978a4d5e7b4SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
979a4d5e7b4SMatthew G. Knepley }
980a4d5e7b4SMatthew G. Knepley 
981a4d5e7b4SMatthew G. Knepley /*@
982012bc364SMatthew G. Knepley   DMPlexTransformGetTargetPoint - Get the number of a point in the transformed mesh based on information from the original mesh.
983012bc364SMatthew G. Knepley 
98420f4b53cSBarry Smith   Not Collective
985012bc364SMatthew G. Knepley 
986012bc364SMatthew G. Knepley   Input Parameters:
987a1cb98faSBarry Smith + tr    - The `DMPlexTransform`
988012bc364SMatthew G. Knepley . ct    - The type of the original point which produces the new point
989012bc364SMatthew G. Knepley . ctNew - The type of the new point
990012bc364SMatthew G. Knepley . p     - The original point which produces the new point
99120f4b53cSBarry Smith - r     - The replica number of the new point, meaning it is the rth point of type `ctNew` produced from `p`
992012bc364SMatthew G. Knepley 
99320f4b53cSBarry Smith   Output Parameter:
994012bc364SMatthew G. Knepley . pNew - The new point number
995012bc364SMatthew G. Knepley 
996012bc364SMatthew G. Knepley   Level: developer
997012bc364SMatthew G. Knepley 
9981cc06b55SBarry Smith .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPolytopeType`, `DMPlexTransformGetSourcePoint()`, `DMPlexTransformCellTransform()`
999012bc364SMatthew G. Knepley @*/
DMPlexTransformGetTargetPoint(DMPlexTransform tr,DMPolytopeType ct,DMPolytopeType ctNew,PetscInt p,PetscInt r,PetscInt * pNew)1000d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformGetTargetPoint(DMPlexTransform tr, DMPolytopeType ct, DMPolytopeType ctNew, PetscInt p, PetscInt r, PetscInt *pNew)
1001d71ae5a4SJacob Faibussowitsch {
1002012bc364SMatthew G. Knepley   DMPolytopeType *rct;
1003012bc364SMatthew G. Knepley   PetscInt       *rsize, *cone, *ornt;
1004012bc364SMatthew G. Knepley   PetscInt        rt, Nct, n, off, rp;
1005012bc364SMatthew G. Knepley   DMLabel         trType = tr->trType;
1006d410b0cfSMatthew G. Knepley   PetscInt        ctS = tr->ctStart[ct], ctE = tr->ctStart[tr->ctOrderOld[tr->ctOrderInvOld[ct] + 1]];
1007d410b0cfSMatthew G. Knepley   PetscInt        ctSN = tr->ctStartNew[ctNew], ctEN = tr->ctStartNew[tr->ctOrderNew[tr->ctOrderInvNew[ctNew] + 1]];
1008012bc364SMatthew G. Knepley   PetscInt        newp = ctSN, cind;
1009012bc364SMatthew G. Knepley 
1010012bc364SMatthew G. Knepley   PetscFunctionBeginHot;
101115d65cafSMatthew G. Knepley   PetscCheck(p >= ctS && p < ctE, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %" PetscInt_FMT " is not a %s [%" PetscInt_FMT ", %" PetscInt_FMT ")", p, DMPolytopeTypes[ct], ctS, ctE);
10129566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformCellTransform(tr, ct, p, &rt, &Nct, &rct, &rsize, &cone, &ornt));
1013012bc364SMatthew G. Knepley   if (trType) {
10149566063dSJacob Faibussowitsch     PetscCall(DMLabelGetValueIndex(trType, rt, &cind));
10159566063dSJacob Faibussowitsch     PetscCall(DMLabelGetStratumPointIndex(trType, rt, p, &rp));
101663a3b9bcSJacob Faibussowitsch     PetscCheck(rp >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell type %s point %" PetscInt_FMT " does not have refine type %" PetscInt_FMT, DMPolytopeTypes[ct], p, rt);
1017012bc364SMatthew G. Knepley   } else {
1018012bc364SMatthew G. Knepley     cind = ct;
1019012bc364SMatthew G. Knepley     rp   = p - ctS;
1020012bc364SMatthew G. Knepley   }
1021012bc364SMatthew G. Knepley   off = tr->offset[cind * DM_NUM_POLYTOPES + ctNew];
102263a3b9bcSJacob Faibussowitsch   PetscCheck(off >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell type %s (%" PetscInt_FMT ") of point %" PetscInt_FMT " does not produce type %s for transform %s", DMPolytopeTypes[ct], rt, p, DMPolytopeTypes[ctNew], tr->hdr.type_name);
1023012bc364SMatthew G. Knepley   newp += off;
1024012bc364SMatthew G. Knepley   for (n = 0; n < Nct; ++n) {
1025012bc364SMatthew G. Knepley     if (rct[n] == ctNew) {
1026012bc364SMatthew G. Knepley       if (rsize[n] && r >= rsize[n])
102763a3b9bcSJacob Faibussowitsch         SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Replica number %" PetscInt_FMT " should be in [0, %" PetscInt_FMT ") for subcell type %s in cell type %s", r, rsize[n], DMPolytopeTypes[rct[n]], DMPolytopeTypes[ct]);
1028012bc364SMatthew G. Knepley       newp += rp * rsize[n] + r;
1029012bc364SMatthew G. Knepley       break;
1030012bc364SMatthew G. Knepley     }
1031012bc364SMatthew G. Knepley   }
1032012bc364SMatthew G. Knepley 
103363a3b9bcSJacob Faibussowitsch   PetscCheck(!(newp < ctSN) && !(newp >= ctEN), PETSC_COMM_SELF, PETSC_ERR_PLIB, "New point %" PetscInt_FMT " is not a %s [%" PetscInt_FMT ", %" PetscInt_FMT ")", newp, DMPolytopeTypes[ctNew], ctSN, ctEN);
1034012bc364SMatthew G. Knepley   *pNew = newp;
10353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1036012bc364SMatthew G. Knepley }
1037012bc364SMatthew G. Knepley 
10388b1ac879SMatthew Knepley /*@
10398b1ac879SMatthew Knepley   DMPlexTransformGetSourcePoint - Get the number of a point in the original mesh based on information from the transformed mesh.
10408b1ac879SMatthew Knepley 
104120f4b53cSBarry Smith   Not Collective
10428b1ac879SMatthew Knepley 
10438b1ac879SMatthew Knepley   Input Parameters:
1044a1cb98faSBarry Smith + tr   - The `DMPlexTransform`
10458b1ac879SMatthew Knepley - pNew - The new point number
10468b1ac879SMatthew Knepley 
10478b1ac879SMatthew Knepley   Output Parameters:
10488b1ac879SMatthew Knepley + ct    - The type of the original point which produces the new point
10498b1ac879SMatthew Knepley . ctNew - The type of the new point
10508b1ac879SMatthew Knepley . p     - The original point which produces the new point
10518b1ac879SMatthew Knepley - r     - The replica number of the new point, meaning it is the rth point of type ctNew produced from p
10528b1ac879SMatthew Knepley 
10538b1ac879SMatthew Knepley   Level: developer
10548b1ac879SMatthew Knepley 
10551cc06b55SBarry Smith .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPolytopeType`, `DMPlexTransformGetTargetPoint()`, `DMPlexTransformCellTransform()`
10568b1ac879SMatthew Knepley @*/
DMPlexTransformGetSourcePoint(DMPlexTransform tr,PetscInt pNew,DMPolytopeType * ct,DMPolytopeType * ctNew,PetscInt * p,PetscInt * r)1057d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformGetSourcePoint(DMPlexTransform tr, PetscInt pNew, DMPolytopeType *ct, DMPolytopeType *ctNew, PetscInt *p, PetscInt *r)
1058d71ae5a4SJacob Faibussowitsch {
1059012bc364SMatthew G. Knepley   DMLabel         trType = tr->trType;
10609f4ada15SMatthew G. Knepley   DMPolytopeType *rct, ctN;
1061012bc364SMatthew G. Knepley   PetscInt       *rsize, *cone, *ornt;
10629f4ada15SMatthew G. Knepley   PetscInt        rt = -1, rtTmp, Nct, n, rp = 0, rO = 0, pO;
10639f4ada15SMatthew G. Knepley   PetscInt        offset = -1, ctS, ctE, ctO = 0, ctTmp, rtS;
1064012bc364SMatthew G. Knepley 
1065012bc364SMatthew G. Knepley   PetscFunctionBegin;
10669f4ada15SMatthew G. Knepley   PetscCall(DMPlexTransformGetCellType(tr, pNew, &ctN));
1067012bc364SMatthew G. Knepley   if (trType) {
1068012bc364SMatthew G. Knepley     DM              dm;
1069012bc364SMatthew G. Knepley     IS              rtIS;
1070012bc364SMatthew G. Knepley     const PetscInt *reftypes;
1071012bc364SMatthew G. Knepley     PetscInt        Nrt, r, rtStart;
1072012bc364SMatthew G. Knepley 
10739566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformGetDM(tr, &dm));
10749566063dSJacob Faibussowitsch     PetscCall(DMLabelGetNumValues(trType, &Nrt));
10759566063dSJacob Faibussowitsch     PetscCall(DMLabelGetValueIS(trType, &rtIS));
10769566063dSJacob Faibussowitsch     PetscCall(ISGetIndices(rtIS, &reftypes));
1077012bc364SMatthew G. Knepley     for (r = 0; r < Nrt; ++r) {
1078012bc364SMatthew G. Knepley       const PetscInt off = tr->offset[r * DM_NUM_POLYTOPES + ctN];
1079012bc364SMatthew G. Knepley 
1080012bc364SMatthew G. Knepley       if (tr->ctStartNew[ctN] + off > pNew) continue;
1081012bc364SMatthew G. Knepley       /* Check that any of this refinement type exist */
1082012bc364SMatthew G. Knepley       /* TODO Actually keep track of the number produced here instead */
10839371c9d4SSatish Balay       if (off > offset) {
10849371c9d4SSatish Balay         rt     = reftypes[r];
10859371c9d4SSatish Balay         offset = off;
10869371c9d4SSatish Balay       }
1087012bc364SMatthew G. Knepley     }
10889566063dSJacob Faibussowitsch     PetscCall(ISRestoreIndices(rtIS, &reftypes));
10899566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&rtIS));
109063a3b9bcSJacob Faibussowitsch     PetscCheck(offset >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Source cell type for target point %" PetscInt_FMT " could be not found", pNew);
1091012bc364SMatthew G. Knepley     /* TODO Map refinement types to cell types */
10929566063dSJacob Faibussowitsch     PetscCall(DMLabelGetStratumBounds(trType, rt, &rtStart, NULL));
109363a3b9bcSJacob Faibussowitsch     PetscCheck(rtStart >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Refinement type %" PetscInt_FMT " has no source points", rt);
1094012bc364SMatthew G. Knepley     for (ctO = 0; ctO < DM_NUM_POLYTOPES; ++ctO) {
1095d410b0cfSMatthew G. Knepley       PetscInt ctS = tr->ctStart[ctO], ctE = tr->ctStart[tr->ctOrderOld[tr->ctOrderInvOld[ctO] + 1]];
1096012bc364SMatthew G. Knepley 
1097012bc364SMatthew G. Knepley       if ((rtStart >= ctS) && (rtStart < ctE)) break;
1098012bc364SMatthew G. Knepley     }
109963a3b9bcSJacob Faibussowitsch     PetscCheck(ctO != DM_NUM_POLYTOPES, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not determine a cell type for refinement type %" PetscInt_FMT, rt);
1100012bc364SMatthew G. Knepley   } else {
1101012bc364SMatthew G. Knepley     for (ctTmp = 0; ctTmp < DM_NUM_POLYTOPES; ++ctTmp) {
1102012bc364SMatthew G. Knepley       const PetscInt off = tr->offset[ctTmp * DM_NUM_POLYTOPES + ctN];
1103012bc364SMatthew G. Knepley 
1104012bc364SMatthew G. Knepley       if (tr->ctStartNew[ctN] + off > pNew) continue;
1105d410b0cfSMatthew G. Knepley       if (tr->ctStart[tr->ctOrderOld[tr->ctOrderInvOld[ctTmp] + 1]] <= tr->ctStart[ctTmp]) continue;
1106012bc364SMatthew G. Knepley       /* TODO Actually keep track of the number produced here instead */
11079371c9d4SSatish Balay       if (off > offset) {
11089371c9d4SSatish Balay         ctO    = ctTmp;
11099371c9d4SSatish Balay         offset = off;
11109371c9d4SSatish Balay       }
1111012bc364SMatthew G. Knepley     }
11129f4ada15SMatthew G. Knepley     rt = -1;
111363a3b9bcSJacob Faibussowitsch     PetscCheck(offset >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Source cell type for target point %" PetscInt_FMT " could be not found", pNew);
1114012bc364SMatthew G. Knepley   }
1115012bc364SMatthew G. Knepley   ctS = tr->ctStart[ctO];
1116d410b0cfSMatthew G. Knepley   ctE = tr->ctStart[tr->ctOrderOld[tr->ctOrderInvOld[ctO] + 1]];
11179f4ada15SMatthew G. Knepley   if (trType) {
11189f4ada15SMatthew G. Knepley     for (rtS = ctS; rtS < ctE; ++rtS) {
11199f4ada15SMatthew G. Knepley       PetscInt val;
11209f4ada15SMatthew G. Knepley       PetscCall(DMLabelGetValue(trType, rtS, &val));
11219f4ada15SMatthew G. Knepley       if (val == rt) break;
11229f4ada15SMatthew G. Knepley     }
11239f4ada15SMatthew G. Knepley     PetscCheck(rtS < ctE, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Could not find point of type %s with refine type %" PetscInt_FMT, DMPolytopeTypes[ctO], rt);
11249f4ada15SMatthew G. Knepley   } else rtS = ctS;
11259f4ada15SMatthew G. Knepley   PetscCall(DMPlexTransformCellTransform(tr, (DMPolytopeType)ctO, rtS, &rtTmp, &Nct, &rct, &rsize, &cone, &ornt));
11269f4ada15SMatthew G. Knepley   PetscCheck(!trType || rt == rtTmp, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Point %" PetscInt_FMT " has refine type %" PetscInt_FMT " != %" PetscInt_FMT " refine type which produced point %" PetscInt_FMT, rtS, rtTmp, rt, pNew);
1127012bc364SMatthew G. Knepley   for (n = 0; n < Nct; ++n) {
11288ca7df70SJacob Faibussowitsch     if (rct[n] == ctN) {
11299f4ada15SMatthew G. Knepley       PetscInt tmp = pNew - tr->ctStartNew[ctN] - offset, val, c;
1130012bc364SMatthew G. Knepley 
11319f4ada15SMatthew G. Knepley       if (trType) {
11329f4ada15SMatthew G. Knepley         for (c = ctS; c < ctE; ++c) {
11339f4ada15SMatthew G. Knepley           PetscCall(DMLabelGetValue(trType, c, &val));
11349f4ada15SMatthew G. Knepley           if (val == rt) {
11359f4ada15SMatthew G. Knepley             if (tmp < rsize[n]) break;
11369f4ada15SMatthew G. Knepley             tmp -= rsize[n];
11379f4ada15SMatthew G. Knepley           }
11389f4ada15SMatthew G. Knepley         }
11399f4ada15SMatthew G. Knepley         PetscCheck(c < ctE, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Parent point for target point %" PetscInt_FMT " could be not found", pNew);
11409f4ada15SMatthew G. Knepley         rp = c - ctS;
11419f4ada15SMatthew G. Knepley         rO = tmp;
11429f4ada15SMatthew G. Knepley       } else {
11439f4ada15SMatthew G. Knepley         // This assumes that all points of type ctO transform the same way
1144012bc364SMatthew G. Knepley         rp = tmp / rsize[n];
1145012bc364SMatthew G. Knepley         rO = tmp % rsize[n];
11469f4ada15SMatthew G. Knepley       }
1147012bc364SMatthew G. Knepley       break;
1148012bc364SMatthew G. Knepley     }
1149012bc364SMatthew G. Knepley   }
115063a3b9bcSJacob Faibussowitsch   PetscCheck(n != Nct, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Replica number for target point %" PetscInt_FMT " could be not found", pNew);
1151012bc364SMatthew G. Knepley   pO = rp + ctS;
115263a3b9bcSJacob Faibussowitsch   PetscCheck(!(pO < ctS) && !(pO >= ctE), PETSC_COMM_SELF, PETSC_ERR_PLIB, "Source point %" PetscInt_FMT " is not a %s [%" PetscInt_FMT ", %" PetscInt_FMT ")", pO, DMPolytopeTypes[ctO], ctS, ctE);
1153012bc364SMatthew G. Knepley   if (ct) *ct = (DMPolytopeType)ctO;
1154835f2295SStefano Zampini   if (ctNew) *ctNew = ctN;
1155012bc364SMatthew G. Knepley   if (p) *p = pO;
1156012bc364SMatthew G. Knepley   if (r) *r = rO;
11573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1158012bc364SMatthew G. Knepley }
1159012bc364SMatthew G. Knepley 
1160012bc364SMatthew G. Knepley /*@
1161012bc364SMatthew G. Knepley   DMPlexTransformCellTransform - Describes the transform of a given source cell into a set of other target cells. These produced cells become the new mesh.
1162012bc364SMatthew G. Knepley 
1163012bc364SMatthew G. Knepley   Input Parameters:
1164a1cb98faSBarry Smith + tr     - The `DMPlexTransform` object
1165012bc364SMatthew G. Knepley . source - The source cell type
1166012bc364SMatthew G. Knepley - p      - The source point, which can also determine the refine type
1167012bc364SMatthew G. Knepley 
1168012bc364SMatthew G. Knepley   Output Parameters:
1169012bc364SMatthew G. Knepley + rt     - The refine type for this point
1170012bc364SMatthew G. Knepley . Nt     - The number of types produced by this point
117120f4b53cSBarry Smith . target - An array of length `Nt` giving the types produced
117220f4b53cSBarry Smith . size   - An array of length `Nt` giving the number of cells of each type produced
117320f4b53cSBarry Smith . cone   - An array of length `Nt`*size[t]*coneSize[t] giving the cell type for each point in the cone of each produced point
117420f4b53cSBarry Smith - ornt   - An array of length `Nt`*size[t]*coneSize[t] giving the orientation for each point in the cone of each produced point
1175012bc364SMatthew G. Knepley 
1176012bc364SMatthew G. Knepley   Level: advanced
1177012bc364SMatthew G. Knepley 
1178a1cb98faSBarry Smith   Notes:
1179a1cb98faSBarry Smith   The cone array gives the cone of each subcell listed by the first three outputs. For each cone point, we
1180a1cb98faSBarry Smith   need the cell type, point identifier, and orientation within the subcell. The orientation is with respect to the canonical
1181a1cb98faSBarry Smith   division (described in these outputs) of the cell in the original mesh. The point identifier is given by
1182a1cb98faSBarry Smith .vb
1183a1cb98faSBarry Smith    the number of cones to be taken, or 0 for the current cell
1184a1cb98faSBarry Smith    the cell cone point number at each level from which it is subdivided
1185a1cb98faSBarry Smith    the replica number r of the subdivision.
1186a1cb98faSBarry Smith .ve
1187a1cb98faSBarry Smith   The orientation is with respect to the canonical cone orientation. For example, the prescription for edge division is
1188a1cb98faSBarry Smith .vb
1189a1cb98faSBarry Smith    Nt     = 2
1190a1cb98faSBarry Smith    target = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT}
1191a1cb98faSBarry Smith    size   = {1, 2}
1192a1cb98faSBarry Smith    cone   = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,  DM_POLYTOPE_POINT, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}
1193a1cb98faSBarry Smith    ornt   = {                         0,                       0,                        0,                          0}
1194a1cb98faSBarry Smith .ve
1195a1cb98faSBarry Smith 
11961cc06b55SBarry Smith .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPolytopeType`, `DMPlexTransformApply()`, `DMPlexTransformCreate()`
1197012bc364SMatthew G. Knepley @*/
DMPlexTransformCellTransform(DMPlexTransform tr,DMPolytopeType source,PetscInt p,PetscInt * rt,PetscInt * Nt,DMPolytopeType * target[],PetscInt * size[],PetscInt * cone[],PetscInt * ornt[])1198d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformCellTransform(DMPlexTransform tr, DMPolytopeType source, PetscInt p, PetscInt *rt, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
1199d71ae5a4SJacob Faibussowitsch {
1200012bc364SMatthew G. Knepley   PetscFunctionBegin;
1201dbbe0bcdSBarry Smith   PetscUseTypeMethod(tr, celltransform, source, p, rt, Nt, target, size, cone, ornt);
12023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1203012bc364SMatthew G. Knepley }
1204012bc364SMatthew G. Knepley 
DMPlexTransformGetSubcellOrientationIdentity(DMPlexTransform tr,DMPolytopeType sct,PetscInt sp,PetscInt so,DMPolytopeType tct,PetscInt r,PetscInt o,PetscInt * rnew,PetscInt * onew)1205d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformGetSubcellOrientationIdentity(DMPlexTransform tr, DMPolytopeType sct, PetscInt sp, PetscInt so, DMPolytopeType tct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew)
1206d71ae5a4SJacob Faibussowitsch {
1207012bc364SMatthew G. Knepley   PetscFunctionBegin;
1208012bc364SMatthew G. Knepley   *rnew = r;
1209012bc364SMatthew G. Knepley   *onew = DMPolytopeTypeComposeOrientation(tct, o, so);
12103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1211012bc364SMatthew G. Knepley }
1212012bc364SMatthew G. Knepley 
1213012bc364SMatthew G. Knepley /* Returns the same thing */
DMPlexTransformCellTransformIdentity(DMPlexTransform tr,DMPolytopeType source,PetscInt p,PetscInt * rt,PetscInt * Nt,DMPolytopeType * target[],PetscInt * size[],PetscInt * cone[],PetscInt * ornt[])1214d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformCellTransformIdentity(DMPlexTransform tr, DMPolytopeType source, PetscInt p, PetscInt *rt, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
1215d71ae5a4SJacob Faibussowitsch {
1216012bc364SMatthew G. Knepley   static DMPolytopeType vertexT[] = {DM_POLYTOPE_POINT};
1217012bc364SMatthew G. Knepley   static PetscInt       vertexS[] = {1};
1218012bc364SMatthew G. Knepley   static PetscInt       vertexC[] = {0};
1219012bc364SMatthew G. Knepley   static PetscInt       vertexO[] = {0};
1220012bc364SMatthew G. Knepley   static DMPolytopeType edgeT[]   = {DM_POLYTOPE_SEGMENT};
1221012bc364SMatthew G. Knepley   static PetscInt       edgeS[]   = {1};
1222012bc364SMatthew G. Knepley   static PetscInt       edgeC[]   = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0};
1223012bc364SMatthew G. Knepley   static PetscInt       edgeO[]   = {0, 0};
1224012bc364SMatthew G. Knepley   static DMPolytopeType tedgeT[]  = {DM_POLYTOPE_POINT_PRISM_TENSOR};
1225012bc364SMatthew G. Knepley   static PetscInt       tedgeS[]  = {1};
1226012bc364SMatthew G. Knepley   static PetscInt       tedgeC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0};
1227012bc364SMatthew G. Knepley   static PetscInt       tedgeO[]  = {0, 0};
1228012bc364SMatthew G. Knepley   static DMPolytopeType triT[]    = {DM_POLYTOPE_TRIANGLE};
1229012bc364SMatthew G. Knepley   static PetscInt       triS[]    = {1};
1230012bc364SMatthew G. Knepley   static PetscInt       triC[]    = {DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0};
1231012bc364SMatthew G. Knepley   static PetscInt       triO[]    = {0, 0, 0};
1232012bc364SMatthew G. Knepley   static DMPolytopeType quadT[]   = {DM_POLYTOPE_QUADRILATERAL};
1233012bc364SMatthew G. Knepley   static PetscInt       quadS[]   = {1};
1234012bc364SMatthew G. Knepley   static PetscInt       quadC[]   = {DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 1, 3, 0};
1235012bc364SMatthew G. Knepley   static PetscInt       quadO[]   = {0, 0, 0, 0};
1236012bc364SMatthew G. Knepley   static DMPolytopeType tquadT[]  = {DM_POLYTOPE_SEG_PRISM_TENSOR};
1237012bc364SMatthew G. Knepley   static PetscInt       tquadS[]  = {1};
1238012bc364SMatthew G. Knepley   static PetscInt       tquadC[]  = {DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 3, 0};
1239012bc364SMatthew G. Knepley   static PetscInt       tquadO[]  = {0, 0, 0, 0};
1240012bc364SMatthew G. Knepley   static DMPolytopeType tetT[]    = {DM_POLYTOPE_TETRAHEDRON};
1241012bc364SMatthew G. Knepley   static PetscInt       tetS[]    = {1};
1242012bc364SMatthew G. Knepley   static PetscInt       tetC[]    = {DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, DM_POLYTOPE_TRIANGLE, 1, 2, 0, DM_POLYTOPE_TRIANGLE, 1, 3, 0};
1243012bc364SMatthew G. Knepley   static PetscInt       tetO[]    = {0, 0, 0, 0};
1244012bc364SMatthew G. Knepley   static DMPolytopeType hexT[]    = {DM_POLYTOPE_HEXAHEDRON};
1245012bc364SMatthew G. Knepley   static PetscInt       hexS[]    = {1};
12469371c9d4SSatish Balay   static PetscInt       hexC[] = {DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 0, DM_POLYTOPE_QUADRILATERAL, 1, 3, 0, DM_POLYTOPE_QUADRILATERAL, 1, 4, 0, DM_POLYTOPE_QUADRILATERAL, 1, 5, 0};
1247012bc364SMatthew G. Knepley   static PetscInt       hexO[] = {0, 0, 0, 0, 0, 0};
1248012bc364SMatthew G. Knepley   static DMPolytopeType tripT[]   = {DM_POLYTOPE_TRI_PRISM};
1249012bc364SMatthew G. Knepley   static PetscInt       tripS[]   = {1};
12509371c9d4SSatish Balay   static PetscInt       tripC[]   = {DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 0, DM_POLYTOPE_QUADRILATERAL, 1, 3, 0, DM_POLYTOPE_QUADRILATERAL, 1, 4, 0};
1251012bc364SMatthew G. Knepley   static PetscInt       tripO[]   = {0, 0, 0, 0, 0};
1252012bc364SMatthew G. Knepley   static DMPolytopeType ttripT[]  = {DM_POLYTOPE_TRI_PRISM_TENSOR};
1253012bc364SMatthew G. Knepley   static PetscInt       ttripS[]  = {1};
12549371c9d4SSatish Balay   static PetscInt       ttripC[]  = {DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 0};
1255012bc364SMatthew G. Knepley   static PetscInt       ttripO[]  = {0, 0, 0, 0, 0};
1256012bc364SMatthew G. Knepley   static DMPolytopeType tquadpT[] = {DM_POLYTOPE_QUAD_PRISM_TENSOR};
1257012bc364SMatthew G. Knepley   static PetscInt       tquadpS[] = {1};
12589371c9d4SSatish Balay   static PetscInt       tquadpC[] = {DM_POLYTOPE_QUADRILATERAL,    1, 0, 0, DM_POLYTOPE_QUADRILATERAL,    1, 1, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 0,
12599371c9d4SSatish Balay                                      DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 5, 0};
1260012bc364SMatthew G. Knepley   static PetscInt       tquadpO[] = {0, 0, 0, 0, 0, 0};
1261012bc364SMatthew G. Knepley   static DMPolytopeType pyrT[]    = {DM_POLYTOPE_PYRAMID};
1262012bc364SMatthew G. Knepley   static PetscInt       pyrS[]    = {1};
12639371c9d4SSatish Balay   static PetscInt       pyrC[]    = {DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, DM_POLYTOPE_TRIANGLE, 1, 2, 0, DM_POLYTOPE_TRIANGLE, 1, 3, 0, DM_POLYTOPE_TRIANGLE, 1, 4, 0};
1264012bc364SMatthew G. Knepley   static PetscInt       pyrO[]    = {0, 0, 0, 0, 0};
1265012bc364SMatthew G. Knepley 
1266012bc364SMatthew G. Knepley   PetscFunctionBegin;
1267012bc364SMatthew G. Knepley   if (rt) *rt = 0;
1268012bc364SMatthew G. Knepley   switch (source) {
12699371c9d4SSatish Balay   case DM_POLYTOPE_POINT:
12709371c9d4SSatish Balay     *Nt     = 1;
12719371c9d4SSatish Balay     *target = vertexT;
12729371c9d4SSatish Balay     *size   = vertexS;
12739371c9d4SSatish Balay     *cone   = vertexC;
12749371c9d4SSatish Balay     *ornt   = vertexO;
12759371c9d4SSatish Balay     break;
12769371c9d4SSatish Balay   case DM_POLYTOPE_SEGMENT:
12779371c9d4SSatish Balay     *Nt     = 1;
12789371c9d4SSatish Balay     *target = edgeT;
12799371c9d4SSatish Balay     *size   = edgeS;
12809371c9d4SSatish Balay     *cone   = edgeC;
12819371c9d4SSatish Balay     *ornt   = edgeO;
12829371c9d4SSatish Balay     break;
12839371c9d4SSatish Balay   case DM_POLYTOPE_POINT_PRISM_TENSOR:
12849371c9d4SSatish Balay     *Nt     = 1;
12859371c9d4SSatish Balay     *target = tedgeT;
12869371c9d4SSatish Balay     *size   = tedgeS;
12879371c9d4SSatish Balay     *cone   = tedgeC;
12889371c9d4SSatish Balay     *ornt   = tedgeO;
12899371c9d4SSatish Balay     break;
12909371c9d4SSatish Balay   case DM_POLYTOPE_TRIANGLE:
12919371c9d4SSatish Balay     *Nt     = 1;
12929371c9d4SSatish Balay     *target = triT;
12939371c9d4SSatish Balay     *size   = triS;
12949371c9d4SSatish Balay     *cone   = triC;
12959371c9d4SSatish Balay     *ornt   = triO;
12969371c9d4SSatish Balay     break;
12979371c9d4SSatish Balay   case DM_POLYTOPE_QUADRILATERAL:
12989371c9d4SSatish Balay     *Nt     = 1;
12999371c9d4SSatish Balay     *target = quadT;
13009371c9d4SSatish Balay     *size   = quadS;
13019371c9d4SSatish Balay     *cone   = quadC;
13029371c9d4SSatish Balay     *ornt   = quadO;
13039371c9d4SSatish Balay     break;
13049371c9d4SSatish Balay   case DM_POLYTOPE_SEG_PRISM_TENSOR:
13059371c9d4SSatish Balay     *Nt     = 1;
13069371c9d4SSatish Balay     *target = tquadT;
13079371c9d4SSatish Balay     *size   = tquadS;
13089371c9d4SSatish Balay     *cone   = tquadC;
13099371c9d4SSatish Balay     *ornt   = tquadO;
13109371c9d4SSatish Balay     break;
13119371c9d4SSatish Balay   case DM_POLYTOPE_TETRAHEDRON:
13129371c9d4SSatish Balay     *Nt     = 1;
13139371c9d4SSatish Balay     *target = tetT;
13149371c9d4SSatish Balay     *size   = tetS;
13159371c9d4SSatish Balay     *cone   = tetC;
13169371c9d4SSatish Balay     *ornt   = tetO;
13179371c9d4SSatish Balay     break;
13189371c9d4SSatish Balay   case DM_POLYTOPE_HEXAHEDRON:
13199371c9d4SSatish Balay     *Nt     = 1;
13209371c9d4SSatish Balay     *target = hexT;
13219371c9d4SSatish Balay     *size   = hexS;
13229371c9d4SSatish Balay     *cone   = hexC;
13239371c9d4SSatish Balay     *ornt   = hexO;
13249371c9d4SSatish Balay     break;
13259371c9d4SSatish Balay   case DM_POLYTOPE_TRI_PRISM:
13269371c9d4SSatish Balay     *Nt     = 1;
13279371c9d4SSatish Balay     *target = tripT;
13289371c9d4SSatish Balay     *size   = tripS;
13299371c9d4SSatish Balay     *cone   = tripC;
13309371c9d4SSatish Balay     *ornt   = tripO;
13319371c9d4SSatish Balay     break;
13329371c9d4SSatish Balay   case DM_POLYTOPE_TRI_PRISM_TENSOR:
13339371c9d4SSatish Balay     *Nt     = 1;
13349371c9d4SSatish Balay     *target = ttripT;
13359371c9d4SSatish Balay     *size   = ttripS;
13369371c9d4SSatish Balay     *cone   = ttripC;
13379371c9d4SSatish Balay     *ornt   = ttripO;
13389371c9d4SSatish Balay     break;
13399371c9d4SSatish Balay   case DM_POLYTOPE_QUAD_PRISM_TENSOR:
13409371c9d4SSatish Balay     *Nt     = 1;
13419371c9d4SSatish Balay     *target = tquadpT;
13429371c9d4SSatish Balay     *size   = tquadpS;
13439371c9d4SSatish Balay     *cone   = tquadpC;
13449371c9d4SSatish Balay     *ornt   = tquadpO;
13459371c9d4SSatish Balay     break;
13469371c9d4SSatish Balay   case DM_POLYTOPE_PYRAMID:
13479371c9d4SSatish Balay     *Nt     = 1;
13489371c9d4SSatish Balay     *target = pyrT;
13499371c9d4SSatish Balay     *size   = pyrS;
13509371c9d4SSatish Balay     *cone   = pyrC;
13519371c9d4SSatish Balay     *ornt   = pyrO;
13529371c9d4SSatish Balay     break;
1353d71ae5a4SJacob Faibussowitsch   default:
1354d71ae5a4SJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
1355012bc364SMatthew G. Knepley   }
13563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1357012bc364SMatthew G. Knepley }
1358012bc364SMatthew G. Knepley 
1359012bc364SMatthew G. Knepley /*@
1360012bc364SMatthew G. Knepley   DMPlexTransformGetSubcellOrientation - Transform the replica number and orientation for a target point according to the group action for the source point
1361012bc364SMatthew G. Knepley 
1362a1cb98faSBarry Smith   Not Collective
1363012bc364SMatthew G. Knepley 
1364012bc364SMatthew G. Knepley   Input Parameters:
1365a1cb98faSBarry Smith + tr  - The `DMPlexTransform`
1366012bc364SMatthew G. Knepley . sct - The source point cell type, from whom the new cell is being produced
1367012bc364SMatthew G. Knepley . sp  - The source point
1368012bc364SMatthew G. Knepley . so  - The orientation of the source point in its enclosing parent
1369012bc364SMatthew G. Knepley . tct - The target point cell type
1370012bc364SMatthew G. Knepley . r   - The replica number requested for the produced cell type
1371012bc364SMatthew G. Knepley - o   - The orientation of the replica
1372012bc364SMatthew G. Knepley 
1373012bc364SMatthew G. Knepley   Output Parameters:
1374012bc364SMatthew G. Knepley + rnew - The replica number, given the orientation of the parent
1375012bc364SMatthew G. Knepley - onew - The replica orientation, given the orientation of the parent
1376012bc364SMatthew G. Knepley 
1377012bc364SMatthew G. Knepley   Level: advanced
1378012bc364SMatthew G. Knepley 
13791cc06b55SBarry Smith .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPolytopeType`, `DMPlexTransformCellTransform()`, `DMPlexTransformApply()`
1380012bc364SMatthew G. Knepley @*/
DMPlexTransformGetSubcellOrientation(DMPlexTransform tr,DMPolytopeType sct,PetscInt sp,PetscInt so,DMPolytopeType tct,PetscInt r,PetscInt o,PetscInt * rnew,PetscInt * onew)1381d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformGetSubcellOrientation(DMPlexTransform tr, DMPolytopeType sct, PetscInt sp, PetscInt so, DMPolytopeType tct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew)
1382d71ae5a4SJacob Faibussowitsch {
1383012bc364SMatthew G. Knepley   PetscFunctionBeginHot;
1384dbbe0bcdSBarry Smith   PetscUseTypeMethod(tr, getsubcellorientation, sct, sp, so, tct, r, o, rnew, onew);
13853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1386012bc364SMatthew G. Knepley }
1387012bc364SMatthew G. Knepley 
DMPlexTransformSetConeSizes(DMPlexTransform tr,DM rdm)1388d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMPlexTransformSetConeSizes(DMPlexTransform tr, DM rdm)
1389d71ae5a4SJacob Faibussowitsch {
1390012bc364SMatthew G. Knepley   DM       dm;
1391f622de60SMatthew G. Knepley   PetscInt pStart, pEnd, pNew;
1392012bc364SMatthew G. Knepley 
1393012bc364SMatthew G. Knepley   PetscFunctionBegin;
13949566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformGetDM(tr, &dm));
1395f7b6882eSMatthew G. Knepley   PetscCall(PetscLogEventBegin(DMPLEXTRANSFORM_SetConeSizes, tr, dm, 0, 0));
1396012bc364SMatthew G. Knepley   /* Must create the celltype label here so that we do not automatically try to compute the types */
13979566063dSJacob Faibussowitsch   PetscCall(DMCreateLabel(rdm, "celltype"));
13989566063dSJacob Faibussowitsch   PetscCall(DMPlexGetChart(dm, &pStart, &pEnd));
1399f622de60SMatthew G. Knepley   for (PetscInt p = pStart; p < pEnd; ++p) {
1400012bc364SMatthew G. Knepley     DMPolytopeType  ct;
1401012bc364SMatthew G. Knepley     DMPolytopeType *rct;
1402012bc364SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
1403012bc364SMatthew G. Knepley     PetscInt        Nct, n, r;
1404012bc364SMatthew G. Knepley 
14059566063dSJacob Faibussowitsch     PetscCall(DMPlexGetCellType(dm, p, &ct));
14069566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformCellTransform(tr, ct, p, NULL, &Nct, &rct, &rsize, &rcone, &rornt));
1407012bc364SMatthew G. Knepley     for (n = 0; n < Nct; ++n) {
1408012bc364SMatthew G. Knepley       for (r = 0; r < rsize[n]; ++r) {
14099566063dSJacob Faibussowitsch         PetscCall(DMPlexTransformGetTargetPoint(tr, ct, rct[n], p, r, &pNew));
14109566063dSJacob Faibussowitsch         PetscCall(DMPlexSetConeSize(rdm, pNew, DMPolytopeTypeGetConeSize(rct[n])));
14119566063dSJacob Faibussowitsch         PetscCall(DMPlexSetCellType(rdm, pNew, rct[n]));
1412012bc364SMatthew G. Knepley       }
1413012bc364SMatthew G. Knepley     }
1414012bc364SMatthew G. Knepley   }
1415012bc364SMatthew G. Knepley   /* Let the DM know we have set all the cell types */
1416012bc364SMatthew G. Knepley   {
1417012bc364SMatthew G. Knepley     DMLabel  ctLabel;
1418012bc364SMatthew G. Knepley     DM_Plex *plex = (DM_Plex *)rdm->data;
1419012bc364SMatthew G. Knepley 
14209566063dSJacob Faibussowitsch     PetscCall(DMPlexGetCellTypeLabel(rdm, &ctLabel));
14219566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)ctLabel, &plex->celltypeState));
1422012bc364SMatthew G. Knepley   }
1423f7b6882eSMatthew G. Knepley   PetscCall(PetscLogEventEnd(DMPLEXTRANSFORM_SetConeSizes, tr, dm, 0, 0));
14243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1425012bc364SMatthew G. Knepley }
1426012bc364SMatthew G. Knepley 
DMPlexTransformGetConeSize(DMPlexTransform tr,PetscInt q,PetscInt * coneSize)14279f4ada15SMatthew G. Knepley PetscErrorCode DMPlexTransformGetConeSize(DMPlexTransform tr, PetscInt q, PetscInt *coneSize)
1428012bc364SMatthew G. Knepley {
14299f4ada15SMatthew G. Knepley   DMPolytopeType ctNew;
1430012bc364SMatthew G. Knepley 
1431012bc364SMatthew G. Knepley   PetscFunctionBegin;
1432012bc364SMatthew G. Knepley   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
14334f572ea9SToby Isaac   PetscAssertPointer(coneSize, 3);
14349f4ada15SMatthew G. Knepley   PetscCall(DMPlexTransformGetCellType(tr, q, &ctNew));
1435835f2295SStefano Zampini   *coneSize = DMPolytopeTypeGetConeSize(ctNew);
14363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1437012bc364SMatthew G. Knepley }
1438012bc364SMatthew G. Knepley 
1439012bc364SMatthew G. Knepley /* The orientation o is for the interior of the cell p */
DMPlexTransformGetCone_Internal(DMPlexTransform tr,PetscInt p,PetscInt o,DMPolytopeType ct,DMPolytopeType ctNew,const PetscInt rcone[],PetscInt * coneoff,const PetscInt rornt[],PetscInt * orntoff,PetscInt coneNew[],PetscInt orntNew[])1440d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMPlexTransformGetCone_Internal(DMPlexTransform tr, PetscInt p, PetscInt o, DMPolytopeType ct, DMPolytopeType ctNew, const PetscInt rcone[], PetscInt *coneoff, const PetscInt rornt[], PetscInt *orntoff, PetscInt coneNew[], PetscInt orntNew[])
1441d71ae5a4SJacob Faibussowitsch {
1442012bc364SMatthew G. Knepley   DM              dm;
1443012bc364SMatthew G. Knepley   const PetscInt  csizeNew = DMPolytopeTypeGetConeSize(ctNew);
1444012bc364SMatthew G. Knepley   const PetscInt *cone;
1445658b9581SMatthew G. Knepley   DMPolytopeType *newft = NULL;
1446012bc364SMatthew G. Knepley   PetscInt        c, coff = *coneoff, ooff = *orntoff;
1447658b9581SMatthew G. Knepley   PetscInt        dim, cr = 0, co = 0, nr, no;
1448012bc364SMatthew G. Knepley 
1449012bc364SMatthew G. Knepley   PetscFunctionBegin;
14509566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformGetDM(tr, &dm));
14519f4ada15SMatthew G. Knepley   PetscCall(DMPlexGetOrientedCone(dm, p, &cone, NULL));
1452658b9581SMatthew G. Knepley   // Check if we have to permute this cell
1453658b9581SMatthew G. Knepley   PetscCall(DMGetDimension(dm, &dim));
1454658b9581SMatthew G. Knepley   if (DMPolytopeTypeGetDim(ctNew) == dim && DMPolytopeTypeGetDim(ct) == dim - 1) {
1455658b9581SMatthew G. Knepley     PetscCall(DMPlexTransformGetSubcellOrientation(tr, ct, p, o, ctNew, cr, co, &nr, &no));
1456658b9581SMatthew G. Knepley     if (cr != nr || co != no) PetscCall(DMGetWorkArray(dm, csizeNew, MPIU_INT, &newft));
1457658b9581SMatthew G. Knepley   }
1458012bc364SMatthew G. Knepley   for (c = 0; c < csizeNew; ++c) {
1459012bc364SMatthew G. Knepley     PetscInt             ppp   = -1;                            /* Parent Parent point: Parent of point pp */
1460012bc364SMatthew G. Knepley     PetscInt             pp    = p;                             /* Parent point: Point in the original mesh producing new cone point */
1461012bc364SMatthew G. Knepley     PetscInt             po    = 0;                             /* Orientation of parent point pp in parent parent point ppp */
1462012bc364SMatthew G. Knepley     DMPolytopeType       pct   = ct;                            /* Parent type: Cell type for parent of new cone point */
1463012bc364SMatthew G. Knepley     const PetscInt      *pcone = cone;                          /* Parent cone: Cone of parent point pp */
1464012bc364SMatthew G. Knepley     PetscInt             pr    = -1;                            /* Replica number of pp that produces new cone point  */
1465012bc364SMatthew G. Knepley     const DMPolytopeType ft    = (DMPolytopeType)rcone[coff++]; /* Cell type for new cone point of pNew */
1466012bc364SMatthew G. Knepley     const PetscInt       fn    = rcone[coff++];                 /* Number of cones of p that need to be taken when producing new cone point */
1467012bc364SMatthew G. Knepley     PetscInt             fo    = rornt[ooff++];                 /* Orientation of new cone point in pNew */
1468012bc364SMatthew G. Knepley     PetscInt             lc;
1469012bc364SMatthew G. Knepley 
1470012bc364SMatthew G. Knepley     /* Get the type (pct) and point number (pp) of the parent point in the original mesh which produces this cone point */
1471012bc364SMatthew G. Knepley     for (lc = 0; lc < fn; ++lc) {
147285036b15SMatthew G. Knepley       const PetscInt *parr = DMPolytopeTypeGetArrangement(pct, po);
1473012bc364SMatthew G. Knepley       const PetscInt  acp  = rcone[coff++];
1474012bc364SMatthew G. Knepley       const PetscInt  pcp  = parr[acp * 2];
1475012bc364SMatthew G. Knepley       const PetscInt  pco  = parr[acp * 2 + 1];
1476012bc364SMatthew G. Knepley       const PetscInt *ppornt;
1477012bc364SMatthew G. Knepley 
1478012bc364SMatthew G. Knepley       ppp = pp;
1479012bc364SMatthew G. Knepley       pp  = pcone[pcp];
14809566063dSJacob Faibussowitsch       PetscCall(DMPlexGetCellType(dm, pp, &pct));
14819f4ada15SMatthew G. Knepley       // Restore the parent cone from the last iterate
14829f4ada15SMatthew G. Knepley       if (lc) PetscCall(DMPlexRestoreOrientedCone(dm, ppp, &pcone, NULL));
14839f4ada15SMatthew G. Knepley       PetscCall(DMPlexGetOrientedCone(dm, pp, &pcone, NULL));
14849f4ada15SMatthew G. Knepley       PetscCall(DMPlexGetOrientedCone(dm, ppp, NULL, &ppornt));
1485012bc364SMatthew G. Knepley       po = DMPolytopeTypeComposeOrientation(pct, ppornt[pcp], pco);
14869f4ada15SMatthew G. Knepley       PetscCall(DMPlexRestoreOrientedCone(dm, ppp, NULL, &ppornt));
1487012bc364SMatthew G. Knepley     }
14889f4ada15SMatthew G. Knepley     if (lc) PetscCall(DMPlexRestoreOrientedCone(dm, pp, &pcone, NULL));
1489012bc364SMatthew G. Knepley     pr = rcone[coff++];
1490012bc364SMatthew G. Knepley     /* Orientation po of pp maps (pr, fo) -> (pr', fo') */
14919566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformGetSubcellOrientation(tr, pct, pp, fn ? po : o, ft, pr, fo, &pr, &fo));
14929566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformGetTargetPoint(tr, pct, ft, pp, pr, &coneNew[c]));
1493012bc364SMatthew G. Knepley     orntNew[c] = fo;
1494658b9581SMatthew G. Knepley     if (newft) newft[c] = ft;
1495012bc364SMatthew G. Knepley   }
14969f4ada15SMatthew G. Knepley   PetscCall(DMPlexRestoreOrientedCone(dm, p, &cone, NULL));
1497658b9581SMatthew G. Knepley   if (newft) {
1498658b9581SMatthew G. Knepley     const PetscInt *arr;
1499658b9581SMatthew G. Knepley     PetscInt       *newcone, *newornt;
1500658b9581SMatthew G. Knepley 
1501658b9581SMatthew G. Knepley     arr = DMPolytopeTypeGetArrangement(ctNew, no);
1502658b9581SMatthew G. Knepley     PetscCall(DMGetWorkArray(dm, csizeNew, MPIU_INT, &newcone));
1503658b9581SMatthew G. Knepley     PetscCall(DMGetWorkArray(dm, csizeNew, MPIU_INT, &newornt));
1504658b9581SMatthew G. Knepley     for (PetscInt c = 0; c < csizeNew; ++c) {
1505658b9581SMatthew G. Knepley       DMPolytopeType ft = newft[c];
1506658b9581SMatthew G. Knepley       PetscInt       nO;
1507658b9581SMatthew G. Knepley 
1508658b9581SMatthew G. Knepley       nO         = DMPolytopeTypeGetNumArrangements(ft) / 2;
1509658b9581SMatthew G. Knepley       newcone[c] = coneNew[arr[c * 2 + 0]];
1510658b9581SMatthew G. Knepley       newornt[c] = DMPolytopeTypeComposeOrientation(ft, arr[c * 2 + 1], orntNew[arr[c * 2 + 0]]);
1511658b9581SMatthew G. Knepley       PetscCheck(!newornt[c] || !(newornt[c] >= nO || newornt[c] < -nO), PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid orientation %" PetscInt_FMT " not in [%" PetscInt_FMT ",%" PetscInt_FMT ") for %s %" PetscInt_FMT, newornt[c], -nO, nO, DMPolytopeTypes[ft], coneNew[c]);
1512658b9581SMatthew G. Knepley     }
1513658b9581SMatthew G. Knepley     for (PetscInt c = 0; c < csizeNew; ++c) {
1514658b9581SMatthew G. Knepley       coneNew[c] = newcone[c];
1515658b9581SMatthew G. Knepley       orntNew[c] = newornt[c];
1516658b9581SMatthew G. Knepley     }
1517658b9581SMatthew G. Knepley     PetscCall(DMRestoreWorkArray(dm, csizeNew, MPIU_INT, &newcone));
1518658b9581SMatthew G. Knepley     PetscCall(DMRestoreWorkArray(dm, csizeNew, MPIU_INT, &newornt));
1519658b9581SMatthew G. Knepley     PetscCall(DMRestoreWorkArray(dm, csizeNew, MPIU_INT, &newft));
1520658b9581SMatthew G. Knepley   }
1521012bc364SMatthew G. Knepley   *coneoff = coff;
1522012bc364SMatthew G. Knepley   *orntoff = ooff;
15233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1524012bc364SMatthew G. Knepley }
1525012bc364SMatthew G. Knepley 
DMPlexTransformSetCones(DMPlexTransform tr,DM rdm)1526d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMPlexTransformSetCones(DMPlexTransform tr, DM rdm)
1527d71ae5a4SJacob Faibussowitsch {
1528012bc364SMatthew G. Knepley   DM             dm;
1529012bc364SMatthew G. Knepley   DMPolytopeType ct;
1530012bc364SMatthew G. Knepley   PetscInt      *coneNew, *orntNew;
1531012bc364SMatthew G. Knepley   PetscInt       maxConeSize = 0, pStart, pEnd, p, pNew;
1532012bc364SMatthew G. Knepley 
1533012bc364SMatthew G. Knepley   PetscFunctionBegin;
15349566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformGetDM(tr, &dm));
1535f7b6882eSMatthew G. Knepley   PetscCall(PetscLogEventBegin(DMPLEXTRANSFORM_SetCones, tr, dm, 0, 0));
1536012bc364SMatthew G. Knepley   for (p = 0; p < DM_NUM_POLYTOPES; ++p) maxConeSize = PetscMax(maxConeSize, DMPolytopeTypeGetConeSize((DMPolytopeType)p));
15379566063dSJacob Faibussowitsch   PetscCall(DMGetWorkArray(rdm, maxConeSize, MPIU_INT, &coneNew));
15389566063dSJacob Faibussowitsch   PetscCall(DMGetWorkArray(rdm, maxConeSize, MPIU_INT, &orntNew));
15399566063dSJacob Faibussowitsch   PetscCall(DMPlexGetChart(dm, &pStart, &pEnd));
1540012bc364SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
1541012bc364SMatthew G. Knepley     PetscInt        coff, ooff;
1542012bc364SMatthew G. Knepley     DMPolytopeType *rct;
1543012bc364SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
1544012bc364SMatthew G. Knepley     PetscInt        Nct, n, r;
1545012bc364SMatthew G. Knepley 
15469566063dSJacob Faibussowitsch     PetscCall(DMPlexGetCellType(dm, p, &ct));
15479566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformCellTransform(tr, ct, p, NULL, &Nct, &rct, &rsize, &rcone, &rornt));
1548012bc364SMatthew G. Knepley     for (n = 0, coff = 0, ooff = 0; n < Nct; ++n) {
1549012bc364SMatthew G. Knepley       const DMPolytopeType ctNew = rct[n];
1550012bc364SMatthew G. Knepley 
1551012bc364SMatthew G. Knepley       for (r = 0; r < rsize[n]; ++r) {
15529566063dSJacob Faibussowitsch         PetscCall(DMPlexTransformGetTargetPoint(tr, ct, rct[n], p, r, &pNew));
15539566063dSJacob Faibussowitsch         PetscCall(DMPlexTransformGetCone_Internal(tr, p, 0, ct, ctNew, rcone, &coff, rornt, &ooff, coneNew, orntNew));
15549566063dSJacob Faibussowitsch         PetscCall(DMPlexSetCone(rdm, pNew, coneNew));
15559566063dSJacob Faibussowitsch         PetscCall(DMPlexSetConeOrientation(rdm, pNew, orntNew));
1556012bc364SMatthew G. Knepley       }
1557012bc364SMatthew G. Knepley     }
1558012bc364SMatthew G. Knepley   }
15599566063dSJacob Faibussowitsch   PetscCall(DMRestoreWorkArray(rdm, maxConeSize, MPIU_INT, &coneNew));
15609566063dSJacob Faibussowitsch   PetscCall(DMRestoreWorkArray(rdm, maxConeSize, MPIU_INT, &orntNew));
15619566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(rdm, NULL, "-rdm_view"));
15629566063dSJacob Faibussowitsch   PetscCall(DMPlexSymmetrize(rdm));
15639566063dSJacob Faibussowitsch   PetscCall(DMPlexStratify(rdm));
156470dc2cbdSMatthew G. Knepley   PetscTryTypeMethod(tr, ordersupports, dm, rdm);
1565f7b6882eSMatthew G. Knepley   PetscCall(PetscLogEventEnd(DMPLEXTRANSFORM_SetCones, tr, dm, 0, 0));
15663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1567012bc364SMatthew G. Knepley }
1568012bc364SMatthew G. Knepley 
DMPlexTransformGetConeOriented(DMPlexTransform tr,PetscInt q,PetscInt po,const PetscInt * cone[],const PetscInt * ornt[])1569d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformGetConeOriented(DMPlexTransform tr, PetscInt q, PetscInt po, const PetscInt *cone[], const PetscInt *ornt[])
1570d71ae5a4SJacob Faibussowitsch {
1571012bc364SMatthew G. Knepley   DM              dm;
1572012bc364SMatthew G. Knepley   DMPolytopeType  ct, qct;
1573012bc364SMatthew G. Knepley   DMPolytopeType *rct;
1574012bc364SMatthew G. Knepley   PetscInt       *rsize, *rcone, *rornt, *qcone, *qornt;
1575012bc364SMatthew G. Knepley   PetscInt        maxConeSize = 0, Nct, p, r, n, nr, coff = 0, ooff = 0;
1576012bc364SMatthew G. Knepley 
1577012bc364SMatthew G. Knepley   PetscFunctionBegin;
1578012bc364SMatthew G. Knepley   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
15794f572ea9SToby Isaac   PetscAssertPointer(cone, 4);
15804f572ea9SToby Isaac   PetscAssertPointer(ornt, 5);
1581012bc364SMatthew G. Knepley   for (p = 0; p < DM_NUM_POLYTOPES; ++p) maxConeSize = PetscMax(maxConeSize, DMPolytopeTypeGetConeSize((DMPolytopeType)p));
15829566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformGetDM(tr, &dm));
15839566063dSJacob Faibussowitsch   PetscCall(DMGetWorkArray(dm, maxConeSize, MPIU_INT, &qcone));
15849566063dSJacob Faibussowitsch   PetscCall(DMGetWorkArray(dm, maxConeSize, MPIU_INT, &qornt));
15859566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformGetSourcePoint(tr, q, &ct, &qct, &p, &r));
15869566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformCellTransform(tr, ct, p, NULL, &Nct, &rct, &rsize, &rcone, &rornt));
1587012bc364SMatthew G. Knepley   for (n = 0; n < Nct; ++n) {
1588012bc364SMatthew G. Knepley     const DMPolytopeType ctNew    = rct[n];
1589012bc364SMatthew G. Knepley     const PetscInt       csizeNew = DMPolytopeTypeGetConeSize(ctNew);
1590012bc364SMatthew G. Knepley     PetscInt             Nr       = rsize[n], fn, c;
1591012bc364SMatthew G. Knepley 
1592012bc364SMatthew G. Knepley     if (ctNew == qct) Nr = r;
1593012bc364SMatthew G. Knepley     for (nr = 0; nr < Nr; ++nr) {
1594012bc364SMatthew G. Knepley       for (c = 0; c < csizeNew; ++c) {
1595012bc364SMatthew G. Knepley         ++coff;             /* Cell type of new cone point */
1596012bc364SMatthew G. Knepley         fn = rcone[coff++]; /* Number of cones of p that need to be taken when producing new cone point */
1597012bc364SMatthew G. Knepley         coff += fn;
1598012bc364SMatthew G. Knepley         ++coff; /* Replica number of new cone point */
1599012bc364SMatthew G. Knepley         ++ooff; /* Orientation of new cone point */
1600012bc364SMatthew G. Knepley       }
1601012bc364SMatthew G. Knepley     }
1602012bc364SMatthew G. Knepley     if (ctNew == qct) break;
1603012bc364SMatthew G. Knepley   }
16049566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformGetCone_Internal(tr, p, po, ct, qct, rcone, &coff, rornt, &ooff, qcone, qornt));
1605012bc364SMatthew G. Knepley   *cone = qcone;
1606012bc364SMatthew G. Knepley   *ornt = qornt;
16073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1608012bc364SMatthew G. Knepley }
1609012bc364SMatthew G. Knepley 
DMPlexTransformGetCone(DMPlexTransform tr,PetscInt q,const PetscInt * cone[],const PetscInt * ornt[])1610d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformGetCone(DMPlexTransform tr, PetscInt q, const PetscInt *cone[], const PetscInt *ornt[])
1611d71ae5a4SJacob Faibussowitsch {
1612012bc364SMatthew G. Knepley   DM              dm;
1613012bc364SMatthew G. Knepley   DMPolytopeType  ct, qct;
1614012bc364SMatthew G. Knepley   DMPolytopeType *rct;
1615012bc364SMatthew G. Knepley   PetscInt       *rsize, *rcone, *rornt, *qcone, *qornt;
1616012bc364SMatthew G. Knepley   PetscInt        maxConeSize = 0, Nct, p, r, n, nr, coff = 0, ooff = 0;
1617012bc364SMatthew G. Knepley 
1618012bc364SMatthew G. Knepley   PetscFunctionBegin;
1619012bc364SMatthew G. Knepley   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
16204f572ea9SToby Isaac   if (cone) PetscAssertPointer(cone, 3);
16214f572ea9SToby Isaac   if (ornt) PetscAssertPointer(ornt, 4);
1622012bc364SMatthew G. Knepley   for (p = 0; p < DM_NUM_POLYTOPES; ++p) maxConeSize = PetscMax(maxConeSize, DMPolytopeTypeGetConeSize((DMPolytopeType)p));
16239566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformGetDM(tr, &dm));
16249566063dSJacob Faibussowitsch   PetscCall(DMGetWorkArray(dm, maxConeSize, MPIU_INT, &qcone));
16259566063dSJacob Faibussowitsch   PetscCall(DMGetWorkArray(dm, maxConeSize, MPIU_INT, &qornt));
16269566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformGetSourcePoint(tr, q, &ct, &qct, &p, &r));
16279566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformCellTransform(tr, ct, p, NULL, &Nct, &rct, &rsize, &rcone, &rornt));
1628012bc364SMatthew G. Knepley   for (n = 0; n < Nct; ++n) {
1629012bc364SMatthew G. Knepley     const DMPolytopeType ctNew    = rct[n];
1630012bc364SMatthew G. Knepley     const PetscInt       csizeNew = DMPolytopeTypeGetConeSize(ctNew);
1631012bc364SMatthew G. Knepley     PetscInt             Nr       = rsize[n], fn, c;
1632012bc364SMatthew G. Knepley 
1633012bc364SMatthew G. Knepley     if (ctNew == qct) Nr = r;
1634012bc364SMatthew G. Knepley     for (nr = 0; nr < Nr; ++nr) {
1635012bc364SMatthew G. Knepley       for (c = 0; c < csizeNew; ++c) {
1636012bc364SMatthew G. Knepley         ++coff;             /* Cell type of new cone point */
1637012bc364SMatthew G. Knepley         fn = rcone[coff++]; /* Number of cones of p that need to be taken when producing new cone point */
1638012bc364SMatthew G. Knepley         coff += fn;
1639012bc364SMatthew G. Knepley         ++coff; /* Replica number of new cone point */
1640012bc364SMatthew G. Knepley         ++ooff; /* Orientation of new cone point */
1641012bc364SMatthew G. Knepley       }
1642012bc364SMatthew G. Knepley     }
1643012bc364SMatthew G. Knepley     if (ctNew == qct) break;
1644012bc364SMatthew G. Knepley   }
16459566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformGetCone_Internal(tr, p, 0, ct, qct, rcone, &coff, rornt, &ooff, qcone, qornt));
16469f4ada15SMatthew G. Knepley   if (cone) *cone = qcone;
16479f4ada15SMatthew G. Knepley   else PetscCall(DMRestoreWorkArray(dm, maxConeSize, MPIU_INT, &qcone));
16489f4ada15SMatthew G. Knepley   if (ornt) *ornt = qornt;
16499f4ada15SMatthew G. Knepley   else PetscCall(DMRestoreWorkArray(dm, maxConeSize, MPIU_INT, &qornt));
16503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1651012bc364SMatthew G. Knepley }
1652012bc364SMatthew G. Knepley 
DMPlexTransformRestoreCone(DMPlexTransform tr,PetscInt q,const PetscInt * cone[],const PetscInt * ornt[])1653d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformRestoreCone(DMPlexTransform tr, PetscInt q, const PetscInt *cone[], const PetscInt *ornt[])
1654d71ae5a4SJacob Faibussowitsch {
1655012bc364SMatthew G. Knepley   DM dm;
1656012bc364SMatthew G. Knepley 
1657012bc364SMatthew G. Knepley   PetscFunctionBegin;
1658012bc364SMatthew G. Knepley   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
16599566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformGetDM(tr, &dm));
16609f4ada15SMatthew G. Knepley   if (cone) PetscCall(DMRestoreWorkArray(dm, 0, MPIU_INT, cone));
16619f4ada15SMatthew G. Knepley   if (ornt) PetscCall(DMRestoreWorkArray(dm, 0, MPIU_INT, ornt));
16623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1663012bc364SMatthew G. Knepley }
1664012bc364SMatthew G. Knepley 
DMPlexTransformCreateCellVertices_Internal(DMPlexTransform tr)1665d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMPlexTransformCreateCellVertices_Internal(DMPlexTransform tr)
1666d71ae5a4SJacob Faibussowitsch {
1667012bc364SMatthew G. Knepley   PetscInt ict;
1668012bc364SMatthew G. Knepley 
1669012bc364SMatthew G. Knepley   PetscFunctionBegin;
16709566063dSJacob Faibussowitsch   PetscCall(PetscCalloc3(DM_NUM_POLYTOPES, &tr->trNv, DM_NUM_POLYTOPES, &tr->trVerts, DM_NUM_POLYTOPES, &tr->trSubVerts));
1671012bc364SMatthew G. Knepley   for (ict = DM_POLYTOPE_POINT; ict < DM_NUM_POLYTOPES; ++ict) {
1672012bc364SMatthew G. Knepley     const DMPolytopeType ct = (DMPolytopeType)ict;
1673012bc364SMatthew G. Knepley     DMPlexTransform      reftr;
1674012bc364SMatthew G. Knepley     DM                   refdm, trdm;
1675012bc364SMatthew G. Knepley     Vec                  coordinates;
1676012bc364SMatthew G. Knepley     const PetscScalar   *coords;
1677012bc364SMatthew G. Knepley     DMPolytopeType      *rct;
1678012bc364SMatthew G. Knepley     PetscInt            *rsize, *rcone, *rornt;
1679bf3df06dSJunchao Zhang     PetscInt             Nct, n, r, pNew = 0;
16802d30e087SMatthew G. Knepley     PetscInt             trdim, vStart, vEnd, Nc;
1681012bc364SMatthew G. Knepley     const PetscInt       debug = 0;
1682012bc364SMatthew G. Knepley     const char          *typeName;
1683012bc364SMatthew G. Knepley 
1684012bc364SMatthew G. Knepley     /* Since points are 0-dimensional, coordinates make no sense */
1685476787b7SMatthew G. Knepley     if (DMPolytopeTypeGetDim(ct) <= 0 || ct == DM_POLYTOPE_UNKNOWN_CELL || ct == DM_POLYTOPE_UNKNOWN_FACE) continue;
16869566063dSJacob Faibussowitsch     PetscCall(DMPlexCreateReferenceCell(PETSC_COMM_SELF, ct, &refdm));
16879566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformCreate(PETSC_COMM_SELF, &reftr));
16889566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformSetDM(reftr, refdm));
16899566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformGetType(tr, &typeName));
16909566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformSetType(reftr, typeName));
16919566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformSetUp(reftr));
16929566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformApply(reftr, refdm, &trdm));
1693012bc364SMatthew G. Knepley 
16942d30e087SMatthew G. Knepley     PetscCall(DMGetDimension(trdm, &trdim));
16959566063dSJacob Faibussowitsch     PetscCall(DMPlexGetDepthStratum(trdm, 0, &vStart, &vEnd));
1696012bc364SMatthew G. Knepley     tr->trNv[ct] = vEnd - vStart;
16979566063dSJacob Faibussowitsch     PetscCall(DMGetCoordinatesLocal(trdm, &coordinates));
16989566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(coordinates, &Nc));
16992d30e087SMatthew G. Knepley     PetscCheck(tr->trNv[ct] * trdim == Nc, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Cell type %s, transformed coordinate size %" PetscInt_FMT " != %" PetscInt_FMT " size of coordinate storage", DMPolytopeTypes[ct], tr->trNv[ct] * trdim, Nc);
17009566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(Nc, &tr->trVerts[ct]));
17019566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(coordinates, &coords));
17029566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(tr->trVerts[ct], coords, Nc));
17039566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(coordinates, &coords));
1704012bc364SMatthew G. Knepley 
17059566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(DM_NUM_POLYTOPES, &tr->trSubVerts[ct]));
17069566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformCellTransform(reftr, ct, 0, NULL, &Nct, &rct, &rsize, &rcone, &rornt));
1707012bc364SMatthew G. Knepley     for (n = 0; n < Nct; ++n) {
1708012bc364SMatthew G. Knepley       /* Since points are 0-dimensional, coordinates make no sense */
1709012bc364SMatthew G. Knepley       if (rct[n] == DM_POLYTOPE_POINT) continue;
17109566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(rsize[n], &tr->trSubVerts[ct][rct[n]]));
1711012bc364SMatthew G. Knepley       for (r = 0; r < rsize[n]; ++r) {
1712012bc364SMatthew G. Knepley         PetscInt *closure = NULL;
1713012bc364SMatthew G. Knepley         PetscInt  clSize, cl, Nv = 0;
1714012bc364SMatthew G. Knepley 
17159566063dSJacob Faibussowitsch         PetscCall(PetscCalloc1(DMPolytopeTypeGetNumVertices(rct[n]), &tr->trSubVerts[ct][rct[n]][r]));
17169566063dSJacob Faibussowitsch         PetscCall(DMPlexTransformGetTargetPoint(reftr, ct, rct[n], 0, r, &pNew));
17179566063dSJacob Faibussowitsch         PetscCall(DMPlexGetTransitiveClosure(trdm, pNew, PETSC_TRUE, &clSize, &closure));
1718012bc364SMatthew G. Knepley         for (cl = 0; cl < clSize * 2; cl += 2) {
1719012bc364SMatthew G. Knepley           const PetscInt sv = closure[cl];
1720012bc364SMatthew G. Knepley 
1721012bc364SMatthew G. Knepley           if ((sv >= vStart) && (sv < vEnd)) tr->trSubVerts[ct][rct[n]][r][Nv++] = sv - vStart;
1722012bc364SMatthew G. Knepley         }
17239566063dSJacob Faibussowitsch         PetscCall(DMPlexRestoreTransitiveClosure(trdm, pNew, PETSC_TRUE, &clSize, &closure));
172463a3b9bcSJacob Faibussowitsch         PetscCheck(Nv == DMPolytopeTypeGetNumVertices(rct[n]), PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of vertices %" PetscInt_FMT " != %" PetscInt_FMT " for %s subcell %" PetscInt_FMT " from cell %s", Nv, DMPolytopeTypeGetNumVertices(rct[n]), DMPolytopeTypes[rct[n]], r, DMPolytopeTypes[ct]);
1725012bc364SMatthew G. Knepley       }
1726012bc364SMatthew G. Knepley     }
1727012bc364SMatthew G. Knepley     if (debug) {
1728012bc364SMatthew G. Knepley       DMPolytopeType *rct;
1729012bc364SMatthew G. Knepley       PetscInt       *rsize, *rcone, *rornt;
17302d30e087SMatthew G. Knepley       PetscInt        v, dE = trdim, d, off = 0;
1731012bc364SMatthew G. Knepley 
173263a3b9bcSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_SELF, "%s: %" PetscInt_FMT " vertices\n", DMPolytopeTypes[ct], tr->trNv[ct]));
1733012bc364SMatthew G. Knepley       for (v = 0; v < tr->trNv[ct]; ++v) {
17349566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_SELF, "  "));
173563a3b9bcSJacob Faibussowitsch         for (d = 0; d < dE; ++d) PetscCall(PetscPrintf(PETSC_COMM_SELF, "%g ", (double)PetscRealPart(tr->trVerts[ct][off++])));
17369566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_SELF, "\n"));
1737012bc364SMatthew G. Knepley       }
1738012bc364SMatthew G. Knepley 
17399566063dSJacob Faibussowitsch       PetscCall(DMPlexTransformCellTransform(reftr, ct, 0, NULL, &Nct, &rct, &rsize, &rcone, &rornt));
1740012bc364SMatthew G. Knepley       for (n = 0; n < Nct; ++n) {
1741012bc364SMatthew G. Knepley         if (rct[n] == DM_POLYTOPE_POINT) continue;
174263a3b9bcSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_SELF, "%s: %s subvertices %" PetscInt_FMT "\n", DMPolytopeTypes[ct], DMPolytopeTypes[rct[n]], tr->trNv[ct]));
1743012bc364SMatthew G. Knepley         for (r = 0; r < rsize[n]; ++r) {
17449566063dSJacob Faibussowitsch           PetscCall(PetscPrintf(PETSC_COMM_SELF, "  "));
174548a46eb9SPierre Jolivet           for (v = 0; v < DMPolytopeTypeGetNumVertices(rct[n]); ++v) PetscCall(PetscPrintf(PETSC_COMM_SELF, "%" PetscInt_FMT " ", tr->trSubVerts[ct][rct[n]][r][v]));
17469566063dSJacob Faibussowitsch           PetscCall(PetscPrintf(PETSC_COMM_SELF, "\n"));
1747012bc364SMatthew G. Knepley         }
1748012bc364SMatthew G. Knepley       }
1749012bc364SMatthew G. Knepley     }
17509566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&refdm));
17519566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&trdm));
17529566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformDestroy(&reftr));
1753012bc364SMatthew G. Knepley   }
17543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1755012bc364SMatthew G. Knepley }
1756012bc364SMatthew G. Knepley 
175720f4b53cSBarry Smith /*@C
1758012bc364SMatthew G. Knepley   DMPlexTransformGetCellVertices - Get the set of transformed vertices lying in the closure of a reference cell of given type
1759012bc364SMatthew G. Knepley 
1760012bc364SMatthew G. Knepley   Input Parameters:
176120f4b53cSBarry Smith + tr - The `DMPlexTransform` object
1762012bc364SMatthew G. Knepley - ct - The cell type
1763012bc364SMatthew G. Knepley 
1764012bc364SMatthew G. Knepley   Output Parameters:
1765012bc364SMatthew G. Knepley + Nv      - The number of transformed vertices in the closure of the reference cell of given type
1766012bc364SMatthew G. Knepley - trVerts - The coordinates of these vertices in the reference cell
1767012bc364SMatthew G. Knepley 
1768012bc364SMatthew G. Knepley   Level: developer
1769012bc364SMatthew G. Knepley 
177020f4b53cSBarry Smith .seealso: `DMPLEX`, `DMPlexTransform`, `DMPolytopeType`, `DMPlexTransformGetSubcellVertices()`
177120f4b53cSBarry Smith @*/
DMPlexTransformGetCellVertices(DMPlexTransform tr,DMPolytopeType ct,PetscInt * Nv,PetscScalar * trVerts[])1772d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformGetCellVertices(DMPlexTransform tr, DMPolytopeType ct, PetscInt *Nv, PetscScalar *trVerts[])
1773d71ae5a4SJacob Faibussowitsch {
1774012bc364SMatthew G. Knepley   PetscFunctionBegin;
17759566063dSJacob Faibussowitsch   if (!tr->trNv) PetscCall(DMPlexTransformCreateCellVertices_Internal(tr));
1776012bc364SMatthew G. Knepley   if (Nv) *Nv = tr->trNv[ct];
1777012bc364SMatthew G. Knepley   if (trVerts) *trVerts = tr->trVerts[ct];
17783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1779012bc364SMatthew G. Knepley }
1780012bc364SMatthew G. Knepley 
178120f4b53cSBarry Smith /*@C
1782012bc364SMatthew G. Knepley   DMPlexTransformGetSubcellVertices - Get the set of transformed vertices defining a subcell in the reference cell of given type
1783012bc364SMatthew G. Knepley 
1784012bc364SMatthew G. Knepley   Input Parameters:
178520f4b53cSBarry Smith + tr  - The `DMPlexTransform` object
1786012bc364SMatthew G. Knepley . ct  - The cell type
1787012bc364SMatthew G. Knepley . rct - The subcell type
1788012bc364SMatthew G. Knepley - r   - The subcell index
1789012bc364SMatthew G. Knepley 
1790012bc364SMatthew G. Knepley   Output Parameter:
179120f4b53cSBarry Smith . subVerts - The indices of these vertices in the set of vertices returned by `DMPlexTransformGetCellVertices()`
1792012bc364SMatthew G. Knepley 
1793012bc364SMatthew G. Knepley   Level: developer
1794012bc364SMatthew G. Knepley 
179520f4b53cSBarry Smith .seealso: `DMPLEX`, `DMPlexTransform`, `DMPolytopeType`, `DMPlexTransformGetCellVertices()`
179620f4b53cSBarry Smith @*/
DMPlexTransformGetSubcellVertices(DMPlexTransform tr,DMPolytopeType ct,DMPolytopeType rct,PetscInt r,PetscInt * subVerts[])1797d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformGetSubcellVertices(DMPlexTransform tr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *subVerts[])
1798d71ae5a4SJacob Faibussowitsch {
1799012bc364SMatthew G. Knepley   PetscFunctionBegin;
18009566063dSJacob Faibussowitsch   if (!tr->trNv) PetscCall(DMPlexTransformCreateCellVertices_Internal(tr));
180108401ef6SPierre Jolivet   PetscCheck(tr->trSubVerts[ct][rct], PetscObjectComm((PetscObject)tr), PETSC_ERR_ARG_WRONG, "Cell type %s does not produce %s", DMPolytopeTypes[ct], DMPolytopeTypes[rct]);
1802012bc364SMatthew G. Knepley   if (subVerts) *subVerts = tr->trSubVerts[ct][rct][r];
18033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1804012bc364SMatthew G. Knepley }
1805012bc364SMatthew G. Knepley 
1806012bc364SMatthew G. Knepley /* Computes new vertex as the barycenter, or centroid */
DMPlexTransformMapCoordinatesBarycenter_Internal(DMPlexTransform tr,DMPolytopeType pct,DMPolytopeType ct,PetscInt p,PetscInt r,PetscInt Nv,PetscInt dE,const PetscScalar in[],PetscScalar out[])1807d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformMapCoordinatesBarycenter_Internal(DMPlexTransform tr, DMPolytopeType pct, DMPolytopeType ct, PetscInt p, PetscInt r, PetscInt Nv, PetscInt dE, const PetscScalar in[], PetscScalar out[])
1808d71ae5a4SJacob Faibussowitsch {
1809012bc364SMatthew G. Knepley   PetscInt v, d;
1810012bc364SMatthew G. Knepley 
1811012bc364SMatthew G. Knepley   PetscFunctionBeginHot;
181208401ef6SPierre Jolivet   PetscCheck(ct == DM_POLYTOPE_POINT, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not for refined point type %s", DMPolytopeTypes[ct]);
1813012bc364SMatthew G. Knepley   for (d = 0; d < dE; ++d) out[d] = 0.0;
18149371c9d4SSatish Balay   for (v = 0; v < Nv; ++v)
18159371c9d4SSatish Balay     for (d = 0; d < dE; ++d) out[d] += in[v * dE + d];
1816012bc364SMatthew G. Knepley   for (d = 0; d < dE; ++d) out[d] /= Nv;
18173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1818012bc364SMatthew G. Knepley }
1819012bc364SMatthew G. Knepley 
1820012bc364SMatthew G. Knepley /*@
1821f1a722f8SMatthew G. Knepley   DMPlexTransformMapCoordinates - Calculate new coordinates for produced points
1822f1a722f8SMatthew G. Knepley 
1823f1a722f8SMatthew G. Knepley   Not collective
1824f1a722f8SMatthew G. Knepley 
1825012bc364SMatthew G. Knepley   Input Parameters:
1826a1cb98faSBarry Smith + tr  - The `DMPlexTransform`
1827012bc364SMatthew G. Knepley . pct - The cell type of the parent, from whom the new cell is being produced
1828012bc364SMatthew G. Knepley . ct  - The type being produced
1829d410b0cfSMatthew G. Knepley . p   - The original point
1830012bc364SMatthew G. Knepley . r   - The replica number requested for the produced cell type
1831012bc364SMatthew G. Knepley . Nv  - Number of vertices in the closure of the parent cell
1832012bc364SMatthew G. Knepley . dE  - Spatial dimension
1833012bc364SMatthew G. Knepley - in  - array of size Nv*dE, holding coordinates of the vertices in the closure of the parent cell
1834012bc364SMatthew G. Knepley 
1835f1a722f8SMatthew G. Knepley   Output Parameter:
1836012bc364SMatthew G. Knepley . out - The coordinates of the new vertices
1837a375dbeeSPatrick Sanan 
1838a375dbeeSPatrick Sanan   Level: intermediate
1839f1a722f8SMatthew G. Knepley 
184060225df5SJacob Faibussowitsch .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPolytopeType`, `DMPlexTransformApply()`
1841012bc364SMatthew G. Knepley @*/
DMPlexTransformMapCoordinates(DMPlexTransform tr,DMPolytopeType pct,DMPolytopeType ct,PetscInt p,PetscInt r,PetscInt Nv,PetscInt dE,const PetscScalar in[],PetscScalar out[])1842d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformMapCoordinates(DMPlexTransform tr, DMPolytopeType pct, DMPolytopeType ct, PetscInt p, PetscInt r, PetscInt Nv, PetscInt dE, const PetscScalar in[], PetscScalar out[])
1843d71ae5a4SJacob Faibussowitsch {
1844012bc364SMatthew G. Knepley   PetscFunctionBeginHot;
18452b6f951bSStefano Zampini   if (Nv) PetscUseTypeMethod(tr, mapcoordinates, pct, ct, p, r, Nv, dE, in, out);
18463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1847012bc364SMatthew G. Knepley }
1848012bc364SMatthew G. Knepley 
1849533617b7SMatthew G. Knepley /*
1850533617b7SMatthew G. Knepley   DMPlexTransformLabelProducedPoint_Private - Label a produced point based on its parent label
1851533617b7SMatthew G. Knepley 
1852533617b7SMatthew G. Knepley   Not Collective
1853533617b7SMatthew G. Knepley 
1854533617b7SMatthew G. Knepley   Input Parameters:
1855533617b7SMatthew G. Knepley + tr    - The `DMPlexTransform`
1856533617b7SMatthew G. Knepley . label - The label in the transformed mesh
1857533617b7SMatthew G. Knepley . pp    - The parent point in the original mesh
1858533617b7SMatthew G. Knepley . pct   - The cell type of the parent point
1859533617b7SMatthew G. Knepley . p     - The point in the transformed mesh
1860533617b7SMatthew G. Knepley . ct    - The cell type of the point
1861533617b7SMatthew G. Knepley . r     - The replica number of the point
1862533617b7SMatthew G. Knepley - val   - The label value of the parent point
1863533617b7SMatthew G. Knepley 
1864533617b7SMatthew G. Knepley   Level: developer
1865533617b7SMatthew G. Knepley 
1866533617b7SMatthew G. Knepley .seealso: `DMPlexTransformCreateLabels()`, `RefineLabel_Internal()`
1867533617b7SMatthew G. Knepley */
DMPlexTransformLabelProducedPoint_Private(DMPlexTransform tr,DMLabel label,PetscInt pp,DMPolytopeType pct,PetscInt p,DMPolytopeType ct,PetscInt r,PetscInt val)1868533617b7SMatthew G. Knepley static PetscErrorCode DMPlexTransformLabelProducedPoint_Private(DMPlexTransform tr, DMLabel label, PetscInt pp, DMPolytopeType pct, PetscInt p, DMPolytopeType ct, PetscInt r, PetscInt val)
1869533617b7SMatthew G. Knepley {
1870533617b7SMatthew G. Knepley   PetscFunctionBeginHot;
1871533617b7SMatthew G. Knepley   if (tr->labelMatchStrata && pct != ct) PetscFunctionReturn(PETSC_SUCCESS);
1872533617b7SMatthew G. Knepley   PetscCall(DMLabelSetValue(label, p, val + tr->labelReplicaInc * r));
1873533617b7SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
1874533617b7SMatthew G. Knepley }
1875533617b7SMatthew G. Knepley 
RefineLabel_Internal(DMPlexTransform tr,DMLabel label,DMLabel labelNew)1876d71ae5a4SJacob Faibussowitsch static PetscErrorCode RefineLabel_Internal(DMPlexTransform tr, DMLabel label, DMLabel labelNew)
1877d71ae5a4SJacob Faibussowitsch {
1878012bc364SMatthew G. Knepley   DM              dm;
1879012bc364SMatthew G. Knepley   IS              valueIS;
1880012bc364SMatthew G. Knepley   const PetscInt *values;
1881012bc364SMatthew G. Knepley   PetscInt        defVal, Nv, val;
1882012bc364SMatthew G. Knepley 
1883012bc364SMatthew G. Knepley   PetscFunctionBegin;
18849566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformGetDM(tr, &dm));
18859566063dSJacob Faibussowitsch   PetscCall(DMLabelGetDefaultValue(label, &defVal));
18869566063dSJacob Faibussowitsch   PetscCall(DMLabelSetDefaultValue(labelNew, defVal));
18879566063dSJacob Faibussowitsch   PetscCall(DMLabelGetValueIS(label, &valueIS));
18889566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(valueIS, &Nv));
18899566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(valueIS, &values));
1890012bc364SMatthew G. Knepley   for (val = 0; val < Nv; ++val) {
1891012bc364SMatthew G. Knepley     IS              pointIS;
1892012bc364SMatthew G. Knepley     const PetscInt *points;
1893012bc364SMatthew G. Knepley     PetscInt        numPoints, p;
1894012bc364SMatthew G. Knepley 
1895012bc364SMatthew G. Knepley     /* Ensure refined label is created with same number of strata as
1896012bc364SMatthew G. Knepley      * original (even if no entries here). */
18979566063dSJacob Faibussowitsch     PetscCall(DMLabelAddStratum(labelNew, values[val]));
18989566063dSJacob Faibussowitsch     PetscCall(DMLabelGetStratumIS(label, values[val], &pointIS));
18999566063dSJacob Faibussowitsch     PetscCall(ISGetLocalSize(pointIS, &numPoints));
19009566063dSJacob Faibussowitsch     PetscCall(ISGetIndices(pointIS, &points));
1901012bc364SMatthew G. Knepley     for (p = 0; p < numPoints; ++p) {
1902012bc364SMatthew G. Knepley       const PetscInt  point = points[p];
1903012bc364SMatthew G. Knepley       DMPolytopeType  ct;
1904012bc364SMatthew G. Knepley       DMPolytopeType *rct;
1905012bc364SMatthew G. Knepley       PetscInt       *rsize, *rcone, *rornt;
1906012bc364SMatthew G. Knepley       PetscInt        Nct, n, r, pNew = 0;
1907012bc364SMatthew G. Knepley 
19089566063dSJacob Faibussowitsch       PetscCall(DMPlexGetCellType(dm, point, &ct));
19099566063dSJacob Faibussowitsch       PetscCall(DMPlexTransformCellTransform(tr, ct, point, NULL, &Nct, &rct, &rsize, &rcone, &rornt));
1910012bc364SMatthew G. Knepley       for (n = 0; n < Nct; ++n) {
1911012bc364SMatthew G. Knepley         for (r = 0; r < rsize[n]; ++r) {
19129566063dSJacob Faibussowitsch           PetscCall(DMPlexTransformGetTargetPoint(tr, ct, rct[n], point, r, &pNew));
1913533617b7SMatthew G. Knepley           PetscCall(DMPlexTransformLabelProducedPoint_Private(tr, labelNew, point, ct, pNew, rct[n], r, values[val]));
1914012bc364SMatthew G. Knepley         }
1915012bc364SMatthew G. Knepley       }
1916012bc364SMatthew G. Knepley     }
19179566063dSJacob Faibussowitsch     PetscCall(ISRestoreIndices(pointIS, &points));
19189566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&pointIS));
1919012bc364SMatthew G. Knepley   }
19209566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(valueIS, &values));
19219566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&valueIS));
19223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1923012bc364SMatthew G. Knepley }
1924012bc364SMatthew G. Knepley 
DMPlexTransformCreateLabels(DMPlexTransform tr,DM rdm)1925d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMPlexTransformCreateLabels(DMPlexTransform tr, DM rdm)
1926d71ae5a4SJacob Faibussowitsch {
1927012bc364SMatthew G. Knepley   DM       dm;
1928012bc364SMatthew G. Knepley   PetscInt numLabels, l;
1929012bc364SMatthew G. Knepley 
1930012bc364SMatthew G. Knepley   PetscFunctionBegin;
19319566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformGetDM(tr, &dm));
1932f7b6882eSMatthew G. Knepley   PetscCall(PetscLogEventBegin(DMPLEXTRANSFORM_CreateLabels, tr, dm, 0, 0));
19339566063dSJacob Faibussowitsch   PetscCall(DMGetNumLabels(dm, &numLabels));
1934012bc364SMatthew G. Knepley   for (l = 0; l < numLabels; ++l) {
1935012bc364SMatthew G. Knepley     DMLabel     label, labelNew;
1936012bc364SMatthew G. Knepley     const char *lname;
1937012bc364SMatthew G. Knepley     PetscBool   isDepth, isCellType;
1938012bc364SMatthew G. Knepley 
19399566063dSJacob Faibussowitsch     PetscCall(DMGetLabelName(dm, l, &lname));
19409566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(lname, "depth", &isDepth));
1941012bc364SMatthew G. Knepley     if (isDepth) continue;
19429566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(lname, "celltype", &isCellType));
1943012bc364SMatthew G. Knepley     if (isCellType) continue;
19449566063dSJacob Faibussowitsch     PetscCall(DMCreateLabel(rdm, lname));
19459566063dSJacob Faibussowitsch     PetscCall(DMGetLabel(dm, lname, &label));
19469566063dSJacob Faibussowitsch     PetscCall(DMGetLabel(rdm, lname, &labelNew));
19479566063dSJacob Faibussowitsch     PetscCall(RefineLabel_Internal(tr, label, labelNew));
1948012bc364SMatthew G. Knepley   }
1949f7b6882eSMatthew G. Knepley   PetscCall(PetscLogEventEnd(DMPLEXTRANSFORM_CreateLabels, tr, dm, 0, 0));
19503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1951012bc364SMatthew G. Knepley }
1952012bc364SMatthew G. Knepley 
1953012bc364SMatthew G. Knepley /* This refines the labels which define regions for fields and DSes since they are not in the list of labels for the DM */
DMPlexTransformCreateDiscLabels(DMPlexTransform tr,DM rdm)1954d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformCreateDiscLabels(DMPlexTransform tr, DM rdm)
1955d71ae5a4SJacob Faibussowitsch {
1956012bc364SMatthew G. Knepley   DM       dm;
1957012bc364SMatthew G. Knepley   PetscInt Nf, f, Nds, s;
1958012bc364SMatthew G. Knepley 
1959012bc364SMatthew G. Knepley   PetscFunctionBegin;
19609566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformGetDM(tr, &dm));
19619566063dSJacob Faibussowitsch   PetscCall(DMGetNumFields(dm, &Nf));
1962012bc364SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
1963012bc364SMatthew G. Knepley     DMLabel     label, labelNew;
1964012bc364SMatthew G. Knepley     PetscObject obj;
1965012bc364SMatthew G. Knepley     const char *lname;
1966012bc364SMatthew G. Knepley 
19679566063dSJacob Faibussowitsch     PetscCall(DMGetField(rdm, f, &label, &obj));
1968012bc364SMatthew G. Knepley     if (!label) continue;
19699566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)label, &lname));
19709566063dSJacob Faibussowitsch     PetscCall(DMLabelCreate(PETSC_COMM_SELF, lname, &labelNew));
19719566063dSJacob Faibussowitsch     PetscCall(RefineLabel_Internal(tr, label, labelNew));
19729566063dSJacob Faibussowitsch     PetscCall(DMSetField_Internal(rdm, f, labelNew, obj));
19739566063dSJacob Faibussowitsch     PetscCall(DMLabelDestroy(&labelNew));
1974012bc364SMatthew G. Knepley   }
19759566063dSJacob Faibussowitsch   PetscCall(DMGetNumDS(dm, &Nds));
1976012bc364SMatthew G. Knepley   for (s = 0; s < Nds; ++s) {
1977012bc364SMatthew G. Knepley     DMLabel     label, labelNew;
1978012bc364SMatthew G. Knepley     const char *lname;
1979012bc364SMatthew G. Knepley 
198007218a29SMatthew G. Knepley     PetscCall(DMGetRegionNumDS(rdm, s, &label, NULL, NULL, NULL));
1981012bc364SMatthew G. Knepley     if (!label) continue;
19829566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)label, &lname));
19839566063dSJacob Faibussowitsch     PetscCall(DMLabelCreate(PETSC_COMM_SELF, lname, &labelNew));
19849566063dSJacob Faibussowitsch     PetscCall(RefineLabel_Internal(tr, label, labelNew));
198507218a29SMatthew G. Knepley     PetscCall(DMSetRegionNumDS(rdm, s, labelNew, NULL, NULL, NULL));
19869566063dSJacob Faibussowitsch     PetscCall(DMLabelDestroy(&labelNew));
1987012bc364SMatthew G. Knepley   }
19883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1989012bc364SMatthew G. Knepley }
1990012bc364SMatthew G. Knepley 
DMPlexTransformCreateSF(DMPlexTransform tr,DM rdm)1991d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMPlexTransformCreateSF(DMPlexTransform tr, DM rdm)
1992d71ae5a4SJacob Faibussowitsch {
1993012bc364SMatthew G. Knepley   DM                 dm;
1994012bc364SMatthew G. Knepley   PetscSF            sf, sfNew;
1995012bc364SMatthew G. Knepley   PetscInt           numRoots, numLeaves, numLeavesNew = 0, l, m;
1996012bc364SMatthew G. Knepley   const PetscInt    *localPoints;
1997012bc364SMatthew G. Knepley   const PetscSFNode *remotePoints;
1998012bc364SMatthew G. Knepley   PetscInt          *localPointsNew;
1999012bc364SMatthew G. Knepley   PetscSFNode       *remotePointsNew;
2000012bc364SMatthew G. Knepley   PetscInt           pStartNew, pEndNew, pNew;
2001012bc364SMatthew G. Knepley   /* Brute force algorithm */
2002012bc364SMatthew G. Knepley   PetscSF         rsf;
2003012bc364SMatthew G. Knepley   PetscSection    s;
2004012bc364SMatthew G. Knepley   const PetscInt *rootdegree;
2005012bc364SMatthew G. Knepley   PetscInt       *rootPointsNew, *remoteOffsets;
2006012bc364SMatthew G. Knepley   PetscInt        numPointsNew, pStart, pEnd, p;
2007012bc364SMatthew G. Knepley 
2008012bc364SMatthew G. Knepley   PetscFunctionBegin;
20099566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformGetDM(tr, &dm));
2010f7b6882eSMatthew G. Knepley   PetscCall(PetscLogEventBegin(DMPLEXTRANSFORM_CreateSF, tr, dm, 0, 0));
20119566063dSJacob Faibussowitsch   PetscCall(DMPlexGetChart(rdm, &pStartNew, &pEndNew));
20129566063dSJacob Faibussowitsch   PetscCall(DMGetPointSF(dm, &sf));
20139566063dSJacob Faibussowitsch   PetscCall(DMGetPointSF(rdm, &sfNew));
2014012bc364SMatthew G. Knepley   /* Calculate size of new SF */
20159566063dSJacob Faibussowitsch   PetscCall(PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints));
201676f6662bSZach Atkins   if (numRoots < 0) {
201776f6662bSZach Atkins     PetscCall(PetscLogEventEnd(DMPLEXTRANSFORM_CreateSF, tr, dm, 0, 0));
201876f6662bSZach Atkins     PetscFunctionReturn(PETSC_SUCCESS);
201976f6662bSZach Atkins   }
2020012bc364SMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
2021012bc364SMatthew G. Knepley     const PetscInt  p = localPoints[l];
2022012bc364SMatthew G. Knepley     DMPolytopeType  ct;
2023012bc364SMatthew G. Knepley     DMPolytopeType *rct;
2024012bc364SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
2025012bc364SMatthew G. Knepley     PetscInt        Nct, n;
2026012bc364SMatthew G. Knepley 
20279566063dSJacob Faibussowitsch     PetscCall(DMPlexGetCellType(dm, p, &ct));
20289566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformCellTransform(tr, ct, p, NULL, &Nct, &rct, &rsize, &rcone, &rornt));
2029ad540459SPierre Jolivet     for (n = 0; n < Nct; ++n) numLeavesNew += rsize[n];
2030012bc364SMatthew G. Knepley   }
2031012bc364SMatthew G. Knepley   /* Send new root point numbers
2032012bc364SMatthew G. Knepley        It is possible to optimize for regular transforms by sending only the cell type offsets, but it seems a needless complication
2033012bc364SMatthew G. Knepley   */
20349566063dSJacob Faibussowitsch   PetscCall(DMPlexGetChart(dm, &pStart, &pEnd));
20359566063dSJacob Faibussowitsch   PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)dm), &s));
20369566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetChart(s, pStart, pEnd));
2037012bc364SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
2038012bc364SMatthew G. Knepley     DMPolytopeType  ct;
2039012bc364SMatthew G. Knepley     DMPolytopeType *rct;
2040012bc364SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
2041012bc364SMatthew G. Knepley     PetscInt        Nct, n;
2042012bc364SMatthew G. Knepley 
20439566063dSJacob Faibussowitsch     PetscCall(DMPlexGetCellType(dm, p, &ct));
20449566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformCellTransform(tr, ct, p, NULL, &Nct, &rct, &rsize, &rcone, &rornt));
204548a46eb9SPierre Jolivet     for (n = 0; n < Nct; ++n) PetscCall(PetscSectionAddDof(s, p, rsize[n]));
2046012bc364SMatthew G. Knepley   }
20479566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetUp(s));
20489566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetStorageSize(s, &numPointsNew));
20499566063dSJacob Faibussowitsch   PetscCall(PetscSFCreateRemoteOffsets(sf, s, s, &remoteOffsets));
20509566063dSJacob Faibussowitsch   PetscCall(PetscSFCreateSectionSF(sf, s, remoteOffsets, s, &rsf));
20519566063dSJacob Faibussowitsch   PetscCall(PetscFree(remoteOffsets));
20529566063dSJacob Faibussowitsch   PetscCall(PetscSFComputeDegreeBegin(sf, &rootdegree));
20539566063dSJacob Faibussowitsch   PetscCall(PetscSFComputeDegreeEnd(sf, &rootdegree));
20549566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(numPointsNew, &rootPointsNew));
2055012bc364SMatthew G. Knepley   for (p = 0; p < numPointsNew; ++p) rootPointsNew[p] = -1;
2056012bc364SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
2057012bc364SMatthew G. Knepley     DMPolytopeType  ct;
2058012bc364SMatthew G. Knepley     DMPolytopeType *rct;
2059012bc364SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
2060012bc364SMatthew G. Knepley     PetscInt        Nct, n, r, off;
2061012bc364SMatthew G. Knepley 
2062012bc364SMatthew G. Knepley     if (!rootdegree[p - pStart]) continue;
20639566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetOffset(s, p, &off));
20649566063dSJacob Faibussowitsch     PetscCall(DMPlexGetCellType(dm, p, &ct));
20659566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformCellTransform(tr, ct, p, NULL, &Nct, &rct, &rsize, &rcone, &rornt));
2066012bc364SMatthew G. Knepley     for (n = 0, m = 0; n < Nct; ++n) {
2067012bc364SMatthew G. Knepley       for (r = 0; r < rsize[n]; ++r, ++m) {
20689566063dSJacob Faibussowitsch         PetscCall(DMPlexTransformGetTargetPoint(tr, ct, rct[n], p, r, &pNew));
2069012bc364SMatthew G. Knepley         rootPointsNew[off + m] = pNew;
2070012bc364SMatthew G. Knepley       }
2071012bc364SMatthew G. Knepley     }
2072012bc364SMatthew G. Knepley   }
20739566063dSJacob Faibussowitsch   PetscCall(PetscSFBcastBegin(rsf, MPIU_INT, rootPointsNew, rootPointsNew, MPI_REPLACE));
20749566063dSJacob Faibussowitsch   PetscCall(PetscSFBcastEnd(rsf, MPIU_INT, rootPointsNew, rootPointsNew, MPI_REPLACE));
20759566063dSJacob Faibussowitsch   PetscCall(PetscSFDestroy(&rsf));
20769566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(numLeavesNew, &localPointsNew));
20779566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(numLeavesNew, &remotePointsNew));
2078012bc364SMatthew G. Knepley   for (l = 0, m = 0; l < numLeaves; ++l) {
2079012bc364SMatthew G. Knepley     const PetscInt  p = localPoints[l];
2080012bc364SMatthew G. Knepley     DMPolytopeType  ct;
2081012bc364SMatthew G. Knepley     DMPolytopeType *rct;
2082012bc364SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
2083012bc364SMatthew G. Knepley     PetscInt        Nct, n, r, q, off;
2084012bc364SMatthew G. Knepley 
20859566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetOffset(s, p, &off));
20869566063dSJacob Faibussowitsch     PetscCall(DMPlexGetCellType(dm, p, &ct));
20879566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformCellTransform(tr, ct, p, NULL, &Nct, &rct, &rsize, &rcone, &rornt));
2088012bc364SMatthew G. Knepley     for (n = 0, q = 0; n < Nct; ++n) {
2089012bc364SMatthew G. Knepley       for (r = 0; r < rsize[n]; ++r, ++m, ++q) {
20909566063dSJacob Faibussowitsch         PetscCall(DMPlexTransformGetTargetPoint(tr, ct, rct[n], p, r, &pNew));
2091012bc364SMatthew G. Knepley         localPointsNew[m]        = pNew;
2092012bc364SMatthew G. Knepley         remotePointsNew[m].index = rootPointsNew[off + q];
2093012bc364SMatthew G. Knepley         remotePointsNew[m].rank  = remotePoints[l].rank;
2094012bc364SMatthew G. Knepley       }
2095012bc364SMatthew G. Knepley     }
2096012bc364SMatthew G. Knepley   }
20979566063dSJacob Faibussowitsch   PetscCall(PetscSectionDestroy(&s));
20989566063dSJacob Faibussowitsch   PetscCall(PetscFree(rootPointsNew));
2099012bc364SMatthew G. Knepley   /* SF needs sorted leaves to correctly calculate Gather */
2100012bc364SMatthew G. Knepley   {
2101012bc364SMatthew G. Knepley     PetscSFNode *rp, *rtmp;
2102012bc364SMatthew G. Knepley     PetscInt    *lp, *idx, *ltmp, i;
2103012bc364SMatthew G. Knepley 
21049566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(numLeavesNew, &idx));
21059566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(numLeavesNew, &lp));
21069566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(numLeavesNew, &rp));
2107012bc364SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
210863a3b9bcSJacob Faibussowitsch       PetscCheck(!(localPointsNew[i] < pStartNew) && !(localPointsNew[i] >= pEndNew), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Local SF point %" PetscInt_FMT " (%" PetscInt_FMT ") not in [%" PetscInt_FMT ", %" PetscInt_FMT ")", localPointsNew[i], i, pStartNew, pEndNew);
2109012bc364SMatthew G. Knepley       idx[i] = i;
2110012bc364SMatthew G. Knepley     }
21119566063dSJacob Faibussowitsch     PetscCall(PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx));
2112012bc364SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
2113012bc364SMatthew G. Knepley       lp[i] = localPointsNew[idx[i]];
2114012bc364SMatthew G. Knepley       rp[i] = remotePointsNew[idx[i]];
2115012bc364SMatthew G. Knepley     }
2116012bc364SMatthew G. Knepley     ltmp            = localPointsNew;
2117012bc364SMatthew G. Knepley     localPointsNew  = lp;
2118012bc364SMatthew G. Knepley     rtmp            = remotePointsNew;
2119012bc364SMatthew G. Knepley     remotePointsNew = rp;
21209566063dSJacob Faibussowitsch     PetscCall(PetscFree(idx));
21219566063dSJacob Faibussowitsch     PetscCall(PetscFree(ltmp));
21229566063dSJacob Faibussowitsch     PetscCall(PetscFree(rtmp));
2123012bc364SMatthew G. Knepley   }
21249566063dSJacob Faibussowitsch   PetscCall(PetscSFSetGraph(sfNew, pEndNew - pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER));
2125f7b6882eSMatthew G. Knepley   PetscCall(PetscLogEventEnd(DMPLEXTRANSFORM_CreateSF, tr, dm, 0, 0));
21263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2127012bc364SMatthew G. Knepley }
2128012bc364SMatthew G. Knepley 
2129a4e35b19SJacob Faibussowitsch /*
2130a4e35b19SJacob Faibussowitsch   DMPlexCellRefinerMapLocalizedCoordinates - Given a cell of `DMPolytopeType` `ct` with localized coordinates `x`, generate localized coordinates `xr` for subcell `r` of type `rct`.
2131012bc364SMatthew G. Knepley 
213220f4b53cSBarry Smith   Not Collective
2133012bc364SMatthew G. Knepley 
2134012bc364SMatthew G. Knepley   Input Parameters:
213520f4b53cSBarry Smith + tr  - The `DMPlexTransform`
2136012bc364SMatthew G. Knepley . ct  - The type of the parent cell
2137012bc364SMatthew G. Knepley . rct - The type of the produced cell
2138012bc364SMatthew G. Knepley . r   - The index of the produced cell
2139012bc364SMatthew G. Knepley - x   - The localized coordinates for the parent cell
2140012bc364SMatthew G. Knepley 
2141012bc364SMatthew G. Knepley   Output Parameter:
2142012bc364SMatthew G. Knepley . xr  - The localized coordinates for the produced cell
2143012bc364SMatthew G. Knepley 
2144012bc364SMatthew G. Knepley   Level: developer
2145012bc364SMatthew G. Knepley 
21461cc06b55SBarry Smith .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPolytopeType`, `DMPlexCellRefinerSetCoordinates()`
2147a4e35b19SJacob Faibussowitsch */
DMPlexTransformMapLocalizedCoordinates(DMPlexTransform tr,DMPolytopeType ct,DMPolytopeType rct,PetscInt r,const PetscScalar x[],PetscScalar xr[])2148d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMPlexTransformMapLocalizedCoordinates(DMPlexTransform tr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, const PetscScalar x[], PetscScalar xr[])
2149d71ae5a4SJacob Faibussowitsch {
2150012bc364SMatthew G. Knepley   PetscFE  fe = NULL;
2151012bc364SMatthew G. Knepley   PetscInt cdim, v, *subcellV;
2152012bc364SMatthew G. Knepley 
2153012bc364SMatthew G. Knepley   PetscFunctionBegin;
21549566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformGetCoordinateFE(tr, ct, &fe));
21559566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformGetSubcellVertices(tr, ct, rct, r, &subcellV));
21569566063dSJacob Faibussowitsch   PetscCall(PetscFEGetNumComponents(fe, &cdim));
215748a46eb9SPierre Jolivet   for (v = 0; v < DMPolytopeTypeGetNumVertices(rct); ++v) PetscCall(PetscFEInterpolate_Static(fe, x, tr->refGeom[ct], subcellV[v], &xr[v * cdim]));
21583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2159012bc364SMatthew G. Knepley }
2160012bc364SMatthew G. Knepley 
DMPlexTransformSetCoordinates(DMPlexTransform tr,DM rdm)2161d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMPlexTransformSetCoordinates(DMPlexTransform tr, DM rdm)
2162d71ae5a4SJacob Faibussowitsch {
21636858538eSMatthew G. Knepley   DM                 dm, cdm, cdmCell, cdmNew, cdmCellNew;
21646858538eSMatthew G. Knepley   PetscSection       coordSection, coordSectionNew, coordSectionCell, coordSectionCellNew;
21656858538eSMatthew G. Knepley   Vec                coordsLocal, coordsLocalNew, coordsLocalCell = NULL, coordsLocalCellNew;
2166012bc364SMatthew G. Knepley   const PetscScalar *coords;
2167012bc364SMatthew G. Knepley   PetscScalar       *coordsNew;
21684fb89dddSMatthew G. Knepley   const PetscReal   *maxCell, *Lstart, *L;
21696858538eSMatthew G. Knepley   PetscBool          localized, localizeVertices = PETSC_FALSE, localizeCells = PETSC_FALSE;
21706858538eSMatthew G. Knepley   PetscInt           dE, dEo, d, cStart, cEnd, c, cStartNew, cEndNew, vStartNew, vEndNew, v, pStart, pEnd, p;
2171012bc364SMatthew G. Knepley 
2172012bc364SMatthew G. Knepley   PetscFunctionBegin;
217338cc584fSMatthew G. Knepley   // Need to clear the DMField for coordinates
217438cc584fSMatthew G. Knepley   PetscCall(DMSetCoordinateField(rdm, NULL));
21759566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformGetDM(tr, &dm));
2176f7b6882eSMatthew G. Knepley   PetscCall(PetscLogEventBegin(DMPLEXTRANSFORM_SetCoordinates, tr, dm, 0, 0));
21779566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinateDM(dm, &cdm));
21786858538eSMatthew G. Knepley   PetscCall(DMGetCellCoordinateDM(dm, &cdmCell));
21799566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinatesLocalized(dm, &localized));
21804fb89dddSMatthew G. Knepley   PetscCall(DMGetPeriodicity(dm, &maxCell, &Lstart, &L));
21816858538eSMatthew G. Knepley   if (localized) {
21826858538eSMatthew G. Knepley     /* Localize coordinates of new vertices */
21836858538eSMatthew G. Knepley     localizeVertices = PETSC_TRUE;
21846858538eSMatthew G. Knepley     /* If we do not have a mechanism for automatically localizing cell coordinates, we need to compute them explicitly for every divided cell */
21856858538eSMatthew G. Knepley     if (!maxCell) localizeCells = PETSC_TRUE;
2186012bc364SMatthew G. Knepley   }
21879566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinateSection(dm, &coordSection));
21889566063dSJacob Faibussowitsch   PetscCall(PetscSectionGetFieldComponents(coordSection, 0, &dEo));
2189012bc364SMatthew G. Knepley   if (maxCell) {
2190012bc364SMatthew G. Knepley     PetscReal maxCellNew[3];
2191012bc364SMatthew G. Knepley 
2192d410b0cfSMatthew G. Knepley     for (d = 0; d < dEo; ++d) maxCellNew[d] = maxCell[d] / 2.0;
21934fb89dddSMatthew G. Knepley     PetscCall(DMSetPeriodicity(rdm, maxCellNew, Lstart, L));
2194012bc364SMatthew G. Knepley   }
21959566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinateDim(rdm, &dE));
21969566063dSJacob Faibussowitsch   PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)rdm), &coordSectionNew));
21979566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetNumFields(coordSectionNew, 1));
21989566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetFieldComponents(coordSectionNew, 0, dE));
21999566063dSJacob Faibussowitsch   PetscCall(DMPlexGetDepthStratum(rdm, 0, &vStartNew, &vEndNew));
22006858538eSMatthew G. Knepley   PetscCall(PetscSectionSetChart(coordSectionNew, vStartNew, vEndNew));
2201012bc364SMatthew G. Knepley   /* Localization should be inherited */
2202012bc364SMatthew G. Knepley   /*   Stefano calculates parent cells for each new cell for localization */
2203012bc364SMatthew G. Knepley   /*   Localized cells need coordinates of closure */
2204012bc364SMatthew G. Knepley   for (v = vStartNew; v < vEndNew; ++v) {
22059566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetDof(coordSectionNew, v, dE));
22069566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetFieldDof(coordSectionNew, v, 0, dE));
2207012bc364SMatthew G. Knepley   }
22086858538eSMatthew G. Knepley   PetscCall(PetscSectionSetUp(coordSectionNew));
22096858538eSMatthew G. Knepley   PetscCall(DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew));
22106858538eSMatthew G. Knepley 
2211012bc364SMatthew G. Knepley   if (localizeCells) {
22126858538eSMatthew G. Knepley     PetscCall(DMGetCoordinateDM(rdm, &cdmNew));
22136858538eSMatthew G. Knepley     PetscCall(DMClone(cdmNew, &cdmCellNew));
22146858538eSMatthew G. Knepley     PetscCall(DMSetCellCoordinateDM(rdm, cdmCellNew));
22156858538eSMatthew G. Knepley     PetscCall(DMDestroy(&cdmCellNew));
22166858538eSMatthew G. Knepley 
22176858538eSMatthew G. Knepley     PetscCall(PetscSectionCreate(PetscObjectComm((PetscObject)rdm), &coordSectionCellNew));
22186858538eSMatthew G. Knepley     PetscCall(PetscSectionSetNumFields(coordSectionCellNew, 1));
22196858538eSMatthew G. Knepley     PetscCall(PetscSectionSetFieldComponents(coordSectionCellNew, 0, dE));
22206858538eSMatthew G. Knepley     PetscCall(DMPlexGetHeightStratum(rdm, 0, &cStartNew, &cEndNew));
22216858538eSMatthew G. Knepley     PetscCall(PetscSectionSetChart(coordSectionCellNew, cStartNew, cEndNew));
22226858538eSMatthew G. Knepley 
22236858538eSMatthew G. Knepley     PetscCall(DMGetCellCoordinateSection(dm, &coordSectionCell));
22249566063dSJacob Faibussowitsch     PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd));
2225012bc364SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2226012bc364SMatthew G. Knepley       PetscInt dof;
2227012bc364SMatthew G. Knepley 
22286858538eSMatthew G. Knepley       PetscCall(PetscSectionGetDof(coordSectionCell, c, &dof));
2229012bc364SMatthew G. Knepley       if (dof) {
2230012bc364SMatthew G. Knepley         DMPolytopeType  ct;
2231012bc364SMatthew G. Knepley         DMPolytopeType *rct;
2232012bc364SMatthew G. Knepley         PetscInt       *rsize, *rcone, *rornt;
2233012bc364SMatthew G. Knepley         PetscInt        dim, cNew, Nct, n, r;
2234012bc364SMatthew G. Knepley 
22359566063dSJacob Faibussowitsch         PetscCall(DMPlexGetCellType(dm, c, &ct));
2236012bc364SMatthew G. Knepley         dim = DMPolytopeTypeGetDim(ct);
22379566063dSJacob Faibussowitsch         PetscCall(DMPlexTransformCellTransform(tr, ct, c, NULL, &Nct, &rct, &rsize, &rcone, &rornt));
2238012bc364SMatthew G. Knepley         /* This allows for different cell types */
2239012bc364SMatthew G. Knepley         for (n = 0; n < Nct; ++n) {
2240012bc364SMatthew G. Knepley           if (dim != DMPolytopeTypeGetDim(rct[n])) continue;
2241012bc364SMatthew G. Knepley           for (r = 0; r < rsize[n]; ++r) {
2242012bc364SMatthew G. Knepley             PetscInt *closure = NULL;
2243012bc364SMatthew G. Knepley             PetscInt  clSize, cl, Nv = 0;
2244012bc364SMatthew G. Knepley 
22459566063dSJacob Faibussowitsch             PetscCall(DMPlexTransformGetTargetPoint(tr, ct, rct[n], c, r, &cNew));
22469566063dSJacob Faibussowitsch             PetscCall(DMPlexGetTransitiveClosure(rdm, cNew, PETSC_TRUE, &clSize, &closure));
22479371c9d4SSatish Balay             for (cl = 0; cl < clSize * 2; cl += 2) {
22489371c9d4SSatish Balay               if ((closure[cl] >= vStartNew) && (closure[cl] < vEndNew)) ++Nv;
22499371c9d4SSatish Balay             }
22509566063dSJacob Faibussowitsch             PetscCall(DMPlexRestoreTransitiveClosure(rdm, cNew, PETSC_TRUE, &clSize, &closure));
22516858538eSMatthew G. Knepley             PetscCall(PetscSectionSetDof(coordSectionCellNew, cNew, Nv * dE));
22526858538eSMatthew G. Knepley             PetscCall(PetscSectionSetFieldDof(coordSectionCellNew, cNew, 0, Nv * dE));
2253012bc364SMatthew G. Knepley           }
2254012bc364SMatthew G. Knepley         }
2255012bc364SMatthew G. Knepley       }
2256012bc364SMatthew G. Knepley     }
22576858538eSMatthew G. Knepley     PetscCall(PetscSectionSetUp(coordSectionCellNew));
22586858538eSMatthew G. Knepley     PetscCall(DMSetCellCoordinateSection(rdm, PETSC_DETERMINE, coordSectionCellNew));
2259012bc364SMatthew G. Knepley   }
22609566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(dm, NULL, "-coarse_dm_view"));
2261012bc364SMatthew G. Knepley   {
2262012bc364SMatthew G. Knepley     VecType     vtype;
2263012bc364SMatthew G. Knepley     PetscInt    coordSizeNew, bs;
2264012bc364SMatthew G. Knepley     const char *name;
2265012bc364SMatthew G. Knepley 
22669566063dSJacob Faibussowitsch     PetscCall(DMGetCoordinatesLocal(dm, &coordsLocal));
22679566063dSJacob Faibussowitsch     PetscCall(VecCreate(PETSC_COMM_SELF, &coordsLocalNew));
22689566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew));
22699566063dSJacob Faibussowitsch     PetscCall(VecSetSizes(coordsLocalNew, coordSizeNew, PETSC_DETERMINE));
22709566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)coordsLocal, &name));
22719566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetName((PetscObject)coordsLocalNew, name));
22729566063dSJacob Faibussowitsch     PetscCall(VecGetBlockSize(coordsLocal, &bs));
22739566063dSJacob Faibussowitsch     PetscCall(VecSetBlockSize(coordsLocalNew, dEo == dE ? bs : dE));
22749566063dSJacob Faibussowitsch     PetscCall(VecGetType(coordsLocal, &vtype));
22759566063dSJacob Faibussowitsch     PetscCall(VecSetType(coordsLocalNew, vtype));
2276012bc364SMatthew G. Knepley   }
22779566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(coordsLocal, &coords));
22789566063dSJacob Faibussowitsch   PetscCall(VecGetArray(coordsLocalNew, &coordsNew));
22799566063dSJacob Faibussowitsch   PetscCall(DMPlexGetChart(dm, &pStart, &pEnd));
2280012bc364SMatthew G. Knepley   /* First set coordinates for vertices */
2281012bc364SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
2282012bc364SMatthew G. Knepley     DMPolytopeType  ct;
2283012bc364SMatthew G. Knepley     DMPolytopeType *rct;
2284012bc364SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
2285012bc364SMatthew G. Knepley     PetscInt        Nct, n, r;
22866858538eSMatthew G. Knepley     PetscBool       hasVertex = PETSC_FALSE;
2287012bc364SMatthew G. Knepley 
22889566063dSJacob Faibussowitsch     PetscCall(DMPlexGetCellType(dm, p, &ct));
22899566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformCellTransform(tr, ct, p, NULL, &Nct, &rct, &rsize, &rcone, &rornt));
2290012bc364SMatthew G. Knepley     for (n = 0; n < Nct; ++n) {
22919371c9d4SSatish Balay       if (rct[n] == DM_POLYTOPE_POINT) {
22929371c9d4SSatish Balay         hasVertex = PETSC_TRUE;
22939371c9d4SSatish Balay         break;
22949371c9d4SSatish Balay       }
2295012bc364SMatthew G. Knepley     }
2296012bc364SMatthew G. Knepley     if (hasVertex) {
2297012bc364SMatthew G. Knepley       const PetscScalar *icoords = NULL;
22986858538eSMatthew G. Knepley       const PetscScalar *array   = NULL;
2299012bc364SMatthew G. Knepley       PetscScalar       *pcoords = NULL;
23006858538eSMatthew G. Knepley       PetscBool          isDG;
2301012bc364SMatthew G. Knepley       PetscInt           Nc, Nv, v, d;
2302012bc364SMatthew G. Knepley 
23036858538eSMatthew G. Knepley       PetscCall(DMPlexGetCellCoordinates(dm, p, &isDG, &Nc, &array, &pcoords));
2304012bc364SMatthew G. Knepley 
2305012bc364SMatthew G. Knepley       icoords = pcoords;
2306d410b0cfSMatthew G. Knepley       Nv      = Nc / dEo;
2307012bc364SMatthew G. Knepley       if (ct != DM_POLYTOPE_POINT) {
23086858538eSMatthew G. Knepley         if (localizeVertices && maxCell) {
2309012bc364SMatthew G. Knepley           PetscScalar anchor[3];
2310012bc364SMatthew G. Knepley 
2311d410b0cfSMatthew G. Knepley           for (d = 0; d < dEo; ++d) anchor[d] = pcoords[d];
23129566063dSJacob Faibussowitsch           for (v = 0; v < Nv; ++v) PetscCall(DMLocalizeCoordinate_Internal(dm, dEo, anchor, &pcoords[v * dEo], &pcoords[v * dEo]));
2313012bc364SMatthew G. Knepley         }
2314012bc364SMatthew G. Knepley       }
2315012bc364SMatthew G. Knepley       for (n = 0; n < Nct; ++n) {
2316012bc364SMatthew G. Knepley         if (rct[n] != DM_POLYTOPE_POINT) continue;
2317012bc364SMatthew G. Knepley         for (r = 0; r < rsize[n]; ++r) {
2318012bc364SMatthew G. Knepley           PetscScalar vcoords[3];
2319012bc364SMatthew G. Knepley           PetscInt    vNew, off;
2320012bc364SMatthew G. Knepley 
23219566063dSJacob Faibussowitsch           PetscCall(DMPlexTransformGetTargetPoint(tr, ct, rct[n], p, r, &vNew));
23229566063dSJacob Faibussowitsch           PetscCall(PetscSectionGetOffset(coordSectionNew, vNew, &off));
23239566063dSJacob Faibussowitsch           PetscCall(DMPlexTransformMapCoordinates(tr, ct, rct[n], p, r, Nv, dEo, icoords, vcoords));
23247625649eSMatthew G. Knepley           PetscCall(DMSnapToGeomModel(dm, p, dE, vcoords, &coordsNew[off]));
2325012bc364SMatthew G. Knepley         }
2326012bc364SMatthew G. Knepley       }
23276858538eSMatthew G. Knepley       PetscCall(DMPlexRestoreCellCoordinates(dm, p, &isDG, &Nc, &array, &pcoords));
2328012bc364SMatthew G. Knepley     }
2329012bc364SMatthew G. Knepley   }
23306858538eSMatthew G. Knepley   PetscCall(VecRestoreArrayRead(coordsLocal, &coords));
23316858538eSMatthew G. Knepley   PetscCall(VecRestoreArray(coordsLocalNew, &coordsNew));
23326858538eSMatthew G. Knepley   PetscCall(DMSetCoordinatesLocal(rdm, coordsLocalNew));
23336858538eSMatthew G. Knepley   PetscCall(VecDestroy(&coordsLocalNew));
23346858538eSMatthew G. Knepley   PetscCall(PetscSectionDestroy(&coordSectionNew));
2335012bc364SMatthew G. Knepley   /* Then set coordinates for cells by localizing */
23366858538eSMatthew G. Knepley   if (!localizeCells) PetscCall(DMLocalizeCoordinates(rdm));
23376858538eSMatthew G. Knepley   else {
23386858538eSMatthew G. Knepley     VecType     vtype;
23396858538eSMatthew G. Knepley     PetscInt    coordSizeNew, bs;
23406858538eSMatthew G. Knepley     const char *name;
23416858538eSMatthew G. Knepley 
23426858538eSMatthew G. Knepley     PetscCall(DMGetCellCoordinatesLocal(dm, &coordsLocalCell));
23436858538eSMatthew G. Knepley     PetscCall(VecCreate(PETSC_COMM_SELF, &coordsLocalCellNew));
23446858538eSMatthew G. Knepley     PetscCall(PetscSectionGetStorageSize(coordSectionCellNew, &coordSizeNew));
23456858538eSMatthew G. Knepley     PetscCall(VecSetSizes(coordsLocalCellNew, coordSizeNew, PETSC_DETERMINE));
23466858538eSMatthew G. Knepley     PetscCall(PetscObjectGetName((PetscObject)coordsLocalCell, &name));
23476858538eSMatthew G. Knepley     PetscCall(PetscObjectSetName((PetscObject)coordsLocalCellNew, name));
23486858538eSMatthew G. Knepley     PetscCall(VecGetBlockSize(coordsLocalCell, &bs));
23496858538eSMatthew G. Knepley     PetscCall(VecSetBlockSize(coordsLocalCellNew, dEo == dE ? bs : dE));
23506858538eSMatthew G. Knepley     PetscCall(VecGetType(coordsLocalCell, &vtype));
23516858538eSMatthew G. Knepley     PetscCall(VecSetType(coordsLocalCellNew, vtype));
23526858538eSMatthew G. Knepley     PetscCall(VecGetArrayRead(coordsLocalCell, &coords));
23536858538eSMatthew G. Knepley     PetscCall(VecGetArray(coordsLocalCellNew, &coordsNew));
23546858538eSMatthew G. Knepley 
2355012bc364SMatthew G. Knepley     for (p = pStart; p < pEnd; ++p) {
2356012bc364SMatthew G. Knepley       DMPolytopeType  ct;
2357012bc364SMatthew G. Knepley       DMPolytopeType *rct;
2358012bc364SMatthew G. Knepley       PetscInt       *rsize, *rcone, *rornt;
23596858538eSMatthew G. Knepley       PetscInt        dof = 0, Nct, n, r;
2360012bc364SMatthew G. Knepley 
23619566063dSJacob Faibussowitsch       PetscCall(DMPlexGetCellType(dm, p, &ct));
23629566063dSJacob Faibussowitsch       PetscCall(DMPlexTransformCellTransform(tr, ct, p, NULL, &Nct, &rct, &rsize, &rcone, &rornt));
23636858538eSMatthew G. Knepley       if (p >= cStart && p < cEnd) PetscCall(PetscSectionGetDof(coordSectionCell, p, &dof));
23646858538eSMatthew G. Knepley       if (dof) {
2365012bc364SMatthew G. Knepley         const PetscScalar *pcoords;
2366012bc364SMatthew G. Knepley 
23676858538eSMatthew G. Knepley         PetscCall(DMPlexPointLocalRead(cdmCell, p, coords, &pcoords));
2368012bc364SMatthew G. Knepley         for (n = 0; n < Nct; ++n) {
2369012bc364SMatthew G. Knepley           const PetscInt Nr = rsize[n];
2370012bc364SMatthew G. Knepley 
2371012bc364SMatthew G. Knepley           if (DMPolytopeTypeGetDim(ct) != DMPolytopeTypeGetDim(rct[n])) continue;
2372012bc364SMatthew G. Knepley           for (r = 0; r < Nr; ++r) {
2373012bc364SMatthew G. Knepley             PetscInt pNew, offNew;
2374012bc364SMatthew G. Knepley 
2375012bc364SMatthew G. Knepley             /* It looks like Stefano and Lisandro are allowing localized coordinates without defining the periodic boundary, which means that
2376012bc364SMatthew G. Knepley                DMLocalizeCoordinate_Internal() will not work. Localized coordinates will have to have obtained by the affine map of the larger
2377012bc364SMatthew G. Knepley                cell to the ones it produces. */
23789566063dSJacob Faibussowitsch             PetscCall(DMPlexTransformGetTargetPoint(tr, ct, rct[n], p, r, &pNew));
23796858538eSMatthew G. Knepley             PetscCall(PetscSectionGetOffset(coordSectionCellNew, pNew, &offNew));
23809566063dSJacob Faibussowitsch             PetscCall(DMPlexTransformMapLocalizedCoordinates(tr, ct, rct[n], r, pcoords, &coordsNew[offNew]));
2381012bc364SMatthew G. Knepley           }
2382012bc364SMatthew G. Knepley         }
2383012bc364SMatthew G. Knepley       }
2384012bc364SMatthew G. Knepley     }
23856858538eSMatthew G. Knepley     PetscCall(VecRestoreArrayRead(coordsLocalCell, &coords));
23866858538eSMatthew G. Knepley     PetscCall(VecRestoreArray(coordsLocalCellNew, &coordsNew));
23876858538eSMatthew G. Knepley     PetscCall(DMSetCellCoordinatesLocal(rdm, coordsLocalCellNew));
23886858538eSMatthew G. Knepley     PetscCall(VecDestroy(&coordsLocalCellNew));
23896858538eSMatthew G. Knepley     PetscCall(PetscSectionDestroy(&coordSectionCellNew));
23906858538eSMatthew G. Knepley   }
2391f7b6882eSMatthew G. Knepley   PetscCall(PetscLogEventEnd(DMPLEXTRANSFORM_SetCoordinates, tr, dm, 0, 0));
23923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2393012bc364SMatthew G. Knepley }
2394012bc364SMatthew G. Knepley 
2395c369401fSMatthew G. Knepley /*@
2396c369401fSMatthew G. Knepley   DMPlexTransformApply - Execute the transformation, producing another `DM`
2397c369401fSMatthew G. Knepley 
2398c369401fSMatthew G. Knepley   Collective
2399c369401fSMatthew G. Knepley 
2400c369401fSMatthew G. Knepley   Input Parameters:
2401c369401fSMatthew G. Knepley + tr - The `DMPlexTransform` object
2402c369401fSMatthew G. Knepley - dm - The original `DM`
2403c369401fSMatthew G. Knepley 
2404c369401fSMatthew G. Knepley   Output Parameter:
2405*81ee147aSBarry Smith . trdm - The transformed `DM`
2406c369401fSMatthew G. Knepley 
2407c369401fSMatthew G. Knepley   Level: intermediate
2408c369401fSMatthew G. Knepley 
2409e0b93839SMatthew G. Knepley   Options Database Keys:
2410e0b93839SMatthew G. Knepley + -dm_plex_transform_label_match_strata      - Only label points of the same stratum as the producing point
2411e0b93839SMatthew G. Knepley . -dm_plex_transform_label_replica_inc <num> - Increment for the label value to be multiplied by the replica number
2412e0b93839SMatthew G. Knepley - -dm_plex_transform_active <name>           - Name for active mesh label
2413e0b93839SMatthew G. Knepley 
2414c369401fSMatthew G. Knepley .seealso: [](plex_transform_table), [](ch_unstructured), `DM`, `DMPLEX`, `DMPlexTransform`, `DMPlexTransformCreate()`, `DMPlexTransformSetDM()`
2415c369401fSMatthew G. Knepley @*/
DMPlexTransformApply(DMPlexTransform tr,DM dm,DM * trdm)2416*81ee147aSBarry Smith PetscErrorCode DMPlexTransformApply(DMPlexTransform tr, DM dm, DM *trdm)
2417d71ae5a4SJacob Faibussowitsch {
2418012bc364SMatthew G. Knepley   DM                     rdm;
2419012bc364SMatthew G. Knepley   DMPlexInterpolatedFlag interp;
24209f4ada15SMatthew G. Knepley   PetscInt               pStart, pEnd;
2421012bc364SMatthew G. Knepley 
2422012bc364SMatthew G. Knepley   PetscFunctionBegin;
2423012bc364SMatthew G. Knepley   PetscValidHeaderSpecific(tr, DMPLEXTRANSFORM_CLASSID, 1);
2424012bc364SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
2425*81ee147aSBarry Smith   PetscAssertPointer(trdm, 3);
2426f7b6882eSMatthew G. Knepley   PetscCall(PetscLogEventBegin(DMPLEXTRANSFORM_Apply, tr, dm, 0, 0));
24279566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformSetDM(tr, dm));
2428012bc364SMatthew G. Knepley 
24299566063dSJacob Faibussowitsch   PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), &rdm));
24309566063dSJacob Faibussowitsch   PetscCall(DMSetType(rdm, DMPLEX));
24319566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformSetDimensions(tr, dm, rdm));
2432012bc364SMatthew G. Knepley   /* Calculate number of new points of each depth */
243355ead5e2SVaclav Hapla   PetscCall(DMPlexIsInterpolatedCollective(dm, &interp));
243408401ef6SPierre Jolivet   PetscCheck(interp == DMPLEX_INTERPOLATED_FULL, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Mesh must be fully interpolated for regular refinement");
2435012bc364SMatthew G. Knepley   /* Step 1: Set chart */
24369f4ada15SMatthew G. Knepley   PetscCall(DMPlexTransformGetChart(tr, &pStart, &pEnd));
24379f4ada15SMatthew G. Knepley   PetscCall(DMPlexSetChart(rdm, pStart, pEnd));
2438012bc364SMatthew G. Knepley   /* Step 2: Set cone/support sizes (automatically stratifies) */
24399566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformSetConeSizes(tr, rdm));
2440012bc364SMatthew G. Knepley   /* Step 3: Setup refined DM */
24419566063dSJacob Faibussowitsch   PetscCall(DMSetUp(rdm));
2442012bc364SMatthew G. Knepley   /* Step 4: Set cones and supports (automatically symmetrizes) */
24439566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformSetCones(tr, rdm));
2444012bc364SMatthew G. Knepley   /* Step 5: Create pointSF */
24459566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformCreateSF(tr, rdm));
2446012bc364SMatthew G. Knepley   /* Step 6: Create labels */
24479566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformCreateLabels(tr, rdm));
2448012bc364SMatthew G. Knepley   /* Step 7: Set coordinates */
24499566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformSetCoordinates(tr, rdm));
24505de52c6dSVaclav Hapla   PetscCall(DMPlexCopy_Internal(dm, PETSC_TRUE, PETSC_TRUE, rdm));
2451dd4c3f67SMatthew G. Knepley   // If the original DM was configured from options, the transformed DM should be as well
2452dd4c3f67SMatthew G. Knepley   rdm->setfromoptionscalled = dm->setfromoptionscalled;
2453f7b6882eSMatthew G. Knepley   PetscCall(PetscLogEventEnd(DMPLEXTRANSFORM_Apply, tr, dm, 0, 0));
2454*81ee147aSBarry Smith   *trdm = rdm;
24553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2456012bc364SMatthew G. Knepley }
2457012bc364SMatthew G. Knepley 
DMPlexTransformAdaptLabel(DM dm,PETSC_UNUSED Vec metric,DMLabel adaptLabel,PETSC_UNUSED DMLabel rgLabel,DM * rdm)2458d71ae5a4SJacob Faibussowitsch PetscErrorCode DMPlexTransformAdaptLabel(DM dm, PETSC_UNUSED Vec metric, DMLabel adaptLabel, PETSC_UNUSED DMLabel rgLabel, DM *rdm)
2459d71ae5a4SJacob Faibussowitsch {
2460012bc364SMatthew G. Knepley   DMPlexTransform tr;
2461012bc364SMatthew G. Knepley   DM              cdm, rcdm;
2462012bc364SMatthew G. Knepley   const char     *prefix;
246361f058f9SMatthew G. Knepley   PetscBool       save;
2464012bc364SMatthew G. Knepley 
2465012bc364SMatthew G. Knepley   PetscFunctionBegin;
24669566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformCreate(PetscObjectComm((PetscObject)dm), &tr));
2467fd3f191cSMatthew G. Knepley   PetscCall(PetscObjectSetName((PetscObject)tr, "Adapt Label Transform"));
24689566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)dm, &prefix));
24699566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)tr, prefix));
24709566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformSetDM(tr, dm));
24719566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformSetFromOptions(tr));
24723a242f00SMatthew G. Knepley   if (adaptLabel) PetscCall(DMPlexTransformSetActive(tr, adaptLabel));
24739566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformSetUp(tr));
24749566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)tr, NULL, "-dm_plex_transform_view"));
24759566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformApply(tr, dm, rdm));
24769566063dSJacob Faibussowitsch   PetscCall(DMCopyDisc(dm, *rdm));
24779566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinateDM(dm, &cdm));
24789566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinateDM(*rdm, &rcdm));
24799566063dSJacob Faibussowitsch   PetscCall(DMCopyDisc(cdm, rcdm));
24809566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformCreateDiscLabels(tr, *rdm));
24819566063dSJacob Faibussowitsch   PetscCall(DMCopyDisc(dm, *rdm));
248261f058f9SMatthew G. Knepley   PetscCall(DMPlexGetSaveTransform(dm, &save));
248361f058f9SMatthew G. Knepley   if (save) PetscCall(DMPlexSetTransform(*rdm, tr));
24849566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformDestroy(&tr));
2485c0517cd5SMatthew G. Knepley   ((DM_Plex *)(*rdm)->data)->useHashLocation = ((DM_Plex *)dm->data)->useHashLocation;
24863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2487012bc364SMatthew G. Knepley }
2488