35 const string default_options =
"-ksp_type fgmres \n"
37 "-pc_factor_mat_solver_type mumps \n"
38 "-mat_mumps_icntl_13 1 \n"
39 "-mat_mumps_icntl_14 800 \n"
40 "-mat_mumps_icntl_20 0 \n"
41 "-mat_mumps_icntl_24 1 \n"
42 "-snes_type newtonls \n"
43 "-snes_linesearch_type basic \n"
44 "-snes_divergence_tolerance 0 \n"
50 "-snes_converged_reason \n"
59 string param_file =
"param_file.petsc";
60 if (!
static_cast<bool>(ifstream(param_file))) {
61 std::ofstream file(param_file.c_str(), std::ios::ate);
63 file << default_options;
80 PetscInt nb_sub_steps = 1;
81 PetscBool is_partitioned = PETSC_FALSE;
82 PetscInt test_num = 0;
83 PetscBool wave_surf_flag = PETSC_FALSE;
84 PetscInt wave_dim = 2;
85 PetscBool is_displacement_field = PETSC_FALSE;
86 PetscInt wave_surf_block_id = 1;
87 PetscReal wave_length = 1.0;
88 PetscReal wave_ampl = 0.01;
89 PetscReal mesh_height = 1.0;
91 CHKERR PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Elastic Config",
"none");
93 CHKERR PetscOptionsString(
"-file_name",
"mesh file name",
"",
"mesh.h5m",
96 CHKERR PetscOptionsInt(
"-order",
"approximation order of spatial positions",
97 "", 1, &
order, PETSC_NULL);
99 CHKERR PetscOptionsInt(
"-step_num",
"number of steps",
"", nb_sub_steps,
100 &nb_sub_steps, PETSC_NULL);
102 CHKERR PetscOptionsBool(
"-is_partitioned",
103 "set if mesh is partitioned (this result that each "
104 "process keeps only part of the mesh",
105 "", PETSC_FALSE, &is_partitioned, PETSC_NULL);
107 CHKERR PetscOptionsInt(
"-test_num",
"test number",
"", 0, &test_num,
110 CHKERR PetscOptionsBool(
"-is_displacement_field",
"use displacement field",
111 "", PETSC_FALSE, &is_displacement_field,
113 CHKERR PetscOptionsBool(
"-wave_surf",
114 "if set true, make one of the surfaces wavy",
"",
115 PETSC_FALSE, &wave_surf_flag, PETSC_NULL);
116 CHKERR PetscOptionsInt(
"-wave_surf_block_id",
117 "make wavy surface of the block with this id",
"",
118 wave_surf_block_id, &wave_surf_block_id, PETSC_NULL);
119 CHKERR PetscOptionsInt(
"-wave_dim",
"dimension (2 or 3)",
"", wave_dim,
120 &wave_dim, PETSC_NULL);
121 CHKERR PetscOptionsReal(
"-wave_length",
"profile wavelength",
"",
122 wave_length, &wave_length, PETSC_NULL);
123 CHKERR PetscOptionsReal(
"-wave_ampl",
"profile amplitude",
"", wave_ampl,
124 &wave_ampl, PETSC_NULL);
125 CHKERR PetscOptionsReal(
"-mesh_height",
"vertical dimension of the mesh ",
126 "", mesh_height, &mesh_height, PETSC_NULL);
128 ierr = PetscOptionsEnd();
132 if (flg_file != PETSC_TRUE) {
133 SETERRQ(PETSC_COMM_SELF, 1,
"*** ERROR -file_name (MESH FILE NEEDED)");
136 if (is_partitioned == PETSC_TRUE)
138 "Partitioned mesh is not supported");
142 ParallelComm *pcomm = ParallelComm::get_pcomm(&moab,
MYPCOMM_INDEX);
144 pcomm =
new ParallelComm(&moab, PETSC_COMM_WORLD);
160 string primary_field_name;
162 if (!is_displacement_field)
163 primary_field_name =
"SPATIAL_POSITION";
165 primary_field_name =
"U";
169 "MESH_NODE_POSITIONS",
170 is_displacement_field);
172 "MESH_NODE_POSITIONS",
173 is_displacement_field);
176 m_field, primary_field_name,
"MESH_NODE_POSITIONS",
"CONTACT_PROB",
177 "ELASTIC", is_displacement_field,
true,
180 CHKERR m_boundary.getCommandLineParameters();
181 CHKERR m_contact.getCommandLineParameters();
182 CHKERR m_elastic.getCommandLineParameters();
184 CHKERR m_boundary.addElementFields();
185 CHKERR m_contact.addElementFields();
186 CHKERR m_elastic.addElementFields();
191 CHKERR m_boundary.createElements();
192 CHKERR m_contact.createElements();
193 CHKERR m_elastic.createElements();
196 if (!is_displacement_field) {
209 auto bit_ref = m_contact.getBitRefLevel();
219 DMType dm_name =
"DMMOFEM";
226 CHKERR DMSetType(dm, dm_name);
230 CHKERR DMSetFromOptions(dm);
234 CHKERR m_boundary.setOperators();
235 CHKERR m_contact.setOperators();
236 CHKERR m_elastic.setOperators();
238 CHKERR m_boundary.addElementsToDM(dm);
239 CHKERR m_contact.addElementsToDM(dm);
240 CHKERR m_elastic.addElementsToDM(dm);
244 CHKERR m_boundary.setupSolverFunctionSNES();
245 CHKERR m_contact.setupSolverFunctionSNES();
246 CHKERR m_elastic.setupSolverFunctionSNES();
248 CHKERR m_boundary.setupSolverJacobianSNES();
249 CHKERR m_contact.setupSolverJacobianSNES();
250 CHKERR m_elastic.setupSolverJacobianSNES();
261 char testing_options[] =
"-ksp_type fgmres "
263 "-pc_factor_mat_solver_type mumps "
264 "-snes_type newtonls "
265 "-snes_linesearch_type basic "
269 CHKERR PetscOptionsInsertString(NULL, testing_options);
273 CHKERR SNESSetDM(snes, dm);
274 CHKERR SNESSetFromOptions(snes);
276 for (
int ss = 0; ss != nb_sub_steps; ++ss) {
279 MOFEM_LOG_C(
"WORLD", Sev::inform,
"Load lambda %6.4e",
282 CHKERR SNESSolve(snes, PETSC_NULL,
D);
285 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
286 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
289 CHKERR m_elastic.postProcessElement(ss);
291 auto common_data_post = m_contact.commonDataPostProc;
292 std::ofstream ofs((std::string(
"test_simple_contact") +
".txt").c_str());
294 m_contact.getPostProcSimpleContactPipeline().push_back(
296 m_field, primary_field_name, common_data_post, ofs));
298 CHKERR m_contact.postProcessElement(ss);
299 CHKERR m_boundary.postProcessElement(ss);
301 double energy = m_elastic.elasticElementPtr->getLoopFeEnergy().eNergy;
303 ofs <<
"Elastic energy: " << energy << endl;
309 auto &nb_gauss_pts = m_contact.nbGaussPts;
310 auto &contact_area = m_contact.contactArea;
312 int expected_nb_gauss_pts;
313 double expected_energy, expected_contact_area;
316 expected_contact_area,
317 expected_nb_gauss_pts);
319 constexpr
double eps = 1e-6;
321 if ((
int)nb_gauss_pts[0] != expected_nb_gauss_pts) {
323 "Wrong number of active gauss pts %d != %d",
324 expected_nb_gauss_pts, (
int)nb_gauss_pts[0]);
326 if (std::abs(contact_area[0] - expected_contact_area) >
eps) {
328 "Wrong active contact area %6.4e != %6.4e",
329 expected_contact_area, contact_area[0]);
333 if (std::abs(energy - expected_energy) >
eps)
335 "Wrong energy %6.4e != %6.4e", expected_energy, energy);