100d473e3SJoe Wallwork static char help[] = "Test metric utils in the uniform, isotropic case.\n\n";
200d473e3SJoe Wallwork
300d473e3SJoe Wallwork #include <petscdmplex.h>
400d473e3SJoe Wallwork
bowl(PetscInt dim,PetscReal time,const PetscReal x[],PetscInt Nc,PetscScalar * u,PetscCtx ctx)5*2a8381b2SBarry Smith static PetscErrorCode bowl(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, PetscCtx 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
123ba16761SJacob Faibussowitsch return PETSC_SUCCESS;
1300d473e3SJoe Wallwork }
1400d473e3SJoe Wallwork
CreateIndicator(DM dm,Vec * indicator,DM * dmIndi)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));
303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
31d8b80fabSJoe Wallwork }
32d8b80fabSJoe Wallwork
main(int argc,char ** argv)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