v0.14.0
Classes | Public Member Functions | Private Member Functions | Private Attributes | List of all members
Contact Struct Reference
Collaboration diagram for Contact:
[legend]

Classes

struct  ScaledTimeScale
 

Public Member Functions

 Contact (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 [Run problem] More...
 

Private Member Functions

MoFEMErrorCode setupProblem ()
 [Run problem] More...
 
MoFEMErrorCode createCommonData ()
 [Set up problem] More...
 
MoFEMErrorCode bC ()
 [Create common data] More...
 
MoFEMErrorCode OPs ()
 [Boundary condition] More...
 
MoFEMErrorCode tsSolve ()
 
MoFEMErrorCode checkResults ()
 [Solve] More...
 

Private Attributes

MoFEM::InterfacemField
 
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uXScatter
 
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uYScatter
 
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uZScatter
 
boost::shared_ptr< GenericElementInterfacemfrontInterface
 
boost::shared_ptr< MonitormonitorPtr
 

Detailed Description

Definition at line 169 of file contact.cpp.

Constructor & Destructor Documentation

◆ Contact()

Contact::Contact ( MoFEM::Interface m_field)
inline

Definition at line 171 of file contact.cpp.

171 : mField(m_field) {}

Member Function Documentation

◆ bC()

MoFEMErrorCode Contact::bC ( )
private

[Create common data]

[Boundary condition]

Definition at line 502 of file contact.cpp.

502  {
504  auto bc_mng = mField.getInterface<BcManager>();
505  auto simple = mField.getInterface<Simple>();
506 
507  for (auto f : {"U", "SIGMA"}) {
508  CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
509  "REMOVE_X", f, 0, 0);
510  CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
511  "REMOVE_Y", f, 1, 1);
512  CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
513  "REMOVE_Z", f, 2, 2);
514  CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
515  "REMOVE_ALL", f, 0, 3);
516  }
517 
518  CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "FIX_X",
519  "SIGMA", 0, 0, false, true);
520  CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "FIX_Y",
521  "SIGMA", 1, 1, false, true);
522  CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "FIX_Z",
523  "SIGMA", 2, 2, false, true);
524  CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "FIX_ALL",
525  "SIGMA", 0, 3, false, true);
526  CHKERR bc_mng->removeBlockDOFsOnEntities(
527  simple->getProblemName(), "NO_CONTACT", "SIGMA", 0, 3, false, true);
528 
529  // Note remove has to be always before push. Then node marking will be
530  // corrupted.
531  CHKERR bc_mng->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
532  simple->getProblemName(), "U");
533 
535 }

◆ checkResults()

MoFEMErrorCode Contact::checkResults ( )
private

[Solve]

[Check]

Definition at line 911 of file contact.cpp.

911  {
913  if (atom_test == 1 && !mField.get_comm_rank()) {
914  const double *t_ptr;
915  CHKERR VecGetArrayRead(ContactOps::CommonData::totalTraction, &t_ptr);
916  double hertz_tract = 158.73;
917  double tol = 4e-3;
918  if (fabs(t_ptr[1] - hertz_tract) / hertz_tract > tol) {
919  SETERRQ3(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
920  "atom test %d diverged! %3.4e != %3.4e", atom_test, t_ptr[1],
921  hertz_tract);
922  }
923  CHKERR VecRestoreArrayRead(ContactOps::CommonData::totalTraction, &t_ptr);
924  }
925 
927 
929 }

◆ createCommonData()

MoFEMErrorCode Contact::createCommonData ( )
private

[Set up problem]

[Create common data]

Definition at line 432 of file contact.cpp.

432  {
434 
435  auto get_options = [&]() {
437  CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-scale", &scale, PETSC_NULL);
438  CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-young_modulus",
439  &young_modulus, PETSC_NULL);
440  CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-poisson_ratio",
441  &poisson_ratio, PETSC_NULL);
442  CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-rho", &rho, PETSC_NULL);
443  CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-cn", &cn_contact,
444  PETSC_NULL);
445  CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-spring_stiffness",
446  &spring_stiffness, PETSC_NULL);
447  CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-vis_spring_stiffness",
448  &vis_spring_stiffness, PETSC_NULL);
449  CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-alpha_damping",
450  &alpha_damping, PETSC_NULL);
451 
452  if (!mfrontInterface) {
453  MOFEM_LOG("CONTACT", Sev::inform) << "Young modulus " << young_modulus;
454  MOFEM_LOG("CONTACT", Sev::inform) << "Poisson_ratio " << poisson_ratio;
455  } else {
456  MOFEM_LOG("CONTACT", Sev::inform) << "Using MFront for material model";
457  }
458 
459  MOFEM_LOG("CONTACT", Sev::inform) << "Density " << rho;
460  MOFEM_LOG("CONTACT", Sev::inform) << "cn_contact " << cn_contact;
461  MOFEM_LOG("CONTACT", Sev::inform)
462  << "Spring stiffness " << spring_stiffness;
463  MOFEM_LOG("CONTACT", Sev::inform)
464  << "Vis spring_stiffness " << vis_spring_stiffness;
465 
466  MOFEM_LOG("CONTACT", Sev::inform) << "alpha_damping " << alpha_damping;
467 
468  PetscBool use_scale = PETSC_FALSE;
469  CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-use_scale", &use_scale,
470  PETSC_NULL);
471  if (use_scale) {
472  scale /= young_modulus;
473  }
474 
475  MOFEM_LOG("CONTACT", Sev::inform) << "Scale " << scale;
476 
477  CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-is_quasi_static",
478  &is_quasi_static, PETSC_NULL);
479  MOFEM_LOG("CONTACT", Sev::inform)
480  << "Is quasi-static: " << (is_quasi_static ? "true" : "false");
481 
483  };
484 
485  CHKERR get_options();
486 
487 #ifdef PYTHON_SDF
488  char sdf_file_name[255];
489  CHKERR PetscOptionsGetString(PETSC_NULL, PETSC_NULL, "-sdf_file",
490  sdf_file_name, 255, PETSC_NULL);
491 
492  sdfPythonPtr = boost::make_shared<SDFPython>();
493  CHKERR sdfPythonPtr->sdfInit(sdf_file_name);
494  sdfPythonWeakPtr = sdfPythonPtr;
495 #endif
496 
498 }

◆ OPs()

MoFEMErrorCode Contact::OPs ( )
private

[Boundary condition]

[Push operators to pip]

[Only used for dynamics]

[Only used for dynamics]

[Only used for dynamics]

[Only used for dynamics]

[Operators used for contact]

[Operators used for contact]

[Operators used for contact]

[Operators used for contact]

Definition at line 539 of file contact.cpp.

539  {
541  auto simple = mField.getInterface<Simple>();
542  auto *pip_mng = mField.getInterface<PipelineManager>();
543  auto bc_mng = mField.getInterface<BcManager>();
544  auto time_scale = boost::make_shared<ScaledTimeScale>();
545  auto body_force_time_scale =
546  boost::make_shared<ScaledTimeScale>("body_force_hist.txt");
547 
548  auto integration_rule_vol = [](int, int, int approx_order) {
549  return 2 * approx_order + geom_order - 1;
550  };
551  auto integration_rule_boundary = [](int, int, int approx_order) {
552  return 2 * approx_order + geom_order - 1;
553  };
554 
555  auto add_domain_base_ops = [&](auto &pip) {
558  "GEOMETRY");
560  };
561 
562  auto henky_common_data_ptr = boost::make_shared<HenckyOps::CommonData>();
563  henky_common_data_ptr->matDPtr = boost::make_shared<MatrixDouble>();
564  henky_common_data_ptr->matGradPtr = boost::make_shared<MatrixDouble>();
565 
566  auto add_domain_ops_lhs = [&](auto &pip) {
568 
569  //! [Only used for dynamics]
572  //! [Only used for dynamics]
573  if (is_quasi_static == PETSC_FALSE) {
574 
575  auto *pip_mng = mField.getInterface<PipelineManager>();
576  auto fe_domain_lhs = pip_mng->getDomainLhsFE();
577 
578  auto get_inertia_and_mass_damping =
579  [this, fe_domain_lhs](const double, const double, const double) {
580  return (rho * scale) * fe_domain_lhs->ts_aa +
581  (alpha_damping * scale) * fe_domain_lhs->ts_a;
582  };
583  pip.push_back(new OpMass("U", "U", get_inertia_and_mass_damping));
584  } else {
585 
586  auto *pip_mng = mField.getInterface<PipelineManager>();
587  auto fe_domain_lhs = pip_mng->getDomainLhsFE();
588 
589  auto get_inertia_and_mass_damping =
590  [this, fe_domain_lhs](const double, const double, const double) {
591  return (alpha_damping * scale) * fe_domain_lhs->ts_a;
592  };
593  pip.push_back(new OpMass("U", "U", get_inertia_and_mass_damping));
594 
595  }
596 
597  if (!mfrontInterface) {
598  CHKERR HenckyOps::opFactoryDomainLhs<SPACE_DIM, AT, IT, DomainEleOp>(
599  mField, pip, "U", "MAT_ELASTIC", Sev::verbose, scale);
600  }
601 
603  };
604 
605  auto add_domain_ops_rhs = [&](auto &pip) {
607 
609  pip, mField, "U", {body_force_time_scale}, Sev::inform);
610 
611  //! [Only used for dynamics]
613  AT>::LinearForm<IT>::OpBaseTimesVector<1, SPACE_DIM, 1>;
614  //! [Only used for dynamics]
615 
616  // only in case of dynamics
617  if (is_quasi_static == PETSC_FALSE) {
618  auto mat_acceleration = boost::make_shared<MatrixDouble>();
620  "U", mat_acceleration));
621  pip.push_back(
622  new OpInertiaForce("U", mat_acceleration, [](double, double, double) {
623  return rho * scale;
624  }));
625 
626  }
627 
628  // only in case of viscosity
629  if (alpha_damping > 0) {
630  auto mat_velocity = boost::make_shared<MatrixDouble>();
631  pip.push_back(
632  new OpCalculateVectorFieldValuesDot<SPACE_DIM>("U", mat_velocity));
633  pip.push_back(
634  new OpInertiaForce("U", mat_velocity, [](double, double, double) {
635  return alpha_damping * scale;
636  }));
637  }
638 
639  if (!mfrontInterface) {
640  CHKERR HenckyOps::opFactoryDomainRhs<SPACE_DIM, AT, IT, DomainEleOp>(
641  mField, pip, "U", "MAT_ELASTIC", Sev::inform, scale);
642  }
643 
644  CHKERR ContactOps::opFactoryDomainRhs<SPACE_DIM, AT, IT, DomainEleOp>(
645  pip, "SIGMA", "U", is_axisymmetric);
646 
648  };
649 
650  auto add_boundary_base_ops = [&](auto &pip) {
653  "GEOMETRY");
654  // We have to integrate on curved face geometry, thus integration weight
655  // have to adjusted.
656  pip.push_back(new OpSetHOWeightsOnSubDim<SPACE_DIM>());
658  };
659 
660  auto add_boundary_ops_lhs = [&](auto &pip) {
662 
663  //! [Operators used for contact]
666  //! [Operators used for contact]
667 
668  // Add Natural BCs to LHS
670  pip, mField, "U", Sev::inform);
671 
672  if (spring_stiffness > 0 || vis_spring_stiffness > 0) {
673 
674  auto *pip_mng = mField.getInterface<PipelineManager>();
675  auto fe_boundary_lhs = pip_mng->getBoundaryLhsFE();
676 
677  pip.push_back(new OpSpringLhs(
678  "U", "U",
679 
680  [this, fe_boundary_lhs](double, double, double) {
681  return spring_stiffness * scale +
682  (vis_spring_stiffness * scale) * fe_boundary_lhs->ts_a;
683  }
684 
685  ));
686  }
687 
688  CHKERR
689  ContactOps::opFactoryBoundaryLhs<SPACE_DIM, AT, GAUSS, BoundaryEleOp>(
690  pip, "SIGMA", "U", is_axisymmetric);
692  DomainEle>(
693  mField, pip, simple->getDomainFEName(), "SIGMA", "U", "GEOMETRY",
694  integration_rule_vol, is_axisymmetric);
695 
697  };
698 
699  auto add_boundary_ops_rhs = [&](auto &pip) {
701 
702  //! [Operators used for contact]
704  AT>::LinearForm<IT>::OpBaseTimesVector<1, SPACE_DIM, 1>;
705  //! [Operators used for contact]
706 
707  // Add Natural BCs to RHS
709  pip, mField, "U", {time_scale}, Sev::inform);
710 
711  if (spring_stiffness > 0 || vis_spring_stiffness > 0) {
712  auto u_disp = boost::make_shared<MatrixDouble>();
713  auto dot_u_disp = boost::make_shared<MatrixDouble>();
714  pip.push_back(new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_disp));
715  pip.push_back(
716  new OpCalculateVectorFieldValuesDot<SPACE_DIM>("U", dot_u_disp));
717  pip.push_back(
718  new OpSpringRhs("U", u_disp, [this](double, double, double) {
719  return spring_stiffness * scale;
720  }));
721  pip.push_back(
722  new OpSpringRhs("U", dot_u_disp, [this](double, double, double) {
723  return vis_spring_stiffness * scale;
724  }));
725  }
726 
727  CHKERR
728  ContactOps::opFactoryBoundaryRhs<SPACE_DIM, AT, GAUSS, BoundaryEleOp>(
729  pip, "SIGMA", "U", is_axisymmetric);
730 
732  };
733 
734  CHKERR add_domain_base_ops(pip_mng->getOpDomainLhsPipeline());
735  CHKERR add_domain_base_ops(pip_mng->getOpDomainRhsPipeline());
736  CHKERR add_domain_ops_lhs(pip_mng->getOpDomainLhsPipeline());
737  CHKERR add_domain_ops_rhs(pip_mng->getOpDomainRhsPipeline());
738 
739  CHKERR add_boundary_base_ops(pip_mng->getOpBoundaryLhsPipeline());
740  CHKERR add_boundary_base_ops(pip_mng->getOpBoundaryRhsPipeline());
741  CHKERR add_boundary_ops_lhs(pip_mng->getOpBoundaryLhsPipeline());
742  CHKERR add_boundary_ops_rhs(pip_mng->getOpBoundaryRhsPipeline());
743 
744  if (mfrontInterface) {
745  auto t_type = GenericElementInterface::IM2;
746  if (is_quasi_static == PETSC_TRUE)
748 
749  CHKERR mfrontInterface->setOperators();
750  CHKERR mfrontInterface->setupSolverFunctionTS(t_type);
751  CHKERR mfrontInterface->setupSolverJacobianTS(t_type);
752  }
753 
754  CHKERR pip_mng->setDomainRhsIntegrationRule(integration_rule_vol);
755  CHKERR pip_mng->setDomainLhsIntegrationRule(integration_rule_vol);
756  CHKERR pip_mng->setBoundaryRhsIntegrationRule(integration_rule_boundary);
757  CHKERR pip_mng->setBoundaryLhsIntegrationRule(integration_rule_boundary);
758 
760 }

◆ runProblem()

MoFEMErrorCode Contact::runProblem ( )

[Run problem]

Definition at line 205 of file contact.cpp.

205  {
209  CHKERR bC();
210  CHKERR OPs();
211  CHKERR tsSolve();
214 }

◆ setupProblem()

MoFEMErrorCode Contact::setupProblem ( )
private

[Run problem]

[Set up problem]

< blocs interation is collective, so that is set irrespective if there are entities in given rank or not in the block

Definition at line 218 of file contact.cpp.

218  {
221  PetscBool use_mfront = PETSC_FALSE;
222 
223  CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-order", &order, PETSC_NULL);
224  CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-contact_order", &contact_order,
225  PETSC_NULL);
226  CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-geom_order", &geom_order,
227  PETSC_NULL);
228 
229  MOFEM_LOG("CONTACT", Sev::inform) << "Order " << order;
230  if (contact_order != order)
231  MOFEM_LOG("CONTACT", Sev::inform) << "Contact order " << contact_order;
232  MOFEM_LOG("CONTACT", Sev::inform) << "Geom order " << geom_order;
233 
234  CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-use_mfront", &use_mfront,
235  PETSC_NULL);
236  CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-is_axisymmetric",
237  &is_axisymmetric, PETSC_NULL);
238  CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-atom_test", &atom_test, PETSC_NULL);
239 
240  // Select base
241  enum bases { AINSWORTH, DEMKOWICZ, LASBASETOPT };
242  const char *list_bases[LASBASETOPT] = {"ainsworth", "demkowicz"};
243  PetscInt choice_base_value = AINSWORTH;
244  CHKERR PetscOptionsGetEList(PETSC_NULL, NULL, "-base", list_bases,
245  LASBASETOPT, &choice_base_value, PETSC_NULL);
246 
248  switch (choice_base_value) {
249  case AINSWORTH:
251  MOFEM_LOG("CONTACT", Sev::inform)
252  << "Set AINSWORTH_LEGENDRE_BASE for displacements";
253  break;
254  case DEMKOWICZ:
255  base = DEMKOWICZ_JACOBI_BASE;
256  MOFEM_LOG("CONTACT", Sev::inform)
257  << "Set DEMKOWICZ_JACOBI_BASE for displacements";
258  break;
259  default:
260  base = LASTBASE;
261  break;
262  }
263 
264  // Note: For tets we have only H1 Ainsworth base, for Hex we have only H1
265  // Demkowicz base. We need to implement Demkowicz H1 base on tet.
266  CHKERR simple->addDomainField("U", H1, base, SPACE_DIM);
267  CHKERR simple->addBoundaryField("U", H1, base, SPACE_DIM);
268  CHKERR simple->addDomainField("SIGMA", CONTACT_SPACE, DEMKOWICZ_JACOBI_BASE,
269  SPACE_DIM);
270  CHKERR simple->addBoundaryField("SIGMA", CONTACT_SPACE, DEMKOWICZ_JACOBI_BASE,
271  SPACE_DIM);
272  CHKERR simple->addDataField("GEOMETRY", H1, base, SPACE_DIM);
273 
274  CHKERR simple->setFieldOrder("U", order);
275  CHKERR simple->setFieldOrder("GEOMETRY", geom_order);
276 
277  auto get_skin = [&]() {
278  Range body_ents;
279  CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM, body_ents);
280  Skinner skin(&mField.get_moab());
281  Range skin_ents;
282  CHKERR skin.find_skin(0, body_ents, false, skin_ents);
283  return skin_ents;
284  };
285 
286  auto filter_blocks = [&](auto skin) {
287  bool is_contact_block = false;
288  Range contact_range;
289  for (auto m :
291 
292  (boost::format("%s(.*)") % "CONTACT").str()
293 
294  ))
295 
296  ) {
297  is_contact_block =
298  true; ///< blocs interation is collective, so that is set irrespective
299  ///< if there are entities in given rank or not in the block
300  MOFEM_LOG("CONTACT", Sev::inform)
301  << "Find contact block set: " << m->getName();
302  auto meshset = m->getMeshset();
303  Range contact_meshset_range;
304  CHKERR mField.get_moab().get_entities_by_dimension(
305  meshset, SPACE_DIM - 1, contact_meshset_range, true);
306 
307  CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
308  contact_meshset_range);
309  contact_range.merge(contact_meshset_range);
310  }
311  if (is_contact_block) {
312  MOFEM_LOG("SYNC", Sev::inform)
313  << "Nb entities in contact surface: " << contact_range.size();
315  skin = intersect(skin, contact_range);
316  }
317  return skin;
318  };
319 
320  auto filter_true_skin = [&](auto skin) {
321  Range boundary_ents;
322  ParallelComm *pcomm =
323  ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
324  CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
325  PSTATUS_NOT, -1, &boundary_ents);
326  return boundary_ents;
327  };
328 
329  auto boundary_ents = filter_true_skin(filter_blocks(get_skin()));
330  CHKERR simple->setFieldOrder("SIGMA", 0);
331  int sigma_order = std::max(order, contact_order) - 1;
332  CHKERR simple->setFieldOrder("SIGMA", sigma_order, &boundary_ents);
333 
334  if (contact_order > order) {
335  Range ho_ents;
336  if constexpr (SPACE_DIM == 3) {
337  CHKERR mField.get_moab().get_adjacencies(boundary_ents, 1, false, ho_ents,
338  moab::Interface::UNION);
339  } else {
340  ho_ents = boundary_ents;
341  }
342  CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(ho_ents);
343  CHKERR simple->setFieldOrder("U", contact_order, &ho_ents);
344  CHKERR mField.getInterface<CommInterface>()->synchroniseFieldEntities("U");
345  }
346 
347  if (is_axisymmetric) {
348  if (SPACE_DIM == 3) {
349  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
350  "Use executable contact_2d with axisymmetric model");
351  } else {
352  if (!use_mfront) {
353  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
354  "Axisymmetric model is only available with MFront (set "
355  "use_mfront to 1)");
356  } else {
357  MOFEM_LOG("CONTACT", Sev::inform) << "Using axisymmetric model";
358  }
359  }
360  } else {
361  if (SPACE_DIM == 2) {
362  MOFEM_LOG("CONTACT", Sev::inform) << "Using plane strain model";
363  }
364  }
365 
366  if (!use_mfront) {
367  CHKERR simple->setUp();
368  } else {
369 #ifndef WITH_MODULE_MFRONT_INTERFACE
370  SETERRQ(
371  PETSC_COMM_SELF, MOFEM_NOT_FOUND,
372  "MFrontInterface module was not found while use_mfront was set to 1");
373 #else
374  if (SCHUR_ASSEMBLE) {
375  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
376  "MFrontInterface module is not compatible with Schur assembly");
377  }
378  if (SPACE_DIM == 3) {
380  boost::make_shared<MFrontMoFEMInterface<TRIDIMENSIONAL>>(
381  mField, "U", "GEOMETRY", true, is_quasi_static);
382  } else if (SPACE_DIM == 2) {
383  if (is_axisymmetric) {
385  boost::make_shared<MFrontMoFEMInterface<AXISYMMETRICAL>>(
386  mField, "U", "GEOMETRY", true, is_quasi_static);
387  } else {
388  mfrontInterface = boost::make_shared<MFrontMoFEMInterface<PLANESTRAIN>>(
389  mField, "U", "GEOMETRY", true, is_quasi_static);
390  }
391  }
392 #endif
393 
394  CHKERR mfrontInterface->getCommandLineParameters();
395  CHKERR mfrontInterface->addElementFields();
396  CHKERR mfrontInterface->createElements();
397 
398  CHKERR simple->defineFiniteElements();
399  CHKERR simple->defineProblem(PETSC_TRUE);
400  CHKERR simple->buildFields();
401  CHKERR simple->buildFiniteElements();
402 
403  CHKERR mField.build_finite_elements("MFRONT_EL");
404  CHKERR mfrontInterface->addElementsToDM(simple->getDM());
405 
406  CHKERR simple->buildProblem();
407  }
408 
409  auto dm = simple->getDM();
410  monitorPtr =
411  boost::make_shared<Monitor>(dm, mfrontInterface, is_axisymmetric);
412  if (use_mfront) {
413  mfrontInterface->setMonitorPtr(monitorPtr);
414  }
415 
416  auto project_ho_geometry = [&]() {
417  Projection10NodeCoordsOnField ent_method(mField, "GEOMETRY");
418  return mField.loop_dofs("GEOMETRY", ent_method);
419  };
420 
421  PetscBool project_geometry = PETSC_TRUE;
422  CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-project_geometry",
423  &project_geometry, PETSC_NULL);
424  if (project_geometry){
425  CHKERR project_ho_geometry();
426  }
427 
429 } //! [Set up problem]

◆ tsSolve()

MoFEMErrorCode Contact::tsSolve ( )
private

Definition at line 773 of file contact.cpp.

773  {
775 
778  ISManager *is_manager = mField.getInterface<ISManager>();
779 
780  auto set_section_monitor = [&](auto solver) {
782  SNES snes;
783  CHKERR TSGetSNES(solver, &snes);
784  PetscViewerAndFormat *vf;
785  CHKERR PetscViewerAndFormatCreate(PETSC_VIEWER_STDOUT_WORLD,
786  PETSC_VIEWER_DEFAULT, &vf);
787  CHKERR SNESMonitorSet(
788  snes,
789  (MoFEMErrorCode(*)(SNES, PetscInt, PetscReal, void *))SNESMonitorFields,
790  vf, (MoFEMErrorCode(*)(void **))PetscViewerAndFormatDestroy);
792  };
793 
794  auto scatter_create = [&](auto D, auto coeff) {
796  CHKERR is_manager->isCreateProblemFieldAndRank(simple->getProblemName(),
797  ROW, "U", coeff, coeff, is);
798  int loc_size;
799  CHKERR ISGetLocalSize(is, &loc_size);
800  Vec v;
801  CHKERR VecCreateMPI(mField.get_comm(), loc_size, PETSC_DETERMINE, &v);
802  VecScatter scatter;
803  CHKERR VecScatterCreate(D, is, v, PETSC_NULL, &scatter);
804  return std::make_tuple(SmartPetscObj<Vec>(v),
805  SmartPetscObj<VecScatter>(scatter));
806  };
807 
808  auto set_time_monitor = [&](auto dm, auto solver) {
810  monitorPtr->setScatterVectors(uXScatter, uYScatter, uZScatter);
811  boost::shared_ptr<ForcesAndSourcesCore> null;
812  CHKERR DMMoFEMTSSetMonitor(dm, solver, simple->getDomainFEName(),
813  monitorPtr, null, null);
815  };
816 
817  auto set_essential_bc = [&]() {
819  // This is low level pushing finite elements (pipelines) to solver
820  auto ts_ctx_ptr = getDMTsCtx(simple->getDM());
821  auto pre_proc_ptr = boost::make_shared<FEMethod>();
822  auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
823  auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
824 
825  // Add boundary condition scaling
826  auto time_scale = boost::make_shared<TimeScale>();
827 
828  auto get_bc_hook_rhs = [&]() {
830  {time_scale}, false);
831  return hook;
832  };
833  pre_proc_ptr->preProcessHook = get_bc_hook_rhs();
834 
835  auto get_post_proc_hook_rhs = [&]() {
837  mField, post_proc_rhs_ptr, 1.);
838  };
839  auto get_post_proc_hook_lhs = [&]() {
841  mField, post_proc_lhs_ptr, 1.);
842  };
843  post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs();
844 
845  ts_ctx_ptr->getPreProcessIFunction().push_front(pre_proc_ptr);
846  ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_ptr);
847  ts_ctx_ptr->getPostProcessIFunction().push_back(post_proc_rhs_ptr);
848  if (AT != AssemblyType::SCHUR) {
849  post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs();
850  ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_lhs_ptr);
851  }
853  };
854 
855  auto set_schur_pc = [&](auto solver) {
856  boost::shared_ptr<SetUpSchur> schur_ptr;
857  if (AT == AssemblyType::SCHUR) {
859  CHK_MOAB_THROW(schur_ptr->setUp(solver), "SetUpSchur::setUp");
860  }
861  return schur_ptr;
862  };
863 
864  auto dm = simple->getDM();
865  auto D = createDMVector(dm);
866 
868 
869  uXScatter = scatter_create(D, 0);
870  uYScatter = scatter_create(D, 1);
871  if (SPACE_DIM == 3)
872  uZScatter = scatter_create(D, 2);
873 
874  // Add extra finite elements to SNES solver pipelines to resolve essential
875  // boundary conditions
876  CHKERR set_essential_bc();
877 
878  if (is_quasi_static == PETSC_TRUE) {
879  auto solver = pip_mng->createTSIM();
880  CHKERR TSSetFromOptions(solver);
881 
882  auto D = createDMVector(dm);
883  auto schur_pc_ptr = set_schur_pc(solver);
884 
885  CHKERR set_section_monitor(solver);
886  CHKERR set_time_monitor(dm, solver);
887  CHKERR TSSetSolution(solver, D);
888  CHKERR TSSetUp(solver);
889  CHKERR TSSolve(solver, NULL);
890  } else {
891  auto solver = pip_mng->createTSIM2();
892  CHKERR TSSetFromOptions(solver);
893 
894  auto dm = simple->getDM();
895  auto D = createDMVector(dm);
896  auto DD = vectorDuplicate(D);
897  auto schur_pc_ptr = set_schur_pc(solver);
898 
899  CHKERR set_section_monitor(solver);
900  CHKERR set_time_monitor(dm, solver);
901  CHKERR TS2SetSolution(solver, D, DD);
902  CHKERR TSSetUp(solver);
903  CHKERR TSSolve(solver, NULL);
904  }
905 
907 }

Member Data Documentation

◆ mField

MoFEM::Interface& Contact::mField
private

Definition at line 176 of file contact.cpp.

◆ mfrontInterface

boost::shared_ptr<GenericElementInterface> Contact::mfrontInterface
private

Definition at line 189 of file contact.cpp.

◆ monitorPtr

boost::shared_ptr<Monitor> Contact::monitorPtr
private

Definition at line 190 of file contact.cpp.

◆ uXScatter

std::tuple<SmartPetscObj<Vec>, SmartPetscObj<VecScatter> > Contact::uXScatter
private

Definition at line 185 of file contact.cpp.

◆ uYScatter

std::tuple<SmartPetscObj<Vec>, SmartPetscObj<VecScatter> > Contact::uYScatter
private

Definition at line 186 of file contact.cpp.

◆ uZScatter

std::tuple<SmartPetscObj<Vec>, SmartPetscObj<VecScatter> > Contact::uZScatter
private

Definition at line 187 of file contact.cpp.


The documentation for this struct was generated from the following file:
MoFEM::UnknownInterface::getInterface
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface refernce to pointer of interface.
Definition: UnknownInterface.hpp:93
CHK_MOAB_THROW
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
Definition: definitions.h:576
MYPCOMM_INDEX
#define MYPCOMM_INDEX
default communicator number PCOMM
Definition: definitions.h:215
spring_stiffness
double spring_stiffness
Definition: contact.cpp:131
MoFEM::CoreInterface::loop_dofs
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.
H1
@ H1
continuous field
Definition: definitions.h:85
Contact::monitorPtr
boost::shared_ptr< Monitor > monitorPtr
Definition: contact.cpp:190
Contact::bC
MoFEMErrorCode bC()
[Create common data]
Definition: contact.cpp:502
LASTBASE
@ LASTBASE
Definition: definitions.h:69
order
int order
Definition: contact.cpp:125
is_axisymmetric
PetscBool is_axisymmetric
Definition: contact.cpp:137
MoFEM::EssentialPostProcLhs< DisplacementCubitBcData >
Specialization for DisplacementCubitBcData.
Definition: EssentialDisplacementCubitBcData.hpp:130
MoFEM::CoreInterface::get_comm
virtual MPI_Comm & get_comm() const =0
MoFEM::Exceptions::MoFEMErrorCode
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
MoFEM::OpCalculateVectorFieldValues
Get values at integration pts for tensor filed rank 1, i.e. vector field.
Definition: UserDataOperators.hpp:466
MoFEM::CoreInterface::get_comm_rank
virtual int get_comm_rank() const =0
MoFEM::EssentialPostProcRhs< DisplacementCubitBcData >
Specialization for DisplacementCubitBcData.
Definition: EssentialDisplacementCubitBcData.hpp:111
Contact::uXScatter
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uXScatter
Definition: contact.cpp:185
MoFEM::PipelineManager
PipelineManager interface.
Definition: PipelineManager.hpp:24
MoFEM::DisplacementCubitBcData
Definition of the displacement bc data structure.
Definition: BCData.hpp:76
MoFEM::Projection10NodeCoordsOnField
Projection of edge entities with one mid-node on hierarchical basis.
Definition: Projection10NodeCoordsOnField.hpp:24
rho
double rho
Definition: contact.cpp:130
Contact::mField
MoFEM::Interface & mField
Definition: contact.cpp:176
MoFEM::Simple
Simple interface for fast problem set-up.
Definition: Simple.hpp:27
ContactOps::opFactoryBoundaryToDomainLhs
MoFEMErrorCode opFactoryBoundaryToDomainLhs(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string fe_domain_name, std::string sigma, std::string u, std::string geom, ForcesAndSourcesCore::RuleHookFun rule, bool is_axisymmetric=false)
Definition: ContactOps.hpp:1142
SetUpSchur::createSetUpSchur
static boost::shared_ptr< SetUpSchur > createSetUpSchur(MoFEM::Interface &m_field, SmartPetscObj< DM > sub_dm, SmartPetscObj< IS > field_split_it, SmartPetscObj< AO > ao_map)
Create data structure for handling Schur complement.
SCHUR_ASSEMBLE
#define SCHUR_ASSEMBLE
Definition: contact.cpp:18
SPACE_DIM
constexpr int SPACE_DIM
Definition: contact.cpp:53
scale
double scale
Definition: contact.cpp:135
ROW
@ ROW
Definition: definitions.h:123
approx_order
static constexpr int approx_order
Definition: prism_polynomial_approximation.cpp:14
MoFEM::OpCalculateVectorFieldValuesFromPetscVecImpl
Approximate field values for given petsc vector.
Definition: UserDataOperators.hpp:595
OpInertiaForce
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesVector< 1, SPACE_DIM, 1 > OpInertiaForce
Definition: dynamic_first_order_con_law.cpp:63
atom_test
int atom_test
Definition: contact.cpp:139
CHKERR
#define CHKERR
Inline error check.
Definition: definitions.h:535
MoFEM::createDMVector
auto createDMVector(DM dm)
Get smart vector from DM.
Definition: DMMoFEM.hpp:1018
MoFEM::EssentialPreProc< DisplacementCubitBcData >
Specialization for DisplacementCubitBcData.
Definition: EssentialDisplacementCubitBcData.hpp:91
MoFEM::CoreInterface::get_moab
virtual moab::Interface & get_moab()=0
vis_spring_stiffness
double vis_spring_stiffness
Definition: contact.cpp:132
MoFEM::ISManager
Section manager is used to create indexes and sections.
Definition: ISManager.hpp:23
MoFEM::BcManager
Simple interface for fast problem set-up.
Definition: BcManager.hpp:25
OpMass
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, SPACE_DIM > OpMass
[Only used with Hooke equation (linear material model)]
Definition: seepage.cpp:57
ContactOps::CommonData::totalTraction
static SmartPetscObj< Vec > totalTraction
Definition: ContactOps.hpp:28
MoFEM::CoreInterface::build_finite_elements
virtual MoFEMErrorCode build_finite_elements(int verb=DEFAULT_VERBOSITY)=0
Build finite elements.
OpSpringRhs
FormsIntegrators< BoundaryEleOp >::Assembly< AT >::LinearForm< IT >::OpBaseTimesVector< 1, SPACE_DIM, 1 > OpSpringRhs
Definition: contact.cpp:120
alpha_damping
double alpha_damping
Definition: contact.cpp:133
simple
void simple(double P1[], double P2[], double P3[], double c[], const int N)
Definition: acoustic.cpp:69
double
MoFEM::FormsIntegrators::Assembly
Assembly methods.
Definition: FormsIntegrators.hpp:302
poisson_ratio
double poisson_ratio
Definition: contact.cpp:129
MOFEM_LOG_SYNCHRONISE
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
Definition: LogManager.hpp:345
Contact::uZScatter
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uZScatter
Definition: contact.cpp:187
MoFEM::GAUSS
@ GAUSS
Definition: FormsIntegrators.hpp:128
contact_order
int contact_order
Definition: contact.cpp:126
Contact::mfrontInterface
boost::shared_ptr< GenericElementInterface > mfrontInterface
Definition: contact.cpp:189
MoFEM::AddFluxToLhsPipelineImpl
Definition: Natural.hpp:49
Contact::createCommonData
MoFEMErrorCode createCommonData()
[Set up problem]
Definition: contact.cpp:432
MoFEM::AddFluxToRhsPipelineImpl
Definition: Natural.hpp:46
BiLinearForm
MOFEM_NOT_FOUND
@ MOFEM_NOT_FOUND
Definition: definitions.h:33
MoFEM::OpSetHOWeightsOnSubDim
Definition: HODataOperators.hpp:145
MoFEM::AddHOOps
Add operators pushing bases from local to physical configuration.
Definition: HODataOperators.hpp:503
ContactOps::CommonData::createTotalTraction
static auto createTotalTraction(MoFEM::Interface &m_field)
Definition: ContactOps.hpp:30
ContactOps::cn_contact
double cn_contact
Definition: EshelbianContact.hpp:19
Contact::OPs
MoFEMErrorCode OPs()
[Boundary condition]
Definition: contact.cpp:539
v
const double v
phase velocity of light in medium (cm/ns)
Definition: initial_diffusion.cpp:40
Range
is_quasi_static
PetscBool is_quasi_static
[Operators used for contact]
Definition: contact.cpp:123
Contact::setupProblem
MoFEMErrorCode setupProblem()
[Run problem]
Definition: contact.cpp:218
MOFEM_LOG
#define MOFEM_LOG(channel, severity)
Log.
Definition: LogManager.hpp:308
MoFEM::vectorDuplicate
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
Definition: PetscSmartObj.hpp:217
young_modulus
double young_modulus
Definition: contact.cpp:128
DEMKOWICZ_JACOBI_BASE
@ DEMKOWICZ_JACOBI_BASE
Definition: definitions.h:66
MoFEM::CommInterface
Managing BitRefLevels.
Definition: CommInterface.hpp:21
HenckyOps::f
auto f
Definition: HenckyOps.hpp:15
MoFEM::DMMoFEMTSSetMonitor
PetscErrorCode DMMoFEMTSSetMonitor(DM dm, TS ts, const std::string fe_name, boost::shared_ptr< MoFEM::FEMethod > method, boost::shared_ptr< MoFEM::BasicMethod > pre_only, boost::shared_ptr< MoFEM::BasicMethod > post_only)
Set Monitor To TS solver.
Definition: DMMoFEM.cpp:1060
AINSWORTH_LEGENDRE_BASE
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition: definitions.h:60
EigenMatrix::Vec
const FTensor::Tensor2< T, Dim, Dim > Vec
Definition: MatrixFunction.hpp:66
MOFEM_DATA_INCONSISTENCY
@ MOFEM_DATA_INCONSISTENCY
Definition: definitions.h:31
MoFEM::PetscOptionsGetString
PetscErrorCode PetscOptionsGetString(PetscOptions *, const char pre[], const char name[], char str[], size_t size, PetscBool *set)
Definition: DeprecatedPetsc.hpp:172
MoFEM::MeshsetsManager
Interface for managing meshsets containing materials and boundary conditions.
Definition: MeshsetsManager.hpp:104
MoFEM::PetscOptionsGetEList
PetscErrorCode PetscOptionsGetEList(PetscOptions *, const char pre[], const char name[], const char *const *list, PetscInt next, PetscInt *value, PetscBool *set)
Definition: DeprecatedPetsc.hpp:203
Contact::tsSolve
MoFEMErrorCode tsSolve()
Definition: contact.cpp:773
FieldApproximationBase
FieldApproximationBase
approximation base
Definition: definitions.h:58
geom_order
int geom_order
Definition: contact.cpp:127
ReactionDiffusionEquation::D
const double D
diffusivity
Definition: reaction_diffusion.cpp:20
m
FTensor::Index< 'm', 3 > m
Definition: shallow_wave.cpp:80
MOFEM_ATOM_TEST_INVALID
@ MOFEM_ATOM_TEST_INVALID
Definition: definitions.h:40
MoFEM::PetscOptionsGetScalar
PetscErrorCode PetscOptionsGetScalar(PetscOptions *, const char pre[], const char name[], PetscScalar *dval, PetscBool *set)
Definition: DeprecatedPetsc.hpp:162
DomainEle
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
Definition: child_and_parent.cpp:34
MoFEM::MeshsetsManager::getCubitMeshsetPtr
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
Definition: MeshsetsManager.cpp:575
MoFEM::SmartPetscObj< IS >
OpSpringLhs
FormsIntegrators< BoundaryEleOp >::Assembly< AT >::BiLinearForm< IT >::OpMass< 1, SPACE_DIM > OpSpringLhs
[Operators used for contact]
Definition: contact.cpp:118
convert.int
int
Definition: convert.py:64
MoFEM::PetscOptionsGetInt
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
Definition: DeprecatedPetsc.hpp:142
MoFEMFunctionReturn
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:416
AT
constexpr AssemblyType AT
Definition: contact.cpp:34
HDIV
@ HDIV
field with continuous normal traction
Definition: definitions.h:87
MOFEM_NOT_IMPLEMENTED
@ MOFEM_NOT_IMPLEMENTED
Definition: definitions.h:32
MoFEM::getDMTsCtx
auto getDMTsCtx(DM dm)
Get TS context data structure used by DM.
Definition: DMMoFEM.hpp:1060
MoFEM::SCHUR
@ SCHUR
Definition: FormsIntegrators.hpp:104
GenericElementInterface::IM2
@ IM2
Definition: GenericElementInterface.hpp:16
MoFEMFunctionBegin
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:346
Contact::checkResults
MoFEMErrorCode checkResults()
[Solve]
Definition: contact.cpp:911
tol
double tol
Definition: mesh_smoothing.cpp:27
CONTACT_SPACE
constexpr FieldSpace CONTACT_SPACE
[Specialisation for assembly]
Definition: contact.cpp:114
GenericElementInterface::IM
@ IM
Definition: GenericElementInterface.hpp:16
MoFEM::PetscOptionsGetBool
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
Definition: DeprecatedPetsc.hpp:182
Contact::uYScatter
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uYScatter
Definition: contact.cpp:186