[petsc-users] grid adaptivity with dmforest
Preda Silvia
silvia.preda at uninsubria.it
Wed Feb 19 10:18:19 CST 2025
Hi,
I'm using the toycode below to manage adaptivity using a DMForest, based on p4est.
The code simply performs three adaptivity steps on a square grid [0,1]x[0,1], uniformly refined at level 2 at the beginning. The minimum and the maximum level of refinement are set to 1 and 5, respectively. During the adaptivity procedure, a quadrant is refined if its centroid is inside the circle of radius 0.25, centred in (0.5,0.5).
I'm facing two main issues:
* As far as I understood, when the label asks to refine a quadrant which is already at the maximum level, the adaption procedure errors out instead of ignoring the request. Thus I need to check the quadrant level before setting the adaptivity label. How can I get access to the quadrant-level of a cell?
* Once the mesh is adapted, data need to be projected on the new mesh and in my method I'll need to write an elaborate ad-hoc procedure for that. How can I access the map that provides the correspondence between the indexes of outcoming quadrants and the indexes of incoming ones?
Below is the code, to be run with these options:
-dm_type p4est
-dm_forest_topology brick
-dm_p4est_brick_size 1,1
-dm_view vtk:brick.vtu
-dm_forest_initial_refinement 2
-dm_forest_minimum_refinement 1
-dm_forest_maximum_refinement 5
static char help[] = "Create and view a forest mesh\n\n";
#include <petscdmforest.h>
#include <petscdmplex.h>
#include <petscoptions.h>
static PetscErrorCode CreateAdaptLabel(DM dm, DM dmConv, PetscInt *nAdaptLoc)
{
DMLabel adaptLabel;
PetscInt cStart, cEnd, c;
PetscFunctionBeginUser;
PetscCall(DMGetCoordinatesLocalSetUp(dm));
PetscCall(DMCreateLabel(dm, "adaptLabel"));
PetscCall(DMGetLabel(dm, "adaptLabel", &adaptLabel));
PetscCall(DMForestGetCellChart(dm, &cStart, &cEnd));
for (c = cStart; c < cEnd; ++c) {
PetscReal centroid[3], volume, x, y;
PetscCall(DMPlexComputeCellGeometryFVM(dmConv, c, &volume, centroid, NULL));
x = centroid[0];
y = centroid[1];
if (std::sqrt((x-0.5)*(x-0.5)+(y-0.5)*(y-0.5))<0.25) {
PetscCall(DMLabelSetValue(adaptLabel, c, DM_ADAPT_REFINE));
++nAdaptLoc[0];
} else {
PetscCall(DMLabelSetValue(adaptLabel, c, DM_ADAPT_KEEP));
++nAdaptLoc[1];
}
}
PetscFunctionReturn(PETSC_SUCCESS);
}
static PetscErrorCode ForestToPlex(DM *dm, DM *dmConv)
{
PetscFunctionBeginUser;
PetscCall(DMConvert(*dm, DMPLEX, dmConv));
PetscCall(DMLocalizeCoordinates(*dmConv));
PetscCall(DMViewFromOptions(*dmConv, NULL, "-dm_conv_view"));
PetscCall(DMPlexCheckCellShape(*dmConv, PETSC_FALSE, PETSC_DETERMINE));
PetscFunctionReturn(PETSC_SUCCESS);
}
static PetscErrorCode AdaptMesh(DM *dm)
{
DM dmCur = *dm;
PetscBool hasLabel=PETSC_FALSE, adapt=PETSC_TRUE;
PetscInt adaptIter=0, maxAdaptIter=3;
PetscFunctionBeginUser;
while (adapt) {
DM dmAdapt;
DMLabel adaptLabel;
PetscInt nAdaptLoc[2]={0,0}, nAdapt[2]={0,0};
++adaptIter;
PetscCall(PetscPrintf(PETSC_COMM_SELF,"\nADAPT ITER %d\n",adaptIter));
DM dmConv;
PetscCall(ForestToPlex(&dmCur,&dmConv));
PetscCall(CreateAdaptLabel(dmCur,dmConv,nAdaptLoc));
PetscCallMPI(MPIU_Allreduce(&nAdaptLoc, &nAdapt, 2, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)dmCur)));
PetscCall(DMGetLabel(dmCur, "adaptLabel", &adaptLabel));
PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Cell to refine = %d\n",nAdapt[0]));
PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Cell to keep = %d\n",nAdapt[1]));
if (nAdapt[0]) {
PetscCall(DMAdaptLabel(dmCur, adaptLabel, &dmAdapt));
PetscCall(DMHasLabel(dmAdapt, "adaptLabel", &hasLabel));
PetscCall(DMDestroy(&dmCur));
PetscCall(DMViewFromOptions(dmAdapt, NULL, "-adapt_dm_view"));
dmCur = dmAdapt;
}
//PetscCall(DMLabelDestroy(&adaptLabel));
PetscCall(DMDestroy(&dmConv));
if (adaptIter==maxAdaptIter) adapt=PETSC_FALSE;
}
*dm = dmCur;
PetscFunctionReturn(PETSC_SUCCESS);
}
int main(int argc, char **argv)
{
DM dm;
char typeString[256] = {'\0'};
PetscViewer viewer = NULL;
PetscFunctionBeginUser;
PetscCall(PetscInitialize(&argc, &argv, NULL, help));
PetscCall(DMCreate(PETSC_COMM_WORLD, &dm));
PetscCall(PetscStrncpy(typeString, DMFOREST, 256));
PetscOptionsBegin(PETSC_COMM_WORLD, NULL, "DM Forest example options", NULL);
PetscCall(PetscOptionsString("-dm_type", "The type of the dm", NULL, DMFOREST, typeString, sizeof(typeString), NULL));
PetscOptionsEnd();
PetscCall(PetscPrintf(PETSC_COMM_SELF,"\n ==== TOY CODE DMFOREST WITH AMR ====\n"));
PetscCall(DMSetType(dm, (DMType)typeString));
PetscCall(DMSetFromOptions(dm));
PetscCall(DMSetUp(dm));
/* Adapt */
PetscCall(PetscPrintf(PETSC_COMM_SELF,"\nADAPTIVITY PHASE STARTED\n"));
PetscCall(AdaptMesh(&dm));
PetscCall(PetscPrintf(PETSC_COMM_SELF,"\nADAPTIVITY PHASE ENDED\n\n"));
PetscCall(DMViewFromOptions(dm, NULL, "-dm_view"));
PetscCall(PetscViewerDestroy(&viewer));
PetscCall(DMDestroy(&dm));
PetscCall(PetscFinalize());
return 0;
}
Thanks a lot,
Silvia
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/petsc-users/attachments/20250219/03d6ebc2/attachment-0001.html>
More information about the petsc-users
mailing list