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