xref: /petsc/src/dm/impls/plex/tests/ex10.c (revision 5f80ce2ab25dff0f4601e710601cbbcecf323266)
1c4762a1bSJed Brown static char help[] = "Test for mesh reordering\n\n";
2c4762a1bSJed Brown 
3c4762a1bSJed Brown #include <petscdmplex.h>
4c4762a1bSJed Brown 
5c4762a1bSJed Brown typedef struct {
6c4762a1bSJed Brown   PetscInt  dim;               /* The topological mesh dimension */
7c4762a1bSJed Brown   PetscReal refinementLimit;   /* Maximum volume of a refined cell */
8c4762a1bSJed Brown   PetscInt  numFields;         /* The number of section fields */
9c4762a1bSJed Brown   PetscInt *numComponents;     /* The number of field components */
10c4762a1bSJed Brown   PetscInt *numDof;            /* The dof signature for the section */
11c4762a1bSJed Brown   PetscInt  numGroups;         /* If greater than 1, use grouping in test */
12c4762a1bSJed Brown } AppCtx;
13c4762a1bSJed Brown 
14c4762a1bSJed Brown PetscErrorCode ProcessOptions(AppCtx *options)
15c4762a1bSJed Brown {
16c4762a1bSJed Brown   PetscInt       len;
17c4762a1bSJed Brown   PetscBool      flg;
18c4762a1bSJed Brown   PetscErrorCode ierr;
19c4762a1bSJed Brown 
20c4762a1bSJed Brown   PetscFunctionBegin;
21c4762a1bSJed Brown   options->numFields     = 1;
22c4762a1bSJed Brown   options->numComponents = NULL;
23c4762a1bSJed Brown   options->numDof        = NULL;
24c4762a1bSJed Brown   options->numGroups     = 0;
25c4762a1bSJed Brown 
26c4762a1bSJed Brown   ierr = PetscOptionsBegin(PETSC_COMM_SELF, "", "Meshing Problem Options", "DMPLEX");CHKERRQ(ierr);
27*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsBoundedInt("-num_fields", "The number of section fields", "ex10.c", options->numFields, &options->numFields, NULL,1));
28c4762a1bSJed Brown   if (options->numFields) {
29c4762a1bSJed Brown     len  = options->numFields;
30*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscCalloc1(len, &options->numComponents));
31*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscOptionsIntArray("-num_components", "The number of components per field", "ex10.c", options->numComponents, &len, &flg));
322c71b3e2SJacob Faibussowitsch     PetscCheckFalse(flg && (len != options->numFields),PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Length of components array is %D should be %D", len, options->numFields);
33c4762a1bSJed Brown   }
34*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsBoundedInt("-num_groups", "Group permutation by this many label values", "ex10.c", options->numGroups, &options->numGroups, NULL,0));
35c4762a1bSJed Brown   ierr = PetscOptionsEnd();CHKERRQ(ierr);
36c4762a1bSJed Brown   PetscFunctionReturn(0);
37c4762a1bSJed Brown }
38c4762a1bSJed Brown 
39c4762a1bSJed Brown PetscErrorCode CleanupContext(AppCtx *user)
40c4762a1bSJed Brown {
41c4762a1bSJed Brown   PetscFunctionBegin;
42*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(user->numComponents));
43*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(user->numDof));
44c4762a1bSJed Brown   PetscFunctionReturn(0);
45c4762a1bSJed Brown }
46c4762a1bSJed Brown 
47c4762a1bSJed Brown /* This mesh comes from~\cite{saad2003}, Fig. 2.10, p. 70. */
48c4762a1bSJed Brown PetscErrorCode CreateTestMesh(MPI_Comm comm, DM *dm, AppCtx *options)
49c4762a1bSJed Brown {
50a4a685f2SJacob Faibussowitsch   const PetscInt    cells[16*3]  = {6, 7, 8,   7, 9, 10,  10, 11, 12,  11, 13, 14,   0,  6, 8,  6,  2,  7,   1, 8,  7,   1,  7, 10,
51c4762a1bSJed Brown                                     2, 9, 7,  10, 9,  4,   1, 10, 12,  10,  4, 11,  12, 11, 3,  3, 11, 14,  11, 4, 13,  14, 13,  5};
52a4a685f2SJacob Faibussowitsch   const PetscReal   coords[15*2] = {0, -3,  0, -1,  2, -1,  0,  1,  2, 1,
53c4762a1bSJed Brown                                     0,  3,  1, -2,  1, -1,  0, -2,  2, 0,
54c4762a1bSJed Brown                                     1,  0,  1,  1,  0,  0,  1,  2,  0, 2};
55c4762a1bSJed Brown 
56c4762a1bSJed Brown   PetscFunctionBegin;
57*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMPlexCreateFromCellListPetsc(comm, 2, 16, 15, 3, PETSC_FALSE, cells, 2, coords, dm));
58c4762a1bSJed Brown   PetscFunctionReturn(0);
59c4762a1bSJed Brown }
60c4762a1bSJed Brown 
61c4762a1bSJed Brown PetscErrorCode TestReordering(DM dm, AppCtx *user)
62c4762a1bSJed Brown {
63c4762a1bSJed Brown   DM              pdm;
64c4762a1bSJed Brown   IS              perm;
65c4762a1bSJed Brown   Mat             A, pA;
66c4762a1bSJed Brown   PetscInt        bw, pbw;
67c4762a1bSJed Brown   MatOrderingType order = MATORDERINGRCM;
68c4762a1bSJed Brown 
69c4762a1bSJed Brown   PetscFunctionBegin;
70*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMPlexGetOrdering(dm, order, NULL, &perm));
71*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMPlexPermute(dm, perm, &pdm));
72*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectSetOptionsPrefix((PetscObject) pdm, "perm_"));
73*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSetFromOptions(pdm));
74*5f80ce2aSJacob Faibussowitsch   CHKERRQ(ISDestroy(&perm));
75*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMViewFromOptions(dm,  NULL, "-orig_dm_view"));
76*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMViewFromOptions(pdm, NULL, "-dm_view"));
77*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMCreateMatrix(dm, &A));
78*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMCreateMatrix(pdm, &pA));
79*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatComputeBandwidth(A, 0.0, &bw));
80*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatComputeBandwidth(pA, 0.0, &pbw));
81*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatViewFromOptions(A,  NULL, "-orig_mat_view"));
82*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatViewFromOptions(pA, NULL, "-perm_mat_view"));
83*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&A));
84*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&pA));
85*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMDestroy(&pdm));
86c4762a1bSJed Brown   if (pbw > bw) {
87*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscPrintf(PetscObjectComm((PetscObject) dm), "Ordering method %s increased bandwidth from %D to %D\n", order, bw, pbw));
88c4762a1bSJed Brown   } else {
89*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscPrintf(PetscObjectComm((PetscObject) dm), "Ordering method %s reduced bandwidth from %D to %D\n", order, bw, pbw));
90c4762a1bSJed Brown   }
91c4762a1bSJed Brown   PetscFunctionReturn(0);
92c4762a1bSJed Brown }
93c4762a1bSJed Brown 
94c4762a1bSJed Brown PetscErrorCode CreateGroupLabel(DM dm, PetscInt numGroups, DMLabel *label, AppCtx *options)
95c4762a1bSJed Brown {
96c4762a1bSJed Brown   const PetscInt groupA[10] = {15, 3, 13, 12, 2, 10, 7, 6, 0, 4};
97c4762a1bSJed Brown   const PetscInt groupB[6]  = {14, 11, 9, 1, 8, 5};
98c4762a1bSJed Brown   PetscInt       c;
99c4762a1bSJed Brown 
100c4762a1bSJed Brown   PetscFunctionBegin;
101c4762a1bSJed Brown   if (numGroups < 2) {*label = NULL; PetscFunctionReturn(0);}
1022c71b3e2SJacob Faibussowitsch   PetscCheckFalse(numGroups != 2,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Test only coded for 2 groups, not %D", numGroups);
103*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMLabelCreate(PETSC_COMM_SELF, "groups", label));
104*5f80ce2aSJacob Faibussowitsch   for (c = 0; c < 10; ++c) CHKERRQ(DMLabelSetValue(*label, groupA[c], 101));
105*5f80ce2aSJacob Faibussowitsch   for (c = 0; c < 6;  ++c) CHKERRQ(DMLabelSetValue(*label, groupB[c], 1001));
106c4762a1bSJed Brown   PetscFunctionReturn(0);
107c4762a1bSJed Brown }
108c4762a1bSJed Brown 
109c4762a1bSJed Brown PetscErrorCode TestReorderingByGroup(DM dm, AppCtx *user)
110c4762a1bSJed Brown {
111c4762a1bSJed Brown   DM              pdm;
112c4762a1bSJed Brown   DMLabel         label;
113c4762a1bSJed Brown   Mat             A, pA;
114c4762a1bSJed Brown   MatOrderingType order = MATORDERINGRCM;
115c4762a1bSJed Brown   IS              perm;
116c4762a1bSJed Brown 
117c4762a1bSJed Brown   PetscFunctionBegin;
118*5f80ce2aSJacob Faibussowitsch   CHKERRQ(CreateGroupLabel(dm, user->numGroups, &label, user));
119*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMPlexGetOrdering(dm, order, label, &perm));
120*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMLabelDestroy(&label));
121*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMPlexPermute(dm, perm, &pdm));
122*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectSetOptionsPrefix((PetscObject) pdm, "perm_"));
123*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSetFromOptions(pdm));
124*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMViewFromOptions(dm,  NULL, "-orig_dm_view"));
125*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMViewFromOptions(pdm, NULL, "-perm_dm_view"));
126*5f80ce2aSJacob Faibussowitsch   CHKERRQ(ISDestroy(&perm));
127*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMCreateMatrix(dm, &A));
128*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMCreateMatrix(pdm, &pA));
129*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatViewFromOptions(A,  NULL, "-orig_mat_view"));
130*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatViewFromOptions(pA, NULL, "-perm_mat_view"));
131*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&A));
132*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&pA));
133*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMDestroy(&pdm));
134c4762a1bSJed Brown   PetscFunctionReturn(0);
135c4762a1bSJed Brown }
136c4762a1bSJed Brown 
137c4762a1bSJed Brown int main(int argc, char **argv)
138c4762a1bSJed Brown {
139c4762a1bSJed Brown   DM             dm;
140c4762a1bSJed Brown   PetscSection   s;
141c4762a1bSJed Brown   AppCtx         user;
14230602db0SMatthew G. Knepley   PetscInt       dim;
143c4762a1bSJed Brown   PetscErrorCode ierr;
144c4762a1bSJed Brown 
145c4762a1bSJed Brown   ierr = PetscInitialize(&argc, &argv, NULL, help);if (ierr) return ierr;
146*5f80ce2aSJacob Faibussowitsch   CHKERRQ(ProcessOptions(&user));
147c4762a1bSJed Brown   if (user.numGroups < 1) {
148*5f80ce2aSJacob Faibussowitsch     CHKERRQ(DMCreate(PETSC_COMM_WORLD, &dm));
149*5f80ce2aSJacob Faibussowitsch     CHKERRQ(DMSetType(dm, DMPLEX));
15030602db0SMatthew G. Knepley   } else {
151*5f80ce2aSJacob Faibussowitsch     CHKERRQ(CreateTestMesh(PETSC_COMM_WORLD, &dm, &user));
1520fdc7489SMatthew Knepley   }
153*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSetFromOptions(dm));
154*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMViewFromOptions(dm, NULL, "-dm_view"));
155*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMGetDimension(dm, &dim));
15630602db0SMatthew G. Knepley   {
15730602db0SMatthew G. Knepley     PetscInt  len = (dim+1) * PetscMax(1, user.numFields);
15830602db0SMatthew G. Knepley     PetscBool flg;
15930602db0SMatthew G. Knepley 
160*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscCalloc1(len, &user.numDof));
16130602db0SMatthew G. Knepley     ierr = PetscOptionsBegin(PETSC_COMM_SELF, "", "Meshing Problem Options", "DMPLEX");CHKERRQ(ierr);
162*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscOptionsIntArray("-num_dof", "The dof signature for the section", "ex10.c", user.numDof, &len, &flg));
1632c71b3e2SJacob Faibussowitsch     PetscCheckFalse(flg && (len != (dim+1) * PetscMax(1, user.numFields)),PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Length of dof array is %D should be %D", len, (dim+1) * PetscMax(1, user.numFields));
16430602db0SMatthew G. Knepley     ierr = PetscOptionsEnd();CHKERRQ(ierr);
16530602db0SMatthew G. Knepley   }
16630602db0SMatthew G. Knepley   if (user.numGroups < 1) {
167*5f80ce2aSJacob Faibussowitsch     CHKERRQ(DMSetNumFields(dm, user.numFields));
168*5f80ce2aSJacob Faibussowitsch     CHKERRQ(DMCreateDS(dm));
169*5f80ce2aSJacob Faibussowitsch     CHKERRQ(DMPlexCreateSection(dm, NULL, user.numComponents, user.numDof, 0, NULL, NULL, NULL, NULL, &s));
170*5f80ce2aSJacob Faibussowitsch     CHKERRQ(DMSetLocalSection(dm, s));
171*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSectionDestroy(&s));
172*5f80ce2aSJacob Faibussowitsch     CHKERRQ(TestReordering(dm, &user));
173c4762a1bSJed Brown   } else {
174*5f80ce2aSJacob Faibussowitsch     CHKERRQ(DMSetNumFields(dm, user.numFields));
175*5f80ce2aSJacob Faibussowitsch     CHKERRQ(DMCreateDS(dm));
176*5f80ce2aSJacob Faibussowitsch     CHKERRQ(DMPlexCreateSection(dm, NULL, user.numComponents, user.numDof, 0, NULL, NULL, NULL, NULL, &s));
177*5f80ce2aSJacob Faibussowitsch     CHKERRQ(DMSetLocalSection(dm, s));
178*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSectionDestroy(&s));
179*5f80ce2aSJacob Faibussowitsch     CHKERRQ(TestReorderingByGroup(dm, &user));
180c4762a1bSJed Brown   }
181*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMDestroy(&dm));
182*5f80ce2aSJacob Faibussowitsch   CHKERRQ(CleanupContext(&user));
183c4762a1bSJed Brown   ierr = PetscFinalize();
184c4762a1bSJed Brown   return ierr;
185c4762a1bSJed Brown }
186c4762a1bSJed Brown 
187c4762a1bSJed Brown /*TEST
188c4762a1bSJed Brown 
189c4762a1bSJed Brown   # Two cell tests 0-3
190c4762a1bSJed Brown   test:
191c4762a1bSJed Brown     suffix: 0
1920fdc7489SMatthew Knepley     requires: triangle
19330602db0SMatthew G. Knepley     args: -dm_plex_simplex 1 -num_dof 1,0,0 -mat_view -dm_coord_space 0
194c4762a1bSJed Brown   test:
195c4762a1bSJed Brown     suffix: 1
19630602db0SMatthew G. Knepley     args: -dm_plex_simplex 0 -num_dof 1,0,0 -mat_view -dm_coord_space 0
197c4762a1bSJed Brown   test:
198c4762a1bSJed Brown     suffix: 2
1990fdc7489SMatthew Knepley     requires: ctetgen
20030602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -dm_plex_simplex 1 -num_dof 1,0,0,0 -mat_view -dm_coord_space 0
201c4762a1bSJed Brown   test:
202c4762a1bSJed Brown     suffix: 3
20330602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -dm_plex_simplex 0 -num_dof 1,0,0,0 -mat_view -dm_coord_space 0
204c4762a1bSJed Brown   # Refined tests 4-7
205c4762a1bSJed Brown   test:
206c4762a1bSJed Brown     suffix: 4
207c4762a1bSJed Brown     requires: triangle
20830602db0SMatthew G. Knepley     args: -dm_plex_simplex 1 -dm_refine_volume_limit_pre 0.00625 -num_dof 1,0,0
209c4762a1bSJed Brown   test:
210c4762a1bSJed Brown     suffix: 5
21130602db0SMatthew G. Knepley     args: -dm_plex_simplex 0 -dm_refine 1 -num_dof 1,0,0
212c4762a1bSJed Brown   test:
213c4762a1bSJed Brown     suffix: 6
214c4762a1bSJed Brown     requires: ctetgen
21530602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -dm_plex_simplex 1 -dm_refine_volume_limit_pre 0.00625 -num_dof 1,0,0,0
216c4762a1bSJed Brown   test:
217c4762a1bSJed Brown     suffix: 7
21830602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -dm_plex_simplex 0 -dm_refine 1 -num_dof 1,0,0,0
219c4762a1bSJed Brown   # Parallel tests
220c4762a1bSJed Brown   # Grouping tests
221c4762a1bSJed Brown   test:
222c4762a1bSJed Brown     suffix: group_1
223c4762a1bSJed Brown     args: -num_groups 1 -num_dof 1,0,0 -is_view -orig_mat_view -perm_mat_view
224c4762a1bSJed Brown   test:
225c4762a1bSJed Brown     suffix: group_2
226c4762a1bSJed Brown     args: -num_groups 2 -num_dof 1,0,0 -is_view -perm_mat_view
227c4762a1bSJed Brown 
228c4762a1bSJed Brown TEST*/
229