xref: /petsc/src/dm/impls/plex/plexrefine.c (revision ad540459ab38c4a232710a68077e487eb6627fe2)
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 
22db781477SPatrick Sanan .seealso: `PetscSFCreate()`, `DMPlexCreateTwoSidedProcessSF()`
23963fc26aSMatthew G. Knepley @*/
249371c9d4SSatish Balay PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) {
2575d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
2675d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
2775d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
2875d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
2975d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
3075d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
319852e123SBarry Smith   PetscMPIInt        size;
3275d3a19aSMatthew G. Knepley 
3375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
34963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
35963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2);
36*ad540459SPierre Jolivet   if (processRanks) PetscValidPointer(processRanks, 3);
37*ad540459SPierre Jolivet   if (sfProcess) PetscValidPointer(sfProcess, 4);
389566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size));
399566063dSJacob Faibussowitsch   PetscCall(PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints));
409566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(numLeaves, &ranks));
41*ad540459SPierre Jolivet   for (l = 0; l < numLeaves; ++l) ranks[l] = remotePoints[l].rank;
429566063dSJacob Faibussowitsch   PetscCall(PetscSortRemoveDupsInt(&numLeaves, ranks));
439566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(numLeaves, &ranksNew));
449566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(numLeaves, &localPointsNew));
459566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(numLeaves, &remotePointsNew));
4675d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
4775d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
4875d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
4975d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
5075d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
5175d3a19aSMatthew G. Knepley   }
529566063dSJacob Faibussowitsch   PetscCall(PetscFree(ranks));
539566063dSJacob Faibussowitsch   if (processRanks) PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks));
549566063dSJacob Faibussowitsch   else PetscCall(PetscFree(ranksNew));
55963fc26aSMatthew G. Knepley   if (sfProcess) {
569566063dSJacob Faibussowitsch     PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess));
579566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetName((PetscObject)*sfProcess, "Process SF"));
589566063dSJacob Faibussowitsch     PetscCall(PetscSFSetFromOptions(*sfProcess));
599566063dSJacob Faibussowitsch     PetscCall(PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER));
60963fc26aSMatthew G. Knepley   }
6175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
6275d3a19aSMatthew G. Knepley }
6375d3a19aSMatthew G. Knepley 
642389894bSMatthew G. Knepley /*@
652389894bSMatthew G. Knepley   DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data
662389894bSMatthew G. Knepley 
67012bc364SMatthew G. Knepley   Collective on dm
68012bc364SMatthew G. Knepley 
692389894bSMatthew G. Knepley   Input Parameter:
702389894bSMatthew G. Knepley . dm - The coarse DM
712389894bSMatthew G. Knepley 
722389894bSMatthew G. Knepley   Output Parameter:
732389894bSMatthew G. Knepley . fpointIS - The IS of all the fine points which exist in the original coarse mesh
742389894bSMatthew G. Knepley 
752389894bSMatthew G. Knepley   Level: developer
762389894bSMatthew G. Knepley 
77db781477SPatrick Sanan .seealso: `DMRefine()`, `DMPlexSetRefinementUniform()`, `DMPlexGetSubpointIS()`
782389894bSMatthew G. Knepley @*/
799371c9d4SSatish Balay PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) {
80012bc364SMatthew G. Knepley   DMPlexTransform tr;
81412e9a14SMatthew G. Knepley   PetscInt       *fpoints;
82327c2912SStefano Zampini   PetscInt        pStart, pEnd, p, vStart, vEnd, v;
832389894bSMatthew G. Knepley 
842389894bSMatthew G. Knepley   PetscFunctionBegin;
859566063dSJacob Faibussowitsch   PetscCall(DMPlexGetChart(dm, &pStart, &pEnd));
869566063dSJacob Faibussowitsch   PetscCall(DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd));
879566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformCreate(PetscObjectComm((PetscObject)dm), &tr));
889566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformSetUp(tr));
899566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(pEnd - pStart, &fpoints));
902389894bSMatthew G. Knepley   for (p = 0; p < pEnd - pStart; ++p) fpoints[p] = -1;
91412e9a14SMatthew G. Knepley   for (v = vStart; v < vEnd; ++v) {
92012bc364SMatthew G. Knepley     PetscInt vNew = -1; /* quiet overzealous may be used uninitialized check */
93327c2912SStefano Zampini 
949566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformGetTargetPoint(tr, DM_POLYTOPE_POINT, DM_POLYTOPE_POINT, p, 0, &vNew));
95412e9a14SMatthew G. Knepley     fpoints[v - pStart] = vNew;
962389894bSMatthew G. Knepley   }
979566063dSJacob Faibussowitsch   PetscCall(DMPlexTransformDestroy(&tr));
989566063dSJacob Faibussowitsch   PetscCall(ISCreateGeneral(PETSC_COMM_SELF, pEnd - pStart, fpoints, PETSC_OWN_POINTER, fpointIS));
992389894bSMatthew G. Knepley   PetscFunctionReturn(0);
1002389894bSMatthew G. Knepley }
1012389894bSMatthew G. Knepley 
102012bc364SMatthew G. Knepley /*@C
103012bc364SMatthew G. Knepley   DMPlexSetTransformType - Set the transform type for uniform refinement
104012bc364SMatthew G. Knepley 
105012bc364SMatthew G. Knepley   Input Parameters:
106012bc364SMatthew G. Knepley + dm - The DM
107012bc364SMatthew G. Knepley - type - The transform type for uniform refinement
108012bc364SMatthew G. Knepley 
109012bc364SMatthew G. Knepley   Level: developer
110012bc364SMatthew G. Knepley 
111db781477SPatrick Sanan .seealso: `DMPlexTransformType`, `DMRefine()`, `DMPlexGetTransformType()`, `DMPlexSetRefinementUniform()`
112012bc364SMatthew G. Knepley @*/
1139371c9d4SSatish Balay PetscErrorCode DMPlexSetTransformType(DM dm, DMPlexTransformType type) {
114012bc364SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex *)dm->data;
115012bc364SMatthew G. Knepley 
116012bc364SMatthew G. Knepley   PetscFunctionBegin;
117012bc364SMatthew G. Knepley   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMPLEX);
118012bc364SMatthew G. Knepley   if (type) PetscValidCharPointer(type, 2);
1199566063dSJacob Faibussowitsch   PetscCall(PetscFree(mesh->transformType));
1209566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(type, &mesh->transformType));
121012bc364SMatthew G. Knepley   PetscFunctionReturn(0);
122012bc364SMatthew G. Knepley }
123012bc364SMatthew G. Knepley 
124012bc364SMatthew G. Knepley /*@C
125012bc364SMatthew G. Knepley   DMPlexGetTransformType - Retrieve the transform type for uniform refinement
126012bc364SMatthew G. Knepley 
127012bc364SMatthew G. Knepley   Input Parameter:
128012bc364SMatthew G. Knepley . dm - The DM
129012bc364SMatthew G. Knepley 
130012bc364SMatthew G. Knepley   Output Parameter:
131012bc364SMatthew G. Knepley . type - The transform type for uniform refinement
132012bc364SMatthew G. Knepley 
133012bc364SMatthew G. Knepley   Level: developer
134012bc364SMatthew G. Knepley 
135db781477SPatrick Sanan .seealso: `DMPlexTransformType`, `DMRefine()`, `DMPlexSetTransformType()`, `DMPlexGetRefinementUniform()`
136012bc364SMatthew G. Knepley @*/
1379371c9d4SSatish Balay PetscErrorCode DMPlexGetTransformType(DM dm, DMPlexTransformType *type) {
138012bc364SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex *)dm->data;
139012bc364SMatthew G. Knepley 
140012bc364SMatthew G. Knepley   PetscFunctionBegin;
141012bc364SMatthew G. Knepley   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMPLEX);
142012bc364SMatthew G. Knepley   PetscValidPointer(type, 2);
143012bc364SMatthew G. Knepley   *type = mesh->transformType;
144012bc364SMatthew G. Knepley   PetscFunctionReturn(0);
145012bc364SMatthew G. Knepley }
146012bc364SMatthew G. Knepley 
1470e2b6761SMatthew G. Knepley /*@
1480e2b6761SMatthew G. Knepley   DMPlexSetRefinementUniform - Set the flag for uniform refinement
1490e2b6761SMatthew G. Knepley 
1500e2b6761SMatthew G. Knepley   Input Parameters:
1510e2b6761SMatthew G. Knepley + dm - The DM
1520e2b6761SMatthew G. Knepley - refinementUniform - The flag for uniform refinement
1530e2b6761SMatthew G. Knepley 
1540e2b6761SMatthew G. Knepley   Level: developer
1550e2b6761SMatthew G. Knepley 
156db781477SPatrick Sanan .seealso: `DMRefine()`, `DMPlexGetRefinementUniform()`, `DMPlexGetRefinementLimit()`, `DMPlexSetRefinementLimit()`
1570e2b6761SMatthew G. Knepley @*/
1589371c9d4SSatish Balay PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) {
15975d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex *)dm->data;
16075d3a19aSMatthew G. Knepley 
16175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
162012bc364SMatthew G. Knepley   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMPLEX);
16375d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
16475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
16575d3a19aSMatthew G. Knepley }
16675d3a19aSMatthew G. Knepley 
1670e2b6761SMatthew G. Knepley /*@
1680e2b6761SMatthew G. Knepley   DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement
1690e2b6761SMatthew G. Knepley 
1700e2b6761SMatthew G. Knepley   Input Parameter:
1710e2b6761SMatthew G. Knepley . dm - The DM
1720e2b6761SMatthew G. Knepley 
1730e2b6761SMatthew G. Knepley   Output Parameter:
1740e2b6761SMatthew G. Knepley . refinementUniform - The flag for uniform refinement
1750e2b6761SMatthew G. Knepley 
1760e2b6761SMatthew G. Knepley   Level: developer
1770e2b6761SMatthew G. Knepley 
178db781477SPatrick Sanan .seealso: `DMRefine()`, `DMPlexSetRefinementUniform()`, `DMPlexGetRefinementLimit()`, `DMPlexSetRefinementLimit()`
1790e2b6761SMatthew G. Knepley @*/
1809371c9d4SSatish Balay PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) {
18175d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex *)dm->data;
18275d3a19aSMatthew G. Knepley 
18375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
184012bc364SMatthew G. Knepley   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMPLEX);
185dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(refinementUniform, 2);
18675d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
18775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
18875d3a19aSMatthew G. Knepley }
18975d3a19aSMatthew G. Knepley 
1900e2b6761SMatthew G. Knepley /*@
1910e2b6761SMatthew G. Knepley   DMPlexSetRefinementLimit - Set the maximum cell volume for refinement
1920e2b6761SMatthew G. Knepley 
1930e2b6761SMatthew G. Knepley   Input Parameters:
1940e2b6761SMatthew G. Knepley + dm - The DM
1950e2b6761SMatthew G. Knepley - refinementLimit - The maximum cell volume in the refined mesh
1960e2b6761SMatthew G. Knepley 
1970e2b6761SMatthew G. Knepley   Level: developer
1980e2b6761SMatthew G. Knepley 
199db781477SPatrick Sanan .seealso: `DMRefine()`, `DMPlexGetRefinementLimit()`, `DMPlexGetRefinementUniform()`, `DMPlexSetRefinementUniform()`
2000e2b6761SMatthew G. Knepley @*/
2019371c9d4SSatish Balay PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) {
20275d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex *)dm->data;
20375d3a19aSMatthew G. Knepley 
20475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
20575d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
20675d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
20775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
20875d3a19aSMatthew G. Knepley }
20975d3a19aSMatthew G. Knepley 
2100e2b6761SMatthew G. Knepley /*@
2110e2b6761SMatthew G. Knepley   DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement
2120e2b6761SMatthew G. Knepley 
2130e2b6761SMatthew G. Knepley   Input Parameter:
2140e2b6761SMatthew G. Knepley . dm - The DM
2150e2b6761SMatthew G. Knepley 
2160e2b6761SMatthew G. Knepley   Output Parameter:
2170e2b6761SMatthew G. Knepley . refinementLimit - The maximum cell volume in the refined mesh
2180e2b6761SMatthew G. Knepley 
2190e2b6761SMatthew G. Knepley   Level: developer
2200e2b6761SMatthew G. Knepley 
221db781477SPatrick Sanan .seealso: `DMRefine()`, `DMPlexSetRefinementLimit()`, `DMPlexGetRefinementUniform()`, `DMPlexSetRefinementUniform()`
2220e2b6761SMatthew G. Knepley @*/
2239371c9d4SSatish Balay PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) {
22475d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex *)dm->data;
22575d3a19aSMatthew G. Knepley 
22675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
22775d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
228dadcf809SJacob Faibussowitsch   PetscValidRealPointer(refinementLimit, 2);
22975d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
23075d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
23175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
23275d3a19aSMatthew G. Knepley }
23375d3a19aSMatthew G. Knepley 
234b28003e6SMatthew G. Knepley /*@
235b28003e6SMatthew G. Knepley   DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement
236b28003e6SMatthew G. Knepley 
237b28003e6SMatthew G. Knepley   Input Parameters:
238b28003e6SMatthew G. Knepley + dm - The DM
239b28003e6SMatthew G. Knepley - refinementFunc - Function giving the maximum cell volume in the refined mesh
240b28003e6SMatthew G. Knepley 
241b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
242b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
243b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
244b28003e6SMatthew G. Knepley 
245b28003e6SMatthew G. Knepley   Level: developer
246b28003e6SMatthew G. Knepley 
247db781477SPatrick Sanan .seealso: `DMRefine()`, `DMPlexGetRefinementFunction()`, `DMPlexGetRefinementUniform()`, `DMPlexSetRefinementUniform()`, `DMPlexGetRefinementLimit()`, `DMPlexSetRefinementLimit()`
248b28003e6SMatthew G. Knepley @*/
2499371c9d4SSatish Balay PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal[], PetscReal *)) {
250b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex *)dm->data;
251b28003e6SMatthew G. Knepley 
252b28003e6SMatthew G. Knepley   PetscFunctionBegin;
253b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
254b28003e6SMatthew G. Knepley   mesh->refinementFunc = refinementFunc;
255b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
256b28003e6SMatthew G. Knepley }
257b28003e6SMatthew G. Knepley 
258b28003e6SMatthew G. Knepley /*@
259b28003e6SMatthew G. Knepley   DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement
260b28003e6SMatthew G. Knepley 
261b28003e6SMatthew G. Knepley   Input Parameter:
262b28003e6SMatthew G. Knepley . dm - The DM
263b28003e6SMatthew G. Knepley 
264b28003e6SMatthew G. Knepley   Output Parameter:
265b28003e6SMatthew G. Knepley . refinementFunc - Function giving the maximum cell volume in the refined mesh
266b28003e6SMatthew G. Knepley 
267b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
268b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
269b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
270b28003e6SMatthew G. Knepley 
271b28003e6SMatthew G. Knepley   Level: developer
272b28003e6SMatthew G. Knepley 
273db781477SPatrick Sanan .seealso: `DMRefine()`, `DMPlexSetRefinementFunction()`, `DMPlexGetRefinementUniform()`, `DMPlexSetRefinementUniform()`, `DMPlexGetRefinementLimit()`, `DMPlexSetRefinementLimit()`
274b28003e6SMatthew G. Knepley @*/
2759371c9d4SSatish Balay PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal[], PetscReal *)) {
276b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex *)dm->data;
277b28003e6SMatthew G. Knepley 
278b28003e6SMatthew G. Knepley   PetscFunctionBegin;
279b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
280b28003e6SMatthew G. Knepley   PetscValidPointer(refinementFunc, 2);
281b28003e6SMatthew G. Knepley   *refinementFunc = mesh->refinementFunc;
282b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
283b28003e6SMatthew G. Knepley }
284b28003e6SMatthew G. Knepley 
2859371c9d4SSatish Balay PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *rdm) {
286492b8470SStefano Zampini   PetscBool isUniform;
2870d1cd5e0SMatthew G. Knepley 
2880d1cd5e0SMatthew G. Knepley   PetscFunctionBegin;
2899566063dSJacob Faibussowitsch   PetscCall(DMPlexGetRefinementUniform(dm, &isUniform));
2909566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(dm, NULL, "-initref_dm_view"));
2910d1cd5e0SMatthew G. Knepley   if (isUniform) {
292012bc364SMatthew G. Knepley     DMPlexTransform     tr;
29351a74b61SMatthew G. Knepley     DM                  cdm, rcdm;
294012bc364SMatthew G. Knepley     DMPlexTransformType trType;
295012bc364SMatthew G. Knepley     const char         *prefix;
296012bc364SMatthew G. Knepley     PetscOptions        options;
2970d1cd5e0SMatthew G. Knepley 
2989566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformCreate(PetscObjectComm((PetscObject)dm), &tr));
2999566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformSetDM(tr, dm));
3009566063dSJacob Faibussowitsch     PetscCall(DMPlexGetTransformType(dm, &trType));
3019566063dSJacob Faibussowitsch     if (trType) PetscCall(DMPlexTransformSetType(tr, trType));
3029566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetOptionsPrefix((PetscObject)dm, &prefix));
3039566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetOptionsPrefix((PetscObject)tr, prefix));
3049566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetOptions((PetscObject)dm, &options));
3059566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetOptions((PetscObject)tr, options));
3069566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformSetFromOptions(tr));
3079566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetOptions((PetscObject)tr, NULL));
3089566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformSetUp(tr));
3099566063dSJacob Faibussowitsch     PetscCall(PetscObjectViewFromOptions((PetscObject)tr, NULL, "-dm_plex_transform_view"));
3109566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformApply(tr, dm, rdm));
3119566063dSJacob Faibussowitsch     PetscCall(DMPlexSetRegularRefinement(*rdm, PETSC_TRUE));
3129566063dSJacob Faibussowitsch     PetscCall(DMCopyDisc(dm, *rdm));
3139566063dSJacob Faibussowitsch     PetscCall(DMGetCoordinateDM(dm, &cdm));
3149566063dSJacob Faibussowitsch     PetscCall(DMGetCoordinateDM(*rdm, &rcdm));
3159566063dSJacob Faibussowitsch     PetscCall(DMCopyDisc(cdm, rcdm));
3169566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformCreateDiscLabels(tr, *rdm));
3179566063dSJacob Faibussowitsch     PetscCall(DMPlexTransformDestroy(&tr));
3180d1cd5e0SMatthew G. Knepley   } else {
3199566063dSJacob Faibussowitsch     PetscCall(DMPlexRefine_Internal(dm, NULL, NULL, NULL, rdm));
3200d1cd5e0SMatthew G. Knepley   }
321012bc364SMatthew G. Knepley   if (*rdm) {
322012bc364SMatthew G. Knepley     ((DM_Plex *)(*rdm)->data)->printFEM = ((DM_Plex *)dm->data)->printFEM;
323012bc364SMatthew G. Knepley     ((DM_Plex *)(*rdm)->data)->printL2  = ((DM_Plex *)dm->data)->printL2;
3246d7c9049SMatthew G. Knepley   }
3259566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(dm, NULL, "-postref_dm_view"));
3260d1cd5e0SMatthew G. Knepley   PetscFunctionReturn(0);
3270d1cd5e0SMatthew G. Knepley }
3280d1cd5e0SMatthew G. Knepley 
3299371c9d4SSatish Balay PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM rdm[]) {
3300d1cd5e0SMatthew G. Knepley   DM        cdm = dm;
3310d1cd5e0SMatthew G. Knepley   PetscInt  r;
3320d1cd5e0SMatthew G. Knepley   PetscBool isUniform, localized;
3330d1cd5e0SMatthew G. Knepley 
3340d1cd5e0SMatthew G. Knepley   PetscFunctionBegin;
3359566063dSJacob Faibussowitsch   PetscCall(DMPlexGetRefinementUniform(dm, &isUniform));
3369566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinatesLocalized(dm, &localized));
3370d1cd5e0SMatthew G. Knepley   if (isUniform) {
3380d1cd5e0SMatthew G. Knepley     for (r = 0; r < nlevels; ++r) {
339012bc364SMatthew G. Knepley       DMPlexTransform tr;
34051a74b61SMatthew G. Knepley       DM              codm, rcodm;
341012bc364SMatthew G. Knepley       const char     *prefix;
3420d1cd5e0SMatthew G. Knepley 
3439566063dSJacob Faibussowitsch       PetscCall(DMPlexTransformCreate(PetscObjectComm((PetscObject)cdm), &tr));
3449566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetOptionsPrefix((PetscObject)cdm, &prefix));
3459566063dSJacob Faibussowitsch       PetscCall(PetscObjectSetOptionsPrefix((PetscObject)tr, prefix));
3469566063dSJacob Faibussowitsch       PetscCall(DMPlexTransformSetDM(tr, cdm));
3479566063dSJacob Faibussowitsch       PetscCall(DMPlexTransformSetFromOptions(tr));
3489566063dSJacob Faibussowitsch       PetscCall(DMPlexTransformSetUp(tr));
3499566063dSJacob Faibussowitsch       PetscCall(DMPlexTransformApply(tr, cdm, &rdm[r]));
3509566063dSJacob Faibussowitsch       PetscCall(DMSetCoarsenLevel(rdm[r], cdm->leveldown));
3519566063dSJacob Faibussowitsch       PetscCall(DMSetRefineLevel(rdm[r], cdm->levelup + 1));
3529566063dSJacob Faibussowitsch       PetscCall(DMCopyDisc(cdm, rdm[r]));
3539566063dSJacob Faibussowitsch       PetscCall(DMGetCoordinateDM(dm, &codm));
3549566063dSJacob Faibussowitsch       PetscCall(DMGetCoordinateDM(rdm[r], &rcodm));
3559566063dSJacob Faibussowitsch       PetscCall(DMCopyDisc(codm, rcodm));
3569566063dSJacob Faibussowitsch       PetscCall(DMPlexTransformCreateDiscLabels(tr, rdm[r]));
3579566063dSJacob Faibussowitsch       PetscCall(DMSetCoarseDM(rdm[r], cdm));
3589566063dSJacob Faibussowitsch       PetscCall(DMPlexSetRegularRefinement(rdm[r], PETSC_TRUE));
359012bc364SMatthew G. Knepley       if (rdm[r]) {
360012bc364SMatthew G. Knepley         ((DM_Plex *)(rdm[r])->data)->printFEM = ((DM_Plex *)dm->data)->printFEM;
361012bc364SMatthew G. Knepley         ((DM_Plex *)(rdm[r])->data)->printL2  = ((DM_Plex *)dm->data)->printL2;
3626d7c9049SMatthew G. Knepley       }
363012bc364SMatthew G. Knepley       cdm = rdm[r];
3649566063dSJacob Faibussowitsch       PetscCall(DMPlexTransformDestroy(&tr));
3650d1cd5e0SMatthew G. Knepley     }
3660d1cd5e0SMatthew G. Knepley   } else {
3670d1cd5e0SMatthew G. Knepley     for (r = 0; r < nlevels; ++r) {
3689566063dSJacob Faibussowitsch       PetscCall(DMRefine(cdm, PetscObjectComm((PetscObject)dm), &rdm[r]));
3699566063dSJacob Faibussowitsch       PetscCall(DMCopyDisc(cdm, rdm[r]));
3709566063dSJacob Faibussowitsch       if (localized) PetscCall(DMLocalizeCoordinates(rdm[r]));
3719566063dSJacob Faibussowitsch       PetscCall(DMSetCoarseDM(rdm[r], cdm));
372012bc364SMatthew G. Knepley       if (rdm[r]) {
373012bc364SMatthew G. Knepley         ((DM_Plex *)(rdm[r])->data)->printFEM = ((DM_Plex *)dm->data)->printFEM;
374012bc364SMatthew G. Knepley         ((DM_Plex *)(rdm[r])->data)->printL2  = ((DM_Plex *)dm->data)->printL2;
3756d7c9049SMatthew G. Knepley       }
376012bc364SMatthew G. Knepley       cdm = rdm[r];
3770d1cd5e0SMatthew G. Knepley     }
3780d1cd5e0SMatthew G. Knepley   }
3790d1cd5e0SMatthew G. Knepley   PetscFunctionReturn(0);
3800d1cd5e0SMatthew G. Knepley }
381