xref: /libCEED/examples/solids/src/cl-options.c (revision 5754ecac3b7d1ff97b39b25dc78c06350f2c900d)
1*5754ecacSJeremy L Thompson /// @file
2*5754ecacSJeremy L Thompson /// Command line option processing for solid mechanics example using PETSc
3*5754ecacSJeremy L Thompson 
4*5754ecacSJeremy L Thompson #include "../include/cl-options.h"
5*5754ecacSJeremy L Thompson 
6*5754ecacSJeremy L Thompson // -----------------------------------------------------------------------------
7*5754ecacSJeremy L Thompson // Process command line options
8*5754ecacSJeremy L Thompson // -----------------------------------------------------------------------------
9*5754ecacSJeremy L Thompson // Process general command line options
10*5754ecacSJeremy L Thompson PetscErrorCode ProcessCommandLineOptions(MPI_Comm comm, AppCtx app_ctx) {
11*5754ecacSJeremy L Thompson   PetscErrorCode ierr;
12*5754ecacSJeremy L Thompson   PetscBool ceed_flag = PETSC_FALSE;
13*5754ecacSJeremy L Thompson 
14*5754ecacSJeremy L Thompson   PetscFunctionBeginUser;
15*5754ecacSJeremy L Thompson 
16*5754ecacSJeremy L Thompson   ierr = PetscOptionsBegin(comm, NULL,
17*5754ecacSJeremy L Thompson                            "Elasticity / Hyperelasticity in PETSc with libCEED",
18*5754ecacSJeremy L Thompson                            NULL); CHKERRQ(ierr);
19*5754ecacSJeremy L Thompson 
20*5754ecacSJeremy L Thompson   ierr = PetscOptionsString("-ceed", "CEED resource specifier",
21*5754ecacSJeremy L Thompson                             NULL, app_ctx->ceed_resource, app_ctx->ceed_resource,
22*5754ecacSJeremy L Thompson                             sizeof(app_ctx->ceed_resource), &ceed_flag);
23*5754ecacSJeremy L Thompson   CHKERRQ(ierr);
24*5754ecacSJeremy L Thompson 
25*5754ecacSJeremy L Thompson   ierr = PetscStrncpy(app_ctx->output_dir, ".", 2);
26*5754ecacSJeremy L Thompson   CHKERRQ(ierr); // Default - current directory
27*5754ecacSJeremy L Thompson   ierr = PetscOptionsString("-output_dir", "Output directory",
28*5754ecacSJeremy L Thompson                             NULL, app_ctx->output_dir, app_ctx->output_dir,
29*5754ecacSJeremy L Thompson                             sizeof(app_ctx->output_dir), NULL); CHKERRQ(ierr);
30*5754ecacSJeremy L Thompson 
31*5754ecacSJeremy L Thompson   app_ctx->degree         = 3;
32*5754ecacSJeremy L Thompson   ierr = PetscOptionsInt("-degree", "Polynomial degree of tensor product basis",
33*5754ecacSJeremy L Thompson                          NULL, app_ctx->degree, &app_ctx->degree, NULL);
34*5754ecacSJeremy L Thompson   CHKERRQ(ierr);
35*5754ecacSJeremy L Thompson 
36*5754ecacSJeremy L Thompson   app_ctx->q_extra         = 0;
37*5754ecacSJeremy L Thompson   ierr = PetscOptionsInt("-qextra", "Number of extra quadrature points",
38*5754ecacSJeremy L Thompson                          NULL, app_ctx->q_extra, &app_ctx->q_extra, NULL);
39*5754ecacSJeremy L Thompson   CHKERRQ(ierr);
40*5754ecacSJeremy L Thompson 
41*5754ecacSJeremy L Thompson   ierr = PetscOptionsString("-mesh", "Read mesh from file", NULL,
42*5754ecacSJeremy L Thompson                             app_ctx->mesh_file, app_ctx->mesh_file,
43*5754ecacSJeremy L Thompson                             sizeof(app_ctx->mesh_file), NULL); CHKERRQ(ierr);
44*5754ecacSJeremy L Thompson 
45*5754ecacSJeremy L Thompson   app_ctx->problem_choice  = ELAS_LINEAR;       // Default - Linear Elasticity
46*5754ecacSJeremy L Thompson   ierr = PetscOptionsEnum("-problem",
47*5754ecacSJeremy L Thompson                           "Solves Elasticity & Hyperelasticity Problems",
48*5754ecacSJeremy L Thompson                           NULL, problemTypes, (PetscEnum)app_ctx->problem_choice,
49*5754ecacSJeremy L Thompson                           (PetscEnum *)&app_ctx->problem_choice, NULL);
50*5754ecacSJeremy L Thompson   CHKERRQ(ierr);
51*5754ecacSJeremy L Thompson   app_ctx->name = problemTypes[app_ctx->problem_choice];
52*5754ecacSJeremy L Thompson   app_ctx->name_for_disp = problemTypesForDisp[app_ctx->problem_choice];
53*5754ecacSJeremy L Thompson 
54*5754ecacSJeremy L Thompson   app_ctx->num_increments = app_ctx->problem_choice == ELAS_LINEAR ? 1 : 10;
55*5754ecacSJeremy L Thompson   ierr = PetscOptionsInt("-num_steps", "Number of pseudo-time steps",
56*5754ecacSJeremy L Thompson                          NULL, app_ctx->num_increments, &app_ctx->num_increments,
57*5754ecacSJeremy L Thompson                          NULL); CHKERRQ(ierr);
58*5754ecacSJeremy L Thompson 
59*5754ecacSJeremy L Thompson   app_ctx->forcing_choice  = FORCE_NONE;     // Default - no forcing term
60*5754ecacSJeremy L Thompson   ierr = PetscOptionsEnum("-forcing", "Set forcing function option", NULL,
61*5754ecacSJeremy L Thompson                           forcing_types, (PetscEnum)app_ctx->forcing_choice,
62*5754ecacSJeremy L Thompson                           (PetscEnum *)&app_ctx->forcing_choice, NULL);
63*5754ecacSJeremy L Thompson   CHKERRQ(ierr);
64*5754ecacSJeremy L Thompson 
65*5754ecacSJeremy L Thompson   PetscInt max_n = 3;
66*5754ecacSJeremy L Thompson   app_ctx->forcing_vector[0] = 0;
67*5754ecacSJeremy L Thompson   app_ctx->forcing_vector[1] = -1;
68*5754ecacSJeremy L Thompson   app_ctx->forcing_vector[2] = 0;
69*5754ecacSJeremy L Thompson   ierr = PetscOptionsScalarArray("-forcing_vec",
70*5754ecacSJeremy L Thompson                                  "Direction to apply constant force", NULL,
71*5754ecacSJeremy L Thompson                                  app_ctx->forcing_vector, &max_n, NULL);
72*5754ecacSJeremy L Thompson   CHKERRQ(ierr);
73*5754ecacSJeremy L Thompson 
74*5754ecacSJeremy L Thompson   if ((app_ctx->problem_choice == ELAS_FSInitial_NH1 ||
75*5754ecacSJeremy L Thompson        app_ctx->problem_choice == ELAS_FSInitial_NH2 ||
76*5754ecacSJeremy L Thompson        app_ctx->problem_choice == ELAS_FSCurrent_NH1 ||
77*5754ecacSJeremy L Thompson        app_ctx->problem_choice == ELAS_FSCurrent_NH2 ||
78*5754ecacSJeremy L Thompson        app_ctx->problem_choice == ELAS_FSInitial_MR1) &&
79*5754ecacSJeremy L Thompson       app_ctx->forcing_choice == FORCE_CONST)
80*5754ecacSJeremy L Thompson     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP,
81*5754ecacSJeremy L Thompson             "Cannot use constant forcing and finite strain formulation. "
82*5754ecacSJeremy L Thompson             "Constant forcing in reference frame currently unavaliable.");
83*5754ecacSJeremy L Thompson 
84*5754ecacSJeremy L Thompson   // Dirichlet boundary conditions
85*5754ecacSJeremy L Thompson   app_ctx->bc_clamp_count = 16;
86*5754ecacSJeremy L Thompson   ierr = PetscOptionsIntArray("-bc_clamp",
87*5754ecacSJeremy L Thompson                               "Face IDs to apply incremental Dirichlet BC",
88*5754ecacSJeremy L Thompson                               NULL, app_ctx->bc_clamp_faces, &app_ctx->bc_clamp_count,
89*5754ecacSJeremy L Thompson                               NULL); CHKERRQ(ierr);
90*5754ecacSJeremy L Thompson   // Set vector for each clamped BC
91*5754ecacSJeremy L Thompson   for (PetscInt i = 0; i < app_ctx->bc_clamp_count; i++) {
92*5754ecacSJeremy L Thompson     // Translation vector
93*5754ecacSJeremy L Thompson     char option_name[25];
94*5754ecacSJeremy L Thompson     const size_t nclamp_params = sizeof(app_ctx->bc_clamp_max[0])/sizeof(
95*5754ecacSJeremy L Thompson                                    app_ctx->bc_clamp_max[0][0]);
96*5754ecacSJeremy L Thompson     for (PetscInt j = 0; j < nclamp_params; j++)
97*5754ecacSJeremy L Thompson       app_ctx->bc_clamp_max[i][j] = 0.;
98*5754ecacSJeremy L Thompson 
99*5754ecacSJeremy L Thompson     snprintf(option_name, sizeof option_name, "-bc_clamp_%d_translate",
100*5754ecacSJeremy L Thompson              app_ctx->bc_clamp_faces[i]);
101*5754ecacSJeremy L Thompson     max_n = 3;
102*5754ecacSJeremy L Thompson     ierr = PetscOptionsScalarArray(option_name,
103*5754ecacSJeremy L Thompson                                    "Vector to translate clamped end by", NULL,
104*5754ecacSJeremy L Thompson                                    app_ctx->bc_clamp_max[i], &max_n, NULL);
105*5754ecacSJeremy L Thompson     CHKERRQ(ierr);
106*5754ecacSJeremy L Thompson 
107*5754ecacSJeremy L Thompson     // Rotation vector
108*5754ecacSJeremy L Thompson     max_n = 5;
109*5754ecacSJeremy L Thompson     snprintf(option_name, sizeof option_name, "-bc_clamp_%d_rotate",
110*5754ecacSJeremy L Thompson              app_ctx->bc_clamp_faces[i]);
111*5754ecacSJeremy L Thompson     ierr = PetscOptionsScalarArray(option_name,
112*5754ecacSJeremy L Thompson                                    "Vector with axis of rotation and rotation, in radians",
113*5754ecacSJeremy L Thompson                                    NULL, &app_ctx->bc_clamp_max[i][3], &max_n, NULL);
114*5754ecacSJeremy L Thompson     CHKERRQ(ierr);
115*5754ecacSJeremy L Thompson 
116*5754ecacSJeremy L Thompson     // Normalize
117*5754ecacSJeremy L Thompson     PetscScalar norm = sqrt(app_ctx->bc_clamp_max[i][3]*app_ctx->bc_clamp_max[i][3]
118*5754ecacSJeremy L Thompson                             + app_ctx->bc_clamp_max[i][4]*app_ctx->bc_clamp_max[i][4]
119*5754ecacSJeremy L Thompson                             + app_ctx->bc_clamp_max[i][5]*app_ctx->bc_clamp_max[i][5]);
120*5754ecacSJeremy L Thompson     if (fabs(norm) < 1e-16)
121*5754ecacSJeremy L Thompson       norm = 1;
122*5754ecacSJeremy L Thompson     for (PetscInt j = 0; j < 3; j++)
123*5754ecacSJeremy L Thompson       app_ctx->bc_clamp_max[i][3 + j] /= norm;
124*5754ecacSJeremy L Thompson   }
125*5754ecacSJeremy L Thompson 
126*5754ecacSJeremy L Thompson   // Neumann boundary conditions
127*5754ecacSJeremy L Thompson   app_ctx->bc_traction_count = 16;
128*5754ecacSJeremy L Thompson   ierr = PetscOptionsIntArray("-bc_traction",
129*5754ecacSJeremy L Thompson                               "Face IDs to apply traction (Neumann) BC",
130*5754ecacSJeremy L Thompson                               NULL, app_ctx->bc_traction_faces,
131*5754ecacSJeremy L Thompson                               &app_ctx->bc_traction_count, NULL); CHKERRQ(ierr);
132*5754ecacSJeremy L Thompson   // Set vector for each traction BC
133*5754ecacSJeremy L Thompson   for (PetscInt i = 0; i < app_ctx->bc_traction_count; i++) {
134*5754ecacSJeremy L Thompson     // Translation vector
135*5754ecacSJeremy L Thompson     char option_name[25];
136*5754ecacSJeremy L Thompson     for (PetscInt j = 0; j < 3; j++)
137*5754ecacSJeremy L Thompson       app_ctx->bc_traction_vector[i][j] = 0.;
138*5754ecacSJeremy L Thompson 
139*5754ecacSJeremy L Thompson     snprintf(option_name, sizeof option_name, "-bc_traction_%d",
140*5754ecacSJeremy L Thompson              app_ctx->bc_traction_faces[i]);
141*5754ecacSJeremy L Thompson     max_n = 3;
142*5754ecacSJeremy L Thompson     PetscBool set = false;
143*5754ecacSJeremy L Thompson     ierr = PetscOptionsScalarArray(option_name,
144*5754ecacSJeremy L Thompson                                    "Traction vector for constrained face", NULL,
145*5754ecacSJeremy L Thompson                                    app_ctx->bc_traction_vector[i], &max_n, &set);
146*5754ecacSJeremy L Thompson     CHKERRQ(ierr);
147*5754ecacSJeremy L Thompson 
148*5754ecacSJeremy L Thompson     if (!set)
149*5754ecacSJeremy L Thompson       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP,
150*5754ecacSJeremy L Thompson               "Traction vector must be set for all traction boundary conditions.");
151*5754ecacSJeremy L Thompson   }
152*5754ecacSJeremy L Thompson 
153*5754ecacSJeremy L Thompson   app_ctx->multigrid_choice = MULTIGRID_LOGARITHMIC;
154*5754ecacSJeremy L Thompson   ierr = PetscOptionsEnum("-multigrid", "Set multigrid type option", NULL,
155*5754ecacSJeremy L Thompson                           multigrid_types, (PetscEnum)app_ctx->multigrid_choice,
156*5754ecacSJeremy L Thompson                           (PetscEnum *)&app_ctx->multigrid_choice, NULL);
157*5754ecacSJeremy L Thompson   CHKERRQ(ierr);
158*5754ecacSJeremy L Thompson 
159*5754ecacSJeremy L Thompson   app_ctx->test_mode = PETSC_FALSE;
160*5754ecacSJeremy L Thompson   ierr = PetscOptionsBool("-test",
161*5754ecacSJeremy L Thompson                           "Testing mode (do not print unless error is large)",
162*5754ecacSJeremy L Thompson                           NULL, app_ctx->test_mode, &(app_ctx->test_mode), NULL);
163*5754ecacSJeremy L Thompson   CHKERRQ(ierr);
164*5754ecacSJeremy L Thompson 
165*5754ecacSJeremy L Thompson   app_ctx->expect_final_strain = -1.;
166*5754ecacSJeremy L Thompson   ierr = PetscOptionsReal("-expect_final_strain_energy",
167*5754ecacSJeremy L Thompson                           "Expect final strain energy close to this value.",
168*5754ecacSJeremy L Thompson                           NULL, app_ctx->expect_final_strain, &app_ctx->expect_final_strain, NULL);
169*5754ecacSJeremy L Thompson   CHKERRQ(ierr);
170*5754ecacSJeremy L Thompson 
171*5754ecacSJeremy L Thompson   app_ctx->test_tol = 1e-8;
172*5754ecacSJeremy L Thompson   ierr = PetscOptionsReal("-expect_final_state_rtol",
173*5754ecacSJeremy L Thompson                           "Relative tolerance for final strain energy test",
174*5754ecacSJeremy L Thompson                           NULL, app_ctx->test_tol, &app_ctx->test_tol, NULL);
175*5754ecacSJeremy L Thompson   CHKERRQ(ierr);
176*5754ecacSJeremy L Thompson 
177*5754ecacSJeremy L Thompson   app_ctx->view_soln = PETSC_FALSE;
178*5754ecacSJeremy L Thompson   ierr = PetscOptionsBool("-view_soln", "Write out solution vector for viewing",
179*5754ecacSJeremy L Thompson                           NULL, app_ctx->view_soln, &(app_ctx->view_soln), NULL);
180*5754ecacSJeremy L Thompson   CHKERRQ(ierr);
181*5754ecacSJeremy L Thompson 
182*5754ecacSJeremy L Thompson   app_ctx->view_final_soln = PETSC_FALSE;
183*5754ecacSJeremy L Thompson   ierr = PetscOptionsBool("-view_final_soln",
184*5754ecacSJeremy L Thompson                           "Write out final solution vector for viewing",
185*5754ecacSJeremy L Thompson                           NULL, app_ctx->view_final_soln, &(app_ctx->view_final_soln),
186*5754ecacSJeremy L Thompson                           NULL); CHKERRQ(ierr);
187*5754ecacSJeremy L Thompson   CHKERRQ(ierr);
188*5754ecacSJeremy L Thompson 
189*5754ecacSJeremy L Thompson   PetscBool set;
190*5754ecacSJeremy L Thompson   char energy_viewer_filename[PETSC_MAX_PATH_LEN] = "";
191*5754ecacSJeremy L Thompson   ierr = PetscOptionsString("-strain_energy_monitor",
192*5754ecacSJeremy L Thompson                             "Print out current strain energy at every load increment",
193*5754ecacSJeremy L Thompson                             NULL, energy_viewer_filename,
194*5754ecacSJeremy L Thompson                             energy_viewer_filename, sizeof(energy_viewer_filename),
195*5754ecacSJeremy L Thompson                             &set); CHKERRQ(ierr);
196*5754ecacSJeremy L Thompson   if (set) {
197*5754ecacSJeremy L Thompson     ierr = PetscViewerASCIIOpen(comm, energy_viewer_filename,
198*5754ecacSJeremy L Thompson                                 &app_ctx->energy_viewer); CHKERRQ(ierr);
199*5754ecacSJeremy L Thompson     ierr = PetscViewerASCIIPrintf(app_ctx->energy_viewer, "increment,energy\n");
200*5754ecacSJeremy L Thompson     CHKERRQ(ierr);
201*5754ecacSJeremy L Thompson     // Initial configuration is base energy state; this may not be true if we extend in the future to
202*5754ecacSJeremy L Thompson     // initially loaded configurations (because a truly at-rest initial state may not be realizable).
203*5754ecacSJeremy L Thompson     ierr = PetscViewerASCIIPrintf(app_ctx->energy_viewer, "%f,%e\n", 0., 0.);
204*5754ecacSJeremy L Thompson     CHKERRQ(ierr);
205*5754ecacSJeremy L Thompson   }
206*5754ecacSJeremy L Thompson   ierr = PetscOptionsEnd(); CHKERRQ(ierr); // End of setting AppCtx
207*5754ecacSJeremy L Thompson 
208*5754ecacSJeremy L Thompson   // Check for all required values set
209*5754ecacSJeremy L Thompson   if (app_ctx->test_mode) {
210*5754ecacSJeremy L Thompson     if (app_ctx->forcing_choice == FORCE_NONE && !app_ctx->bc_clamp_count)
211*5754ecacSJeremy L Thompson       app_ctx->forcing_choice = FORCE_MMS;
212*5754ecacSJeremy L Thompson   }
213*5754ecacSJeremy L Thompson   if (!app_ctx->bc_clamp_count && app_ctx->forcing_choice != FORCE_MMS) {
214*5754ecacSJeremy L Thompson     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "-boundary options needed");
215*5754ecacSJeremy L Thompson   }
216*5754ecacSJeremy L Thompson 
217*5754ecacSJeremy L Thompson   // Provide default ceed resource if not specified
218*5754ecacSJeremy L Thompson   if (!ceed_flag) {
219*5754ecacSJeremy L Thompson     const char *ceed_resource = "/cpu/self";
220*5754ecacSJeremy L Thompson     strncpy(app_ctx->ceed_resource, ceed_resource, 10);
221*5754ecacSJeremy L Thompson   }
222*5754ecacSJeremy L Thompson 
223*5754ecacSJeremy L Thompson   // Determine number of levels
224*5754ecacSJeremy L Thompson   switch (app_ctx->multigrid_choice) {
225*5754ecacSJeremy L Thompson   case MULTIGRID_LOGARITHMIC:
226*5754ecacSJeremy L Thompson     app_ctx->num_levels = ceil(log(app_ctx->degree)/log(2)) + 1;
227*5754ecacSJeremy L Thompson     break;
228*5754ecacSJeremy L Thompson   case MULTIGRID_UNIFORM:
229*5754ecacSJeremy L Thompson     app_ctx->num_levels = app_ctx->degree;
230*5754ecacSJeremy L Thompson     break;
231*5754ecacSJeremy L Thompson   case MULTIGRID_NONE:
232*5754ecacSJeremy L Thompson     app_ctx->num_levels = 1;
233*5754ecacSJeremy L Thompson     break;
234*5754ecacSJeremy L Thompson   }
235*5754ecacSJeremy L Thompson 
236*5754ecacSJeremy L Thompson   // Populate array of degrees for each level for multigrid
237*5754ecacSJeremy L Thompson   ierr = PetscMalloc1(app_ctx->num_levels, &(app_ctx->level_degrees));
238*5754ecacSJeremy L Thompson   CHKERRQ(ierr);
239*5754ecacSJeremy L Thompson 
240*5754ecacSJeremy L Thompson   switch (app_ctx->multigrid_choice) {
241*5754ecacSJeremy L Thompson   case MULTIGRID_LOGARITHMIC:
242*5754ecacSJeremy L Thompson     for (int i = 0; i < app_ctx->num_levels-1; i++)
243*5754ecacSJeremy L Thompson       app_ctx->level_degrees[i] = pow(2,i);
244*5754ecacSJeremy L Thompson     app_ctx->level_degrees[app_ctx->num_levels-1] = app_ctx->degree;
245*5754ecacSJeremy L Thompson     break;
246*5754ecacSJeremy L Thompson   case MULTIGRID_UNIFORM:
247*5754ecacSJeremy L Thompson     for (int i = 0; i < app_ctx->num_levels; i++)
248*5754ecacSJeremy L Thompson       app_ctx->level_degrees[i] = i + 1;
249*5754ecacSJeremy L Thompson     break;
250*5754ecacSJeremy L Thompson   case MULTIGRID_NONE:
251*5754ecacSJeremy L Thompson     app_ctx->level_degrees[0] = app_ctx->degree;
252*5754ecacSJeremy L Thompson     break;
253*5754ecacSJeremy L Thompson   }
254*5754ecacSJeremy L Thompson 
255*5754ecacSJeremy L Thompson   PetscFunctionReturn(0);
256*5754ecacSJeremy L Thompson };
257