xref: /petsc/src/dm/impls/plex/tests/ex10.c (revision 31d78bcd2b98084dc1368b20eb1129c8b9fb39fe)
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 
ProcessOptions(AppCtx * options)14d71ae5a4SJacob Faibussowitsch PetscErrorCode ProcessOptions(AppCtx *options)
15d71ae5a4SJacob Faibussowitsch {
16c4762a1bSJed Brown   PetscInt  len;
17c4762a1bSJed Brown   PetscBool flg;
18c4762a1bSJed Brown 
19c4762a1bSJed Brown   PetscFunctionBegin;
20c4762a1bSJed Brown   options->numFields     = 1;
21c4762a1bSJed Brown   options->numComponents = NULL;
22c4762a1bSJed Brown   options->numDof        = NULL;
23c4762a1bSJed Brown   options->numGroups     = 0;
24c4762a1bSJed Brown 
25d0609cedSBarry Smith   PetscOptionsBegin(PETSC_COMM_SELF, "", "Meshing Problem Options", "DMPLEX");
269566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-num_fields", "The number of section fields", "ex10.c", options->numFields, &options->numFields, NULL, 1));
27c4762a1bSJed Brown   if (options->numFields) {
28c4762a1bSJed Brown     len = options->numFields;
299566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(len, &options->numComponents));
309566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray("-num_components", "The number of components per field", "ex10.c", options->numComponents, &len, &flg));
3163a3b9bcSJacob Faibussowitsch     PetscCheck(!flg || !(len != options->numFields), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Length of components array is %" PetscInt_FMT " should be %" PetscInt_FMT, len, options->numFields);
32c4762a1bSJed Brown   }
339566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-num_groups", "Group permutation by this many label values", "ex10.c", options->numGroups, &options->numGroups, NULL, 0));
34d0609cedSBarry Smith   PetscOptionsEnd();
35*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
36c4762a1bSJed Brown }
37c4762a1bSJed Brown 
CleanupContext(AppCtx * user)38d71ae5a4SJacob Faibussowitsch PetscErrorCode CleanupContext(AppCtx *user)
39d71ae5a4SJacob Faibussowitsch {
40c4762a1bSJed Brown   PetscFunctionBegin;
419566063dSJacob Faibussowitsch   PetscCall(PetscFree(user->numComponents));
429566063dSJacob Faibussowitsch   PetscCall(PetscFree(user->numDof));
43*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
44c4762a1bSJed Brown }
45c4762a1bSJed Brown 
46c4762a1bSJed Brown /* This mesh comes from~\cite{saad2003}, Fig. 2.10, p. 70. */
CreateTestMesh(MPI_Comm comm,DM * dm,AppCtx * options)47d71ae5a4SJacob Faibussowitsch PetscErrorCode CreateTestMesh(MPI_Comm comm, DM *dm, AppCtx *options)
48d71ae5a4SJacob Faibussowitsch {
499371c9d4SSatish Balay   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, 2, 9, 7, 10, 9, 4, 1, 10, 12, 10, 4, 11, 12, 11, 3, 3, 11, 14, 11, 4, 13, 14, 13, 5};
509371c9d4SSatish Balay   const PetscReal coords[15 * 2] = {0, -3, 0, -1, 2, -1, 0, 1, 2, 1, 0, 3, 1, -2, 1, -1, 0, -2, 2, 0, 1, 0, 1, 1, 0, 0, 1, 2, 0, 2};
51c4762a1bSJed Brown 
52c4762a1bSJed Brown   PetscFunctionBegin;
539566063dSJacob Faibussowitsch   PetscCall(DMPlexCreateFromCellListPetsc(comm, 2, 16, 15, 3, PETSC_FALSE, cells, 2, coords, dm));
54*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
55c4762a1bSJed Brown }
56c4762a1bSJed Brown 
TestReordering(DM dm,AppCtx * user)57d71ae5a4SJacob Faibussowitsch PetscErrorCode TestReordering(DM dm, AppCtx *user)
58d71ae5a4SJacob Faibussowitsch {
59c4762a1bSJed Brown   DM              pdm;
60c4762a1bSJed Brown   IS              perm;
61c4762a1bSJed Brown   Mat             A, pA;
62c4762a1bSJed Brown   PetscInt        bw, pbw;
63c4762a1bSJed Brown   MatOrderingType order = MATORDERINGRCM;
64c4762a1bSJed Brown 
65c4762a1bSJed Brown   PetscFunctionBegin;
669566063dSJacob Faibussowitsch   PetscCall(DMPlexGetOrdering(dm, order, NULL, &perm));
679566063dSJacob Faibussowitsch   PetscCall(DMPlexPermute(dm, perm, &pdm));
689566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)pdm, "perm_"));
699566063dSJacob Faibussowitsch   PetscCall(DMSetFromOptions(pdm));
709566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&perm));
719566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(dm, NULL, "-orig_dm_view"));
729566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(pdm, NULL, "-dm_view"));
739566063dSJacob Faibussowitsch   PetscCall(DMCreateMatrix(dm, &A));
749566063dSJacob Faibussowitsch   PetscCall(DMCreateMatrix(pdm, &pA));
759566063dSJacob Faibussowitsch   PetscCall(MatComputeBandwidth(A, 0.0, &bw));
769566063dSJacob Faibussowitsch   PetscCall(MatComputeBandwidth(pA, 0.0, &pbw));
779566063dSJacob Faibussowitsch   PetscCall(MatViewFromOptions(A, NULL, "-orig_mat_view"));
789566063dSJacob Faibussowitsch   PetscCall(MatViewFromOptions(pA, NULL, "-perm_mat_view"));
799566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&A));
809566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&pA));
819566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&pdm));
82c4762a1bSJed Brown   if (pbw > bw) {
8363a3b9bcSJacob Faibussowitsch     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)dm), "Ordering method %s increased bandwidth from %" PetscInt_FMT " to %" PetscInt_FMT "\n", order, bw, pbw));
84c4762a1bSJed Brown   } else {
8563a3b9bcSJacob Faibussowitsch     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)dm), "Ordering method %s reduced bandwidth from %" PetscInt_FMT " to %" PetscInt_FMT "\n", order, bw, pbw));
86c4762a1bSJed Brown   }
87*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
88c4762a1bSJed Brown }
89c4762a1bSJed Brown 
CreateGroupLabel(DM dm,PetscInt numGroups,DMLabel * label,AppCtx * options)90d71ae5a4SJacob Faibussowitsch PetscErrorCode CreateGroupLabel(DM dm, PetscInt numGroups, DMLabel *label, AppCtx *options)
91d71ae5a4SJacob Faibussowitsch {
92c4762a1bSJed Brown   const PetscInt groupA[10] = {15, 3, 13, 12, 2, 10, 7, 6, 0, 4};
93c4762a1bSJed Brown   const PetscInt groupB[6]  = {14, 11, 9, 1, 8, 5};
94c4762a1bSJed Brown   PetscInt       c;
95c4762a1bSJed Brown 
96c4762a1bSJed Brown   PetscFunctionBegin;
979371c9d4SSatish Balay   if (numGroups < 2) {
989371c9d4SSatish Balay     *label = NULL;
99*3ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
1009371c9d4SSatish Balay   }
10163a3b9bcSJacob Faibussowitsch   PetscCheck(numGroups == 2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Test only coded for 2 groups, not %" PetscInt_FMT, numGroups);
1029566063dSJacob Faibussowitsch   PetscCall(DMLabelCreate(PETSC_COMM_SELF, "groups", label));
1039566063dSJacob Faibussowitsch   for (c = 0; c < 10; ++c) PetscCall(DMLabelSetValue(*label, groupA[c], 101));
1049566063dSJacob Faibussowitsch   for (c = 0; c < 6; ++c) PetscCall(DMLabelSetValue(*label, groupB[c], 1001));
105*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
106c4762a1bSJed Brown }
107c4762a1bSJed Brown 
TestReorderingByGroup(DM dm,AppCtx * user)108d71ae5a4SJacob Faibussowitsch PetscErrorCode TestReorderingByGroup(DM dm, AppCtx *user)
109d71ae5a4SJacob Faibussowitsch {
110c4762a1bSJed Brown   DM              pdm;
111c4762a1bSJed Brown   DMLabel         label;
112c4762a1bSJed Brown   Mat             A, pA;
113c4762a1bSJed Brown   MatOrderingType order = MATORDERINGRCM;
114c4762a1bSJed Brown   IS              perm;
115c4762a1bSJed Brown 
116c4762a1bSJed Brown   PetscFunctionBegin;
1179566063dSJacob Faibussowitsch   PetscCall(CreateGroupLabel(dm, user->numGroups, &label, user));
1189566063dSJacob Faibussowitsch   PetscCall(DMPlexGetOrdering(dm, order, label, &perm));
1199566063dSJacob Faibussowitsch   PetscCall(DMLabelDestroy(&label));
1209566063dSJacob Faibussowitsch   PetscCall(DMPlexPermute(dm, perm, &pdm));
1219566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)pdm, "perm_"));
1229566063dSJacob Faibussowitsch   PetscCall(DMSetFromOptions(pdm));
1239566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(dm, NULL, "-orig_dm_view"));
1249566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(pdm, NULL, "-perm_dm_view"));
1259566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&perm));
1269566063dSJacob Faibussowitsch   PetscCall(DMCreateMatrix(dm, &A));
1279566063dSJacob Faibussowitsch   PetscCall(DMCreateMatrix(pdm, &pA));
1289566063dSJacob Faibussowitsch   PetscCall(MatViewFromOptions(A, NULL, "-orig_mat_view"));
1299566063dSJacob Faibussowitsch   PetscCall(MatViewFromOptions(pA, NULL, "-perm_mat_view"));
1309566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&A));
1319566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&pA));
1329566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&pdm));
133*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
134c4762a1bSJed Brown }
135c4762a1bSJed Brown 
main(int argc,char ** argv)136d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv)
137d71ae5a4SJacob Faibussowitsch {
138c4762a1bSJed Brown   DM           dm;
139c4762a1bSJed Brown   PetscSection s;
140c4762a1bSJed Brown   AppCtx       user;
14130602db0SMatthew G. Knepley   PetscInt     dim;
142c4762a1bSJed Brown 
143327415f7SBarry Smith   PetscFunctionBeginUser;
1449566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
1459566063dSJacob Faibussowitsch   PetscCall(ProcessOptions(&user));
146c4762a1bSJed Brown   if (user.numGroups < 1) {
1479566063dSJacob Faibussowitsch     PetscCall(DMCreate(PETSC_COMM_WORLD, &dm));
1489566063dSJacob Faibussowitsch     PetscCall(DMSetType(dm, DMPLEX));
14930602db0SMatthew G. Knepley   } else {
1509566063dSJacob Faibussowitsch     PetscCall(CreateTestMesh(PETSC_COMM_WORLD, &dm, &user));
1510fdc7489SMatthew Knepley   }
1529566063dSJacob Faibussowitsch   PetscCall(DMSetFromOptions(dm));
1539566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(dm, NULL, "-dm_view"));
1549566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
15530602db0SMatthew G. Knepley   {
15630602db0SMatthew G. Knepley     PetscInt  len = (dim + 1) * PetscMax(1, user.numFields);
15730602db0SMatthew G. Knepley     PetscBool flg;
15830602db0SMatthew G. Knepley 
1599566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(len, &user.numDof));
160d0609cedSBarry Smith     PetscOptionsBegin(PETSC_COMM_SELF, "", "Meshing Problem Options", "DMPLEX");
1619566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray("-num_dof", "The dof signature for the section", "ex10.c", user.numDof, &len, &flg));
16263a3b9bcSJacob Faibussowitsch     if (flg) PetscCheck(len == ((dim + 1) * PetscMax(1, user.numFields)), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Length of dof array is %" PetscInt_FMT " should be %" PetscInt_FMT, len, (dim + 1) * PetscMax(1, user.numFields));
163d0609cedSBarry Smith     PetscOptionsEnd();
16430602db0SMatthew G. Knepley   }
16530602db0SMatthew G. Knepley   if (user.numGroups < 1) {
1669566063dSJacob Faibussowitsch     PetscCall(DMSetNumFields(dm, user.numFields));
1679566063dSJacob Faibussowitsch     PetscCall(DMCreateDS(dm));
1689566063dSJacob Faibussowitsch     PetscCall(DMPlexCreateSection(dm, NULL, user.numComponents, user.numDof, 0, NULL, NULL, NULL, NULL, &s));
1699566063dSJacob Faibussowitsch     PetscCall(DMSetLocalSection(dm, s));
1709566063dSJacob Faibussowitsch     PetscCall(PetscSectionDestroy(&s));
1719566063dSJacob Faibussowitsch     PetscCall(TestReordering(dm, &user));
172c4762a1bSJed Brown   } else {
1739566063dSJacob Faibussowitsch     PetscCall(DMSetNumFields(dm, user.numFields));
1749566063dSJacob Faibussowitsch     PetscCall(DMCreateDS(dm));
1759566063dSJacob Faibussowitsch     PetscCall(DMPlexCreateSection(dm, NULL, user.numComponents, user.numDof, 0, NULL, NULL, NULL, NULL, &s));
1769566063dSJacob Faibussowitsch     PetscCall(DMSetLocalSection(dm, s));
1779566063dSJacob Faibussowitsch     PetscCall(PetscSectionDestroy(&s));
1789566063dSJacob Faibussowitsch     PetscCall(TestReorderingByGroup(dm, &user));
179c4762a1bSJed Brown   }
1809566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&dm));
1819566063dSJacob Faibussowitsch   PetscCall(CleanupContext(&user));
1829566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
183b122ec5aSJacob Faibussowitsch   return 0;
184c4762a1bSJed Brown }
185c4762a1bSJed Brown 
186c4762a1bSJed Brown /*TEST
187c4762a1bSJed Brown 
188c4762a1bSJed Brown   # Two cell tests 0-3
189c4762a1bSJed Brown   test:
190c4762a1bSJed Brown     suffix: 0
1910fdc7489SMatthew Knepley     requires: triangle
19230602db0SMatthew G. Knepley     args: -dm_plex_simplex 1 -num_dof 1,0,0 -mat_view -dm_coord_space 0
193c4762a1bSJed Brown   test:
194c4762a1bSJed Brown     suffix: 1
19530602db0SMatthew G. Knepley     args: -dm_plex_simplex 0 -num_dof 1,0,0 -mat_view -dm_coord_space 0
196c4762a1bSJed Brown   test:
197c4762a1bSJed Brown     suffix: 2
1980fdc7489SMatthew Knepley     requires: ctetgen
19930602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -dm_plex_simplex 1 -num_dof 1,0,0,0 -mat_view -dm_coord_space 0
200c4762a1bSJed Brown   test:
201c4762a1bSJed Brown     suffix: 3
20230602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -dm_plex_simplex 0 -num_dof 1,0,0,0 -mat_view -dm_coord_space 0
203c4762a1bSJed Brown   # Refined tests 4-7
204c4762a1bSJed Brown   test:
205c4762a1bSJed Brown     suffix: 4
206c4762a1bSJed Brown     requires: triangle
20730602db0SMatthew G. Knepley     args: -dm_plex_simplex 1 -dm_refine_volume_limit_pre 0.00625 -num_dof 1,0,0
208c4762a1bSJed Brown   test:
209c4762a1bSJed Brown     suffix: 5
21030602db0SMatthew G. Knepley     args: -dm_plex_simplex 0 -dm_refine 1 -num_dof 1,0,0
211c4762a1bSJed Brown   test:
212c4762a1bSJed Brown     suffix: 6
213c4762a1bSJed Brown     requires: ctetgen
21430602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -dm_plex_simplex 1 -dm_refine_volume_limit_pre 0.00625 -num_dof 1,0,0,0
215c4762a1bSJed Brown   test:
216c4762a1bSJed Brown     suffix: 7
21730602db0SMatthew G. Knepley     args: -dm_plex_dim 3 -dm_plex_simplex 0 -dm_refine 1 -num_dof 1,0,0,0
218c4762a1bSJed Brown   # Parallel tests
219c4762a1bSJed Brown   # Grouping tests
220c4762a1bSJed Brown   test:
221c4762a1bSJed Brown     suffix: group_1
222c4762a1bSJed Brown     args: -num_groups 1 -num_dof 1,0,0 -is_view -orig_mat_view -perm_mat_view
223c4762a1bSJed Brown   test:
224c4762a1bSJed Brown     suffix: group_2
225c4762a1bSJed Brown     args: -num_groups 2 -num_dof 1,0,0 -is_view -perm_mat_view
226c4762a1bSJed Brown 
227c4762a1bSJed Brown TEST*/
228