xref: /libCEED/examples/solids/src/cl-options.c (revision 67490bc6de48fa3615ca135c74fbc2a7c9584dee)
13d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors.
23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
33d8e8822SJeremy L Thompson //
43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause
53d8e8822SJeremy L Thompson //
63d8e8822SJeremy L Thompson // This file is part of CEED:  http://github.com/ceed
73d8e8822SJeremy L Thompson 
85754ecacSJeremy L Thompson /// @file
95754ecacSJeremy L Thompson /// Command line option processing for solid mechanics example using PETSc
105754ecacSJeremy L Thompson 
115754ecacSJeremy L Thompson #include "../include/cl-options.h"
125754ecacSJeremy L Thompson 
135754ecacSJeremy L Thompson // -----------------------------------------------------------------------------
145754ecacSJeremy L Thompson // Process command line options
155754ecacSJeremy L Thompson // -----------------------------------------------------------------------------
165754ecacSJeremy L Thompson // Process general command line options
175754ecacSJeremy L Thompson PetscErrorCode ProcessCommandLineOptions(MPI_Comm comm, AppCtx app_ctx) {
185754ecacSJeremy L Thompson   PetscErrorCode ierr;
195754ecacSJeremy L Thompson   PetscBool ceed_flag = PETSC_FALSE;
205754ecacSJeremy L Thompson 
215754ecacSJeremy L Thompson   PetscFunctionBeginUser;
225754ecacSJeremy L Thompson 
23*67490bc6SJeremy L Thompson   PetscOptionsBegin(comm, NULL,
24*67490bc6SJeremy L Thompson                     "Elasticity / Hyperelasticity in PETSc with libCEED", NULL);
255754ecacSJeremy L Thompson 
265754ecacSJeremy L Thompson   ierr = PetscOptionsString("-ceed", "CEED resource specifier",
275754ecacSJeremy L Thompson                             NULL, app_ctx->ceed_resource, app_ctx->ceed_resource,
285754ecacSJeremy L Thompson                             sizeof(app_ctx->ceed_resource), &ceed_flag);
295754ecacSJeremy L Thompson   CHKERRQ(ierr);
305754ecacSJeremy L Thompson 
315754ecacSJeremy L Thompson   ierr = PetscStrncpy(app_ctx->output_dir, ".", 2);
325754ecacSJeremy L Thompson   CHKERRQ(ierr); // Default - current directory
335754ecacSJeremy L Thompson   ierr = PetscOptionsString("-output_dir", "Output directory",
345754ecacSJeremy L Thompson                             NULL, app_ctx->output_dir, app_ctx->output_dir,
355754ecacSJeremy L Thompson                             sizeof(app_ctx->output_dir), NULL); CHKERRQ(ierr);
365754ecacSJeremy L Thompson 
375754ecacSJeremy L Thompson   app_ctx->degree         = 3;
385754ecacSJeremy L Thompson   ierr = PetscOptionsInt("-degree", "Polynomial degree of tensor product basis",
395754ecacSJeremy L Thompson                          NULL, app_ctx->degree, &app_ctx->degree, NULL);
405754ecacSJeremy L Thompson   CHKERRQ(ierr);
415754ecacSJeremy L Thompson 
425754ecacSJeremy L Thompson   app_ctx->q_extra         = 0;
435754ecacSJeremy L Thompson   ierr = PetscOptionsInt("-qextra", "Number of extra quadrature points",
445754ecacSJeremy L Thompson                          NULL, app_ctx->q_extra, &app_ctx->q_extra, NULL);
455754ecacSJeremy L Thompson   CHKERRQ(ierr);
465754ecacSJeremy L Thompson 
475754ecacSJeremy L Thompson   ierr = PetscOptionsString("-mesh", "Read mesh from file", NULL,
485754ecacSJeremy L Thompson                             app_ctx->mesh_file, app_ctx->mesh_file,
495754ecacSJeremy L Thompson                             sizeof(app_ctx->mesh_file), NULL); CHKERRQ(ierr);
505754ecacSJeremy L Thompson 
515754ecacSJeremy L Thompson   app_ctx->problem_choice  = ELAS_LINEAR;       // Default - Linear Elasticity
525754ecacSJeremy L Thompson   ierr = PetscOptionsEnum("-problem",
535754ecacSJeremy L Thompson                           "Solves Elasticity & Hyperelasticity Problems",
545754ecacSJeremy L Thompson                           NULL, problemTypes, (PetscEnum)app_ctx->problem_choice,
555754ecacSJeremy L Thompson                           (PetscEnum *)&app_ctx->problem_choice, NULL);
565754ecacSJeremy L Thompson   CHKERRQ(ierr);
575754ecacSJeremy L Thompson   app_ctx->name = problemTypes[app_ctx->problem_choice];
585754ecacSJeremy L Thompson   app_ctx->name_for_disp = problemTypesForDisp[app_ctx->problem_choice];
595754ecacSJeremy L Thompson 
605754ecacSJeremy L Thompson   app_ctx->num_increments = app_ctx->problem_choice == ELAS_LINEAR ? 1 : 10;
615754ecacSJeremy L Thompson   ierr = PetscOptionsInt("-num_steps", "Number of pseudo-time steps",
625754ecacSJeremy L Thompson                          NULL, app_ctx->num_increments, &app_ctx->num_increments,
635754ecacSJeremy L Thompson                          NULL); CHKERRQ(ierr);
645754ecacSJeremy L Thompson 
655754ecacSJeremy L Thompson   app_ctx->forcing_choice  = FORCE_NONE;     // Default - no forcing term
665754ecacSJeremy L Thompson   ierr = PetscOptionsEnum("-forcing", "Set forcing function option", NULL,
675754ecacSJeremy L Thompson                           forcing_types, (PetscEnum)app_ctx->forcing_choice,
685754ecacSJeremy L Thompson                           (PetscEnum *)&app_ctx->forcing_choice, NULL);
695754ecacSJeremy L Thompson   CHKERRQ(ierr);
705754ecacSJeremy L Thompson 
715754ecacSJeremy L Thompson   PetscInt max_n = 3;
725754ecacSJeremy L Thompson   app_ctx->forcing_vector[0] = 0;
735754ecacSJeremy L Thompson   app_ctx->forcing_vector[1] = -1;
745754ecacSJeremy L Thompson   app_ctx->forcing_vector[2] = 0;
755754ecacSJeremy L Thompson   ierr = PetscOptionsScalarArray("-forcing_vec",
765754ecacSJeremy L Thompson                                  "Direction to apply constant force", NULL,
775754ecacSJeremy L Thompson                                  app_ctx->forcing_vector, &max_n, NULL);
785754ecacSJeremy L Thompson   CHKERRQ(ierr);
795754ecacSJeremy L Thompson 
805754ecacSJeremy L Thompson   if ((app_ctx->problem_choice == ELAS_FSInitial_NH1 ||
815754ecacSJeremy L Thompson        app_ctx->problem_choice == ELAS_FSInitial_NH2 ||
825754ecacSJeremy L Thompson        app_ctx->problem_choice == ELAS_FSCurrent_NH1 ||
835754ecacSJeremy L Thompson        app_ctx->problem_choice == ELAS_FSCurrent_NH2 ||
845754ecacSJeremy L Thompson        app_ctx->problem_choice == ELAS_FSInitial_MR1) &&
855754ecacSJeremy L Thompson       app_ctx->forcing_choice == FORCE_CONST)
865754ecacSJeremy L Thompson     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP,
875754ecacSJeremy L Thompson             "Cannot use constant forcing and finite strain formulation. "
885754ecacSJeremy L Thompson             "Constant forcing in reference frame currently unavaliable.");
895754ecacSJeremy L Thompson 
905754ecacSJeremy L Thompson   // Dirichlet boundary conditions
915754ecacSJeremy L Thompson   app_ctx->bc_clamp_count = 16;
925754ecacSJeremy L Thompson   ierr = PetscOptionsIntArray("-bc_clamp",
935754ecacSJeremy L Thompson                               "Face IDs to apply incremental Dirichlet BC",
945754ecacSJeremy L Thompson                               NULL, app_ctx->bc_clamp_faces, &app_ctx->bc_clamp_count,
955754ecacSJeremy L Thompson                               NULL); CHKERRQ(ierr);
965754ecacSJeremy L Thompson   // Set vector for each clamped BC
975754ecacSJeremy L Thompson   for (PetscInt i = 0; i < app_ctx->bc_clamp_count; i++) {
985754ecacSJeremy L Thompson     // Translation vector
995754ecacSJeremy L Thompson     char option_name[25];
1005754ecacSJeremy L Thompson     const size_t nclamp_params = sizeof(app_ctx->bc_clamp_max[0])/sizeof(
1015754ecacSJeremy L Thompson                                    app_ctx->bc_clamp_max[0][0]);
1025754ecacSJeremy L Thompson     for (PetscInt j = 0; j < nclamp_params; j++)
1035754ecacSJeremy L Thompson       app_ctx->bc_clamp_max[i][j] = 0.;
1045754ecacSJeremy L Thompson 
1055754ecacSJeremy L Thompson     snprintf(option_name, sizeof option_name, "-bc_clamp_%d_translate",
1065754ecacSJeremy L Thompson              app_ctx->bc_clamp_faces[i]);
1075754ecacSJeremy L Thompson     max_n = 3;
1085754ecacSJeremy L Thompson     ierr = PetscOptionsScalarArray(option_name,
1095754ecacSJeremy L Thompson                                    "Vector to translate clamped end by", NULL,
1105754ecacSJeremy L Thompson                                    app_ctx->bc_clamp_max[i], &max_n, NULL);
1115754ecacSJeremy L Thompson     CHKERRQ(ierr);
1125754ecacSJeremy L Thompson 
1135754ecacSJeremy L Thompson     // Rotation vector
1145754ecacSJeremy L Thompson     max_n = 5;
1155754ecacSJeremy L Thompson     snprintf(option_name, sizeof option_name, "-bc_clamp_%d_rotate",
1165754ecacSJeremy L Thompson              app_ctx->bc_clamp_faces[i]);
1175754ecacSJeremy L Thompson     ierr = PetscOptionsScalarArray(option_name,
1185754ecacSJeremy L Thompson                                    "Vector with axis of rotation and rotation, in radians",
1195754ecacSJeremy L Thompson                                    NULL, &app_ctx->bc_clamp_max[i][3], &max_n, NULL);
1205754ecacSJeremy L Thompson     CHKERRQ(ierr);
1215754ecacSJeremy L Thompson 
1225754ecacSJeremy L Thompson     // Normalize
1235754ecacSJeremy L Thompson     PetscScalar norm = sqrt(app_ctx->bc_clamp_max[i][3]*app_ctx->bc_clamp_max[i][3]
1245754ecacSJeremy L Thompson                             + app_ctx->bc_clamp_max[i][4]*app_ctx->bc_clamp_max[i][4]
1255754ecacSJeremy L Thompson                             + app_ctx->bc_clamp_max[i][5]*app_ctx->bc_clamp_max[i][5]);
1265754ecacSJeremy L Thompson     if (fabs(norm) < 1e-16)
1275754ecacSJeremy L Thompson       norm = 1;
1285754ecacSJeremy L Thompson     for (PetscInt j = 0; j < 3; j++)
1295754ecacSJeremy L Thompson       app_ctx->bc_clamp_max[i][3 + j] /= norm;
1305754ecacSJeremy L Thompson   }
1315754ecacSJeremy L Thompson 
1325754ecacSJeremy L Thompson   // Neumann boundary conditions
1335754ecacSJeremy L Thompson   app_ctx->bc_traction_count = 16;
1345754ecacSJeremy L Thompson   ierr = PetscOptionsIntArray("-bc_traction",
1355754ecacSJeremy L Thompson                               "Face IDs to apply traction (Neumann) BC",
1365754ecacSJeremy L Thompson                               NULL, app_ctx->bc_traction_faces,
1375754ecacSJeremy L Thompson                               &app_ctx->bc_traction_count, NULL); CHKERRQ(ierr);
1385754ecacSJeremy L Thompson   // Set vector for each traction BC
1395754ecacSJeremy L Thompson   for (PetscInt i = 0; i < app_ctx->bc_traction_count; i++) {
1405754ecacSJeremy L Thompson     // Translation vector
1415754ecacSJeremy L Thompson     char option_name[25];
1425754ecacSJeremy L Thompson     for (PetscInt j = 0; j < 3; j++)
1435754ecacSJeremy L Thompson       app_ctx->bc_traction_vector[i][j] = 0.;
1445754ecacSJeremy L Thompson 
1455754ecacSJeremy L Thompson     snprintf(option_name, sizeof option_name, "-bc_traction_%d",
1465754ecacSJeremy L Thompson              app_ctx->bc_traction_faces[i]);
1475754ecacSJeremy L Thompson     max_n = 3;
1485754ecacSJeremy L Thompson     PetscBool set = false;
1495754ecacSJeremy L Thompson     ierr = PetscOptionsScalarArray(option_name,
1505754ecacSJeremy L Thompson                                    "Traction vector for constrained face", NULL,
1515754ecacSJeremy L Thompson                                    app_ctx->bc_traction_vector[i], &max_n, &set);
1525754ecacSJeremy L Thompson     CHKERRQ(ierr);
1535754ecacSJeremy L Thompson 
1545754ecacSJeremy L Thompson     if (!set)
1555754ecacSJeremy L Thompson       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP,
1565754ecacSJeremy L Thompson               "Traction vector must be set for all traction boundary conditions.");
1575754ecacSJeremy L Thompson   }
1585754ecacSJeremy L Thompson 
1595754ecacSJeremy L Thompson   app_ctx->multigrid_choice = MULTIGRID_LOGARITHMIC;
1605754ecacSJeremy L Thompson   ierr = PetscOptionsEnum("-multigrid", "Set multigrid type option", NULL,
1615754ecacSJeremy L Thompson                           multigrid_types, (PetscEnum)app_ctx->multigrid_choice,
1625754ecacSJeremy L Thompson                           (PetscEnum *)&app_ctx->multigrid_choice, NULL);
1635754ecacSJeremy L Thompson   CHKERRQ(ierr);
1645754ecacSJeremy L Thompson 
1655754ecacSJeremy L Thompson   app_ctx->test_mode = PETSC_FALSE;
1665754ecacSJeremy L Thompson   ierr = PetscOptionsBool("-test",
1675754ecacSJeremy L Thompson                           "Testing mode (do not print unless error is large)",
1685754ecacSJeremy L Thompson                           NULL, app_ctx->test_mode, &(app_ctx->test_mode), NULL);
1695754ecacSJeremy L Thompson   CHKERRQ(ierr);
1705754ecacSJeremy L Thompson 
1715754ecacSJeremy L Thompson   app_ctx->expect_final_strain = -1.;
1725754ecacSJeremy L Thompson   ierr = PetscOptionsReal("-expect_final_strain_energy",
1735754ecacSJeremy L Thompson                           "Expect final strain energy close to this value.",
1745754ecacSJeremy L Thompson                           NULL, app_ctx->expect_final_strain, &app_ctx->expect_final_strain, NULL);
1755754ecacSJeremy L Thompson   CHKERRQ(ierr);
1765754ecacSJeremy L Thompson 
1775754ecacSJeremy L Thompson   app_ctx->test_tol = 1e-8;
1785754ecacSJeremy L Thompson   ierr = PetscOptionsReal("-expect_final_state_rtol",
1795754ecacSJeremy L Thompson                           "Relative tolerance for final strain energy test",
1805754ecacSJeremy L Thompson                           NULL, app_ctx->test_tol, &app_ctx->test_tol, NULL);
1815754ecacSJeremy L Thompson   CHKERRQ(ierr);
1825754ecacSJeremy L Thompson 
1835754ecacSJeremy L Thompson   app_ctx->view_soln = PETSC_FALSE;
1845754ecacSJeremy L Thompson   ierr = PetscOptionsBool("-view_soln", "Write out solution vector for viewing",
1855754ecacSJeremy L Thompson                           NULL, app_ctx->view_soln, &(app_ctx->view_soln), NULL);
1865754ecacSJeremy L Thompson   CHKERRQ(ierr);
1875754ecacSJeremy L Thompson 
1885754ecacSJeremy L Thompson   app_ctx->view_final_soln = PETSC_FALSE;
1895754ecacSJeremy L Thompson   ierr = PetscOptionsBool("-view_final_soln",
1905754ecacSJeremy L Thompson                           "Write out final solution vector for viewing",
1915754ecacSJeremy L Thompson                           NULL, app_ctx->view_final_soln, &(app_ctx->view_final_soln),
1925754ecacSJeremy L Thompson                           NULL); CHKERRQ(ierr);
1935754ecacSJeremy L Thompson   CHKERRQ(ierr);
1945754ecacSJeremy L Thompson 
1955754ecacSJeremy L Thompson   PetscBool set;
1965754ecacSJeremy L Thompson   char energy_viewer_filename[PETSC_MAX_PATH_LEN] = "";
1975754ecacSJeremy L Thompson   ierr = PetscOptionsString("-strain_energy_monitor",
1985754ecacSJeremy L Thompson                             "Print out current strain energy at every load increment",
1995754ecacSJeremy L Thompson                             NULL, energy_viewer_filename,
2005754ecacSJeremy L Thompson                             energy_viewer_filename, sizeof(energy_viewer_filename),
2015754ecacSJeremy L Thompson                             &set); CHKERRQ(ierr);
2025754ecacSJeremy L Thompson   if (set) {
2035754ecacSJeremy L Thompson     ierr = PetscViewerASCIIOpen(comm, energy_viewer_filename,
2045754ecacSJeremy L Thompson                                 &app_ctx->energy_viewer); CHKERRQ(ierr);
2055754ecacSJeremy L Thompson     ierr = PetscViewerASCIIPrintf(app_ctx->energy_viewer, "increment,energy\n");
2065754ecacSJeremy L Thompson     CHKERRQ(ierr);
2075754ecacSJeremy L Thompson     // Initial configuration is base energy state; this may not be true if we extend in the future to
2085754ecacSJeremy L Thompson     // initially loaded configurations (because a truly at-rest initial state may not be realizable).
2095754ecacSJeremy L Thompson     ierr = PetscViewerASCIIPrintf(app_ctx->energy_viewer, "%f,%e\n", 0., 0.);
2105754ecacSJeremy L Thompson     CHKERRQ(ierr);
2115754ecacSJeremy L Thompson   }
212*67490bc6SJeremy L Thompson   PetscOptionsEnd(); // End of setting AppCtx
2135754ecacSJeremy L Thompson 
2145754ecacSJeremy L Thompson   // Check for all required values set
2155754ecacSJeremy L Thompson   if (app_ctx->test_mode) {
2165754ecacSJeremy L Thompson     if (app_ctx->forcing_choice == FORCE_NONE && !app_ctx->bc_clamp_count)
2175754ecacSJeremy L Thompson       app_ctx->forcing_choice = FORCE_MMS;
2185754ecacSJeremy L Thompson   }
2195754ecacSJeremy L Thompson   if (!app_ctx->bc_clamp_count && app_ctx->forcing_choice != FORCE_MMS) {
2205754ecacSJeremy L Thompson     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "-boundary options needed");
2215754ecacSJeremy L Thompson   }
2225754ecacSJeremy L Thompson 
2235754ecacSJeremy L Thompson   // Provide default ceed resource if not specified
2245754ecacSJeremy L Thompson   if (!ceed_flag) {
2255754ecacSJeremy L Thompson     const char *ceed_resource = "/cpu/self";
2265754ecacSJeremy L Thompson     strncpy(app_ctx->ceed_resource, ceed_resource, 10);
2275754ecacSJeremy L Thompson   }
2285754ecacSJeremy L Thompson 
2295754ecacSJeremy L Thompson   // Determine number of levels
2305754ecacSJeremy L Thompson   switch (app_ctx->multigrid_choice) {
2315754ecacSJeremy L Thompson   case MULTIGRID_LOGARITHMIC:
2325754ecacSJeremy L Thompson     app_ctx->num_levels = ceil(log(app_ctx->degree)/log(2)) + 1;
2335754ecacSJeremy L Thompson     break;
2345754ecacSJeremy L Thompson   case MULTIGRID_UNIFORM:
2355754ecacSJeremy L Thompson     app_ctx->num_levels = app_ctx->degree;
2365754ecacSJeremy L Thompson     break;
2375754ecacSJeremy L Thompson   case MULTIGRID_NONE:
2385754ecacSJeremy L Thompson     app_ctx->num_levels = 1;
2395754ecacSJeremy L Thompson     break;
2405754ecacSJeremy L Thompson   }
2415754ecacSJeremy L Thompson 
2425754ecacSJeremy L Thompson   // Populate array of degrees for each level for multigrid
2435754ecacSJeremy L Thompson   ierr = PetscMalloc1(app_ctx->num_levels, &(app_ctx->level_degrees));
2445754ecacSJeremy L Thompson   CHKERRQ(ierr);
2455754ecacSJeremy L Thompson 
2465754ecacSJeremy L Thompson   switch (app_ctx->multigrid_choice) {
2475754ecacSJeremy L Thompson   case MULTIGRID_LOGARITHMIC:
2485754ecacSJeremy L Thompson     for (int i = 0; i < app_ctx->num_levels-1; i++)
2495754ecacSJeremy L Thompson       app_ctx->level_degrees[i] = pow(2,i);
2505754ecacSJeremy L Thompson     app_ctx->level_degrees[app_ctx->num_levels-1] = app_ctx->degree;
2515754ecacSJeremy L Thompson     break;
2525754ecacSJeremy L Thompson   case MULTIGRID_UNIFORM:
2535754ecacSJeremy L Thompson     for (int i = 0; i < app_ctx->num_levels; i++)
2545754ecacSJeremy L Thompson       app_ctx->level_degrees[i] = i + 1;
2555754ecacSJeremy L Thompson     break;
2565754ecacSJeremy L Thompson   case MULTIGRID_NONE:
2575754ecacSJeremy L Thompson     app_ctx->level_degrees[0] = app_ctx->degree;
2585754ecacSJeremy L Thompson     break;
2595754ecacSJeremy L Thompson   }
2605754ecacSJeremy L Thompson 
2615754ecacSJeremy L Thompson   PetscFunctionReturn(0);
2625754ecacSJeremy L Thompson };
263