12 using namespace MoFEM;
79 CHKERR boundaryCondition();
94 char meshFileName[255];
96 meshFileName, 255, PETSC_NULL);
108 enum bases { AINSWORTH, DEMKOWICZ, LASBASETOPT };
109 const char *list_bases[LASBASETOPT] = {
"ainsworth",
"demkowicz"};
110 PetscInt choice_base_value = AINSWORTH;
112 LASBASETOPT, &choice_base_value, PETSC_NULL);
115 switch (choice_base_value) {
119 <<
"Set AINSWORTH_LEGENDRE_BASE for displacements";
124 <<
"Set DEMKOWICZ_JACOBI_BASE for displacements";
148 auto time_scale = boost::make_shared<TimeScale>();
159 pipeline_mng->getOpBoundaryRhsPipeline(), mField,
"U", {time_scale},
160 "FORCE", Sev::inform);
164 pipeline_mng->getOpDomainRhsPipeline(), mField,
"U", {time_scale},
165 "BODY_FORCE", Sev::inform);
168 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_X",
170 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_Y",
172 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_Z",
175 simple->getProblemName(),
"U");
178 CHKERR bc_mng->addBlockDOFsToMPCs(
simple->getProblemName(),
"U");
190 auto add_domain_ops_lhs = [&](
auto &pip) {
193 CHKERR HenckyOps::opFactoryDomainLhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
194 mField, pip,
"U",
"MAT_ELASTIC", Sev::inform);
198 auto add_domain_ops_rhs = [&](
auto &pip) {
201 CHKERR HenckyOps::opFactoryDomainRhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
202 mField, pip,
"U",
"MAT_ELASTIC", Sev::inform);
206 CHKERR add_domain_ops_lhs(pipeline_mng->getOpDomainLhsPipeline());
207 CHKERR add_domain_ops_rhs(pipeline_mng->getOpDomainRhsPipeline());
221 : dM(dm), postProc(post_proc){};
228 postProc->mField, postProc->getPostProcMesh(), {
"U"});
230 CHKERR postProc->writeFile(
231 "out_step_" + boost::lexical_cast<std::string>(ts_step) +
".h5m");
247 auto dm =
simple->getDM();
248 auto ts = pipeline_mng->createTSIM();
251 auto create_post_proc_fe = [dm,
this,
simple]() {
252 auto post_proc_ele_domain = [dm,
this](
auto &pip_domain) {
254 auto common_ptr = commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
255 mField, pip_domain,
"U",
"MAT_ELASTIC", Sev::inform);
259 auto post_proc_fe_bdy = boost::make_shared<PostProcEleBdy>(mField);
260 auto u_ptr = boost::make_shared<MatrixDouble>();
261 post_proc_fe_bdy->getOpPtrVector().push_back(
265 auto common_ptr = post_proc_ele_domain(op_loop_side->getOpPtrVector());
266 post_proc_fe_bdy->getOpPtrVector().push_back(op_loop_side);
270 post_proc_fe_bdy->getOpPtrVector().push_back(
274 post_proc_fe_bdy->getPostProcMesh(),
275 post_proc_fe_bdy->getMapGaussPts(),
281 {{
"GRAD", common_ptr->matGradPtr},
282 {
"FIRST_PIOLA", common_ptr->getMatFirstPiolaStress()}},
289 return post_proc_fe_bdy;
292 auto add_extra_finite_elements_to_ksp_solver_pipelines = [&]() {
295 auto pre_proc_ptr = boost::make_shared<FEMethod>();
296 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
297 auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
299 auto time_scale = boost::make_shared<TimeScale>();
301 auto get_bc_hook_rhs = [
this, pre_proc_ptr, time_scale]() {
304 {time_scale},
false)();
308 pre_proc_ptr->preProcessHook = get_bc_hook_rhs;
310 auto get_post_proc_hook_rhs = [
this, post_proc_rhs_ptr]() {
313 mField, post_proc_rhs_ptr,
nullptr, Sev::verbose)();
315 mField, post_proc_rhs_ptr, 1.)();
319 auto get_post_proc_hook_lhs = [
this, post_proc_lhs_ptr]() {
322 mField, post_proc_lhs_ptr, 1.)();
326 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
327 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs;
331 ts_ctx_ptr->getPreProcessIFunction().push_front(pre_proc_ptr);
332 ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_ptr);
333 ts_ctx_ptr->getPostProcessIFunction().push_back(post_proc_rhs_ptr);
334 ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_lhs_ptr);
340 CHKERR add_extra_finite_elements_to_ksp_solver_pipelines();
342 auto create_monitor_fe = [dm](
auto &&post_proc_fe) {
343 return boost::make_shared<Monitor>(dm, post_proc_fe);
347 boost::shared_ptr<FEMethod> null_fe;
348 auto monitor_ptr = create_monitor_fe(create_post_proc_fe());
350 null_fe, monitor_ptr);
354 CHKERR TSSetDuration(ts, PETSC_DEFAULT, ftime);
355 CHKERR TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP);
360 CHKERR TSSetFromOptions(ts);
363 CHKERR TSGetTime(ts, &ftime);
365 PetscInt steps, snesfails, rejects, nonlinits, linits;
366 CHKERR TSGetStepNumber(ts, &steps);
367 CHKERR TSGetSNESFailures(ts, &snesfails);
368 CHKERR TSGetStepRejections(ts, &rejects);
369 CHKERR TSGetSNESIterations(ts, &nonlinits);
370 CHKERR TSGetKSPIterations(ts, &linits);
372 "steps %d (%d rejected, %d SNES fails), ftime %g, nonlinits "
374 steps, rejects, snesfails, ftime, nonlinits, linits);
385 auto dm =
simple->getDM();
391 CHKERR VecNorm(T, NORM_2, &nrm2);
392 MOFEM_LOG(
"EXAMPLE", Sev::inform) <<
"Solution norm " << nrm2;
394 auto post_proc_norm_fe = boost::make_shared<DomainEle>(mField);
396 auto post_proc_norm_rule_hook = [](
int,
int,
int p) ->
int {
return 2 * p; };
397 post_proc_norm_fe->getRuleHook = post_proc_norm_rule_hook;
400 post_proc_norm_fe->getOpPtrVector(), {H1});
402 enum NORMS { U_NORM_L2 = 0, PIOLA_NORM, LAST_NORM };
405 (mField.get_comm_rank() == 0) ? LAST_NORM : 0, LAST_NORM);
406 CHKERR VecZeroEntries(norms_vec);
408 auto u_ptr = boost::make_shared<MatrixDouble>();
409 post_proc_norm_fe->getOpPtrVector().push_back(
412 post_proc_norm_fe->getOpPtrVector().push_back(
415 auto common_ptr = commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
416 mField, post_proc_norm_fe->getOpPtrVector(),
"U",
"MAT_ELASTIC",
419 post_proc_norm_fe->getOpPtrVector().push_back(
421 common_ptr->getMatFirstPiolaStress(), norms_vec, PIOLA_NORM));
426 CHKERR VecAssemblyBegin(norms_vec);
427 CHKERR VecAssemblyEnd(norms_vec);
430 if (mField.get_comm_rank() == 0) {
432 CHKERR VecGetArrayRead(norms_vec, &norms);
434 <<
"norm_u: " << std::scientific << std::sqrt(norms[U_NORM_L2]);
436 <<
"norm_piola: " << std::scientific << std::sqrt(norms[PIOLA_NORM]);
437 CHKERR VecRestoreArrayRead(norms_vec, &norms);
447 PetscInt test_nb = 0;
448 PetscBool test_flg = PETSC_FALSE;
457 CHKERR VecNorm(T, NORM_2, &nrm2);
458 MOFEM_LOG(
"EXAMPLE", Sev::verbose) <<
"Regression norm " << nrm2;
459 double regression_value = 0;
462 regression_value = 1.02789;
465 regression_value = 1.8841e+00;
468 regression_value = 1.8841e+00;
471 regression_value = 4.9625e+00;
474 regression_value = 6.6394e+00;
477 regression_value = 4.98764e+00;
480 regression_value = 4.9473e+00;
483 regression_value = 2.5749e-01;
490 if (fabs(nrm2 - regression_value) > 1e-2)
492 "Regression test field; wrong norm value. %6.4e != %6.4e", nrm2,
506 static char help[] =
"...\n\n";
508 int main(
int argc,
char *argv[]) {
511 const char param_file[] =
"param_file.petsc";
515 auto core_log = logging::core::get();
524 DMType dm_name =
"DMMOFEM";