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