1adcf2cb4SMatthew G. Knepley static char help[] = "TDycore Mesh Examples\n\n"; 2adcf2cb4SMatthew G. Knepley 3adcf2cb4SMatthew G. Knepley #include <petscdmplex.h> 4adcf2cb4SMatthew G. Knepley 5adcf2cb4SMatthew G. Knepley typedef struct { 6adcf2cb4SMatthew G. Knepley PetscBool adapt; /* Flag for adaptation of the surface mesh */ 7adcf2cb4SMatthew G. Knepley } AppCtx; 8adcf2cb4SMatthew G. Knepley 9adcf2cb4SMatthew G. Knepley static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) 10adcf2cb4SMatthew G. Knepley { 11adcf2cb4SMatthew G. Knepley PetscErrorCode ierr; 12adcf2cb4SMatthew G. Knepley 13adcf2cb4SMatthew G. Knepley PetscFunctionBeginUser; 14adcf2cb4SMatthew G. Knepley options->adapt = PETSC_FALSE; 15adcf2cb4SMatthew G. Knepley 16adcf2cb4SMatthew G. Knepley ierr = PetscOptionsBegin(comm, "", "Meshing Interpolation Test Options", "DMPLEX");CHKERRQ(ierr); 17*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsBool("-adapt", "Flag for adaptation of the surface mesh", "ex10.c", options->adapt, &options->adapt, NULL)); 181e1ea65dSPierre Jolivet ierr = PetscOptionsEnd();CHKERRQ(ierr); 19adcf2cb4SMatthew G. Knepley PetscFunctionReturn(0); 20adcf2cb4SMatthew G. Knepley } 21adcf2cb4SMatthew G. Knepley 22adcf2cb4SMatthew G. Knepley static PetscErrorCode CreateDomainLabel(DM dm) 23adcf2cb4SMatthew G. Knepley { 24adcf2cb4SMatthew G. Knepley DMLabel label; 25adcf2cb4SMatthew G. Knepley PetscInt cStart, cEnd, c; 26adcf2cb4SMatthew G. Knepley 27adcf2cb4SMatthew G. Knepley PetscFunctionBeginUser; 28*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMCreateLabel(dm, "Cell Sets")); 29*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetLabel(dm, "Cell Sets", &label)); 30*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd)); 31adcf2cb4SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 32adcf2cb4SMatthew G. Knepley PetscReal centroid[3], volume, x, y; 33adcf2cb4SMatthew G. Knepley 34*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexComputeCellGeometryFVM(dm, c, &volume, centroid, NULL)); 35adcf2cb4SMatthew G. Knepley x = centroid[0]; y = centroid[1]; 36adcf2cb4SMatthew G. Knepley /* Headwaters are (0.0,0.25)--(0.1,0.75) */ 37*5f80ce2aSJacob Faibussowitsch if ((x >= 0.0 && x < 0.1) && (y >= 0.25 && y <= 0.75)) {CHKERRQ(DMLabelSetValue(label, c, 1));continue;} 38adcf2cb4SMatthew G. Knepley /* River channel is (0.1,0.45)--(1.0,0.55) */ 39*5f80ce2aSJacob Faibussowitsch if ((x >= 0.1 && x <= 1.0) && (y >= 0.45 && y <= 0.55)) {CHKERRQ(DMLabelSetValue(label, c, 2));continue;} 40adcf2cb4SMatthew G. Knepley } 41adcf2cb4SMatthew G. Knepley PetscFunctionReturn(0); 42adcf2cb4SMatthew G. Knepley } 43adcf2cb4SMatthew G. Knepley 44adcf2cb4SMatthew G. Knepley static PetscErrorCode AdaptMesh(DM *dm, AppCtx *ctx) 45adcf2cb4SMatthew G. Knepley { 46adcf2cb4SMatthew G. Knepley DM dmCur = *dm; 47adcf2cb4SMatthew G. Knepley DMLabel label; 48adcf2cb4SMatthew G. Knepley IS valueIS, vIS; 49adcf2cb4SMatthew G. Knepley PetscBool hasLabel; 50adcf2cb4SMatthew G. Knepley const PetscInt *values; 51adcf2cb4SMatthew G. Knepley PetscReal *volConst; /* Volume constraints for each label value */ 52adcf2cb4SMatthew G. Knepley PetscReal ratio; 53adcf2cb4SMatthew G. Knepley PetscInt dim, Nv, v, cStart, cEnd, c; 54adcf2cb4SMatthew G. Knepley PetscBool adapt = PETSC_TRUE; 55adcf2cb4SMatthew G. Knepley 56adcf2cb4SMatthew G. Knepley PetscFunctionBeginUser; 57adcf2cb4SMatthew G. Knepley if (!ctx->adapt) PetscFunctionReturn(0); 58*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMHasLabel(*dm, "Cell Sets", &hasLabel)); 59*5f80ce2aSJacob Faibussowitsch if (!hasLabel) CHKERRQ(CreateDomainLabel(*dm)); 60*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetDimension(*dm, &dim)); 61adcf2cb4SMatthew G. Knepley ratio = PetscPowRealInt(0.5, dim); 62adcf2cb4SMatthew G. Knepley /* Get volume constraints */ 63*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetLabel(*dm, "Cell Sets", &label)); 64*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMLabelGetValueIS(label, &vIS)); 65*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISDuplicate(vIS, &valueIS)); 66*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&vIS)); 67adcf2cb4SMatthew G. Knepley /* Sorting ruins the label */ 68*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISSort(valueIS)); 69*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetLocalSize(valueIS, &Nv)); 70*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetIndices(valueIS, &values)); 71*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(Nv, &volConst)); 72adcf2cb4SMatthew G. Knepley for (v = 0; v < Nv; ++v) { 73adcf2cb4SMatthew G. Knepley char opt[128]; 74adcf2cb4SMatthew G. Knepley 75adcf2cb4SMatthew G. Knepley volConst[v] = PETSC_MAX_REAL; 76*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSNPrintf(opt, 128, "-volume_constraint_%d", (int) values[v])); 77*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetReal(NULL, NULL, opt, &volConst[v], NULL)); 78adcf2cb4SMatthew G. Knepley } 79*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISRestoreIndices(valueIS, &values)); 80*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&valueIS)); 81adcf2cb4SMatthew G. Knepley /* Adapt mesh iteratively */ 82adcf2cb4SMatthew G. Knepley while (adapt) { 83adcf2cb4SMatthew G. Knepley DM dmAdapt; 84adcf2cb4SMatthew G. Knepley DMLabel adaptLabel; 85adcf2cb4SMatthew G. Knepley PetscInt nAdaptLoc[2], nAdapt[2]; 86adcf2cb4SMatthew G. Knepley 87adcf2cb4SMatthew G. Knepley adapt = PETSC_FALSE; 88adcf2cb4SMatthew G. Knepley nAdaptLoc[0] = nAdaptLoc[1] = 0; 89adcf2cb4SMatthew G. Knepley nAdapt[0] = nAdapt[1] = 0; 90adcf2cb4SMatthew G. Knepley /* Adaptation is not preserving the domain label */ 91*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMHasLabel(dmCur, "Cell Sets", &hasLabel)); 92*5f80ce2aSJacob Faibussowitsch if (!hasLabel) CHKERRQ(CreateDomainLabel(dmCur)); 93*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetLabel(dmCur, "Cell Sets", &label)); 94*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMLabelGetValueIS(label, &vIS)); 95*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISDuplicate(vIS, &valueIS)); 96*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&vIS)); 97adcf2cb4SMatthew G. Knepley /* Sorting directly the label's value IS would corrupt the label so we duplicate the IS first */ 98*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISSort(valueIS)); 99*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetLocalSize(valueIS, &Nv)); 100*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetIndices(valueIS, &values)); 101adcf2cb4SMatthew G. Knepley /* Construct adaptation label */ 102*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMLabelCreate(PETSC_COMM_SELF, "adapt", &adaptLabel)); 103*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexGetHeightStratum(dmCur, 0, &cStart, &cEnd)); 104adcf2cb4SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 105adcf2cb4SMatthew G. Knepley PetscReal volume, centroid[3]; 106adcf2cb4SMatthew G. Knepley PetscInt value, vidx; 107adcf2cb4SMatthew G. Knepley 108*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexComputeCellGeometryFVM(dmCur, c, &volume, centroid, NULL)); 109*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMLabelGetValue(label, c, &value)); 110adcf2cb4SMatthew G. Knepley if (value < 0) continue; 111*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFindInt(value, Nv, values, &vidx)); 1122c71b3e2SJacob Faibussowitsch PetscCheckFalse(vidx < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Value %D for cell %D does not exist in label", value, c); 113*5f80ce2aSJacob Faibussowitsch if (volume > volConst[vidx]) {CHKERRQ(DMLabelSetValue(adaptLabel, c, DM_ADAPT_REFINE)); ++nAdaptLoc[0];} 114*5f80ce2aSJacob Faibussowitsch if (volume < volConst[vidx]*ratio) {CHKERRQ(DMLabelSetValue(adaptLabel, c, DM_ADAPT_COARSEN)); ++nAdaptLoc[1];} 115adcf2cb4SMatthew G. Knepley } 116*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISRestoreIndices(valueIS, &values)); 117*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&valueIS)); 118*5f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Allreduce(&nAdaptLoc, &nAdapt, 2, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject) dmCur))); 119adcf2cb4SMatthew G. Knepley if (nAdapt[0]) { 120*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscInfo(dmCur, "Adapted mesh, marking %D cells for refinement, and %D cells for coarsening\n", nAdapt[0], nAdapt[1])); 121*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMAdaptLabel(dmCur, adaptLabel, &dmAdapt)); 122*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDestroy(&dmCur)); 123*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMViewFromOptions(dmAdapt, NULL, "-adapt_dm_view")); 124adcf2cb4SMatthew G. Knepley dmCur = dmAdapt; 125adcf2cb4SMatthew G. Knepley adapt = PETSC_TRUE; 126adcf2cb4SMatthew G. Knepley } 127*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMLabelDestroy(&adaptLabel)); 128adcf2cb4SMatthew G. Knepley } 129*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(volConst)); 130adcf2cb4SMatthew G. Knepley *dm = dmCur; 131adcf2cb4SMatthew G. Knepley PetscFunctionReturn(0); 132adcf2cb4SMatthew G. Knepley } 133adcf2cb4SMatthew G. Knepley 134adcf2cb4SMatthew G. Knepley static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) 135adcf2cb4SMatthew G. Knepley { 136adcf2cb4SMatthew G. Knepley PetscInt dim; 137adcf2cb4SMatthew G. Knepley 138adcf2cb4SMatthew G. Knepley PetscFunctionBeginUser; 139adcf2cb4SMatthew G. Knepley /* Create top surface */ 140*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMCreate(comm, dm)); 141*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMSetType(*dm, DMPLEX)); 142*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectSetOptionsPrefix((PetscObject) *dm, "init_")); 143*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMSetFromOptions(*dm)); 144*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectSetOptionsPrefix((PetscObject) *dm, NULL)); 145adcf2cb4SMatthew G. Knepley /* Adapt surface */ 146*5f80ce2aSJacob Faibussowitsch CHKERRQ(AdaptMesh(dm, user)); 147adcf2cb4SMatthew G. Knepley /* Extrude surface to get volume mesh */ 148*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetDimension(*dm, &dim)); 149*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMLocalizeCoordinates(*dm)); 150*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectSetName((PetscObject) *dm, "Mesh")); 151*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMSetFromOptions(*dm)); 152*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMViewFromOptions(*dm, NULL, "-dm_view")); 153adcf2cb4SMatthew G. Knepley PetscFunctionReturn(0); 154adcf2cb4SMatthew G. Knepley } 155adcf2cb4SMatthew G. Knepley 156adcf2cb4SMatthew G. Knepley int main(int argc, char **argv) 157adcf2cb4SMatthew G. Knepley { 158adcf2cb4SMatthew G. Knepley DM dm; 159adcf2cb4SMatthew G. Knepley AppCtx user; 160adcf2cb4SMatthew G. Knepley PetscErrorCode ierr; 161adcf2cb4SMatthew G. Knepley 162adcf2cb4SMatthew G. Knepley ierr = PetscInitialize(&argc, &argv, NULL, help);if (ierr) return ierr; 163*5f80ce2aSJacob Faibussowitsch CHKERRQ(ProcessOptions(PETSC_COMM_WORLD, &user)); 164*5f80ce2aSJacob Faibussowitsch CHKERRQ(CreateMesh(PETSC_COMM_WORLD, &user, &dm)); 165*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMDestroy(&dm)); 166adcf2cb4SMatthew G. Knepley ierr = PetscFinalize(); 167adcf2cb4SMatthew G. Knepley return ierr; 168adcf2cb4SMatthew G. Knepley } 169adcf2cb4SMatthew G. Knepley 170adcf2cb4SMatthew G. Knepley /*TEST 171adcf2cb4SMatthew G. Knepley 172adcf2cb4SMatthew G. Knepley test: 173adcf2cb4SMatthew G. Knepley suffix: 0 174adcf2cb4SMatthew G. Knepley requires: triangle 175d410b0cfSMatthew G. Knepley args: -init_dm_plex_dim 2 -init_dm_plex_box_faces 1,1 -dm_extrude 1 -dm_view 176adcf2cb4SMatthew G. Knepley 177adcf2cb4SMatthew G. Knepley test: # Regularly refine the surface before extrusion 178adcf2cb4SMatthew G. Knepley suffix: 1 179adcf2cb4SMatthew G. Knepley requires: triangle 180d410b0cfSMatthew G. Knepley args: -init_dm_plex_dim 2 -init_dm_refine 2 -dm_extrude 1 -dm_view 181adcf2cb4SMatthew G. Knepley 182adcf2cb4SMatthew G. Knepley test: # Parallel run 183adcf2cb4SMatthew G. Knepley suffix: 2 184adcf2cb4SMatthew G. Knepley requires: triangle 185adcf2cb4SMatthew G. Knepley nsize: 5 186e600fa54SMatthew G. Knepley args: -init_dm_plex_dim 2 -init_dm_refine 3 -petscpartitioner_type simple -dm_extrude 3 -dm_view 187adcf2cb4SMatthew G. Knepley 188adcf2cb4SMatthew G. Knepley test: # adaptively refine the surface before extrusion 189adcf2cb4SMatthew G. Knepley suffix: 3 190adcf2cb4SMatthew G. Knepley requires: triangle 191d410b0cfSMatthew G. Knepley args: -init_dm_plex_dim 2 -init_dm_plex_box_faces 5,5 -adapt -volume_constraint_1 0.01 -volume_constraint_2 0.000625 -dm_extrude 10 192adcf2cb4SMatthew G. Knepley 193adcf2cb4SMatthew G. Knepley TEST*/ 194