33 {
34
35 const string default_options = "-ksp_type fgmres \n"
36 "-pc_type lu \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"
45 "-snes_max_it 50 \n"
46 "-snes_atol 1e-8 \n"
47 "-snes_rtol 1e-10 \n"
48 "-snes_monitor \n"
49 "-ksp_monitor \n"
50 "-snes_converged_reason \n"
51 "-order 1 \n"
52 "-order_lambda 1 \n"
53 "-order_contact 2 \n"
54 "-ho_levels_num 1 \n"
55 "-step_num 1 \n"
56 "-cn_value 1. \n"
57 "-alm_flag 0 \n";
58
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);
62 if (file.is_open()) {
63 file << default_options;
64 file.close();
65 }
66 }
67
68
70
71
72 moab::Core mb_instance;
73 moab::Interface &moab = mb_instance;
74
75 try {
76 PetscBool flg_file;
77
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;
90
91 CHKERR PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Elastic Config",
"none");
92
93 CHKERR PetscOptionsString(
"-file_name",
"mesh file name",
"",
"mesh.h5m",
95
96 CHKERR PetscOptionsInt(
"-order",
"approximation order of spatial positions",
97 "", 1, &
order, PETSC_NULL);
98
99 CHKERR PetscOptionsInt(
"-step_num",
"number of steps",
"", nb_sub_steps,
100 &nb_sub_steps, PETSC_NULL);
101
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);
106
107 CHKERR PetscOptionsInt(
"-test_num",
"test number",
"", 0, &test_num,
108 PETSC_NULL);
109
110 CHKERR PetscOptionsBool(
"-is_displacement_field",
"use displacement field",
111 "", PETSC_FALSE, &is_displacement_field,
112 PETSC_NULL);
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);
127
128 ierr = PetscOptionsEnd();
130
131
132 if (flg_file != PETSC_TRUE) {
133 SETERRQ(PETSC_COMM_SELF, 1, "*** ERROR -file_name (MESH FILE NEEDED)");
134 }
135
136 if (is_partitioned == PETSC_TRUE)
138 "Partitioned mesh is not supported");
139
140
141
142 ParallelComm *pcomm = ParallelComm::get_pcomm(&moab,
MYPCOMM_INDEX);
143 if (pcomm == NULL)
144 pcomm = new ParallelComm(&moab, PETSC_COMM_WORLD);
145
146
149
152
157
159
160 string primary_field_name;
161
162 if (!is_displacement_field)
163 primary_field_name = "SPATIAL_POSITION";
164 else
165 primary_field_name = "U";
166
167
169 "MESH_NODE_POSITIONS",
170 is_displacement_field);
172 "MESH_NODE_POSITIONS",
173 is_displacement_field);
174
176 m_field, primary_field_name, "MESH_NODE_POSITIONS", "CONTACT_PROB",
177 "ELASTIC", is_displacement_field, true,
179
180 CHKERR m_boundary.getCommandLineParameters();
181 CHKERR m_contact.getCommandLineParameters();
182 CHKERR m_elastic.getCommandLineParameters();
183
184 CHKERR m_boundary.addElementFields();
185 CHKERR m_contact.addElementFields();
186 CHKERR m_elastic.addElementFields();
187
188
190
191 CHKERR m_boundary.createElements();
192 CHKERR m_contact.createElements();
193 CHKERR m_elastic.createElements();
194
195
196 if (!is_displacement_field) {
199 }
200
201 {
204 }
205
206
208
209 auto bit_ref = m_contact.getBitRefLevel();
210
212
213
215
216
218
219 DMType dm_name = "DMMOFEM";
221
224
225
226 CHKERR DMSetType(dm, dm_name);
227
228
230 CHKERR DMSetFromOptions(dm);
232
233
234 CHKERR m_boundary.setOperators();
235 CHKERR m_contact.setOperators();
236 CHKERR m_elastic.setOperators();
237
238 CHKERR m_boundary.addElementsToDM(dm);
239 CHKERR m_contact.addElementsToDM(dm);
240 CHKERR m_elastic.addElementsToDM(dm);
241
243
244 CHKERR m_boundary.setupSolverFunctionSNES();
245 CHKERR m_contact.setupSolverFunctionSNES();
246 CHKERR m_elastic.setupSolverFunctionSNES();
247
248 CHKERR m_boundary.setupSolverJacobianSNES();
249 CHKERR m_contact.setupSolverJacobianSNES();
250 CHKERR m_elastic.setupSolverJacobianSNES();
251
252
253
254
255
256
257
258
260 if (test_num) {
261 char testing_options[] = "-ksp_type fgmres "
262 "-pc_type lu "
263 "-pc_factor_mat_solver_type mumps "
264 "-snes_type newtonls "
265 "-snes_linesearch_type basic "
266 "-snes_max_it 20 "
267 "-snes_atol 1e-8 "
268 "-snes_rtol 1e-8 ";
269 CHKERR PetscOptionsInsertString(NULL, testing_options);
270 }
271
273 CHKERR SNESSetDM(snes, dm);
274 CHKERR SNESSetFromOptions(snes);
275
276 for (int ss = 0; ss != nb_sub_steps; ++ss) {
277
279 MOFEM_LOG_C(
"WORLD", Sev::inform,
"Load lambda %6.4e",
281
282 CHKERR SNESSolve(snes, PETSC_NULL,
D);
283
284
285 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
286 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
288
289 CHKERR m_elastic.postProcessElement(ss);
290
291 auto common_data_post = m_contact.commonDataPostProc;
292 std::ofstream ofs((std::string("test_simple_contact") + ".txt").c_str());
293
294 m_contact.getPostProcSimpleContactPipeline().push_back(
296 m_field, primary_field_name, common_data_post, ofs));
297
298 CHKERR m_contact.postProcessElement(ss);
299 CHKERR m_boundary.postProcessElement(ss);
300
301 double energy = m_elastic.elasticElementPtr->getLoopFeEnergy().eNergy;
302
303 ofs << "Elastic energy: " << energy << endl;
304 ofs.flush();
305 ofs.close();
306
307 if (test_num) {
308
309 auto &nb_gauss_pts = m_contact.nbGaussPts;
310 auto &contact_area = m_contact.contactArea;
311
312 int expected_nb_gauss_pts;
313 double expected_energy, expected_contact_area;
314
316 expected_contact_area,
317 expected_nb_gauss_pts);
318
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]);
325 }
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]);
330 }
331 }
332
333 if (std::abs(energy - expected_energy) >
eps)
335 "Wrong energy %6.4e != %6.4e", expected_energy, energy);
336 }
337 }
338 }
340
341
343
344 return 0;
345}
#define MOFEM_LOG_C(channel, severity, format,...)
void simple(double P1[], double P2[], double P3[], double c[], const int N)
#define CATCH_ERRORS
Catch errors.
#define MYPCOMM_INDEX
default communicator number PCOMM
@ MOFEM_ATOM_TEST_INVALID
#define CHKERR
Inline error check.
PetscErrorCode DMMoFEMSetIsPartitioned(DM dm, PetscBool is_partitioned)
PetscErrorCode DMMoFEMCreateMoFEM(DM dm, MoFEM::Interface *m_field_ptr, const char problem_name[], const MoFEM::BitRefLevel bit_level, const MoFEM::BitRefLevel bit_mask=MoFEM::BitRefLevel().set())
Must be called by user to set MoFEM data structures.
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
PetscErrorCode DMoFEMMeshToGlobalVector(DM dm, Vec g, InsertMode mode, ScatterMode scatter_mode)
set ghosted vector values on all existing mesh entities
virtual MoFEMErrorCode build_finite_elements(int verb=DEFAULT_VERBOSITY)=0
Build finite elements.
virtual MoFEMErrorCode build_fields(int verb=DEFAULT_VERBOSITY)=0
virtual MoFEMErrorCode loop_dofs(const Problem *problem_ptr, const std::string &field_name, RowColData rc, DofMethod &method, int lower_rank, int upper_rank, int verb=DEFAULT_VERBOSITY)=0
Make a loop over dofs.
virtual MoFEMErrorCode add_problem(const std::string &name, enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
Add problem.
virtual MoFEMErrorCode modify_problem_ref_level_add_bit(const std::string &name_problem, const BitRefLevel &bit)=0
add ref level to problem
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
auto createSNES(MPI_Comm comm)
DEPRECATED auto createSmartDM(MPI_Comm comm, const std::string dm_type_name)
DEPRECATED auto smartCreateDMVector(DM dm)
MoFEMErrorCode check_tests(int ss, int test_num, double &expected_energy, double &expected_contact_area, int &expected_nb_gauss_pts)
Set of functions declaring elements and setting operators for basic boundary conditions interface.
virtual MoFEMErrorCode build_adjacencies(const Range &ents, int verb=DEFAULT_VERBOSITY)=0
build adjacencies
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Deprecated interface functions.
Interface for managing meshsets containing materials and boundary conditions.
MoFEMErrorCode printForceSet() const
print meshsets with force boundary conditions data structure
MoFEMErrorCode printMaterialsSet() const
print meshsets with material data structure set on it
MoFEMErrorCode printDisplacementSet() const
print meshsets with displacement boundary conditions data structure
Projection of edge entities with one mid-node on hierarchical basis.
Simple interface for fast problem set-up.
intrusive_ptr for managing petsc objects
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Set of functions declaring elements and setting operators for generic element interface.