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 122 of file contact.cpp.

Constructor & Destructor Documentation

◆ Contact()

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

Definition at line 124 of file contact.cpp.

124 : mField(m_field) {}

Member Function Documentation

◆ bC()

MoFEMErrorCode Contact::bC ( )
private

[Create common data]

[Boundary condition]

Definition at line 432 of file contact.cpp.

432  {
434  auto bc_mng = mField.getInterface<BcManager>();
435  auto simple = mField.getInterface<Simple>();
436 
437  for (auto f : {"U", "SIGMA"}) {
438  CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
439  "REMOVE_X", f, 0, 0);
440  CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
441  "REMOVE_Y", f, 1, 1);
442  CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
443  "REMOVE_Z", f, 2, 2);
444  CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
445  "REMOVE_ALL", f, 0, 3);
446  }
447 
448  CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "FIX_X",
449  "SIGMA", 0, 0, false, true);
450  CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "FIX_Y",
451  "SIGMA", 1, 1, false, true);
452  CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "FIX_Z",
453  "SIGMA", 2, 2, false, true);
454  CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "FIX_ALL",
455  "SIGMA", 0, 3, false, true);
456  CHKERR bc_mng->removeBlockDOFsOnEntities(
457  simple->getProblemName(), "NO_CONTACT", "SIGMA", 0, 3, false, true);
458 
459  // Note remove has to be always before push. Then node marking will be
460  // corrupted.
461  CHKERR bc_mng->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
462  simple->getProblemName(), "U");
463 
465 }

◆ checkResults()

MoFEMErrorCode Contact::checkResults ( )
private

[Solve]

[Check]

Definition at line 836 of file contact.cpp.

836  {
838  if (atom_test && !mField.get_comm_rank()) {
839  const double *t_ptr;
840  CHKERR VecGetArrayRead(ContactOps::CommonData::totalTraction, &t_ptr);
841  double hertz_force;
842  double fem_force;
843  double norm = 1e-5;
844  double tol = 1e-3;
845  double tol_norm = 7.5; // change when analytical functions are updated
846  switch (atom_test) {
847  case 1: // plane stress
848  hertz_force = 3.927;
849  fem_force = t_ptr[1];
850  break;
851  case 2: // plane strain
852  hertz_force = 4.675;
853  fem_force = t_ptr[1];
854  norm = monitorPtr->getErrorNorm(1);
855  break;
856  case 3: // 3D
857  hertz_force = 3.968;
858  fem_force = t_ptr[2];
859  case 4: // axisymmetric
860  tol = 5e3;
861  case 5: // axisymmetric
862  hertz_force = 15.873;
863  fem_force = t_ptr[1];
864  norm = monitorPtr->getErrorNorm(1);
865  break;
866  case 6: // wavy 2d
867  hertz_force = 0.374;
868  fem_force = t_ptr[1];
869  break;
870  case 7: // wavy 3d
871  hertz_force = 0.5289;
872  fem_force = t_ptr[2];
873  break;
874  default:
875  SETERRQ1(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
876  "atom test %d does not exist", atom_test);
877  }
878  if (fabs(fem_force - hertz_force) / hertz_force > tol) {
879  SETERRQ3(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
880  "atom test %d diverged! %3.4e != %3.4e", atom_test, fem_force,
881  hertz_force);
882  }
883  if (norm > tol_norm) {
884  SETERRQ3(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
885  "atom test %d diverged! %3.4e > %3.4e", atom_test, norm,
886  tol_norm);
887  }
888  CHKERR VecRestoreArrayRead(ContactOps::CommonData::totalTraction, &t_ptr);
889  }
890 
892 
894 }

◆ createCommonData()

MoFEMErrorCode Contact::createCommonData ( )
private

[Set up problem]

[Create common data]

Definition at line 311 of file contact.cpp.

311  {
313 
314  PetscBool use_mfront = PETSC_FALSE;
315  CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-use_mfront", &use_mfront,
316  PETSC_NULL);
317  CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-is_axisymmetric",
318  &is_axisymmetric, PETSC_NULL);
319  CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-atom_test", &atom_test,
320  PETSC_NULL);
321 
322  CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-scale", &scale, PETSC_NULL);
323  CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-young_modulus", &young_modulus,
324  PETSC_NULL);
325  CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-poisson_ratio", &poisson_ratio,
326  PETSC_NULL);
327  CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-rho", &rho, PETSC_NULL);
328  CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-cn", &cn_contact, PETSC_NULL);
329  CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-spring_stiffness",
330  &spring_stiffness, PETSC_NULL);
331  CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-vis_spring_stiffness",
332  &vis_spring_stiffness, PETSC_NULL);
333  CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-alpha_damping", &alpha_damping,
334  PETSC_NULL);
335 
336  if (!mfrontInterface) {
337  MOFEM_LOG("CONTACT", Sev::inform) << "Young modulus " << young_modulus;
338  MOFEM_LOG("CONTACT", Sev::inform) << "Poisson_ratio " << poisson_ratio;
339  } else {
340  MOFEM_LOG("CONTACT", Sev::inform) << "Using MFront for material model";
341  }
342 
343  MOFEM_LOG("CONTACT", Sev::inform) << "Density " << rho;
344  MOFEM_LOG("CONTACT", Sev::inform) << "cn_contact " << cn_contact;
345  MOFEM_LOG("CONTACT", Sev::inform) << "Spring stiffness " << spring_stiffness;
346  MOFEM_LOG("CONTACT", Sev::inform)
347  << "Vis spring_stiffness " << vis_spring_stiffness;
348 
349  MOFEM_LOG("CONTACT", Sev::inform) << "alpha_damping " << alpha_damping;
350 
351  PetscBool use_scale = PETSC_FALSE;
352  CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-use_scale", &use_scale,
353  PETSC_NULL);
354  if (use_scale) {
355  scale /= young_modulus;
356  }
357 
358  MOFEM_LOG("CONTACT", Sev::inform) << "Scale " << scale;
359 
360  CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-is_quasi_static",
361  &is_quasi_static, PETSC_NULL);
362  MOFEM_LOG("CONTACT", Sev::inform)
363  << "Is quasi-static: " << (is_quasi_static ? "true" : "false");
364 
365 #ifdef PYTHON_SDF
366  char sdf_file_name[255];
367  CHKERR PetscOptionsGetString(PETSC_NULL, PETSC_NULL, "-sdf_file",
368  sdf_file_name, 255, PETSC_NULL);
369 
370  sdfPythonPtr = boost::make_shared<SDFPython>();
371  CHKERR sdfPythonPtr->sdfInit(sdf_file_name);
372  sdfPythonWeakPtr = sdfPythonPtr;
373 #endif
374 
375  if (is_axisymmetric) {
376  if (SPACE_DIM == 3) {
377  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
378  "Use executable contact_2d with axisymmetric model");
379  } else {
380  if (!use_mfront) {
381  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
382  "Axisymmetric model is only available with MFront (set "
383  "use_mfront to 1)");
384  } else {
385  MOFEM_LOG("CONTACT", Sev::inform) << "Using axisymmetric model";
386  }
387  }
388  } else {
389  if (SPACE_DIM == 2) {
390  MOFEM_LOG("CONTACT", Sev::inform) << "Using plane strain model";
391  }
392  }
393 
394  if (use_mfront) {
395 #ifndef WITH_MODULE_MFRONT_INTERFACE
396  SETERRQ(
397  PETSC_COMM_SELF, MOFEM_NOT_FOUND,
398  "MFrontInterface module was not found while use_mfront was set to 1");
399 #else
400  if (SPACE_DIM == 3) {
402  boost::make_shared<MFrontMoFEMInterface<TRIDIMENSIONAL>>(
403  mField, "U", "GEOMETRY", true, is_quasi_static);
404  } else if (SPACE_DIM == 2) {
405  if (is_axisymmetric) {
407  boost::make_shared<MFrontMoFEMInterface<AXISYMMETRICAL>>(
408  mField, "U", "GEOMETRY", true, is_quasi_static);
409  } else {
410  mfrontInterface = boost::make_shared<MFrontMoFEMInterface<PLANESTRAIN>>(
411  mField, "U", "GEOMETRY", true, is_quasi_static);
412  }
413  }
414 #endif
415  CHKERR mfrontInterface->getCommandLineParameters();
416  }
417 
419  auto dm = simple->getDM();
420  monitorPtr =
421  boost::make_shared<Monitor>(dm, scale, mfrontInterface, is_axisymmetric);
422 
423  if (use_mfront) {
424  mfrontInterface->setMonitorPtr(monitorPtr);
425  }
426 
428 }

◆ 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 469 of file contact.cpp.

469  {
471  auto simple = mField.getInterface<Simple>();
472  auto *pip_mng = mField.getInterface<PipelineManager>();
473  auto bc_mng = mField.getInterface<BcManager>();
474  auto time_scale = boost::make_shared<ScaledTimeScale>();
475  auto body_force_time_scale =
476  boost::make_shared<ScaledTimeScale>("body_force_hist.txt");
477 
478  auto integration_rule_vol = [](int, int, int approx_order) {
479  return 2 * approx_order + geom_order - 1;
480  };
481  auto integration_rule_boundary = [](int, int, int approx_order) {
482  return 2 * approx_order + geom_order - 1;
483  };
484 
485  auto add_domain_base_ops = [&](auto &pip) {
488  "GEOMETRY");
490  };
491 
492  auto henky_common_data_ptr = boost::make_shared<HenckyOps::CommonData>();
493  henky_common_data_ptr->matDPtr = boost::make_shared<MatrixDouble>();
494  henky_common_data_ptr->matGradPtr = boost::make_shared<MatrixDouble>();
495 
496  auto add_domain_ops_lhs = [&](auto &pip) {
498 
499  //! [Only used for dynamics]
502  //! [Only used for dynamics]
503  if (is_quasi_static == PETSC_FALSE) {
504 
505  auto *pip_mng = mField.getInterface<PipelineManager>();
506  auto fe_domain_lhs = pip_mng->getDomainLhsFE();
507 
508  auto get_inertia_and_mass_damping =
509  [this, fe_domain_lhs](const double, const double, const double) {
510  return (rho * scale) * fe_domain_lhs->ts_aa +
511  (alpha_damping * scale) * fe_domain_lhs->ts_a;
512  };
513  pip.push_back(new OpMass("U", "U", get_inertia_and_mass_damping));
514  } else {
515 
516  auto *pip_mng = mField.getInterface<PipelineManager>();
517  auto fe_domain_lhs = pip_mng->getDomainLhsFE();
518 
519  auto get_inertia_and_mass_damping =
520  [this, fe_domain_lhs](const double, const double, const double) {
521  return (alpha_damping * scale) * fe_domain_lhs->ts_a;
522  };
523  pip.push_back(new OpMass("U", "U", get_inertia_and_mass_damping));
524  }
525 
526  if (!mfrontInterface) {
527  CHKERR HenckyOps::opFactoryDomainLhs<SPACE_DIM, AT, IT, DomainEleOp>(
528  mField, pip, "U", "MAT_ELASTIC", Sev::verbose, scale);
529  } else {
530  CHKERR mfrontInterface->opFactoryDomainLhs(pip);
531  }
532 
534  };
535 
536  auto add_domain_ops_rhs = [&](auto &pip) {
538 
540  pip, mField, "U", {body_force_time_scale}, Sev::inform);
541 
542  //! [Only used for dynamics]
544  AT>::LinearForm<IT>::OpBaseTimesVector<1, SPACE_DIM, 1>;
545  //! [Only used for dynamics]
546 
547  // only in case of dynamics
548  if (is_quasi_static == PETSC_FALSE) {
549  auto mat_acceleration = boost::make_shared<MatrixDouble>();
551  "U", mat_acceleration));
552  pip.push_back(
553  new OpInertiaForce("U", mat_acceleration, [](double, double, double) {
554  return rho * scale;
555  }));
556  }
557 
558  // only in case of viscosity
559  if (alpha_damping > 0) {
560  auto mat_velocity = boost::make_shared<MatrixDouble>();
561  pip.push_back(
562  new OpCalculateVectorFieldValuesDot<SPACE_DIM>("U", mat_velocity));
563  pip.push_back(
564  new OpInertiaForce("U", mat_velocity, [](double, double, double) {
565  return alpha_damping * scale;
566  }));
567  }
568 
569  if (!mfrontInterface) {
570  CHKERR HenckyOps::opFactoryDomainRhs<SPACE_DIM, AT, IT, DomainEleOp>(
571  mField, pip, "U", "MAT_ELASTIC", Sev::inform, scale);
572  } else {
573  CHKERR mfrontInterface->opFactoryDomainRhs(pip);
574  }
575 
576  CHKERR ContactOps::opFactoryDomainRhs<SPACE_DIM, AT, IT, DomainEleOp>(
577  pip, "SIGMA", "U", is_axisymmetric);
578 
580  };
581 
582  auto add_boundary_base_ops = [&](auto &pip) {
585  "GEOMETRY");
586  // We have to integrate on curved face geometry, thus integration weight
587  // have to adjusted.
588  pip.push_back(new OpSetHOWeightsOnSubDim<SPACE_DIM>());
590  };
591 
592  auto add_boundary_ops_lhs = [&](auto &pip) {
594 
595  //! [Operators used for contact]
598  //! [Operators used for contact]
599 
600  // Add Natural BCs to LHS
602  pip, mField, "U", Sev::inform);
603 
604  if (spring_stiffness > 0 || vis_spring_stiffness > 0) {
605 
606  auto *pip_mng = mField.getInterface<PipelineManager>();
607  auto fe_boundary_lhs = pip_mng->getBoundaryLhsFE();
608 
609  pip.push_back(new OpSpringLhs(
610  "U", "U",
611 
612  [this, fe_boundary_lhs](double, double, double) {
613  return spring_stiffness * scale +
614  (vis_spring_stiffness * scale) * fe_boundary_lhs->ts_a;
615  }
616 
617  ));
618  }
619 
620  CHKERR
621  ContactOps::opFactoryBoundaryLhs<SPACE_DIM, AT, GAUSS, BoundaryEleOp>(
622  pip, "SIGMA", "U", is_axisymmetric);
624  DomainEle>(
625  mField, pip, simple->getDomainFEName(), "SIGMA", "U", "GEOMETRY",
626  integration_rule_vol, is_axisymmetric);
627 
629  };
630 
631  auto add_boundary_ops_rhs = [&](auto &pip) {
633 
634  //! [Operators used for contact]
636  AT>::LinearForm<IT>::OpBaseTimesVector<1, SPACE_DIM, 1>;
637  //! [Operators used for contact]
638 
639  // Add Natural BCs to RHS
641  pip, mField, "U", {time_scale}, Sev::inform);
642 
643  if (spring_stiffness > 0 || vis_spring_stiffness > 0) {
644  auto u_disp = boost::make_shared<MatrixDouble>();
645  auto dot_u_disp = boost::make_shared<MatrixDouble>();
646  pip.push_back(new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_disp));
647  pip.push_back(
648  new OpCalculateVectorFieldValuesDot<SPACE_DIM>("U", dot_u_disp));
649  pip.push_back(
650  new OpSpringRhs("U", u_disp, [this](double, double, double) {
651  return spring_stiffness * scale;
652  }));
653  pip.push_back(
654  new OpSpringRhs("U", dot_u_disp, [this](double, double, double) {
655  return vis_spring_stiffness * scale;
656  }));
657  }
658 
659  CHKERR
660  ContactOps::opFactoryBoundaryRhs<SPACE_DIM, AT, GAUSS, BoundaryEleOp>(
661  pip, "SIGMA", "U", is_axisymmetric);
662 
664  };
665 
666  CHKERR add_domain_base_ops(pip_mng->getOpDomainLhsPipeline());
667  CHKERR add_domain_base_ops(pip_mng->getOpDomainRhsPipeline());
668  CHKERR add_domain_ops_lhs(pip_mng->getOpDomainLhsPipeline());
669  CHKERR add_domain_ops_rhs(pip_mng->getOpDomainRhsPipeline());
670 
671  CHKERR add_boundary_base_ops(pip_mng->getOpBoundaryLhsPipeline());
672  CHKERR add_boundary_base_ops(pip_mng->getOpBoundaryRhsPipeline());
673  CHKERR add_boundary_ops_lhs(pip_mng->getOpBoundaryLhsPipeline());
674  CHKERR add_boundary_ops_rhs(pip_mng->getOpBoundaryRhsPipeline());
675 
676  if (mfrontInterface) {
677  CHKERR mfrontInterface->setUpdateElementVariablesOperators();
678  }
679 
680  CHKERR pip_mng->setDomainRhsIntegrationRule(integration_rule_vol);
681  CHKERR pip_mng->setDomainLhsIntegrationRule(integration_rule_vol);
682  CHKERR pip_mng->setBoundaryRhsIntegrationRule(integration_rule_boundary);
683  CHKERR pip_mng->setBoundaryLhsIntegrationRule(integration_rule_boundary);
684 
686 }

◆ runProblem()

MoFEMErrorCode Contact::runProblem ( )

[Run problem]

Definition at line 158 of file contact.cpp.

158  {
162  CHKERR bC();
163  CHKERR OPs();
164  CHKERR tsSolve();
167 }

◆ 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 171 of file contact.cpp.

171  {
174 
175  CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-order", &order, PETSC_NULL);
176  CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-contact_order", &contact_order,
177  PETSC_NULL);
178  CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-geom_order", &geom_order,
179  PETSC_NULL);
180 
181  MOFEM_LOG("CONTACT", Sev::inform) << "Order " << order;
182  if (contact_order != order)
183  MOFEM_LOG("CONTACT", Sev::inform) << "Contact order " << contact_order;
184  MOFEM_LOG("CONTACT", Sev::inform) << "Geom order " << geom_order;
185 
186  // Select base
187  enum bases { AINSWORTH, DEMKOWICZ, LASBASETOPT };
188  const char *list_bases[LASBASETOPT] = {"ainsworth", "demkowicz"};
189  PetscInt choice_base_value = AINSWORTH;
190  CHKERR PetscOptionsGetEList(PETSC_NULL, NULL, "-base", list_bases,
191  LASBASETOPT, &choice_base_value, PETSC_NULL);
192 
194  switch (choice_base_value) {
195  case AINSWORTH:
197  MOFEM_LOG("CONTACT", Sev::inform)
198  << "Set AINSWORTH_LEGENDRE_BASE for displacements";
199  break;
200  case DEMKOWICZ:
201  base = DEMKOWICZ_JACOBI_BASE;
202  MOFEM_LOG("CONTACT", Sev::inform)
203  << "Set DEMKOWICZ_JACOBI_BASE for displacements";
204  break;
205  default:
206  base = LASTBASE;
207  break;
208  }
209 
210  // Note: For tets we have only H1 Ainsworth base, for Hex we have only H1
211  // Demkowicz base. We need to implement Demkowicz H1 base on tet.
212  CHKERR simple->addDomainField("U", H1, base, SPACE_DIM);
213  CHKERR simple->addBoundaryField("U", H1, base, SPACE_DIM);
214  CHKERR simple->addDomainField("SIGMA", CONTACT_SPACE, DEMKOWICZ_JACOBI_BASE,
215  SPACE_DIM);
216  CHKERR simple->addBoundaryField("SIGMA", CONTACT_SPACE, DEMKOWICZ_JACOBI_BASE,
217  SPACE_DIM);
218  CHKERR simple->addDataField("GEOMETRY", H1, base, SPACE_DIM);
219 
220  CHKERR simple->setFieldOrder("U", order);
221  CHKERR simple->setFieldOrder("GEOMETRY", geom_order);
222 
223  auto get_skin = [&]() {
224  Range body_ents;
225  CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM, body_ents);
226  Skinner skin(&mField.get_moab());
227  Range skin_ents;
228  CHKERR skin.find_skin(0, body_ents, false, skin_ents);
229  return skin_ents;
230  };
231 
232  auto filter_blocks = [&](auto skin) {
233  bool is_contact_block = false;
234  Range contact_range;
235  for (auto m :
237 
238  (boost::format("%s(.*)") % "CONTACT").str()
239 
240  ))
241 
242  ) {
243  is_contact_block =
244  true; ///< blocs interation is collective, so that is set irrespective
245  ///< if there are entities in given rank or not in the block
246  MOFEM_LOG("CONTACT", Sev::inform)
247  << "Find contact block set: " << m->getName();
248  auto meshset = m->getMeshset();
249  Range contact_meshset_range;
250  CHKERR mField.get_moab().get_entities_by_dimension(
251  meshset, SPACE_DIM - 1, contact_meshset_range, true);
252 
253  CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
254  contact_meshset_range);
255  contact_range.merge(contact_meshset_range);
256  }
257  if (is_contact_block) {
258  MOFEM_LOG("SYNC", Sev::inform)
259  << "Nb entities in contact surface: " << contact_range.size();
261  skin = intersect(skin, contact_range);
262  }
263  return skin;
264  };
265 
266  auto filter_true_skin = [&](auto skin) {
267  Range boundary_ents;
268  ParallelComm *pcomm =
269  ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
270  CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
271  PSTATUS_NOT, -1, &boundary_ents);
272  return boundary_ents;
273  };
274 
275  auto boundary_ents = filter_true_skin(filter_blocks(get_skin()));
276  CHKERR simple->setFieldOrder("SIGMA", 0);
277  int sigma_order = std::max(order, contact_order) - 1;
278  CHKERR simple->setFieldOrder("SIGMA", sigma_order, &boundary_ents);
279 
280  if (contact_order > order) {
281  Range ho_ents;
282  if constexpr (SPACE_DIM == 3) {
283  CHKERR mField.get_moab().get_adjacencies(boundary_ents, 1, false, ho_ents,
284  moab::Interface::UNION);
285  } else {
286  ho_ents = boundary_ents;
287  }
288  CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(ho_ents);
289  CHKERR simple->setFieldOrder("U", contact_order, &ho_ents);
290  CHKERR mField.getInterface<CommInterface>()->synchroniseFieldEntities("U");
291  }
292 
293  CHKERR simple->setUp();
294 
295  auto project_ho_geometry = [&]() {
296  Projection10NodeCoordsOnField ent_method(mField, "GEOMETRY");
297  return mField.loop_dofs("GEOMETRY", ent_method);
298  };
299 
300  PetscBool project_geometry = PETSC_TRUE;
301  CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-project_geometry",
302  &project_geometry, PETSC_NULL);
303  if (project_geometry) {
304  CHKERR project_ho_geometry();
305  }
306 
308 } //! [Set up problem]

◆ tsSolve()

MoFEMErrorCode Contact::tsSolve ( )
private

Definition at line 699 of file contact.cpp.

699  {
701 
704  ISManager *is_manager = mField.getInterface<ISManager>();
705 
706  auto set_section_monitor = [&](auto solver) {
708  SNES snes;
709  CHKERR TSGetSNES(solver, &snes);
710  PetscViewerAndFormat *vf;
711  CHKERR PetscViewerAndFormatCreate(PETSC_VIEWER_STDOUT_WORLD,
712  PETSC_VIEWER_DEFAULT, &vf);
713  CHKERR SNESMonitorSet(
714  snes,
715  (MoFEMErrorCode(*)(SNES, PetscInt, PetscReal, void *))SNESMonitorFields,
716  vf, (MoFEMErrorCode(*)(void **))PetscViewerAndFormatDestroy);
718  };
719 
720  auto scatter_create = [&](auto D, auto coeff) {
722  CHKERR is_manager->isCreateProblemFieldAndRank(simple->getProblemName(),
723  ROW, "U", coeff, coeff, is);
724  int loc_size;
725  CHKERR ISGetLocalSize(is, &loc_size);
726  Vec v;
727  CHKERR VecCreateMPI(mField.get_comm(), loc_size, PETSC_DETERMINE, &v);
728  VecScatter scatter;
729  CHKERR VecScatterCreate(D, is, v, PETSC_NULL, &scatter);
730  return std::make_tuple(SmartPetscObj<Vec>(v),
731  SmartPetscObj<VecScatter>(scatter));
732  };
733 
734  auto set_time_monitor = [&](auto dm, auto solver) {
736  monitorPtr->setScatterVectors(uXScatter, uYScatter, uZScatter);
737  boost::shared_ptr<ForcesAndSourcesCore> null;
738  CHKERR DMMoFEMTSSetMonitor(dm, solver, simple->getDomainFEName(),
739  monitorPtr, null, null);
741  };
742 
743  auto set_essential_bc = [&]() {
745  // This is low level pushing finite elements (pipelines) to solver
746  auto ts_ctx_ptr = getDMTsCtx(simple->getDM());
747  auto pre_proc_ptr = boost::make_shared<FEMethod>();
748  auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
749  auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
750 
751  // Add boundary condition scaling
752  auto time_scale = boost::make_shared<TimeScale>();
753 
754  auto get_bc_hook_rhs = [&]() {
756  {time_scale}, false);
757  return hook;
758  };
759  pre_proc_ptr->preProcessHook = get_bc_hook_rhs();
760 
761  auto get_post_proc_hook_rhs = [&]() {
763  mField, post_proc_rhs_ptr, 1.);
764  };
765  auto get_post_proc_hook_lhs = [&]() {
767  mField, post_proc_lhs_ptr, 1.);
768  };
769  post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs();
770 
771  ts_ctx_ptr->getPreProcessIFunction().push_front(pre_proc_ptr);
772  ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_ptr);
773  ts_ctx_ptr->getPostProcessIFunction().push_back(post_proc_rhs_ptr);
774  post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs();
775  ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_lhs_ptr);
777  };
778 
779  // Set up Schur preconditioner
780  auto set_schur_pc = [&](auto solver) {
781  boost::shared_ptr<SetUpSchur> schur_ptr;
782  if (AT == AssemblyType::BLOCK_SCHUR) {
783  // Set up Schur preconditioner
785  CHK_MOAB_THROW(schur_ptr->setUp(solver), "SetUpSchur::setUp");
786  }
787  return schur_ptr;
788  };
789 
790  auto dm = simple->getDM();
791  auto D = createDMVector(dm);
792 
794 
795  uXScatter = scatter_create(D, 0);
796  uYScatter = scatter_create(D, 1);
797  if (SPACE_DIM == 3)
798  uZScatter = scatter_create(D, 2);
799 
800  // Add extra finite elements to SNES solver pipelines to resolve essential
801  // boundary conditions
802  CHKERR set_essential_bc();
803 
804  if (is_quasi_static == PETSC_TRUE) {
805  auto solver = pip_mng->createTSIM();
806  CHKERR TSSetFromOptions(solver);
807  auto schur_pc_ptr = set_schur_pc(solver);
808 
809  auto D = createDMVector(dm);
810  CHKERR set_section_monitor(solver);
811  CHKERR set_time_monitor(dm, solver);
812  CHKERR TSSetSolution(solver, D);
813  CHKERR TSSetUp(solver);
814  CHKERR TSSolve(solver, NULL);
815  } else {
816  auto solver = pip_mng->createTSIM2();
817  CHKERR TSSetFromOptions(solver);
818  auto schur_pc_ptr = set_schur_pc(solver);
819 
820  auto dm = simple->getDM();
821  auto D = createDMVector(dm);
822  auto DD = vectorDuplicate(D);
823 
824  CHKERR set_section_monitor(solver);
825  CHKERR set_time_monitor(dm, solver);
826  CHKERR TS2SetSolution(solver, D, DD);
827  CHKERR TSSetUp(solver);
828  CHKERR TSSolve(solver, NULL);
829  }
830 
832 }

Member Data Documentation

◆ mField

MoFEM::Interface& Contact::mField
private

Definition at line 129 of file contact.cpp.

◆ mfrontInterface

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

Definition at line 142 of file contact.cpp.

◆ monitorPtr

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

Definition at line 143 of file contact.cpp.

◆ uXScatter

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

Definition at line 138 of file contact.cpp.

◆ uYScatter

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

Definition at line 139 of file contact.cpp.

◆ uZScatter

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

Definition at line 140 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 reference 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:84
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:143
Contact::bC
MoFEMErrorCode bC()
[Create common data]
Definition: contact.cpp:432
LASTBASE
@ LASTBASE
Definition: definitions.h:69
order
int order
Definition: contact.cpp:78
is_axisymmetric
PetscBool is_axisymmetric
Definition: contact.cpp:90
MoFEM::EssentialPostProcLhs< DisplacementCubitBcData >
Specialization for DisplacementCubitBcData.
Definition: EssentialDisplacementCubitBcData.hpp:134
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:113
Contact::uXScatter
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uXScatter
Definition: contact.cpp:138
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:83
Contact::mField
MoFEM::Interface & mField
Definition: contact.cpp:129
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:1144
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.
SPACE_DIM
constexpr int SPACE_DIM
Definition: contact.cpp:53
scale
double scale
Definition: contact.cpp:88
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:94
CHKERR
#define CHKERR
Inline error check.
Definition: definitions.h:535
MoFEM::createDMVector
auto createDMVector(DM dm)
Get smart vector from DM.
Definition: DMMoFEM.hpp:1067
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:85
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
OpSpringRhs
FormsIntegrators< BoundaryEleOp >::Assembly< AT >::LinearForm< IT >::OpBaseTimesVector< 1, SPACE_DIM, 1 > OpSpringRhs
Definition: contact.cpp:73
alpha_damping
double alpha_damping
Definition: contact.cpp:86
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:310
poisson_ratio
double poisson_ratio
Definition: contact.cpp:82
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:140
MoFEM::GAUSS
@ GAUSS
Definition: FormsIntegrators.hpp:136
contact_order
int contact_order
Definition: contact.cpp:79
Contact::mfrontInterface
boost::shared_ptr< GenericElementInterface > mfrontInterface
Definition: contact.cpp:142
MoFEM::AddFluxToLhsPipelineImpl
Definition: Natural.hpp:49
Contact::createCommonData
MoFEMErrorCode createCommonData()
[Set up problem]
Definition: contact.cpp:311
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:469
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:76
Contact::setupProblem
MoFEMErrorCode setupProblem()
[Run problem]
Definition: contact.cpp:171
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:221
young_modulus
double young_modulus
Definition: contact.cpp:81
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:1056
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:699
FieldApproximationBase
FieldApproximationBase
approximation base
Definition: definitions.h:58
geom_order
int geom_order
Definition: contact.cpp:80
ReactionDiffusionEquation::D
const double D
diffusivity
Definition: reaction_diffusion.cpp:20
MoFEM::BLOCK_SCHUR
@ BLOCK_SCHUR
Definition: FormsIntegrators.hpp:108
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:71
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:1109
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:836
MOFEM_INVALID_DATA
@ MOFEM_INVALID_DATA
Definition: definitions.h:36
tol
double tol
Definition: mesh_smoothing.cpp:27
CONTACT_SPACE
constexpr FieldSpace CONTACT_SPACE
[Specialisation for assembly]
Definition: contact.cpp:67
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:139