xref: /petsc/src/dm/impls/plex/tests/ex57.c (revision 25538a83be053a25dc3a58593d8b8b46995d4259)
1*25538a83SMatthew G. Knepley static char help[] = "Tests for ephemeral meshes.\n";
2*25538a83SMatthew G. Knepley 
3*25538a83SMatthew G. Knepley #include <petscdmplex.h>
4*25538a83SMatthew G. Knepley #include <petscdmplextransform.h>
5*25538a83SMatthew G. Knepley 
6*25538a83SMatthew G. Knepley /*
7*25538a83SMatthew G. Knepley   Use
8*25538a83SMatthew G. Knepley 
9*25538a83SMatthew G. Knepley     -ref_dm_view -eph_dm_view
10*25538a83SMatthew G. Knepley 
11*25538a83SMatthew G. Knepley   to view the concrete and ephemeral meshes from the first transformation, and
12*25538a83SMatthew G. Knepley 
13*25538a83SMatthew G. Knepley    -ref_dm_sec_view -eph_dm_sec_view
14*25538a83SMatthew G. Knepley 
15*25538a83SMatthew G. Knepley   for the second.
16*25538a83SMatthew G. Knepley */
17*25538a83SMatthew G. Knepley 
18*25538a83SMatthew G. Knepley // Should remove when I have an API for everything
19*25538a83SMatthew G. Knepley #include <petsc/private/dmplextransformimpl.h>
20*25538a83SMatthew G. Knepley 
21*25538a83SMatthew G. Knepley typedef struct {
22*25538a83SMatthew G. Knepley   DMLabel   active;   /* Label for transform */
23*25538a83SMatthew G. Knepley   PetscBool second;   /* Flag to execute a second transformation */
24*25538a83SMatthew G. Knepley   PetscBool concrete; /* Flag to use the concrete mesh for the second transformation */
25*25538a83SMatthew G. Knepley } AppCtx;
26*25538a83SMatthew G. Knepley 
27*25538a83SMatthew G. Knepley static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options)
28*25538a83SMatthew G. Knepley {
29*25538a83SMatthew G. Knepley   PetscInt  cells[1024], Nc = 1024;
30*25538a83SMatthew G. Knepley   PetscBool flg;
31*25538a83SMatthew G. Knepley 
32*25538a83SMatthew G. Knepley   PetscFunctionBeginUser;
33*25538a83SMatthew G. Knepley   options->active   = NULL;
34*25538a83SMatthew G. Knepley   options->second   = PETSC_FALSE;
35*25538a83SMatthew G. Knepley   options->concrete = PETSC_FALSE;
36*25538a83SMatthew G. Knepley 
37*25538a83SMatthew G. Knepley   PetscOptionsBegin(comm, "", "Ephemeral Meshing Options", "DMPLEX");
38*25538a83SMatthew G. Knepley   PetscCall(PetscOptionsIntArray("-cells", "Cells to mark for transformation", "ex57.c", cells, &Nc, &flg));
39*25538a83SMatthew G. Knepley   if (flg) {
40*25538a83SMatthew G. Knepley     PetscCall(DMLabelCreate(comm, "active", &options->active));
41*25538a83SMatthew G. Knepley     for (PetscInt c = 0; c < Nc; ++c) PetscCall(DMLabelSetValue(options->active, cells[c], DM_ADAPT_REFINE));
42*25538a83SMatthew G. Knepley   }
43*25538a83SMatthew G. Knepley   PetscCall(PetscOptionsBool("-second", "Use a second transformation", "ex57.c", options->second, &options->second, &flg));
44*25538a83SMatthew G. Knepley   PetscCall(PetscOptionsBool("-concrete", "Use concrete mesh for the second transformation", "ex57.c", options->concrete, &options->concrete, &flg));
45*25538a83SMatthew G. Knepley   PetscOptionsEnd();
46*25538a83SMatthew G. Knepley   PetscFunctionReturn(0);
47*25538a83SMatthew G. Knepley }
48*25538a83SMatthew G. Knepley 
49*25538a83SMatthew G. Knepley static PetscErrorCode CreateMesh(MPI_Comm comm, DM *dm)
50*25538a83SMatthew G. Knepley {
51*25538a83SMatthew G. Knepley   PetscFunctionBeginUser;
52*25538a83SMatthew G. Knepley   PetscCall(DMCreate(comm, dm));
53*25538a83SMatthew G. Knepley   PetscCall(DMSetType(*dm, DMPLEX));
54*25538a83SMatthew G. Knepley   PetscCall(DMSetFromOptions(*dm));
55*25538a83SMatthew G. Knepley   PetscCall(PetscObjectSetName((PetscObject)*dm, "Mesh"));
56*25538a83SMatthew G. Knepley   PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view"));
57*25538a83SMatthew G. Knepley   PetscFunctionReturn(0);
58*25538a83SMatthew G. Knepley }
59*25538a83SMatthew G. Knepley 
60*25538a83SMatthew G. Knepley static PetscErrorCode CreateTransform(DM dm, DMLabel active, const char prefix[], DMPlexTransform *tr)
61*25538a83SMatthew G. Knepley {
62*25538a83SMatthew G. Knepley   PetscFunctionBeginUser;
63*25538a83SMatthew G. Knepley   PetscCall(DMPlexTransformCreate(PetscObjectComm((PetscObject)dm), tr));
64*25538a83SMatthew G. Knepley   PetscCall(PetscObjectSetName((PetscObject)*tr, "Transform"));
65*25538a83SMatthew G. Knepley   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*tr, prefix));
66*25538a83SMatthew G. Knepley   PetscCall(DMPlexTransformSetDM(*tr, dm));
67*25538a83SMatthew G. Knepley   PetscCall(DMPlexTransformSetActive(*tr, active));
68*25538a83SMatthew G. Knepley   PetscCall(DMPlexTransformSetFromOptions(*tr));
69*25538a83SMatthew G. Knepley   PetscCall(DMPlexTransformSetUp(*tr));
70*25538a83SMatthew G. Knepley 
71*25538a83SMatthew G. Knepley   PetscCall(DMSetApplicationContext(dm, *tr));
72*25538a83SMatthew G. Knepley   PetscCall(PetscObjectViewFromOptions((PetscObject)*tr, NULL, "-dm_plex_transform_view"));
73*25538a83SMatthew G. Knepley   PetscFunctionReturn(0);
74*25538a83SMatthew G. Knepley }
75*25538a83SMatthew G. Knepley 
76*25538a83SMatthew G. Knepley static PetscErrorCode CreateEphemeralMesh(DMPlexTransform tr, DM *tdm)
77*25538a83SMatthew G. Knepley {
78*25538a83SMatthew G. Knepley   PetscFunctionBegin;
79*25538a83SMatthew G. Knepley   PetscCall(DMCreate(PetscObjectComm((PetscObject)tr), tdm));
80*25538a83SMatthew G. Knepley   PetscCall(DMSetType(*tdm, DMPLEX));
81*25538a83SMatthew G. Knepley   PetscCall(DMSetFromOptions(*tdm));
82*25538a83SMatthew G. Knepley 
83*25538a83SMatthew G. Knepley   PetscCall(PetscObjectReference((PetscObject)tr));
84*25538a83SMatthew G. Knepley   PetscCall(DMPlexTransformDestroy(&((DM_Plex *)(*tdm)->data)->tr));
85*25538a83SMatthew G. Knepley   ((DM_Plex *)(*tdm)->data)->tr = tr;
86*25538a83SMatthew G. Knepley 
87*25538a83SMatthew G. Knepley   PetscCall(PetscObjectSetName((PetscObject)*tdm, "Ephemeral Mesh"));
88*25538a83SMatthew G. Knepley   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*tdm, "eph_"));
89*25538a83SMatthew G. Knepley   PetscFunctionReturn(0);
90*25538a83SMatthew G. Knepley }
91*25538a83SMatthew G. Knepley 
92*25538a83SMatthew G. Knepley static PetscErrorCode CreateConcreteMesh(DMPlexTransform tr, DM *rdm)
93*25538a83SMatthew G. Knepley {
94*25538a83SMatthew G. Knepley   DM cdm, codm, rcodm;
95*25538a83SMatthew G. Knepley 
96*25538a83SMatthew G. Knepley   PetscFunctionBegin;
97*25538a83SMatthew G. Knepley   PetscCall(DMPlexTransformGetDM(tr, &cdm));
98*25538a83SMatthew G. Knepley   PetscCall(DMPlexTransformApply(tr, cdm, rdm));
99*25538a83SMatthew G. Knepley   PetscCall(DMSetCoarsenLevel(*rdm, cdm->leveldown));
100*25538a83SMatthew G. Knepley   PetscCall(DMSetRefineLevel(*rdm, cdm->levelup + 1));
101*25538a83SMatthew G. Knepley   PetscCall(DMCopyDisc(cdm, *rdm));
102*25538a83SMatthew G. Knepley   PetscCall(DMGetCoordinateDM(cdm, &codm));
103*25538a83SMatthew G. Knepley   PetscCall(DMGetCoordinateDM(*rdm, &rcodm));
104*25538a83SMatthew G. Knepley   PetscCall(DMCopyDisc(codm, rcodm));
105*25538a83SMatthew G. Knepley   PetscCall(DMPlexTransformCreateDiscLabels(tr, *rdm));
106*25538a83SMatthew G. Knepley   PetscCall(DMSetCoarseDM(*rdm, cdm));
107*25538a83SMatthew G. Knepley   PetscCall(DMPlexSetRegularRefinement(*rdm, PETSC_TRUE));
108*25538a83SMatthew G. Knepley   if (rdm) {
109*25538a83SMatthew G. Knepley     ((DM_Plex *)(*rdm)->data)->printFEM = ((DM_Plex *)cdm->data)->printFEM;
110*25538a83SMatthew G. Knepley     ((DM_Plex *)(*rdm)->data)->printL2  = ((DM_Plex *)cdm->data)->printL2;
111*25538a83SMatthew G. Knepley   }
112*25538a83SMatthew G. Knepley   PetscCall(PetscObjectSetName((PetscObject)*rdm, "Concrete Mesh"));
113*25538a83SMatthew G. Knepley   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*rdm, "ref_"));
114*25538a83SMatthew G. Knepley   PetscFunctionReturn(0);
115*25538a83SMatthew G. Knepley }
116*25538a83SMatthew G. Knepley 
117*25538a83SMatthew G. Knepley static PetscErrorCode CompareMeshes(DM dmA, DM dmB, DM dm)
118*25538a83SMatthew G. Knepley {
119*25538a83SMatthew G. Knepley   PetscInt dim, dimB, pStart, pEnd, pStartB, pEndB;
120*25538a83SMatthew G. Knepley   MPI_Comm comm;
121*25538a83SMatthew G. Knepley 
122*25538a83SMatthew G. Knepley   PetscFunctionBegin;
123*25538a83SMatthew G. Knepley   PetscCall(PetscObjectGetComm((PetscObject)dmA, &comm));
124*25538a83SMatthew G. Knepley   PetscCall(DMGetDimension(dmA, &dim));
125*25538a83SMatthew G. Knepley   PetscCall(DMGetDimension(dmB, &dimB));
126*25538a83SMatthew G. Knepley   PetscCheck(dim == dimB, comm, PETSC_ERR_ARG_INCOMP, "Dimension from dmA %" PetscInt_FMT " != %" PetscInt_FMT " from dmB", dim, dimB);
127*25538a83SMatthew G. Knepley   PetscCall(DMPlexGetChart(dmA, &pStart, &pEnd));
128*25538a83SMatthew G. Knepley   PetscCall(DMPlexGetChart(dmB, &pStartB, &pEndB));
129*25538a83SMatthew G. Knepley   PetscCheck(pStart == pStartB && pEnd == pEndB, comm, PETSC_ERR_ARG_INCOMP, "Chart from dmA (%" PetscInt_FMT ", %" PetscInt_FMT ") does not match (%" PetscInt_FMT ", %" PetscInt_FMT ") for dmB", pStart, pEnd, pStartB, pEndB);
130*25538a83SMatthew G. Knepley   for (PetscInt p = pStart; p < pEnd; ++p) {
131*25538a83SMatthew G. Knepley     const PetscInt *cone, *ornt, *coneB, *orntB;
132*25538a83SMatthew G. Knepley     PetscInt        coneSize, coneSizeB;
133*25538a83SMatthew G. Knepley 
134*25538a83SMatthew G. Knepley     PetscCall(DMPlexGetConeSize(dmA, p, &coneSize));
135*25538a83SMatthew G. Knepley     PetscCall(DMPlexGetConeSize(dmB, p, &coneSizeB));
136*25538a83SMatthew G. Knepley     PetscCheck(coneSize == coneSizeB, comm, PETSC_ERR_ARG_INCOMP, "Cone size for %" PetscInt_FMT " from dmA %" PetscInt_FMT " does not match %" PetscInt_FMT " for dmB", p, coneSize, coneSizeB);
137*25538a83SMatthew G. Knepley     PetscCall(DMPlexGetOrientedCone(dmA, p, &cone, &ornt));
138*25538a83SMatthew G. Knepley     PetscCall(DMPlexGetOrientedCone(dmB, p, &coneB, &orntB));
139*25538a83SMatthew G. Knepley     for (PetscInt c = 0; c < coneSize; ++c) {
140*25538a83SMatthew G. Knepley       PetscCheck(cone[c] == coneB[c] && ornt[c] == orntB[c], comm, PETSC_ERR_ARG_INCOMP, "Cone point %" PetscInt_FMT " for point %" PetscInt_FMT " from dmA (%" PetscInt_FMT ", %" PetscInt_FMT ") does not match (%" PetscInt_FMT ", %" PetscInt_FMT ") for dmB", c, p, cone[c], ornt[c], coneB[c], orntB[c]);
141*25538a83SMatthew G. Knepley     }
142*25538a83SMatthew G. Knepley     PetscCall(DMPlexRestoreOrientedCone(dmA, p, &cone, &ornt));
143*25538a83SMatthew G. Knepley     PetscCall(DMPlexRestoreOrientedCone(dmB, p, &coneB, &orntB));
144*25538a83SMatthew G. Knepley   }
145*25538a83SMatthew G. Knepley   PetscFunctionReturn(0);
146*25538a83SMatthew G. Knepley }
147*25538a83SMatthew G. Knepley 
148*25538a83SMatthew G. Knepley int main(int argc, char *argv[])
149*25538a83SMatthew G. Knepley {
150*25538a83SMatthew G. Knepley   DM              dm, tdm, rdm;
151*25538a83SMatthew G. Knepley   DMPlexTransform tr;
152*25538a83SMatthew G. Knepley   AppCtx          user;
153*25538a83SMatthew G. Knepley   MPI_Comm        comm;
154*25538a83SMatthew G. Knepley 
155*25538a83SMatthew G. Knepley   PetscFunctionBeginUser;
156*25538a83SMatthew G. Knepley   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
157*25538a83SMatthew G. Knepley   comm = PETSC_COMM_WORLD;
158*25538a83SMatthew G. Knepley   PetscCall(ProcessOptions(comm, &user));
159*25538a83SMatthew G. Knepley   PetscCall(CreateMesh(comm, &dm));
160*25538a83SMatthew G. Knepley   PetscCall(CreateTransform(dm, user.active, "first_", &tr));
161*25538a83SMatthew G. Knepley   PetscCall(CreateEphemeralMesh(tr, &tdm));
162*25538a83SMatthew G. Knepley   PetscCall(CreateConcreteMesh(tr, &rdm));
163*25538a83SMatthew G. Knepley   if (user.second) {
164*25538a83SMatthew G. Knepley     DMPlexTransform tr2;
165*25538a83SMatthew G. Knepley     DM              tdm2, rdm2;
166*25538a83SMatthew G. Knepley 
167*25538a83SMatthew G. Knepley     PetscCall(DMViewFromOptions(rdm, NULL, "-dm_sec_view"));
168*25538a83SMatthew G. Knepley     PetscCall(DMViewFromOptions(tdm, NULL, "-dm_sec_view"));
169*25538a83SMatthew G. Knepley     if (user.concrete) PetscCall(CreateTransform(rdm, user.active, "second_", &tr2));
170*25538a83SMatthew G. Knepley     else PetscCall(CreateTransform(tdm, user.active, "second_", &tr2));
171*25538a83SMatthew G. Knepley     PetscCall(CreateEphemeralMesh(tr2, &tdm2));
172*25538a83SMatthew G. Knepley     PetscCall(CreateConcreteMesh(tr2, &rdm2));
173*25538a83SMatthew G. Knepley     PetscCall(DMDestroy(&tdm));
174*25538a83SMatthew G. Knepley     PetscCall(DMDestroy(&rdm));
175*25538a83SMatthew G. Knepley     PetscCall(DMPlexTransformDestroy(&tr2));
176*25538a83SMatthew G. Knepley     tdm = tdm2;
177*25538a83SMatthew G. Knepley     rdm = rdm2;
178*25538a83SMatthew G. Knepley   }
179*25538a83SMatthew G. Knepley   PetscCall(DMViewFromOptions(tdm, NULL, "-dm_view"));
180*25538a83SMatthew G. Knepley   PetscCall(DMViewFromOptions(rdm, NULL, "-dm_view"));
181*25538a83SMatthew G. Knepley   PetscCall(CompareMeshes(rdm, tdm, dm));
182*25538a83SMatthew G. Knepley   PetscCall(DMPlexTransformDestroy(&tr));
183*25538a83SMatthew G. Knepley   PetscCall(DMDestroy(&tdm));
184*25538a83SMatthew G. Knepley   PetscCall(DMDestroy(&rdm));
185*25538a83SMatthew G. Knepley   PetscCall(DMDestroy(&dm));
186*25538a83SMatthew G. Knepley   PetscCall(DMLabelDestroy(&user.active));
187*25538a83SMatthew G. Knepley   PetscCall(PetscFinalize());
188*25538a83SMatthew G. Knepley   return 0;
189*25538a83SMatthew G. Knepley }
190*25538a83SMatthew G. Knepley 
191*25538a83SMatthew G. Knepley /*TEST
192*25538a83SMatthew G. Knepley 
193*25538a83SMatthew G. Knepley   # Tests for regular refinement of whole meshes
194*25538a83SMatthew G. Knepley   test:
195*25538a83SMatthew G. Knepley     suffix: tri
196*25538a83SMatthew G. Knepley     requires: triangle
197*25538a83SMatthew G. Knepley     args: -first_dm_plex_transform_view ::ascii_info_detail
198*25538a83SMatthew G. Knepley 
199*25538a83SMatthew G. Knepley   test:
200*25538a83SMatthew G. Knepley     suffix: quad
201*25538a83SMatthew G. Knepley     args: -dm_plex_simplex 0
202*25538a83SMatthew G. Knepley 
203*25538a83SMatthew G. Knepley   test:
204*25538a83SMatthew G. Knepley     suffix: tet
205*25538a83SMatthew G. Knepley     requires: ctetgen
206*25538a83SMatthew G. Knepley     args: -dm_plex_dim 3
207*25538a83SMatthew G. Knepley 
208*25538a83SMatthew G. Knepley   test:
209*25538a83SMatthew G. Knepley     suffix: hex
210*25538a83SMatthew G. Knepley     args: -dm_plex_dim 3 -dm_plex_simplex 0
211*25538a83SMatthew G. Knepley 
212*25538a83SMatthew G. Knepley   # Tests for filter patches
213*25538a83SMatthew G. Knepley   testset:
214*25538a83SMatthew G. Knepley     args: -first_dm_plex_transform_type transform_filter -ref_dm_view
215*25538a83SMatthew G. Knepley 
216*25538a83SMatthew G. Knepley     test:
217*25538a83SMatthew G. Knepley       suffix: tri_patch
218*25538a83SMatthew G. Knepley       requires: triangle
219*25538a83SMatthew G. Knepley       args: -cells 0,1,2,4
220*25538a83SMatthew G. Knepley 
221*25538a83SMatthew G. Knepley     test:
222*25538a83SMatthew G. Knepley       suffix: quad_patch
223*25538a83SMatthew G. Knepley       args: -dm_plex_simplex 0 -dm_plex_box_faces 3,3 -cells 0,1,3,4
224*25538a83SMatthew G. Knepley 
225*25538a83SMatthew G. Knepley   # Tests for refined filter patches
226*25538a83SMatthew G. Knepley   testset:
227*25538a83SMatthew G. Knepley     args: -first_dm_plex_transform_type transform_filter -ref_dm_view -second
228*25538a83SMatthew G. Knepley 
229*25538a83SMatthew G. Knepley     test:
230*25538a83SMatthew G. Knepley       suffix: tri_patch_ref
231*25538a83SMatthew G. Knepley       requires: triangle
232*25538a83SMatthew G. Knepley       args: -cells 0,1,2,4
233*25538a83SMatthew G. Knepley 
234*25538a83SMatthew G. Knepley     test:
235*25538a83SMatthew G. Knepley       suffix: tri_patch_ref_concrete
236*25538a83SMatthew G. Knepley       requires: triangle
237*25538a83SMatthew G. Knepley       args: -cells 0,1,2,4 -concrete -first_dm_plex_transform_view ::ascii_info_detail
238*25538a83SMatthew G. Knepley 
239*25538a83SMatthew G. Knepley   # Tests for boundary layer refinement
240*25538a83SMatthew G. Knepley   test:
241*25538a83SMatthew G. Knepley     suffix: quad_bl
242*25538a83SMatthew G. Knepley     args: -dm_plex_simplex 0 -dm_plex_dim 1 -dm_plex_box_faces 5 -dm_extrude 2 -cells 0,2,4,6,8 \
243*25538a83SMatthew G. Knepley           -first_dm_plex_transform_type refine_boundary_layer -first_dm_plex_transform_bl_splits 4 \
244*25538a83SMatthew G. Knepley           -ref_dm_view
245*25538a83SMatthew G. Knepley 
246*25538a83SMatthew G. Knepley TEST*/
247