100d473e3SJoe Wallwork static char help[] = "Test metric utils in the uniform, isotropic case.\n\n"; 200d473e3SJoe Wallwork 300d473e3SJoe Wallwork #include <petscdmplex.h> 400d473e3SJoe Wallwork 5d71ae5a4SJacob Faibussowitsch static PetscErrorCode bowl(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) 6d71ae5a4SJacob Faibussowitsch { 700d473e3SJoe Wallwork PetscInt d; 800d473e3SJoe Wallwork 900d473e3SJoe Wallwork *u = 0.0; 1000d473e3SJoe Wallwork for (d = 0; d < dim; d++) *u += 0.5 * (x[d] - 0.5) * (x[d] - 0.5); 1100d473e3SJoe Wallwork 12*3ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 1300d473e3SJoe Wallwork } 1400d473e3SJoe Wallwork 15d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreateIndicator(DM dm, Vec *indicator, DM *dmIndi) 16d71ae5a4SJacob Faibussowitsch { 17d8b80fabSJoe Wallwork MPI_Comm comm; 18d8b80fabSJoe Wallwork PetscFE fe; 19d8b80fabSJoe Wallwork PetscInt dim; 20d8b80fabSJoe Wallwork 21d8b80fabSJoe Wallwork PetscFunctionBeginUser; 229566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 239566063dSJacob Faibussowitsch PetscCall(DMClone(dm, dmIndi)); 249566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 259566063dSJacob Faibussowitsch PetscCall(PetscFECreateLagrange(comm, dim, 1, PETSC_TRUE, 1, PETSC_DETERMINE, &fe)); 269566063dSJacob Faibussowitsch PetscCall(DMSetField(*dmIndi, 0, NULL, (PetscObject)fe)); 279566063dSJacob Faibussowitsch PetscCall(DMCreateDS(*dmIndi)); 289566063dSJacob Faibussowitsch PetscCall(PetscFEDestroy(&fe)); 299566063dSJacob Faibussowitsch PetscCall(DMCreateLocalVector(*dmIndi, indicator)); 30*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 31d8b80fabSJoe Wallwork } 32d8b80fabSJoe Wallwork 33d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv) 34d71ae5a4SJacob Faibussowitsch { 35e600fa54SMatthew G. Knepley DM dm, dmAdapt; 3621b3e102SJoe Wallwork DMLabel bdLabel = NULL, rgLabel = NULL; 3700d473e3SJoe Wallwork MPI_Comm comm; 3841473654SJoe Wallwork PetscBool uniform = PETSC_FALSE, isotropic = PETSC_FALSE, noTagging = PETSC_FALSE; 39e600fa54SMatthew G. Knepley PetscInt dim; 4000d473e3SJoe Wallwork PetscReal scaling = 1.0; 4100d473e3SJoe Wallwork Vec metric; 4200d473e3SJoe Wallwork 4300d473e3SJoe Wallwork /* Set up */ 44327415f7SBarry Smith PetscFunctionBeginUser; 459566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 4600d473e3SJoe Wallwork comm = PETSC_COMM_WORLD; 47d0609cedSBarry Smith PetscOptionsBegin(comm, "", "Mesh adaptation options", "DMPLEX"); 489566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-noTagging", "Should tag preservation testing be turned off?", "ex60.c", noTagging, &noTagging, NULL)); 49d0609cedSBarry Smith PetscOptionsEnd(); 5000d473e3SJoe Wallwork 5100d473e3SJoe Wallwork /* Create box mesh */ 529566063dSJacob Faibussowitsch PetscCall(DMCreate(comm, &dm)); 539566063dSJacob Faibussowitsch PetscCall(DMSetType(dm, DMPLEX)); 549566063dSJacob Faibussowitsch PetscCall(DMSetFromOptions(dm)); 559566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)dm, "DM_init")); 569566063dSJacob Faibussowitsch PetscCall(DMViewFromOptions(dm, NULL, "-initial_mesh_view")); 579566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 5800d473e3SJoe Wallwork 5941473654SJoe Wallwork /* Set tags to be preserved */ 6041473654SJoe Wallwork if (!noTagging) { 6141473654SJoe Wallwork DM cdm; 6241473654SJoe Wallwork PetscInt cStart, cEnd, c, fStart, fEnd, f, vStart, vEnd; 6341473654SJoe Wallwork const PetscScalar *coords; 6441473654SJoe Wallwork Vec coordinates; 6541473654SJoe Wallwork 6641473654SJoe Wallwork /* Cell tags */ 678fb5bd83SMatthew G. Knepley PetscCall(DMGetCoordinatesLocalSetUp(dm)); 689566063dSJacob Faibussowitsch PetscCall(DMCreateLabel(dm, "Cell Sets")); 699566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, "Cell Sets", &rgLabel)); 709566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd)); 7141473654SJoe Wallwork for (c = cStart; c < cEnd; ++c) { 7241473654SJoe Wallwork PetscReal centroid[3], volume, x; 7341473654SJoe Wallwork 749566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFVM(dm, c, &volume, centroid, NULL)); 7541473654SJoe Wallwork x = centroid[0]; 769566063dSJacob Faibussowitsch if (x < 0.5) PetscCall(DMLabelSetValue(rgLabel, c, 3)); 779566063dSJacob Faibussowitsch else PetscCall(DMLabelSetValue(rgLabel, c, 4)); 7841473654SJoe Wallwork } 7941473654SJoe Wallwork 8041473654SJoe Wallwork /* Face tags */ 819566063dSJacob Faibussowitsch PetscCall(DMCreateLabel(dm, "Face Sets")); 829566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, "Face Sets", &bdLabel)); 839566063dSJacob Faibussowitsch PetscCall(DMPlexMarkBoundaryFaces(dm, 1, bdLabel)); 849566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd)); 859566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd)); 869566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDM(dm, &cdm)); 879566063dSJacob Faibussowitsch PetscCall(DMGetCoordinatesLocal(dm, &coordinates)); 889566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(coordinates, &coords)); 8941473654SJoe Wallwork for (f = fStart; f < fEnd; ++f) { 9041473654SJoe Wallwork PetscBool flg = PETSC_TRUE; 9141473654SJoe Wallwork PetscInt *closure = NULL, closureSize, cl; 9241473654SJoe Wallwork PetscReal eps = 1.0e-08; 9341473654SJoe Wallwork 949566063dSJacob Faibussowitsch PetscCall(DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &closure)); 9541473654SJoe Wallwork for (cl = 0; cl < closureSize * 2; cl += 2) { 9641473654SJoe Wallwork PetscInt off = closure[cl]; 9741473654SJoe Wallwork PetscReal *x; 9841473654SJoe Wallwork 9941473654SJoe Wallwork if ((off < vStart) || (off >= vEnd)) continue; 1009566063dSJacob Faibussowitsch PetscCall(DMPlexPointLocalRead(cdm, off, coords, &x)); 10141473654SJoe Wallwork if ((x[0] < 0.5 - eps) || (x[0] > 0.5 + eps)) flg = PETSC_FALSE; 10241473654SJoe Wallwork } 1039566063dSJacob Faibussowitsch if (flg) PetscCall(DMLabelSetValue(bdLabel, f, 2)); 1049566063dSJacob Faibussowitsch PetscCall(DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &closure)); 10541473654SJoe Wallwork } 1069566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(coordinates, &coords)); 10741473654SJoe Wallwork } 10841473654SJoe Wallwork 10900d473e3SJoe Wallwork /* Construct metric */ 1109566063dSJacob Faibussowitsch PetscCall(DMPlexMetricSetFromOptions(dm)); 1119566063dSJacob Faibussowitsch PetscCall(DMPlexMetricIsUniform(dm, &uniform)); 1129566063dSJacob Faibussowitsch PetscCall(DMPlexMetricIsIsotropic(dm, &isotropic)); 11300d473e3SJoe Wallwork if (uniform) { 1149566063dSJacob Faibussowitsch PetscCall(DMPlexMetricCreateUniform(dm, 0, scaling, &metric)); 1159371c9d4SSatish Balay } else { 11600d473e3SJoe Wallwork DM dmIndi; 11700d473e3SJoe Wallwork Vec indicator; 11800d473e3SJoe Wallwork 11900d473e3SJoe Wallwork /* Construct "error indicator" */ 1209566063dSJacob Faibussowitsch PetscCall(CreateIndicator(dm, &indicator, &dmIndi)); 121e5697243SJoe Wallwork if (isotropic) { 12200d473e3SJoe Wallwork /* Isotropic case: just specify unity */ 1239566063dSJacob Faibussowitsch PetscCall(VecSet(indicator, scaling)); 1249566063dSJacob Faibussowitsch PetscCall(DMPlexMetricCreateIsotropic(dm, 0, indicator, &metric)); 12500d473e3SJoe Wallwork 12600d473e3SJoe Wallwork } else { 127d8b80fabSJoe Wallwork PetscFE fe; 12800d473e3SJoe Wallwork 12900d473e3SJoe Wallwork /* 'Anisotropic' case: approximate the identity by recovering the Hessian of a parabola */ 13000d473e3SJoe Wallwork DM dmGrad; 13100d473e3SJoe Wallwork PetscErrorCode (*funcs[1])(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *) = {bowl}; 13200d473e3SJoe Wallwork Vec gradient; 13300d473e3SJoe Wallwork 13400d473e3SJoe Wallwork /* Project the parabola into P1 space */ 1359566063dSJacob Faibussowitsch PetscCall(DMProjectFunctionLocal(dmIndi, 0.0, funcs, NULL, INSERT_ALL_VALUES, indicator)); 13600d473e3SJoe Wallwork 13700d473e3SJoe Wallwork /* Approximate the gradient */ 1389566063dSJacob Faibussowitsch PetscCall(DMClone(dmIndi, &dmGrad)); 1399566063dSJacob Faibussowitsch PetscCall(PetscFECreateLagrange(comm, dim, dim, PETSC_TRUE, 1, PETSC_DETERMINE, &fe)); 1409566063dSJacob Faibussowitsch PetscCall(DMSetField(dmGrad, 0, NULL, (PetscObject)fe)); 1419566063dSJacob Faibussowitsch PetscCall(DMCreateDS(dmGrad)); 1429566063dSJacob Faibussowitsch PetscCall(PetscFEDestroy(&fe)); 1439566063dSJacob Faibussowitsch PetscCall(DMCreateLocalVector(dmGrad, &gradient)); 1449566063dSJacob Faibussowitsch PetscCall(DMPlexComputeGradientClementInterpolant(dmIndi, indicator, gradient)); 1459566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(gradient, NULL, "-adapt_gradient_view")); 14600d473e3SJoe Wallwork 14700d473e3SJoe Wallwork /* Approximate the Hessian */ 1489566063dSJacob Faibussowitsch PetscCall(DMPlexMetricCreate(dm, 0, &metric)); 1499566063dSJacob Faibussowitsch PetscCall(DMPlexComputeGradientClementInterpolant(dmGrad, gradient, metric)); 1509566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(metric, NULL, "-adapt_hessian_view")); 1519566063dSJacob Faibussowitsch PetscCall(VecDestroy(&gradient)); 1529566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dmGrad)); 15300d473e3SJoe Wallwork } 1549566063dSJacob Faibussowitsch PetscCall(VecDestroy(&indicator)); 1559566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dmIndi)); 15600d473e3SJoe Wallwork } 15700d473e3SJoe Wallwork 15800d473e3SJoe Wallwork /* Test metric routines */ 15900d473e3SJoe Wallwork { 160f49e87b0SJoe Wallwork DM dmDet; 16100d473e3SJoe Wallwork PetscReal errornorm, norm, tol = 1.0e-10, weights[2] = {0.8, 0.2}; 162f49e87b0SJoe Wallwork Vec metric1, metric2, metricComb, determinant; 16300d473e3SJoe Wallwork Vec metrics[2]; 16400d473e3SJoe Wallwork 1659566063dSJacob Faibussowitsch PetscCall(VecDuplicate(metric, &metric1)); 1669566063dSJacob Faibussowitsch PetscCall(VecSet(metric1, 0)); 1679566063dSJacob Faibussowitsch PetscCall(VecAXPY(metric1, 0.625, metric)); 1689566063dSJacob Faibussowitsch PetscCall(VecDuplicate(metric, &metric2)); 1699566063dSJacob Faibussowitsch PetscCall(VecSet(metric2, 0)); 1709566063dSJacob Faibussowitsch PetscCall(VecAXPY(metric2, 2.5, metric)); 17100d473e3SJoe Wallwork metrics[0] = metric1; 17200d473e3SJoe Wallwork metrics[1] = metric2; 17300d473e3SJoe Wallwork 17400d473e3SJoe Wallwork /* Test metric average */ 17540a2a1afSJoe Wallwork PetscCall(DMPlexMetricCreate(dm, 0, &metricComb)); 17640a2a1afSJoe Wallwork PetscCall(DMPlexMetricAverage(dm, 2, weights, metrics, metricComb)); 1779566063dSJacob Faibussowitsch PetscCall(VecAXPY(metricComb, -1, metric)); 1789566063dSJacob Faibussowitsch PetscCall(VecNorm(metric, NORM_2, &norm)); 1799566063dSJacob Faibussowitsch PetscCall(VecNorm(metricComb, NORM_2, &errornorm)); 18000d473e3SJoe Wallwork errornorm /= norm; 18163a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(comm, "Metric average L2 error: %.4f%%\n", (double)(100 * errornorm))); 18240a2a1afSJoe Wallwork PetscCheck(errornorm < tol, comm, PETSC_ERR_ARG_OUTOFRANGE, "Metric average test failed"); 18300d473e3SJoe Wallwork 18400d473e3SJoe Wallwork /* Test metric intersection */ 18561a4b293SJoe Wallwork PetscCall(DMPlexMetricDeterminantCreate(dm, 0, &determinant, &dmDet)); 18661a4b293SJoe Wallwork if (!isotropic) { 18761a4b293SJoe Wallwork PetscCall(DMPlexMetricEnforceSPD(dm, metrics[0], PETSC_FALSE, PETSC_FALSE, metricComb, determinant)); 18861a4b293SJoe Wallwork PetscCall(VecCopy(metricComb, metrics[0])); 18961a4b293SJoe Wallwork PetscCall(DMPlexMetricEnforceSPD(dm, metrics[1], PETSC_FALSE, PETSC_FALSE, metricComb, determinant)); 19061a4b293SJoe Wallwork PetscCall(VecCopy(metricComb, metrics[1])); 19161a4b293SJoe Wallwork } 1926f71502aSJoe Wallwork PetscCall(DMPlexMetricIntersection(dm, 2, metrics, metricComb)); 1936f71502aSJoe Wallwork PetscCall(VecAXPY(metricComb, -1, metric2)); 1949566063dSJacob Faibussowitsch PetscCall(VecNorm(metricComb, NORM_2, &errornorm)); 19500d473e3SJoe Wallwork errornorm /= norm; 19663a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(comm, "Metric intersection L2 error: %.4f%%\n", (double)(100 * errornorm))); 19740a2a1afSJoe Wallwork PetscCheck(errornorm < tol, comm, PETSC_ERR_ARG_OUTOFRANGE, "Metric intersection test failed"); 1989566063dSJacob Faibussowitsch PetscCall(VecDestroy(&metric2)); 1999566063dSJacob Faibussowitsch PetscCall(VecDestroy(&metricComb)); 20000d473e3SJoe Wallwork 20100d473e3SJoe Wallwork /* Test metric SPD enforcement */ 20240a2a1afSJoe Wallwork PetscCall(DMPlexMetricEnforceSPD(dm, metric, PETSC_TRUE, PETSC_TRUE, metric1, determinant)); 203e5697243SJoe Wallwork if (isotropic) { 204f49e87b0SJoe Wallwork Vec err; 205f49e87b0SJoe Wallwork 2069566063dSJacob Faibussowitsch PetscCall(VecDuplicate(determinant, &err)); 2079566063dSJacob Faibussowitsch PetscCall(VecSet(err, 1.0)); 2089566063dSJacob Faibussowitsch PetscCall(VecNorm(err, NORM_2, &norm)); 2099566063dSJacob Faibussowitsch PetscCall(VecAXPY(err, -1, determinant)); 2109566063dSJacob Faibussowitsch PetscCall(VecNorm(err, NORM_2, &errornorm)); 2119566063dSJacob Faibussowitsch PetscCall(VecDestroy(&err)); 212f49e87b0SJoe Wallwork errornorm /= norm; 21363a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(comm, "Metric determinant L2 error: %.4f%%\n", (double)(100 * errornorm))); 21440a2a1afSJoe Wallwork PetscCheck(errornorm < tol, comm, PETSC_ERR_ARG_OUTOFRANGE, "Determinant is not unit"); 2159566063dSJacob Faibussowitsch PetscCall(VecAXPY(metric1, -1, metric)); 2169566063dSJacob Faibussowitsch PetscCall(VecNorm(metric1, NORM_2, &errornorm)); 21700d473e3SJoe Wallwork errornorm /= norm; 21863a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(comm, "Metric SPD enforcement L2 error: %.4f%%\n", (double)(100 * errornorm))); 21940a2a1afSJoe Wallwork PetscCheck(errornorm < tol, comm, PETSC_ERR_ARG_OUTOFRANGE, "Metric SPD enforcement test failed"); 22000d473e3SJoe Wallwork } 22100d473e3SJoe Wallwork 22200d473e3SJoe Wallwork /* Test metric normalization */ 22340a2a1afSJoe Wallwork PetscCall(DMPlexMetricNormalize(dm, metric, PETSC_TRUE, PETSC_TRUE, metric1, determinant)); 224e5697243SJoe Wallwork if (isotropic) { 225e5697243SJoe Wallwork PetscReal target; 226e5697243SJoe Wallwork 2279566063dSJacob Faibussowitsch PetscCall(DMPlexMetricGetTargetComplexity(dm, &target)); 228e5697243SJoe Wallwork scaling = PetscPowReal(target, 2.0 / dim); 229d8b80fabSJoe Wallwork if (uniform) { 2309566063dSJacob Faibussowitsch PetscCall(DMPlexMetricCreateUniform(dm, 0, scaling, &metric2)); 231d8b80fabSJoe Wallwork } else { 232d8b80fabSJoe Wallwork DM dmIndi; 233d8b80fabSJoe Wallwork Vec indicator; 234d8b80fabSJoe Wallwork 2359566063dSJacob Faibussowitsch PetscCall(CreateIndicator(dm, &indicator, &dmIndi)); 2369566063dSJacob Faibussowitsch PetscCall(VecSet(indicator, scaling)); 2379566063dSJacob Faibussowitsch PetscCall(DMPlexMetricCreateIsotropic(dm, 0, indicator, &metric2)); 2389566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dmIndi)); 2399566063dSJacob Faibussowitsch PetscCall(VecDestroy(&indicator)); 240d8b80fabSJoe Wallwork } 2419566063dSJacob Faibussowitsch PetscCall(VecAXPY(metric2, -1, metric1)); 2429566063dSJacob Faibussowitsch PetscCall(VecNorm(metric2, NORM_2, &errornorm)); 24300d473e3SJoe Wallwork errornorm /= norm; 24463a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(comm, "Metric normalization L2 error: %.4f%%\n", (double)(100 * errornorm))); 24540a2a1afSJoe Wallwork PetscCheck(errornorm < tol, comm, PETSC_ERR_ARG_OUTOFRANGE, "Metric normalization test failed"); 24600d473e3SJoe Wallwork } 24740a2a1afSJoe Wallwork PetscCall(VecDestroy(&determinant)); 24840a2a1afSJoe Wallwork PetscCall(DMDestroy(&dmDet)); 2499566063dSJacob Faibussowitsch PetscCall(VecCopy(metric1, metric)); 2509566063dSJacob Faibussowitsch PetscCall(VecDestroy(&metric2)); 2519566063dSJacob Faibussowitsch PetscCall(VecDestroy(&metric1)); 25200d473e3SJoe Wallwork } 25300d473e3SJoe Wallwork 25400d473e3SJoe Wallwork /* Adapt the mesh */ 2559566063dSJacob Faibussowitsch PetscCall(DMAdaptMetric(dm, metric, bdLabel, rgLabel, &dmAdapt)); 2569566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm)); 2579566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)dmAdapt, "DM_adapted")); 2589566063dSJacob Faibussowitsch PetscCall(VecDestroy(&metric)); 2599566063dSJacob Faibussowitsch PetscCall(DMViewFromOptions(dmAdapt, NULL, "-adapted_mesh_view")); 26000d473e3SJoe Wallwork 26141473654SJoe Wallwork /* Test tag preservation */ 26241473654SJoe Wallwork if (!noTagging) { 26341473654SJoe Wallwork PetscBool hasTag; 26441473654SJoe Wallwork PetscInt size; 26541473654SJoe Wallwork 2669566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dmAdapt, "Face Sets", &bdLabel)); 2679566063dSJacob Faibussowitsch PetscCall(DMLabelHasStratum(bdLabel, 1, &hasTag)); 26828b400f6SJacob Faibussowitsch PetscCheck(hasTag, comm, PETSC_ERR_ARG_OUTOFRANGE, "Adapted mesh does not have face tag 1"); 2699566063dSJacob Faibussowitsch PetscCall(DMLabelHasStratum(bdLabel, 2, &hasTag)); 27028b400f6SJacob Faibussowitsch PetscCheck(hasTag, comm, PETSC_ERR_ARG_OUTOFRANGE, "Adapted mesh does not have face tag 2"); 2719566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(bdLabel, &size)); 27263a3b9bcSJacob Faibussowitsch PetscCheck(size == 2, comm, PETSC_ERR_ARG_OUTOFRANGE, "Adapted mesh has the wrong number of face tags (got %" PetscInt_FMT ", expected 2)", size); 27341473654SJoe Wallwork 2749566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dmAdapt, "Cell Sets", &rgLabel)); 2759566063dSJacob Faibussowitsch PetscCall(DMLabelHasStratum(rgLabel, 3, &hasTag)); 27628b400f6SJacob Faibussowitsch PetscCheck(hasTag, comm, PETSC_ERR_ARG_OUTOFRANGE, "Adapted mesh does not have cell tag 3"); 2779566063dSJacob Faibussowitsch PetscCall(DMLabelHasStratum(rgLabel, 4, &hasTag)); 27828b400f6SJacob Faibussowitsch PetscCheck(hasTag, comm, PETSC_ERR_ARG_OUTOFRANGE, "Adapted mesh does not have cell tag 4"); 2799566063dSJacob Faibussowitsch PetscCall(DMLabelGetNumValues(rgLabel, &size)); 28063a3b9bcSJacob Faibussowitsch PetscCheck(size == 2, comm, PETSC_ERR_ARG_OUTOFRANGE, "Adapted mesh has the wrong number of cell tags (got %" PetscInt_FMT ", expected 2)", size); 28141473654SJoe Wallwork } 28241473654SJoe Wallwork 28300d473e3SJoe Wallwork /* Clean up */ 2849566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dmAdapt)); 2859566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 28600d473e3SJoe Wallwork return 0; 28700d473e3SJoe Wallwork } 28800d473e3SJoe Wallwork 28900d473e3SJoe Wallwork /*TEST 29000d473e3SJoe Wallwork 29180f7b1e7SJoe Wallwork testset: 29280f7b1e7SJoe Wallwork requires: pragmatic 293e600fa54SMatthew G. Knepley args: -dm_plex_box_faces 4,4 -dm_plex_metric_target_complexity 100 -dm_adaptor pragmatic -noTagging 29480f7b1e7SJoe Wallwork 295dd0671eeSJoe Wallwork test: 296dd0671eeSJoe Wallwork suffix: uniform_2d_pragmatic 297d8b80fabSJoe Wallwork args: -dm_plex_metric_uniform 29800d473e3SJoe Wallwork test: 299dd0671eeSJoe Wallwork suffix: iso_2d_pragmatic 300d8b80fabSJoe Wallwork args: -dm_plex_metric_isotropic 30100d473e3SJoe Wallwork test: 302dd0671eeSJoe Wallwork suffix: hessian_2d_pragmatic 30380f7b1e7SJoe Wallwork 30480f7b1e7SJoe Wallwork testset: 30580f7b1e7SJoe Wallwork requires: pragmatic tetgen 306e600fa54SMatthew G. Knepley args: -dm_plex_dim 3 -dm_plex_box_faces 4,4,4 -dm_plex_metric_target_complexity 100 -dm_adaptor pragmatic -noTagging 30780f7b1e7SJoe Wallwork 30880f7b1e7SJoe Wallwork test: 30980f7b1e7SJoe Wallwork suffix: uniform_3d_pragmatic 310d8b80fabSJoe Wallwork args: -dm_plex_metric_uniform -noTagging 31180f7b1e7SJoe Wallwork test: 31280f7b1e7SJoe Wallwork suffix: iso_3d_pragmatic 313d8b80fabSJoe Wallwork args: -dm_plex_metric_isotropic -noTagging 31400d473e3SJoe Wallwork test: 315dd0671eeSJoe Wallwork suffix: hessian_3d_pragmatic 31680f7b1e7SJoe Wallwork 31780f7b1e7SJoe Wallwork testset: 31880f7b1e7SJoe Wallwork requires: mmg 319e600fa54SMatthew G. Knepley args: -dm_plex_box_faces 4,4 -dm_plex_metric_target_complexity 100 -dm_adaptor mmg 32080f7b1e7SJoe Wallwork 32100d473e3SJoe Wallwork test: 322dd0671eeSJoe Wallwork suffix: uniform_2d_mmg 323d8b80fabSJoe Wallwork args: -dm_plex_metric_uniform 324dd0671eeSJoe Wallwork test: 325dd0671eeSJoe Wallwork suffix: iso_2d_mmg 326d8b80fabSJoe Wallwork args: -dm_plex_metric_isotropic 327dd0671eeSJoe Wallwork test: 328dd0671eeSJoe Wallwork suffix: hessian_2d_mmg 32980f7b1e7SJoe Wallwork 33080f7b1e7SJoe Wallwork testset: 33180f7b1e7SJoe Wallwork requires: mmg tetgen 332e600fa54SMatthew G. Knepley args: -dm_plex_dim 3 -dm_plex_box_faces 4,4,4 -dm_plex_metric_target_complexity 100 -dm_adaptor mmg 33380f7b1e7SJoe Wallwork 33480f7b1e7SJoe Wallwork test: 33580f7b1e7SJoe Wallwork suffix: uniform_3d_mmg 336d8b80fabSJoe Wallwork args: -dm_plex_metric_uniform 33780f7b1e7SJoe Wallwork test: 33880f7b1e7SJoe Wallwork suffix: iso_3d_mmg 339d8b80fabSJoe Wallwork args: -dm_plex_metric_isotropic 340dd0671eeSJoe Wallwork test: 341dd0671eeSJoe Wallwork suffix: hessian_3d_mmg 34280f7b1e7SJoe Wallwork 34380f7b1e7SJoe Wallwork testset: 34480f7b1e7SJoe Wallwork requires: parmmg tetgen 34580f7b1e7SJoe Wallwork nsize: 2 346e600fa54SMatthew G. Knepley args: -dm_plex_dim 3 -dm_plex_box_faces 4,4,4 -dm_plex_metric_target_complexity 100 -dm_adaptor parmmg 34780f7b1e7SJoe Wallwork 348dd0671eeSJoe Wallwork test: 349dd0671eeSJoe Wallwork suffix: uniform_3d_parmmg 350d8b80fabSJoe Wallwork args: -dm_plex_metric_uniform 351dd0671eeSJoe Wallwork test: 352dd0671eeSJoe Wallwork suffix: iso_3d_parmmg 353d8b80fabSJoe Wallwork args: -dm_plex_metric_isotropic 354dd0671eeSJoe Wallwork test: 355dd0671eeSJoe Wallwork suffix: hessian_3d_parmmg 35600d473e3SJoe Wallwork 35700d473e3SJoe Wallwork TEST*/ 358