v0.15.0
Loading...
Searching...
No Matches
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]
 
 Contact (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 

Private Member Functions

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

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< MFrontInterfacemfrontInterfacePtr
 
boost::shared_ptr< MonitormonitorPtr
 
boost::shared_ptr< GenericElementInterfacemfrontInterface
 

Detailed Description

Definition at line 120 of file contact.cpp.

Constructor & Destructor Documentation

◆ Contact() [1/2]

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

Definition at line 122 of file contact.cpp.

◆ Contact() [2/2]

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

Definition at line 128 of file contact.cpp.

128: mField(m_field) {}
MoFEM::Interface & mField
Definition contact.cpp:128

Member Function Documentation

◆ bC() [1/2]

MoFEMErrorCode Contact::bC ( )
private

[Create common data]

[Boundary condition]

Definition at line 443 of file contact.cpp.

450 {
451 mfrontInterface->setMonitorPtr(monitorPtr);
452 }
453
455}
456//! [Create common data]
457
458//! [Boundary condition]
461 auto bc_mng = mField.getInterface<BcManager>();
463
464 for (auto f : {"U", "SIGMA"}) {
465 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
466 "REMOVE_X", f, 0, 0);
467 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
468 "REMOVE_Y", f, 1, 1);
469 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
470 "REMOVE_Z", f, 2, 2);
471 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(),
472 "REMOVE_ALL", f, 0, 3);
473 }
474
475 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "FIX_X",
476 "SIGMA", 0, 0, false, true);
void simple(double P1[], double P2[], double P3[], double c[], const int N)
Definition acoustic.cpp:69
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
boost::shared_ptr< GenericElementInterface > mfrontInterface
Definition contact.cpp:146
boost::shared_ptr< Monitor > monitorPtr
Definition contact.cpp:142
MoFEMErrorCode bC()
[Create common data]
Definition contact.cpp:443
Boundary condition manager for finite element problem setup.
Simple interface for fast problem set-up.
Definition Simple.hpp:27
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.

◆ bC() [2/2]

MoFEMErrorCode Contact::bC ( )
private

◆ checkResults() [1/2]

MoFEMErrorCode Contact::checkResults ( )
private

[Solve]

[Check]

Definition at line 860 of file contact.cpp.

868 {
870 if (atom_test && !mField.get_comm_rank()) {
871 const double *t_ptr;
872 CHKERR VecGetArrayRead(ContactOps::CommonData::totalTraction, &t_ptr);
873 double hertz_force;
874 double fem_force;
875 double analytical_active_area = 1.0;
876 double norm = 1e-5;
877 double tol_force = 1e-3;
878 double tol_norm = 7.5; // change when analytical functions are updated
879 double tol_area = 3e-2;
880 double fem_active_area = t_ptr[3];
881
882 switch (atom_test) {
883 case 1: // plane stress
884 hertz_force = 3.927;
885 fem_force = t_ptr[1];
886 break;
887
888 case 2: // plane strain
889 hertz_force = 4.675;
890 fem_force = t_ptr[1];
891 norm = monitorPtr->getErrorNorm(1);
892 break;
893
894 case 3: // Hertz 3D
895 hertz_force = 3.968;
896 tol_force = 2e-3;
897 fem_force = t_ptr[2];
898 analytical_active_area = M_PI / 4;
899 tol_area = 0.2;
900 break;
901
902 case 4: // axisymmetric
903 tol_force = 5e-3;
904 tol_area = 0.2;
905 // analytical_active_area = M_PI;
906
907 case 5: // axisymmetric
908 hertz_force = 15.873;
909 tol_force = 5e-3;
910 fem_force = t_ptr[1];
911 norm = monitorPtr->getErrorNorm(1);
912 analytical_active_area = M_PI;
913 break;
914
915 case 6: // wavy 2d
916 hertz_force = 0.374;
917 fem_force = t_ptr[1];
918 break;
919
920 case 7: // wavy 3d
921 hertz_force = 0.5289;
922 fem_force = t_ptr[2];
923 break;
924
925 default:
926 SETERRQ1(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
927 "atom test %d does not exist", atom_test);
928 }
929 if (fabs(fem_force - hertz_force) / hertz_force > tol_force) {
930 SETERRQ3(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
931 "atom test %d failed: Wrong FORCE output: %3.4e != %3.4e",
932 atom_test, fem_force, hertz_force);
933 }
934 if (norm > tol_norm) {
935 SETERRQ3(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
936 "atom test %d failed: Wrong NORM output: %3.4e > %3.4e",
937 atom_test, norm, tol_norm);
938 }
939 if (fabs(fem_active_area - analytical_active_area) > tol_area) {
940 SETERRQ3(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
941 "atom test %d failed: AREA computed %3.4e but should be %3.4e",
942 atom_test, fem_active_area, analytical_active_area);
@ MOFEM_ATOM_TEST_INVALID
Definition definitions.h:40
@ MOFEM_INVALID_DATA
Definition definitions.h:36
static SmartPetscObj< Vec > totalTraction
virtual int get_comm_rank() const =0
int atom_test
Definition contact.cpp:94

◆ checkResults() [2/2]

MoFEMErrorCode Contact::checkResults ( )
private

◆ createCommonData() [1/2]

MoFEMErrorCode Contact::createCommonData ( )
private

[Set up problem]

[Create common data]

Definition at line 310 of file contact.cpp.

310 {
311 Projection10NodeCoordsOnField ent_method(mField, "GEOMETRY");
312 return mField.loop_dofs("GEOMETRY", ent_method);
313 };
314
315 PetscBool project_geometry = PETSC_TRUE;
316 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-project_geometry",
317 &project_geometry, PETSC_NULL);
318 if (project_geometry) {
319 CHKERR project_ho_geometry();
320 }
321
323} //! [Set up problem]
324
325//! [Create common data]
328
329 PetscBool use_mfront = PETSC_FALSE;
330 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-use_mfront", &use_mfront,
331 PETSC_NULL);
332 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-is_axisymmetric",
333 &is_axisymmetric, PETSC_NULL);
334 CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-atom_test", &atom_test,
335 PETSC_NULL);
336
337 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-scale", &scale, PETSC_NULL);
338 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-young_modulus", &young_modulus,
339 PETSC_NULL);
340 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-poisson_ratio", &poisson_ratio,
341 PETSC_NULL);
342 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-rho", &rho, PETSC_NULL);
343 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-cn", &cn_contact, PETSC_NULL);
344 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-spring_stiffness",
345 &spring_stiffness, PETSC_NULL);
346 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-vis_spring_stiffness",
347 &vis_spring_stiffness, PETSC_NULL);
348 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-alpha_damping", &alpha_damping,
349 PETSC_NULL);
350
351 if (!mfrontInterface) {
352 MOFEM_LOG("CONTACT", Sev::inform) << "Young modulus " << young_modulus;
353 MOFEM_LOG("CONTACT", Sev::inform) << "Poisson_ratio " << poisson_ratio;
354 } else {
355 MOFEM_LOG("CONTACT", Sev::inform) << "Using MFront for material model";
356 }
357
358 MOFEM_LOG("CONTACT", Sev::inform) << "Density " << rho;
359 MOFEM_LOG("CONTACT", Sev::inform) << "cn_contact " << cn_contact;
360 MOFEM_LOG("CONTACT", Sev::inform) << "Spring stiffness " << spring_stiffness;
361 MOFEM_LOG("CONTACT", Sev::inform)
362 << "Vis spring_stiffness " << vis_spring_stiffness;
363
364 MOFEM_LOG("CONTACT", Sev::inform) << "alpha_damping " << alpha_damping;
365
366 PetscBool use_scale = PETSC_FALSE;
367 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-use_scale", &use_scale,
368 PETSC_NULL);
369 if (use_scale) {
371 }
372
373 MOFEM_LOG("CONTACT", Sev::inform) << "Scale " << scale;
374
375 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-is_quasi_static",
376 &is_quasi_static, PETSC_NULL);
377 MOFEM_LOG("CONTACT", Sev::inform)
378 << "Is quasi-static: " << (is_quasi_static ? "true" : "false");
379
380#ifdef ENABLE_PYTHON_BINDING
381 auto file_exists = [](std::string myfile) {
382 std::ifstream file(myfile.c_str());
383 if (file) {
384 return true;
385 }
386 return false;
387 };
388 char sdf_file_name[255] = "sdf.py";
389 CHKERR PetscOptionsGetString(PETSC_NULL, PETSC_NULL, "-sdf_file",
390 sdf_file_name, 255, PETSC_NULL);
391
392 if (file_exists(sdf_file_name)) {
393 MOFEM_LOG("CONTACT", Sev::inform) << sdf_file_name << " file found";
394 sdfPythonPtr = boost::make_shared<SDFPython>();
395 CHKERR sdfPythonPtr->sdfInit(sdf_file_name);
396 sdfPythonWeakPtr = sdfPythonPtr;
397 } else {
398 MOFEM_LOG("CONTACT", Sev::warning) << sdf_file_name << " file NOT found";
399 }
400#endif
401
402 if (is_axisymmetric) {
403 if (SPACE_DIM == 3) {
404 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
405 "Use executable contact_2d with axisymmetric model");
406 } else {
407 if (!use_mfront) {
408 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
409 "Axisymmetric model is only available with MFront (set "
410 "use_mfront to 1)");
411 } else {
412 MOFEM_LOG("CONTACT", Sev::inform) << "Using axisymmetric model";
413 }
414 }
415 } else {
416 if (SPACE_DIM == 2) {
417 MOFEM_LOG("CONTACT", Sev::inform) << "Using plane strain model";
418 }
419 }
420
421 if (use_mfront) {
422#ifndef WITH_MODULE_MFRONT_INTERFACE
423 SETERRQ(
424 PETSC_COMM_SELF, MOFEM_NOT_FOUND,
425 "MFrontInterface module was not found while use_mfront was set to 1");
426#else
427 if (SPACE_DIM == 3) {
429 boost::make_shared<MFrontMoFEMInterface<TRIDIMENSIONAL>>(
430 mField, "U", "GEOMETRY", true, is_quasi_static);
431 } else if (SPACE_DIM == 2) {
432 if (is_axisymmetric) {
434 boost::make_shared<MFrontMoFEMInterface<AXISYMMETRICAL>>(
435 mField, "U", "GEOMETRY", true, is_quasi_static);
436 } else {
437 mfrontInterface = boost::make_shared<MFrontMoFEMInterface<PLANESTRAIN>>(
438 mField, "U", "GEOMETRY", true, is_quasi_static);
439 }
@ MOFEM_NOT_FOUND
Definition definitions.h:33
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
#define MOFEM_LOG(channel, severity)
Log.
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.
double cn_contact
Definition contact.cpp:97
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
PetscErrorCode PetscOptionsGetScalar(PetscOptions *, const char pre[], const char name[], PetscScalar *dval, PetscBool *set)
PetscErrorCode PetscOptionsGetString(PetscOptions *, const char pre[], const char name[], char str[], size_t size, PetscBool *set)
MoFEMErrorCode createCommonData()
[Set up problem]
Definition contact.cpp:310
Projection of edge entities with one mid-node on hierarchical basis.
double young_modulus
Definition contact.cpp:82
double spring_stiffness
Definition contact.cpp:85
double rho
Definition contact.cpp:84
PetscBool is_quasi_static
[Operators used for contact]
Definition contact.cpp:76
double alpha_damping
Definition contact.cpp:87
constexpr int SPACE_DIM
Definition contact.cpp:53
double poisson_ratio
Definition contact.cpp:83
double vis_spring_stiffness
Definition contact.cpp:86
double scale
Definition contact.cpp:89
PetscBool is_axisymmetric
Definition contact.cpp:91

◆ createCommonData() [2/2]

MoFEMErrorCode Contact::createCommonData ( )
private

◆ OPs() [1/2]

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

496 {
499 auto *pip_mng = mField.getInterface<PipelineManager>();
500 auto time_scale = boost::make_shared<ScaledTimeScale>();
501 auto body_force_time_scale =
502 boost::make_shared<ScaledTimeScale>("body_force_hist.txt");
503
504 auto integration_rule_vol = [](int, int, int approx_order) {
505 return 2 * approx_order + geom_order - 1;
506 };
507 auto integration_rule_boundary = [](int, int, int approx_order) {
508 return 2 * approx_order + geom_order - 1;
509 };
510
511 auto add_domain_base_ops = [&](auto &pip) {
514 "GEOMETRY");
516 };
517
518 auto add_domain_ops_lhs = [&](auto &pip) {
520
521 //! [Only used for dynamics]
524 //! [Only used for dynamics]
525 if (is_quasi_static == PETSC_FALSE) {
526
527 auto *pip_mng = mField.getInterface<PipelineManager>();
528 auto fe_domain_lhs = pip_mng->getDomainLhsFE();
529
530 auto get_inertia_and_mass_damping =
531 [this, fe_domain_lhs](const double, const double, const double) {
532 return (rho * scale) * fe_domain_lhs->ts_aa +
533 (alpha_damping * scale) * fe_domain_lhs->ts_a;
534 };
535 pip.push_back(new OpMass("U", "U", get_inertia_and_mass_damping));
536 } else {
537
538 auto *pip_mng = mField.getInterface<PipelineManager>();
539 auto fe_domain_lhs = pip_mng->getDomainLhsFE();
540
541 auto get_inertia_and_mass_damping =
542 [this, fe_domain_lhs](const double, const double, const double) {
543 return (alpha_damping * scale) * fe_domain_lhs->ts_a;
544 };
545 pip.push_back(new OpMass("U", "U", get_inertia_and_mass_damping));
546 }
547
548 if (!mfrontInterface) {
549 if (!is_large_strain) {
550 CHKERR HookeOps::opFactoryDomainLhs<SPACE_DIM, AT, IT, DomainEleOp>(
551 mField, pip, "U", "MAT_ELASTIC", Sev::verbose, scale);
552 } else {
553 CHKERR HenckyOps::opFactoryDomainLhs<SPACE_DIM, AT, IT, DomainEleOp>(
554 mField, pip, "U", "MAT_ELASTIC", Sev::verbose, scale);
555 }
556 } else {
557 CHKERR mfrontInterface->opFactoryDomainLhs(pip);
558 }
559
561 };
562
563 auto add_domain_ops_rhs = [&](auto &pip) {
565
567 pip, mField, "U", {body_force_time_scale}, Sev::inform);
568
569 //! [Only used for dynamics]
572 //! [Only used for dynamics]
573
574 // only in case of dynamics
575 if (is_quasi_static == PETSC_FALSE) {
576 auto mat_acceleration = boost::make_shared<MatrixDouble>();
578 "U", mat_acceleration));
579 pip.push_back(
580 new OpInertiaForce("U", mat_acceleration, [](double, double, double) {
581 return rho * scale;
582 }));
583 }
584
585 // only in case of viscosity
586 if (alpha_damping > 0) {
587 auto mat_velocity = boost::make_shared<MatrixDouble>();
588 pip.push_back(
589 new OpCalculateVectorFieldValuesDot<SPACE_DIM>("U", mat_velocity));
590 pip.push_back(
591 new OpInertiaForce("U", mat_velocity, [](double, double, double) {
592 return alpha_damping * scale;
593 }));
594 }
595
596 if (!mfrontInterface) {
597 if (!is_large_strain) {
598 CHKERR HookeOps::opFactoryDomainRhs<SPACE_DIM, AT, IT, DomainEleOp>(
599 mField, pip, "U", "MAT_ELASTIC", Sev::inform, 1, scale);
600 } else {
601 CHKERR HenckyOps::opFactoryDomainRhs<SPACE_DIM, AT, IT, DomainEleOp>(
602 mField, pip, "U", "MAT_ELASTIC", Sev::inform, scale);
603 }
604 } else {
605 CHKERR mfrontInterface->opFactoryDomainRhs(pip);
606 }
607
608 CHKERR ContactOps::opFactoryDomainRhs<SPACE_DIM, AT, IT, DomainEleOp>(
609 pip, "SIGMA", "U", is_axisymmetric);
610
612 };
613
614 auto add_boundary_base_ops = [&](auto &pip) {
617 "GEOMETRY");
618 // We have to integrate on curved face geometry, thus integration weight
619 // have to adjusted.
620 pip.push_back(new OpSetHOWeightsOnSubDim<SPACE_DIM>());
622 };
623
624 auto add_boundary_ops_lhs = [&](auto &pip) {
626
627 //! [Operators used for contact]
630 //! [Operators used for contact]
631
632 // Add Natural BCs to LHS
634 pip, mField, "U", Sev::inform);
635
636 if (spring_stiffness > 0 || vis_spring_stiffness > 0) {
637
638 auto *pip_mng = mField.getInterface<PipelineManager>();
639 auto fe_boundary_lhs = pip_mng->getBoundaryLhsFE();
640
641 pip.push_back(new OpSpringLhs(
642 "U", "U",
643
644 [this, fe_boundary_lhs](double, double, double) {
645 return spring_stiffness * scale +
646 (vis_spring_stiffness * scale) * fe_boundary_lhs->ts_a;
647 }
648
649 ));
650 }
651
652 CHKERR
653 ContactOps::opFactoryBoundaryLhs<SPACE_DIM, AT, GAUSS, BoundaryEleOp>(
654 pip, "SIGMA", "U", is_axisymmetric);
656 DomainEle>(
657 mField, pip, simple->getDomainFEName(), "SIGMA", "U", "GEOMETRY",
658 integration_rule_vol, is_axisymmetric);
659
661 };
662
663 auto add_boundary_ops_rhs = [&](auto &pip) {
665
666 //! [Operators used for contact]
669 //! [Operators used for contact]
670
671 // Add Natural BCs to RHS
673 pip, mField, "U", {time_scale}, Sev::inform);
674
675 if (spring_stiffness > 0 || vis_spring_stiffness > 0) {
676 auto u_disp = boost::make_shared<MatrixDouble>();
677 auto dot_u_disp = boost::make_shared<MatrixDouble>();
678 pip.push_back(new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_disp));
679 pip.push_back(
680 new OpCalculateVectorFieldValuesDot<SPACE_DIM>("U", dot_u_disp));
681 pip.push_back(
682 new OpSpringRhs("U", u_disp, [this](double, double, double) {
683 return spring_stiffness * scale;
684 }));
685 pip.push_back(
686 new OpSpringRhs("U", dot_u_disp, [this](double, double, double) {
688 }));
689 }
690
691 CHKERR
692 ContactOps::opFactoryBoundaryRhs<SPACE_DIM, AT, GAUSS, BoundaryEleOp>(
693 pip, "SIGMA", "U", is_axisymmetric);
694
696 };
697
698 CHKERR add_domain_base_ops(pip_mng->getOpDomainLhsPipeline());
699 CHKERR add_domain_base_ops(pip_mng->getOpDomainRhsPipeline());
700 CHKERR add_domain_ops_lhs(pip_mng->getOpDomainLhsPipeline());
701 CHKERR add_domain_ops_rhs(pip_mng->getOpDomainRhsPipeline());
702
703 CHKERR add_boundary_base_ops(pip_mng->getOpBoundaryLhsPipeline());
704 CHKERR add_boundary_base_ops(pip_mng->getOpBoundaryRhsPipeline());
705 CHKERR add_boundary_ops_lhs(pip_mng->getOpBoundaryLhsPipeline());
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
@ H1
continuous field
Definition definitions.h:85
@ HDIV
field with continuous normal traction
Definition definitions.h:87
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesVector< 1, SPACE_DIM, 1 > OpInertiaForce
@ GAUSS
Gaussian quadrature integration.
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)
static constexpr int approx_order
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, SPACE_DIM > OpMass
[Only used with Hooke equation (linear material model)]
Definition seepage.cpp:56
Add operators pushing bases from local to physical configuration.
Approximate field values for given petsc vector.
Specialization for double precision vector field values calculation.
PipelineManager interface.
constexpr AssemblyType AT
Definition contact.cpp:34
FormsIntegrators< BoundaryEleOp >::Assembly< AT >::LinearForm< IT >::OpBaseTimesVector< 1, SPACE_DIM, 1 > OpSpringRhs
Definition contact.cpp:73
FormsIntegrators< BoundaryEleOp >::Assembly< AT >::BiLinearForm< IT >::OpMass< 1, SPACE_DIM > OpSpringLhs
[Operators used for contact]
Definition contact.cpp:71
PetscBool is_large_strain
Definition contact.cpp:92
int geom_order
Definition contact.cpp:81

◆ OPs() [2/2]

MoFEMErrorCode Contact::OPs ( )
private

◆ runProblem() [1/2]

MoFEMErrorCode Contact::runProblem ( )

[Run problem]

Definition at line 157 of file contact.cpp.

162 {
166 CHKERR bC();
MoFEMErrorCode setupProblem()
[Run problem]
Definition contact.cpp:170

◆ runProblem() [2/2]

MoFEMErrorCode Contact::runProblem ( )

◆ setupProblem() [1/2]

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

175 {
178
179 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-large_strain", &is_large_strain,
180 PETSC_NULL);
181
182 CHKERR PetscOptionsGetBool(PETSC_NULL, "", "-plane_strain", &is_plane_strain,
183 PETSC_NULL);
184 CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-order", &order, PETSC_NULL);
185 CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-contact_order", &contact_order,
186 PETSC_NULL);
187 sigma_order = std::max(order, contact_order) - 1;
188 CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-sigma_order", &sigma_order,
189 PETSC_NULL);
190 CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-geom_order", &geom_order,
191 PETSC_NULL);
192 if (!is_large_strain) {
193 MOFEM_LOG("CONTACT", Sev::inform)
194 << "Selected material model: Hooke (small strain)";
195 } else {
196 MOFEM_LOG("CONTACT", Sev::inform)
197 << "Selected deafult material model: Hencky (finite strain)";
198 }
199 MOFEM_LOG("CONTACT", Sev::inform) << "Order " << order;
200 MOFEM_LOG("CONTACT", Sev::inform) << "Contact order " << contact_order;
201 MOFEM_LOG("CONTACT", Sev::inform) << "Sigma order " << sigma_order;
202 MOFEM_LOG("CONTACT", Sev::inform) << "Geom order " << geom_order;
203
204 // Select base
205 enum bases { AINSWORTH, DEMKOWICZ, LASBASETOPT };
206 const char *list_bases[LASBASETOPT] = {"ainsworth", "demkowicz"};
207 PetscInt choice_base_value = AINSWORTH;
208 CHKERR PetscOptionsGetEList(PETSC_NULL, NULL, "-base", list_bases,
209 LASBASETOPT, &choice_base_value, PETSC_NULL);
210
212 switch (choice_base_value) {
213 case AINSWORTH:
215 MOFEM_LOG("CONTACT", Sev::inform)
216 << "Set AINSWORTH_LEGENDRE_BASE for displacements";
217 break;
218 case DEMKOWICZ:
220 MOFEM_LOG("CONTACT", Sev::inform)
221 << "Set DEMKOWICZ_JACOBI_BASE for displacements";
222 break;
223 default:
224 base = LASTBASE;
225 break;
226 }
227
228 // Note: For tets we have only H1 Ainsworth base, for Hex we have only H1
229 // Demkowicz base. We need to implement Demkowicz H1 base on tet.
230 CHKERR simple->addDomainField("U", H1, base, SPACE_DIM);
231 CHKERR simple->addBoundaryField("U", H1, base, SPACE_DIM);
232 CHKERR simple->addDomainField("SIGMA", CONTACT_SPACE, DEMKOWICZ_JACOBI_BASE,
233 SPACE_DIM);
234 CHKERR simple->addBoundaryField("SIGMA", CONTACT_SPACE, DEMKOWICZ_JACOBI_BASE,
235 SPACE_DIM);
236 CHKERR simple->addDataField("GEOMETRY", H1, base, SPACE_DIM);
237
238 CHKERR simple->setFieldOrder("U", order);
239 CHKERR simple->setFieldOrder("GEOMETRY", geom_order);
240
241 auto get_skin = [&]() {
242 Range body_ents;
243 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM, body_ents);
244 Skinner skin(&mField.get_moab());
245 Range skin_ents;
246 CHKERR skin.find_skin(0, body_ents, false, skin_ents);
247 return skin_ents;
248 };
249
250 auto filter_blocks = [&](auto skin) {
251 bool is_contact_block = false;
252 Range contact_range;
253 for (auto m :
254 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
255
256 (boost::format("%s(.*)") % "CONTACT").str()
257
258 ))
259
260 ) {
261 is_contact_block =
262 true; ///< blocs interation is collective, so that is set irrespective
263 ///< if there are entities in given rank or not in the block
264 MOFEM_LOG("CONTACT", Sev::inform)
265 << "Find contact block set: " << m->getName();
266 auto meshset = m->getMeshset();
267 Range contact_meshset_range;
268 CHKERR mField.get_moab().get_entities_by_dimension(
269 meshset, SPACE_DIM - 1, contact_meshset_range, true);
270
271 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
272 contact_meshset_range);
273 contact_range.merge(contact_meshset_range);
274 }
275 if (is_contact_block) {
276 MOFEM_LOG("SYNC", Sev::inform)
277 << "Nb entities in contact surface: " << contact_range.size();
279 skin = intersect(skin, contact_range);
280 }
281 return skin;
282 };
283
284 auto filter_true_skin = [&](auto skin) {
285 Range boundary_ents;
286 ParallelComm *pcomm =
287 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
288 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
289 PSTATUS_NOT, -1, &boundary_ents);
290 return boundary_ents;
291 };
292
293 auto boundary_ents = filter_true_skin(filter_blocks(get_skin()));
294 CHKERR simple->setFieldOrder("SIGMA", 0);
295 CHKERR simple->setFieldOrder("SIGMA", sigma_order, &boundary_ents);
296
297 if (contact_order > order) {
298 Range ho_ents;
299
300 CHKERR mField.get_moab().get_adjacencies(boundary_ents, 1, false, ho_ents,
301 moab::Interface::UNION);
302
303 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(ho_ents);
304 CHKERR simple->setFieldOrder("U", contact_order, &ho_ents);
305 CHKERR mField.getInterface<CommInterface>()->synchroniseFieldEntities("U");
306 }
307
static auto filter_true_skin(MoFEM::Interface &m_field, Range &&skin)
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
FieldApproximationBase
approximation base
Definition definitions.h:58
@ LASTBASE
Definition definitions.h:69
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
@ DEMKOWICZ_JACOBI_BASE
Definition definitions.h:66
#define MYPCOMM_INDEX
default communicator number PCOMM
PetscErrorCode PetscOptionsGetEList(PetscOptions *, const char pre[], const char name[], const char *const *list, PetscInt next, PetscInt *value, PetscBool *set)
FTensor::Index< 'm', 3 > m
Managing BitRefLevels.
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =0
Interface for managing meshsets containing materials and boundary conditions.
int sigma_order
Definition contact.cpp:80
PetscBool is_plane_strain
Definition contact.cpp:95
int contact_order
Definition contact.cpp:79
int order
Definition contact.cpp:78
constexpr FieldSpace CONTACT_SPACE
[Specialisation for assembly]
Definition contact.cpp:67

◆ setupProblem() [2/2]

MoFEMErrorCode Contact::setupProblem ( )
private

◆ tsSolve() [1/2]

MoFEMErrorCode Contact::tsSolve ( )
private

Definition at line 718 of file contact.cpp.

722 {
723 static boost::shared_ptr<SetUpSchur>
724 createSetUpSchur(MoFEM::Interface &m_field);
725 virtual MoFEMErrorCode setUp(SmartPetscObj<TS> solver) = 0;
726
727protected:
728 SetUpSchur() = default;
729};
730
733
736 ISManager *is_manager = mField.getInterface<ISManager>();
737
738 auto set_section_monitor = [&](auto solver) {
740 SNES snes;
741 CHKERR TSGetSNES(solver, &snes);
742 PetscViewerAndFormat *vf;
743 CHKERR PetscViewerAndFormatCreate(PETSC_VIEWER_STDOUT_WORLD,
744 PETSC_VIEWER_DEFAULT, &vf);
745 CHKERR SNESMonitorSet(
746 snes,
747 (MoFEMErrorCode (*)(SNES, PetscInt, PetscReal, void *))SNESMonitorFields,
748 vf, (MoFEMErrorCode (*)(void **))PetscViewerAndFormatDestroy);
750 };
751
752 auto scatter_create = [&](auto D, auto coeff) {
754 CHKERR is_manager->isCreateProblemFieldAndRank(simple->getProblemName(),
755 ROW, "U", coeff, coeff, is);
756 int loc_size;
757 CHKERR ISGetLocalSize(is, &loc_size);
758 Vec v;
759 CHKERR VecCreateMPI(mField.get_comm(), loc_size, PETSC_DETERMINE, &v);
760 VecScatter scatter;
761 CHKERR VecScatterCreate(D, is, v, PETSC_NULL, &scatter);
762 return std::make_tuple(SmartPetscObj<Vec>(v),
764 };
765
766 auto set_time_monitor = [&](auto dm, auto solver) {
768 monitorPtr->setScatterVectors(uXScatter, uYScatter, uZScatter);
769 boost::shared_ptr<ForcesAndSourcesCore> null;
770 CHKERR DMMoFEMTSSetMonitor(dm, solver, simple->getDomainFEName(),
771 monitorPtr, null, null);
773 };
774
775 auto set_essential_bc = [&]() {
777 // This is low level pushing finite elements (pipelines) to solver
778 auto ts_ctx_ptr = getDMTsCtx(simple->getDM());
779 auto pre_proc_ptr = boost::make_shared<FEMethod>();
780 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
781 auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
782
783 // Add boundary condition scaling
784 auto time_scale = boost::make_shared<TimeScale>();
785
786 auto get_bc_hook_rhs = [&]() {
788 {time_scale}, false);
789 return hook;
790 };
791 pre_proc_ptr->preProcessHook = get_bc_hook_rhs();
792
793 auto get_post_proc_hook_rhs = [&]() {
795 mField, post_proc_rhs_ptr, 1.);
796 };
797 auto get_post_proc_hook_lhs = [&]() {
799 mField, post_proc_lhs_ptr, 1.);
800 };
801 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs();
802
803 ts_ctx_ptr->getPreProcessIFunction().push_front(pre_proc_ptr);
804 ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_ptr);
805 ts_ctx_ptr->getPostProcessIFunction().push_back(post_proc_rhs_ptr);
806 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs();
807 ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_lhs_ptr);
809 };
810
811 // Set up Schur preconditioner
812 auto set_schur_pc = [&](auto solver) {
813 boost::shared_ptr<SetUpSchur> schur_ptr;
814 if (AT == AssemblyType::BLOCK_SCHUR) {
815 // Set up Schur preconditioner
817 CHK_MOAB_THROW(schur_ptr->setUp(solver), "SetUpSchur::setUp");
818 }
819 return schur_ptr;
820 };
821
822 auto dm = simple->getDM();
823 auto D = createDMVector(dm);
824
826
827 uXScatter = scatter_create(D, 0);
828 uYScatter = scatter_create(D, 1);
829 if (SPACE_DIM == 3)
830 uZScatter = scatter_create(D, 2);
831
832 // Add extra finite elements to SNES solver pipelines to resolve essential
833 // boundary conditions
834 CHKERR set_essential_bc();
835
836 if (is_quasi_static == PETSC_TRUE) {
837 auto solver = pip_mng->createTSIM();
838 CHKERR TSSetFromOptions(solver);
839 auto schur_pc_ptr = set_schur_pc(solver);
840
841 auto D = createDMVector(dm);
842 CHKERR set_section_monitor(solver);
843 CHKERR set_time_monitor(dm, solver);
844 CHKERR TSSetSolution(solver, D);
845 CHKERR TSSetUp(solver);
846 CHKERR TSSolve(solver, NULL);
847 } else {
848 auto solver = pip_mng->createTSIM2();
849 CHKERR TSSetFromOptions(solver);
850 auto schur_pc_ptr = set_schur_pc(solver);
851
852 auto dm = simple->getDM();
853 auto D = createDMVector(dm);
854 auto DD = vectorDuplicate(D);
855
856 CHKERR set_section_monitor(solver);
@ ROW
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
auto createDMVector(DM dm)
Get smart vector from DM.
Definition DMMoFEM.hpp:1234
double D
const double v
phase velocity of light in medium (cm/ns)
const FTensor::Tensor2< T, Dim, Dim > Vec
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:1046
auto getDMTsCtx(DM dm)
Get TS context data structure used by DM.
Definition DMMoFEM.hpp:1276
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
static auto createTotalTraction(MoFEM::Interface &m_field)
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uZScatter
Definition contact.cpp:139
MoFEMErrorCode tsSolve()
Definition contact.cpp:718
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uXScatter
Definition contact.cpp:137
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uYScatter
Definition contact.cpp:138
Deprecated interface functions.
Class (Function) to enforce essential constrains on the left hand side diagonal.
Definition Essential.hpp:33
Class (Function) to enforce essential constrains on the right hand side diagonal.
Definition Essential.hpp:41
Class (Function) to enforce essential constrains.
Definition Essential.hpp:25
Section manager is used to create indexes and sections.
Definition ISManager.hpp:23
intrusive_ptr for managing petsc objects
[Push operators to pipeline]
static boost::shared_ptr< SetUpSchur > createSetUpSchur(MoFEM::Interface &m_field)

◆ tsSolve() [2/2]

MoFEMErrorCode Contact::tsSolve ( )
private

Member Data Documentation

◆ mField

MoFEM::Interface & Contact::mField
private

Definition at line 128 of file contact.cpp.

◆ mfrontInterface

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

Definition at line 146 of file contact.cpp.

◆ mfrontInterfacePtr

boost::shared_ptr<MFrontInterface> Contact::mfrontInterfacePtr
private

Definition at line 141 of file contact.cpp.

◆ monitorPtr

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

Definition at line 142 of file contact.cpp.

◆ uXScatter

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

Definition at line 137 of file contact.cpp.

◆ uYScatter

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

Definition at line 138 of file contact.cpp.

◆ uZScatter

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

Definition at line 139 of file contact.cpp.


The documentation for this struct was generated from the following file: