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