v0.15.0
Loading...
Searching...
No Matches
Contact Struct Reference
Collaboration diagram for Contact:
[legend]

Classes

struct  ScaledTimeScale
 

Public Member Functions

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

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]
 

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

Constructor & Destructor Documentation

◆ Contact()

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:133

Member Function Documentation

◆ bC()

MoFEMErrorCode Contact::bC ( )
private

[Create common data]

[Boundary condition]

Definition at line 459 of file contact.cpp.

459 {
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);
477 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "FIX_Y",
478 "SIGMA", 1, 1, false, true);
479 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "FIX_Z",
480 "SIGMA", 2, 2, false, true);
481 CHKERR bc_mng->removeBlockDOFsOnEntities(simple->getProblemName(), "FIX_ALL",
482 "SIGMA", 0, 3, false, true);
483 CHKERR bc_mng->removeBlockDOFsOnEntities(
484 simple->getProblemName(), "NO_CONTACT", "SIGMA", 0, 3, false, true);
485
486 // Note remove has to be always before push. Then node marking will be
487 // corrupted.
488 CHKERR bc_mng->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
489 simple->getProblemName(), "U");
490
492}
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.
Simple interface for fast problem set-up.
Definition BcManager.hpp:29
Definition of the displacement bc data structure.
Definition BCData.hpp:72
Simple interface for fast problem set-up.
Definition Simple.hpp:27
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.

◆ checkResults()

MoFEMErrorCode Contact::checkResults ( )
private

[Solve]

[Check]

Definition at line 872 of file contact.cpp.

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

◆ createCommonData()

MoFEMErrorCode Contact::createCommonData ( )
private

[Set up problem]

[Create common data]

Definition at line 326 of file contact.cpp.

326 {
328
329 PetscBool use_mfront = PETSC_FALSE;
330 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-use_mfront", &use_mfront,
331 PETSC_NULLPTR);
332 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-is_axisymmetric",
333 &is_axisymmetric, PETSC_NULLPTR);
334 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-atom_test", &atom_test,
335 PETSC_NULLPTR);
336
337 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-scale", &scale, PETSC_NULLPTR);
338 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-young_modulus", &young_modulus,
339 PETSC_NULLPTR);
340 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-poisson_ratio", &poisson_ratio,
341 PETSC_NULLPTR);
342 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-rho", &rho, PETSC_NULLPTR);
343 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-cn", &cn_contact, PETSC_NULLPTR);
344 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-spring_stiffness",
345 &spring_stiffness, PETSC_NULLPTR);
346 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-vis_spring_stiffness",
347 &vis_spring_stiffness, PETSC_NULLPTR);
348 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-alpha_damping", &alpha_damping,
349 PETSC_NULLPTR);
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_NULLPTR, "", "-use_scale", &use_scale,
368 PETSC_NULLPTR);
369 if (use_scale) {
371 }
372
373 MOFEM_LOG("CONTACT", Sev::inform) << "Scale " << scale;
374
375 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-is_quasi_static",
376 &is_quasi_static, PETSC_NULLPTR);
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_NULLPTR, PETSC_NULLPTR, "-sdf_file",
390 sdf_file_name, 255, PETSC_NULLPTR);
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 }
440 }
441#endif
442 CHKERR mfrontInterface->getCommandLineParameters();
443 }
444
446 auto dm = simple->getDM();
447 monitorPtr =
448 boost::make_shared<Monitor>(dm, scale, mfrontInterface, is_axisymmetric, is_large_strain);
449
450 if (use_mfront) {
451 mfrontInterface->setMonitorPtr(monitorPtr);
452 }
453
455}
double young_modulus
Definition contact.cpp:84
double spring_stiffness
Definition contact.cpp:87
PetscBool is_large_strain
Definition contact.cpp:94
double rho
Definition contact.cpp:86
PetscBool is_quasi_static
[Operators used for contact]
Definition contact.cpp:78
double alpha_damping
Definition contact.cpp:89
constexpr int SPACE_DIM
Definition contact.cpp:55
double poisson_ratio
Definition contact.cpp:85
double vis_spring_stiffness
Definition contact.cpp:88
double scale
Definition contact.cpp:91
PetscBool is_axisymmetric
Definition contact.cpp:93
@ 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.
double cn_contact
Definition contact.cpp:99
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)
boost::shared_ptr< GenericElementInterface > mfrontInterface
Definition contact.cpp:146
MoFEMErrorCode getDM(DM *dm)
Get DM.
Definition Simple.cpp:800

◆ 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 496 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) {
551 mField, pip, "U", "MAT_ELASTIC", Sev::verbose, scale);
552 } else {
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) {
599 mField, pip, "U", "MAT_ELASTIC", Sev::inform, 1, scale);
600 } else {
602 mField, pip, "U", "MAT_ELASTIC", Sev::inform, scale);
603 }
604 } else {
605 CHKERR mfrontInterface->opFactoryDomainRhs(pip);
606 }
607
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
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
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());
706 CHKERR add_boundary_ops_rhs(pip_mng->getOpBoundaryRhsPipeline());
707
708 if (mfrontInterface) {
709 CHKERR mfrontInterface->setUpdateElementVariablesOperators();
710 }
711
712 CHKERR pip_mng->setDomainRhsIntegrationRule(integration_rule_vol);
713 CHKERR pip_mng->setDomainLhsIntegrationRule(integration_rule_vol);
714 CHKERR pip_mng->setBoundaryRhsIntegrationRule(integration_rule_boundary);
715 CHKERR pip_mng->setBoundaryLhsIntegrationRule(integration_rule_boundary);
716
718}
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
[Define dimension]
constexpr AssemblyType AT
Definition contact.cpp:36
FormsIntegrators< BoundaryEleOp >::Assembly< AT >::LinearForm< IT >::OpBaseTimesVector< 1, SPACE_DIM, 1 > OpSpringRhs
Definition contact.cpp:74
FormsIntegrators< BoundaryEleOp >::Assembly< AT >::BiLinearForm< IT >::OpMass< 1, SPACE_DIM > OpSpringLhs
[Operators used for contact]
Definition contact.cpp:72
int geom_order
Definition contact.cpp:83
@ 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
MoFEMErrorCode opFactoryDomainRhs(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string sigma, std::string u, bool is_axisymmetric=false)
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)
MoFEMErrorCode opFactoryBoundaryRhs(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string sigma, std::string u, bool is_axisymmetric=false)
MoFEMErrorCode opFactoryBoundaryLhs(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string sigma, std::string u, bool is_axisymmetric=false)
MoFEMErrorCode opFactoryDomainLhs(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, boost::shared_ptr< HenckyOps::CommonData > common_ptr, Sev sev)
MoFEMErrorCode opFactoryDomainRhs(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, boost::shared_ptr< HenckyOps::CommonData > common_ptr, Sev sev)
MoFEMErrorCode opFactoryDomainLhs(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, boost::shared_ptr< HookeOps::CommonData > common_ptr, Sev sev)
Assemble domain LHS K factory (LHS first overload) Initializes and pushes operators to assemble the L...
Definition HookeOps.hpp:302
MoFEMErrorCode opFactoryDomainRhs(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, boost::shared_ptr< HookeOps::CommonData > common_ptr, Sev sev, bool is_non_linear=false)
Factory function to create and push internal force operators for the domain RHS. (RHS first overload)...
Definition HookeOps.hpp:242
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:55
Add operators pushing bases from local to physical configuration.
Approximate field values for given petsc vector.
Get values at integration pts for tensor field rank 1, i.e. vector field.
PipelineManager interface.

◆ runProblem()

MoFEMErrorCode Contact::runProblem ( )

[Run problem]

Definition at line 162 of file contact.cpp.

162 {
166 CHKERR bC();
167 CHKERR OPs();
168 CHKERR tsSolve();
171}
MoFEMErrorCode tsSolve()
Definition contact.cpp:731
MoFEMErrorCode setupProblem()
[Run problem]
Definition contact.cpp:175
MoFEMErrorCode OPs()
[Boundary condition]
Definition contact.cpp:496
MoFEMErrorCode createCommonData()
[Set up problem]
Definition contact.cpp:326
MoFEMErrorCode checkResults()
[Solve]
Definition contact.cpp:872
MoFEMErrorCode bC()
[Create common data]
Definition contact.cpp:459

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

175 {
178
179 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-large_strain", &is_large_strain,
180 PETSC_NULLPTR);
181
182 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-plane_strain", &is_plane_strain,
183 PETSC_NULLPTR);
184 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-order", &order, PETSC_NULLPTR);
185 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-contact_order", &contact_order,
186 PETSC_NULLPTR);
187 sigma_order = std::max(order, contact_order) - 1;
188 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-sigma_order", &sigma_order,
189 PETSC_NULLPTR);
190 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-geom_order", &geom_order,
191 PETSC_NULLPTR);
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_NULLPTR, NULL, "-base", list_bases,
209 LASBASETOPT, &choice_base_value, PETSC_NULLPTR);
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 :
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
308 CHKERR simple->setUp();
309
310 auto project_ho_geometry = [&]() {
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_NULLPTR, "", "-project_geometry",
317 &project_geometry, PETSC_NULLPTR);
318 if (project_geometry) {
319 CHKERR project_ho_geometry();
320 }
321
323} //! [Set up problem]
static auto filter_true_skin(MoFEM::Interface &m_field, Range &&skin)
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
int sigma_order
Definition contact.cpp:82
PetscBool is_plane_strain
Definition contact.cpp:95
int contact_order
Definition contact.cpp:81
int order
Definition contact.cpp:80
constexpr FieldSpace CONTACT_SPACE
[Specialisation for assembly]
Definition contact.cpp:69
FieldApproximationBase
approximation base
Definition definitions.h:58
@ LASTBASE
Definition definitions.h:69
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base nme:nme847.
Definition definitions.h:60
@ DEMKOWICZ_JACOBI_BASE
Definition definitions.h:66
#define MYPCOMM_INDEX
default communicator number PCOMM
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.
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
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.
Projection of edge entities with one mid-node on hierarchical basis.

◆ tsSolve()

MoFEMErrorCode Contact::tsSolve ( )
private

Definition at line 731 of file contact.cpp.

731 {
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_NULLPTR, &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
840 auto B = createDMMatrix(dm);
841 CHKERR TSSetIJacobian(solver, B, B, PETSC_NULLPTR, PETSC_NULLPTR);
842 auto schur_pc_ptr = set_schur_pc(solver);
843
844 auto D = createDMVector(dm);
845 CHKERR set_section_monitor(solver);
846 CHKERR set_time_monitor(dm, solver);
847 CHKERR TSSetSolution(solver, D);
848 CHKERR TSSetUp(solver);
849 CHKERR TSSolve(solver, NULL);
850 } else {
851 auto solver = pip_mng->createTSIM2();
852 CHKERR TSSetFromOptions(solver);
853
854 auto B = createDMMatrix(dm);
855 CHKERR TSSetI2Jacobian(solver, B, B, PETSC_NULLPTR, PETSC_NULLPTR);
856 auto schur_pc_ptr = set_schur_pc(solver);
857
858 auto D = createDMVector(dm);
859 auto DD = vectorDuplicate(D);
860 CHKERR set_section_monitor(solver);
861 CHKERR set_time_monitor(dm, solver);
862 CHKERR TS2SetSolution(solver, D, DD);
863 CHKERR TSSetUp(solver);
864 CHKERR TSSolve(solver, NULL);
865 }
866
868}
@ 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:1102
auto createDMMatrix(DM dm)
Get smart matrix from DM.
Definition DMMoFEM.hpp:1059
double D
const double v
phase velocity of light in medium (cm/ns)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
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:1144
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
static auto createTotalTraction(MoFEM::Interface &m_field)
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uYScatter
Definition contact.cpp:143
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uXScatter
Definition contact.cpp:142
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uZScatter
Definition contact.cpp:144
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
static boost::shared_ptr< SetUpSchur > createSetUpSchur(MoFEM::Interface &m_field)

Member Data Documentation

◆ mField

MoFEM::Interface& Contact::mField
private

Definition at line 133 of file contact.cpp.

◆ mfrontInterface

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

Definition at line 146 of file contact.cpp.

◆ monitorPtr

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

Definition at line 147 of file contact.cpp.

◆ uXScatter

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

Definition at line 142 of file contact.cpp.

◆ uYScatter

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

Definition at line 143 of file contact.cpp.

◆ uZScatter

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

Definition at line 144 of file contact.cpp.


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