xref: /libCEED/examples/solids/src/setup-dm.c (revision 5754ecac3b7d1ff97b39b25dc78c06350f2c900d)
1*5754ecacSJeremy L Thompson /// @file
2*5754ecacSJeremy L Thompson /// DM setup for solid mechanics example using PETSc
3*5754ecacSJeremy L Thompson 
4*5754ecacSJeremy L Thompson #include "../include/boundary.h"
5*5754ecacSJeremy L Thompson #include "../include/setup-dm.h"
6*5754ecacSJeremy L Thompson #include "../include/petsc-macros.h"
7*5754ecacSJeremy L Thompson 
8*5754ecacSJeremy L Thompson // -----------------------------------------------------------------------------
9*5754ecacSJeremy L Thompson // Setup DM
10*5754ecacSJeremy L Thompson // -----------------------------------------------------------------------------
11*5754ecacSJeremy L Thompson PetscErrorCode CreateBCLabel(DM dm, const char name[]) {
12*5754ecacSJeremy L Thompson   PetscErrorCode ierr;
13*5754ecacSJeremy L Thompson   DMLabel label;
14*5754ecacSJeremy L Thompson 
15*5754ecacSJeremy L Thompson   PetscFunctionBeginUser;
16*5754ecacSJeremy L Thompson 
17*5754ecacSJeremy L Thompson   ierr = DMCreateLabel(dm, name); CHKERRQ(ierr);
18*5754ecacSJeremy L Thompson   ierr = DMGetLabel(dm, name, &label); CHKERRQ(ierr);
19*5754ecacSJeremy L Thompson   ierr = DMPlexMarkBoundaryFaces(dm, 1, label); CHKERRQ(ierr);
20*5754ecacSJeremy L Thompson   ierr = DMPlexLabelComplete(dm, label); CHKERRQ(ierr);
21*5754ecacSJeremy L Thompson 
22*5754ecacSJeremy L Thompson   PetscFunctionReturn(0);
23*5754ecacSJeremy L Thompson };
24*5754ecacSJeremy L Thompson 
25*5754ecacSJeremy L Thompson // Read mesh and distribute DM in parallel
26*5754ecacSJeremy L Thompson PetscErrorCode CreateDistributedDM(MPI_Comm comm, AppCtx app_ctx, DM *dm) {
27*5754ecacSJeremy L Thompson   PetscErrorCode  ierr;
28*5754ecacSJeremy L Thompson   const char      *filename = app_ctx->mesh_file;
29*5754ecacSJeremy L Thompson   PetscBool       interpolate = PETSC_TRUE;
30*5754ecacSJeremy L Thompson   DM              distributed_mesh = NULL;
31*5754ecacSJeremy L Thompson   PetscPartitioner part;
32*5754ecacSJeremy L Thompson 
33*5754ecacSJeremy L Thompson   PetscFunctionBeginUser;
34*5754ecacSJeremy L Thompson 
35*5754ecacSJeremy L Thompson   if (!*filename) {
36*5754ecacSJeremy L Thompson     PetscInt dim = 3, faces[3] = {3, 3, 3};
37*5754ecacSJeremy L Thompson     ierr = PetscOptionsGetIntArray(NULL, NULL, "-dm_plex_box_faces",
38*5754ecacSJeremy L Thompson                                    faces, &dim, NULL); CHKERRQ(ierr);
39*5754ecacSJeremy L Thompson     ierr = DMPlexCreateBoxMesh(comm, dim, PETSC_FALSE, faces, NULL,
40*5754ecacSJeremy L Thompson                                NULL, NULL, interpolate, dm); CHKERRQ(ierr);
41*5754ecacSJeremy L Thompson   } else {
42*5754ecacSJeremy L Thompson     ierr = DMPlexCreateFromFile(comm, filename, interpolate, dm); CHKERRQ(ierr);
43*5754ecacSJeremy L Thompson   }
44*5754ecacSJeremy L Thompson 
45*5754ecacSJeremy L Thompson   // Distribute DM in parallel
46*5754ecacSJeremy L Thompson   ierr = DMPlexGetPartitioner(*dm, &part); CHKERRQ(ierr);
47*5754ecacSJeremy L Thompson   ierr = PetscPartitionerSetFromOptions(part); CHKERRQ(ierr);
48*5754ecacSJeremy L Thompson   ierr = DMPlexDistribute(*dm, 0, NULL, &distributed_mesh); CHKERRQ(ierr);
49*5754ecacSJeremy L Thompson   if (distributed_mesh) {
50*5754ecacSJeremy L Thompson     ierr = DMDestroy(dm); CHKERRQ(ierr);
51*5754ecacSJeremy L Thompson     *dm  = distributed_mesh;
52*5754ecacSJeremy L Thompson   }
53*5754ecacSJeremy L Thompson   ierr = DMViewFromOptions(*dm, NULL, "-dm_view"); CHKERRQ(ierr);
54*5754ecacSJeremy L Thompson 
55*5754ecacSJeremy L Thompson   PetscFunctionReturn(0);
56*5754ecacSJeremy L Thompson };
57*5754ecacSJeremy L Thompson 
58*5754ecacSJeremy L Thompson // Create FE by degree
59*5754ecacSJeremy L Thompson PetscErrorCode PetscFECreateByDegree(DM dm, PetscInt dim, PetscInt Nc,
60*5754ecacSJeremy L Thompson                                      PetscBool isSimplex, const char prefix[],
61*5754ecacSJeremy L Thompson                                      PetscInt order, PetscFE *fem) {
62*5754ecacSJeremy L Thompson   PetscQuadrature q, fq;
63*5754ecacSJeremy L Thompson   DM              K;
64*5754ecacSJeremy L Thompson   PetscSpace      P;
65*5754ecacSJeremy L Thompson   PetscDualSpace  Q;
66*5754ecacSJeremy L Thompson   PetscInt        quadPointsPerEdge;
67*5754ecacSJeremy L Thompson   PetscBool       tensor = isSimplex ? PETSC_FALSE : PETSC_TRUE;
68*5754ecacSJeremy L Thompson   PetscErrorCode  ierr;
69*5754ecacSJeremy L Thompson 
70*5754ecacSJeremy L Thompson   PetscFunctionBeginUser;
71*5754ecacSJeremy L Thompson   /* Create space */
72*5754ecacSJeremy L Thompson   ierr = PetscSpaceCreate(PetscObjectComm((PetscObject) dm), &P); CHKERRQ(ierr);
73*5754ecacSJeremy L Thompson   ierr = PetscObjectSetOptionsPrefix((PetscObject) P, prefix); CHKERRQ(ierr);
74*5754ecacSJeremy L Thompson   ierr = PetscSpacePolynomialSetTensor(P, tensor); CHKERRQ(ierr);
75*5754ecacSJeremy L Thompson   ierr = PetscSpaceSetFromOptions(P); CHKERRQ(ierr);
76*5754ecacSJeremy L Thompson   ierr = PetscSpaceSetNumComponents(P, Nc); CHKERRQ(ierr);
77*5754ecacSJeremy L Thompson   ierr = PetscSpaceSetNumVariables(P, dim); CHKERRQ(ierr);
78*5754ecacSJeremy L Thompson   ierr = PetscSpaceSetDegree(P, order, order); CHKERRQ(ierr);
79*5754ecacSJeremy L Thompson   ierr = PetscSpaceSetUp(P); CHKERRQ(ierr);
80*5754ecacSJeremy L Thompson   ierr = PetscSpacePolynomialGetTensor(P, &tensor); CHKERRQ(ierr);
81*5754ecacSJeremy L Thompson   /* Create dual space */
82*5754ecacSJeremy L Thompson   ierr = PetscDualSpaceCreate(PetscObjectComm((PetscObject) dm), &Q);
83*5754ecacSJeremy L Thompson   CHKERRQ(ierr);
84*5754ecacSJeremy L Thompson   ierr = PetscDualSpaceSetType(Q,PETSCDUALSPACELAGRANGE); CHKERRQ(ierr);
85*5754ecacSJeremy L Thompson   ierr = PetscObjectSetOptionsPrefix((PetscObject) Q, prefix); CHKERRQ(ierr);
86*5754ecacSJeremy L Thompson   ierr = PetscDualSpaceCreateReferenceCell(Q, dim, isSimplex, &K); CHKERRQ(ierr);
87*5754ecacSJeremy L Thompson   ierr = PetscDualSpaceSetDM(Q, K); CHKERRQ(ierr);
88*5754ecacSJeremy L Thompson   ierr = DMDestroy(&K); CHKERRQ(ierr);
89*5754ecacSJeremy L Thompson   ierr = PetscDualSpaceSetNumComponents(Q, Nc); CHKERRQ(ierr);
90*5754ecacSJeremy L Thompson   ierr = PetscDualSpaceSetOrder(Q, order); CHKERRQ(ierr);
91*5754ecacSJeremy L Thompson   ierr = PetscDualSpaceLagrangeSetTensor(Q, tensor); CHKERRQ(ierr);
92*5754ecacSJeremy L Thompson   ierr = PetscDualSpaceSetFromOptions(Q); CHKERRQ(ierr);
93*5754ecacSJeremy L Thompson   ierr = PetscDualSpaceSetUp(Q); CHKERRQ(ierr);
94*5754ecacSJeremy L Thompson   /* Create element */
95*5754ecacSJeremy L Thompson   ierr = PetscFECreate(PetscObjectComm((PetscObject) dm), fem); CHKERRQ(ierr);
96*5754ecacSJeremy L Thompson   ierr = PetscObjectSetOptionsPrefix((PetscObject) *fem, prefix); CHKERRQ(ierr);
97*5754ecacSJeremy L Thompson   ierr = PetscFESetFromOptions(*fem); CHKERRQ(ierr);
98*5754ecacSJeremy L Thompson   ierr = PetscFESetBasisSpace(*fem, P); CHKERRQ(ierr);
99*5754ecacSJeremy L Thompson   ierr = PetscFESetDualSpace(*fem, Q); CHKERRQ(ierr);
100*5754ecacSJeremy L Thompson   ierr = PetscFESetNumComponents(*fem, Nc); CHKERRQ(ierr);
101*5754ecacSJeremy L Thompson   ierr = PetscFESetUp(*fem); CHKERRQ(ierr);
102*5754ecacSJeremy L Thompson   ierr = PetscSpaceDestroy(&P); CHKERRQ(ierr);
103*5754ecacSJeremy L Thompson   ierr = PetscDualSpaceDestroy(&Q); CHKERRQ(ierr);
104*5754ecacSJeremy L Thompson   /* Create quadrature */
105*5754ecacSJeremy L Thompson   quadPointsPerEdge = PetscMax(order + 1,1);
106*5754ecacSJeremy L Thompson   if (isSimplex) {
107*5754ecacSJeremy L Thompson     ierr = PetscDTStroudConicalQuadrature(dim,   1, quadPointsPerEdge, -1.0, 1.0,
108*5754ecacSJeremy L Thompson                                           &q); CHKERRQ(ierr);
109*5754ecacSJeremy L Thompson     ierr = PetscDTStroudConicalQuadrature(dim-1, 1, quadPointsPerEdge, -1.0, 1.0,
110*5754ecacSJeremy L Thompson                                           &fq); CHKERRQ(ierr);
111*5754ecacSJeremy L Thompson   } else {
112*5754ecacSJeremy L Thompson     ierr = PetscDTGaussTensorQuadrature(dim,   1, quadPointsPerEdge, -1.0, 1.0,
113*5754ecacSJeremy L Thompson                                         &q); CHKERRQ(ierr);
114*5754ecacSJeremy L Thompson     ierr = PetscDTGaussTensorQuadrature(dim-1, 1, quadPointsPerEdge, -1.0, 1.0,
115*5754ecacSJeremy L Thompson                                         &fq); CHKERRQ(ierr);
116*5754ecacSJeremy L Thompson   }
117*5754ecacSJeremy L Thompson   ierr = PetscFESetQuadrature(*fem, q); CHKERRQ(ierr);
118*5754ecacSJeremy L Thompson   ierr = PetscFESetFaceQuadrature(*fem, fq); CHKERRQ(ierr);
119*5754ecacSJeremy L Thompson   ierr = PetscQuadratureDestroy(&q); CHKERRQ(ierr);
120*5754ecacSJeremy L Thompson   ierr = PetscQuadratureDestroy(&fq); CHKERRQ(ierr);
121*5754ecacSJeremy L Thompson 
122*5754ecacSJeremy L Thompson   PetscFunctionReturn(0);
123*5754ecacSJeremy L Thompson }
124*5754ecacSJeremy L Thompson 
125*5754ecacSJeremy L Thompson // Setup DM with FE space of appropriate degree
126*5754ecacSJeremy L Thompson PetscErrorCode SetupDMByDegree(DM dm, AppCtx app_ctx, PetscInt order,
127*5754ecacSJeremy L Thompson                                PetscBool boundary, PetscInt num_comp_u) {
128*5754ecacSJeremy L Thompson   PetscErrorCode  ierr;
129*5754ecacSJeremy L Thompson   PetscInt        dim;
130*5754ecacSJeremy L Thompson   PetscFE         fe;
131*5754ecacSJeremy L Thompson   IS              face_set_is;         // Index Set for Face Sets
132*5754ecacSJeremy L Thompson   const char      *name = "Face Sets"; // PETSc internal requirement
133*5754ecacSJeremy L Thompson   PetscInt        num_face_sets;       // Number of FaceSets in face_set_is
134*5754ecacSJeremy L Thompson   const PetscInt  *face_set_ids;       // id of each FaceSet
135*5754ecacSJeremy L Thompson 
136*5754ecacSJeremy L Thompson   PetscFunctionBeginUser;
137*5754ecacSJeremy L Thompson 
138*5754ecacSJeremy L Thompson   // Setup DM
139*5754ecacSJeremy L Thompson   ierr = DMGetDimension(dm, &dim); CHKERRQ(ierr);
140*5754ecacSJeremy L Thompson   ierr = PetscFECreateByDegree(dm, dim, num_comp_u, PETSC_FALSE, NULL, order,
141*5754ecacSJeremy L Thompson                                &fe);
142*5754ecacSJeremy L Thompson   CHKERRQ(ierr);
143*5754ecacSJeremy L Thompson   ierr = DMSetFromOptions(dm); CHKERRQ(ierr);
144*5754ecacSJeremy L Thompson   ierr = DMAddField(dm, NULL, (PetscObject)fe); CHKERRQ(ierr);
145*5754ecacSJeremy L Thompson   ierr = DMCreateDS(dm); CHKERRQ(ierr);
146*5754ecacSJeremy L Thompson 
147*5754ecacSJeremy L Thompson   // Add Dirichlet (Essential) boundary
148*5754ecacSJeremy L Thompson   if (boundary) {
149*5754ecacSJeremy L Thompson     if (app_ctx->forcing_choice == FORCE_MMS) {
150*5754ecacSJeremy L Thompson       if (app_ctx->test_mode) {
151*5754ecacSJeremy L Thompson         // -- Test mode - box mesh
152*5754ecacSJeremy L Thompson         PetscBool has_label;
153*5754ecacSJeremy L Thompson         PetscInt marker_ids[1] = {1};
154*5754ecacSJeremy L Thompson         ierr = DMHasLabel(dm, "marker", &has_label); CHKERRQ(ierr);
155*5754ecacSJeremy L Thompson         if (!has_label) {
156*5754ecacSJeremy L Thompson           ierr = CreateBCLabel(dm, "marker"); CHKERRQ(ierr);
157*5754ecacSJeremy L Thompson         }
158*5754ecacSJeremy L Thompson         DMLabel label;
159*5754ecacSJeremy L Thompson         ierr = DMGetLabel(dm, "marker", &label); CHKERRQ(ierr);
160*5754ecacSJeremy L Thompson         ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "mms", label, "marker", 1, marker_ids,
161*5754ecacSJeremy L Thompson                              0, 0, NULL, (void(*)(void))BCMMS, NULL, NULL, NULL);
162*5754ecacSJeremy L Thompson         CHKERRQ(ierr);
163*5754ecacSJeremy L Thompson       } else {
164*5754ecacSJeremy L Thompson         // -- ExodusII mesh with MMS
165*5754ecacSJeremy L Thompson         ierr = DMGetLabelIdIS(dm, name, &face_set_is); CHKERRQ(ierr);
166*5754ecacSJeremy L Thompson         ierr = ISGetSize(face_set_is,&num_face_sets); CHKERRQ(ierr);
167*5754ecacSJeremy L Thompson         ierr = ISGetIndices(face_set_is, &face_set_ids); CHKERRQ(ierr);
168*5754ecacSJeremy L Thompson         DMLabel label;
169*5754ecacSJeremy L Thompson         ierr = DMGetLabel(dm, "Face Sets", &label); CHKERRQ(ierr);
170*5754ecacSJeremy L Thompson         ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "mms", label, "Face Sets",
171*5754ecacSJeremy L Thompson                              num_face_sets, face_set_ids, 0, 0, NULL,
172*5754ecacSJeremy L Thompson                              (void(*)(void))BCMMS, NULL, NULL, NULL);
173*5754ecacSJeremy L Thompson         CHKERRQ(ierr);
174*5754ecacSJeremy L Thompson         ierr = ISRestoreIndices(face_set_is, &face_set_ids); CHKERRQ(ierr);
175*5754ecacSJeremy L Thompson         ierr = ISDestroy(&face_set_is); CHKERRQ(ierr);
176*5754ecacSJeremy L Thompson       }
177*5754ecacSJeremy L Thompson     } else {
178*5754ecacSJeremy L Thompson       // -- ExodusII mesh with user specified BCs
179*5754ecacSJeremy L Thompson       // -- Clamp BCs
180*5754ecacSJeremy L Thompson       DMLabel label;
181*5754ecacSJeremy L Thompson       ierr = DMGetLabel(dm, "Face Sets", &label); CHKERRQ(ierr);
182*5754ecacSJeremy L Thompson       for (PetscInt i = 0; i < app_ctx->bc_clamp_count; i++) {
183*5754ecacSJeremy L Thompson         char bcName[25];
184*5754ecacSJeremy L Thompson         snprintf(bcName, sizeof bcName, "clamp_%d", app_ctx->bc_clamp_faces[i]);
185*5754ecacSJeremy L Thompson         ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, bcName, label, "Face Sets", 1,
186*5754ecacSJeremy L Thompson                              &app_ctx->bc_clamp_faces[i], 0, 0,
187*5754ecacSJeremy L Thompson                              NULL, (void(*)(void))BCClamp, NULL,
188*5754ecacSJeremy L Thompson                              (void *)&app_ctx->bc_clamp_max[i], NULL);
189*5754ecacSJeremy L Thompson         CHKERRQ(ierr);
190*5754ecacSJeremy L Thompson       }
191*5754ecacSJeremy L Thompson     }
192*5754ecacSJeremy L Thompson   }
193*5754ecacSJeremy L Thompson   ierr = DMPlexSetClosurePermutationTensor(dm, PETSC_DETERMINE, NULL);
194*5754ecacSJeremy L Thompson   CHKERRQ(ierr);
195*5754ecacSJeremy L Thompson 
196*5754ecacSJeremy L Thompson   // Cleanup
197*5754ecacSJeremy L Thompson   ierr = PetscFEDestroy(&fe); CHKERRQ(ierr);
198*5754ecacSJeremy L Thompson 
199*5754ecacSJeremy L Thompson   PetscFunctionReturn(0);
200*5754ecacSJeremy L Thompson };
201