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