v0.14.0
contact.cpp
Go to the documentation of this file.
1 /**
2  * \file contact.cpp
3  * \CONTACT contact.cpp
4  *
5  * CONTACT of contact problem
6  *
7  * @copyright Copyright (c) 2023
8  */
9 
10 /* The above code is a preprocessor directive in C++ that checks if the macro
11 "EXECUTABLE_DIMENSION" has been defined. If it has not been defined, it is set
12 to 3" */
13 #ifndef EXECUTABLE_DIMENSION
14 #define EXECUTABLE_DIMENSION 3
15 #endif
16 
17 #ifndef SCHUR_ASSEMBLE
18 #define SCHUR_ASSEMBLE 0
19 #endif
20 
21 #include <MoFEM.hpp>
22 #include <MatrixFunction.hpp>
23 
24 #ifdef PYTHON_SDF
25 #include <boost/python.hpp>
26 #include <boost/python/def.hpp>
27 #include <boost/python/numpy.hpp>
28 namespace bp = boost::python;
29 namespace np = boost::python::numpy;
30 #endif
31 
32 using namespace MoFEM;
33 
34 constexpr AssemblyType AT =
36  : AssemblyType::PETSC; //< selected assembly type
37 constexpr IntegrationType IT =
38  IntegrationType::GAUSS; //< selected integration type
39 
40 template <int DIM> struct ElementsAndOps;
41 
42 template <> struct ElementsAndOps<2> : PipelineManager::ElementsAndOpsByDim<2> {
43  static constexpr FieldSpace CONTACT_SPACE = HCURL;
44 };
45 
46 template <> struct ElementsAndOps<3> : PipelineManager::ElementsAndOpsByDim<3> {
47  static constexpr FieldSpace CONTACT_SPACE = HDIV;
48 };
49 
52 
53 constexpr int SPACE_DIM =
54  EXECUTABLE_DIMENSION; //< Space dimension of problem, mesh
55 
56 /* The above code is defining an alias `EntData` for the type
57 `EntitiesFieldData::EntData`. This is a C++ syntax for creating a new name for
58 an existing type. */
64 
65 //! [Specialisation for assembly]
66 
67 // Assemble to A matrix, by default, however, some terms are assembled only to
68 // preconditioning.
69 
70 template <>
74  const EntitiesFieldData::EntData &row_data,
75  const EntitiesFieldData::EntData &col_data, MatrixDouble &m) {
76  return MatSetValues<AssemblyTypeSelector<SCHUR>>(
77  op_ptr->getKSPA(), row_data, col_data, m, ADD_VALUES);
78  };
79 
80 template <>
84  const EntitiesFieldData::EntData &row_data,
85  const EntitiesFieldData::EntData &col_data, MatrixDouble &m) {
86  return MatSetValues<AssemblyTypeSelector<SCHUR>>(
87  op_ptr->getKSPA(), row_data, col_data, m, ADD_VALUES);
88  };
89 
90 /**
91  * @brief Element used to specialise assembly
92  *
93  */
96 };
97 
98 /**
99  * @brief Specialise assembly for Stabilised matrix
100  *
101  * @tparam
102  */
103 template <>
107  const EntitiesFieldData::EntData &row_data,
108  const EntitiesFieldData::EntData &col_data, MatrixDouble &m) {
109  return MatSetValues<AssemblyTypeSelector<SCHUR>>(
110  op_ptr->getKSPB(), row_data, col_data, m, ADD_VALUES);
111  };
112 //! [Specialisation for assembly]
113 
115 
116 //! [Operators used for contact]
120  IT>::OpBaseTimesVector<1, SPACE_DIM, 1>;
121 //! [Operators used for contact]
122 
123 PetscBool is_quasi_static = PETSC_TRUE;
124 
125 int order = 2;
127 int geom_order = 1;
128 double young_modulus = 100;
129 double poisson_ratio = 0.25;
130 double rho = 0.0;
131 double spring_stiffness = 0.0;
132 double vis_spring_stiffness = 0.0;
133 double alpha_damping = 0;
134 
135 double scale = 1.;
136 
137 PetscBool is_axisymmetric = PETSC_FALSE; //< Axisymmetric model
138 
139 int atom_test = 0;
140 
141 namespace ContactOps {
142 double cn_contact = 0.1;
143 }; // namespace ContactOps
144 
145 //#define HENCKY_SMALL_STRAIN
146 
147 #include <HenckyOps.hpp>
148 using namespace HenckyOps;
149 #include <ContactOps.hpp>
150 #include <PostProcContact.hpp>
151 #include <ContactNaturalBC.hpp>
152 
153 #ifdef WITH_MODULE_MFRONT_INTERFACE
154 #include <MFrontMoFEMInterface.hpp>
155 #endif
156 
158 using OpDomainRhsBCs =
161 using OpBoundaryRhsBCs =
164 using OpBoundaryLhsBCs =
166 
167 using namespace ContactOps;
168 
169 struct Contact {
170 
171  Contact(MoFEM::Interface &m_field) : mField(m_field) {}
172 
173  MoFEMErrorCode runProblem();
174 
175 private:
177 
178  MoFEMErrorCode setupProblem();
179  MoFEMErrorCode createCommonData();
180  MoFEMErrorCode bC();
181  MoFEMErrorCode OPs();
182  MoFEMErrorCode tsSolve();
183  MoFEMErrorCode checkResults();
184 
185  std::tuple<SmartPetscObj<Vec>, SmartPetscObj<VecScatter>> uXScatter;
186  std::tuple<SmartPetscObj<Vec>, SmartPetscObj<VecScatter>> uYScatter;
187  std::tuple<SmartPetscObj<Vec>, SmartPetscObj<VecScatter>> uZScatter;
188 
189  boost::shared_ptr<GenericElementInterface> mfrontInterface;
190  boost::shared_ptr<Monitor> monitorPtr;
191 
192 #ifdef PYTHON_SDF
193  boost::shared_ptr<SDFPython> sdfPythonPtr;
194 #endif
195 
198  double getScale(const double time) {
199  return scale * MoFEM::TimeScale::getScale(time);
200  };
201  };
202 };
203 
204 //! [Run problem]
207  CHKERR setupProblem();
208  CHKERR createCommonData();
209  CHKERR bC();
210  CHKERR OPs();
211  CHKERR tsSolve();
212  CHKERR checkResults();
214 }
215 //! [Run problem]
216 
217 //! [Set up problem]
220  Simple *simple = mField.getInterface<Simple>();
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 :
290  mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
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();
314  MOFEM_LOG_SYNCHRONISE(mField.get_comm());
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) {
379  mfrontInterface =
380  boost::make_shared<MFrontMoFEMInterface<TRIDIMENSIONAL>>(
381  mField, "U", "GEOMETRY", true, is_quasi_static);
382  } else if (SPACE_DIM == 2) {
383  if (is_axisymmetric) {
384  mfrontInterface =
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]
430 
431 //! [Create common data]
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 }
499 //! [Create common data]
500 
501 //! [Boundary condition]
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 }
536 //! [Boundary condition]
537 
538 //! [Push operators to pip]
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 }
761 //! [Push operators to pip]
762 
763 //! [Solve]
764 struct SetUpSchur {
765  static boost::shared_ptr<SetUpSchur>
766  createSetUpSchur(MoFEM::Interface &m_field);
767  virtual MoFEMErrorCode setUp(SmartPetscObj<TS> solver) = 0;
768 
769 protected:
770  SetUpSchur() = default;
771 };
772 
775 
776  Simple *simple = mField.getInterface<Simple>();
777  PipelineManager *pip_mng = mField.getInterface<PipelineManager>();
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 = [&]() {
829  EssentialPreProc<DisplacementCubitBcData> hook(mField, pre_proc_ptr,
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) {
858  schur_ptr = SetUpSchur::createSetUpSchur(mField);
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 }
908 //! [Solve]
909 
910 //! [Check]
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 }
930 //! [Check]
931 
932 static char help[] = "...\n\n";
933 
934 int main(int argc, char *argv[]) {
935 
936 #ifdef PYTHON_SDF
937  Py_Initialize();
938  np::initialize();
939 #endif
940 
941  // Initialisation of MoFEM/PETSc and MOAB data structures
942  const char param_file[] = "param_file.petsc";
943  MoFEM::Core::Initialize(&argc, &argv, param_file, help);
944 
945  // Add logging channel for CONTACT
946  auto core_log = logging::core::get();
947  core_log->add_sink(
949  LogManager::setLog("CONTACT");
950  MOFEM_LOG_TAG("CONTACT", "Indent");
951 
952  try {
953 
954  //! [Register MoFEM discrete manager in PETSc]
955  DMType dm_name = "DMMOFEM";
956  CHKERR DMRegister_MoFEM(dm_name);
957  //! [Register MoFEM discrete manager in PETSc
958 
959  //! [Create MoAB]
960  moab::Core mb_instance; ///< mesh database
961  moab::Interface &moab = mb_instance; ///< mesh database interface
962  //! [Create MoAB]
963 
964  //! [Create MoFEM]
965  MoFEM::Core core(moab); ///< finite element database
966  MoFEM::Interface &m_field = core; ///< finite element database interface
967  //! [Create MoFEM]
968 
969  //! [Load mesh]
970  Simple *simple = m_field.getInterface<Simple>();
971  CHKERR simple->getOptions();
972  CHKERR simple->loadFile("");
973  //! [Load mesh]
974 
975  //! [CONTACT]
976  Contact ex(m_field);
977  CHKERR ex.runProblem();
978  //! [CONTACT]
979  }
980  CATCH_ERRORS;
981 
983 
984 #ifdef PYTHON_SDF
985  if (Py_FinalizeEx() < 0) {
986  exit(120);
987  }
988 #endif
989 
990  return 0;
991 }
992 
993 struct SetUpSchurImpl : public SetUpSchur {
994 
995  SetUpSchurImpl(MoFEM::Interface &m_field) : SetUpSchur(), mField(m_field) {}
996 
997  virtual ~SetUpSchurImpl() {
998  A.reset();
999  P.reset();
1000  S.reset();
1001  }
1002 
1003  MoFEMErrorCode setUp(SmartPetscObj<TS> solver);
1004 
1005 private:
1006  MoFEMErrorCode setEntities();
1007  MoFEMErrorCode setOperator();
1008  MoFEMErrorCode setPC(PC pc);
1009 
1010  SmartPetscObj<DM> createSubDM();
1011 
1015 
1016  MoFEM::Interface &mField;
1017 
1018  SmartPetscObj<DM> subDM;
1019 };
1020 
1023  auto simple = mField.getInterface<Simple>();
1024  auto pip = mField.getInterface<PipelineManager>();
1025  auto dm = simple->getDM();
1026 
1027  SNES snes;
1028  CHKERR TSGetSNES(solver, &snes);
1029  KSP ksp;
1030  CHKERR SNESGetKSP(snes, &ksp);
1031  CHKERR KSPSetFromOptions(ksp);
1032 
1033  PC pc;
1034  CHKERR KSPGetPC(ksp, &pc);
1035 
1036  PetscBool is_pcfs = PETSC_FALSE;
1037  PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
1038  if (is_pcfs) {
1039 
1040  MOFEM_LOG("CONTACT", Sev::inform) << "Setup Schur pc";
1041 
1042  if (A || P || S) {
1045  "It is expected that Schur matrix is not allocated. This is "
1046  "possible only if PC is set up twice");
1047  }
1048 
1049  A = createDMMatrix(dm);
1050  P = matDuplicate(A, MAT_DO_NOT_COPY_VALUES);
1051  subDM = createSubDM();
1052  S = createDMMatrix(subDM);
1053  CHKERR MatSetBlockSize(S, SPACE_DIM);
1054 
1055  auto ts_ctx_ptr = getDMTsCtx(dm);
1056  CHKERR TSSetIJacobian(solver, A, P, TsSetIJacobian, ts_ctx_ptr.get());
1057 
1058  CHKERR setOperator();
1059  CHKERR setPC(pc);
1060 
1061  } else {
1062  MOFEM_LOG("CONTACT", Sev::inform) << "No Schur pc";
1063 
1064  pip->getOpBoundaryLhsPipeline().push_front(new OpSchurAssembleBegin());
1065  pip->getOpBoundaryLhsPipeline().push_back(
1066  new OpSchurAssembleEnd<SCHUR_DGESV>({}, {}, {}, {}, {}));
1067  pip->getOpDomainLhsPipeline().push_front(new OpSchurAssembleBegin());
1068  pip->getOpDomainLhsPipeline().push_back(
1069  new OpSchurAssembleEnd<SCHUR_DGESV>({}, {}, {}, {}, {}));
1070 
1071  auto post_proc_schur_lhs_ptr = boost::make_shared<FEMethod>();
1072  post_proc_schur_lhs_ptr->postProcessHook = [this,
1073  post_proc_schur_lhs_ptr]() {
1076  mField, post_proc_schur_lhs_ptr, 1.)();
1078  };
1079  auto ts_ctx_ptr = getDMTsCtx(dm);
1080  ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_schur_lhs_ptr);
1081  }
1083 }
1084 
1086  auto simple = mField.getInterface<Simple>();
1087  auto sub_dm = createDM(mField.get_comm(), "DMMOFEM");
1088  auto set_up = [&]() {
1090  CHKERR DMMoFEMCreateSubDM(sub_dm, simple->getDM(), "SUB");
1091  CHKERR DMMoFEMSetSquareProblem(sub_dm, PETSC_TRUE);
1092  CHKERR DMMoFEMAddElement(sub_dm, simple->getDomainFEName());
1093  CHKERR DMMoFEMAddSubFieldRow(sub_dm, "U");
1094  CHKERR DMSetUp(sub_dm);
1096  };
1097  CHK_THROW_MESSAGE(set_up(), "sey up dm");
1098  return sub_dm;
1099 }
1100 
1103 
1104  double eps_stab = 1e-4;
1105  CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-eps_stab", &eps_stab,
1106  PETSC_NULL);
1107 
1108  using B =
1110  using OpMassStab = B::OpMass<3, SPACE_DIM * SPACE_DIM>;
1111 
1112  auto pip = mField.getInterface<PipelineManager>();
1113  // Boundary
1114  auto dm_is = getDMSubData(subDM)->getSmartRowIs();
1115  auto ao_up = createAOMappingIS(dm_is, PETSC_NULL);
1116 
1117  pip->getOpBoundaryLhsPipeline().push_front(new OpSchurAssembleBegin());
1118  pip->getOpBoundaryLhsPipeline().push_back(
1119  new OpMassStab("SIGMA", "SIGMA",
1120  [eps_stab](double, double, double) { return eps_stab; }));
1121  pip->getOpBoundaryLhsPipeline().push_back(new OpSchurAssembleEnd<SCHUR_DGESV>(
1122  {"SIGMA"}, {nullptr}, {ao_up}, {S}, {false}, false));
1123 
1124  // Domain
1125  pip->getOpDomainLhsPipeline().push_front(new OpSchurAssembleBegin());
1126  pip->getOpDomainLhsPipeline().push_back(new OpSchurAssembleEnd<SCHUR_DGESV>(
1127  {"SIGMA"}, {nullptr}, {ao_up}, {S}, {false}, false));
1128 
1129  auto pre_proc_schur_lhs_ptr = boost::make_shared<FEMethod>();
1130  auto post_proc_schur_lhs_ptr = boost::make_shared<FEMethod>();
1131 
1132  pre_proc_schur_lhs_ptr->preProcessHook = [this]() {
1134  CHKERR MatZeroEntries(A);
1135  CHKERR MatZeroEntries(P);
1136  CHKERR MatZeroEntries(S);
1137  MOFEM_LOG("CONTACT", Sev::verbose) << "Lhs Assemble Begin";
1139  };
1140 
1141  post_proc_schur_lhs_ptr->postProcessHook = [this, ao_up,
1142  post_proc_schur_lhs_ptr]() {
1144  MOFEM_LOG("CONTACT", Sev::verbose) << "Lhs Assemble End";
1145 
1146  *post_proc_schur_lhs_ptr->matAssembleSwitch = false;
1147 
1148  auto print_mat_norm = [this](auto a, std::string prefix) {
1150  double nrm;
1151  CHKERR MatNorm(a, NORM_FROBENIUS, &nrm);
1152  MOFEM_LOG("CONTACT", Sev::noisy) << prefix << " norm = " << nrm;
1154  };
1155 
1156  CHKERR MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY);
1157  CHKERR MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY);
1159  mField, post_proc_schur_lhs_ptr, 1, A)();
1160 
1161  CHKERR MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY);
1162  CHKERR MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY);
1163  CHKERR MatAXPY(P, 1, A, SAME_NONZERO_PATTERN);
1164 
1165  CHKERR MatAssemblyBegin(S, MAT_FINAL_ASSEMBLY);
1166  CHKERR MatAssemblyEnd(S, MAT_FINAL_ASSEMBLY);
1167 
1169  mField, post_proc_schur_lhs_ptr, 1, S, ao_up)();
1170 
1171 #ifndef NDEBUG
1172  CHKERR print_mat_norm(A, "A");
1173  CHKERR print_mat_norm(P, "P");
1174  CHKERR print_mat_norm(S, "S");
1175 #endif // NDEBUG
1176 
1177  MOFEM_LOG("CONTACT", Sev::verbose) << "Lhs Assemble Finish";
1179  };
1180 
1181  auto simple = mField.getInterface<Simple>();
1182  auto ts_ctx_ptr = getDMTsCtx(simple->getDM());
1183  ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_schur_lhs_ptr);
1184  ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_schur_lhs_ptr);
1185 
1187 }
1188 
1191  auto simple = mField.getInterface<Simple>();
1192  SmartPetscObj<IS> is;
1193  mField.getInterface<ISManager>()->isCreateProblemFieldAndRank(
1194  simple->getProblemName(), ROW, "SIGMA", 0, SPACE_DIM, is);
1195  CHKERR PCFieldSplitSetIS(pc, NULL, is);
1196  CHKERR PCFieldSplitSetSchurPre(pc, PC_FIELDSPLIT_SCHUR_PRE_USER, S);
1198 }
1199 
1200 boost::shared_ptr<SetUpSchur>
1202  return boost::shared_ptr<SetUpSchur>(new SetUpSchurImpl(m_field));
1203 }
MoFEM::NaturalBC::Assembly::LinearForm
Definition: Natural.hpp:67
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
MoFEM::createAOMappingIS
auto createAOMappingIS(IS isapp, IS ispetsc)
Creates an application mapping using two index sets.
Definition: PetscSmartObj.hpp:302
SetUpSchurImpl
Definition: SetUpSchurImpl.cpp:9
MoFEM::EntitiesFieldData::EntData
Data on single entity (This is passed as argument to DataOperator::doWork)
Definition: EntitiesFieldData.hpp:127
BoundaryEle
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
Definition: child_and_parent.cpp:39
SetUpSchurImpl::setUp
MoFEMErrorCode setUp(KSP solver)
Definition: SetUpSchurImpl.cpp:39
MYPCOMM_INDEX
#define MYPCOMM_INDEX
default communicator number PCOMM
Definition: definitions.h:215
spring_stiffness
double spring_stiffness
Definition: contact.cpp:131
MoFEM::CoreTmp< 0 >
Core (interface) class.
Definition: Core.hpp:82
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
SetUpSchurImpl::createSubDM
SmartPetscObj< DM > createSubDM()
Definition: contact.cpp:1085
ContactOps
Definition: EshelbianContact.hpp:10
IT
constexpr IntegrationType IT
Definition: contact.cpp:37
MoFEM::OpFluxRhsImpl
Definition: Natural.hpp:39
main
int main(int argc, char *argv[])
Definition: contact.cpp:934
MoFEM::PipelineManager::ElementsAndOpsByDim
Definition: PipelineManager.hpp:38
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::NaturalBC::Assembly::BiLinearForm
Definition: Natural.hpp:74
CHK_THROW_MESSAGE
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
Definition: definitions.h:596
MoFEM::DMMoFEMSetSquareProblem
PetscErrorCode DMMoFEMSetSquareProblem(DM dm, PetscBool square_problem)
set squared problem
Definition: DMMoFEM.cpp:460
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::Types::MatrixDouble
UBlasMatrix< double > MatrixDouble
Definition: Types.hpp:77
SetUpSchurImpl::~SetUpSchurImpl
virtual ~SetUpSchurImpl()
Definition: contact.cpp:997
SetUpSchurImpl::setPC
MoFEMErrorCode setPC(PC pc)
Definition: contact.cpp:1189
MoFEM::EssentialPostProcRhs< DisplacementCubitBcData >
Specialization for DisplacementCubitBcData.
Definition: EssentialDisplacementCubitBcData.hpp:111
MoFEM::PETSC
@ PETSC
Definition: FormsIntegrators.hpp:104
Contact::uXScatter
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uXScatter
Definition: contact.cpp:185
MoFEM::PipelineManager
PipelineManager interface.
Definition: PipelineManager.hpp:24
MoFEM.hpp
A
constexpr AssemblyType A
Definition: operators_tests.cpp:30
MoFEM::OpSchurAssembleEnd< SCHUR_DGESV >
Definition: Schur.hpp:114
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
MoFEM::CoreTmp< 0 >::Finalize
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Definition: Core.cpp:112
rho
double rho
Definition: contact.cpp:130
HenckyOps
Definition: HenckyOps.hpp:11
Contact::mField
MoFEM::Interface & mField
Definition: contact.cpp:176
BoundaryEleOpStab
Element used to specialise assembly.
Definition: contact.cpp:94
MoFEM::LogManager::createSink
static boost::shared_ptr< SinkType > createSink(boost::shared_ptr< std::ostream > stream_ptr, std::string comm_filter)
Create a sink object.
Definition: LogManager.cpp:298
HenckyOps.hpp
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
MoFEM::getDMSubData
auto getDMSubData(DM dm)
Get sub problem data structure.
Definition: DMMoFEM.hpp:1076
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.
MoFEM::createDMMatrix
auto createDMMatrix(DM dm)
Get smart matrix from DM.
Definition: DMMoFEM.hpp:1003
MoFEM::DMMoFEMAddElement
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
Definition: DMMoFEM.cpp:501
SCHUR_ASSEMBLE
#define SCHUR_ASSEMBLE
Definition: contact.cpp:18
MoFEM::DeprecatedCoreInterface
Deprecated interface functions.
Definition: DeprecatedCoreInterface.hpp:16
SPACE_DIM
constexpr int SPACE_DIM
Definition: contact.cpp:53
scale
double scale
Definition: contact.cpp:135
MoFEM::OpFluxLhsImpl
Definition: Natural.hpp:43
ROW
@ ROW
Definition: definitions.h:123
MoFEM::Interface
DeprecatedCoreInterface Interface
Definition: Interface.hpp:1975
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
EntData
EntitiesFieldData::EntData EntData
Definition: contact.cpp:59
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
FieldSpace
FieldSpace
approximation spaces
Definition: definitions.h:82
MoFEM::ForcesAndSourcesCore::UserDataOperator::getKSPA
Mat getKSPA() const
Definition: ForcesAndSourcesCore.hpp:1095
MoFEM::OpBaseImpl
Definition: FormsIntegrators.hpp:170
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
vis_spring_stiffness
double vis_spring_stiffness
Definition: contact.cpp:132
MoFEM::OpSchurAssembleBegin
Clear Schur complement internal data.
Definition: Schur.hpp:22
MoFEM
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:10
MoFEM::ISManager
Section manager is used to create indexes and sections.
Definition: ISManager.hpp:23
MoFEM::createDM
auto createDM(MPI_Comm comm, const std::string dm_type_name)
Creates smart DM object.
Definition: PetscSmartObj.hpp:137
a
constexpr double a
Definition: approx_sphere.cpp:30
MoFEM::TimeScale::TimeScale
TimeScale(std::string file_name="", bool error_if_file_not_given=false)
TimeScale constructor.
Definition: ScalingMethod.cpp:22
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::ForcesAndSourcesCore::UserDataOperator
Definition: ForcesAndSourcesCore.hpp:549
MoFEM::FaceElementForcesAndSourcesCore::UserDataOperator
default operator for TRI element
Definition: FaceElementForcesAndSourcesCore.hpp:94
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
MoFEM::DMMoFEMCreateSubDM
PetscErrorCode DMMoFEMCreateSubDM(DM subdm, DM dm, const char problem_name[])
Must be called by user to set Sub DM MoFEM data structures.
Definition: DMMoFEM.cpp:219
double
SetUpSchurImpl::A
SmartPetscObj< Mat > A
Definition: contact.cpp:1012
MoFEM::FormsIntegrators::Assembly
Assembly methods.
Definition: FormsIntegrators.hpp:302
poisson_ratio
double poisson_ratio
Definition: contact.cpp:129
MoFEM::TimeScale
Force scale operator for reading two columns.
Definition: ScalingMethod.hpp:32
MOFEM_LOG_SYNCHRONISE
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
Definition: LogManager.hpp:345
Contact
Definition: contact.cpp:169
EshelbianPlasticity::P
@ P
Definition: EshelbianContact.cpp:193
Contact::uZScatter
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uZScatter
Definition: contact.cpp:187
MoFEM::LogManager::getStrmWorld
static boost::shared_ptr< std::ostream > getStrmWorld()
Get the strm world object.
Definition: LogManager.cpp:344
MoFEM::DMRegister_MoFEM
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition: DMMoFEM.cpp:47
MoFEM::GAUSS
@ GAUSS
Definition: FormsIntegrators.hpp:128
contact_order
int contact_order
Definition: contact.cpp:126
MatrixFunction.hpp
Contact::mfrontInterface
boost::shared_ptr< GenericElementInterface > mfrontInterface
Definition: contact.cpp:189
MoFEM::AddFluxToLhsPipelineImpl
Definition: Natural.hpp:49
MoFEM::TsSetIJacobian
PetscErrorCode TsSetIJacobian(TS ts, PetscReal t, Vec u, Vec u_t, PetscReal a, Mat A, Mat B, void *ctx)
Set function evaluating jacobian in TS solver.
Definition: TsCtx.cpp:165
Contact::Contact
Contact(MoFEM::Interface &m_field)
Definition: contact.cpp:171
EXECUTABLE_DIMENSION
#define EXECUTABLE_DIMENSION
Definition: contact.cpp:14
SetUpSchurImpl::setOperator
MoFEMErrorCode setOperator()
Definition: contact.cpp:1101
MOFEM_LOG_TAG
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
Definition: LogManager.hpp:339
Contact::createCommonData
MoFEMErrorCode createCommonData()
[Set up problem]
Definition: contact.cpp:432
MoFEM::AddFluxToRhsPipelineImpl
Definition: Natural.hpp:46
MoFEM::matDuplicate
SmartPetscObj< Mat > matDuplicate(Mat mat, MatDuplicateOption op)
Definition: PetscSmartObj.hpp:230
MoFEM::OpBaseImpl::MatSetValuesHook
boost::function< MoFEMErrorCode(ForcesAndSourcesCore::UserDataOperator *op_ptr, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, MatrixDouble &m)> MatSetValuesHook
Definition: FormsIntegrators.hpp:210
BiLinearForm
Contact::ScaledTimeScale
Definition: contact.cpp:196
MOFEM_NOT_FOUND
@ MOFEM_NOT_FOUND
Definition: definitions.h:33
MoFEM::OpSetHOWeightsOnSubDim
Definition: HODataOperators.hpp:145
SetUpSchur::SetUpSchur
SetUpSchur()=default
Contact::ScaledTimeScale::getScale
double getScale(const double time)
Get scaling at a given time.
Definition: contact.cpp:198
MoFEM::TimeScale::getScale
double getScale(const double time)
Get scaling at a given time.
Definition: ScalingMethod.cpp:133
ContactOps.hpp
MoFEM::IntegrationType
IntegrationType
Form integrator integration types.
Definition: FormsIntegrators.hpp:128
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
ElementsAndOps
Definition: child_and_parent.cpp:18
Range
DomainEleOp
is_quasi_static
PetscBool is_quasi_static
[Operators used for contact]
Definition: contact.cpp:123
MoFEM::CoreTmp< 0 >::Initialize
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
Definition: Core.cpp:72
Contact::setupProblem
MoFEMErrorCode setupProblem()
[Run problem]
Definition: contact.cpp:218
MOFEM_LOG
#define MOFEM_LOG(channel, severity)
Log.
Definition: LogManager.hpp:308
MoFEM::NaturalBC::Assembly
Assembly methods.
Definition: Natural.hpp:65
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
CATCH_ERRORS
#define CATCH_ERRORS
Catch errors.
Definition: definitions.h:372
DEMKOWICZ_JACOBI_BASE
@ DEMKOWICZ_JACOBI_BASE
Definition: definitions.h:66
MoFEM::AssemblyType
AssemblyType
[Storage and set boundary conditions]
Definition: FormsIntegrators.hpp:104
MoFEM::CommInterface
Managing BitRefLevels.
Definition: CommInterface.hpp:21
BoundaryEleOp
BoundaryEle::UserDataOperator BoundaryEleOp
Definition: contact.cpp:63
MoFEM::Core
CoreTmp< 0 > Core
Definition: Core.hpp:1094
HenckyOps::f
auto f
Definition: HenckyOps.hpp:15
UserDataOperator
ForcesAndSourcesCore::UserDataOperator UserDataOperator
Definition: HookeElement.hpp:75
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
HCURL
@ HCURL
field with continuous tangents
Definition: definitions.h:86
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
Contact::runProblem
MoFEMErrorCode runProblem()
[Run problem]
Definition: contact.cpp:205
FieldApproximationBase
FieldApproximationBase
approximation base
Definition: definitions.h:58
SetUpSchurImpl::SetUpSchurImpl
SetUpSchurImpl(MoFEM::Interface &m_field)
Definition: contact.cpp:995
geom_order
int geom_order
Definition: contact.cpp:127
ReactionDiffusionEquation::D
const double D
diffusivity
Definition: reaction_diffusion.cpp:20
ContactNaturalBC.hpp
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
MoFEM::DMMoFEMAddSubFieldRow
PetscErrorCode DMMoFEMAddSubFieldRow(DM dm, const char field_name[])
Definition: DMMoFEM.cpp:242
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
help
static char help[]
[Check]
Definition: contact.cpp:932
MoFEM::LogManager::setLog
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
Definition: LogManager.cpp:389
MoFEM::SmartPetscObj
intrusive_ptr for managing petsc objects
Definition: PetscSmartObj.hpp:78
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
PostProcContact.hpp
MoFEM::ForcesAndSourcesCore::UserDataOperator::getKSPB
Mat getKSPB() const
Definition: ForcesAndSourcesCore.hpp:1103
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