xref: /petsc/src/dm/impls/plex/plexrefine.c (revision db7814771ca77b190574494e87b584e981451db0)
1af0996ceSBarry Smith #include <petsc/private/dmpleximpl.h>   /*I      "petscdmplex.h"   I*/
2412e9a14SMatthew G. Knepley #include <petsc/private/petscfeimpl.h>  /* For PetscFEInterpolate_Static() */
3012bc364SMatthew G. Knepley 
4012bc364SMatthew G. Knepley #include <petscdmplextransform.h>
575d3a19aSMatthew G. Knepley #include <petscsf.h>
675d3a19aSMatthew G. Knepley 
7963fc26aSMatthew G. Knepley /*@
8963fc26aSMatthew G. Knepley   DMPlexCreateProcessSF - Create an SF which just has process connectivity
9963fc26aSMatthew G. Knepley 
10d083f849SBarry Smith   Collective on dm
11963fc26aSMatthew G. Knepley 
12963fc26aSMatthew G. Knepley   Input Parameters:
13963fc26aSMatthew G. Knepley + dm      - The DM
14963fc26aSMatthew G. Knepley - sfPoint - The PetscSF which encodes point connectivity
15963fc26aSMatthew G. Knepley 
16963fc26aSMatthew G. Knepley   Output Parameters:
17963fc26aSMatthew G. Knepley + processRanks - A list of process neighbors, or NULL
18963fc26aSMatthew G. Knepley - sfProcess    - An SF encoding the process connectivity, or NULL
19963fc26aSMatthew G. Knepley 
20963fc26aSMatthew G. Knepley   Level: developer
21963fc26aSMatthew G. Knepley 
22*db781477SPatrick Sanan .seealso: `PetscSFCreate()`, `DMPlexCreateTwoSidedProcessSF()`
23963fc26aSMatthew G. Knepley @*/
24963fc26aSMatthew G. Knepley PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
2575d3a19aSMatthew G. Knepley {
2675d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
2775d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
2875d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
2975d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
3075d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
3175d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
329852e123SBarry Smith   PetscMPIInt        size;
3375d3a19aSMatthew G. Knepley 
3475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
35963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
36963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2);
37963fc26aSMatthew G. Knepley   if (processRanks) {PetscValidPointer(processRanks, 3);}
38963fc26aSMatthew G. Knepley   if (sfProcess)    {PetscValidPointer(sfProcess, 4);}
399566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size));
409566063dSJacob Faibussowitsch   PetscCall(PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints));
419566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(numLeaves, &ranks));
4275d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
4375d3a19aSMatthew G. Knepley     ranks[l] = remotePoints[l].rank;
4475d3a19aSMatthew G. Knepley   }
459566063dSJacob Faibussowitsch   PetscCall(PetscSortRemoveDupsInt(&numLeaves, ranks));
469566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(numLeaves, &ranksNew));
479566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(numLeaves, &localPointsNew));
489566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(numLeaves, &remotePointsNew));
4975d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
5075d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
5175d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
5275d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
5375d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
5475d3a19aSMatthew G. Knepley   }
559566063dSJacob Faibussowitsch   PetscCall(PetscFree(ranks));
569566063dSJacob Faibussowitsch   if (processRanks) PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks));
579566063dSJacob Faibussowitsch   else              PetscCall(PetscFree(ranksNew));
58963fc26aSMatthew G. Knepley   if (sfProcess) {
599566063dSJacob Faibussowitsch     PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess));
609566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetName((PetscObject) *sfProcess, "Process SF"));
619566063dSJacob Faibussowitsch     PetscCall(PetscSFSetFromOptions(*sfProcess));
629566063dSJacob Faibussowitsch     PetscCall(PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER));
63963fc26aSMatthew G. Knepley   }
6475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
6575d3a19aSMatthew G. Knepley }
6675d3a19aSMatthew G. Knepley 
672389894bSMatthew G. Knepley /*@
682389894bSMatthew G. Knepley   DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data
692389894bSMatthew G. Knepley 
70012bc364SMatthew G. Knepley   Collective on dm
71012bc364SMatthew G. Knepley 
722389894bSMatthew G. Knepley   Input Parameter:
732389894bSMatthew G. Knepley . dm - The coarse DM
742389894bSMatthew G. Knepley 
752389894bSMatthew G. Knepley   Output Parameter:
762389894bSMatthew G. Knepley . fpointIS - The IS of all the fine points which exist in the original coarse mesh
772389894bSMatthew G. Knepley 
782389894bSMatthew G. Knepley   Level: developer
792389894bSMatthew G. Knepley 
80*db781477SPatrick Sanan .seealso: `DMRefine()`, `DMPlexSetRefinementUniform()`, `DMPlexGetSubpointIS()`
812389894bSMatthew G. Knepley @*/
822389894bSMatthew G. Knepley PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS)
832389894bSMatthew G. Knepley {
84012bc364SMatthew G. Knepley   DMPlexTransform tr;
85412e9a14SMatthew G. Knepley   PetscInt       *fpoints;
86327c2912SStefano Zampini   PetscInt        pStart, pEnd, p, vStart, vEnd, v;
872389894bSMatthew G. Knepley 
882389894bSMatthew G. Knepley   PetscFunctionBegin;
899566063dSJacob Faibussowitsch   PetscCall(DMPlexGetChart(dm, &pStart, &pEnd));
909566063dSJacob Faibussowitsch   PetscCall(DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd));
919566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformCreate(PetscObjectComm((PetscObject) dm), &tr));
929566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformSetUp(tr));
939566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(pEnd-pStart, &fpoints));
942389894bSMatthew G. Knepley   for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1;
95412e9a14SMatthew G. Knepley   for (v = vStart; v < vEnd; ++v) {
96012bc364SMatthew G. Knepley     PetscInt vNew = -1; /* quiet overzealous may be used uninitialized check */
97327c2912SStefano Zampini 
989566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformGetTargetPoint(tr, DM_POLYTOPE_POINT, DM_POLYTOPE_POINT, p, 0, &vNew));
99412e9a14SMatthew G. Knepley     fpoints[v-pStart] = vNew;
1002389894bSMatthew G. Knepley   }
1019566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformDestroy(&tr));
1029566063dSJacob Faibussowitsch   PetscCall(ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS));
1032389894bSMatthew G. Knepley   PetscFunctionReturn(0);
1042389894bSMatthew G. Knepley }
1052389894bSMatthew G. Knepley 
106012bc364SMatthew G. Knepley /*@C
107012bc364SMatthew G. Knepley   DMPlexSetTransformType - Set the transform type for uniform refinement
108012bc364SMatthew G. Knepley 
109012bc364SMatthew G. Knepley   Input Parameters:
110012bc364SMatthew G. Knepley + dm - The DM
111012bc364SMatthew G. Knepley - type - The transform type for uniform refinement
112012bc364SMatthew G. Knepley 
113012bc364SMatthew G. Knepley   Level: developer
114012bc364SMatthew G. Knepley 
115*db781477SPatrick Sanan .seealso: `DMPlexTransformType`, `DMRefine()`, `DMPlexGetTransformType()`, `DMPlexSetRefinementUniform()`
116012bc364SMatthew G. Knepley @*/
117012bc364SMatthew G. Knepley PetscErrorCode DMPlexSetTransformType(DM dm, DMPlexTransformType type)
118012bc364SMatthew G. Knepley {
119012bc364SMatthew G. Knepley   DM_Plex        *mesh = (DM_Plex*) dm->data;
120012bc364SMatthew G. Knepley 
121012bc364SMatthew G. Knepley   PetscFunctionBegin;
122012bc364SMatthew G. Knepley   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMPLEX);
123012bc364SMatthew G. Knepley   if (type) PetscValidCharPointer(type, 2);
1249566063dSJacob Faibussowitsch   PetscCall(PetscFree(mesh->transformType));
1259566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(type, &mesh->transformType));
126012bc364SMatthew G. Knepley   PetscFunctionReturn(0);
127012bc364SMatthew G. Knepley }
128012bc364SMatthew G. Knepley 
129012bc364SMatthew G. Knepley /*@C
130012bc364SMatthew G. Knepley   DMPlexGetTransformType - Retrieve the transform type for uniform refinement
131012bc364SMatthew G. Knepley 
132012bc364SMatthew G. Knepley   Input Parameter:
133012bc364SMatthew G. Knepley . dm - The DM
134012bc364SMatthew G. Knepley 
135012bc364SMatthew G. Knepley   Output Parameter:
136012bc364SMatthew G. Knepley . type - The transform type for uniform refinement
137012bc364SMatthew G. Knepley 
138012bc364SMatthew G. Knepley   Level: developer
139012bc364SMatthew G. Knepley 
140*db781477SPatrick Sanan .seealso: `DMPlexTransformType`, `DMRefine()`, `DMPlexSetTransformType()`, `DMPlexGetRefinementUniform()`
141012bc364SMatthew G. Knepley @*/
142012bc364SMatthew G. Knepley PetscErrorCode DMPlexGetTransformType(DM dm, DMPlexTransformType *type)
143012bc364SMatthew G. Knepley {
144012bc364SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
145012bc364SMatthew G. Knepley 
146012bc364SMatthew G. Knepley   PetscFunctionBegin;
147012bc364SMatthew G. Knepley   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMPLEX);
148012bc364SMatthew G. Knepley   PetscValidPointer(type, 2);
149012bc364SMatthew G. Knepley   *type = mesh->transformType;
150012bc364SMatthew G. Knepley   PetscFunctionReturn(0);
151012bc364SMatthew G. Knepley }
152012bc364SMatthew G. Knepley 
1530e2b6761SMatthew G. Knepley /*@
1540e2b6761SMatthew G. Knepley   DMPlexSetRefinementUniform - Set the flag for uniform refinement
1550e2b6761SMatthew G. Knepley 
1560e2b6761SMatthew G. Knepley   Input Parameters:
1570e2b6761SMatthew G. Knepley + dm - The DM
1580e2b6761SMatthew G. Knepley - refinementUniform - The flag for uniform refinement
1590e2b6761SMatthew G. Knepley 
1600e2b6761SMatthew G. Knepley   Level: developer
1610e2b6761SMatthew G. Knepley 
162*db781477SPatrick Sanan .seealso: `DMRefine()`, `DMPlexGetRefinementUniform()`, `DMPlexGetRefinementLimit()`, `DMPlexSetRefinementLimit()`
1630e2b6761SMatthew G. Knepley @*/
16475d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
16575d3a19aSMatthew G. Knepley {
16675d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
16775d3a19aSMatthew G. Knepley 
16875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
169012bc364SMatthew G. Knepley   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMPLEX);
17075d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
17175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
17275d3a19aSMatthew G. Knepley }
17375d3a19aSMatthew G. Knepley 
1740e2b6761SMatthew G. Knepley /*@
1750e2b6761SMatthew G. Knepley   DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement
1760e2b6761SMatthew G. Knepley 
1770e2b6761SMatthew G. Knepley   Input Parameter:
1780e2b6761SMatthew G. Knepley . dm - The DM
1790e2b6761SMatthew G. Knepley 
1800e2b6761SMatthew G. Knepley   Output Parameter:
1810e2b6761SMatthew G. Knepley . refinementUniform - The flag for uniform refinement
1820e2b6761SMatthew G. Knepley 
1830e2b6761SMatthew G. Knepley   Level: developer
1840e2b6761SMatthew G. Knepley 
185*db781477SPatrick Sanan .seealso: `DMRefine()`, `DMPlexSetRefinementUniform()`, `DMPlexGetRefinementLimit()`, `DMPlexSetRefinementLimit()`
1860e2b6761SMatthew G. Knepley @*/
18775d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
18875d3a19aSMatthew G. Knepley {
18975d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
19075d3a19aSMatthew G. Knepley 
19175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
192012bc364SMatthew G. Knepley   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMPLEX);
193dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(refinementUniform,  2);
19475d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
19575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
19675d3a19aSMatthew G. Knepley }
19775d3a19aSMatthew G. Knepley 
1980e2b6761SMatthew G. Knepley /*@
1990e2b6761SMatthew G. Knepley   DMPlexSetRefinementLimit - Set the maximum cell volume for refinement
2000e2b6761SMatthew G. Knepley 
2010e2b6761SMatthew G. Knepley   Input Parameters:
2020e2b6761SMatthew G. Knepley + dm - The DM
2030e2b6761SMatthew G. Knepley - refinementLimit - The maximum cell volume in the refined mesh
2040e2b6761SMatthew G. Knepley 
2050e2b6761SMatthew G. Knepley   Level: developer
2060e2b6761SMatthew G. Knepley 
207*db781477SPatrick Sanan .seealso: `DMRefine()`, `DMPlexGetRefinementLimit()`, `DMPlexGetRefinementUniform()`, `DMPlexSetRefinementUniform()`
2080e2b6761SMatthew G. Knepley @*/
20975d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
21075d3a19aSMatthew G. Knepley {
21175d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
21275d3a19aSMatthew G. Knepley 
21375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
21475d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
21575d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
21675d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
21775d3a19aSMatthew G. Knepley }
21875d3a19aSMatthew G. Knepley 
2190e2b6761SMatthew G. Knepley /*@
2200e2b6761SMatthew G. Knepley   DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement
2210e2b6761SMatthew G. Knepley 
2220e2b6761SMatthew G. Knepley   Input Parameter:
2230e2b6761SMatthew G. Knepley . dm - The DM
2240e2b6761SMatthew G. Knepley 
2250e2b6761SMatthew G. Knepley   Output Parameter:
2260e2b6761SMatthew G. Knepley . refinementLimit - The maximum cell volume in the refined mesh
2270e2b6761SMatthew G. Knepley 
2280e2b6761SMatthew G. Knepley   Level: developer
2290e2b6761SMatthew G. Knepley 
230*db781477SPatrick Sanan .seealso: `DMRefine()`, `DMPlexSetRefinementLimit()`, `DMPlexGetRefinementUniform()`, `DMPlexSetRefinementUniform()`
2310e2b6761SMatthew G. Knepley @*/
23275d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
23375d3a19aSMatthew G. Knepley {
23475d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
23575d3a19aSMatthew G. Knepley 
23675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
23775d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
238dadcf809SJacob Faibussowitsch   PetscValidRealPointer(refinementLimit,  2);
23975d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
24075d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
24175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
24275d3a19aSMatthew G. Knepley }
24375d3a19aSMatthew G. Knepley 
244b28003e6SMatthew G. Knepley /*@
245b28003e6SMatthew G. Knepley   DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement
246b28003e6SMatthew G. Knepley 
247b28003e6SMatthew G. Knepley   Input Parameters:
248b28003e6SMatthew G. Knepley + dm - The DM
249b28003e6SMatthew G. Knepley - refinementFunc - Function giving the maximum cell volume in the refined mesh
250b28003e6SMatthew G. Knepley 
251b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
252b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
253b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
254b28003e6SMatthew G. Knepley 
255b28003e6SMatthew G. Knepley   Level: developer
256b28003e6SMatthew G. Knepley 
257*db781477SPatrick Sanan .seealso: `DMRefine()`, `DMPlexGetRefinementFunction()`, `DMPlexGetRefinementUniform()`, `DMPlexSetRefinementUniform()`, `DMPlexGetRefinementLimit()`, `DMPlexSetRefinementLimit()`
258b28003e6SMatthew G. Knepley @*/
259b28003e6SMatthew G. Knepley PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *))
260b28003e6SMatthew G. Knepley {
261b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
262b28003e6SMatthew G. Knepley 
263b28003e6SMatthew G. Knepley   PetscFunctionBegin;
264b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
265b28003e6SMatthew G. Knepley   mesh->refinementFunc = refinementFunc;
266b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
267b28003e6SMatthew G. Knepley }
268b28003e6SMatthew G. Knepley 
269b28003e6SMatthew G. Knepley /*@
270b28003e6SMatthew G. Knepley   DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement
271b28003e6SMatthew G. Knepley 
272b28003e6SMatthew G. Knepley   Input Parameter:
273b28003e6SMatthew G. Knepley . dm - The DM
274b28003e6SMatthew G. Knepley 
275b28003e6SMatthew G. Knepley   Output Parameter:
276b28003e6SMatthew G. Knepley . refinementFunc - Function giving the maximum cell volume in the refined mesh
277b28003e6SMatthew G. Knepley 
278b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
279b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
280b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
281b28003e6SMatthew G. Knepley 
282b28003e6SMatthew G. Knepley   Level: developer
283b28003e6SMatthew G. Knepley 
284*db781477SPatrick Sanan .seealso: `DMRefine()`, `DMPlexSetRefinementFunction()`, `DMPlexGetRefinementUniform()`, `DMPlexSetRefinementUniform()`, `DMPlexGetRefinementLimit()`, `DMPlexSetRefinementLimit()`
285b28003e6SMatthew G. Knepley @*/
286b28003e6SMatthew G. Knepley PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *))
287b28003e6SMatthew G. Knepley {
288b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
289b28003e6SMatthew G. Knepley 
290b28003e6SMatthew G. Knepley   PetscFunctionBegin;
291b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
292b28003e6SMatthew G. Knepley   PetscValidPointer(refinementFunc,  2);
293b28003e6SMatthew G. Knepley   *refinementFunc = mesh->refinementFunc;
294b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
295b28003e6SMatthew G. Knepley }
296b28003e6SMatthew G. Knepley 
297012bc364SMatthew G. Knepley PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *rdm)
2980d1cd5e0SMatthew G. Knepley {
299492b8470SStefano Zampini   PetscBool      isUniform;
3000d1cd5e0SMatthew G. Knepley 
3010d1cd5e0SMatthew G. Knepley   PetscFunctionBegin;
3029566063dSJacob Faibussowitsch   PetscCall(DMPlexGetRefinementUniform(dm, &isUniform));
3039566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(dm, NULL, "-initref_dm_view"));
3040d1cd5e0SMatthew G. Knepley   if (isUniform) {
305012bc364SMatthew G. Knepley     DMPlexTransform     tr;
30651a74b61SMatthew G. Knepley     DM                  cdm, rcdm;
307012bc364SMatthew G. Knepley     DMPlexTransformType trType;
308012bc364SMatthew G. Knepley     const char         *prefix;
309012bc364SMatthew G. Knepley     PetscOptions       options;
3100d1cd5e0SMatthew G. Knepley 
3119566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformCreate(PetscObjectComm((PetscObject) dm), &tr));
3129566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformSetDM(tr, dm));
3139566063dSJacob Faibussowitsch     PetscCall(DMPlexGetTransformType(dm, &trType));
3149566063dSJacob Faibussowitsch     if (trType) PetscCall(DMPlexTransformSetType(tr, trType));
3159566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetOptionsPrefix((PetscObject) dm, &prefix));
3169566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetOptionsPrefix((PetscObject) tr,  prefix));
3179566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetOptions((PetscObject) dm, &options));
3189566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetOptions((PetscObject) tr, options));
3199566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformSetFromOptions(tr));
3209566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetOptions((PetscObject) tr, NULL));
3219566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformSetUp(tr));
3229566063dSJacob Faibussowitsch     PetscCall(PetscObjectViewFromOptions((PetscObject) tr, NULL, "-dm_plex_transform_view"));
3239566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformApply(tr, dm, rdm));
3249566063dSJacob Faibussowitsch     PetscCall(DMPlexSetRegularRefinement(*rdm, PETSC_TRUE));
3259566063dSJacob Faibussowitsch     PetscCall(DMCopyDisc(dm, *rdm));
3269566063dSJacob Faibussowitsch     PetscCall(DMGetCoordinateDM(dm, &cdm));
3279566063dSJacob Faibussowitsch     PetscCall(DMGetCoordinateDM(*rdm, &rcdm));
3289566063dSJacob Faibussowitsch     PetscCall(DMCopyDisc(cdm, rcdm));
3299566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformCreateDiscLabels(tr, *rdm));
3309566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformDestroy(&tr));
3310d1cd5e0SMatthew G. Knepley   } else {
3329566063dSJacob Faibussowitsch     PetscCall(DMPlexRefine_Internal(dm, NULL, NULL, NULL, rdm));
3330d1cd5e0SMatthew G. Knepley   }
334012bc364SMatthew G. Knepley   if (*rdm) {
335012bc364SMatthew G. Knepley     ((DM_Plex *) (*rdm)->data)->printFEM = ((DM_Plex *) dm->data)->printFEM;
336012bc364SMatthew G. Knepley     ((DM_Plex *) (*rdm)->data)->printL2  = ((DM_Plex *) dm->data)->printL2;
3376d7c9049SMatthew G. Knepley   }
3389566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(dm, NULL, "-postref_dm_view"));
3390d1cd5e0SMatthew G. Knepley   PetscFunctionReturn(0);
3400d1cd5e0SMatthew G. Knepley }
3410d1cd5e0SMatthew G. Knepley 
342012bc364SMatthew G. Knepley PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM rdm[])
3430d1cd5e0SMatthew G. Knepley {
3440d1cd5e0SMatthew G. Knepley   DM             cdm = dm;
3450d1cd5e0SMatthew G. Knepley   PetscInt       r;
3460d1cd5e0SMatthew G. Knepley   PetscBool      isUniform, localized;
3470d1cd5e0SMatthew G. Knepley 
3480d1cd5e0SMatthew G. Knepley   PetscFunctionBegin;
3499566063dSJacob Faibussowitsch   PetscCall(DMPlexGetRefinementUniform(dm, &isUniform));
3509566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinatesLocalized(dm, &localized));
3510d1cd5e0SMatthew G. Knepley   if (isUniform) {
3520d1cd5e0SMatthew G. Knepley     for (r = 0; r < nlevels; ++r) {
353012bc364SMatthew G. Knepley       DMPlexTransform tr;
35451a74b61SMatthew G. Knepley       DM              codm, rcodm;
355012bc364SMatthew G. Knepley       const char     *prefix;
3560d1cd5e0SMatthew G. Knepley 
3579566063dSJacob Faibussowitsch       PetscCall(DMPlexTransformCreate(PetscObjectComm((PetscObject) cdm), &tr));
3589566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetOptionsPrefix((PetscObject) cdm, &prefix));
3599566063dSJacob Faibussowitsch       PetscCall(PetscObjectSetOptionsPrefix((PetscObject) tr,   prefix));
3609566063dSJacob Faibussowitsch       PetscCall(DMPlexTransformSetDM(tr, cdm));
3619566063dSJacob Faibussowitsch       PetscCall(DMPlexTransformSetFromOptions(tr));
3629566063dSJacob Faibussowitsch       PetscCall(DMPlexTransformSetUp(tr));
3639566063dSJacob Faibussowitsch       PetscCall(DMPlexTransformApply(tr, cdm, &rdm[r]));
3649566063dSJacob Faibussowitsch       PetscCall(DMSetCoarsenLevel(rdm[r], cdm->leveldown));
3659566063dSJacob Faibussowitsch       PetscCall(DMSetRefineLevel(rdm[r], cdm->levelup+1));
3669566063dSJacob Faibussowitsch       PetscCall(DMCopyDisc(cdm, rdm[r]));
3679566063dSJacob Faibussowitsch       PetscCall(DMGetCoordinateDM(dm, &codm));
3689566063dSJacob Faibussowitsch       PetscCall(DMGetCoordinateDM(rdm[r], &rcodm));
3699566063dSJacob Faibussowitsch       PetscCall(DMCopyDisc(codm, rcodm));
3709566063dSJacob Faibussowitsch       PetscCall(DMPlexTransformCreateDiscLabels(tr, rdm[r]));
3719566063dSJacob Faibussowitsch       PetscCall(DMSetCoarseDM(rdm[r], cdm));
3729566063dSJacob Faibussowitsch       PetscCall(DMPlexSetRegularRefinement(rdm[r], PETSC_TRUE));
373012bc364SMatthew G. Knepley       if (rdm[r]) {
374012bc364SMatthew G. Knepley         ((DM_Plex *) (rdm[r])->data)->printFEM = ((DM_Plex *) dm->data)->printFEM;
375012bc364SMatthew G. Knepley         ((DM_Plex *) (rdm[r])->data)->printL2  = ((DM_Plex *) dm->data)->printL2;
3766d7c9049SMatthew G. Knepley       }
377012bc364SMatthew G. Knepley       cdm  = rdm[r];
3789566063dSJacob Faibussowitsch       PetscCall(DMPlexTransformDestroy(&tr));
3790d1cd5e0SMatthew G. Knepley     }
3800d1cd5e0SMatthew G. Knepley   } else {
3810d1cd5e0SMatthew G. Knepley     for (r = 0; r < nlevels; ++r) {
3829566063dSJacob Faibussowitsch       PetscCall(DMRefine(cdm, PetscObjectComm((PetscObject) dm), &rdm[r]));
3839566063dSJacob Faibussowitsch       PetscCall(DMCopyDisc(cdm, rdm[r]));
3849566063dSJacob Faibussowitsch       if (localized) PetscCall(DMLocalizeCoordinates(rdm[r]));
3859566063dSJacob Faibussowitsch       PetscCall(DMSetCoarseDM(rdm[r], cdm));
386012bc364SMatthew G. Knepley       if (rdm[r]) {
387012bc364SMatthew G. Knepley         ((DM_Plex *) (rdm[r])->data)->printFEM = ((DM_Plex *) dm->data)->printFEM;
388012bc364SMatthew G. Knepley         ((DM_Plex *) (rdm[r])->data)->printL2  = ((DM_Plex *) dm->data)->printL2;
3896d7c9049SMatthew G. Knepley       }
390012bc364SMatthew G. Knepley       cdm  = rdm[r];
3910d1cd5e0SMatthew G. Knepley     }
3920d1cd5e0SMatthew G. Knepley   }
3930d1cd5e0SMatthew G. Knepley   PetscFunctionReturn(0);
3940d1cd5e0SMatthew G. Knepley }
395