v0.15.0
Loading...
Searching...
No Matches
Classes | Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | Friends | List of all members
EshelbianCore Struct Reference

#include "users_modules/eshelbian_plasticity/src/EshelbianCore.hpp"

Inheritance diagram for EshelbianCore:
[legend]
Collaboration diagram for EshelbianCore:
[legend]

Classes

struct  DynamicRelaxationTimeScale
 
struct  SetUpSchur
 

Public Member Functions

MoFEMErrorCode query_interface (boost::typeindex::type_index type_index, UnknownInterface **iface) const
 Getting interface of core database.
 
 EshelbianCore (MoFEM::Interface &m_field)
 
virtual ~EshelbianCore ()
 
MoFEMErrorCode getOptions ()
 
template<typename BC >
MoFEMErrorCode getBc (boost::shared_ptr< BC > &bc_vec_ptr, const std::string block_name, const int nb_attributes)
 
MoFEMErrorCode getSpatialDispBc ()
 [Getting norms]
 
MoFEMErrorCode getSpatialRotationBc ()
 
MoFEMErrorCode getSpatialTractionBc ()
 
MoFEMErrorCode getTractionFreeBc (const EntityHandle meshset, boost::shared_ptr< TractionFreeBc > &bc_ptr, const std::string contact_set_name)
 Remove all, but entities where kinematic constrains are applied.
 
MoFEMErrorCode getSpatialTractionFreeBc (const EntityHandle meshset=0)
 
MoFEMErrorCode getExternalStrain ()
 
MoFEMErrorCode createExchangeVectors (Sev sev)
 
MoFEMErrorCode addFields (const EntityHandle meshset=0)
 
MoFEMErrorCode projectGeometry (const EntityHandle meshset=0)
 
MoFEMErrorCode addVolumeFiniteElement (const EntityHandle meshset=0)
 
MoFEMErrorCode addBoundaryFiniteElement (const EntityHandle meshset=0)
 
MoFEMErrorCode addDMs (const BitRefLevel bit=BitRefLevel().set(0), const EntityHandle meshset=0)
 
MoFEMErrorCode addMaterial_HMHHStVenantKirchhoff (const int tape, const double lambda, const double mu, const double sigma_y)
 
MoFEMErrorCode addMaterial_HMHMooneyRivlin (const int tape, const double alpha, const double beta, const double lambda, const double sigma_y)
 
MoFEMErrorCode addMaterial_HMHNeohookean (const int tape, const double c10, const double K)
 
MoFEMErrorCode addMaterial_Hencky (double E, double nu)
 
MoFEMErrorCode setBaseVolumeElementOps (const int tag, const bool do_rhs, const bool do_lhs, const bool calc_rates, SmartPetscObj< Vec > ver_vec, boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe)
 
MoFEMErrorCode setVolumeElementOps (const int tag, const bool add_elastic, const bool add_material, boost::shared_ptr< VolumeElementForcesAndSourcesCore > &fe_rhs, boost::shared_ptr< VolumeElementForcesAndSourcesCore > &fe_lhs)
 
MoFEMErrorCode setFaceElementOps (const bool add_elastic, const bool add_material, boost::shared_ptr< FaceElementForcesAndSourcesCore > &fe_rhs, boost::shared_ptr< FaceElementForcesAndSourcesCore > &fe_lhs)
 
MoFEMErrorCode setContactElementRhsOps (boost::shared_ptr< ContactTree > &fe_contact_tree)
 
MoFEMErrorCode setElasticElementOps (const int tag)
 
MoFEMErrorCode setElasticElementToTs (DM dm)
 
MoFEMErrorCode solveElastic (TS ts, Vec x)
 
MoFEMErrorCode solveDynamicRelaxation (TS ts, Vec x)
 
MoFEMErrorCode setBlockTagsOnSkin ()
 
MoFEMErrorCode postProcessResults (const int tag, const std::string file, Vec f_residual=PETSC_NULLPTR, Vec var_vec=PETSC_NULLPTR, std::vector< Tag > tags_to_transfer={})
 
MoFEMErrorCode postProcessSkeletonResults (const int tag, const std::string file, Vec f_residual=PETSC_NULLPTR, std::vector< Tag > tags_to_transfer={})
 
MoFEMErrorCode calculateCrackArea (boost::shared_ptr< double > area_ptr)
 
MoFEMErrorCode gettingNorms ()
 [Getting norms]
 
MoFEMErrorCode calculateFaceMaterialForce (const int tag, TS ts)
 
MoFEMErrorCode calculateOrientation (const int tag, bool set_orientation)
 
MoFEMErrorCode setNewFrontCoordinates ()
 
MoFEMErrorCode addCrackSurfaces (const bool debug=false)
 
MoFEMErrorCode saveOrgCoords ()
 
MoFEMErrorCode createCrackSurfaceMeshset ()
 
- Public Member Functions inherited from MoFEM::UnknownInterface
virtual MoFEMErrorCode query_interface (boost::typeindex::type_index type_index, UnknownInterface **iface) const =0
 
template<class IFACE >
MoFEMErrorCode registerInterface (bool error_if_registration_failed=true)
 Register interface.
 
template<class IFACE >
MoFEMErrorCode getInterface (IFACE *&iface) const
 Get interface reference to pointer of interface.
 
template<class IFACE >
MoFEMErrorCode getInterface (IFACE **const iface) const
 Get interface pointer to pointer of interface.
 
template<class IFACE , typename boost::enable_if< boost::is_pointer< IFACE >, int >::type = 0>
IFACE getInterface () const
 Get interface pointer to pointer of interface.
 
template<class IFACE , typename boost::enable_if< boost::is_reference< IFACE >, int >::type = 0>
IFACE getInterface () const
 Get reference to interface.
 
template<class IFACE >
IFACE * getInterface () const
 Function returning pointer to interface.
 
virtual ~UnknownInterface ()=default
 

Static Public Member Functions

static double f_log_e_quadratic (const double v)
 
static double d_f_log_e_quadratic (const double v)
 
static double dd_f_log_e_quadratic (const double v)
 
static double f_log_e (const double v)
 
static double d_f_log_e (const double v)
 
static double dd_f_log_e (const double v)
 
static double inv_f_log_e (const double v)
 
static double inv_d_f_log_e (const double v)
 
static double inv_dd_f_log_e (const double v)
 
static double f_log (const double v)
 
static double d_f_log (const double v)
 
static double dd_f_log (const double v)
 
static double inv_f_log (const double v)
 
static double inv_d_f_log (const double v)
 
static double inv_dd_f_log (const double v)
 
static double f_linear (const double v)
 
static double d_f_linear (const double v)
 
static double dd_f_linear (const double v)
 
static double inv_f_linear (const double v)
 
static double inv_d_f_linear (const double v)
 
static double inv_dd_f_linear (const double v)
 
- Static Public Member Functions inherited from MoFEM::UnknownInterface
static MoFEMErrorCode getLibVersion (Version &version)
 Get library version.
 
static MoFEMErrorCode getFileVersion (moab::Interface &moab, Version &version)
 Get database major version.
 
static MoFEMErrorCode setFileVersion (moab::Interface &moab, Version version=Version(MoFEM_VERSION_MAJOR, MoFEM_VERSION_MINOR, MoFEM_VERSION_BUILD))
 Get database major version.
 
static MoFEMErrorCode getInterfaceVersion (Version &version)
 Get database major version.
 

Public Attributes

MoFEM::InterfacemField
 
boost::shared_ptr< DataAtIntegrationPtsdataAtPts
 
boost::shared_ptr< PhysicalEquations > physicalEquations
 
boost::shared_ptr< AnalyticalExprPython > AnalyticalExprPythonPtr
 
boost::shared_ptr< VolumeElementForcesAndSourcesCore > elasticFeRhs
 
boost::shared_ptr< VolumeElementForcesAndSourcesCore > elasticFeLhs
 
boost::shared_ptr< FaceElementForcesAndSourcesCoreelasticBcLhs
 
boost::shared_ptr< FaceElementForcesAndSourcesCoreelasticBcRhs
 
boost::shared_ptr< ContactTree > contactTreeRhs
 Make a contact tree.
 
SmartPetscObj< DM > dM
 Coupled problem all fields.
 
SmartPetscObj< DM > dmElastic
 Elastic problem.
 
SmartPetscObj< DM > dmMaterial
 Material problem.
 
SmartPetscObj< DM > dmPrjSpatial
 Projection spatial displacement.
 
const std::string piolaStress = "P"
 
const std::string spatialL2Disp = "wL2"
 
const std::string spatialH1Disp = "wH1"
 
const std::string materialH1Positions = "XH1"
 
const std::string hybridSpatialDisp = "hybridSpatialDisp"
 
const std::string contactDisp = "contactDisp"
 
const std::string stretchTensor = "u"
 
const std::string rotAxis = "omega"
 
const std::string bubbleField = "bubble"
 
const std::string elementVolumeName = "EP"
 
const std::string naturalBcElement = "NATURAL_BC"
 
const std::string skinElement = "SKIN"
 
const std::string skeletonElement = "SKELETON"
 
const std::string contactElement = "CONTACT"
 
int spaceOrder = 2
 
int spaceH1Order = -1
 
int materialOrder = 1
 
double alphaU = 0
 
double alphaW = 0
 
double alphaOmega = 0
 
double alphaRho = 0
 
int contactRefinementLevels = 1
 
int frontLayers = 3
 
boost::shared_ptr< BcDispVec > bcSpatialDispVecPtr
 
boost::shared_ptr< BcRotVec > bcSpatialRotationVecPtr
 
boost::shared_ptr< TractionBcVec > bcSpatialTractionVecPtr
 
boost::shared_ptr< TractionFreeBc > bcSpatialFreeTractionVecPtr
 
boost::shared_ptr< NormalDisplacementBcVec > bcSpatialNormalDisplacementVecPtr
 
boost::shared_ptr< AnalyticalDisplacementBcVec > bcSpatialAnalyticalDisplacementVecPtr
 
boost::shared_ptr< AnalyticalTractionBcVec > bcSpatialAnalyticalTractionVecPtr
 
boost::shared_ptr< PressureBcVec > bcSpatialPressureVecPtr
 
boost::shared_ptr< ExternalStrainVec > externalStrainVecPtr
 
std::map< std::string, boost::shared_ptr< ScalingMethod > > timeScaleMap
 
boost::shared_ptr< RangecontactFaces
 
boost::shared_ptr< RangecrackFaces
 
boost::shared_ptr< RangefrontEdges
 
boost::shared_ptr< RangefrontAdjEdges
 
boost::shared_ptr< RangefrontVertices
 
boost::shared_ptr< RangeskeletonFaces
 
boost::shared_ptr< RangematerialSkeletonFaces
 
boost::shared_ptr< RangemaxMovedFaces
 
boost::shared_ptr< ParentFiniteElementAdjacencyFunctionSkeleton< 2 > > parentAdjSkeletonFunctionDim2
 
BitRefLevel bitAdjParent = BitRefLevel().set()
 bit ref level for parent
 
BitRefLevel bitAdjParentMask
 bit ref level for parent parent
 
BitRefLevel bitAdjEnt = BitRefLevel().set()
 bit ref level for parent
 
BitRefLevel bitAdjEntMask
 bit ref level for parent parent
 
SmartPetscObj< Vec > solTSStep
 
CommInterface::EntitiesPetscVector volumeExchange
 
CommInterface::EntitiesPetscVector faceExchange
 
CommInterface::EntitiesPetscVector edgeExchange
 
CommInterface::EntitiesPetscVector vertexExchange
 
std::vector< TaglistTagsToTransfer
 list of tags to transfer to postprocessor
 
Mat S = PETSC_NULLPTR
 
AO aoS = PETSC_NULLPTR
 
SmartPetscObj< IS > crackHybridIs
 
std::vector< std::string > a00FieldList
 
std::vector< boost::shared_ptr< Range > > a00RangeList
 
int nbCrackFaces = 0
 

Static Public Attributes

static enum SymmetrySelector symmetrySelector = NOT_SYMMETRIC
 
static enum RotSelector rotSelector = LARGE_ROT
 
static enum RotSelector gradApproximator = LARGE_ROT
 
static enum StretchSelector stretchSelector = LOG
 
static PetscBool noStretch = PETSC_FALSE
 
static PetscBool setSingularity = PETSC_TRUE
 
static PetscBool dynamicRelaxation
 
static PetscBool crackingOn = PETSC_FALSE
 
static double crackingStartTime = 0
 
static int nbJIntegralLevels
 
static double dynamicTime
 
static int dynamicStep
 
static PetscBool l2UserBaseScale = PETSC_TRUE
 
static int addCrackMeshsetId = 1000
 
static double griffithEnergy = 1
 Griffith energy.
 
static enum EnergyReleaseSelector energyReleaseSelector
 
static std::string internalStressTagName
 
static int internalStressInterpOrder
 
static PetscBool internalStressVoigt
 
static double exponentBase = exp(1)
 
static boost::function< double(const double)> f = EshelbianCore::f_log_e
 
static boost::function< double(const double)> d_f
 
static boost::function< double(const double)> dd_f
 
static boost::function< double(const double)> inv_f
 
static boost::function< double(const double)> inv_d_f
 
static boost::function< double(const double)> inv_dd_f
 
static constexpr bool use_quadratic_exp = true
 
static constexpr double v_max = 12
 
static constexpr double v_min = -v_max
 

Friends

struct solve_elastic_set_up
 

Detailed Description

Examples
EshelbianPlasticity.cpp, and ep.cpp.

Definition at line 12 of file EshelbianCore.hpp.

Constructor & Destructor Documentation

◆ EshelbianCore()

EshelbianCore::EshelbianCore ( MoFEM::Interface m_field)
Examples
EshelbianPlasticity.cpp.

Definition at line 916 of file EshelbianPlasticity.cpp.

916 : mField(m_field) {
917 CHK_THROW_MESSAGE(getOptions(), "getOptions failed");
918}
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
MoFEM::Interface & mField
MoFEMErrorCode getOptions()

◆ ~EshelbianCore()

EshelbianCore::~EshelbianCore ( )
virtualdefault

Member Function Documentation

◆ addBoundaryFiniteElement()

MoFEMErrorCode EshelbianCore::addBoundaryFiniteElement ( const EntityHandle  meshset = 0)
Examples
EshelbianPlasticity.cpp, and ep.cpp.

Definition at line 1583 of file EshelbianPlasticity.cpp.

1583 {
1585
1586 Range meshset_ents;
1587 CHKERR mField.get_moab().get_entities_by_handle(meshset, meshset_ents);
1588
1589 auto set_fe_adjacency = [&](auto fe_name) {
1592 boost::make_shared<ParentFiniteElementAdjacencyFunctionSkeleton<2>>(
1595 fe_name, MBTRI, *parentAdjSkeletonFunctionDim2);
1597 };
1598
1599 // set finite element fields
1600 auto add_field_to_fe = [this](const std::string fe,
1601 const std::string field_name) {
1608 };
1609
1611
1612 Range natural_bc_elements;
1613 if (bcSpatialDispVecPtr) {
1614 for (auto &v : *bcSpatialDispVecPtr) {
1615 natural_bc_elements.merge(v.faces);
1616 }
1617 }
1619 for (auto &v : *bcSpatialRotationVecPtr) {
1620 natural_bc_elements.merge(v.faces);
1621 }
1622 }
1624 for (auto &v : *bcSpatialNormalDisplacementVecPtr) {
1625 natural_bc_elements.merge(v.faces);
1626 }
1627 }
1630 natural_bc_elements.merge(v.faces);
1631 }
1632 }
1634 for (auto &v : *bcSpatialTractionVecPtr) {
1635 natural_bc_elements.merge(v.faces);
1636 }
1637 }
1639 for (auto &v : *bcSpatialAnalyticalTractionVecPtr) {
1640 natural_bc_elements.merge(v.faces);
1641 }
1642 }
1644 for (auto &v : *bcSpatialPressureVecPtr) {
1645 natural_bc_elements.merge(v.faces);
1646 }
1647 }
1648 natural_bc_elements = intersect(natural_bc_elements, meshset_ents);
1649
1651 CHKERR mField.add_ents_to_finite_element_by_type(natural_bc_elements, MBTRI,
1653 CHKERR add_field_to_fe(naturalBcElement, piolaStress);
1654 CHKERR add_field_to_fe(naturalBcElement, hybridSpatialDisp);
1655 CHKERR set_fe_adjacency(naturalBcElement);
1657 }
1658
1659 auto get_skin = [&](auto &body_ents) {
1660 Skinner skin(&mField.get_moab());
1661 Range skin_ents;
1662 CHKERR skin.find_skin(0, body_ents, false, skin_ents);
1663 return skin_ents;
1664 };
1665
1666 auto filter_true_skin = [&](auto &&skin) {
1667 Range boundary_ents;
1668 ParallelComm *pcomm =
1669 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
1670 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
1671 PSTATUS_NOT, -1, &boundary_ents);
1672 return boundary_ents;
1673 };
1674
1676
1677 Range body_ents;
1678 CHKERR mField.get_moab().get_entities_by_dimension(meshset, SPACE_DIM,
1679 body_ents);
1680 auto skin = filter_true_skin(get_skin(body_ents));
1681
1689 contactDisp);
1692 // CHKERR add_field_to_fe(skinElement, hybridSpatialDisp);
1693 // CHKERR add_field_to_fe(skinElement, hybridMaterialDisp);
1694
1696 }
1697
1699 if (contactFaces) {
1700 MOFEM_LOG("EP", Sev::inform)
1701 << "Contact elements " << contactFaces->size();
1705 CHKERR add_field_to_fe(contactElement, piolaStress);
1706 CHKERR add_field_to_fe(contactElement, hybridSpatialDisp);
1707 CHKERR add_field_to_fe(contactElement, contactDisp);
1708 CHKERR add_field_to_fe(contactElement, spatialH1Disp);
1709 CHKERR set_fe_adjacency(contactElement);
1711 }
1712 }
1713
1715 if (!skeletonFaces)
1716 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "No skeleton faces");
1717 MOFEM_LOG("EP", Sev::inform)
1718 << "Skeleton elements " << skeletonFaces->size();
1722 CHKERR add_field_to_fe(skeletonElement, piolaStress);
1723 CHKERR add_field_to_fe(skeletonElement, hybridSpatialDisp);
1724 CHKERR add_field_to_fe(skeletonElement, contactDisp);
1725 CHKERR add_field_to_fe(skeletonElement, spatialH1Disp);
1726 CHKERR set_fe_adjacency(skeletonElement);
1728 }
1729
1730 // if (!mField.check_finite_element(materialSkeletonElement)) {
1731
1732 // Range front_edges = get_range_from_block(mField, "FRONT", SPACE_DIM -
1733 // 2);
1734
1735 // Range front_elements;
1736 // for (auto l = 0; l != frontLayers; ++l) {
1737 // Range front_elements_layer;
1738 // CHKERR mField.get_moab().get_adjacencies(front_edges, SPACE_DIM,
1739 // true,
1740 // front_elements_layer,
1741 // moab::Interface::UNION);
1742 // front_elements.merge(front_elements_layer);
1743 // front_edges.clear();
1744 // CHKERR mField.get_moab().get_adjacencies(front_elements_layer,
1745 // SPACE_DIM - 2, true,
1746 // front_edges,
1747 // moab::Interface::UNION);
1748 // }
1749 // Range body_ents;
1750 // CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
1751 // body_ents); Range front_elements_faces; CHKERR
1752 // mField.get_moab().get_adjacencies(front_elements, SPACE_DIM - 1,
1753 // true, front_elements_faces,
1754 // moab::Interface::UNION);
1755 // auto body_skin = filter_true_skin(get_skin(body_ents));
1756 // auto front_elements_skin = filter_true_skin(get_skin(front_elements));
1757 // Range material_skeleton_faces =
1758 // subtract(front_elements_faces, front_elements_skin);
1759 // material_skeleton_faces.merge(intersect(front_elements_skin,
1760 // body_skin));
1761
1762 // #ifndef NDEBUG
1763 // CHKERR save_range(mField.get_moab(), "front_elements.vtk",
1764 // front_elements); CHKERR save_range(mField.get_moab(),
1765 // "front_elements_skin.vtk",
1766 // front_elements_skin);
1767 // CHKERR save_range(mField.get_moab(), "material_skeleton_faces.vtk",
1768 // material_skeleton_faces);
1769 // #endif
1770
1771 // CHKERR mField.add_finite_element(materialSkeletonElement, MF_ZERO);
1772 // CHKERR mField.add_ents_to_finite_element_by_type(
1773 // material_skeleton_faces, MBTRI, materialSkeletonElement);
1774 // // CHKERR add_field_to_fe(materialSkeletonElement, eshelbyStress);
1775 // // CHKERR add_field_to_fe(materialSkeletonElement, hybridMaterialDisp);
1776 // CHKERR set_fe_adjacency(materialSkeletonElement);
1777 // CHKERR mField.build_finite_elements(materialSkeletonElement);
1778 // }
1779
1781}
static auto filter_true_skin(MoFEM::Interface &m_field, Range &&skin)
static auto get_skin(MoFEM::Interface &m_field, Range body_ents)
constexpr int SPACE_DIM
@ MF_ZERO
#define MYPCOMM_INDEX
default communicator number PCOMM
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
virtual MoFEMErrorCode add_finite_element(const std::string &fe_name, enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
add finite element
virtual MoFEMErrorCode build_finite_elements(int verb=DEFAULT_VERBOSITY)=0
Build finite elements.
virtual MoFEMErrorCode modify_finite_element_add_field_col(const std::string &fe_name, const std::string name_row)=0
set field col which finite element use
virtual MoFEMErrorCode modify_finite_element_adjacency_table(const std::string &fe_name, const EntityType type, ElementAdjacencyFunct function)=0
modify finite element table, only for advanced user
virtual MoFEMErrorCode add_ents_to_finite_element_by_type(const EntityHandle entities, const EntityType type, const std::string name, const bool recursive=true)=0
add entities to finite element
virtual MoFEMErrorCode modify_finite_element_add_field_row(const std::string &fe_name, const std::string name_row)=0
set field row which finite element use
virtual MoFEMErrorCode modify_finite_element_add_field_data(const std::string &fe_name, const std::string name_field)=0
set finite element field data
#define MOFEM_LOG(channel, severity)
Log.
const double v
phase velocity of light in medium (cm/ns)
constexpr auto field_name
const std::string skeletonElement
boost::shared_ptr< TractionBcVec > bcSpatialTractionVecPtr
boost::shared_ptr< Range > contactFaces
BitRefLevel bitAdjEnt
bit ref level for parent
const std::string materialH1Positions
boost::shared_ptr< BcRotVec > bcSpatialRotationVecPtr
const std::string spatialH1Disp
boost::shared_ptr< NormalDisplacementBcVec > bcSpatialNormalDisplacementVecPtr
const std::string piolaStress
boost::shared_ptr< AnalyticalDisplacementBcVec > bcSpatialAnalyticalDisplacementVecPtr
boost::shared_ptr< ParentFiniteElementAdjacencyFunctionSkeleton< 2 > > parentAdjSkeletonFunctionDim2
boost::shared_ptr< Range > skeletonFaces
BitRefLevel bitAdjParentMask
bit ref level for parent parent
const std::string contactDisp
boost::shared_ptr< BcDispVec > bcSpatialDispVecPtr
const std::string skinElement
boost::shared_ptr< AnalyticalTractionBcVec > bcSpatialAnalyticalTractionVecPtr
BitRefLevel bitAdjParent
bit ref level for parent
const std::string naturalBcElement
boost::shared_ptr< PressureBcVec > bcSpatialPressureVecPtr
const std::string hybridSpatialDisp
BitRefLevel bitAdjEntMask
bit ref level for parent parent
const std::string contactElement
virtual moab::Interface & get_moab()=0
virtual bool check_finite_element(const std::string &name) const =0
Check if finite element is in database.
virtual MPI_Comm & get_comm() const =0

◆ addCrackSurfaces()

MoFEMErrorCode EshelbianCore::addCrackSurfaces ( const bool  debug = false)
Examples
EshelbianPlasticity.cpp.

Definition at line 5998 of file EshelbianPlasticity.cpp.

5998 {
6000
6001 constexpr bool potential_crack_debug = false;
6002 if constexpr (potential_crack_debug) {
6003
6004 auto add_ents = get_range_from_block(mField, "POTENTIAL", SPACE_DIM - 1);
6005 Range crack_front_verts;
6006 CHKERR mField.get_moab().get_connectivity(*frontEdges, crack_front_verts,
6007 true);
6008 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
6009 crack_front_verts);
6010 Range crack_front_faces;
6011 CHKERR mField.get_moab().get_adjacencies(crack_front_verts, SPACE_DIM - 1,
6012 true, crack_front_faces,
6013 moab::Interface::UNION);
6014 crack_front_faces = intersect(crack_front_faces, add_ents);
6015 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
6016 crack_front_faces);
6017 CHKERR mField.getInterface<MeshsetsManager>()->addEntitiesToMeshset(
6018 BLOCKSET, addCrackMeshsetId, crack_front_faces);
6019 }
6020
6021 auto get_crack_faces = [&]() {
6022 if (maxMovedFaces) {
6023 return unite(*crackFaces, *maxMovedFaces);
6024 } else {
6025 return *crackFaces;
6026 }
6027 };
6028
6029 auto get_extended_crack_faces = [&]() {
6030 auto get_faces_of_crack_front_verts = [&](auto crack_faces_org) {
6031 ParallelComm *pcomm =
6032 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
6033
6034 Range crack_faces;
6035
6036 if (!pcomm->rank()) {
6037
6038 auto get_nodes = [&](auto &&e) {
6039 Range nodes;
6040 CHK_MOAB_THROW(mField.get_moab().get_connectivity(e, nodes, true),
6041 "get connectivity");
6042 return nodes;
6043 };
6044
6045 auto get_adj = [&](auto &&e, auto dim,
6046 auto t = moab::Interface::UNION) {
6047 Range adj;
6049 mField.get_moab().get_adjacencies(e, dim, true, adj, t),
6050 "get adj");
6051 return adj;
6052 };
6053
6054 Range body_ents;
6055 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
6056 body_ents);
6057 auto body_skin = get_skin(mField, body_ents);
6058 auto body_skin_edges = get_adj(body_skin, 1, moab::Interface::UNION);
6059 auto geometry_edges = get_range_from_block(mField, "EDGES", 1);
6060 auto front_block_edges = get_range_from_block(mField, "FRONT", 1);
6061 auto front_block_nodes = get_nodes(front_block_edges);
6062
6063 size_t s;
6064 do {
6065 s = crack_faces.size();
6066
6067 auto crack_face_nodes = get_nodes(crack_faces_org);
6068 auto crack_faces_edges =
6069 get_adj(crack_faces_org, 1, moab::Interface::UNION);
6070
6071 auto crack_skin = get_skin(mField, crack_faces_org);
6072 front_block_edges = subtract(front_block_edges, crack_skin);
6073 auto crack_skin_nodes = get_nodes(crack_skin);
6074 crack_skin_nodes.merge(front_block_nodes);
6075
6076 auto crack_skin_faces =
6077 get_adj(crack_skin, 2, moab::Interface::UNION);
6078 crack_skin_faces =
6079 subtract(subtract(crack_skin_faces, crack_faces_org), body_skin);
6080
6081 crack_faces = crack_faces_org;
6082 for (auto f : crack_skin_faces) {
6083 auto edges = intersect(
6084 get_adj(Range(f, f), 1, moab::Interface::UNION), crack_skin);
6085
6086 // if other edge is part of body skin, e.g. crack punching through
6087 // body surface
6088 if (edges.size() == 2) {
6089 edges.merge(
6090 intersect(get_adj(Range(f, f), 1, moab::Interface::UNION),
6091 body_skin_edges));
6092 }
6093
6094 if (edges.size() == 2) {
6095 auto edge_conn = get_nodes(Range(edges));
6096 auto faces = intersect(get_adj(edges, 2, moab::Interface::UNION),
6097 crack_faces_org);
6098 if (faces.size() == 2) {
6099 auto edge0_conn = get_nodes(Range(edges[0], edges[0]));
6100 auto edge1_conn = get_nodes(Range(edges[1], edges[1]));
6101 auto edges_conn = intersect(intersect(edge0_conn, edge1_conn),
6102 crack_skin_nodes); // node at apex
6103 if (edges_conn.size() == 1) {
6104
6105 auto node_edges =
6106 subtract(intersect(get_adj(edges_conn, 1,
6107 moab::Interface::INTERSECT),
6108 crack_faces_edges),
6109 crack_skin); // nodes on crack surface, but not
6110 // at the skin
6111
6112 if (node_edges.size()) {
6115 CHKERR mField.get_moab().get_coords(edges_conn, &t_v0(0));
6116
6117 auto get_t_dir = [&](auto e_conn) {
6118 auto other_node = subtract(e_conn, edges_conn);
6120 CHKERR mField.get_moab().get_coords(other_node,
6121 &t_dir(0));
6122 t_dir(i) -= t_v0(i);
6123 return t_dir;
6124 };
6125
6127 t_ave_dir(i) =
6128 get_t_dir(edge0_conn)(i) + get_t_dir(edge1_conn)(i);
6129
6130 FTensor::Tensor1<double, SPACE_DIM> t_crack_surface_ave_dir;
6131 t_crack_surface_ave_dir(i) = 0;
6132 for (auto e : node_edges) {
6133 auto e_conn = get_nodes(Range(e, e));
6134 auto t_dir = get_t_dir(e_conn);
6135 t_crack_surface_ave_dir(i) += t_dir(i);
6136 }
6137
6138 auto dot = t_ave_dir(i) * t_crack_surface_ave_dir(i);
6139 // ave edges is in opposite direction to crack surface, so
6140 // thus crack is not turning back
6141 if (dot < -std::numeric_limits<double>::epsilon()) {
6142 crack_faces.insert(f);
6143 }
6144 } else {
6145 crack_faces.insert(f);
6146 }
6147 }
6148 }
6149 } else if (edges.size() == 3) {
6150 crack_faces.insert(f);
6151 }
6152
6153 // if other edge is part of geometry edge, e.g. keyway
6154 if (edges.size() == 1) {
6155 edges.merge(
6156 intersect(get_adj(Range(f, f), 1, moab::Interface::UNION),
6157 geometry_edges));
6158 edges.merge(
6159 intersect(get_adj(Range(f, f), 1, moab::Interface::UNION),
6160 front_block_edges));
6161 if (edges.size() == 2) {
6162 crack_faces.insert(f);
6163 continue;
6164 }
6165 }
6166 }
6167
6168 crack_faces_org = crack_faces;
6169
6170 } while (s != crack_faces.size());
6171 };
6172
6173 return crack_faces; // send_type(mField, crack_faces, MBTRI);
6174 };
6175
6176 return get_faces_of_crack_front_verts(get_crack_faces());
6177 };
6178
6179 if (debug) {
6180 CHKERR save_range(mField.get_moab(), "new_crack_surface_debug.vtk",
6181 get_extended_crack_faces());
6182 }
6183
6184 auto reconstruct_crack_faces = [&](auto crack_faces) {
6185 ParallelComm *pcomm =
6186 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
6187
6188 auto impl = [&]() {
6190
6191 Range new_crack_faces;
6192 if (!pcomm->rank()) {
6193
6194 auto get_nodes = [&](auto &&e) {
6195 Range nodes;
6196 CHK_MOAB_THROW(mField.get_moab().get_connectivity(e, nodes, true),
6197 "get connectivity");
6198 return nodes;
6199 };
6200
6201 auto get_adj = [&](auto &&e, auto dim,
6202 auto t = moab::Interface::UNION) {
6203 Range adj;
6205 mField.get_moab().get_adjacencies(e, dim, true, adj, t),
6206 "get adj");
6207 return adj;
6208 };
6209
6210 auto get_test_on_crack_surface = [&]() {
6211 auto crack_faces_nodes =
6212 get_nodes(crack_faces); // nodes on crac faces
6213 auto crack_faces_tets =
6214 get_adj(crack_faces_nodes, 3,
6215 moab::Interface::UNION); // adjacent
6216 // tets to
6217 // crack
6218 // faces throug nodes
6219 auto crack_faces_tets_nodes =
6220 get_nodes(crack_faces_tets); // nodes on crack faces tets
6221 crack_faces_tets_nodes =
6222 subtract(crack_faces_tets_nodes, crack_faces_nodes);
6223 crack_faces_tets =
6224 subtract(crack_faces_tets, get_adj(crack_faces_tets_nodes, 3,
6225 moab::Interface::UNION));
6226 new_crack_faces =
6227 get_adj(crack_faces_tets, 2,
6228 moab::Interface::UNION); // adjacency faces to crack
6229 // faces through tets
6230 new_crack_faces.merge(crack_faces); // add original crack faces
6231
6232 return std::make_tuple(new_crack_faces, crack_faces_tets);
6233 };
6234
6235 auto carck_faces_test_edges = [&](auto faces, auto tets) {
6236 auto adj_tets_faces = get_adj(tets, 2, moab::Interface::UNION);
6237 auto adj_faces_edges = get_adj(subtract(faces, adj_tets_faces), 1,
6238 moab::Interface::UNION);
6239 auto adj_tets_edges = get_adj(tets, 1, moab::Interface::UNION);
6240 auto geometry_edges = get_range_from_block(mField, "EDGES", 1);
6241 auto front_block_edges = get_range_from_block(mField, "FRONT", 1);
6242 adj_faces_edges.merge(geometry_edges); // geometry edges
6243 adj_faces_edges.merge(front_block_edges); // front block edges
6244
6245 auto boundary_tets_edges = intersect(adj_tets_edges, adj_faces_edges);
6246 auto boundary_test_nodes = get_nodes(boundary_tets_edges);
6247 auto boundary_test_nodes_edges =
6248 get_adj(boundary_test_nodes, 1, moab::Interface::UNION);
6249 auto boundary_test_nodes_edges_nodes = subtract(
6250 get_nodes(boundary_test_nodes_edges), boundary_test_nodes);
6251
6252 boundary_tets_edges =
6253 subtract(boundary_test_nodes_edges,
6254 get_adj(boundary_test_nodes_edges_nodes, 1,
6255 moab::Interface::UNION));
6256
6257 Range body_ents;
6258 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
6259 body_ents);
6260 auto body_skin = get_skin(mField, body_ents);
6261
6262 auto body_skin_edges = get_adj(body_skin, 1, moab::Interface::UNION);
6263 body_skin_edges = intersect(get_adj(tets, 1, moab::Interface::UNION),
6264 body_skin_edges);
6265 body_skin = intersect(body_skin, adj_tets_faces);
6266 body_skin_edges = subtract(
6267 body_skin_edges, get_adj(body_skin, 1, moab::Interface::UNION));
6268
6269 save_range(mField.get_moab(), "body_skin_edges.vtk", body_skin_edges);
6270 for (auto e : body_skin_edges) {
6271 auto adj_tet = intersect(
6272 get_adj(Range(e, e), 3, moab::Interface::INTERSECT), tets);
6273 if (adj_tet.size() == 1) {
6274 boundary_tets_edges.insert(e);
6275 }
6276 }
6277
6278 return boundary_tets_edges;
6279 };
6280
6281 auto p = get_test_on_crack_surface();
6282 auto &[new_crack_faces, crack_faces_tets] = p;
6283
6284 if (debug) {
6285 CHKERR save_range(mField.get_moab(), "hole_crack_faces_debug.vtk",
6286 crack_faces);
6287 CHKERR save_range(mField.get_moab(), "new_crack_faces_debug.vtk",
6288 new_crack_faces);
6289 CHKERR save_range(mField.get_moab(), "new_crack_tets_debug.vtk",
6290 crack_faces_tets);
6291 }
6292
6293 auto boundary_tets_edges =
6294 carck_faces_test_edges(new_crack_faces, crack_faces_tets);
6295 CHKERR save_range(mField.get_moab(), "boundary_tets_edges.vtk",
6296 boundary_tets_edges);
6297
6298 auto resolve_surface = [&](auto boundary_tets_edges,
6299 auto crack_faces_tets) {
6300 auto boundary_tets_edges_nodes = get_nodes(boundary_tets_edges);
6301 auto crack_faces_tets_faces =
6302 get_adj(crack_faces_tets, 2, moab::Interface::UNION);
6303
6304 Range all_removed_faces;
6305 Range all_removed_tets;
6306 int counter = 0;
6307
6308 int size = 0;
6309 while (size != crack_faces_tets.size()) {
6310 auto tets_faces =
6311 get_adj(crack_faces_tets, 2, moab::Interface::UNION);
6312 auto skin_tets = get_skin(mField, crack_faces_tets);
6313 auto skin_skin =
6314 get_skin(mField, subtract(crack_faces_tets_faces, tets_faces));
6315 auto skin_skin_nodes = get_nodes(skin_skin);
6316
6317 size = crack_faces_tets.size();
6318 MOFEM_LOG("SELF", Sev::inform)
6319 << "Crack faces tets size " << crack_faces_tets.size()
6320 << " crack faces size " << crack_faces_tets_faces.size();
6321 auto skin_tets_nodes = subtract(
6322 get_nodes(skin_tets),
6323 boundary_tets_edges_nodes); // not remove tets which are
6324 // adjagasent to crack faces nodes
6325 skin_tets_nodes = subtract(skin_tets_nodes, skin_skin_nodes);
6326
6327 Range removed_nodes;
6328 Range tets_to_remove;
6329 Range faces_to_remove;
6330 for (auto n : skin_tets_nodes) {
6331 auto tets =
6332 intersect(get_adj(Range(n, n), 3, moab::Interface::INTERSECT),
6333 crack_faces_tets);
6334 if (tets.size() == 0) {
6335 continue;
6336 }
6337
6338 auto hole_detetction = [&]() {
6339 auto adj_tets =
6340 get_adj(Range(n, n), 3, moab::Interface::INTERSECT);
6341 adj_tets =
6342 subtract(adj_tets,
6343 crack_faces_tets); // tetst adjacent to the node
6344 // but not part of crack surface
6345 if (adj_tets.size() == 0) {
6346 return std::make_pair(
6347 intersect(
6348 get_adj(Range(n, n), 2, moab::Interface::INTERSECT),
6349 tets_faces),
6350 tets);
6351 }
6352
6353 std::vector<Range> tets_groups;
6354 auto test_adj_tets = adj_tets;
6355 while (test_adj_tets.size()) {
6356 auto seed_size = 0;
6357 Range seed = Range(test_adj_tets[0], test_adj_tets[0]);
6358 while (seed.size() != seed_size) {
6359 auto adj_faces =
6360 subtract(get_adj(seed, 2, moab::Interface::UNION),
6361 tets_faces); // edges which are not
6362 // part of the node
6363 seed_size = seed.size();
6364 seed.merge(
6365 intersect(get_adj(adj_faces, 3, moab::Interface::UNION),
6366 test_adj_tets ));
6367 }
6368 tets_groups.push_back(seed);
6369 test_adj_tets = subtract(test_adj_tets, seed);
6370 }
6371 if (tets_groups.size() == 1) {
6372
6373 return std::make_pair(
6374 intersect(
6375 get_adj(Range(n, n), 2, moab::Interface::INTERSECT),
6376 tets_faces),
6377 tets);
6378
6379 }
6380
6381 Range tets_to_remove;
6382 Range faces_to_remove;
6383 for (auto &r : tets_groups) {
6384 auto f = get_adj(r, 2, moab::Interface::UNION);
6385 auto t = intersect(get_adj(f, 3, moab::Interface::UNION),
6386 crack_faces_tets); // tets
6387
6388 if (f.size() > faces_to_remove.size() ||
6389 faces_to_remove.size() == 0) {
6390 faces_to_remove = f;
6391 tets_to_remove = t; // largest group of tets
6392 }
6393 }
6394 MOFEM_LOG("EPSELF", Sev::inform)
6395 << "Hole detection: faces to remove "
6396 << faces_to_remove.size() << " tets to remove "
6397 << tets_to_remove.size();
6398 return std::make_pair(faces_to_remove, tets_to_remove);
6399 };
6400
6401 if (tets.size() < tets_to_remove.size() ||
6402 tets_to_remove.size() == 0) {
6403 removed_nodes = Range(n, n);
6404 auto [h_faces_to_remove, h_tets_to_remove] =
6405 hole_detetction(); // find faces and tets to remove
6406 faces_to_remove = h_faces_to_remove;
6407 tets_to_remove = h_tets_to_remove;
6408
6409 // intersect(
6410 // get_adj(Range(n, n), 2, moab::Interface::INTERSECT),
6411 // tets_faces);
6412
6413 } // find tets which is largest adjacencty size, so that it is
6414 // removed first, and then faces are removed
6415 all_removed_faces.merge(faces_to_remove);
6416 all_removed_tets.merge(tets_to_remove);
6417 }
6418
6419 crack_faces_tets = subtract(crack_faces_tets, tets_to_remove);
6420 crack_faces_tets_faces =
6421 subtract(crack_faces_tets_faces, faces_to_remove);
6422
6423 if (debug) {
6425 "removed_nodes_" +
6426 boost::lexical_cast<std::string>(counter) + ".vtk",
6427 removed_nodes);
6429 "faces_to_remove_" +
6430 boost::lexical_cast<std::string>(counter) + ".vtk",
6431 faces_to_remove);
6433 "tets_to_remove_" +
6434 boost::lexical_cast<std::string>(counter) + ".vtk",
6435 tets_to_remove);
6437 "crack_faces_tets_faces_" +
6438 boost::lexical_cast<std::string>(counter) + ".vtk",
6439 crack_faces_tets_faces);
6441 "crack_faces_tets_" +
6442 boost::lexical_cast<std::string>(counter) + ".vtk",
6443 crack_faces_tets);
6444 }
6445 counter++;
6446 }
6447
6448 auto cese_internal_faces = [&]() {
6450 auto skin_tets = get_skin(mField, crack_faces_tets);
6451 auto adj_faces = get_adj(skin_tets, 2, moab::Interface::UNION);
6452 adj_faces =
6453 subtract(adj_faces, skin_tets); // remove skin tets faces
6454 auto adj_tets = get_adj(adj_faces, 3,
6455 moab::Interface::UNION); // tets which are
6456 // adjacent to skin
6457 crack_faces_tets =
6458 subtract(crack_faces_tets,
6459 adj_tets); // remove tets which are adjacent to
6460 // skin, so that they are not removed
6461 crack_faces_tets_faces =
6462 subtract(crack_faces_tets_faces, adj_faces);
6463
6464 all_removed_faces.merge(adj_faces);
6465 all_removed_tets.merge(adj_tets);
6466
6467
6468 MOFEM_LOG("EPSELF", Sev::inform)
6469 << "Remove internal faces size " << adj_faces.size()
6470 << " tets size " << adj_tets.size();
6472 };
6473
6474 auto case_only_one_free_edge = [&]() {
6476
6477 for (auto t : Range(crack_faces_tets)) {
6478
6479 auto adj_faces = get_adj(
6480 Range(t, t), 2,
6481 moab::Interface::UNION); // faces of tet which can be removed
6482 auto crack_surface_edges =
6483 get_adj(subtract(unite(crack_faces_tets_faces, crack_faces),
6484 adj_faces),
6485 1,
6486 moab::Interface::UNION); // edges not on the tet but
6487 // on crack surface
6488 auto adj_edges =
6489 subtract(get_adj(Range(t, t), 1, moab::Interface::INTERSECT),
6490 crack_surface_edges); // free edges
6491 adj_edges = subtract(
6492 adj_edges,
6493 boundary_tets_edges); // edges which are not part of gemetry
6494
6495 if (adj_edges.size() == 1) {
6496 crack_faces_tets =
6497 subtract(crack_faces_tets,
6498 Range(t, t)); // remove tets which are adjacent to
6499 // skin, so that they are not removed
6500
6501 auto faces_to_remove =
6502 get_adj(adj_edges, 2, moab::Interface::UNION); // faces
6503 // which can
6504 // be removed
6505 crack_faces_tets_faces =
6506 subtract(crack_faces_tets_faces, faces_to_remove);
6507
6508 all_removed_faces.merge(faces_to_remove);
6509 all_removed_tets.merge(Range(t, t));
6510
6511 MOFEM_LOG("EPSELF", Sev::inform) << "Remove free one edges ";
6512 }
6513 }
6514
6515 crack_faces_tets = subtract(crack_faces_tets, all_removed_tets);
6516 crack_faces_tets_faces =
6517 subtract(crack_faces_tets_faces, all_removed_faces);
6518
6520 };
6521
6522 auto cese_flat_tet = [&](auto max_adj_edges) {
6524
6525 Range body_ents;
6526 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
6527 body_ents);
6528 auto body_skin = get_skin(mField, body_ents);
6529 auto body_skin_edges =
6530 get_adj(body_skin, 1, moab::Interface::UNION);
6531
6532 for (auto t : Range(crack_faces_tets)) {
6533
6534 auto adj_faces = get_adj(
6535 Range(t, t), 2,
6536 moab::Interface::UNION); // faces of tet which can be removed
6537 auto crack_surface_edges =
6538 get_adj(subtract(unite(crack_faces_tets_faces, crack_faces),
6539 adj_faces),
6540 1,
6541 moab::Interface::UNION); // edges not on the tet but
6542 // on crack surface
6543 auto adj_edges =
6544 subtract(get_adj(Range(t, t), 1, moab::Interface::INTERSECT),
6545 crack_surface_edges); // free edges
6546 adj_edges = subtract(adj_edges, body_skin_edges);
6547
6548 auto tet_edges = get_adj(Range(t, t), 1,
6549 moab::Interface::UNION); // edges of
6550 // tet
6551 tet_edges = subtract(tet_edges, adj_edges);
6552
6553 for (auto e : tet_edges) {
6554 constexpr int opposite_edge[] = {5, 3, 4, 1, 2, 0};
6555 auto get_side = [&](auto e) {
6556 int side, sense, offset;
6558 mField.get_moab().side_number(t, e, side, sense, offset),
6559 "get side number failed");
6560 return side;
6561 };
6562 auto get_side_ent = [&](auto side) {
6563 EntityHandle side_edge;
6565 mField.get_moab().side_element(t, 1, side, side_edge),
6566 "get side failed");
6567 return side_edge;
6568 };
6569 adj_edges.erase(get_side_ent(opposite_edge[get_side(e)]));
6570 }
6571
6572 if (adj_edges.size() <= max_adj_edges) {
6573
6574 double dot = 1;
6575 Range faces_to_remove;
6576 for (auto e : adj_edges) {
6577 auto edge_adj_faces =
6578 get_adj(Range(e, e), 2, moab::Interface::UNION);
6579 edge_adj_faces = intersect(edge_adj_faces, adj_faces);
6580 if (edge_adj_faces.size() != 2) {
6582 "Adj faces size is not 2 for edge " +
6583 boost::lexical_cast<std::string>(e));
6584 }
6585
6586 auto get_normal = [&](auto f) {
6589 mField.getInterface<Tools>()->getTriNormal(f, &t_n(0)),
6590 "get tri normal failed");
6591 return t_n;
6592 };
6593 auto t_n0 = get_normal(edge_adj_faces[0]);
6594 auto t_n1 = get_normal(edge_adj_faces[1]);
6595 auto get_sense = [&](auto f) {
6596 int side, sense, offset;
6597 CHK_MOAB_THROW(mField.get_moab().side_number(t, f, side,
6598 sense, offset),
6599 "get side number failed");
6600 return sense;
6601 };
6602 auto sense0 = get_sense(edge_adj_faces[0]);
6603 auto sense1 = get_sense(edge_adj_faces[1]);
6604 t_n0.normalize();
6605 t_n1.normalize();
6606
6608 auto dot_e = (sense0 * sense1) * t_n0(i) * t_n1(i);
6609 if (dot_e < dot || e == adj_edges[0]) {
6610 dot = dot_e;
6611 faces_to_remove = edge_adj_faces;
6612 }
6613 }
6614
6615 all_removed_faces.merge(faces_to_remove);
6616 all_removed_tets.merge(Range(t, t));
6617
6618 MOFEM_LOG("EPSELF", Sev::inform)
6619 << "Remove free edges on flat tet, with considered nb. of "
6620 "edges "
6621 << adj_edges.size();
6622 }
6623 }
6624
6625 crack_faces_tets = subtract(crack_faces_tets, all_removed_tets);
6626 crack_faces_tets_faces =
6627 subtract(crack_faces_tets_faces, all_removed_faces);
6628
6630 };
6631
6632 CHK_THROW_MESSAGE(case_only_one_free_edge(),
6633 "Case only one free edge failed");
6634 for (auto max_adj_edges : {0, 1, 2, 3}) {
6635 CHK_THROW_MESSAGE(cese_flat_tet(max_adj_edges),
6636 "Case only one free edge failed");
6637 }
6638 CHK_THROW_MESSAGE(cese_internal_faces(),
6639 "Case internal faces failed");
6640
6641 if (debug) {
6643 "crack_faces_tets_faces_" +
6644 boost::lexical_cast<std::string>(counter) + ".vtk",
6645 crack_faces_tets_faces);
6647 "crack_faces_tets_" +
6648 boost::lexical_cast<std::string>(counter) + ".vtk",
6649 crack_faces_tets);
6650 }
6651
6652 return std::make_tuple(crack_faces_tets_faces, crack_faces_tets,
6653 all_removed_faces, all_removed_tets);
6654 };
6655
6656 auto [resolved_faces, resolved_tets, all_removed_faces,
6657 all_removed_tets] =
6658 resolve_surface(boundary_tets_edges, crack_faces_tets);
6659 resolved_faces.merge(subtract(crack_faces, all_removed_faces));
6660 if (debug) {
6661 CHKERR save_range(mField.get_moab(), "resolved_faces.vtk",
6662 resolved_faces);
6663 CHKERR save_range(mField.get_moab(), "resolved_tets.vtk",
6664 resolved_tets);
6665 }
6666
6667 crack_faces = resolved_faces;
6668 }
6669
6671 };
6672
6673 CHK_THROW_MESSAGE(impl(), "resolve new crack surfaces");
6674
6675 return crack_faces; // send_type(mField, crack_faces, MBTRI);
6676 };
6677
6678
6679 auto resolve_consisten_crack_extension = [&]() {
6681 auto crack_meshset =
6682 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
6684 auto meshset = crack_meshset->getMeshset();
6685
6686
6687 if (!mField.get_comm_rank()) {
6688 Range old_crack_faces;
6689 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTRI,
6690 old_crack_faces);
6691 auto extendeded_crack_faces = get_extended_crack_faces();
6692 auto reconstructed_crack_faces =
6693 subtract(reconstruct_crack_faces(extendeded_crack_faces),
6694 subtract(*crackFaces, old_crack_faces));
6695 if (nbCrackFaces >= reconstructed_crack_faces.size()) {
6696 MOFEM_LOG("EPSELF", Sev::warning)
6697 << "No new crack faces to add, skipping adding to meshset";
6698 extendeded_crack_faces = subtract(
6699 extendeded_crack_faces, subtract(*crackFaces, old_crack_faces));
6700 MOFEM_LOG("EPSELF", Sev::inform)
6701 << "Number crack faces size (extended) "
6702 << extendeded_crack_faces.size();
6703 CHKERR mField.get_moab().clear_meshset(&meshset, 1);
6704 CHKERR mField.get_moab().add_entities(meshset, extendeded_crack_faces);
6705 } else {
6706 CHKERR mField.get_moab().clear_meshset(&meshset, 1);
6707 CHKERR mField.get_moab().add_entities(meshset,
6708 reconstructed_crack_faces);
6709 MOFEM_LOG("EPSELF", Sev::inform)
6710 << "Number crack faces size (reconstructed) "
6711 << reconstructed_crack_faces.size();
6712 nbCrackFaces = reconstructed_crack_faces.size();
6713 }
6714 }
6715
6716 Range crack_faces;
6717 if (!mField.get_comm_rank()) {
6718 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTRI,
6719 crack_faces);
6720 }
6721 crack_faces = send_type(mField, crack_faces, MBTRI);
6722 if (mField.get_comm_rank()) {
6723 CHKERR mField.get_moab().clear_meshset(&meshset, 1);
6724 CHKERR mField.get_moab().add_entities(meshset, crack_faces);
6725 }
6726
6728 };
6729
6730 CHKERR resolve_consisten_crack_extension();
6731
6733};
static auto send_type(MoFEM::Interface &m_field, Range r, const EntityType type)
#define FTENSOR_INDEX(DIM, I)
Range get_range_from_block(MoFEM::Interface &m_field, const std::string block_name, int dim)
Definition adjoint.cpp:2579
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
@ BLOCKSET
static const bool debug
FTensor::Index< 'i', SPACE_DIM > i
const double n
refractive index of diffusive medium
static constexpr int edges_conn[]
constexpr double t
plate stiffness
Definition plate.cpp:58
boost::shared_ptr< Range > maxMovedFaces
static boost::function< double(const double)> f
static int addCrackMeshsetId
boost::shared_ptr< Range > crackFaces
boost::shared_ptr< Range > frontEdges
Managing BitRefLevels.
virtual int get_comm_rank() const =0
Interface for managing meshsets containing materials and boundary conditions.
Auxiliary tools.
Definition Tools.hpp:19
static MoFEMErrorCode getTriNormal(const double *coords, double *normal, double *d_normal=nullptr)
Get the Tri Normal objectGet triangle normal.
Definition Tools.cpp:353
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
auto save_range

◆ addDMs()

MoFEMErrorCode EshelbianCore::addDMs ( const BitRefLevel  bit = BitRefLevel().set(0),
const EntityHandle  meshset = 0 
)
Examples
EshelbianPlasticity.cpp, and ep.cpp.

Definition at line 1783 of file EshelbianPlasticity.cpp.

1784 {
1786
1787 // find adjacencies between finite elements and dofs
1789
1790 // Create coupled problem
1791 dM = createDM(mField.get_comm(), "DMMOFEM");
1792 CHKERR DMMoFEMCreateMoFEM(dM, &mField, "ESHELBY_PLASTICITY", bit,
1793 BitRefLevel().set());
1794 CHKERR DMMoFEMSetDestroyProblem(dM, PETSC_TRUE);
1795 CHKERR DMMoFEMSetIsPartitioned(dM, PETSC_TRUE);
1801
1802 mField.getInterface<ProblemsManager>()->buildProblemFromFields = PETSC_TRUE;
1803 CHKERR DMSetUp(dM);
1804 mField.getInterface<ProblemsManager>()->buildProblemFromFields = PETSC_FALSE;
1805
1806 auto remove_dofs_on_broken_skin = [&](const std::string prb_name) {
1808 for (int d : {0, 1, 2}) {
1809 std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_to_remove;
1811 ->getSideDofsOnBrokenSpaceEntities(
1812 dofs_to_remove, prb_name, ROW, piolaStress,
1814 // remove piola dofs, i.e. traction free boundary
1815 CHKERR mField.getInterface<ProblemsManager>()->removeDofs(prb_name, ROW,
1816 dofs_to_remove);
1817 CHKERR mField.getInterface<ProblemsManager>()->removeDofs(prb_name, COL,
1818 dofs_to_remove);
1819 }
1821 };
1822 CHKERR remove_dofs_on_broken_skin("ESHELBY_PLASTICITY");
1823
1824 // Create elastic sub-problem
1825 dmElastic = createDM(mField.get_comm(), "DMMOFEM");
1826 CHKERR DMMoFEMCreateSubDM(dmElastic, dM, "ELASTIC_PROBLEM");
1832 if (!noStretch) {
1834 }
1844 CHKERR DMSetUp(dmElastic);
1845
1846 // dmMaterial = createDM(mField.get_comm(), "DMMOFEM");
1847 // CHKERR DMMoFEMCreateSubDM(dmMaterial, dM, "MATERIAL_PROBLEM");
1848 // CHKERR DMMoFEMSetDestroyProblem(dmMaterial, PETSC_TRUE);
1849 // CHKERR DMMoFEMAddSubFieldRow(dmMaterial, eshelbyStress);
1850 // CHKERR DMMoFEMAddSubFieldRow(dmMaterial, materialL2Disp);
1851 // CHKERR DMMoFEMAddElement(dmMaterh elementVolumeName);
1852 // CHKERR DMMoFEMAddElement(dmMaterial, naturalBcElement);
1853 // CHKERR DMMoFEMAddElement(dmMaterial, skinElement);
1854 // CHKERR DMMoFEMSetSquareProblem(dmMaterial, PETSC_TRUE);
1855 // CHKERR DMMoFEMSetIsPartitioned(dmMaterial, PETSC_TRUE);
1856 // CHKERR DMSetUp(dmMaterial);
1857
1858 auto set_zero_block = [&]() {
1860 if (!noStretch) {
1861 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1862 "ELASTIC_PROBLEM", spatialL2Disp, stretchTensor);
1863 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1864 "ELASTIC_PROBLEM", stretchTensor, spatialL2Disp);
1865 }
1866 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1867 "ELASTIC_PROBLEM", spatialL2Disp, rotAxis);
1868 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1869 "ELASTIC_PROBLEM", rotAxis, spatialL2Disp);
1870 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1871 "ELASTIC_PROBLEM", spatialL2Disp, bubbleField);
1872 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1873 "ELASTIC_PROBLEM", bubbleField, spatialL2Disp);
1874 if (!noStretch) {
1875 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1876 "ELASTIC_PROBLEM", bubbleField, bubbleField);
1877 CHKERR
1878 mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1879 "ELASTIC_PROBLEM", piolaStress, piolaStress);
1880 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1881 "ELASTIC_PROBLEM", bubbleField, piolaStress);
1882 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1883 "ELASTIC_PROBLEM", piolaStress, bubbleField);
1884 }
1885
1888 };
1889
1890 auto set_section = [&]() {
1892 PetscSection section;
1893 CHKERR mField.getInterface<ISManager>()->sectionCreate("ELASTIC_PROBLEM",
1894 &section);
1895 CHKERR DMSetSection(dmElastic, section);
1896 CHKERR DMSetGlobalSection(dmElastic, section);
1897 CHKERR PetscSectionDestroy(&section);
1899 };
1900
1901 CHKERR set_zero_block();
1902 CHKERR set_section();
1903
1904 dmPrjSpatial = createDM(mField.get_comm(), "DMMOFEM");
1905 CHKERR DMMoFEMCreateSubDM(dmPrjSpatial, dM, "PROJECT_SPATIAL");
1911 CHKERR DMSetUp(dmPrjSpatial);
1912
1913 // CHKERR mField.getInterface<BcManager>()
1914 // ->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
1915 // "PROJECT_SPATIAL", spatialH1Disp, true, false);
1916
1918}
@ QUIET
@ COL
@ ROW
PetscErrorCode DMMoFEMSetIsPartitioned(DM dm, PetscBool is_partitioned)
Definition DMMoFEM.cpp:1113
PetscErrorCode DMMoFEMCreateSubDM(DM subdm, DM dm, const char problem_name[])
Must be called by user to set Sub DM MoFEM data structures.
Definition DMMoFEM.cpp:215
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
Definition DMMoFEM.cpp:488
PetscErrorCode DMMoFEMSetSquareProblem(DM dm, PetscBool square_problem)
set squared problem
Definition DMMoFEM.cpp:450
PetscErrorCode DMMoFEMCreateMoFEM(DM dm, MoFEM::Interface *m_field_ptr, const char problem_name[], const MoFEM::BitRefLevel bit_level, const MoFEM::BitRefLevel bit_mask=MoFEM::BitRefLevel().set())
Must be called by user to set MoFEM data structures.
Definition DMMoFEM.cpp:114
PetscErrorCode DMMoFEMAddSubFieldRow(DM dm, const char field_name[])
Definition DMMoFEM.cpp:238
auto createDMVector(DM dm)
Get smart vector from DM.
Definition DMMoFEM.hpp:1119
auto bit
set bit
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
Definition Types.hpp:40
PetscErrorCode DMMoFEMSetDestroyProblem(DM dm, PetscBool destroy_problem)
Definition DMMoFEM.cpp:434
auto createDM(MPI_Comm comm, const std::string dm_type_name)
Creates smart DM object.
const std::string spatialL2Disp
SmartPetscObj< DM > dM
Coupled problem all fields.
boost::shared_ptr< TractionFreeBc > bcSpatialFreeTractionVecPtr
const std::string elementVolumeName
const std::string bubbleField
static PetscBool noStretch
const std::string rotAxis
SmartPetscObj< DM > dmPrjSpatial
Projection spatial displacement.
SmartPetscObj< Vec > solTSStep
SmartPetscObj< DM > dmElastic
Elastic problem.
const std::string stretchTensor
virtual MoFEMErrorCode build_adjacencies(const Range &ents, int verb=DEFAULT_VERBOSITY)=0
build adjacencies
Section manager is used to create indexes and sections.
Definition ISManager.hpp:23
Problem manager is used to build and partition problems.

◆ addFields()

MoFEMErrorCode EshelbianCore::addFields ( const EntityHandle  meshset = 0)
Examples
EshelbianPlasticity.cpp, and ep.cpp.

Definition at line 1157 of file EshelbianPlasticity.cpp.

1157 {
1159
1160 auto get_tets = [&]() {
1161 Range tets;
1162 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
1163 return tets;
1164 };
1165
1166 auto get_tets_skin = [&]() {
1167 Range tets_skin_part;
1168 Skinner skin(&mField.get_moab());
1169 CHKERR skin.find_skin(0, get_tets(), false, tets_skin_part);
1170 ParallelComm *pcomm =
1171 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
1172 Range tets_skin;
1173 CHKERR pcomm->filter_pstatus(tets_skin_part,
1174 PSTATUS_SHARED | PSTATUS_MULTISHARED,
1175 PSTATUS_NOT, -1, &tets_skin);
1176 return tets_skin;
1177 };
1178
1179 auto subtract_boundary_conditions = [&](auto &&tets_skin) {
1180 // That mean, that hybrid field on all faces on which traction is applied,
1181 // on other faces, or enforcing displacements as
1182 // natural boundary condition.
1184 for (auto &v : *bcSpatialTractionVecPtr) {
1185 tets_skin = subtract(tets_skin, v.faces);
1186 }
1188 for (auto &v : *bcSpatialAnalyticalTractionVecPtr) {
1189 tets_skin = subtract(tets_skin, v.faces);
1190 }
1191
1193 for (auto &v : *bcSpatialPressureVecPtr) {
1194 tets_skin = subtract(tets_skin, v.faces);
1195 }
1196
1197 return tets_skin;
1198 };
1199
1200 auto add_blockset = [&](auto block_name, auto &&tets_skin) {
1201 auto crack_faces =
1202 get_range_from_block(mField, "block_name", SPACE_DIM - 1);
1203 tets_skin.merge(crack_faces);
1204 return tets_skin;
1205 };
1206
1207 auto subtract_blockset = [&](auto block_name, auto &&tets_skin) {
1208 auto contact_range =
1209 get_range_from_block(mField, block_name, SPACE_DIM - 1);
1210 tets_skin = subtract(tets_skin, contact_range);
1211 return tets_skin;
1212 };
1213
1214 auto get_stress_trace_faces = [&](auto &&tets_skin) {
1215 Range faces;
1216 CHKERR mField.get_moab().get_adjacencies(get_tets(), SPACE_DIM - 1, true,
1217 faces, moab::Interface::UNION);
1218 Range trace_faces = subtract(faces, tets_skin);
1219 return trace_faces;
1220 };
1221
1222 auto tets = get_tets();
1223
1224 // remove also contact faces, i.e. that is also kind of hybrid field but
1225 // named but used to enforce contact conditions
1226 auto trace_faces = get_stress_trace_faces(
1227
1228 subtract_blockset("CONTACT",
1229 subtract_boundary_conditions(get_tets_skin()))
1230
1231 );
1232
1233 contactFaces = boost::make_shared<Range>(intersect(
1234 trace_faces, get_range_from_block(mField, "CONTACT", SPACE_DIM - 1)));
1236 boost::make_shared<Range>(subtract(trace_faces, *contactFaces));
1237 // materialSkeletonFaces =
1238 // boost::make_shared<Range>(get_stress_trace_faces(Range()));
1239
1240#ifndef NDEBUG
1241 if (contactFaces->size())
1243 "contact_faces_" +
1244 std::to_string(mField.get_comm_rank()) + ".vtk",
1245 *contactFaces);
1246 if (skeletonFaces->size())
1248 "skeleton_faces_" +
1249 std::to_string(mField.get_comm_rank()) + ".vtk",
1250 *skeletonFaces);
1251 // if (skeletonFaces->size())
1252 // CHKERR save_range(mField.get_moab(), "material_skeleton_faces.vtk",
1253 // *materialSkeletonFaces);
1254#endif
1255
1256 auto add_broken_hdiv_field = [this, meshset](const std::string field_name,
1257 const int order) {
1259
1261
1262 auto get_side_map_hdiv = [&]() {
1263 return std::vector<
1264
1265 std::pair<EntityType,
1267
1268 >>{
1269
1270 {MBTET,
1271 [&](BaseFunction::DofsSideMap &dofs_side_map) -> MoFEMErrorCode {
1272 return TetPolynomialBase::setDofsSideMap(HDIV, DISCONTINUOUS, base,
1273 dofs_side_map);
1274 }}
1275
1276 };
1277 };
1278
1280 get_side_map_hdiv(), MB_TAG_DENSE, MF_ZERO);
1282 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1284 };
1285
1286 auto add_l2_field = [this, meshset](const std::string field_name,
1287 const int order, const int dim) {
1290 MB_TAG_DENSE, MF_ZERO);
1292 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1294 };
1295
1296 auto add_h1_field = [this, meshset](const std::string field_name,
1297 const int order, const int dim) {
1300 MB_TAG_DENSE, MF_ZERO);
1302 CHKERR mField.set_field_order(meshset, MBVERTEX, field_name, 1);
1303 CHKERR mField.set_field_order(meshset, MBEDGE, field_name, order);
1304 CHKERR mField.set_field_order(meshset, MBTRI, field_name, order);
1305 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1307 };
1308
1309 auto add_l2_field_by_range = [this](const std::string field_name,
1310 const int order, const int dim,
1311 const int field_dim, Range &&r) {
1314 MB_TAG_DENSE, MF_ZERO);
1315 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(r);
1319 };
1320
1321 auto add_bubble_field = [this, meshset](const std::string field_name,
1322 const int order, const int dim) {
1324 CHKERR mField.add_field(field_name, HDIV, USER_BASE, dim, MB_TAG_DENSE,
1325 MF_ZERO);
1326 // Modify field
1327 auto field_ptr = mField.get_field_structure(field_name);
1328 auto field_order_table =
1329 const_cast<Field *>(field_ptr)->getFieldOrderTable();
1330 auto get_cgg_bubble_order_zero = [](int p) { return 0; };
1331 auto get_cgg_bubble_order_tet = [](int p) {
1332 return NBVOLUMETET_CCG_BUBBLE(p);
1333 };
1334 field_order_table[MBVERTEX] = get_cgg_bubble_order_zero;
1335 field_order_table[MBEDGE] = get_cgg_bubble_order_zero;
1336 field_order_table[MBTRI] = get_cgg_bubble_order_zero;
1337 field_order_table[MBTET] = get_cgg_bubble_order_tet;
1339 CHKERR mField.set_field_order(meshset, MBTRI, field_name, order);
1340 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1342 };
1343
1344 auto add_user_l2_field = [this, meshset](const std::string field_name,
1345 const int order, const int dim) {
1347 CHKERR mField.add_field(field_name, L2, USER_BASE, dim, MB_TAG_DENSE,
1348 MF_ZERO);
1349 // Modify field
1350 auto field_ptr = mField.get_field_structure(field_name);
1351 auto field_order_table =
1352 const_cast<Field *>(field_ptr)->getFieldOrderTable();
1353 auto zero_dofs = [](int p) { return 0; };
1354 auto dof_l2_tet = [](int p) { return NBVOLUMETET_L2(p); };
1355 field_order_table[MBVERTEX] = zero_dofs;
1356 field_order_table[MBEDGE] = zero_dofs;
1357 field_order_table[MBTRI] = zero_dofs;
1358 field_order_table[MBTET] = dof_l2_tet;
1360 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1362 };
1363
1364 // spatial fields
1365 CHKERR add_broken_hdiv_field(piolaStress, spaceOrder);
1366 CHKERR add_bubble_field(bubbleField, spaceOrder, 1);
1367 CHKERR add_l2_field(spatialL2Disp, spaceOrder - 1, 3);
1368 CHKERR add_l2_field(rotAxis, spaceOrder - 1, 3);
1369 CHKERR add_user_l2_field(stretchTensor, noStretch ? -1 : spaceOrder, 6);
1370
1371 if (!skeletonFaces)
1372 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "No skeleton faces");
1373 if (!contactFaces)
1374 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "No contact faces");
1375
1376 auto get_hybridised_disp = [&]() {
1377 auto faces = *skeletonFaces;
1378 auto skin = subtract_boundary_conditions(get_tets_skin());
1379 for (auto &bc : *bcSpatialNormalDisplacementVecPtr) {
1380 faces.merge(intersect(bc.faces, skin));
1381 }
1382 return faces;
1383 };
1384
1385 CHKERR add_l2_field_by_range(hybridSpatialDisp, spaceOrder - 1, 2, 3,
1386 get_hybridised_disp());
1387 CHKERR add_l2_field_by_range(contactDisp, spaceOrder - 1, 2, 3,
1389
1390 // spatial displacement
1391 CHKERR add_h1_field(spatialH1Disp, spaceH1Order, 3);
1392 // material positions
1393 CHKERR add_h1_field(materialH1Positions, 2, 3);
1394
1395 // Eshelby stress
1396 // CHKERR add_broken_hdiv_field(eshelbyStress, spaceOrder);
1397 // CHKERR add_l2_field(materialL2Disp, spaceOrder - 1, 3);
1398 // CHKERR add_l2_field_by_range(hybridMaterialDisp, spaceOrder - 1, 2, 3,
1399 // Range(*materialSkeletonFaces));
1400
1402
1404}
#define NBVOLUMETET_CCG_BUBBLE(P)
Bubble function for CGG H div space.
FieldApproximationBase
approximation base
Definition definitions.h:58
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
@ USER_BASE
user implemented approximation base
Definition definitions.h:68
@ DEMKOWICZ_JACOBI_BASE
Definition definitions.h:66
@ L2
field with C-1 continuity
Definition definitions.h:88
@ H1
continuous field
Definition definitions.h:85
@ HDIV
field with continuous normal traction
Definition definitions.h:87
@ DISCONTINUOUS
Broken continuity (No effect on L2 space)
constexpr int order
virtual const Field * get_field_structure(const std::string &name, enum MoFEMTypes bh=MF_EXIST) const =0
get field structure
virtual MoFEMErrorCode build_fields(int verb=DEFAULT_VERBOSITY)=0
virtual MoFEMErrorCode add_ents_to_field_by_dim(const Range &ents, const int dim, const std::string &name, int verb=DEFAULT_VERBOSITY)=0
Add entities to field meshset.
virtual MoFEMErrorCode set_field_order(const EntityHandle meshset, const EntityType type, const std::string &name, const ApproximationOrder order, int verb=DEFAULT_VERBOSITY)=0
Set order approximation of the entities in the field.
virtual MoFEMErrorCode add_ents_to_field_by_type(const Range &ents, const EntityType type, const std::string &name, int verb=DEFAULT_VERBOSITY)=0
Add entities to field meshset.
#define NBVOLUMETET_L2(P)
Number of base functions on tetrahedron for L2 space.
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
int r
Definition sdf.py:8
multi_index_container< DofsSideMapData, indexed_by< ordered_non_unique< tag< TypeSide_mi_tag >, composite_key< DofsSideMapData, member< DofsSideMapData, EntityType, &DofsSideMapData::type >, member< DofsSideMapData, int, &DofsSideMapData::side > > >, ordered_unique< tag< EntDofIdx_mi_tag >, member< DofsSideMapData, int, &DofsSideMapData::dof > > > > DofsSideMap
Map entity stype and side to element/entity dof index.
virtual MoFEMErrorCode add_broken_field(const std::string name, const FieldSpace space, const FieldApproximationBase base, const FieldCoefficientsNumber nb_of_coefficients, const std::vector< std::pair< EntityType, std::function< MoFEMErrorCode(BaseFunction::DofsSideMap &)> > > list_dof_side_map, const TagType tag_type=MB_TAG_SPARSE, const enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
Add field.
virtual MoFEMErrorCode add_field(const std::string name, const FieldSpace space, const FieldApproximationBase base, const FieldCoefficientsNumber nb_of_coefficients, const TagType tag_type=MB_TAG_SPARSE, const enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
Add field.
Provide data structure for (tensor) field approximation.

◆ addMaterial_Hencky()

MoFEMErrorCode EshelbianCore::addMaterial_Hencky ( double  E,
double  nu 
)
Examples
ep.cpp.

Definition at line 540 of file EshelbianADOL-C.cpp.

540 {
542 physicalEquations = boost::make_shared<HMHHencky>(mField, E, nu);
544}
boost::shared_ptr< PhysicalEquations > physicalEquations

◆ addMaterial_HMHHStVenantKirchhoff()

MoFEMErrorCode EshelbianCore::addMaterial_HMHHStVenantKirchhoff ( const int  tape,
const double  lambda,
const double  mu,
const double  sigma_y 
)
Examples
ep.cpp.

Definition at line 513 of file EshelbianADOL-C.cpp.

515 {
517 physicalEquations = boost::make_shared<HMHStVenantKirchhoff>(lambda, mu);
518 CHKERR physicalEquations->recordTape(tape, nullptr);
520}
static double lambda

◆ addMaterial_HMHMooneyRivlin()

MoFEMErrorCode EshelbianCore::addMaterial_HMHMooneyRivlin ( const int  tape,
const double  alpha,
const double  beta,
const double  lambda,
const double  sigma_y 
)
Examples
ep.cpp.

Definition at line 522 of file EshelbianADOL-C.cpp.

524 {
527 boost::make_shared<HMHPMooneyRivlinWriggersEq63>(alpha, beta, lambda);
528 CHKERR physicalEquations->recordTape(tape, nullptr);
530}

◆ addMaterial_HMHNeohookean()

MoFEMErrorCode EshelbianCore::addMaterial_HMHNeohookean ( const int  tape,
const double  c10,
const double  K 
)
Examples
ep.cpp.

Definition at line 531 of file EshelbianADOL-C.cpp.

533 {
535 physicalEquations = boost::make_shared<HMHNeohookean>(mField, c10, K);
536 CHKERR physicalEquations->recordTape(tape, nullptr);
538}

◆ addVolumeFiniteElement()

MoFEMErrorCode EshelbianCore::addVolumeFiniteElement ( const EntityHandle  meshset = 0)
Examples
EshelbianPlasticity.cpp, and ep.cpp.

Definition at line 1520 of file EshelbianPlasticity.cpp.

1520 {
1522
1523 // set finite element fields
1524 auto add_field_to_fe = [this](const std::string fe,
1525 const std::string field_name) {
1531 };
1532
1537
1538 CHKERR add_field_to_fe(elementVolumeName, piolaStress);
1539 CHKERR add_field_to_fe(elementVolumeName, bubbleField);
1540 if (!noStretch)
1541 CHKERR add_field_to_fe(elementVolumeName, stretchTensor);
1542 CHKERR add_field_to_fe(elementVolumeName, rotAxis);
1543 CHKERR add_field_to_fe(elementVolumeName, spatialL2Disp);
1544 CHKERR add_field_to_fe(elementVolumeName, spatialH1Disp);
1545 CHKERR add_field_to_fe(elementVolumeName, contactDisp);
1548
1549 // build finite elements data structures
1551 }
1552
1553 // if (!mField.check_finite_element(materialVolumeElement)) {
1554
1555 // Range front_edges = get_range_from_block(mField, "FRONT", SPACE_DIM - 2);
1556
1557 // Range front_elements;
1558 // for (auto l = 0; l != frontLayers; ++l) {
1559 // Range front_elements_layer;
1560 // CHKERR mField.get_moab().get_adjacencies(front_edges, SPACE_DIM, true,
1561 // front_elements_layer,
1562 // moab::Interface::UNION);
1563 // front_elements.merge(front_elements_layer);
1564 // front_edges.clear();
1565 // CHKERR mField.get_moab().get_adjacencies(front_elements_layer,
1566 // SPACE_DIM - 2, true,
1567 // front_edges,
1568 // moab::Interface::UNION);
1569 // }
1570
1571 // CHKERR mField.add_finite_element(materialVolumeElement, MF_ZERO);
1572 // CHKERR mField.add_ents_to_finite_element_by_type(front_elements, MBTET,
1573 // materialVolumeElement);
1574 // // CHKERR add_field_to_fe(materialVolumeElement, eshelbyStress);
1575 // // CHKERR add_field_to_fe(materialVolumeElement, materialL2Disp);
1576 // CHKERR mField.build_finite_elements(materialVolumeElement);
1577 // }
1578
1580}

◆ calculateCrackArea()

MoFEMErrorCode EshelbianCore::calculateCrackArea ( boost::shared_ptr< double area_ptr)
Examples
EshelbianPlasticity.cpp.

Definition at line 7092 of file EshelbianPlasticity.cpp.

7092 {
7094
7095 if (!area_ptr) {
7096 CHK_THROW_MESSAGE(MOFEM_INVALID_DATA, "area_ptr is null");
7097 }
7098
7099 int success;
7100 *area_ptr = 0;
7101 if (mField.get_comm_rank() == 0) {
7102 MOFEM_LOG("EP", Sev::inform) << "Calculate crack area";
7103 auto crack_faces = get_range_from_block(mField, "CRACK", SPACE_DIM - 1);
7104 for (auto f : crack_faces) {
7105 *area_ptr += mField.getInterface<Tools>()->getTriArea(f);
7106 }
7107 success = MPI_Bcast(area_ptr.get(), 1, MPI_DOUBLE, 0, mField.get_comm());
7108 } else {
7109 success = MPI_Bcast(area_ptr.get(), 1, MPI_DOUBLE, 0, mField.get_comm());
7110 }
7111 if (success != MPI_SUCCESS) {
7113 }
7115}
@ MOFEM_OPERATION_UNSUCCESSFUL
Definition definitions.h:34
@ MOFEM_INVALID_DATA
Definition definitions.h:36

◆ calculateFaceMaterialForce()

MoFEMErrorCode EshelbianCore::calculateFaceMaterialForce ( const int  tag,
TS  ts 
)

Create element to integration faces energies

Examples
EshelbianPlasticity.cpp.

Definition at line 4329 of file EshelbianPlasticity.cpp.

4329 {
4331
4332 constexpr bool debug = false;
4333
4334 auto get_tags_vec = [&](std::vector<std::pair<std::string, int>> names) {
4335 std::vector<Tag> tags;
4336 tags.reserve(names.size());
4337 auto create_and_clean = [&]() {
4339 for (auto n : names) {
4340 tags.push_back(Tag());
4341 auto &tag = tags.back();
4342 auto &moab = mField.get_moab();
4343 auto rval = moab.tag_get_handle(n.first.c_str(), tag);
4344 if (rval == MB_SUCCESS) {
4345 moab.tag_delete(tag);
4346 }
4347 double def_val[] = {0., 0., 0.};
4348 CHKERR moab.tag_get_handle(n.first.c_str(), n.second, MB_TYPE_DOUBLE,
4349 tag, MB_TAG_CREAT | MB_TAG_SPARSE, def_val);
4350 }
4352 };
4353 CHK_THROW_MESSAGE(create_and_clean(), "create_and_clean");
4354 return tags;
4355 };
4356
4357 enum ExhangeTags { MATERIALFORCE, AREAGROWTH, GRIFFITHFORCE, FACEPRESSURE };
4358
4359 auto tags = get_tags_vec({{"MaterialForce", 3},
4360 {"AreaGrowth", 3},
4361 {"GriffithForce", 1},
4362 {"FacePressure", 1}});
4363
4364 auto calculate_material_forces = [&]() {
4366
4367 /**
4368 * @brief Create element to integration faces energies
4369 */
4370 auto get_face_material_force_fe = [&]() {
4372 auto fe_ptr = boost::make_shared<FaceEle>(mField);
4373 fe_ptr->getRuleHook = [](int, int, int) { return -1; };
4374 fe_ptr->setRuleHook =
4375 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
4376
4377 // hybrid disp, evalated on face first
4378 EshelbianPlasticity::AddHOOps<2, 2, 3>::add(
4379 fe_ptr->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
4380 fe_ptr->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4381 hybridSpatialDisp, dataAtPts->getHybridDispAtPts()));
4382 fe_ptr->getOpPtrVector().push_back(
4384 hybridSpatialDisp, dataAtPts->getGradHybridDispAtPts()));
4385 auto op_loop_domain_side =
4387 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
4388 fe_ptr->getOpPtrVector().push_back(op_loop_domain_side);
4389 fe_ptr->getOpPtrVector().push_back(new OpFaceMaterialForce(dataAtPts));
4390
4391 // evaluated in side domain, that is op_loop_domain_side
4392 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
4393 boost::make_shared<CGGUserPolynomialBase>();
4394
4395 auto inv_jac = boost::make_shared<MatrixDouble>();
4396 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4397 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
4398 materialH1Positions, frontAdjEdges, nullptr, nullptr, inv_jac);
4399 op_loop_domain_side->getOpPtrVector().push_back(
4400 new OpSetHOInvJacVectorBase(HDIV, inv_jac));
4401 op_loop_domain_side->getOpPtrVector().push_back(
4403 piolaStress, dataAtPts->getApproxPAtPts()));
4404 op_loop_domain_side->getOpPtrVector().push_back(
4406 bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
4407 op_loop_domain_side->getOpPtrVector().push_back(
4409 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
4410 if (noStretch) {
4411 op_loop_domain_side->getOpPtrVector().push_back(
4412 physicalEquations->returnOpCalculateStretchFromStress(
4414 } else {
4415 op_loop_domain_side->getOpPtrVector().push_back(
4417 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
4418 }
4419 op_loop_domain_side->getOpPtrVector().push_back(
4421 hybridSpatialDisp, dataAtPts->getGradPAtPts()()));
4422 op_loop_domain_side->getOpPtrVector().push_back(
4424
4425 return fe_ptr;
4426 };
4427
4428 auto integrate_face_material_force_fe = [&](auto &&face_energy_fe) {
4431 dM, skeletonElement, face_energy_fe, 0, mField.get_comm_size());
4432
4433 auto face_exchange = CommInterface::createEntitiesPetscVector(
4434 mField.get_comm(), mField.get_moab(), 2, 3, Sev::inform);
4435
4436 auto print_loc_size = [this](auto v, auto str, auto sev) {
4438 int size;
4439 CHKERR VecGetLocalSize(v.second, &size);
4440 int low, high;
4441 CHKERR VecGetOwnershipRange(v.second, &low, &high);
4442 MOFEM_LOG("EPSYNC", sev) << str << " local size " << size << " ( "
4443 << low << " " << high << " ) ";
4446 };
4447 CHKERR print_loc_size(face_exchange, "material face_exchange",
4448 Sev::verbose);
4449
4451 mField.get_moab(), face_exchange, tags[ExhangeTags::MATERIALFORCE]);
4453 mField.get_moab(), faceExchange, tags[ExhangeTags::FACEPRESSURE]);
4454
4455 // #ifndef NDEBUG
4456 if (debug) {
4458 "front_skin_faces_material_force_" +
4459 std::to_string(mField.get_comm_rank()) + ".vtk",
4460 *skeletonFaces);
4461 }
4462 // #endif
4463
4465 };
4466
4467 CHKERR integrate_face_material_force_fe(get_face_material_force_fe());
4468
4470 };
4471
4472 auto calculate_front_material_force = [&]() {
4475
4476 auto get_conn = [&](auto e) {
4477 Range conn;
4478 CHK_MOAB_THROW(mField.get_moab().get_connectivity(&e, 1, conn, true),
4479 "get connectivity");
4480 return conn;
4481 };
4482
4483 auto get_conn_range = [&](auto e) {
4484 Range conn;
4485 CHK_MOAB_THROW(mField.get_moab().get_connectivity(e, conn, true),
4486 "get connectivity");
4487 return conn;
4488 };
4489
4490 auto get_adj = [&](auto e, auto dim) {
4491 Range adj;
4492 CHK_MOAB_THROW(mField.get_moab().get_adjacencies(&e, 1, dim, true, adj),
4493 "get adj");
4494 return adj;
4495 };
4496
4497 auto get_adj_range = [&](auto e, auto dim) {
4498 Range adj;
4499 CHK_MOAB_THROW(mField.get_moab().get_adjacencies(e, dim, true, adj,
4500 moab::Interface::UNION),
4501 "get adj");
4502 return adj;
4503 };
4504
4505 auto get_material_force = [&](auto r, auto th) {
4506 MatrixDouble material_forces(r.size(), 3, false);
4508 mField.get_moab().tag_get_data(th, r, material_forces.data().data()),
4509 "get data");
4510 return material_forces;
4511 };
4512
4513 if (mField.get_comm_rank() == 0) {
4514
4515 auto crack_edges = get_adj_range(*crackFaces, 1);
4516 auto front_nodes = get_conn_range(*frontEdges);
4517 auto body_edges = get_range_from_block(mField, "EDGES", 1);
4518 // auto front_block_edges = get_range_from_block(mField, "FRONT", 1);
4519 // front_block_edges = subtract(front_block_edges, crack_edges);
4520 // auto front_block_edges_conn = get_conn_range(front_block_edges);
4521
4522 // #ifndef NDEBUG
4523 Range all_skin_faces;
4524 Range all_front_faces;
4525 // #endif
4526
4527 auto calculate_edge_direction = [&](auto e) {
4528 const EntityHandle *conn;
4529 int num_nodes;
4531 mField.get_moab().get_connectivity(e, conn, num_nodes, true),
4532 "get connectivity");
4533 std::array<double, 6> coords;
4535 mField.get_moab().get_coords(conn, num_nodes, coords.data()),
4536 "get coords");
4538 &coords[0], &coords[1], &coords[2]};
4540 &coords[3], &coords[4], &coords[5]};
4543 t_dir(i) = t_p1(i) - t_p0(i);
4544 return t_dir;
4545 };
4546
4547 // take bubble tets at node, and then avarage over the edges
4548 auto calculate_force_through_node = [&]() {
4550
4555
4556 Range body_ents;
4557 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
4558 body_ents);
4559 auto body_skin = get_skin(mField, body_ents);
4560 auto body_skin_conn = get_conn_range(body_skin);
4561
4562 // calculate nodal material force
4563 for (auto n : front_nodes) {
4564 auto adj_tets = get_adj(n, 3);
4565 for (int ll = 0; ll < nbJIntegralLevels; ++ll) {
4566 auto conn = get_conn_range(adj_tets);
4567 adj_tets = get_adj_range(conn, 3);
4568 }
4569 auto skin_faces = get_skin(mField, adj_tets);
4570 auto material_forces = get_material_force(skin_faces, tags[0]);
4571
4572 // #ifndef NDEBUG
4573 if (debug) {
4574 all_skin_faces.merge(skin_faces);
4575 }
4576 // #endif
4577
4578 auto calculate_node_material_force = [&]() {
4579 auto t_face_T =
4580 getFTensor1FromPtr<SPACE_DIM>(material_forces.data().data());
4581 FTensor::Tensor1<double, SPACE_DIM> t_node_force{0., 0., 0.};
4582 for (auto face : skin_faces) {
4583
4584 FTensor::Tensor1<double, SPACE_DIM> t_face_force_tmp{0., 0., 0.};
4585 t_face_force_tmp(I) = t_face_T(I);
4586 ++t_face_T;
4587
4588 auto face_tets = intersect(get_adj(face, 3), adj_tets);
4589
4590 if (face_tets.empty()) {
4591 continue;
4592 }
4593
4594 if (face_tets.size() != 1) {
4596 "face_tets.size() != 1");
4597 }
4598
4599 int side_number, sense, offset;
4600 CHK_MOAB_THROW(mField.get_moab().side_number(face_tets[0], face,
4601 side_number, sense,
4602 offset),
4603 "moab side number");
4604 t_face_force_tmp(I) *= sense;
4605 t_node_force(I) += t_face_force_tmp(I);
4606 }
4607
4608 return t_node_force;
4609 };
4610
4611 auto calculate_crack_area_growth_direction =
4612 [&](auto n, auto &t_node_force) {
4613 // if skin is on body surface, project the direction on it
4614 FTensor::Tensor1<double, SPACE_DIM> t_project{0., 0., 0.};
4615 auto boundary_node = intersect(Range(n, n), body_skin_conn);
4616 if (boundary_node.size()) {
4617 auto faces = intersect(get_adj(n, 2), body_skin);
4618 for (auto f : faces) {
4619 FTensor::Tensor1<double, 3> t_normal_face;
4620 CHKERR mField.getInterface<Tools>()->getTriNormal(
4621 f, &t_normal_face(0));
4622 t_project(I) += t_normal_face(I);
4623 }
4624 t_project.normalize();
4625 }
4626
4627 // calculate surface projection matrix
4630 t_Q(I, J) = t_kd(I, J);
4631 if (boundary_node.size()) {
4632 t_Q(I, J) -= t_project(I) * t_project(J);
4633 }
4634
4635 auto adj_faces = intersect(get_adj(n, 2), *crackFaces);
4636 if (adj_faces.empty()) {
4637 auto adj_edges =
4638 intersect(get_adj(n, 1), unite(*frontEdges, body_edges));
4639 double l = 0;
4640 for (auto e : adj_edges) {
4641 auto t_dir = calculate_edge_direction(e);
4642 l += t_dir.l2();
4643 }
4644 l /= 2;
4645 FTensor::Tensor1<double, SPACE_DIM> t_area_dir{0., 0., 0.};
4646 FTensor::Tensor1<double, SPACE_DIM> t_node_force_tmp;
4647 t_node_force_tmp(I) = t_node_force(I);
4648 t_node_force_tmp.normalize();
4649 t_area_dir(I) = -t_node_force_tmp(I);
4650 t_area_dir(I) *= l / 2;
4651 return t_area_dir;
4652 }
4653
4654 // calculate direction
4655 auto front_edges = get_adj(n, 1);
4656 FTensor::Tensor1<double, 3> t_area_dir{0., 0., 0.};
4657 for (auto f : adj_faces) {
4658 int num_nodes;
4659 const EntityHandle *conn;
4660 CHKERR mField.get_moab().get_connectivity(f, conn, num_nodes,
4661 true);
4662 std::array<double, 9> coords;
4663 CHKERR mField.get_moab().get_coords(conn, num_nodes,
4664 coords.data());
4665 FTensor::Tensor1<double, 3> t_face_normal;
4667 CHKERR mField.getInterface<Tools>()->getTriNormal(
4668 coords.data(), &t_face_normal(0), &t_d_normal(0, 0, 0));
4669 auto n_it = std::find(conn, conn + num_nodes, n);
4670 auto n_index = std::distance(conn, n_it);
4671
4672 FTensor::Tensor2<double, 3, 3> t_face_hessian{
4673 t_d_normal(0, n_index, 0), t_d_normal(0, n_index, 1),
4674 t_d_normal(0, n_index, 2),
4675
4676 t_d_normal(1, n_index, 0), t_d_normal(1, n_index, 1),
4677 t_d_normal(1, n_index, 2),
4678
4679 t_d_normal(2, n_index, 0), t_d_normal(2, n_index, 1),
4680 t_d_normal(2, n_index, 2)};
4681
4682 FTensor::Tensor2<double, 3, 3> t_projected_hessian;
4683 t_projected_hessian(I, J) =
4684 t_Q(I, K) * (t_face_hessian(K, L) * t_Q(L, J));
4685 t_face_normal.normalize();
4686 t_area_dir(K) +=
4687 t_face_normal(I) * t_projected_hessian(I, K) / 2.;
4688 }
4689
4690 return t_area_dir;
4691 };
4692
4693 auto t_node_force = calculate_node_material_force();
4694 t_node_force(I) /= griffithEnergy; // scale all by griffith energy
4696 mField.get_moab().tag_set_data(tags[ExhangeTags::MATERIALFORCE],
4697 &n, 1, &t_node_force(0)),
4698 "set data");
4699
4700 auto get_area_dir = [&]() {
4701 auto adj_faces = get_adj_range(adj_tets, 2);
4702 auto t_area_dir = calculate_crack_area_growth_direction(
4703 n, t_node_force);
4704 if (nbJIntegralLevels) {
4705 auto adj_edges = intersect(get_adj_range(adj_tets, 1),
4706 unite(*frontEdges, body_edges));
4707 auto seed_n = get_conn_range(adj_edges);
4708 auto skin_adj_edges = get_skin(mField, adj_edges);
4709 skin_adj_edges = subtract(skin_adj_edges, body_skin_conn);
4710 seed_n = subtract(seed_n, skin_adj_edges);
4711 t_area_dir(I) = 0;
4712 for (auto sn : seed_n) {
4713 auto t_area_dir_sn = calculate_crack_area_growth_direction(
4714 sn, t_node_force);
4715 t_area_dir(I) += t_area_dir_sn(I);
4716 }
4717 for (auto sn : skin_adj_edges) {
4718 auto t_area_dir_sn = calculate_crack_area_growth_direction(
4719 sn, t_node_force);
4720 t_area_dir(I) += t_area_dir_sn(I) / 2;
4721 }
4722 }
4723
4724 return t_area_dir;
4725 };
4726
4727 auto t_area_dir = get_area_dir();
4728
4730 mField.get_moab().tag_set_data(tags[ExhangeTags::AREAGROWTH], &n,
4731 1, &t_area_dir(0)),
4732 "set data");
4733 auto griffith = -t_node_force(I) * t_area_dir(I) /
4734 (t_area_dir(K) * t_area_dir(K));
4736 mField.get_moab().tag_set_data(tags[ExhangeTags::GRIFFITHFORCE],
4737 &n, 1, &griffith),
4738 "set data");
4739 }
4740
4741 // iterate over edges, and calculate average edge material force
4742 auto ave_node_force = [&](auto th) {
4744
4745 for (auto e : *frontEdges) {
4746
4747 auto conn = get_conn(e);
4748 auto data = get_material_force(conn, th);
4749 auto t_node = getFTensor1FromPtr<SPACE_DIM>(data.data().data());
4750 FTensor::Tensor1<double, SPACE_DIM> t_edge{0., 0., 0.};
4751 for (auto n : conn) {
4752 t_edge(I) += t_node(I);
4753 ++t_node;
4754 }
4755 t_edge(I) /= conn.size();
4756
4757 FTensor::Tensor1<double, SPACE_DIM> t_edge_direction =
4758 calculate_edge_direction(e);
4759 t_edge_direction.normalize();
4760
4765 t_cross(K) =
4766 FTensor::levi_civita(I, J, K) * t_edge_direction(I) * t_edge(J);
4767 t_edge(K) = FTensor::levi_civita(I, J, K) * t_edge_direction(J) *
4768 t_cross(I);
4769
4770 CHKERR mField.get_moab().tag_set_data(th, &e, 1, &t_edge(0));
4771 }
4773 };
4774
4775 // iterate over edges, and calculate average edge griffith energy
4776 auto ave_node_griffith_energy = [&](auto th) {
4778 for (auto e : *frontEdges) {
4780 CHKERR mField.get_moab().tag_get_data(
4781 tags[ExhangeTags::MATERIALFORCE], &e, 1, &t_edge_force(0));
4783 CHKERR mField.get_moab().tag_get_data(tags[ExhangeTags::AREAGROWTH],
4784 &e, 1, &t_edge_area_dir(0));
4785 double griffith_energy = -t_edge_force(I) * t_edge_area_dir(I) /
4786 (t_edge_area_dir(K) * t_edge_area_dir(K));
4787 CHKERR mField.get_moab().tag_set_data(th, &e, 1, &griffith_energy);
4788 }
4790 };
4791
4792 CHKERR ave_node_force(tags[ExhangeTags::MATERIALFORCE]);
4793 CHKERR ave_node_force(tags[ExhangeTags::AREAGROWTH]);
4794 CHKERR ave_node_griffith_energy(tags[ExhangeTags::GRIFFITHFORCE]);
4795
4797 };
4798
4799 CHKERR calculate_force_through_node();
4800
4801 // calculate face cross
4802 for (auto e : *frontEdges) {
4803 auto adj_faces = get_adj(e, 2);
4804 auto crack_face = intersect(get_adj(e, 2), *crackFaces);
4805
4806 // #ifndef NDEBUG
4807 if (debug) {
4808 all_front_faces.merge(adj_faces);
4809 }
4810 // #endif
4811
4813 CHKERR mField.get_moab().tag_get_data(tags[ExhangeTags::MATERIALFORCE],
4814 &e, 1, &t_edge_force(0));
4815 FTensor::Tensor1<double, SPACE_DIM> t_edge_direction =
4816 calculate_edge_direction(e);
4817 t_edge_direction.normalize();
4822 t_cross(K) = FTensor::levi_civita(I, J, K) * t_edge_direction(I) *
4823 t_edge_force(J);
4824
4825 for (auto f : adj_faces) {
4827 CHKERR mField.getInterface<Tools>()->getTriNormal(f, &t_normal(0));
4828 t_normal.normalize();
4829 int side_number, sense, offset;
4830 CHKERR mField.get_moab().side_number(f, e, side_number, sense,
4831 offset);
4832 auto dot = -sense * t_cross(I) * t_normal(I);
4833 CHK_MOAB_THROW(mField.get_moab().tag_set_data(
4834 tags[ExhangeTags::GRIFFITHFORCE], &f, 1, &dot),
4835 "set data");
4836 }
4837 }
4838
4839 // #ifndef NDEBUG
4840 if (debug) {
4841 int ts_step;
4842 CHKERR TSGetStepNumber(ts, &ts_step);
4844 "front_edges_material_force_" +
4845 std::to_string(ts_step) + ".vtk",
4846 *frontEdges);
4848 "front_skin_faces_material_force_" +
4849 std::to_string(ts_step) + ".vtk",
4850 all_skin_faces);
4852 "front_faces_material_force_" +
4853 std::to_string(ts_step) + ".vtk",
4854 all_front_faces);
4855 }
4856 // #endif
4857 }
4858
4859 auto edge_exchange = CommInterface::createEntitiesPetscVector(
4860 mField.get_comm(), mField.get_moab(), 1, 3, Sev::inform);
4862 mField.get_moab(), edge_exchange, tags[ExhangeTags::MATERIALFORCE]);
4864 mField.get_moab(), edge_exchange, tags[ExhangeTags::AREAGROWTH]);
4866 mField.get_moab(), edgeExchange, tags[ExhangeTags::GRIFFITHFORCE]);
4867
4869 };
4870
4871 auto print_results = [&]() {
4873
4874 auto get_conn_range = [&](auto e) {
4875 Range conn;
4876 CHK_MOAB_THROW(mField.get_moab().get_connectivity(e, conn, true),
4877 "get connectivity");
4878 return conn;
4879 };
4880
4881 auto get_tag_data = [&](auto &ents, auto tag, auto dim) {
4882 std::vector<double> data(ents.size() * dim);
4883 CHK_MOAB_THROW(mField.get_moab().tag_get_data(tag, ents, data.data()),
4884 "get data");
4885 return data;
4886 };
4887
4888 if (mField.get_comm_rank() == 0) {
4889 auto at_nodes = [&]() {
4891 auto conn = get_conn_range(*frontEdges);
4892 auto material_force =
4893 get_tag_data(conn, tags[ExhangeTags::MATERIALFORCE], 3);
4894 auto area_growth = get_tag_data(conn, tags[ExhangeTags::AREAGROWTH], 3);
4895 auto griffith_force =
4896 get_tag_data(conn, tags[ExhangeTags::GRIFFITHFORCE], 1);
4897 std::vector<double> coords(conn.size() * 3);
4898 CHK_MOAB_THROW(mField.get_moab().get_coords(conn, coords.data()),
4899 "get coords");
4900 if (conn.size())
4901 MOFEM_LOG("EPSELF", Sev::inform) << "Material force at nodes";
4902 for (size_t i = 0; i < conn.size(); ++i) {
4903 MOFEM_LOG("EPSELF", Sev::inform)
4904 << "Node " << conn[i] << " coords "
4905 << coords[i * 3 + 0] << " " << coords[i * 3 + 1] << " "
4906 << coords[i * 3 + 2] << " material force "
4907 << material_force[i * 3 + 0] << " "
4908 << material_force[i * 3 + 1] << " "
4909 << material_force[i * 3 + 2] << " area growth "
4910 << area_growth[i * 3 + 0] << " " << area_growth[i * 3 + 1]
4911 << " " << area_growth[i * 3 + 2] << " griffith force "
4912 << griffith_force[i];
4913 }
4915 };
4916
4917 at_nodes();
4918 }
4920 };
4921
4922 CHKERR calculate_material_forces();
4923 CHKERR calculate_front_material_force();
4924 CHKERR print_results();
4925
4927}
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
Kronecker Delta class.
Tensor1< T, Tensor_Dim > normalize()
constexpr auto t_kd
PetscErrorCode DMoFEMLoopFiniteElementsUpAndLowRank(DM dm, const char fe_name[], MoFEM::FEMethod *method, int low_rank, int up_rank, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
Definition DMMoFEM.cpp:557
FTensor::Index< 'J', DIM1 > J
Definition level_set.cpp:30
FTensor::Index< 'l', 3 > l
constexpr std::enable_if<(Dim0<=2 &&Dim1<=2), Tensor2_Expr< Levi_Civita< T >, T, Dim0, Dim1, i, j > >::type levi_civita(const Index< i, Dim0 > &, const Index< j, Dim1 > &)
levi_civita functions to make for easy adhoc use
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
constexpr IntegrationType I
boost::shared_ptr< Range > frontAdjEdges
static double griffithEnergy
Griffith energy.
CommInterface::EntitiesPetscVector edgeExchange
static int nbJIntegralLevels
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
boost::shared_ptr< Range > frontVertices
CommInterface::EntitiesPetscVector faceExchange
static MoFEMErrorCode updateEntitiesPetscVector(moab::Interface &moab, EntitiesPetscVector &vec, Tag tag, UpdateGhosts update_gosts=defaultUpdateGhosts)
Exchange data between vector and data.
static EntitiesPetscVector createEntitiesPetscVector(MPI_Comm comm, moab::Interface &moab, int dim, const int nb_coeffs, Sev sev=Sev::verbose, int root_rank=0)
Create a ghost vector for exchanging data.
virtual int get_comm_size() const =0
Calculate tenor field using tensor base, i.e. Hdiv/Hcurl.
Calculate tenor field using vectorial base, i.e. Hdiv/Hcurl.
Calculate gradient of vector field.
Calculate symmetric tensor field values at integration pts.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Get values at integration pts for tensor field rank 1, i.e. vector field.
Element used to execute operators on side of the element.
transform local reference derivatives of shape function to global derivatives if higher order geometr...

◆ calculateOrientation()

MoFEMErrorCode EshelbianCore::calculateOrientation ( const int  tag,
bool  set_orientation 
)

Iterate over front edges, get adjacent faces, find maximal face energy. Maximal face energy is stored in the edge. Maximal face energy is magnitude of edge Griffith force.

For each front edge, find maximal face energy and orientation. This is by finding angle between edge material force and maximal face normal

Examples
EshelbianPlasticity.cpp.

Definition at line 4929 of file EshelbianPlasticity.cpp.

4930 {
4932
4933 constexpr bool debug = false;
4934 constexpr auto sev = Sev::verbose;
4935
4936 Range body_ents;
4937 CHKERR mField.get_moab().get_entities_by_dimension(0, 3, body_ents);
4938 auto body_skin = get_skin(mField, body_ents);
4939 Range body_skin_edges;
4940 CHKERR mField.get_moab().get_adjacencies(body_skin, 1, false, body_skin_edges,
4941 moab::Interface::UNION);
4942 Range boundary_skin_verts;
4943 CHKERR mField.get_moab().get_connectivity(body_skin_edges,
4944 boundary_skin_verts, true);
4945
4946 auto geometry_edges = get_range_from_block(mField, "EDGES", 1);
4947 Range geometry_edges_verts;
4948 CHKERR mField.get_moab().get_connectivity(geometry_edges,
4949 geometry_edges_verts, true);
4950 Range crack_faces_verts;
4951 CHKERR mField.get_moab().get_connectivity(*crackFaces, crack_faces_verts,
4952 true);
4953 Range crack_faces_edges;
4954 CHKERR mField.get_moab().get_adjacencies(
4955 *crackFaces, 1, true, crack_faces_edges, moab::Interface::UNION);
4956 Range crack_faces_tets;
4957 CHKERR mField.get_moab().get_adjacencies(
4958 *crackFaces, 3, true, crack_faces_tets, moab::Interface::UNION);
4959
4960 Range front_verts;
4961 CHKERR mField.get_moab().get_connectivity(*frontEdges, front_verts, true);
4962 Range front_faces;
4963 CHKERR mField.get_moab().get_adjacencies(*frontEdges, 2, true, front_faces,
4964 moab::Interface::UNION);
4965 Range front_verts_edges;
4966 CHKERR mField.get_moab().get_adjacencies(
4967 front_verts, 1, true, front_verts_edges, moab::Interface::UNION);
4968
4969 auto get_tags_vec = [&](auto tag_name, int dim) {
4970 std::vector<Tag> tags(1);
4971
4972 if (dim > 3)
4974
4975 auto create_and_clean = [&]() {
4977 auto &moab = mField.get_moab();
4978 auto rval = moab.tag_get_handle(tag_name, tags[0]);
4979 if (rval == MB_SUCCESS) {
4980 moab.tag_delete(tags[0]);
4981 }
4982 double def_val[] = {0., 0., 0.};
4983 CHKERR moab.tag_get_handle(tag_name, dim, MB_TYPE_DOUBLE, tags[0],
4984 MB_TAG_CREAT | MB_TAG_SPARSE, def_val);
4986 };
4987
4988 CHK_THROW_MESSAGE(create_and_clean(), "create_and_clean");
4989
4990 return tags;
4991 };
4992
4993 auto get_adj_front = [&](bool subtract_crack) {
4994 Range adj_front;
4995 CHKERR mField.get_moab().get_adjacencies(*frontEdges, SPACE_DIM - 1, true,
4996 adj_front, moab::Interface::UNION);
4997 if (subtract_crack)
4998 adj_front = subtract(adj_front, *crackFaces);
4999 return adj_front;
5000 };
5001
5002 MOFEM_LOG_CHANNEL("SELF");
5003
5004 auto th_front_position = get_tags_vec("FrontPosition", 3);
5005 auto th_max_face_energy = get_tags_vec("MaxFaceEnergy", 1);
5006
5007 if (mField.get_comm_rank() == 0) {
5008
5009 auto get_crack_adj_tets = [&](auto r) {
5010 Range crack_faces_conn;
5011 CHKERR mField.get_moab().get_connectivity(r, crack_faces_conn);
5012 Range crack_faces_conn_tets;
5013 CHKERR mField.get_moab().get_adjacencies(crack_faces_conn, SPACE_DIM,
5014 true, crack_faces_conn_tets,
5015 moab::Interface::UNION);
5016 return crack_faces_conn_tets;
5017 };
5018
5019 auto get_layers_for_sides = [&](auto &side) {
5020 std::vector<Range> layers;
5021 auto get = [&]() {
5023
5024 auto get_adj = [&](auto &r, int dim) {
5025 Range adj;
5026 CHKERR mField.get_moab().get_adjacencies(r, dim, true, adj,
5027 moab::Interface::UNION);
5028 return adj;
5029 };
5030
5031 auto get_tets = [&](auto r) { return get_adj(r, SPACE_DIM); };
5032
5033 Range front_nodes;
5034 CHKERR mField.get_moab().get_connectivity(*frontEdges, front_nodes,
5035 true);
5036 Range front_faces = get_adj(front_nodes, 2);
5037 front_faces = subtract(front_faces, *crackFaces);
5038 auto front_tets = get_tets(front_nodes);
5039 auto front_side = intersect(side, front_tets);
5040 layers.push_back(front_side);
5041 for (;;) {
5042 auto adj_faces = get_skin(mField, layers.back());
5043 adj_faces = intersect(adj_faces, front_faces);
5044 auto adj_faces_tets = get_tets(adj_faces);
5045 adj_faces_tets = intersect(adj_faces_tets, front_tets);
5046 layers.push_back(unite(layers.back(), adj_faces_tets));
5047 if (layers.back().size() == layers[layers.size() - 2].size()) {
5048 break;
5049 }
5050 }
5052 };
5053 CHK_THROW_MESSAGE(get(), "get_layers_for_sides");
5054 return layers;
5055 };
5056
5058 auto layers_top = get_layers_for_sides(sides_pair.first);
5059 auto layers_bottom = get_layers_for_sides(sides_pair.second);
5060
5061#ifndef NDEBUG
5062 if (debug) {
5064 mField.get_moab(),
5065 "crack_tets_" +
5066 boost::lexical_cast<std::string>(mField.get_comm_rank()) + ".vtk",
5067 get_crack_adj_tets(*crackFaces));
5068 CHKERR save_range(mField.get_moab(), "sides_first.vtk", sides_pair.first);
5069 CHKERR save_range(mField.get_moab(), "sides_second.vtk",
5070 sides_pair.second);
5071 MOFEM_LOG("EP", sev) << "Nb. layers " << layers_top.size();
5072 int l = 0;
5073 for (auto &r : layers_top) {
5074 MOFEM_LOG("EP", sev) << "Layer " << l << " size " << r.size();
5076 mField.get_moab(),
5077 "layers_top_" + boost::lexical_cast<std::string>(l) + ".vtk", r);
5078 ++l;
5079 }
5080
5081 l = 0;
5082 for (auto &r : layers_bottom) {
5083 MOFEM_LOG("EP", sev) << "Layer " << l << " size " << r.size();
5085 mField.get_moab(),
5086 "layers_bottom_" + boost::lexical_cast<std::string>(l) + ".vtk", r);
5087 ++l;
5088 }
5089 }
5090#endif
5091
5092 auto get_cross = [&](auto t_dir, auto f) {
5094 CHKERR mField.getInterface<Tools>()->getTriNormal(f, &t_normal(0));
5095 t_normal.normalize();
5100 t_cross(i) = FTensor::levi_civita(i, j, k) * t_normal(j) * t_dir(k);
5101 return t_cross;
5102 };
5103
5104 auto get_sense = [&](auto f, auto e) {
5105 int side, sense, offset;
5106 CHK_MOAB_THROW(mField.get_moab().side_number(f, e, side, sense, offset),
5107 "get sense");
5108 return std::make_tuple(side, sense, offset);
5109 };
5110
5111 auto calculate_edge_direction = [&](auto e, auto normalize = true) {
5112 const EntityHandle *conn;
5113 int num_nodes;
5114 CHKERR mField.get_moab().get_connectivity(e, conn, num_nodes, true);
5115 std::array<double, 6> coords;
5116 CHKERR mField.get_moab().get_coords(conn, num_nodes, coords.data());
5118 &coords[0], &coords[1], &coords[2]};
5120 &coords[3], &coords[4], &coords[5]};
5123 t_dir(i) = t_p1(i) - t_p0(i);
5124 if (normalize)
5125 t_dir.normalize();
5126 return t_dir;
5127 };
5128
5129 auto evaluate_face_energy_and_set_orientation = [&](auto front_edges,
5130 auto front_faces,
5131 auto &sides_pair,
5132 auto th_position) {
5134
5135 Tag th_face_energy;
5136 Tag th_material_force;
5137 switch (energyReleaseSelector) {
5138 case GRIFFITH_FORCE:
5139 case GRIFFITH_SKELETON:
5140 CHKERR mField.get_moab().tag_get_handle("GriffithForce",
5141 th_face_energy);
5142 CHKERR mField.get_moab().tag_get_handle("MaterialForce",
5143 th_material_force);
5144 break;
5145 default:
5146 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
5147 "Unknown energy release selector");
5148 };
5149
5150 /**
5151 * Iterate over front edges, get adjacent faces, find maximal face energy.
5152 * Maximal face energy is stored in the edge. Maximal face energy is
5153 * magnitude of edge Griffith force.
5154 */
5155 auto find_maximal_face_energy = [&](auto front_edges, auto front_faces,
5156 auto &edge_face_max_energy_map) {
5158
5159 Range body_ents;
5160 CHKERR mField.get_moab().get_entities_by_dimension(0, 3, body_ents);
5161 auto body_skin = get_skin(mField, body_ents);
5162
5163 Range max_faces;
5164
5165 for (auto e : front_edges) {
5166
5167 double griffith_force;
5168 CHKERR mField.get_moab().tag_get_data(th_face_energy, &e, 1,
5169 &griffith_force);
5170
5171 Range faces;
5172 CHKERR mField.get_moab().get_adjacencies(&e, 1, 2, false, faces);
5173 faces = subtract(intersect(faces, front_faces), body_skin);
5174 std::vector<double> face_energy(faces.size());
5175 CHKERR mField.get_moab().tag_get_data(th_face_energy, faces,
5176 face_energy.data());
5177 auto max_energy_it =
5178 std::max_element(face_energy.begin(), face_energy.end());
5179 double max_energy =
5180 max_energy_it != face_energy.end() ? *max_energy_it : 0;
5181
5182 edge_face_max_energy_map[e] =
5183 std::make_tuple(faces[max_energy_it - face_energy.begin()],
5184 griffith_force, static_cast<double>(0));
5185 MOFEM_LOG("EP", Sev::inform)
5186 << "Edge " << e << " griffith force " << griffith_force
5187 << " max face energy " << max_energy << " factor "
5188 << max_energy / griffith_force;
5189
5190 max_faces.insert(faces[max_energy_it - face_energy.begin()]);
5191 }
5192
5193#ifndef NDEBUG
5194 if (debug) {
5196 mField.get_moab(),
5197 "max_faces_" +
5198 boost::lexical_cast<std::string>(mField.get_comm_rank()) +
5199 ".vtk",
5200 max_faces);
5201 }
5202#endif
5203
5205 };
5206
5207 /**
5208 * For each front edge, find maximal face energy and orientation. This is
5209 * by finding angle between edge material force and maximal face normal
5210 *
5211 */
5212 auto calculate_face_orientation = [&](auto &edge_face_max_energy_map) {
5214
5215 auto up_down_face = [&](
5216
5217 auto &face_angle_map_up,
5218 auto &face_angle_map_down
5219
5220 ) {
5222
5223 for (auto &m : edge_face_max_energy_map) {
5224 auto e = m.first;
5225 auto [max_face, energy, opt_angle] = m.second;
5226
5227 Range faces;
5228 CHKERR mField.get_moab().get_adjacencies(&e, 1, 2, false, faces);
5229 faces = intersect(faces, front_faces);
5230 Range adj_tets; // tetrahedrons adjacent to the face
5231 CHKERR mField.get_moab().get_adjacencies(&max_face, 1, SPACE_DIM,
5232 false, adj_tets,
5233 moab::Interface::UNION);
5234 if (adj_tets.size()) {
5235
5236 Range adj_tets; // tetrahedrons adjacent to the face
5237 CHKERR mField.get_moab().get_adjacencies(&max_face, 1, SPACE_DIM,
5238 false, adj_tets,
5239 moab::Interface::UNION);
5240 if (adj_tets.size()) {
5241
5242 Range adj_tets_faces;
5243 // get faces
5244 CHKERR mField.get_moab().get_adjacencies(
5245 adj_tets, SPACE_DIM - 1, false, adj_tets_faces,
5246 moab::Interface::UNION);
5247 adj_tets_faces = intersect(adj_tets_faces, faces);
5249
5250 // cross product of face normal and edge direction
5251 auto t_cross_max =
5252 get_cross(calculate_edge_direction(e, true), max_face);
5253 auto [side_max, sense_max, offset_max] = get_sense(max_face, e);
5254 t_cross_max(i) *= sense_max;
5255
5256 for (auto t : adj_tets) {
5257 Range adj_tets_faces;
5258 CHKERR mField.get_moab().get_adjacencies(
5259 &t, 1, SPACE_DIM - 1, false, adj_tets_faces);
5260 adj_tets_faces = intersect(adj_tets_faces, faces);
5261 adj_tets_faces =
5262 subtract(adj_tets_faces, Range(max_face, max_face));
5263
5264 if (adj_tets_faces.size() == 1) {
5265
5266 // cross product of adjacent face normal and edge
5267 // direction
5268 auto t_cross = get_cross(calculate_edge_direction(e, true),
5269 adj_tets_faces[0]);
5270 auto [side, sense, offset] =
5271 get_sense(adj_tets_faces[0], e);
5272 t_cross(i) *= sense;
5273 double dot = t_cross(i) * t_cross_max(i);
5274 auto angle = std::acos(dot);
5275
5276 double face_energy;
5277 CHKERR mField.get_moab().tag_get_data(
5278 th_face_energy, adj_tets_faces, &face_energy);
5279
5280 auto [side_face, sense_face, offset_face] =
5281 get_sense(t, max_face);
5282
5283 if (sense_face > 0) {
5284 face_angle_map_up[e] = std::make_tuple(face_energy, angle,
5285 adj_tets_faces[0]);
5286
5287 } else {
5288 face_angle_map_down[e] = std::make_tuple(
5289 face_energy, -angle, adj_tets_faces[0]);
5290 }
5291 }
5292 }
5293 }
5294 }
5295 }
5296
5298 };
5299
5300 auto calc_optimal_angle = [&](
5301
5302 auto &face_angle_map_up,
5303 auto &face_angle_map_down
5304
5305 ) {
5307
5308 for (auto &m : edge_face_max_energy_map) {
5309 auto e = m.first;
5310 auto &[max_face, e0, a0] = m.second;
5311
5312 if (std::abs(e0) > std::numeric_limits<double>::epsilon()) {
5313
5314 if (face_angle_map_up.find(e) == face_angle_map_up.end() ||
5315 face_angle_map_down.find(e) == face_angle_map_down.end()) {
5316 // Do nothing
5317 } else {
5318
5319 switch (energyReleaseSelector) {
5320 case GRIFFITH_FORCE:
5321 case GRIFFITH_SKELETON: {
5322
5323 Tag th_material_force;
5324 CHKERR mField.get_moab().tag_get_handle("MaterialForce",
5325 th_material_force);
5326 FTensor::Tensor1<double, SPACE_DIM> t_material_force;
5327 CHKERR mField.get_moab().tag_get_data(
5328 th_material_force, &e, 1, &t_material_force(0));
5329 auto material_force_magnitude = t_material_force.l2();
5330 if (material_force_magnitude <
5331 std::numeric_limits<double>::epsilon()) {
5332 a0 = 0;
5333
5334 } else {
5335
5336 auto t_edge_dir = calculate_edge_direction(e, true);
5337 auto t_cross_max = get_cross(t_edge_dir, max_face);
5338 auto [side, sense, offset] = get_sense(max_face, e);
5339 t_cross_max(sense) *= sense;
5340
5344
5345 t_material_force.normalize();
5346 t_cross_max.normalize();
5348 t_cross(I) = FTensor::levi_civita(I, J, K) *
5349 t_material_force(J) * t_cross_max(K);
5350 a0 = -std::asin(t_cross(I) * t_edge_dir(I));
5351
5352 MOFEM_LOG("EP", sev)
5353 << "Optimal angle " << a0 << " energy " << e0;
5354 }
5355 break;
5356 }
5357 default: {
5358
5359 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
5360 "Unknown energy release selector");
5361 }
5362 }
5363 }
5364 }
5365 }
5366
5368 };
5369
5370 std::map<EntityHandle, std::tuple<double, double, EntityHandle>>
5371 face_angle_map_up;
5372 std::map<EntityHandle, std::tuple<double, double, EntityHandle>>
5373 face_angle_map_down;
5374 CHKERR up_down_face(face_angle_map_up, face_angle_map_down);
5375 CHKERR calc_optimal_angle(face_angle_map_up, face_angle_map_down);
5376
5377#ifndef NDEBUG
5378 if (debug) {
5379 auto th_angle = get_tags_vec("Angle", 1);
5380 Range up;
5381 for (auto &m : face_angle_map_up) {
5382 auto [e, a, face] = m.second;
5383 up.insert(face);
5384 CHKERR mField.get_moab().tag_set_data(th_angle[0], &face, 1, &a);
5385 }
5386 Range down;
5387 for (auto &m : face_angle_map_down) {
5388 auto [e, a, face] = m.second;
5389 down.insert(face);
5390 CHKERR mField.get_moab().tag_set_data(th_angle[0], &face, 1, &a);
5391 }
5392
5393 Range max_energy_faces;
5394 for (auto &m : edge_face_max_energy_map) {
5395 auto [face, e, angle] = m.second;
5396 max_energy_faces.insert(face);
5397 CHKERR mField.get_moab().tag_set_data(th_angle[0], &face, 1,
5398 &angle);
5399 }
5400 if (mField.get_comm_rank() == 0) {
5401 CHKERR save_range(mField.get_moab(), "up_faces.vtk", up);
5402 CHKERR save_range(mField.get_moab(), "down_faces.vtk", down);
5403 CHKERR save_range(mField.get_moab(), "max_energy_faces.vtk",
5404 max_energy_faces);
5405 }
5406 }
5407#endif // NDEBUG
5408
5410 };
5411
5412 auto get_conn = [&](auto e) {
5413 Range conn;
5414 CHK_MOAB_THROW(mField.get_moab().get_connectivity(e, conn, true),
5415 "get conn");
5416 return conn;
5417 };
5418
5419 auto get_adj = [&](auto e, auto dim) {
5420 Range adj;
5421 CHK_MOAB_THROW(mField.get_moab().get_adjacencies(
5422 e, dim, false, adj, moab::Interface::UNION),
5423 "get adj");
5424 return adj;
5425 };
5426
5427 auto get_coords = [&](auto v) {
5429 CHK_MOAB_THROW(mField.get_moab().get_coords(v, &t_coords(0)),
5430 "get coords");
5431 return t_coords;
5432 };
5433
5434 // calulate normal of the max energy face
5435 auto get_rotated_normal = [&](auto e, auto f, auto angle) {
5438 auto t_edge_dir = calculate_edge_direction(e, true);
5439 auto [side, sense, offset] = get_sense(f, e);
5440 t_edge_dir(i) *= sense;
5441 t_edge_dir.normalize();
5442 t_edge_dir(i) *= angle;
5443 auto t_R = LieGroups::SO3::exp(t_edge_dir, angle);
5445 mField.getInterface<Tools>()->getTriNormal(f, &t_normal(0));
5446 FTensor::Tensor1<double, SPACE_DIM> t_rotated_normal;
5447 t_rotated_normal(i) = t_R(i, j) * t_normal(j);
5448 return std::make_tuple(t_normal, t_rotated_normal);
5449 };
5450
5451 auto set_coord = [&](auto v, auto &adj_vertex_tets_verts, auto &coords,
5452 auto &t_move, auto gamma) {
5453 auto index = adj_vertex_tets_verts.index(v);
5454 if (index >= 0) {
5455 for (auto ii : {0, 1, 2}) {
5456 coords[3 * index + ii] += gamma * t_move(ii);
5457 }
5458 return true;
5459 }
5460 return false;
5461 };
5462
5463 auto tets_quality = [&](auto quality, auto &adj_vertex_tets_verts,
5464 auto &adj_vertex_tets, auto &coords) {
5465 for (auto t : adj_vertex_tets) {
5466 const EntityHandle *conn;
5467 int num_nodes;
5468 CHKERR mField.get_moab().get_connectivity(t, conn, num_nodes, true);
5469 std::array<double, 12> tet_coords;
5470 for (auto n = 0; n != 4; ++n) {
5471 auto index = adj_vertex_tets_verts.index(conn[n]);
5472 if (index < 0) {
5474 }
5475 for (auto ii = 0; ii != 3; ++ii) {
5476 tet_coords[3 * n + ii] = coords[3 * index + ii];
5477 }
5478 }
5479 double q = Tools::volumeLengthQuality(tet_coords.data());
5480 if (!std::isnormal(q))
5481 q = -2;
5482 quality = std::min(quality, q);
5483 };
5484
5485 return quality;
5486 };
5487
5488 auto calculate_free_face_node_displacement =
5489 [&](auto &edge_face_max_energy_map) {
5490 // get edges adjacent to vertex along which nodes are moving
5491 auto get_vertex_edges = [&](auto vertex) {
5492 Range vertex_edges; // edges adjacent to vertex
5493
5494 auto impl = [&]() {
5496 CHKERR mField.get_moab().get_adjacencies(vertex, 1, false,
5497 vertex_edges);
5498 vertex_edges = subtract(vertex_edges, front_verts_edges);
5499
5500 if (boundary_skin_verts.size() &&
5501 boundary_skin_verts.find(vertex[0]) !=
5502 boundary_skin_verts.end()) {
5503 MOFEM_LOG("EP", sev) << "Boundary vertex";
5504 vertex_edges = intersect(vertex_edges, body_skin_edges);
5505 }
5506 if (geometry_edges_verts.size() &&
5507 geometry_edges_verts.find(vertex[0]) !=
5508 geometry_edges_verts.end()) {
5509 MOFEM_LOG("EP", sev) << "Geometry edge vertex";
5510 vertex_edges = intersect(vertex_edges, geometry_edges);
5511 }
5512 if (crack_faces_verts.size() &&
5513 crack_faces_verts.find(vertex[0]) !=
5514 crack_faces_verts.end()) {
5515 MOFEM_LOG("EP", sev) << "Crack face vertex";
5516 vertex_edges = intersect(vertex_edges, crack_faces_edges);
5517 }
5519 };
5520
5521 CHK_THROW_MESSAGE(impl(), "get_vertex_edges");
5522
5523 return vertex_edges;
5524 };
5525
5526 // vector of rotated faces, edge along node is moved, moved edge,
5527 // moved displacement, quality, cardinality, gamma
5528 using Bundle = std::vector<
5529
5532
5533 >;
5534 std::map<EntityHandle, Bundle> edge_bundle_map;
5535
5536 for (auto &m : edge_face_max_energy_map) {
5537
5538 auto edge = m.first;
5539 auto &[max_face, energy, opt_angle] = m.second;
5540
5541 // calculate rotation of max energy face
5542 auto [t_normal, t_rotated_normal] =
5543 get_rotated_normal(edge, max_face, opt_angle);
5544
5545 auto front_vertex = get_conn(Range(m.first, m.first));
5546 auto adj_tets = get_adj(Range(max_face, max_face), 3);
5547 auto adj_tets_faces = get_adj(adj_tets, 2);
5548 auto adj_front_faces = subtract(
5549 intersect(get_adj(Range(edge, edge), 2), adj_tets_faces),
5550 *crackFaces);
5551 if (adj_front_faces.size() > 3)
5553 "adj_front_faces.size()>3");
5554
5555 FTensor::Tensor1<double, SPACE_DIM> t_material_force;
5556 CHKERR mField.get_moab().tag_get_data(th_material_force, &edge, 1,
5557 &t_material_force(0));
5558 std::vector<double> griffith_energy(adj_front_faces.size());
5559 CHKERR mField.get_moab().tag_get_data(
5560 th_face_energy, adj_front_faces, griffith_energy.data());
5561
5562
5563 auto set_edge_bundle = [&](auto min_gamma) {
5564 for (auto rotated_f : adj_front_faces) {
5565
5566 double rotated_face_energy =
5567 griffith_energy[adj_front_faces.index(rotated_f)];
5568
5569 auto vertex = subtract(get_conn(Range(rotated_f, rotated_f)),
5570 front_vertex);
5571 if (vertex.size() != 1) {
5573 "Wrong number of vertex to move");
5574 }
5575 auto front_vertex_edges_vertex = get_conn(
5576 intersect(get_adj(front_vertex, 1), crack_faces_edges));
5577 vertex = subtract(
5578 vertex, front_vertex_edges_vertex); // vertex free to move
5579 if (vertex.empty()) {
5580 continue;
5581 }
5582
5583 auto face_cardinality = [&](auto f, auto &seen_front_edges) {
5584 auto whole_front =
5585 unite(*frontEdges,
5586 subtract(body_skin_edges, crack_faces_edges));
5587 auto faces = Range(f, f);
5588 int c = 0;
5589 for (; c < 10; ++c) {
5590 auto front_edges =
5591 subtract(get_adj(faces, 1), seen_front_edges);
5592 if (front_edges.size() == 0) {
5593 return 0;
5594 }
5595 auto front_connected_edges =
5596 intersect(front_edges, whole_front);
5597 if (front_connected_edges.size()) {
5598 seen_front_edges.merge(front_connected_edges);
5599 return c;
5600 }
5601 faces.merge(get_adj(front_edges, 2));
5602 ++c;
5603 }
5604 return c;
5605 };
5606
5607 Range seen_edges = Range(edge, edge);
5608 double rotated_face_cardinality = face_cardinality(
5609 rotated_f,
5610 seen_edges); // add cardinality of max energy
5611 // face to rotated face cardinality
5612 // rotated_face_cardinality +=
5613 // face_cardinality(max_face, seen_edges);
5614 rotated_face_cardinality = std::max(rotated_face_cardinality,
5615 1.); // at least one edge
5616
5617 auto t_vertex_coords = get_coords(vertex);
5618 auto vertex_edges = get_vertex_edges(vertex);
5619
5620 EntityHandle f0 = front_vertex[0];
5621 EntityHandle f1 = front_vertex[1];
5622 FTensor::Tensor1<double, 3> t_v_e0, t_v_e1;
5623 CHKERR mField.get_moab().get_coords(&f0, 1, &t_v_e0(0));
5624 CHKERR mField.get_moab().get_coords(&f1, 1, &t_v_e1(0));
5625
5627 for (auto e_used_to_move_detection : vertex_edges) {
5628 auto edge_conn = get_conn(Range(e_used_to_move_detection,
5629 e_used_to_move_detection));
5630 edge_conn = subtract(edge_conn, vertex);
5631 // Find displacement of the edge such that dot porduct with
5632 // normal is zero.
5633 //
5634 // { (t_v0 - t_vertex_coords) + gamma * (t_v3 -
5635 // t_vertex_coords) } * n = 0
5636 // where t_v0 is the edge vertex, t_v3 is the edge end
5637 // point, n is the rotated normal of the face gamma is the
5638 // factor by which the edge is moved
5640 t_v0(i) = (t_v_e0(i) + t_v_e1(i)) / 2;
5642 CHKERR mField.get_moab().get_coords(edge_conn, &t_v3(0));
5643 auto a =
5644 (t_v0(i) - t_vertex_coords(i)) * t_rotated_normal(i);
5645 auto b =
5646 (t_v3(i) - t_vertex_coords(i)) * t_rotated_normal(i);
5647 auto gamma = a / b;
5648
5649 constexpr double eps =
5650 std::numeric_limits<double>::epsilon();
5651 if (std::isnormal(gamma) && gamma < 1.0 - eps &&
5652 gamma > -0.1) {
5654 t_move(i) = gamma * (t_v3(i) - t_vertex_coords(i));
5655
5656 auto check_rotated_face_directoon = [&]() {
5658 t_delta(i) = t_vertex_coords(i) + t_move(i) - t_v0(i);
5659 t_delta.normalize();
5660 auto dot =
5661 (t_material_force(i) / t_material_force.l2()) *
5662 t_delta(i);
5663 return -dot > 0 ? true : false;
5664 };
5665
5666 if (check_rotated_face_directoon()) {
5667
5668 MOFEM_LOG("EP", Sev::inform)
5669 << "Crack edge " << edge << " moved face "
5670 << rotated_f
5671 << " edge: " << e_used_to_move_detection
5672 << " face direction/energy " << rotated_face_energy
5673 << " face cardinality " << rotated_face_cardinality
5674 << " gamma: " << gamma;
5675
5676 auto &bundle = edge_bundle_map[edge];
5677 bundle.emplace_back(rotated_f, e_used_to_move_detection,
5678 vertex[0], t_move, 1,
5679 rotated_face_cardinality, gamma);
5680 }
5681 }
5682 }
5683 }
5684 };
5685
5686 set_edge_bundle(std::numeric_limits<double>::epsilon());
5687 if (edge_bundle_map[edge].empty()) {
5688 set_edge_bundle(-1.);
5689 }
5690 }
5691
5692 return edge_bundle_map;
5693 };
5694
5695 auto get_sort_by_energy = [&](auto &edge_face_max_energy_map) {
5696 std::map<double, std::tuple<EntityHandle, EntityHandle, double>>
5697 sort_by_energy;
5698
5699 for (auto &m : edge_face_max_energy_map) {
5700 auto e = m.first;
5701 auto &[max_face, energy, opt_angle] = m.second;
5702 sort_by_energy[energy] = std::make_tuple(e, max_face, opt_angle);
5703 }
5704
5705 return sort_by_energy;
5706 };
5707
5708 auto set_tag = [&](auto &&adj_edges_map, auto &&sort_by_energy) {
5710
5711 Tag th_face_pressure;
5713 mField.get_moab().tag_get_handle("FacePressure", th_face_pressure),
5714 "get tag");
5715 auto get_face_pressure = [&](auto face) {
5716 double pressure;
5717 CHK_MOAB_THROW(mField.get_moab().tag_get_data(th_face_pressure, &face,
5718 1, &pressure),
5719 "get rag data");
5720 return pressure;
5721 };
5722
5723 MOFEM_LOG("EPSELF", Sev::inform)
5724 << "Number of edges to check " << sort_by_energy.size();
5725
5726 enum face_energy { POSITIVE, NEGATIVE };
5727 constexpr bool skip_negative = true;
5728
5729 for (auto fe : {face_energy::POSITIVE, face_energy::NEGATIVE}) {
5730
5731 // iterate edges wih maximal energy, and make them seed. Such edges,
5732 // will most likely will have also smallest node displacement
5733 for (auto it = sort_by_energy.rbegin(); it != sort_by_energy.rend();
5734 ++it) {
5735
5736 auto energy = it->first;
5737 auto [max_edge, max_face, opt_angle] = it->second;
5738
5739 auto face_pressure = get_face_pressure(max_face);
5740 if (skip_negative) {
5741 if (fe == face_energy::POSITIVE) {
5742 if (face_pressure < 0) {
5743 MOFEM_LOG("EPSELF", Sev::inform)
5744 << "Skip negative face " << max_face << " with energy "
5745 << energy << " and pressure " << face_pressure;
5746 continue;
5747 }
5748 }
5749 }
5750
5751 MOFEM_LOG("EPSELF", Sev::inform)
5752 << "Check face " << max_face << " edge " << max_edge
5753 << " energy " << energy << " optimal angle " << opt_angle
5754 << " face pressure " << face_pressure;
5755
5756 auto jt = adj_edges_map.find(max_edge);
5757 if (jt == adj_edges_map.end()) {
5758 MOFEM_LOG("EPSELF", Sev::warning)
5759 << "Edge " << max_edge << " not found in adj_edges_map";
5760 continue;
5761 }
5762 auto &bundle = jt->second;
5763
5764 auto find_max_in_bundle_impl = [&](auto edge, auto &bundle,
5765 auto gamma) {
5767
5768 EntityHandle vertex_max = 0;
5769 EntityHandle face_max = 0;
5770 EntityHandle move_edge_max = 0;
5771 double max_quality = -2;
5772 double max_quality_evaluated = -2;
5773 double min_cardinality = std::numeric_limits<double>::max();
5774
5775 FTensor::Tensor1<double, SPACE_DIM> t_move_last{0., 0., 0.};
5776
5777 for (auto &b : bundle) {
5778 auto &[face, move_edge, vertex, t_move, quality, cardinality,
5779 edge_gamma] = b;
5780
5781 auto adj_vertex_tets = get_adj(Range(vertex, vertex), 3);
5782 auto adj_vertex_tets_verts = get_conn(adj_vertex_tets);
5783 std::vector<double> coords(3 * adj_vertex_tets_verts.size());
5784 CHK_MOAB_THROW(mField.get_moab().get_coords(
5785 adj_vertex_tets_verts, coords.data()),
5786 "get coords");
5787
5788 set_coord(vertex, adj_vertex_tets_verts, coords, t_move, gamma);
5789 quality = tets_quality(quality, adj_vertex_tets_verts,
5790 adj_vertex_tets, coords);
5791
5792 auto eval_quality = [](auto q, auto c, auto edge_gamma) {
5793 if (q < 0) {
5794 return q;
5795 } else {
5796 return ((edge_gamma < 0) ? (q / 2) : q) / pow(c, 2);
5797 }
5798 };
5799
5800 if (eval_quality(quality, cardinality, edge_gamma) >=
5801 max_quality_evaluated) {
5802 max_quality = quality;
5803 min_cardinality = cardinality;
5804 vertex_max = vertex;
5805 face_max = face;
5806 move_edge_max = move_edge;
5807 t_move_last(i) = t_move(i);
5808 max_quality_evaluated =
5809 eval_quality(max_quality, min_cardinality, edge_gamma);
5810 }
5811 }
5812
5813 return std::make_tuple(vertex_max, face_max, t_move_last,
5814 max_quality, min_cardinality);
5815 };
5816
5817 auto find_max_in_bundle = [&](auto edge, auto &bundle) {
5818 auto b_org_bundle = bundle;
5819 auto r = find_max_in_bundle_impl(edge, bundle, 1.);
5820 auto &[vertex_max, face_max, t_move_last, max_quality,
5821 cardinality] = r;
5822 if (max_quality < 0) {
5823 for (double gamma = 0.95; gamma >= 0.45; gamma -= 0.05) {
5824 bundle = b_org_bundle;
5825 r = find_max_in_bundle_impl(edge, bundle, gamma);
5826 auto &[vertex_max, face_max, t_move_last, max_quality,
5827 cardinality] = r;
5828 MOFEM_LOG("EPSELF", Sev::warning)
5829 << "Back tracking: gamma " << gamma << " edge " << edge
5830 << " quality " << max_quality << " cardinality "
5831 << cardinality;
5832 if (max_quality > 0.01) {
5834 t_move_last(I) *= gamma;
5835 return r;
5836 }
5837 }
5839 t_move_last(I) = 0;
5840 }
5841 return r;
5842 };
5843
5844 // set tags with displacement of node and face energy
5845 auto set_tag_to_vertex_and_face = [&](auto &&r, auto &quality) {
5847 auto &[v, f, t_move, q, cardinality] = r;
5848
5849 if ((q > 0 && std::isnormal(q)) && energy > 0) {
5850
5851 MOFEM_LOG("EPSELF", Sev::inform)
5852 << "Set tag: vertex " << v << " face " << f << " "
5853 << max_edge << " move " << t_move << " energy " << energy
5854 << " quality " << q << " cardinality " << cardinality;
5855 CHKERR mField.get_moab().tag_set_data(th_position[0], &v, 1,
5856 &t_move(0));
5857 CHKERR mField.get_moab().tag_set_data(th_max_face_energy[0], &f,
5858 1, &energy);
5859 }
5860
5861 quality = q;
5863 };
5864
5865 double quality = -2;
5866 CHKERR set_tag_to_vertex_and_face(
5867
5868 find_max_in_bundle(max_edge, bundle),
5869
5870 quality
5871
5872 );
5873
5874 if (quality > 0 && std::isnormal(quality) && energy > 0) {
5875 MOFEM_LOG("EPSELF", Sev::inform)
5876 << "Crack face set with quality: " << quality;
5878 }
5879 }
5880
5881 if (!skip_negative)
5882 break;
5883 }
5884
5886 };
5887
5888 // map: {edge, {face, energy, optimal_angle}}
5889 MOFEM_LOG("EP", sev) << "Calculate orientation";
5890 std::map<EntityHandle, std::tuple<EntityHandle, double, double>>
5891 edge_face_max_energy_map;
5892 CHKERR find_maximal_face_energy(front_edges, front_faces,
5893 edge_face_max_energy_map);
5894 CHKERR calculate_face_orientation(edge_face_max_energy_map);
5895
5896 MOFEM_LOG("EP", sev) << "Calculate node positions";
5897 CHKERR set_tag(
5898
5899 calculate_free_face_node_displacement(edge_face_max_energy_map),
5900 get_sort_by_energy(edge_face_max_energy_map)
5901
5902 );
5903
5905 };
5906
5907 MOFEM_LOG("EP", sev) << "Front edges " << frontEdges->size();
5908 CHKERR evaluate_face_energy_and_set_orientation(
5909 *frontEdges, get_adj_front(false), sides_pair, th_front_position);
5910 }
5911
5912 // exchange positions and energies from processor zero to all other
5913 CHKERR VecZeroEntries(vertexExchange.second);
5914 CHKERR VecGhostUpdateBegin(vertexExchange.second, INSERT_VALUES,
5915 SCATTER_FORWARD);
5916 CHKERR VecGhostUpdateEnd(vertexExchange.second, INSERT_VALUES,
5917 SCATTER_FORWARD);
5918 CHKERR mField.getInterface<CommInterface>()->updateEntitiesPetscVector(
5919 mField.get_moab(), vertexExchange, th_front_position[0]);
5920 CHKERR VecZeroEntries(faceExchange.second);
5921 CHKERR VecGhostUpdateBegin(faceExchange.second, INSERT_VALUES,
5922 SCATTER_FORWARD);
5923 CHKERR VecGhostUpdateEnd(faceExchange.second, INSERT_VALUES, SCATTER_FORWARD);
5924 CHKERR mField.getInterface<CommInterface>()->updateEntitiesPetscVector(
5925 mField.get_moab(), faceExchange, th_max_face_energy[0]);
5926
5927 auto get_max_moved_faces = [&]() {
5928 Range max_moved_faces;
5929 auto adj_front = get_adj_front(false);
5930 std::vector<double> face_energy(adj_front.size());
5931 CHKERR mField.get_moab().tag_get_data(th_max_face_energy[0], adj_front,
5932 face_energy.data());
5933 for (int i = 0; i != adj_front.size(); ++i) {
5934 if (face_energy[i] > std::numeric_limits<double>::epsilon()) {
5935 max_moved_faces.insert(adj_front[i]);
5936 }
5937 }
5938
5939 return boost::make_shared<Range>(max_moved_faces);
5940 };
5941
5942 // move all faces with energy larger than 0
5943 maxMovedFaces = get_max_moved_faces();
5944 MOFEM_LOG("EP", sev) << "Number of of moved faces: " << maxMovedFaces->size();
5945
5946#ifndef NDEBUG
5947 if (debug) {
5949 mField.get_moab(),
5950 "max_moved_faces_" +
5951 boost::lexical_cast<std::string>(mField.get_comm_rank()) + ".vtk",
5952 *maxMovedFaces);
5953 }
5954#endif
5955
5957}
static auto get_two_sides_of_crack_surface(MoFEM::Interface &m_field, Range crack_faces)
constexpr double a
static const double eps
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ MOFEM_ATOM_TEST_INVALID
Definition definitions.h:40
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
constexpr double a0
const double c
speed of light (cm/ns)
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
FTensor::Index< 'm', 3 > m
CommInterface::EntitiesPetscVector vertexExchange
static enum EnergyReleaseSelector energyReleaseSelector
static auto exp(A &&t_w_vee, B &&theta)
Definition Lie.hpp:48
static double volumeLengthQuality(const double *coords)
Calculate tetrahedron volume length quality.
Definition Tools.cpp:15

◆ createCrackSurfaceMeshset()

MoFEMErrorCode EshelbianCore::createCrackSurfaceMeshset ( )
Examples
EshelbianPlasticity.cpp, and ep.cpp.

Definition at line 6755 of file EshelbianPlasticity.cpp.

6755 {
6757 auto meshset_mng = mField.getInterface<MeshsetsManager>();
6758 while (meshset_mng->checkMeshset(addCrackMeshsetId, BLOCKSET))
6760 MOFEM_LOG("EP", Sev::inform)
6761 << "Crack added surface meshset " << addCrackMeshsetId;
6762 CHKERR meshset_mng->addMeshset(BLOCKSET, addCrackMeshsetId, "CRACK_COMPUTED");
6764};
MoFEMErrorCode addMeshset(const CubitBCType cubit_bc_type, const int ms_id, const std::string name="")
add cubit meshset

◆ createExchangeVectors()

MoFEMErrorCode EshelbianCore::createExchangeVectors ( Sev  sev)
Examples
EshelbianPlasticity.cpp, and ep.cpp.

Definition at line 7060 of file EshelbianPlasticity.cpp.

7060 {
7062
7063 auto print_loc_size = [this](auto v, auto str, auto sev) {
7065 int size;
7066 CHKERR VecGetLocalSize(v.second, &size);
7067 int low, high;
7068 CHKERR VecGetOwnershipRange(v.second, &low, &high);
7069 MOFEM_LOG("EPSYNC", sev) << str << " local size " << size << " ( " << low
7070 << " " << high << " ) ";
7073 };
7074
7076 mField.get_comm(), mField.get_moab(), 3, 1, sev);
7077 CHKERR print_loc_size(volumeExchange, "volumeExchange", sev);
7079 mField.get_comm(), mField.get_moab(), 2, 1, Sev::inform);
7080 CHKERR print_loc_size(faceExchange, "faceExchange", sev);
7082 mField.get_comm(), mField.get_moab(), 1, 1, Sev::inform);
7083 CHKERR print_loc_size(edgeExchange, "edgeExchange", sev);
7085 mField.get_comm(), mField.get_moab(), 0, 3, Sev::inform);
7086 CHKERR print_loc_size(vertexExchange, "vertexExchange", sev);
7087
7089}
CommInterface::EntitiesPetscVector volumeExchange

◆ d_f_linear()

static double EshelbianCore::d_f_linear ( const double  v)
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 159 of file EshelbianCore.hpp.

159{ return 1; }

◆ d_f_log()

static double EshelbianCore::d_f_log ( const double  v)
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 140 of file EshelbianCore.hpp.

140 {
141 return pow(exponentBase, v) * log(EshelbianCore::exponentBase);
142 }
static double exponentBase

◆ d_f_log_e()

static double EshelbianCore::d_f_log_e ( const double  v)
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 95 of file EshelbianCore.hpp.

95 {
96 if constexpr (use_quadratic_exp) {
97 return d_f_log_e_quadratic(v);
98 } else {
99 if (v > v_max)
100 return std::exp(v_max);
101 else
102 return std::exp(v);
103 }
104 }
static constexpr bool use_quadratic_exp
static constexpr double v_max
static double d_f_log_e_quadratic(const double v)

◆ d_f_log_e_quadratic()

static double EshelbianCore::d_f_log_e_quadratic ( const double  v)
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 64 of file EshelbianCore.hpp.

64 {
65 if (v > v_max) {
66 double e = static_cast<double>(std::exp(v_max));
67 double dv = v - v_max;
68 return e * dv + e;
69 } else {
70 return static_cast<double>(std::exp(v));
71 }
72 }

◆ dd_f_linear()

static double EshelbianCore::dd_f_linear ( const double  v)
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 160 of file EshelbianCore.hpp.

160{ return 0; }

◆ dd_f_log()

static double EshelbianCore::dd_f_log ( const double  v)
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 143 of file EshelbianCore.hpp.

◆ dd_f_log_e()

static double EshelbianCore::dd_f_log_e ( const double  v)
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 105 of file EshelbianCore.hpp.

105 {
106 if constexpr (use_quadratic_exp) {
107 return dd_f_log_e_quadratic(v);
108 } else {
109 if (v > v_max)
110 return 0.;
111 else
112 return std::exp(v);
113 }
114 }
static double dd_f_log_e_quadratic(const double v)

◆ dd_f_log_e_quadratic()

static double EshelbianCore::dd_f_log_e_quadratic ( const double  v)
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 74 of file EshelbianCore.hpp.

74 {
75 if (v > v_max) {
76 return static_cast<double>(std::exp(v_max));
77 } else {
78 return static_cast<double>(std::exp(v));
79 }
80 }

◆ f_linear()

static double EshelbianCore::f_linear ( const double  v)
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 158 of file EshelbianCore.hpp.

158{ return v + 1; }

◆ f_log()

static double EshelbianCore::f_log ( const double  v)
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 137 of file EshelbianCore.hpp.

137 {
138 return pow(EshelbianCore::exponentBase, v);
139 }

◆ f_log_e()

static double EshelbianCore::f_log_e ( const double  v)
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 82 of file EshelbianCore.hpp.

82 {
83 if constexpr(use_quadratic_exp) {
84 return f_log_e_quadratic(v);
85 } else {
86 if (v > v_max)
87 // y = exp(v_max) * v + exp(v_max) * (1 - v_max);
88 // y/exp(v_max) = v + (1 - v_max);
89 // y/exp(v_max) - (1 - v_max) = v;
90 return std::exp(v_max) * v + std::exp(v_max) * (1 - v_max);
91 else
92 return std::exp(v);
93 }
94 }
static double f_log_e_quadratic(const double v)

◆ f_log_e_quadratic()

static double EshelbianCore::f_log_e_quadratic ( const double  v)
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 54 of file EshelbianCore.hpp.

54 {
55 if (v > v_max) {
56 double e = static_cast<double>(std::exp(v_max));
57 double dv = v - v_max;
58 return 0.5 * e * dv * dv + e * dv + e;
59 } else {
60 return static_cast<double>(std::exp(v));
61 }
62 }

◆ getBc()

template<typename BC >
MoFEMErrorCode EshelbianCore::getBc ( boost::shared_ptr< BC > &  bc_vec_ptr,
const std::string  block_name,
const int  nb_attributes 
)
inline
Examples
EshelbianPlasticity.cpp.

Definition at line 243 of file EshelbianCore.hpp.

244 {
246 for (auto it :
247 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
248
249 (boost::format("%s(.*)") % block_name).str()
250
251 ))
252
253 ) {
254 std::vector<double> block_attributes;
255 CHKERR it->getAttributes(block_attributes);
256 if (block_attributes.size() < nb_attributes) {
257 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
258 "In block %s expected %d attributes, but given %ld",
259 it->getName().c_str(), nb_attributes, block_attributes.size());
260 }
261 Range faces;
262 CHKERR it->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2, faces,
263 true);
264 bc_vec_ptr->emplace_back(it->getName(), block_attributes, faces);
265 }
267 }
IFACE getInterface() const
Get interface pointer to pointer of interface.

◆ getExternalStrain()

MoFEMErrorCode EshelbianCore::getExternalStrain ( )
Examples
EshelbianPlasticity.cpp, and ep.cpp.

Definition at line 7013 of file EshelbianPlasticity.cpp.

7013 {
7015
7016 auto getExternalStrain = [&](boost::shared_ptr<ExternalStrainVec> &ext_strain_vec_ptr,
7017 const std::string block_name,
7018 const int nb_attributes) {
7020 for (auto it : mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
7021 std::regex((boost::format("%s(.*)") % block_name).str()))
7022 ) {
7023 std::vector<double> block_attributes;
7024 CHKERR it->getAttributes(block_attributes);
7025 if (block_attributes.size() < nb_attributes) {
7026 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
7027 "In block %s expected %d attributes, but given %ld",
7028 it->getName().c_str(), nb_attributes, block_attributes.size());
7029 }
7030
7031 auto get_block_ents = [&]() {
7032 Range ents;
7033 CHKERR mField.get_moab().get_entities_by_handle(it->meshset, ents,
7034 true);
7035 return ents;
7036 };
7037 auto Ents = get_block_ents();
7038 ext_strain_vec_ptr->emplace_back(it->getName(), block_attributes,
7039 get_block_ents());
7040 }
7042 };
7043
7044 externalStrainVecPtr = boost::make_shared<ExternalStrainVec>();
7045 CHKERR getExternalStrain(externalStrainVecPtr, "EXTERNALSTRAIN", 2);
7046
7047 auto ts_pre_stretch =
7048 boost::make_shared<DynamicRelaxationTimeScale>("externalstrain_history.txt");
7049 for (auto &ext_strain_block: *externalStrainVecPtr) {
7050 MOFEM_LOG("EP", Sev::noisy)
7051 << "Add time scaling external strain: " << ext_strain_block.blockName;
7052 timeScaleMap[ext_strain_block.blockName] =
7054 ts_pre_stretch, "externalstrain_history", ".txt", ext_strain_block.blockName);
7055 }
7056
7058}
boost::shared_ptr< ExternalStrainVec > externalStrainVecPtr
std::map< std::string, boost::shared_ptr< ScalingMethod > > timeScaleMap
MoFEMErrorCode getExternalStrain()
static boost::shared_ptr< ScalingMethod > get(boost::shared_ptr< ScalingMethod > ts, std::string file_prefix, std::string file_suffix, std::string block_name, Args &&...args)

◆ getOptions()

MoFEMErrorCode EshelbianCore::getOptions ( )
Examples
EshelbianPlasticity.cpp.

Definition at line 922 of file EshelbianPlasticity.cpp.

922 {
924 const char *list_rots[] = {"small", "moderate", "large", "no_h1"};
925 const char *list_symm[] = {"symm", "not_symm"};
926 const char *list_release[] = {"griffith_force", "griffith_skeleton"};
927 const char *list_stretches[] = {"linear", "log", "log_quadratic"};
928 PetscInt choice_rot = EshelbianCore::rotSelector;
929 PetscInt choice_grad = EshelbianCore::gradApproximator;
930 PetscInt choice_symm = EshelbianCore::symmetrySelector;
931 PetscInt choice_release = EshelbianCore::energyReleaseSelector;
932 PetscInt choice_stretch = StretchSelector::LOG;
933 char analytical_expr_file_name[255] = "analytical_expr.py";
934
935 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Eshelbian plasticity",
936 "none");
937 CHKERR PetscOptionsInt("-space_order", "approximation oder for space", "",
938 spaceOrder, &spaceOrder, PETSC_NULLPTR);
939 CHKERR PetscOptionsInt("-space_h1_order", "approximation oder for space", "",
940 spaceH1Order, &spaceH1Order, PETSC_NULLPTR);
941 CHKERR PetscOptionsInt("-material_order", "approximation oder for material",
942 "", materialOrder, &materialOrder, PETSC_NULLPTR);
943 CHKERR PetscOptionsScalar("-viscosity_alpha_u", "viscosity", "", alphaU,
944 &alphaU, PETSC_NULLPTR);
945 CHKERR PetscOptionsScalar("-viscosity_alpha_w", "viscosity", "", alphaW,
946 &alphaW, PETSC_NULLPTR);
947 CHKERR PetscOptionsScalar("-viscosity_alpha_omega", "rot viscosity", "",
948 alphaOmega, &alphaOmega, PETSC_NULLPTR);
949 CHKERR PetscOptionsScalar("-density_alpha_rho", "density", "", alphaRho,
950 &alphaRho, PETSC_NULLPTR);
951 CHKERR PetscOptionsEList("-rotations", "rotations", "", list_rots,
952 LARGE_ROT + 1, list_rots[choice_rot], &choice_rot,
953 PETSC_NULLPTR);
954 CHKERR PetscOptionsEList("-grad", "gradient of defamation approximate", "",
955 list_rots, NO_H1_CONFIGURATION + 1,
956 list_rots[choice_grad], &choice_grad, PETSC_NULLPTR);
957 CHKERR PetscOptionsEList("-symm", "symmetric variant", "", list_symm, 2,
958 list_symm[choice_symm], &choice_symm, PETSC_NULLPTR);
959
960 CHKERR PetscOptionsScalar("-exponent_base", "exponent_base", "", exponentBase,
961 &EshelbianCore::exponentBase, PETSC_NULLPTR);
962 CHKERR PetscOptionsEList("-stretches", "stretches", "", list_stretches,
963 StretchSelector::STRETCH_SELECTOR_LAST,
964 list_stretches[choice_stretch], &choice_stretch,
965 PETSC_NULLPTR);
966
967 CHKERR PetscOptionsBool("-no_stretch", "do not solve for stretch", "",
968 noStretch, &noStretch, PETSC_NULLPTR);
969 CHKERR PetscOptionsBool("-set_singularity", "set singularity", "",
970 setSingularity, &setSingularity, PETSC_NULLPTR);
971 CHKERR PetscOptionsBool("-l2_user_base_scale", "streach scale", "",
972 l2UserBaseScale, &l2UserBaseScale, PETSC_NULLPTR);
973
974 // dynamic relaxation
975 CHKERR PetscOptionsBool("-dynamic_relaxation", "dynamic time relaxation", "",
976 dynamicRelaxation, &dynamicRelaxation, PETSC_NULLPTR);
977
978 // contact parameters
979 CHKERR PetscOptionsInt("-contact_max_post_proc_ref_level", "refinement level",
981 PETSC_NULLPTR);
982
983 // cracking parameters
984 CHKERR PetscOptionsBool("-cracking_on", "cracking ON", "", crackingOn,
985 &crackingOn, PETSC_NULLPTR);
986 CHKERR PetscOptionsScalar("-cracking_start_time", "cracking start time", "",
987 crackingStartTime, &crackingStartTime, PETSC_NULLPTR);
988 CHKERR PetscOptionsScalar("-griffith_energy", "Griffith energy", "",
989 griffithEnergy, &griffithEnergy, PETSC_NULLPTR);
990 CHKERR PetscOptionsEList("-energy_release_variant", "energy release variant",
991 "", list_release, 2, list_release[choice_release],
992 &choice_release, PETSC_NULLPTR);
993 CHKERR PetscOptionsInt("-nb_J_integral_levels", "Number of J integarl levels",
994 "", nbJIntegralLevels, &nbJIntegralLevels, PETSC_NULLPTR);
995
996 // internal stress
997 char tag_name[255] = "";
998 CHKERR PetscOptionsString("-internal_stress_tag_name",
999 "internal stress tag name", "", "", tag_name, 255,
1000 PETSC_NULLPTR);
1001 internalStressTagName = string(tag_name);
1002 CHKERR PetscOptionsInt(
1003 "-internal_stress_interp_order", "internal stress interpolation order",
1005 CHKERR PetscOptionsBool("-internal_stress_voigt", "Voigt index notation", "",
1007 PETSC_NULLPTR);
1008
1009 CHKERR PetscOptionsGetString(PETSC_NULLPTR, PETSC_NULLPTR, "-analytical_expr_file",
1010 analytical_expr_file_name, 255, PETSC_NULLPTR);
1011
1012 PetscOptionsEnd();
1013
1015 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
1016 "Unsupported internal stress interpolation order %d",
1018 }
1019
1020 if (setSingularity) {
1021 l2UserBaseScale = PETSC_TRUE;
1022 }
1023
1024 EshelbianCore::rotSelector = static_cast<RotSelector>(choice_rot);
1025 EshelbianCore::gradApproximator = static_cast<RotSelector>(choice_grad);
1026 EshelbianCore::stretchSelector = static_cast<StretchSelector>(choice_stretch);
1027 EshelbianCore::symmetrySelector = static_cast<SymmetrySelector>(choice_symm);
1029 static_cast<EnergyReleaseSelector>(choice_release);
1030
1032 case StretchSelector::LINEAR:
1039 break;
1040 case StretchSelector::LOG:
1041 if (std::fabs(EshelbianCore::exponentBase - exp(1)) >
1042 std::numeric_limits<float>::epsilon()) {
1049 } else {
1056 }
1057 break;
1058 case StretchSelector::LOG_QUADRATIC:
1062 EshelbianCore::inv_f = [](const double x) {
1064 "No logarithmic quadratic stretch for this case");
1065 return 0;
1066 };
1069 break; // no stretch, do not use stretch functions
1070 default:
1071 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "Unknown stretch");
1072 break;
1073 };
1074
1075 MOFEM_LOG("EP", Sev::inform) << "spaceOrder: -space_order " << spaceOrder;
1076 MOFEM_LOG("EP", Sev::inform)
1077 << "spaceH1Order: -space_h1_order " << spaceH1Order;
1078 MOFEM_LOG("EP", Sev::inform)
1079 << "materialOrder: -material_order " << materialOrder;
1080 MOFEM_LOG("EP", Sev::inform) << "alphaU: -viscosity_alpha_u " << alphaU;
1081 MOFEM_LOG("EP", Sev::inform) << "alphaW: -viscosity_alpha_w " << alphaW;
1082 MOFEM_LOG("EP", Sev::inform)
1083 << "alphaOmega: -viscosity_alpha_omega " << alphaOmega;
1084 MOFEM_LOG("EP", Sev::inform) << "alphaRho: -density_alpha_rho " << alphaRho;
1085 MOFEM_LOG("EP", Sev::inform)
1086 << "Rotations: -rotations " << list_rots[EshelbianCore::rotSelector];
1087 MOFEM_LOG("EP", Sev::inform) << "Gradient of deformation "
1088 << list_rots[EshelbianCore::gradApproximator];
1089 MOFEM_LOG("EP", Sev::inform)
1090 << "Symmetry: -symm " << list_symm[EshelbianCore::symmetrySelector];
1091 if (exponentBase != exp(1))
1092 MOFEM_LOG("EP", Sev::inform)
1093 << "Base exponent: -exponent_base " << EshelbianCore::exponentBase;
1094 else
1095 MOFEM_LOG("EP", Sev::inform) << "Base exponent e";
1096 MOFEM_LOG("EP", Sev::inform)
1097 << "Stretch: -stretches " << list_stretches[choice_stretch];
1098 MOFEM_LOG("EP", Sev::inform) << "No stretch: -no_stretch " << (noStretch)
1099 ? "yes"
1100 : "no";
1101
1102 MOFEM_LOG("EP", Sev::inform)
1103 << "Dynamic relaxation: -dynamic_relaxation " << (dynamicRelaxation)
1104 ? "yes"
1105 : "no";
1106 MOFEM_LOG("EP", Sev::inform)
1107 << "Singularity: -set_singularity " << (setSingularity)
1108 ? "yes"
1109 : "no";
1110 MOFEM_LOG("EP", Sev::inform)
1111 << "L2 user base scale: -l2_user_base_scale " << (l2UserBaseScale)
1112 ? "yes"
1113 : "no";
1114
1115 MOFEM_LOG("EP", Sev::inform) << "Cracking on: -cracking_on " << (crackingOn)
1116 ? "yes"
1117 : "no";
1118 MOFEM_LOG("EP", Sev::inform)
1119 << "Cracking start time: -cracking_start_time " << crackingStartTime;
1120 MOFEM_LOG("EP", Sev::inform)
1121 << "Griffith energy: -griffith_energy " << griffithEnergy;
1122 MOFEM_LOG("EP", Sev::inform)
1123 << "Energy release variant: -energy_release_variant "
1124 << list_release[EshelbianCore::energyReleaseSelector];
1125 MOFEM_LOG("EP", Sev::inform)
1126 << "Number of J integral levels: -nb_J_integral_levels "
1128
1129#ifdef ENABLE_PYTHON_BINDING
1130 auto file_exists = [](std::string myfile) {
1131 std::ifstream file(myfile.c_str());
1132 if (file) {
1133 return true;
1134 }
1135 return false;
1136 };
1137
1138 if (file_exists(analytical_expr_file_name)) {
1139 MOFEM_LOG("EP", Sev::inform) << analytical_expr_file_name << " file found";
1140
1141 AnalyticalExprPythonPtr = boost::make_shared<AnalyticalExprPython>();
1142 CHKERR AnalyticalExprPythonPtr->analyticalExprInit(
1143 analytical_expr_file_name);
1144 AnalyticalExprPythonWeakPtr = AnalyticalExprPythonPtr;
1145 } else {
1146 MOFEM_LOG("EP", Sev::warning)
1147 << analytical_expr_file_name << " file NOT found";
1148 }
1149#endif
1150
1151 if (spaceH1Order == -1)
1153
1155}
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
PetscErrorCode PetscOptionsGetString(PetscOptions *, const char pre[], const char name[], char str[], size_t size, PetscBool *set)
static enum StretchSelector stretchSelector
static double inv_f_linear(const double v)
static double dd_f_log(const double v)
static boost::function< double(const double)> inv_dd_f
static double inv_d_f_log(const double v)
static PetscBool l2UserBaseScale
static int internalStressInterpOrder
static PetscBool crackingOn
static double dd_f_log_e(const double v)
static enum RotSelector rotSelector
static enum RotSelector gradApproximator
static PetscBool dynamicRelaxation
static double d_f_log(const double v)
static double crackingStartTime
static double inv_f_log(const double v)
static double dd_f_linear(const double v)
boost::shared_ptr< AnalyticalExprPython > AnalyticalExprPythonPtr
static double inv_d_f_linear(const double v)
static double inv_dd_f_log(const double v)
static std::string internalStressTagName
static enum SymmetrySelector symmetrySelector
static PetscBool internalStressVoigt
static double inv_dd_f_linear(const double v)
static PetscBool setSingularity
static double d_f_log_e(const double v)
static boost::function< double(const double)> dd_f
static double f_log_e(const double v)
static boost::function< double(const double)> d_f
static boost::function< double(const double)> inv_d_f
static double d_f_linear(const double v)
static double f_log(const double v)
static boost::function< double(const double)> inv_f
static double f_linear(const double v)

◆ getSpatialDispBc()

MoFEMErrorCode EshelbianCore::getSpatialDispBc ( )

[Getting norms]

Examples
EshelbianPlasticity.cpp, and ep.cpp.

Definition at line 6835 of file EshelbianPlasticity.cpp.

6835 {
6837
6838 auto bc_mng = mField.getInterface<BcManager>();
6840 "", piolaStress, false, false);
6841
6842 bcSpatialDispVecPtr = boost::make_shared<BcDispVec>();
6843 for (auto bc : bc_mng->getBcMapByBlockName()) {
6844 if (auto disp_bc = bc.second->dispBcPtr) {
6845
6846 auto [field_name, block_name] =
6848 MOFEM_LOG("EP", Sev::inform)
6849 << "Field name: " << field_name << " Block name: " << block_name;
6850 MOFEM_LOG("EP", Sev::noisy) << "Displacement BC: " << *disp_bc;
6851
6852 std::vector<double> block_attributes(6, 0.);
6853 if (disp_bc->data.flag1 == 1) {
6854 block_attributes[0] = disp_bc->data.value1;
6855 block_attributes[3] = 1;
6856 }
6857 if (disp_bc->data.flag2 == 1) {
6858 block_attributes[1] = disp_bc->data.value2;
6859 block_attributes[4] = 1;
6860 }
6861 if (disp_bc->data.flag3 == 1) {
6862 block_attributes[2] = disp_bc->data.value3;
6863 block_attributes[5] = 1;
6864 }
6865 auto faces = bc.second->bcEnts.subset_by_dimension(2);
6866 bcSpatialDispVecPtr->emplace_back(block_name, block_attributes, faces);
6867 }
6868 }
6869 // old way of naming blocksets for displacement BCs
6870 CHKERR getBc(bcSpatialDispVecPtr, "SPATIAL_DISP_BC", 6);
6871
6873 boost::make_shared<NormalDisplacementBcVec>();
6874 for (auto bc : bc_mng->getBcMapByBlockName()) {
6875 auto block_name = "(.*)NORMAL_DISPLACEMENT(.*)";
6876 std::regex reg_name(block_name);
6877 if (std::regex_match(bc.first, reg_name)) {
6878 auto [field_name, block_name] =
6880 MOFEM_LOG("EP", Sev::inform)
6881 << "Field name: " << field_name << " Block name: " << block_name;
6883 block_name, bc.second->bcAttributes,
6884 bc.second->bcEnts.subset_by_dimension(2));
6885 }
6886 }
6887
6889 boost::make_shared<AnalyticalDisplacementBcVec>();
6890
6891 for (auto bc : bc_mng->getBcMapByBlockName()) {
6892 auto block_name = "(.*)ANALYTICAL_DISPLACEMENT(.*)";
6893 std::regex reg_name(block_name);
6894 if (std::regex_match(bc.first, reg_name)) {
6895 auto [field_name, block_name] =
6897 MOFEM_LOG("EP", Sev::inform)
6898 << "Field name: " << field_name << " Block name: " << block_name;
6900 block_name, bc.second->bcAttributes,
6901 bc.second->bcEnts.subset_by_dimension(2));
6902 }
6903 }
6904
6905 auto ts_displacement =
6906 boost::make_shared<DynamicRelaxationTimeScale>("disp_history.txt");
6907 for (auto &bc : *bcSpatialDispVecPtr) {
6908 MOFEM_LOG("EP", Sev::noisy)
6909 << "Add time scaling displacement BC: " << bc.blockName;
6910 timeScaleMap[bc.blockName] =
6912 ts_displacement, "disp_history", ".txt", bc.blockName);
6913 }
6914
6915 auto ts_normal_displacement =
6916 boost::make_shared<DynamicRelaxationTimeScale>("normal_disp_history.txt");
6917 for (auto &bc : *bcSpatialNormalDisplacementVecPtr) {
6918 MOFEM_LOG("EP", Sev::noisy)
6919 << "Add time scaling normal displacement BC: " << bc.blockName;
6920 timeScaleMap[bc.blockName] =
6922 ts_normal_displacement, "normal_disp_history", ".txt",
6923 bc.blockName);
6924 }
6925
6927}
MoFEMErrorCode getBc(boost::shared_ptr< BC > &bc_vec_ptr, const std::string block_name, const int nb_attributes)
Simple interface for fast problem set-up.
Definition BcManager.hpp:29
static std::pair< std::string, std::string > extractStringFromBlockId(const std::string block_id, const std::string prb_name)
Extract block name and block name form block id.
MoFEMErrorCode pushMarkDOFsOnEntities(const std::string problem_name, const std::string block_name, const std::string field_name, int lo, int hi, bool get_low_dim_ents=true)
Mark block DOFs.
Definition of the displacement bc data structure.
Definition BCData.hpp:72

◆ getSpatialRotationBc()

MoFEMErrorCode EshelbianCore::getSpatialRotationBc ( )
inline
Examples
ep.cpp.

Definition at line 271 of file EshelbianCore.hpp.

271 {
273 bcSpatialRotationVecPtr = boost::make_shared<BcRotVec>();
274 CHKERR getBc(bcSpatialRotationVecPtr, "SPATIAL_ROTATION_BC", 4);
275 CHKERR getBc(bcSpatialRotationVecPtr, "SPATIAL_ROTATION_AXIS_BC", 7);
276
277 auto ts_rotation =
278 boost::make_shared<DynamicRelaxationTimeScale>("rotation_history.txt");
279 for (auto &bc : *bcSpatialRotationVecPtr) {
280 timeScaleMap[bc.blockName] =
281 GetBlockScalingMethod<DynamicRelaxationTimeScale>::get(
282 ts_rotation, "rotation_history", ".txt", bc.blockName);
283 }
284
286 }

◆ getSpatialTractionBc()

MoFEMErrorCode EshelbianCore::getSpatialTractionBc ( )
Examples
EshelbianPlasticity.cpp, and ep.cpp.

Definition at line 6929 of file EshelbianPlasticity.cpp.

6929 {
6931
6932 auto bc_mng = mField.getInterface<BcManager>();
6934 false, false);
6935
6936 bcSpatialTractionVecPtr = boost::make_shared<TractionBcVec>();
6937
6938 for (auto bc : bc_mng->getBcMapByBlockName()) {
6939 if (auto force_bc = bc.second->forceBcPtr) {
6940
6941 auto [field_name, block_name] =
6943 MOFEM_LOG("EP", Sev::inform)
6944 << "Field name: " << field_name << " Block name: " << block_name;
6945 MOFEM_LOG("EP", Sev::noisy) << "Force BC: " << *force_bc;
6946
6947 std::vector<double> block_attributes(6, 0.);
6948 block_attributes[0] = -force_bc->data.value3 * force_bc->data.value1;
6949 block_attributes[3] = 1;
6950 block_attributes[1] = -force_bc->data.value4 * force_bc->data.value1;
6951 block_attributes[4] = 1;
6952 block_attributes[2] = -force_bc->data.value5 * force_bc->data.value1;
6953 block_attributes[5] = 1;
6954 auto faces = bc.second->bcEnts.subset_by_dimension(2);
6955 bcSpatialTractionVecPtr->emplace_back(block_name, block_attributes,
6956 faces);
6957 }
6958 }
6959 CHKERR getBc(bcSpatialTractionVecPtr, "SPATIAL_TRACTION_BC", 6);
6960
6961 bcSpatialPressureVecPtr = boost::make_shared<PressureBcVec>();
6962 for (auto bc : bc_mng->getBcMapByBlockName()) {
6963 auto block_name = "(.*)PRESSURE(.*)";
6964 std::regex reg_name(block_name);
6965 if (std::regex_match(bc.first, reg_name)) {
6966
6967 auto [field_name, block_name] =
6969 MOFEM_LOG("EP", Sev::inform)
6970 << "Field name: " << field_name << " Block name: " << block_name;
6971 bcSpatialPressureVecPtr->emplace_back(
6972 block_name, bc.second->bcAttributes,
6973 bc.second->bcEnts.subset_by_dimension(2));
6974 }
6975 }
6976
6978 boost::make_shared<AnalyticalTractionBcVec>();
6979
6980 for (auto bc : bc_mng->getBcMapByBlockName()) {
6981 auto block_name = "(.*)ANALYTICAL_TRACTION(.*)";
6982 std::regex reg_name(block_name);
6983 if (std::regex_match(bc.first, reg_name)) {
6984 auto [field_name, block_name] =
6986 MOFEM_LOG("EP", Sev::inform)
6987 << "Field name: " << field_name << " Block name: " << block_name;
6989 block_name, bc.second->bcAttributes,
6990 bc.second->bcEnts.subset_by_dimension(2));
6991 }
6992 }
6993
6994 auto ts_traction =
6995 boost::make_shared<DynamicRelaxationTimeScale>("traction_history.txt");
6996 for (auto &bc : *bcSpatialTractionVecPtr) {
6997 timeScaleMap[bc.blockName] =
6999 ts_traction, "traction_history", ".txt", bc.blockName);
7000 }
7001
7002 auto ts_pressure =
7003 boost::make_shared<DynamicRelaxationTimeScale>("pressure_history.txt");
7004 for (auto &bc : *bcSpatialPressureVecPtr) {
7005 timeScaleMap[bc.blockName] =
7007 ts_pressure, "pressure_history", ".txt", bc.blockName);
7008 }
7009
7011}
Definition of the force bc data structure.
Definition BCData.hpp:135

◆ getSpatialTractionFreeBc()

MoFEMErrorCode EshelbianCore::getSpatialTractionFreeBc ( const EntityHandle  meshset = 0)
inline
Examples
ep.cpp.

Definition at line 305 of file EshelbianCore.hpp.

305 {
307 boost::shared_ptr<TractionFreeBc>(new TractionFreeBc());
308 return getTractionFreeBc(meshset, bcSpatialFreeTractionVecPtr, "CONTACT");
309 }
std::vector< Range > TractionFreeBc
MoFEMErrorCode getTractionFreeBc(const EntityHandle meshset, boost::shared_ptr< TractionFreeBc > &bc_ptr, const std::string contact_set_name)
Remove all, but entities where kinematic constrains are applied.

◆ gettingNorms()

MoFEMErrorCode EshelbianCore::gettingNorms ( )

[Getting norms]

Examples
EshelbianPlasticity.cpp.

Definition at line 6767 of file EshelbianPlasticity.cpp.

6767 {
6769
6770 auto post_proc_norm_fe =
6771 boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
6772
6773 auto post_proc_norm_rule_hook = [](int, int, int p) -> int {
6774 return 2 * (p);
6775 };
6776 post_proc_norm_fe->getRuleHook = post_proc_norm_rule_hook;
6777
6778 post_proc_norm_fe->getUserPolynomialBase() =
6779 boost::shared_ptr<BaseFunction>(new CGGUserPolynomialBase());
6780
6781 CHKERR EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
6782 post_proc_norm_fe->getOpPtrVector(), {L2, H1, HDIV}, materialH1Positions,
6784
6785 enum NORMS { U_NORM_L2 = 0, U_NORM_H1, PIOLA_NORM, U_ERROR_L2, LAST_NORM };
6786 auto norms_vec =
6787 createVectorMPI(mField.get_comm(), LAST_NORM, PETSC_DETERMINE);
6788 CHKERR VecZeroEntries(norms_vec);
6789
6790 auto u_l2_ptr = boost::make_shared<MatrixDouble>();
6791 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
6792 post_proc_norm_fe->getOpPtrVector().push_back(
6794 post_proc_norm_fe->getOpPtrVector().push_back(
6796 post_proc_norm_fe->getOpPtrVector().push_back(
6797 new OpCalcNormL2Tensor1<SPACE_DIM>(u_l2_ptr, norms_vec, U_NORM_L2));
6798 post_proc_norm_fe->getOpPtrVector().push_back(
6799 new OpCalcNormL2Tensor1<SPACE_DIM>(u_h1_ptr, norms_vec, U_NORM_H1));
6800 post_proc_norm_fe->getOpPtrVector().push_back(
6801 new OpCalcNormL2Tensor1<SPACE_DIM>(u_l2_ptr, norms_vec, U_ERROR_L2,
6802 u_h1_ptr));
6803
6804 auto piola_ptr = boost::make_shared<MatrixDouble>();
6805 post_proc_norm_fe->getOpPtrVector().push_back(
6807 post_proc_norm_fe->getOpPtrVector().push_back(
6809 MBMAXTYPE));
6810
6811 post_proc_norm_fe->getOpPtrVector().push_back(
6812 new OpCalcNormL2Tensor2<3, 3>(piola_ptr, norms_vec, PIOLA_NORM));
6813
6814 TetPolynomialBase::switchCacheBaseOn<HDIV>({post_proc_norm_fe.get()});
6816 *post_proc_norm_fe);
6817 TetPolynomialBase::switchCacheBaseOff<HDIV>({post_proc_norm_fe.get()});
6818
6819 CHKERR VecAssemblyBegin(norms_vec);
6820 CHKERR VecAssemblyEnd(norms_vec);
6821 const double *norms;
6822 CHKERR VecGetArrayRead(norms_vec, &norms);
6823 MOFEM_LOG("EP", Sev::inform) << "norm_u: " << std::sqrt(norms[U_NORM_L2]);
6824 MOFEM_LOG("EP", Sev::inform) << "norm_u_h1: " << std::sqrt(norms[U_NORM_H1]);
6825 MOFEM_LOG("EP", Sev::inform)
6826 << "norm_error_u_l2: " << std::sqrt(norms[U_ERROR_L2]);
6827 MOFEM_LOG("EP", Sev::inform)
6828 << "norm_piola: " << std::sqrt(norms[PIOLA_NORM]);
6829 CHKERR VecRestoreArrayRead(norms_vec, &norms);
6830
6832}
virtual MoFEMErrorCode loop_finite_elements(const std::string problem_name, const std::string &fe_name, FEMethod &method, boost::shared_ptr< NumeredEntFiniteElement_multiIndex > fe_ptr=nullptr, MoFEMTypes bh=MF_EXIST, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr(), int verb=DEFAULT_VERBOSITY)=0
Make a loop over finite elements.
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
Get norm of input MatrixDouble for Tensor1.
Get norm of input MatrixDouble for Tensor2.

◆ getTractionFreeBc()

MoFEMErrorCode EshelbianCore::getTractionFreeBc ( const EntityHandle  meshset,
boost::shared_ptr< TractionFreeBc > &  bc_ptr,
const std::string  contact_set_name 
)

Remove all, but entities where kinematic constrains are applied.

Parameters
meshset
bc_ptr
disp_block_set_name
rot_block_set_name
contact_set_name
Returns
MoFEMErrorCode
Examples
EshelbianPlasticity.cpp.

Definition at line 2073 of file EshelbianPlasticity.cpp.

2075 {
2077
2078 // get skin from all tets
2079 Range tets;
2080 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
2081 Range tets_skin_part;
2082 Skinner skin(&mField.get_moab());
2083 CHKERR skin.find_skin(0, tets, false, tets_skin_part);
2084 ParallelComm *pcomm =
2085 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
2086 Range tets_skin;
2087 CHKERR pcomm->filter_pstatus(tets_skin_part,
2088 PSTATUS_SHARED | PSTATUS_MULTISHARED,
2089 PSTATUS_NOT, -1, &tets_skin);
2090
2091 bc_ptr->resize(3);
2092 for (int dd = 0; dd != 3; ++dd)
2093 (*bc_ptr)[dd] = tets_skin;
2094
2095 // Do not remove dofs on which traction is applied
2097 for (auto &v : *bcSpatialDispVecPtr) {
2098 if (v.flags[0])
2099 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2100 if (v.flags[1])
2101 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2102 if (v.flags[2])
2103 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2104 }
2105
2106 // Do not remove dofs on which rotation is applied
2108 for (auto &v : *bcSpatialRotationVecPtr) {
2109 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2110 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2111 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2112 }
2113
2115 for (auto &v : *bcSpatialNormalDisplacementVecPtr) {
2116 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2117 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2118 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2119 }
2120
2123 if (v.flags[0])
2124 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2125 if (v.flags[1])
2126 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2127 if (v.flags[2])
2128 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2129 }
2130
2132 for (auto &v : *bcSpatialTractionVecPtr) {
2133 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2134 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2135 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2136 }
2137
2139 for (auto &v : *bcSpatialAnalyticalTractionVecPtr) {
2140 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2141 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2142 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2143 }
2144
2146 for (auto &v : *bcSpatialPressureVecPtr) {
2147 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2148 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2149 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2150 }
2151
2152 // remove contact
2153 for (auto m : mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
2154 std::regex((boost::format("%s(.*)") % contact_set_name).str()))) {
2155 Range faces;
2156 CHKERR m->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2, faces,
2157 true);
2158 (*bc_ptr)[0] = subtract((*bc_ptr)[0], faces);
2159 (*bc_ptr)[1] = subtract((*bc_ptr)[1], faces);
2160 (*bc_ptr)[2] = subtract((*bc_ptr)[2], faces);
2161 }
2162
2164}
const Tensor2_symmetric_Expr< const ddTensor0< T, Dim, i, j >, typename promote< T, double >::V, Dim, i, j > dd(const Tensor0< T * > &a, const Index< i, Dim > index1, const Index< j, Dim > index2, const Tensor1< int, Dim > &d_ijk, const Tensor1< double, Dim > &d_xyz)
Definition ddTensor0.hpp:33

◆ inv_d_f_linear()

static double EshelbianCore::inv_d_f_linear ( const double  v)
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 163 of file EshelbianCore.hpp.

163{ return 0; }

◆ inv_d_f_log()

static double EshelbianCore::inv_d_f_log ( const double  v)
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 151 of file EshelbianCore.hpp.

151 {
152 return (1. / v) / log(EshelbianCore::exponentBase);
153 }

◆ inv_d_f_log_e()

static double EshelbianCore::inv_d_f_log_e ( const double  v)
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 124 of file EshelbianCore.hpp.

124 {
125 if (v > std::exp(v_min))
126 return 1. / v;
127 else
128 return 1. / exp(v_min);
129 }
static constexpr double v_min

◆ inv_dd_f_linear()

static double EshelbianCore::inv_dd_f_linear ( const double  v)
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 164 of file EshelbianCore.hpp.

164{ return 0; }

◆ inv_dd_f_log()

static double EshelbianCore::inv_dd_f_log ( const double  v)
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 154 of file EshelbianCore.hpp.

154 {
155 return -(1. / (v * v)) / log(EshelbianCore::exponentBase);
156 }

◆ inv_dd_f_log_e()

static double EshelbianCore::inv_dd_f_log_e ( const double  v)
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 130 of file EshelbianCore.hpp.

130 {
131 if (v > std::exp(v_min))
132 return -1. / (v * v);
133 else
134 return 0.;
135 }

◆ inv_f_linear()

static double EshelbianCore::inv_f_linear ( const double  v)
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 162 of file EshelbianCore.hpp.

162{ return v - 1; }

◆ inv_f_log()

static double EshelbianCore::inv_f_log ( const double  v)
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 148 of file EshelbianCore.hpp.

148 {
149 return log(v) / log(EshelbianCore::exponentBase);
150 }

◆ inv_f_log_e()

static double EshelbianCore::inv_f_log_e ( const double  v)
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 115 of file EshelbianCore.hpp.

115 {
116 if (v > std::exp(v_min))
117 return std::log(v);
118 else
119 // y = exp(v_min) * v + exp(v_min) * (1 - v_min);
120 // y/exp(v_min) = v + (1 - v_min);
121 // y/exp(v_min) - (1 - v_min) = v;
122 return v / exp(v_min) - (1 - v_min);
123 }

◆ postProcessResults()

MoFEMErrorCode EshelbianCore::postProcessResults ( const int  tag,
const std::string  file,
Vec  f_residual = PETSC_NULLPTR,
Vec  var_vec = PETSC_NULLPTR,
std::vector< Tag tags_to_transfer = {} 
)
Examples
EshelbianPlasticity.cpp.

Definition at line 3713 of file EshelbianPlasticity.cpp.

3715 {
3717
3718 // mark crack surface
3719 if (crackingOn) {
3720 Tag th;
3721 rval = mField.get_moab().tag_get_handle("CRACK", th);
3722 if (rval == MB_SUCCESS) {
3723 CHKERR mField.get_moab().tag_delete(th);
3724 }
3725 int def_val[] = {0};
3726 CHKERR mField.get_moab().tag_get_handle(
3727 "CRACK", 1, MB_TYPE_INTEGER, th, MB_TAG_SPARSE | MB_TAG_CREAT, def_val);
3728 int mark[] = {1};
3729 CHKERR mField.get_moab().tag_clear_data(th, *crackFaces, mark);
3730 tags_to_transfer.push_back(th);
3731
3732 auto get_tag = [&](auto name, auto dim) {
3733 auto &mob = mField.get_moab();
3734 Tag tag;
3735 double def_val[] = {0., 0., 0.};
3736 CHK_MOAB_THROW(mob.tag_get_handle(name, dim, MB_TYPE_DOUBLE, tag,
3737 MB_TAG_CREAT | MB_TAG_SPARSE, def_val),
3738 "create tag");
3739 return tag;
3740 };
3741
3742 tags_to_transfer.push_back(get_tag("MaterialForce", 3));
3743 // tags_to_transfer.push_back(get_tag("GriffithForce", 1));
3744 }
3745
3746 // add tags to transfer
3747 for (auto t : listTagsToTransfer) {
3748 tags_to_transfer.push_back(t);
3749 }
3750
3751 if (!dataAtPts) {
3752 dataAtPts =
3753 boost::shared_ptr<DataAtIntegrationPts>(new DataAtIntegrationPts());
3754 }
3755
3756 struct exclude_sdf {
3757 exclude_sdf(Range &&r) : map(r) {}
3758 bool operator()(FEMethod *fe_method_ptr) {
3759 auto ent = fe_method_ptr->getFEEntityHandle();
3760 if (map.find(ent) != map.end()) {
3761 return false;
3762 }
3763 return true;
3764 }
3765
3766 private:
3767 Range map;
3768 };
3769
3770 contactTreeRhs->exeTestHook =
3771 exclude_sdf(get_range_from_block(mField, "CONTACT_SDF", SPACE_DIM - 1));
3772
3774
3775 auto get_post_proc = [&](auto &post_proc_mesh, auto sense) {
3777 auto post_proc_ptr =
3778 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
3779 mField, post_proc_mesh);
3780 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3781 post_proc_ptr->getOpPtrVector(), {L2}, materialH1Positions,
3783
3784 auto domain_ops = [&](auto &fe, int sense) {
3786 fe.getUserPolynomialBase() =
3787 boost::shared_ptr<BaseFunction>(new CGGUserPolynomialBase());
3788 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3789 fe.getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions,
3791 auto piola_scale_ptr = boost::make_shared<double>(1.0);
3792 fe.getOpPtrVector().push_back(physicalEquations->returnOpSetScale(
3793 piola_scale_ptr, physicalEquations));
3794 fe.getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
3795 piolaStress, dataAtPts->getApproxPAtPts(), piola_scale_ptr));
3796 fe.getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
3797 bubbleField, dataAtPts->getApproxPAtPts(), piola_scale_ptr,
3798 SmartPetscObj<Vec>(), MBMAXTYPE));
3799 if (noStretch) {
3800 fe.getOpPtrVector().push_back(
3801 physicalEquations->returnOpCalculateStretchFromStress(
3803 } else {
3804 fe.getOpPtrVector().push_back(
3806 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
3807 }
3808 if (var_vector) {
3809 auto vec = SmartPetscObj<Vec>(var_vector, true);
3810 fe.getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
3811 piolaStress, dataAtPts->getVarPiolaPts(),
3812 boost::make_shared<double>(1), vec));
3813 fe.getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
3814 bubbleField, dataAtPts->getVarPiolaPts(),
3815 boost::make_shared<double>(1), vec, MBMAXTYPE));
3816 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
3817 rotAxis, dataAtPts->getVarRotAxisPts(), vec, MBTET));
3818 if (noStretch) {
3819 fe.getOpPtrVector().push_back(
3820 physicalEquations->returnOpCalculateVarStretchFromStress(
3822 } else {
3823 fe.getOpPtrVector().push_back(
3825 stretchTensor, dataAtPts->getVarLogStreachPts(), vec, MBTET));
3826 }
3827 }
3828
3829 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
3830 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
3831 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
3832 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
3833
3834 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
3835 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
3836 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
3837 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
3838 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldGradient<3, 3>(
3839 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
3840 // evaluate derived quantities
3841 fe.getOpPtrVector().push_back(
3843
3844 // evaluate integration points
3845 fe.getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
3846 tag, true, false, dataAtPts, physicalEquations));
3847 if (auto op =
3848 physicalEquations->returnOpCalculateEnergy(dataAtPts, nullptr)) {
3849 fe.getOpPtrVector().push_back(op);
3850 fe.getOpPtrVector().push_back(new OpCalculateEshelbyStress(dataAtPts));
3851 }
3852
3853 // // post-proc
3856 VolumeElementForcesAndSourcesCoreOnSide::UserDataOperator>;
3857
3858 struct OpSidePPMap : public OpPPMap {
3859 OpSidePPMap(moab::Interface &post_proc_mesh,
3860 std::vector<EntityHandle> &map_gauss_pts,
3861 DataMapVec data_map_scalar, DataMapMat data_map_vec,
3862 DataMapMat data_map_mat, DataMapMat data_symm_map_mat,
3863 int sense)
3864 : OpPPMap(post_proc_mesh, map_gauss_pts, data_map_scalar,
3865 data_map_vec, data_map_mat, data_symm_map_mat),
3866 tagSense(sense) {}
3867
3868 MoFEMErrorCode doWork(int side, EntityType type,
3871
3872 if (tagSense != OpPPMap::getSkeletonSense())
3874
3875 CHKERR OpPPMap::doWork(side, type, data);
3877 }
3878
3879 private:
3880 int tagSense;
3881 };
3882
3883 OpPPMap::DataMapMat vec_fields;
3884 vec_fields["SpatialDisplacementL2"] = dataAtPts->getSmallWL2AtPts();
3885 vec_fields["SpatialDisplacementH1"] = dataAtPts->getSmallWH1AtPts();
3886 vec_fields["Omega"] = dataAtPts->getRotAxisAtPts();
3887 vec_fields["ContactDisplacement"] = dataAtPts->getContactL2AtPts();
3888 vec_fields["AngularMomentum"] = dataAtPts->getLeviKirchhoffAtPts();
3889 vec_fields["X"] = dataAtPts->getLargeXH1AtPts();
3890 if (!noStretch) {
3891 vec_fields["EiegnLogStreach"] = dataAtPts->getEigenValsAtPts();
3892 }
3893 if (var_vector) {
3894 auto vec = SmartPetscObj<Vec>(var_vector, true);
3895 vec_fields["VarOmega"] = dataAtPts->getVarRotAxisPts();
3896 vec_fields["VarSpatialDisplacementL2"] =
3897 boost::make_shared<MatrixDouble>();
3898 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
3899 spatialL2Disp, vec_fields["VarSpatialDisplacementL2"], vec, MBTET));
3900 }
3901 if (f_residual) {
3902 auto vec = SmartPetscObj<Vec>(f_residual, true);
3903 vec_fields["ResSpatialDisplacementL2"] =
3904 boost::make_shared<MatrixDouble>();
3905 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
3906 spatialL2Disp, vec_fields["ResSpatialDisplacementL2"], vec, MBTET));
3907 vec_fields["ResOmega"] = boost::make_shared<MatrixDouble>();
3908 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
3909 rotAxis, vec_fields["ResOmega"], vec, MBTET));
3910 }
3911
3912 OpPPMap::DataMapMat mat_fields;
3913 mat_fields["PiolaStress"] = dataAtPts->getApproxPAtPts();
3914 if (var_vector) {
3915 mat_fields["VarPiolaStress"] = dataAtPts->getVarPiolaPts();
3916 }
3917 if (f_residual) {
3918 auto vec = SmartPetscObj<Vec>(f_residual, true);
3919 mat_fields["ResPiolaStress"] = boost::make_shared<MatrixDouble>();
3920 fe.getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
3921 piolaStress, mat_fields["ResPiolaStress"],
3922 boost::make_shared<double>(1), vec));
3923 fe.getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
3924 bubbleField, mat_fields["ResPiolaStress"],
3925 boost::make_shared<double>(1), vec, MBMAXTYPE));
3926 }
3927 if (!internalStressTagName.empty()) {
3928 mat_fields[internalStressTagName] = dataAtPts->getInternalStressAtPts();
3929 switch (internalStressInterpOrder) {
3930 case 0:
3931 fe.getOpPtrVector().push_back(
3933 break;
3934 case 1:
3935 fe.getOpPtrVector().push_back(
3937 break;
3938 default:
3939 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
3940 "Unsupported internal stress interpolation order %d",
3942 }
3943 }
3944
3945 OpPPMap::DataMapMat mat_fields_symm;
3946 mat_fields_symm["LogSpatialStretch"] =
3947 dataAtPts->getLogStretchTensorAtPts();
3948 mat_fields_symm["SpatialStretch"] = dataAtPts->getStretchTensorAtPts();
3949 if (var_vector) {
3950 mat_fields_symm["VarLogSpatialStretch"] =
3951 dataAtPts->getVarLogStreachPts();
3952 }
3953 if (f_residual) {
3954 auto vec = SmartPetscObj<Vec>(f_residual, true);
3955 if (!noStretch) {
3956 mat_fields_symm["ResLogSpatialStretch"] =
3957 boost::make_shared<MatrixDouble>();
3958 fe.getOpPtrVector().push_back(
3960 stretchTensor, mat_fields_symm["ResLogSpatialStretch"], vec,
3961 MBTET));
3962 }
3963 }
3964
3965 fe.getOpPtrVector().push_back(
3966
3967 new OpSidePPMap(
3968
3969 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
3970
3971 {},
3972
3973 vec_fields,
3974
3975 mat_fields,
3976
3977 mat_fields_symm,
3978
3979 sense
3980
3981 )
3982
3983 );
3984
3985 fe.getOpPtrVector().push_back(new OpPostProcDataStructure(
3986 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
3987 dataAtPts, sense));
3988
3990 };
3991
3992 post_proc_ptr->getOpPtrVector().push_back(
3994 dataAtPts->getContactL2AtPts()));
3995
3996 auto X_h1_ptr = boost::make_shared<MatrixDouble>();
3997 // H1 material positions
3998 post_proc_ptr->getOpPtrVector().push_back(
4000 dataAtPts->getLargeXH1AtPts()));
4001
4002 // domain
4005 domain_ops(*(op_loop_side->getSideFEPtr()), sense);
4006 post_proc_ptr->getOpPtrVector().push_back(op_loop_side);
4007
4008 return post_proc_ptr;
4009 };
4010
4011 // contact
4012 auto calcs_side_traction_and_displacements = [&](auto &post_proc_ptr,
4013 auto &pip) {
4015 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
4016 // evaluate traction
4017 using EleOnSide =
4019 using SideEleOp = EleOnSide::UserDataOperator;
4020 auto op_loop_domain_side = new OpLoopSide<EleOnSide>(
4021 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
4022 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
4023 boost::shared_ptr<BaseFunction>(new CGGUserPolynomialBase());
4024 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4025 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
4027 op_loop_domain_side->getOpPtrVector().push_back(
4029 piolaStress, contact_common_data_ptr->contactTractionPtr(),
4030 boost::make_shared<double>(1.0)));
4031 pip.push_back(op_loop_domain_side);
4032 // evaluate contact displacement and contact conditions
4033 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
4034 pip.push_back(new OpCalculateVectorFieldValues<3>(spatialH1Disp, u_h1_ptr));
4036 contactDisp, contact_common_data_ptr->contactDispPtr()));
4037 pip.push_back(new OpTreeSearch(
4038 contactTreeRhs, contact_common_data_ptr, u_h1_ptr,
4039 get_range_from_block(mField, "CONTACT", SPACE_DIM - 1),
4040 &post_proc_ptr->getPostProcMesh(), &post_proc_ptr->getMapGaussPts()));
4041
4042 if (f_residual) {
4043
4044 using BoundaryEle =
4046 auto op_this = new OpLoopThis<BoundaryEle>(mField, contactElement);
4047 pip.push_back(op_this);
4048 auto contact_residual = boost::make_shared<MatrixDouble>();
4049 op_this->getOpPtrVector().push_back(
4051 contactDisp, contact_residual,
4052 SmartPetscObj<Vec>(f_residual, true)));
4054 op_this->getOpPtrVector().push_back(
4055
4056 new OpPPMap(
4057
4058 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4059
4060 {},
4061
4062 {{"res_contact", contact_residual}},
4063
4064 {},
4065
4066 {}
4067
4068 )
4069
4070 );
4071 }
4072
4074 };
4075
4076 auto post_proc_mesh = boost::make_shared<moab::Core>();
4077 auto post_proc_ptr = get_post_proc(post_proc_mesh, 1);
4078 auto post_proc_negative_sense_ptr = get_post_proc(post_proc_mesh, -1);
4079 CHKERR calcs_side_traction_and_displacements(post_proc_ptr,
4080 post_proc_ptr->getOpPtrVector());
4081
4082 auto own_tets =
4084 .subset_by_dimension(SPACE_DIM);
4085 Range own_faces;
4086 CHKERR mField.get_moab().get_adjacencies(own_tets, SPACE_DIM - 1, true,
4087 own_faces, moab::Interface::UNION);
4088
4089 auto get_post_negative = [&](auto &&ents) {
4090 auto crack_faces_pos = ents;
4091 auto crack_faces_neg = crack_faces_pos;
4092 auto skin = get_skin(mField, own_tets);
4093 auto crack_on_proc_skin = intersect(crack_faces_pos, skin);
4094 for (auto f : crack_on_proc_skin) {
4095 Range tet;
4096 CHKERR mField.get_moab().get_adjacencies(&f, 1, SPACE_DIM, false, tet);
4097 tet = intersect(tet, own_tets);
4098 int side_number, sense, offset;
4099 CHKERR mField.get_moab().side_number(tet[0], f, side_number, sense,
4100 offset);
4101 if (sense == 1) {
4102 crack_faces_neg.erase(f);
4103 } else {
4104 crack_faces_pos.erase(f);
4105 }
4106 }
4107 return std::make_pair(crack_faces_pos, crack_faces_neg);
4108 };
4109
4110 auto get_crack_faces = [&](auto crack_faces) {
4111 auto get_adj = [&](auto e, auto dim) {
4112 Range adj;
4113 CHKERR mField.get_moab().get_adjacencies(e, dim, true, adj,
4114 moab::Interface::UNION);
4115 return adj;
4116 };
4117 auto tets = get_adj(crack_faces, 3);
4118 auto faces = subtract(get_adj(tets, 2), crack_faces);
4119 tets = subtract(tets, get_adj(faces, 3));
4120 return subtract(crack_faces, get_adj(tets, 2));
4121 };
4122
4123 auto [crack_faces_pos, crack_faces_neg] =
4124 get_post_negative(intersect(own_faces, get_crack_faces(*crackFaces)));
4125
4126 auto only_crack_faces = [&](FEMethod *fe_method_ptr) {
4127 auto ent = fe_method_ptr->getFEEntityHandle();
4128 if (crack_faces_pos.find(ent) == crack_faces_pos.end()) {
4129 return false;
4130 }
4131 return true;
4132 };
4133
4134 auto only_negative_crack_faces = [&](FEMethod *fe_method_ptr) {
4135 auto ent = fe_method_ptr->getFEEntityHandle();
4136 if (crack_faces_neg.find(ent) == crack_faces_neg.end()) {
4137 return false;
4138 }
4139 return true;
4140 };
4141
4142 auto get_adj_front = [&]() {
4143 auto skeleton_faces = *skeletonFaces;
4144 Range adj_front;
4145 CHKERR mField.get_moab().get_adjacencies(*frontEdges, 2, true, adj_front,
4146 moab::Interface::UNION);
4147
4148 adj_front = intersect(adj_front, skeleton_faces);
4149 adj_front = subtract(adj_front, *crackFaces);
4150 adj_front = intersect(own_faces, adj_front);
4151 return adj_front;
4152 };
4153
4154 post_proc_ptr->setTagsToTransfer(tags_to_transfer);
4155 post_proc_negative_sense_ptr->setTagsToTransfer(tags_to_transfer);
4156
4157 auto post_proc_begin =
4159 CHKERR DMoFEMPreProcessFiniteElements(dM, post_proc_begin.getFEMethod());
4161 post_proc_ptr->exeTestHook = only_crack_faces;
4162 post_proc_negative_sense_ptr->exeTestHook = only_negative_crack_faces;
4164 dM, skeletonElement, post_proc_ptr, 0, mField.get_comm_size());
4166 post_proc_negative_sense_ptr, 0,
4168
4169 constexpr bool debug = false;
4170 if (debug) {
4171
4172 auto [adj_front_pos, adj_front_neg] =
4173 get_post_negative(filter_owners(mField, get_adj_front()));
4174
4175 auto only_front_faces_pos = [adj_front_pos](FEMethod *fe_method_ptr) {
4176 auto ent = fe_method_ptr->getFEEntityHandle();
4177 if (adj_front_pos.find(ent) == adj_front_pos.end()) {
4178 return false;
4179 }
4180 return true;
4181 };
4182
4183 auto only_front_faces_neg = [adj_front_neg](FEMethod *fe_method_ptr) {
4184 auto ent = fe_method_ptr->getFEEntityHandle();
4185 if (adj_front_neg.find(ent) == adj_front_neg.end()) {
4186 return false;
4187 }
4188 return true;
4189 };
4190
4191 post_proc_ptr->exeTestHook = only_front_faces_pos;
4193 dM, skeletonElement, post_proc_ptr, 0, mField.get_comm_size());
4194 post_proc_negative_sense_ptr->exeTestHook = only_front_faces_neg;
4196 post_proc_negative_sense_ptr, 0,
4198 }
4199 auto post_proc_end = PostProcBrokenMeshInMoabBaseEnd(mField, post_proc_mesh);
4200 CHKERR DMoFEMPostProcessFiniteElements(dM, post_proc_end.getFEMethod());
4201
4202 CHKERR post_proc_end.writeFile(file.c_str());
4204}
static auto filter_owners(MoFEM::Interface &m_field, Range skin)
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
PetscErrorCode DMoFEMPostProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
Definition DMMoFEM.cpp:546
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
Definition DMMoFEM.cpp:576
PetscErrorCode DMoFEMPreProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
Definition DMMoFEM.cpp:536
PostProcBrokenMeshInMoabBaseEndImpl< PostProcBrokenMeshInMoabBase< ForcesAndSourcesCore > > PostProcBrokenMeshInMoabBaseEnd
Enable to run stack of post-processing elements. Use this to end stack.
PostProcBrokenMeshInMoabBaseBeginImpl< PostProcBrokenMeshInMoabBase< ForcesAndSourcesCore > > PostProcBrokenMeshInMoabBaseBegin
Enable to run stack of post-processing elements. Use this to begin stack.
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
PipelineManager::ElementsAndOpsByDim< SPACE_DIM >::FaceSideEle EleOnSide
std::vector< Tag > listTagsToTransfer
list of tags to transfer to postprocessor
boost::shared_ptr< ContactTree > contactTreeRhs
Make a contact tree.
static Range getPartEntities(moab::Interface &moab, int part)
Data on single entity (This is passed as argument to DataOperator::doWork)
structure for User Loop Methods on finite elements
EntityHandle getFEEntityHandle() const
Calculate trace of vector (Hdiv/Hcurl) space.
Execute "this" element in the operator.
Post post-proc data at points from hash maps.
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
std::map< std::string, boost::shared_ptr< MatrixDouble > > DataMapMat
intrusive_ptr for managing petsc objects

◆ postProcessSkeletonResults()

MoFEMErrorCode EshelbianCore::postProcessSkeletonResults ( const int  tag,
const std::string  file,
Vec  f_residual = PETSC_NULLPTR,
std::vector< Tag tags_to_transfer = {} 
)
Examples
EshelbianPlasticity.cpp.

Definition at line 4207 of file EshelbianPlasticity.cpp.

4209 {
4211
4213
4214 auto post_proc_mesh = boost::make_shared<moab::Core>();
4215 auto post_proc_ptr =
4216 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
4217 mField, post_proc_mesh);
4218 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM - 1, SPACE_DIM>::add(
4219 post_proc_ptr->getOpPtrVector(), {L2}, materialH1Positions,
4221
4222 auto hybrid_disp = boost::make_shared<MatrixDouble>();
4223 post_proc_ptr->getOpPtrVector().push_back(
4225 post_proc_ptr->getOpPtrVector().push_back(
4227 hybridSpatialDisp, dataAtPts->getGradHybridDispAtPts()));
4228
4229 auto op_loop_domain_side =
4231 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
4232 post_proc_ptr->getOpPtrVector().push_back(op_loop_domain_side);
4233
4234 // evaluated in side domain, that is op_loop_domain_side
4235 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
4236 boost::make_shared<CGGUserPolynomialBase>();
4237 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4238 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
4240 op_loop_domain_side->getOpPtrVector().push_back(
4242 piolaStress, dataAtPts->getApproxPAtPts()));
4243 op_loop_domain_side->getOpPtrVector().push_back(
4245 bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
4246 op_loop_domain_side->getOpPtrVector().push_back(
4248 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
4249 if (noStretch) {
4250 op_loop_domain_side->getOpPtrVector().push_back(
4251 physicalEquations->returnOpCalculateStretchFromStress(
4253 } else {
4254 op_loop_domain_side->getOpPtrVector().push_back(
4256 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
4257 }
4258
4260
4261 OpPPMap::DataMapMat vec_fields;
4262 vec_fields["HybridDisplacement"] = hybrid_disp;
4263 vec_fields["Omega"] = dataAtPts->getRotAxisAtPts();
4264 OpPPMap::DataMapMat mat_fields;
4265 mat_fields["PiolaStress"] = dataAtPts->getApproxPAtPts();
4266 mat_fields["HybridDisplacementGradient"] =
4267 dataAtPts->getGradHybridDispAtPts();
4268 OpPPMap::DataMapMat mat_fields_symm;
4269 mat_fields_symm["LogSpatialStretch"] = dataAtPts->getLogStretchTensorAtPts();
4270
4271 post_proc_ptr->getOpPtrVector().push_back(
4272
4273 new OpPPMap(
4274
4275 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4276
4277 {},
4278
4279 vec_fields,
4280
4281 mat_fields,
4282
4283 mat_fields_symm
4284
4285 )
4286
4287 );
4288
4289 if (f_residual) {
4290 auto hybrid_res = boost::make_shared<MatrixDouble>();
4291 post_proc_ptr->getOpPtrVector().push_back(
4293 hybridSpatialDisp, hybrid_res,
4294 SmartPetscObj<Vec>(f_residual, true)));
4296 post_proc_ptr->getOpPtrVector().push_back(
4297
4298 new OpPPMap(
4299
4300 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4301
4302 {},
4303
4304 {{"res_hybrid", hybrid_res}},
4305
4306 {},
4307
4308 {}
4309
4310 )
4311
4312 );
4313 }
4314
4315 post_proc_ptr->setTagsToTransfer(tags_to_transfer);
4316
4317 auto post_proc_begin =
4319 CHKERR DMoFEMPreProcessFiniteElements(dM, post_proc_begin.getFEMethod());
4321 auto post_proc_end = PostProcBrokenMeshInMoabBaseEnd(mField, post_proc_mesh);
4322 CHKERR DMoFEMPostProcessFiniteElements(dM, post_proc_end.getFEMethod());
4323
4324 CHKERR post_proc_end.writeFile(file.c_str());
4325
4327}

◆ projectGeometry()

MoFEMErrorCode EshelbianCore::projectGeometry ( const EntityHandle  meshset = 0)
Examples
EshelbianPlasticity.cpp, and ep.cpp.

Definition at line 1406 of file EshelbianPlasticity.cpp.

1406 {
1408
1409 Range meshset_ents;
1410 CHKERR mField.get_moab().get_entities_by_handle(meshset, meshset_ents);
1411
1412 auto project_ho_geometry = [&](auto field) {
1414 return mField.loop_dofs(field, ent_method);
1415 };
1416 CHKERR project_ho_geometry(materialH1Positions);
1417
1418 auto get_adj_front_edges = [&](auto &front_edges) {
1419 Range front_crack_nodes;
1420 Range crack_front_edges_with_both_nodes_not_at_front;
1421
1422 if (mField.get_comm_rank() == 0) {
1423 auto &moab = mField.get_moab();
1424 CHKERR moab.get_connectivity(front_edges, front_crack_nodes, true);
1425 Range crack_front_edges;
1426 CHKERR moab.get_adjacencies(front_crack_nodes, SPACE_DIM - 2, false,
1427 crack_front_edges, moab::Interface::UNION);
1428 crack_front_edges_with_both_nodes_not_at_front =
1429 subtract(crack_front_edges, front_edges);
1430 }
1431
1432 front_crack_nodes = send_type(mField, front_crack_nodes, MBVERTEX);
1433 crack_front_edges_with_both_nodes_not_at_front = send_type(
1434 mField, crack_front_edges_with_both_nodes_not_at_front, MBEDGE);
1435
1436 return std::make_pair(boost::make_shared<Range>(front_crack_nodes),
1437 boost::make_shared<Range>(
1438 crack_front_edges_with_both_nodes_not_at_front));
1439 };
1440
1441 crackFaces = boost::make_shared<Range>(
1442 get_range_from_block(mField, "CRACK", SPACE_DIM - 1));
1443 frontEdges =
1444 boost::make_shared<Range>(get_crack_front_edges(mField, *crackFaces));
1445 auto [front_vertices, front_adj_edges] = get_adj_front_edges(*frontEdges);
1446 frontVertices = front_vertices;
1447 frontAdjEdges = front_adj_edges;
1448
1449#ifndef NDEBUG
1450 if (crackingOn) {
1451 auto rank = mField.get_comm_rank();
1452 // CHKERR save_range(mField.get_moab(),
1453 // (boost::format("meshset_ents_%d.vtk") % rank).str(),
1454 // meshset_ents);
1456 (boost::format("crack_faces_%d.vtk") % rank).str(),
1457 *crackFaces);
1459 (boost::format("front_edges_%d.vtk") % rank).str(),
1460 *frontEdges);
1461 // CHKERR save_range(mField.get_moab(),
1462 // (boost::format("front_vertices_%d.vtk") % rank).str(),
1463 // *frontVertices);
1464 // CHKERR save_range(mField.get_moab(),
1465 // (boost::format("front_adj_edges_%d.vtk") % rank).str(),
1466 // *frontAdjEdges);
1467 }
1468#endif // NDEBUG
1469
1470 auto set_singular_dofs = [&](auto &front_adj_edges, auto &front_vertices) {
1472 auto &moab = mField.get_moab();
1473
1474 double eps = 1;
1475 double beta = 0;
1476 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "-singularity_eps", &beta,
1477 PETSC_NULLPTR);
1478 MOFEM_LOG("EP", Sev::inform) << "Singularity eps " << beta;
1479 eps -= beta;
1480
1481 for (auto edge : front_adj_edges) {
1482 int num_nodes;
1483 const EntityHandle *conn;
1484 CHKERR moab.get_connectivity(edge, conn, num_nodes, false);
1485 double coords[6];
1486 CHKERR moab.get_coords(conn, num_nodes, coords);
1487 const double dir[3] = {coords[3] - coords[0], coords[4] - coords[1],
1488 coords[5] - coords[2]};
1489 double dof[3] = {0, 0, 0};
1490 if (front_vertices.find(conn[0]) != front_vertices.end()) {
1491 for (int dd = 0; dd != 3; dd++) {
1492 dof[dd] = -dir[dd] * eps;
1493 }
1494 } else if (front_vertices.find(conn[1]) != front_vertices.end()) {
1495 for (int dd = 0; dd != 3; dd++) {
1496 dof[dd] = +dir[dd] * eps;
1497 }
1498 }
1500 mField, materialH1Positions, edge, dit)) {
1501 const int idx = dit->get()->getEntDofIdx();
1502 if (idx > 2) {
1503 dit->get()->getFieldData() = 0;
1504 } else {
1505 dit->get()->getFieldData() = dof[idx];
1506 }
1507 }
1508 }
1509
1511 };
1512
1513 if (setSingularity)
1514 CHKERR set_singular_dofs(*frontAdjEdges, *frontVertices);
1515
1517}
static auto get_crack_front_edges(MoFEM::Interface &m_field, Range crack_faces)
#define _IT_GET_DOFS_FIELD_BY_NAME_AND_ENT_FOR_LOOP_(MFIELD, NAME, ENT, IT)
loop over all dofs from a moFEM field and particular field
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.
PetscErrorCode PetscOptionsGetScalar(PetscOptions *, const char pre[], const char name[], PetscScalar *dval, PetscBool *set)
Projection of edge entities with one mid-node on hierarchical basis.

◆ query_interface()

MoFEMErrorCode EshelbianCore::query_interface ( boost::typeindex::type_index  type_index,
UnknownInterface **  iface 
) const

Getting interface of core database.

Parameters
uuidunique ID of interface
ifacereturned pointer to interface
Returns
error code
Examples
EshelbianPlasticity.cpp.

Definition at line 898 of file EshelbianPlasticity.cpp.

899 {
900 *iface = const_cast<EshelbianCore *>(this);
901 return 0;
902}

◆ saveOrgCoords()

MoFEMErrorCode EshelbianCore::saveOrgCoords ( )
Examples
EshelbianPlasticity.cpp.

Definition at line 6735 of file EshelbianPlasticity.cpp.

6735 {
6737 auto crack_faces =
6738 get_range_from_block(mField, "CRACK_COMPUTED", SPACE_DIM - 1);
6739 Range conn;
6740 CHKERR mField.get_moab().get_connectivity(crack_faces, conn, true);
6741 Range verts;
6742 CHKERR mField.get_moab().get_entities_by_type(0, MBVERTEX, verts);
6743 verts = subtract(verts, conn);
6744 std::vector<double> coords(3 * verts.size());
6745 CHKERR mField.get_moab().get_coords(verts, coords.data());
6746 double def_coords[] = {0., 0., 0.};
6747 Tag th_org_coords;
6748 CHKERR mField.get_moab().tag_get_handle(
6749 "ORG_COORDS", 3, MB_TYPE_DOUBLE, th_org_coords,
6750 MB_TAG_CREAT | MB_TAG_DENSE, def_coords);
6751 CHKERR mField.get_moab().tag_set_data(th_org_coords, verts, coords.data());
6753}

◆ setBaseVolumeElementOps()

MoFEMErrorCode EshelbianCore::setBaseVolumeElementOps ( const int  tag,
const bool  do_rhs,
const bool  do_lhs,
const bool  calc_rates,
SmartPetscObj< Vec >  ver_vec,
boost::shared_ptr< VolumeElementForcesAndSourcesCore fe 
)
Examples
EshelbianPlasticity.cpp.

Definition at line 2307 of file EshelbianPlasticity.cpp.

2310 {
2312
2313 auto bubble_cache =
2314 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0, MatrixDouble());
2315 fe->getUserPolynomialBase() =
2316 boost::make_shared<CGGUserPolynomialBase>(bubble_cache);
2317 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2318 fe->getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions, frontAdjEdges);
2319
2320 // set integration rule
2321 fe->getRuleHook = [](int, int, int) { return -1; };
2322 fe->setRuleHook = SetIntegrationAtFrontVolume(frontVertices, frontAdjEdges);
2323 // fe->getRuleHook = VolRule();
2324
2325 if (!dataAtPts) {
2326 dataAtPts =
2327 boost::shared_ptr<DataAtIntegrationPts>(new DataAtIntegrationPts());
2328 dataAtPts->physicsPtr = physicalEquations;
2329 }
2330
2331 // calculate fields values
2332 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
2333 piolaStress, dataAtPts->getApproxPAtPts()));
2334 fe->getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
2335 bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
2336 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorDivergence<3, 3>(
2337 piolaStress, dataAtPts->getDivPAtPts()));
2338
2339 if (noStretch) {
2340 fe->getOpPtrVector().push_back(
2341 physicalEquations->returnOpCalculateStretchFromStress(
2343 } else {
2344 fe->getOpPtrVector().push_back(
2346 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
2347 }
2348
2349 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2350 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
2351 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2352 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
2353 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2354 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
2355
2356 // H1 displacements
2357 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2358 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
2359 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldGradient<3, 3>(
2360 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
2361
2362 // velocities
2363 if (calc_rates) {
2364 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValuesDot<3>(
2365 spatialL2Disp, dataAtPts->getSmallWL2DotAtPts(), MBTET));
2366 if (noStretch) {
2367 } else {
2368 fe->getOpPtrVector().push_back(
2370 stretchTensor, dataAtPts->getLogStretchDotTensorAtPts(), MBTET));
2371 fe->getOpPtrVector().push_back(
2373 stretchTensor, dataAtPts->getGradLogStretchDotTensorAtPts(),
2374 MBTET));
2375 }
2376 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValuesDot<3>(
2377 rotAxis, dataAtPts->getRotAxisDotAtPts(), MBTET));
2378 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldGradientDot<3, 3>(
2379 rotAxis, dataAtPts->getRotAxisGradDotAtPts(), MBTET));
2380
2381 // acceleration
2382 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
2383 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValuesDotDot<3>(
2384 spatialL2Disp, dataAtPts->getSmallWL2DotDotAtPts(), MBTET));
2385 }
2386 }
2387
2388 // variations
2389 if (var_vec.use_count()) {
2390 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
2391 piolaStress, dataAtPts->getVarPiolaPts(), boost::make_shared<double>(1),
2392 var_vec));
2393 fe->getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
2394 bubbleField, dataAtPts->getVarPiolaPts(), boost::make_shared<double>(1),
2395 var_vec, MBMAXTYPE));
2396 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2397 rotAxis, dataAtPts->getVarRotAxisPts(), var_vec, MBTET));
2398 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorDivergence<3, 3>(
2399 piolaStress, dataAtPts->getDivVarPiolaPts(), var_vec));
2400 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2401 spatialL2Disp, dataAtPts->getVarWL2Pts(), var_vec, MBTET));
2402
2403 if (noStretch) {
2404 fe->getOpPtrVector().push_back(
2405 physicalEquations->returnOpCalculateVarStretchFromStress(
2407 } else {
2408 fe->getOpPtrVector().push_back(
2410 stretchTensor, dataAtPts->getVarLogStreachPts(), var_vec, MBTET));
2411 }
2412 }
2413
2414 // calculate other derived quantities
2415 fe->getOpPtrVector().push_back(new OpCalculateRotationAndSpatialGradient(
2416 dataAtPts, ((do_rhs || do_lhs) && calc_rates) ? alphaOmega : 0.));
2417
2418 // evaluate integration points
2419 if (noStretch) {
2420 } else {
2421 fe->getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
2422 tag, do_rhs, do_lhs, dataAtPts, physicalEquations));
2423 }
2424
2426}
UBlasMatrix< double > MatrixDouble
Definition Types.hpp:77
Calculate divergence of tonsorial field using vectorial base.
Calculate symmetric tensor field rates ant integratio pts.
Get field gradients time derivative at integration pts for scalar field rank 0, i....
Approximate field values for given petsc vector.

◆ setBlockTagsOnSkin()

MoFEMErrorCode EshelbianCore::setBlockTagsOnSkin ( )
Examples
EshelbianPlasticity.cpp, and ep.cpp.

Definition at line 3652 of file EshelbianPlasticity.cpp.

3652 {
3654
3655 auto set_block = [&](auto name, int dim) {
3656 std::map<int, Range> map;
3657 auto set_tag_impl = [&](auto name) {
3659 auto mesh_mng = mField.getInterface<MeshsetsManager>();
3660 auto bcs = mesh_mng->getCubitMeshsetPtr(
3661
3662 std::regex((boost::format("%s(.*)") % name).str())
3663
3664 );
3665 for (auto bc : bcs) {
3666 Range r;
3667 CHKERR bc->getMeshsetIdEntitiesByDimension(mField.get_moab(), dim, r,
3668 true);
3669 map[bc->getMeshsetId()] = r;
3670 }
3672 };
3673
3674 CHKERR set_tag_impl(name);
3675
3676 return std::make_pair(name, map);
3677 };
3678
3679 auto set_skin = [&](auto &&map) {
3680 for (auto &m : map.second) {
3681 auto s = filter_true_skin(mField, get_skin(mField, m.second));
3682 m.second.swap(s);
3683 }
3684 return map;
3685 };
3686
3687 auto set_tag = [&](auto &&map) {
3688 Tag th;
3689 auto name = map.first;
3690 int def_val[] = {-1};
3692 mField.get_moab().tag_get_handle(name, 1, MB_TYPE_INTEGER, th,
3693 MB_TAG_SPARSE | MB_TAG_CREAT, def_val),
3694 "create tag");
3695 for (auto &m : map.second) {
3696 int id = m.first;
3697 CHK_MOAB_THROW(mField.get_moab().tag_clear_data(th, m.second, &id),
3698 "clear tag");
3699 }
3700 return th;
3701 };
3702
3703 listTagsToTransfer.push_back(set_tag(set_skin(set_block("BODY", 3))));
3704 listTagsToTransfer.push_back(set_tag(set_skin(set_block("MAT_ELASTIC", 3))));
3705 listTagsToTransfer.push_back(
3706 set_tag(set_skin(set_block("MAT_NEOHOOKEAN", 3))));
3707 listTagsToTransfer.push_back(set_tag(set_block("CONTACT", 2)));
3708
3710}
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset

◆ setContactElementRhsOps()

MoFEMErrorCode EshelbianCore::setContactElementRhsOps ( boost::shared_ptr< ContactTree > &  fe_contact_tree)

Contact requires that body is marked

Examples
EshelbianPlasticity.cpp.

Definition at line 3079 of file EshelbianPlasticity.cpp.

3083 {
3085
3086 /** Contact requires that body is marked */
3087 auto get_body_range = [this](auto name, int dim, auto sev) {
3088 std::map<int, Range> map;
3089
3090 for (auto m_ptr :
3091 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
3092
3093 (boost::format("%s(.*)") % name).str()
3094
3095 ))
3096
3097 ) {
3098 Range ents;
3099 CHK_MOAB_THROW(m_ptr->getMeshsetIdEntitiesByDimension(mField.get_moab(),
3100 dim, ents, true),
3101 "by dim");
3102 map[m_ptr->getMeshsetId()] = ents;
3103 MOFEM_LOG("EPSYNC", sev) << "Meshset: " << m_ptr->getMeshsetId() << " "
3104 << ents.size() << " entities";
3105 }
3106
3108 return map;
3109 };
3110
3111 auto get_map_skin = [this](auto &&map) {
3112 ParallelComm *pcomm =
3113 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
3114
3115 Skinner skin(&mField.get_moab());
3116 for (auto &m : map) {
3117 Range skin_faces;
3118 CHKERR skin.find_skin(0, m.second, false, skin_faces);
3119 CHK_MOAB_THROW(pcomm->filter_pstatus(skin_faces,
3120 PSTATUS_SHARED | PSTATUS_MULTISHARED,
3121 PSTATUS_NOT, -1, nullptr),
3122 "filter");
3123 m.second.swap(skin_faces);
3124 }
3125 return map;
3126 };
3127
3128 /* The above code is written in C++ and it appears to be defining and using
3129 various operations on boundary elements and side elements. */
3131 using BoundaryEleOp = BoundaryEle::UserDataOperator;
3132
3133 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
3134
3135 auto calcs_side_traction = [&](auto &pip) {
3137 using EleOnSide =
3139 using SideEleOp = EleOnSide::UserDataOperator;
3140 auto op_loop_domain_side = new OpLoopSide<EleOnSide>(
3141 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
3142 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3143 boost::make_shared<CGGUserPolynomialBase>();
3144 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3145 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3147 op_loop_domain_side->getOpPtrVector().push_back(
3149 piolaStress, contact_common_data_ptr->contactTractionPtr(),
3150 boost::make_shared<double>(1.0)));
3151 pip.push_back(op_loop_domain_side);
3153 };
3154
3155 auto add_contact_three = [&]() {
3157 auto tree_moab_ptr = boost::make_shared<moab::Core>();
3158 fe_contact_tree = boost::make_shared<ContactTree>(
3159 mField, tree_moab_ptr, spaceOrder,
3160 get_body_range("CONTACT", SPACE_DIM - 1, Sev::inform));
3161 fe_contact_tree->getOpPtrVector().push_back(
3163 contactDisp, contact_common_data_ptr->contactDispPtr()));
3164 CHKERR calcs_side_traction(fe_contact_tree->getOpPtrVector());
3165 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
3166 fe_contact_tree->getOpPtrVector().push_back(
3168 fe_contact_tree->getOpPtrVector().push_back(
3169 new OpMoveNode(fe_contact_tree, contact_common_data_ptr, u_h1_ptr));
3171 };
3172
3173 CHKERR add_contact_three();
3174
3176}

◆ setElasticElementOps()

MoFEMErrorCode EshelbianCore::setElasticElementOps ( const int  tag)
Examples
EshelbianPlasticity.cpp, and ep.cpp.

Definition at line 3178 of file EshelbianPlasticity.cpp.

3178 {
3180
3181 // Add contact operators. Note that only for rhs. THe lhs is assembled with
3182 // volume element, to enable schur complement evaluation.
3184
3187
3188 auto adj_cache =
3189 boost::make_shared<ForcesAndSourcesCore::UserDataOperator::AdjCache>();
3190
3191 auto get_op_contact_bc = [&]() {
3193 auto op_loop_side = new OpLoopSide<SideEle>(
3194 mField, contactElement, SPACE_DIM - 1, Sev::noisy, adj_cache);
3195 return op_loop_side;
3196 };
3197
3199}
ElementsAndOps< SPACE_DIM >::SideEle SideEle
Definition plastic.cpp:61
boost::shared_ptr< FaceElementForcesAndSourcesCore > elasticBcRhs
boost::shared_ptr< FaceElementForcesAndSourcesCore > elasticBcLhs
boost::shared_ptr< VolumeElementForcesAndSourcesCore > elasticFeRhs
MoFEMErrorCode setVolumeElementOps(const int tag, const bool add_elastic, const bool add_material, boost::shared_ptr< VolumeElementForcesAndSourcesCore > &fe_rhs, boost::shared_ptr< VolumeElementForcesAndSourcesCore > &fe_lhs)
boost::shared_ptr< VolumeElementForcesAndSourcesCore > elasticFeLhs
MoFEMErrorCode setContactElementRhsOps(boost::shared_ptr< ContactTree > &fe_contact_tree)
MoFEMErrorCode setFaceElementOps(const bool add_elastic, const bool add_material, boost::shared_ptr< FaceElementForcesAndSourcesCore > &fe_rhs, boost::shared_ptr< FaceElementForcesAndSourcesCore > &fe_lhs)

◆ setElasticElementToTs()

MoFEMErrorCode EshelbianCore::setElasticElementToTs ( DM  dm)
Examples
EshelbianPlasticity.cpp, and ep.cpp.

Definition at line 3201 of file EshelbianPlasticity.cpp.

3201 {
3203 boost::shared_ptr<FEMethod> null;
3204
3205 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
3206
3208 null);
3210 null);
3212 null);
3214 null);
3215
3216 } else {
3218 null);
3220 null);
3222 null);
3224 null);
3225 }
3226
3228}
PetscErrorCode DMMoFEMTSSetIFunction(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
set TS implicit function evaluation function
Definition DMMoFEM.cpp:790
PetscErrorCode DMMoFEMTSSetIJacobian(DM dm, 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 TS Jacobian evaluation function
Definition DMMoFEM.cpp:843
PetscErrorCode DMMoFEMTSSetI2Jacobian(DM dm, 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 TS Jacobian evaluation function
Definition DMMoFEM.cpp:1007
PetscErrorCode DMMoFEMTSSetI2Function(DM dm, 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 TS implicit function evaluation function
Definition DMMoFEM.cpp:965

◆ setFaceElementOps()

MoFEMErrorCode EshelbianCore::setFaceElementOps ( const bool  add_elastic,
const bool  add_material,
boost::shared_ptr< FaceElementForcesAndSourcesCore > &  fe_rhs,
boost::shared_ptr< FaceElementForcesAndSourcesCore > &  fe_lhs 
)
Examples
EshelbianPlasticity.cpp.

Definition at line 2920 of file EshelbianPlasticity.cpp.

2923 {
2925
2926 fe_rhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
2927 fe_lhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
2928
2929 // set integration rule
2930 // fe_rhs->getRuleHook = [](int, int, int p) { return 2 * (p + 1); };
2931 // fe_lhs->getRuleHook = [](int, int, int p) { return 2 * (p + 1); };
2932 fe_rhs->getRuleHook = [](int, int, int) { return -1; };
2933 fe_lhs->getRuleHook = [](int, int, int) { return -1; };
2934 fe_rhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
2935 fe_lhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
2936
2937 CHKERR
2938 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2939 fe_rhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
2940 CHKERR
2941 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2942 fe_lhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
2943
2944 if (add_elastic) {
2945
2946 auto get_broken_op_side = [this](auto &pip) {
2947 using EleOnSide =
2949 using SideEleOp = EleOnSide::UserDataOperator;
2950 // Iterate over domain FEs adjacent to boundary.
2951 auto broken_data_ptr =
2952 boost::make_shared<std::vector<BrokenBaseSideData>>();
2953 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
2954 auto op_loop_domain_side = new OpLoopSide<EleOnSide>(
2955 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
2956 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2957 boost::make_shared<CGGUserPolynomialBase>();
2958 CHKERR
2959 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2960 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2962 op_loop_domain_side->getOpPtrVector().push_back(
2963 new OpGetBrokenBaseSideData<SideEleOp>(piolaStress, broken_data_ptr));
2964 boost::shared_ptr<double> piola_scale_ptr(new double);
2965 op_loop_domain_side->getOpPtrVector().push_back(
2966 physicalEquations->returnOpSetScale(piola_scale_ptr,
2968
2969 auto piola_stress_mat_ptr = boost::make_shared<MatrixDouble>();
2970 op_loop_domain_side->getOpPtrVector().push_back(
2972 piola_stress_mat_ptr));
2973 pip.push_back(op_loop_domain_side);
2974 return std::make_tuple(broken_data_ptr, piola_scale_ptr,
2975 piola_stress_mat_ptr);
2976 };
2977
2978 auto set_rhs = [&]() {
2980
2981 auto [broken_data_ptr, piola_scale_ptr, piola_stress_mat_ptr] =
2982 get_broken_op_side(fe_rhs->getOpPtrVector());
2983
2984 fe_rhs->getOpPtrVector().push_back(
2985 new OpDispBc(broken_data_ptr, bcSpatialDispVecPtr, timeScaleMap));
2986 fe_rhs->getOpPtrVector().push_back(new OpAnalyticalDispBc(
2988 timeScaleMap));
2989 fe_rhs->getOpPtrVector().push_back(new OpRotationBc(
2990 broken_data_ptr, bcSpatialRotationVecPtr, timeScaleMap));
2991
2992 fe_rhs->getOpPtrVector().push_back(
2994 piola_scale_ptr, timeScaleMap));
2995 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
2996 // if you push gradient of L2 base to physical element, it will not work.
2997 fe_rhs->getOpPtrVector().push_back(
2999 hybridSpatialDisp, hybrid_grad_ptr));
3000 fe_rhs->getOpPtrVector().push_back(new OpBrokenPressureBc(
3002 hybrid_grad_ptr, timeScaleMap));
3003 fe_rhs->getOpPtrVector().push_back(new OpBrokenAnalyticalTractionBc(
3005 timeScaleMap));
3006
3007 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3008 fe_rhs->getOpPtrVector().push_back(
3010 hybrid_ptr));
3011 fe_rhs->getOpPtrVector().push_back(new OpNormalDispRhsBc(
3012 hybridSpatialDisp, hybrid_ptr, piola_stress_mat_ptr,
3014
3015 auto get_normal_disp_bc_faces = [&]() {
3016 auto faces =
3017 get_range_from_block(mField, "NORMAL_DISPLACEMENT", SPACE_DIM - 1);
3018 return boost::make_shared<Range>(faces);
3019 };
3020
3021 using BoundaryEle =
3023 using BdyEleOp = BoundaryEle::UserDataOperator;
3025 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
3026 fe_rhs->getOpPtrVector().push_back(new OpC_dBroken(
3027 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0),
3028 get_normal_disp_bc_faces()));
3029
3031 };
3032
3033 auto set_lhs = [&]() {
3035
3036 auto [broken_data_ptr, piola_scale_ptr, piola_stress_mat_ptr] =
3037 get_broken_op_side(fe_lhs->getOpPtrVector());
3038
3039 fe_lhs->getOpPtrVector().push_back(new OpNormalDispLhsBc_dU(
3041 fe_lhs->getOpPtrVector().push_back(new OpNormalDispLhsBc_dP(
3043 timeScaleMap));
3044
3045 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
3046 // if you push gradient of L2 base to physical element, it will not work.
3047 fe_rhs->getOpPtrVector().push_back(
3049 hybridSpatialDisp, hybrid_grad_ptr));
3050 fe_lhs->getOpPtrVector().push_back(new OpBrokenPressureBcLhs_dU(
3052 timeScaleMap));
3053
3054 auto get_normal_disp_bc_faces = [&]() {
3055 auto faces =
3056 get_range_from_block(mField, "NORMAL_DISPLACEMENT", SPACE_DIM - 1);
3057 return boost::make_shared<Range>(faces);
3058 };
3059
3060 using BoundaryEle =
3062 using BdyEleOp = BoundaryEle::UserDataOperator;
3064 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
3065 fe_lhs->getOpPtrVector().push_back(new OpC(
3066 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0),
3067 true, true, get_normal_disp_bc_faces()));
3068
3070 };
3071
3072 CHKERR set_rhs();
3073 CHKERR set_lhs();
3074 }
3075
3077}
constexpr AssemblyType A
Apply rotation boundary condition.
BoundaryEle::UserDataOperator BdyEleOp

◆ setNewFrontCoordinates()

MoFEMErrorCode EshelbianCore::setNewFrontCoordinates ( )
Examples
EshelbianPlasticity.cpp.

Definition at line 5959 of file EshelbianPlasticity.cpp.

5959 {
5961
5962 if (!maxMovedFaces)
5964
5965 Tag th_front_position;
5966 auto rval =
5967 mField.get_moab().tag_get_handle("FrontPosition", th_front_position);
5968 if (rval == MB_SUCCESS && maxMovedFaces) {
5969 Range verts;
5970 CHKERR mField.get_moab().get_connectivity(*maxMovedFaces, verts, true);
5971 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(verts);
5972 std::vector<double> coords(3 * verts.size());
5973 CHKERR mField.get_moab().get_coords(verts, coords.data());
5974 std::vector<double> pos(3 * verts.size());
5975 CHKERR mField.get_moab().tag_get_data(th_front_position, verts, pos.data());
5976 for (int i = 0; i != 3 * verts.size(); ++i) {
5977 coords[i] += pos[i];
5978 }
5979 CHKERR mField.get_moab().set_coords(verts, coords.data());
5980 double zero[] = {0., 0., 0.};
5981 CHKERR mField.get_moab().tag_clear_data(th_front_position, verts, zero);
5982 }
5983
5984#ifndef NDEBUG
5985 constexpr bool debug = false;
5986 if (debug) {
5987
5989 mField.get_moab(),
5990 "set_coords_faces_" +
5991 boost::lexical_cast<std::string>(mField.get_comm_rank()) + ".vtk",
5992 *maxMovedFaces);
5993 }
5994#endif
5996}

◆ setVolumeElementOps()

MoFEMErrorCode EshelbianCore::setVolumeElementOps ( const int  tag,
const bool  add_elastic,
const bool  add_material,
boost::shared_ptr< VolumeElementForcesAndSourcesCore > &  fe_rhs,
boost::shared_ptr< VolumeElementForcesAndSourcesCore > &  fe_lhs 
)

Contact requires that body is marked

Examples
EshelbianPlasticity.cpp.

Definition at line 2428 of file EshelbianPlasticity.cpp.

2431 {
2433
2434 /** Contact requires that body is marked */
2435 auto get_body_range = [this](auto name, int dim) {
2436 std::map<int, Range> map;
2437
2438 for (auto m_ptr :
2439 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
2440
2441 (boost::format("%s(.*)") % name).str()
2442
2443 ))
2444
2445 ) {
2446 Range ents;
2447 CHK_MOAB_THROW(m_ptr->getMeshsetIdEntitiesByDimension(mField.get_moab(),
2448 dim, ents, true),
2449 "by dim");
2450 map[m_ptr->getMeshsetId()] = ents;
2451 }
2452
2453 return map;
2454 };
2455
2456 auto rule_contact = [](int, int, int o) { return -1; };
2458
2459 auto set_rule_contact = [refine](
2460
2461 ForcesAndSourcesCore *fe_raw_ptr, int order_row,
2462 int order_col, int order_data
2463
2464 ) {
2466 auto rule = 2 * order_data;
2467 fe_raw_ptr->gaussPts = Tools::refineTriangleIntegrationPts(rule, refine);
2469 };
2470
2471 // Right hand side
2472 fe_rhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
2473 CHKERR setBaseVolumeElementOps(tag, true, false, true, SmartPetscObj<Vec>(),
2474 fe_rhs);
2475
2476 // elastic
2477 if (add_elastic) {
2478
2479 fe_rhs->getOpPtrVector().push_back(
2481 fe_rhs->getOpPtrVector().push_back(
2483 if (noStretch) {
2484 // do nothing - no stretch approximation
2485 } else {
2486 if (!internalStressTagName.empty()) {
2487 switch (internalStressInterpOrder) {
2488 case 0:
2489 fe_rhs->getOpPtrVector().push_back(
2491 break;
2492 case 1:
2493 fe_rhs->getOpPtrVector().push_back(
2495 break;
2496 default:
2497 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
2498 "Unsupported internal stress interpolation order %d",
2500 }
2501 if (internalStressVoigt) {
2502 fe_rhs->getOpPtrVector().push_back(
2504 dataAtPts));
2505 } else {
2506 fe_rhs->getOpPtrVector().push_back(
2508 dataAtPts));
2509 }
2510 }
2511 if (auto op = physicalEquations->returnOpSpatialPhysicalExternalStrain(
2513 fe_rhs->getOpPtrVector().push_back(op);
2514 } else if (externalStrainVecPtr && !externalStrainVecPtr->empty()) {
2515 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
2516 "OpSpatialPhysicalExternalStrain not implemented for this "
2517 "material");
2518 }
2519
2520 fe_rhs->getOpPtrVector().push_back(
2521 physicalEquations->returnOpSpatialPhysical(stretchTensor, dataAtPts,
2522 alphaU));
2523 }
2524 fe_rhs->getOpPtrVector().push_back(
2526 fe_rhs->getOpPtrVector().push_back(
2528 fe_rhs->getOpPtrVector().push_back(
2530
2531 auto set_hybridisation = [&](auto &pip) {
2533
2534 using BoundaryEle =
2536 using EleOnSide =
2538 using SideEleOp = EleOnSide::UserDataOperator;
2539 using BdyEleOp = BoundaryEle::UserDataOperator;
2540
2541 // First: Iterate over skeleton FEs adjacent to Domain FEs
2542 // Note: BoundaryEle, i.e. uses skeleton interation rule
2543 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
2544 mField, skeletonElement, SPACE_DIM - 1, Sev::noisy);
2545 // op_loop_skeleton_side->getSideFEPtr()->getRuleHook = FaceRule();
2546 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
2547 return -1;
2548 };
2549 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
2550 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
2551
2552 CHKERR EshelbianPlasticity::
2553 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2554 op_loop_skeleton_side->getOpPtrVector(), {L2},
2556
2557 // Second: Iterate over domain FEs adjacent to skelton, particularly one
2558 // domain element.
2559 auto broken_data_ptr =
2560 boost::make_shared<std::vector<BrokenBaseSideData>>();
2561 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
2562 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
2563 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
2564 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2565 boost::make_shared<CGGUserPolynomialBase>();
2566 CHKERR
2567 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2568 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2570 op_loop_domain_side->getOpPtrVector().push_back(
2571 new OpGetBrokenBaseSideData<SideEleOp>(piolaStress, broken_data_ptr));
2572 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
2573 op_loop_domain_side->getOpPtrVector().push_back(
2575 flux_mat_ptr));
2576 op_loop_domain_side->getOpPtrVector().push_back(
2577 new OpSetFlux<SideEleOp>(broken_data_ptr, flux_mat_ptr));
2578
2579 // Assemble on skeleton
2580 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
2582 GAUSS>::OpBrokenSpaceConstrainDHybrid<SPACE_DIM>;
2584 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
2585 op_loop_skeleton_side->getOpPtrVector().push_back(new OpC_dHybrid(
2586 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0)));
2587 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
2588 op_loop_skeleton_side->getOpPtrVector().push_back(
2590 hybrid_ptr));
2591 op_loop_skeleton_side->getOpPtrVector().push_back(new OpC_dBroken(
2592 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0)));
2593
2594 // Add skeleton to domain pipeline
2595 pip.push_back(op_loop_skeleton_side);
2596
2598 };
2599
2600 auto set_contact = [&](auto &pip) {
2602
2603 using BoundaryEle =
2605 using EleOnSide =
2607 using SideEleOp = EleOnSide::UserDataOperator;
2608 using BdyEleOp = BoundaryEle::UserDataOperator;
2609
2610 // First: Iterate over skeleton FEs adjacent to Domain FEs
2611 // Note: BoundaryEle, i.e. uses skeleton interation rule
2612 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
2613 mField, contactElement, SPACE_DIM - 1, Sev::noisy);
2614
2615 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
2616 op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
2617 CHKERR EshelbianPlasticity::
2618 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2619 op_loop_skeleton_side->getOpPtrVector(), {L2},
2621
2622 // Second: Iterate over domain FEs adjacent to skelton, particularly
2623 // one domain element.
2624 auto broken_data_ptr =
2625 boost::make_shared<std::vector<BrokenBaseSideData>>();
2626
2627 // Data storing contact fields
2628 auto contact_common_data_ptr =
2629 boost::make_shared<ContactOps::CommonData>();
2630
2631 auto add_ops_domain_side = [&](auto &pip) {
2633 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
2634 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
2635 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
2636 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2637 boost::make_shared<CGGUserPolynomialBase>();
2638 CHKERR
2639 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2640 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2642 op_loop_domain_side->getOpPtrVector().push_back(
2644 broken_data_ptr));
2645 op_loop_domain_side->getOpPtrVector().push_back(
2647 piolaStress, contact_common_data_ptr->contactTractionPtr()));
2648 pip.push_back(op_loop_domain_side);
2650 };
2651
2652 auto add_ops_contact_rhs = [&](auto &pip) {
2654 // get body id and SDF range
2655 auto contact_sfd_map_range_ptr =
2656 boost::make_shared<std::map<int, Range>>(
2657 get_body_range("CONTACT_SDF", SPACE_DIM - 1));
2658
2659 pip.push_back(new OpCalculateVectorFieldValues<3>(
2660 contactDisp, contact_common_data_ptr->contactDispPtr()));
2661 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2662 pip.push_back(
2664 pip.push_back(new OpTreeSearch(
2665 contactTreeRhs, contact_common_data_ptr, u_h1_ptr,
2666 get_range_from_block(mField, "CONTACT", SPACE_DIM - 1), nullptr,
2667 nullptr));
2669 contactDisp, contact_common_data_ptr, contactTreeRhs,
2670 contact_sfd_map_range_ptr));
2671 pip.push_back(
2673 broken_data_ptr, contact_common_data_ptr, contactTreeRhs));
2674
2676 };
2677
2678 // push ops to face/side pipeline
2679 CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
2680 CHKERR add_ops_contact_rhs(op_loop_skeleton_side->getOpPtrVector());
2681
2682 // Add skeleton to domain pipeline
2683 pip.push_back(op_loop_skeleton_side);
2684
2686 };
2687
2688 CHKERR set_hybridisation(fe_rhs->getOpPtrVector());
2689 CHKERR set_contact(fe_rhs->getOpPtrVector());
2690
2691 // Body forces
2692 using BodyNaturalBC =
2694 Assembly<PETSC>::LinearForm<GAUSS>;
2695 using OpBodyForce =
2696 BodyNaturalBC::OpFlux<NaturalMeshsetType<BLOCKSET>, 1, 3>;
2697
2698 auto body_time_scale =
2699 boost::make_shared<DynamicRelaxationTimeScale>("body_force.txt");
2700 CHKERR BodyNaturalBC::AddFluxToPipeline<OpBodyForce>::add(
2701 fe_rhs->getOpPtrVector(), mField, spatialL2Disp, {body_time_scale},
2702 "BODY_FORCE", Sev::inform);
2703 }
2704
2705 // Left hand side
2706 fe_lhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
2707 CHKERR setBaseVolumeElementOps(tag, true, true, true, SmartPetscObj<Vec>(),
2708 fe_lhs);
2709
2710 // elastic
2711 if (add_elastic) {
2712
2713 if (noStretch) {
2714 fe_lhs->getOpPtrVector().push_back(
2716 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dBubble_dP(
2718 fe_lhs->getOpPtrVector().push_back(
2720 dataAtPts));
2721 } else {
2722 fe_lhs->getOpPtrVector().push_back(
2723 physicalEquations->returnOpSpatialPhysical_du_du(
2725 fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_dP(
2727 fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_dBubble(
2729 fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_domega(
2731 symmetrySelector == SYMMETRIC ? true : false));
2732 }
2733
2734 fe_lhs->getOpPtrVector().push_back(new OpSpatialEquilibrium_dw_dP(
2736 fe_lhs->getOpPtrVector().push_back(new OpSpatialEquilibrium_dw_dw(
2738
2739 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dP_domega(
2741 symmetrySelector == SYMMETRIC ? true : false));
2742 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dBubble_domega(
2744 symmetrySelector == SYMMETRIC ? true : false));
2745
2746 if (symmetrySelector > SYMMETRIC) {
2747 if (!noStretch) {
2748 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_du(
2749 rotAxis, stretchTensor, dataAtPts, false));
2750 }
2751 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_dP(
2752 rotAxis, piolaStress, dataAtPts, false));
2753 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_dBubble(
2754 rotAxis, bubbleField, dataAtPts, false));
2755 }
2756 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_domega(
2758
2759 // stabilise
2760 fe_lhs->getOpPtrVector().push_back(new OpAssembleVolumeStabilize());
2761
2762
2763 auto set_hybridisation = [&](auto &pip) {
2765
2766 using BoundaryEle =
2768 using EleOnSide =
2770 using SideEleOp = EleOnSide::UserDataOperator;
2771 using BdyEleOp = BoundaryEle::UserDataOperator;
2772
2773 // First: Iterate over skeleton FEs adjacent to Domain FEs
2774 // Note: BoundaryEle, i.e. uses skeleton interation rule
2775 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
2776 mField, skeletonElement, SPACE_DIM - 1, Sev::noisy);
2777 // op_loop_skeleton_side->getSideFEPtr()->getRuleHook = FaceRule();
2778 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
2779 return -1;
2780 };
2781 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
2782 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
2783 CHKERR EshelbianPlasticity::
2784 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2785 op_loop_skeleton_side->getOpPtrVector(), {L2},
2787
2788 // Second: Iterate over domain FEs adjacent to skelton, particularly one
2789 // domain element.
2790 auto broken_data_ptr =
2791 boost::make_shared<std::vector<BrokenBaseSideData>>();
2792 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
2793 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
2794 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
2795 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2796 boost::make_shared<CGGUserPolynomialBase>();
2797 CHKERR
2798 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2799 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2801 op_loop_domain_side->getOpPtrVector().push_back(
2802 new OpGetBrokenBaseSideData<SideEleOp>(piolaStress, broken_data_ptr));
2803
2804 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
2806 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
2807 op_loop_skeleton_side->getOpPtrVector().push_back(
2808 new OpC(hybridSpatialDisp, broken_data_ptr,
2809 boost::make_shared<double>(1.0), true, false));
2810
2811 pip.push_back(op_loop_skeleton_side);
2812
2814 };
2815
2816 auto set_contact = [&](auto &pip) {
2818
2819 using BoundaryEle =
2821 using EleOnSide =
2823 using SideEleOp = EleOnSide::UserDataOperator;
2824 using BdyEleOp = BoundaryEle::UserDataOperator;
2825
2826 // First: Iterate over skeleton FEs adjacent to Domain FEs
2827 // Note: BoundaryEle, i.e. uses skeleton interation rule
2828 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
2829 mField, contactElement, SPACE_DIM - 1, Sev::noisy);
2830
2831 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
2832 op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
2833 CHKERR EshelbianPlasticity::
2834 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2835 op_loop_skeleton_side->getOpPtrVector(), {L2},
2837
2838 // Second: Iterate over domain FEs adjacent to skelton, particularly
2839 // one domain element.
2840 auto broken_data_ptr =
2841 boost::make_shared<std::vector<BrokenBaseSideData>>();
2842
2843 // Data storing contact fields
2844 auto contact_common_data_ptr =
2845 boost::make_shared<ContactOps::CommonData>();
2846
2847 auto add_ops_domain_side = [&](auto &pip) {
2849 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
2850 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
2851 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
2852 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2853 boost::make_shared<CGGUserPolynomialBase>();
2854 CHKERR
2855 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2856 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2858 op_loop_domain_side->getOpPtrVector().push_back(
2860 broken_data_ptr));
2861 op_loop_domain_side->getOpPtrVector().push_back(
2863 piolaStress, contact_common_data_ptr->contactTractionPtr()));
2864 pip.push_back(op_loop_domain_side);
2866 };
2867
2868 auto add_ops_contact_lhs = [&](auto &pip) {
2870 pip.push_back(new OpCalculateVectorFieldValues<3>(
2871 contactDisp, contact_common_data_ptr->contactDispPtr()));
2872 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2873 pip.push_back(
2875 pip.push_back(new OpTreeSearch(
2876 contactTreeRhs, contact_common_data_ptr, u_h1_ptr,
2877 get_range_from_block(mField, "CONTACT", SPACE_DIM - 1), nullptr,
2878 nullptr));
2879
2880 // get body id and SDF range
2881 auto contact_sfd_map_range_ptr =
2882 boost::make_shared<std::map<int, Range>>(
2883 get_body_range("CONTACT_SDF", SPACE_DIM - 1));
2884
2886 contactDisp, contactDisp, contact_common_data_ptr, contactTreeRhs,
2887 contact_sfd_map_range_ptr));
2888 pip.push_back(
2890 contactDisp, broken_data_ptr, contact_common_data_ptr,
2891 contactTreeRhs, contact_sfd_map_range_ptr));
2892 pip.push_back(
2894 broken_data_ptr, contactDisp, contact_common_data_ptr,
2896
2898 };
2899
2900 // push ops to face/side pipeline
2901 CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
2902 CHKERR add_ops_contact_lhs(op_loop_skeleton_side->getOpPtrVector());
2903
2904 // Add skeleton to domain pipeline
2905 pip.push_back(op_loop_skeleton_side);
2906
2908 };
2909
2910 CHKERR set_hybridisation(fe_lhs->getOpPtrVector());
2911 CHKERR set_contact(fe_lhs->getOpPtrVector());
2912 }
2913
2914 if (add_material) {
2915 }
2916
2918}
MoFEMErrorCode setBaseVolumeElementOps(const int tag, const bool do_rhs, const bool do_lhs, const bool calc_rates, SmartPetscObj< Vec > ver_vec, boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe)
structure to get information form mofem into EntitiesFieldData
MatrixDouble gaussPts
Matrix of integration points.
Natural boundary conditions.
Definition Natural.hpp:57
Operator for broken loop side.
static RefineTrianglesReturn refineTriangle(int nb_levels)
create uniform triangle mesh of refined elements
Definition Tools.cpp:724
static MatrixDouble refineTriangleIntegrationPts(MatrixDouble pts, RefineTrianglesReturn refined)
generate integration points for refined triangle mesh for last level
Definition Tools.cpp:791

◆ solveDynamicRelaxation()

MoFEMErrorCode EshelbianCore::solveDynamicRelaxation ( TS  ts,
Vec  x 
)
Examples
EshelbianPlasticity.cpp, and ep.cpp.

Definition at line 3561 of file EshelbianPlasticity.cpp.

3561 {
3563
3564 auto storage = solve_elastic_setup::setup(this, ts, x, false);
3565
3566 double final_time = 1;
3567 double delta_time = 0.1;
3568 int max_it = 10;
3569 PetscBool ts_h1_update = PETSC_FALSE;
3570
3571 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Dynamic Relaxation Options",
3572 "none");
3573
3574 CHKERR PetscOptionsScalar("-dynamic_final_time",
3575 "dynamic relaxation final time", "", final_time,
3576 &final_time, PETSC_NULLPTR);
3577 CHKERR PetscOptionsScalar("-dynamic_delta_time",
3578 "dynamic relaxation final time", "", delta_time,
3579 &delta_time, PETSC_NULLPTR);
3580 CHKERR PetscOptionsInt("-dynamic_max_it", "dynamic relaxation iterations", "",
3581 max_it, &max_it, PETSC_NULLPTR);
3582 CHKERR PetscOptionsBool("-dynamic_h1_update", "update each ts step", "",
3583 ts_h1_update, &ts_h1_update, PETSC_NULLPTR);
3584
3585 PetscOptionsEnd();
3586
3587 auto setup_ts_monitor = [&]() {
3588 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*this);
3589 return monitor_ptr;
3590 };
3591 auto monitor_ptr = setup_ts_monitor();
3592
3593 TetPolynomialBase::switchCacheBaseOn<HDIV>(
3594 {elasticFeLhs.get(), elasticFeRhs.get()});
3595 CHKERR TSSetUp(ts);
3597
3598 double ts_delta_time;
3599 CHKERR TSGetTimeStep(ts, &ts_delta_time);
3600
3601 if (ts_h1_update) {
3602 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
3603 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
3604 }
3605
3608
3609 dynamicTime = 0;
3610 dynamicStep = 0;
3611 monitor_ptr->ts_u = PETSC_NULLPTR;
3612 monitor_ptr->ts_t = dynamicTime;
3613 monitor_ptr->ts_step = dynamicStep;
3615 MOFEM_LOG("EP", Sev::inform) << "IT " << dynamicStep << " Time "
3616 << dynamicTime << " delta time " << delta_time;
3617 dynamicTime += delta_time;
3618 ++dynamicStep;
3619
3620 for (; dynamicTime < final_time; dynamicTime += delta_time) {
3621 MOFEM_LOG("EP", Sev::inform) << "IT " << dynamicStep << " Time "
3622 << dynamicTime << " delta time " << delta_time;
3623
3624 CHKERR TSSetStepNumber(ts, 0);
3625 CHKERR TSSetTime(ts, 0);
3626 CHKERR TSSetTimeStep(ts, ts_delta_time);
3627 if (!ts_h1_update) {
3629 }
3630 CHKERR TSSolve(ts, PETSC_NULLPTR);
3631 if (!ts_h1_update) {
3633 }
3634
3635 monitor_ptr->ts_u = PETSC_NULLPTR;
3636 monitor_ptr->ts_t = dynamicTime;
3637 monitor_ptr->ts_step = dynamicStep;
3639
3640 ++dynamicStep;
3641 if (dynamicStep > max_it)
3642 break;
3643 }
3644
3646 TetPolynomialBase::switchCacheBaseOff<HDIV>(
3647 {elasticFeLhs.get(), elasticFeRhs.get()});
3648
3650}
static double dynamicTime
static int dynamicStep
static MoFEMErrorCode postStepInitialise(EshelbianCore *ep_ptr)
static MoFEMErrorCode postStepDestroy()
static MoFEMErrorCode preStepFun(TS ts)
static MoFEMErrorCode postStepFun(TS ts)

◆ solveElastic()

MoFEMErrorCode EshelbianCore::solveElastic ( TS  ts,
Vec  x 
)
Examples
EshelbianPlasticity.cpp, and ep.cpp.

Definition at line 3431 of file EshelbianPlasticity.cpp.

3431 {
3433
3434 PetscBool debug_model = PETSC_FALSE;
3435 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-debug_model", &debug_model,
3436 PETSC_NULLPTR);
3437
3438 if (debug_model == PETSC_TRUE) {
3439 auto ts_ctx_ptr = getDMTsCtx(dmElastic);
3440 auto post_proc = [&](TS ts, PetscReal t, Vec u, Vec u_t, Vec u_tt, Vec F,
3441 void *ctx) {
3443
3444 SNES snes;
3445 CHKERR TSGetSNES(ts, &snes);
3446 int it;
3447 CHKERR SNESGetIterationNumber(snes, &it);
3448 std::string file_name = "snes_iteration_" + std::to_string(it) + ".h5m";
3449 CHKERR postProcessResults(1, file_name, F, u_t);
3450 std::string file_skel_name =
3451 "snes_iteration_skel_" + std::to_string(it) + ".h5m";
3452
3453 auto get_material_force_tag = [&]() {
3454 auto &moab = mField.get_moab();
3455 Tag tag;
3456 CHK_MOAB_THROW(moab.tag_get_handle("MaterialForce", tag),
3457 "can't get tag");
3458 return tag;
3459 };
3460
3462 CHKERR postProcessSkeletonResults(1, file_skel_name, F,
3463 {get_material_force_tag()});
3464
3466 };
3467 ts_ctx_ptr->tsDebugHook = post_proc;
3468 }
3469
3470 auto storage = solve_elastic_setup::setup(this, ts, x, true);
3471
3472 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
3473 Vec xx;
3474 CHKERR VecDuplicate(x, &xx);
3475 CHKERR VecZeroEntries(xx);
3476 CHKERR TS2SetSolution(ts, x, xx);
3477 CHKERR VecDestroy(&xx);
3478 } else {
3479 CHKERR TSSetSolution(ts, x);
3480 }
3481
3482 TetPolynomialBase::switchCacheBaseOn<HDIV>(
3483 {elasticFeLhs.get(), elasticFeRhs.get()});
3484 CHKERR TSSetUp(ts);
3485 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
3486 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
3488 CHKERR TSSolve(ts, PETSC_NULLPTR);
3490 TetPolynomialBase::switchCacheBaseOff<HDIV>(
3491 {elasticFeLhs.get(), elasticFeRhs.get()});
3492
3493 SNES snes;
3494 CHKERR TSGetSNES(ts, &snes);
3495 int lin_solver_iterations;
3496 CHKERR SNESGetLinearSolveIterations(snes, &lin_solver_iterations);
3497 MOFEM_LOG("EP", Sev::inform)
3498 << "Number of linear solver iterations " << lin_solver_iterations;
3499
3500 PetscBool test_cook_flg = PETSC_FALSE;
3501 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-test_cook", &test_cook_flg,
3502 PETSC_NULLPTR);
3503 if (test_cook_flg) {
3504 constexpr int expected_lin_solver_iterations = 11;
3505 if (lin_solver_iterations > expected_lin_solver_iterations)
3506 SETERRQ(
3507 PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
3508 "Expected number of iterations is different than expected %d > %d",
3509 lin_solver_iterations, expected_lin_solver_iterations);
3510 }
3511
3512 PetscBool test_sslv116_flag = PETSC_FALSE;
3513 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-test_sslv116",
3514 &test_sslv116_flag, PETSC_NULLPTR);
3515
3516 if (test_sslv116_flag) {
3517 double max_val = 0.0;
3518 double min_val = 0.0;
3519 auto field_min_max = [&](boost::shared_ptr<FieldEntity> ent_ptr) {
3521 auto ent_type = ent_ptr->getEntType();
3522 if (ent_type == MBVERTEX) {
3523 max_val = std::max(ent_ptr->getEntFieldData()[SPACE_DIM - 1], max_val);
3524 min_val = std::min(ent_ptr->getEntFieldData()[SPACE_DIM - 1], min_val);
3525 }
3527 };
3528 CHKERR mField.getInterface<FieldBlas>()->fieldLambdaOnEntities(
3529 field_min_max, spatialH1Disp);
3530
3531 double global_max_val = 0.0;
3532 double global_min_val = 0.0;
3533 MPI_Allreduce(&max_val, &global_max_val, 1, MPI_DOUBLE, MPI_MAX,
3534 mField.get_comm());
3535 MPI_Allreduce(&min_val, &global_min_val, 1, MPI_DOUBLE, MPI_MIN,
3536 mField.get_comm());
3537 MOFEM_LOG("EP", Sev::inform)
3538 << "Max " << spatialH1Disp << " value: " << global_max_val;
3539 MOFEM_LOG("EP", Sev::inform)
3540 << "Min " << spatialH1Disp << " value: " << global_min_val;
3541
3542 double ref_max_val = 0.00767;
3543 double ref_min_val = -0.00329;
3544 if (std::abs(global_max_val - ref_max_val) > 1e-5) {
3545 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
3546 "Incorrect max value of the displacement field: %f != %f",
3547 global_max_val, ref_max_val);
3548 }
3549 if (std::abs(global_min_val - ref_min_val) > 4e-5) {
3550 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
3551 "Incorrect min value of the displacement field: %f != %f",
3552 global_min_val, ref_min_val);
3553 }
3554 }
3555
3557
3559}
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ F
const FTensor::Tensor2< T, Dim, Dim > Vec
auto getDMTsCtx(DM dm)
Get TS context data structure used by DM.
Definition DMMoFEM.hpp:1161
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
MoFEMErrorCode calculateFaceMaterialForce(const int tag, TS ts)
MoFEMErrorCode gettingNorms()
[Getting norms]
MoFEMErrorCode postProcessSkeletonResults(const int tag, const std::string file, Vec f_residual=PETSC_NULLPTR, std::vector< Tag > tags_to_transfer={})
MoFEMErrorCode postProcessResults(const int tag, const std::string file, Vec f_residual=PETSC_NULLPTR, Vec var_vec=PETSC_NULLPTR, std::vector< Tag > tags_to_transfer={})
Basic algebra on fields.
Definition FieldBlas.hpp:21

Friends And Related Symbol Documentation

◆ solve_elastic_set_up

friend struct solve_elastic_set_up
friend

Definition at line 362 of file EshelbianCore.hpp.

Member Data Documentation

◆ a00FieldList

std::vector<std::string> EshelbianCore::a00FieldList

Definition at line 446 of file EshelbianCore.hpp.

◆ a00RangeList

std::vector<boost::shared_ptr<Range> > EshelbianCore::a00RangeList

Definition at line 448 of file EshelbianCore.hpp.

◆ addCrackMeshsetId

int EshelbianCore::addCrackMeshsetId = 1000
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 31 of file EshelbianCore.hpp.

◆ alphaOmega

double EshelbianCore::alphaOmega = 0
Examples
EshelbianPlasticity.cpp.

Definition at line 221 of file EshelbianCore.hpp.

◆ alphaRho

double EshelbianCore::alphaRho = 0
Examples
EshelbianPlasticity.cpp.

Definition at line 222 of file EshelbianCore.hpp.

◆ alphaU

double EshelbianCore::alphaU = 0
Examples
EshelbianPlasticity.cpp.

Definition at line 219 of file EshelbianCore.hpp.

◆ alphaW

double EshelbianCore::alphaW = 0
Examples
EshelbianPlasticity.cpp.

Definition at line 220 of file EshelbianCore.hpp.

◆ AnalyticalExprPythonPtr

boost::shared_ptr<AnalyticalExprPython> EshelbianCore::AnalyticalExprPythonPtr
Examples
EshelbianPlasticity.cpp.

Definition at line 179 of file EshelbianCore.hpp.

◆ aoS

AO EshelbianCore::aoS = PETSC_NULLPTR

Definition at line 444 of file EshelbianCore.hpp.

◆ bcSpatialAnalyticalDisplacementVecPtr

boost::shared_ptr<AnalyticalDisplacementBcVec> EshelbianCore::bcSpatialAnalyticalDisplacementVecPtr
Examples
EshelbianPlasticity.cpp.

Definition at line 235 of file EshelbianCore.hpp.

◆ bcSpatialAnalyticalTractionVecPtr

boost::shared_ptr<AnalyticalTractionBcVec> EshelbianCore::bcSpatialAnalyticalTractionVecPtr
Examples
EshelbianPlasticity.cpp.

Definition at line 236 of file EshelbianCore.hpp.

◆ bcSpatialDispVecPtr

boost::shared_ptr<BcDispVec> EshelbianCore::bcSpatialDispVecPtr
Examples
EshelbianPlasticity.cpp.

Definition at line 229 of file EshelbianCore.hpp.

◆ bcSpatialFreeTractionVecPtr

boost::shared_ptr<TractionFreeBc> EshelbianCore::bcSpatialFreeTractionVecPtr
Examples
EshelbianPlasticity.cpp.

Definition at line 232 of file EshelbianCore.hpp.

◆ bcSpatialNormalDisplacementVecPtr

boost::shared_ptr<NormalDisplacementBcVec> EshelbianCore::bcSpatialNormalDisplacementVecPtr
Examples
EshelbianPlasticity.cpp.

Definition at line 233 of file EshelbianCore.hpp.

◆ bcSpatialPressureVecPtr

boost::shared_ptr<PressureBcVec> EshelbianCore::bcSpatialPressureVecPtr
Examples
EshelbianPlasticity.cpp.

Definition at line 237 of file EshelbianCore.hpp.

◆ bcSpatialRotationVecPtr

boost::shared_ptr<BcRotVec> EshelbianCore::bcSpatialRotationVecPtr
Examples
EshelbianPlasticity.cpp.

Definition at line 230 of file EshelbianCore.hpp.

◆ bcSpatialTractionVecPtr

boost::shared_ptr<TractionBcVec> EshelbianCore::bcSpatialTractionVecPtr
Examples
EshelbianPlasticity.cpp.

Definition at line 231 of file EshelbianCore.hpp.

◆ bitAdjEnt

BitRefLevel EshelbianCore::bitAdjEnt = BitRefLevel().set()

bit ref level for parent

Examples
EshelbianPlasticity.cpp.

Definition at line 429 of file EshelbianCore.hpp.

◆ bitAdjEntMask

BitRefLevel EshelbianCore::bitAdjEntMask
Initial value:
=
BitRefLevel().set()

bit ref level for parent parent

Examples
EshelbianPlasticity.cpp.

Definition at line 430 of file EshelbianCore.hpp.

◆ bitAdjParent

BitRefLevel EshelbianCore::bitAdjParent = BitRefLevel().set()

bit ref level for parent

Examples
EshelbianPlasticity.cpp.

Definition at line 426 of file EshelbianCore.hpp.

◆ bitAdjParentMask

BitRefLevel EshelbianCore::bitAdjParentMask
Initial value:
=
BitRefLevel().set()

bit ref level for parent parent

Examples
EshelbianPlasticity.cpp.

Definition at line 427 of file EshelbianCore.hpp.

◆ bubbleField

const std::string EshelbianCore::bubbleField = "bubble"
Examples
EshelbianPlasticity.cpp.

Definition at line 203 of file EshelbianCore.hpp.

◆ contactDisp

const std::string EshelbianCore::contactDisp = "contactDisp"
Examples
EshelbianPlasticity.cpp.

Definition at line 200 of file EshelbianCore.hpp.

◆ contactElement

const std::string EshelbianCore::contactElement = "CONTACT"
Examples
EshelbianPlasticity.cpp.

Definition at line 209 of file EshelbianCore.hpp.

◆ contactFaces

boost::shared_ptr<Range> EshelbianCore::contactFaces
Examples
EshelbianPlasticity.cpp.

Definition at line 414 of file EshelbianCore.hpp.

◆ contactRefinementLevels

int EshelbianCore::contactRefinementLevels = 1
Examples
EshelbianPlasticity.cpp.

Definition at line 224 of file EshelbianCore.hpp.

◆ contactTreeRhs

boost::shared_ptr<ContactTree> EshelbianCore::contactTreeRhs

Make a contact tree.

Examples
EshelbianPlasticity.cpp.

Definition at line 185 of file EshelbianCore.hpp.

◆ crackFaces

boost::shared_ptr<Range> EshelbianCore::crackFaces
Examples
EshelbianPlasticity.cpp.

Definition at line 415 of file EshelbianCore.hpp.

◆ crackHybridIs

SmartPetscObj<IS> EshelbianCore::crackHybridIs

Definition at line 445 of file EshelbianCore.hpp.

◆ crackingOn

PetscBool EshelbianCore::crackingOn = PETSC_FALSE
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 22 of file EshelbianCore.hpp.

◆ crackingStartTime

double EshelbianCore::crackingStartTime = 0
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 23 of file EshelbianCore.hpp.

◆ d_f

boost::function< double(const double)> EshelbianCore::d_f
static
Initial value:
Examples
EshelbianOperators.cpp, and EshelbianPlasticity.cpp.

Definition at line 44 of file EshelbianCore.hpp.

◆ dataAtPts

boost::shared_ptr<DataAtIntegrationPts> EshelbianCore::dataAtPts
Examples
EshelbianPlasticity.cpp.

Definition at line 177 of file EshelbianCore.hpp.

◆ dd_f

boost::function< double(const double)> EshelbianCore::dd_f
static
Initial value:
Examples
EshelbianPlasticity.cpp.

Definition at line 45 of file EshelbianCore.hpp.

◆ dM

SmartPetscObj<DM> EshelbianCore::dM

Coupled problem all fields.

Examples
EshelbianPlasticity.cpp.

Definition at line 187 of file EshelbianCore.hpp.

◆ dmElastic

SmartPetscObj<DM> EshelbianCore::dmElastic

Elastic problem.

Examples
EshelbianPlasticity.cpp, and ep.cpp.

Definition at line 188 of file EshelbianCore.hpp.

◆ dmMaterial

SmartPetscObj<DM> EshelbianCore::dmMaterial

Material problem.

Definition at line 189 of file EshelbianCore.hpp.

◆ dmPrjSpatial

SmartPetscObj<DM> EshelbianCore::dmPrjSpatial

Projection spatial displacement.

Examples
EshelbianPlasticity.cpp.

Definition at line 190 of file EshelbianCore.hpp.

◆ dynamicRelaxation

PetscBool EshelbianCore::dynamicRelaxation
inlinestatic
Initial value:
=
PETSC_FALSE
Examples
EshelbianOperators.cpp, EshelbianPlasticity.cpp, and ep.cpp.

Definition at line 20 of file EshelbianCore.hpp.

◆ dynamicStep

int EshelbianCore::dynamicStep
inlinestatic
Initial value:
=
0
Examples
EshelbianOperators.cpp, and EshelbianPlasticity.cpp.

Definition at line 28 of file EshelbianCore.hpp.

◆ dynamicTime

double EshelbianCore::dynamicTime
inlinestatic
Initial value:
=
0
Examples
EshelbianOperators.cpp, and EshelbianPlasticity.cpp.

Definition at line 26 of file EshelbianCore.hpp.

◆ edgeExchange

CommInterface::EntitiesPetscVector EshelbianCore::edgeExchange
Examples
EshelbianPlasticity.cpp.

Definition at line 437 of file EshelbianCore.hpp.

◆ elasticBcLhs

boost::shared_ptr<FaceElementForcesAndSourcesCore> EshelbianCore::elasticBcLhs
Examples
EshelbianPlasticity.cpp.

Definition at line 183 of file EshelbianCore.hpp.

◆ elasticBcRhs

boost::shared_ptr<FaceElementForcesAndSourcesCore> EshelbianCore::elasticBcRhs
Examples
EshelbianPlasticity.cpp.

Definition at line 184 of file EshelbianCore.hpp.

◆ elasticFeLhs

boost::shared_ptr<VolumeElementForcesAndSourcesCore> EshelbianCore::elasticFeLhs
Examples
EshelbianPlasticity.cpp.

Definition at line 182 of file EshelbianCore.hpp.

◆ elasticFeRhs

boost::shared_ptr<VolumeElementForcesAndSourcesCore> EshelbianCore::elasticFeRhs
Examples
EshelbianPlasticity.cpp.

Definition at line 181 of file EshelbianCore.hpp.

◆ elementVolumeName

const std::string EshelbianCore::elementVolumeName = "EP"
Examples
EshelbianPlasticity.cpp.

Definition at line 205 of file EshelbianCore.hpp.

◆ energyReleaseSelector

enum EnergyReleaseSelector EshelbianCore::energyReleaseSelector
inlinestatic
Initial value:
=
GRIFFITH_SKELETON
Examples
EshelbianOperators.cpp, and EshelbianPlasticity.cpp.

Definition at line 33 of file EshelbianCore.hpp.

◆ exponentBase

double EshelbianCore::exponentBase = exp(1)
static
Examples
EshelbianPlasticity.cpp.

Definition at line 42 of file EshelbianCore.hpp.

◆ externalStrainVecPtr

boost::shared_ptr<ExternalStrainVec> EshelbianCore::externalStrainVecPtr
Examples
EshelbianPlasticity.cpp.

Definition at line 238 of file EshelbianCore.hpp.

◆ f

boost::function< double(const double)> EshelbianCore::f = EshelbianCore::f_log_e
static
Examples
EshelbianOperators.cpp, and EshelbianPlasticity.cpp.

Definition at line 43 of file EshelbianCore.hpp.

◆ faceExchange

CommInterface::EntitiesPetscVector EshelbianCore::faceExchange
Examples
EshelbianPlasticity.cpp.

Definition at line 436 of file EshelbianCore.hpp.

◆ frontAdjEdges

boost::shared_ptr<Range> EshelbianCore::frontAdjEdges
Examples
EshelbianPlasticity.cpp.

Definition at line 417 of file EshelbianCore.hpp.

◆ frontEdges

boost::shared_ptr<Range> EshelbianCore::frontEdges
Examples
EshelbianPlasticity.cpp.

Definition at line 416 of file EshelbianCore.hpp.

◆ frontLayers

int EshelbianCore::frontLayers = 3

Definition at line 225 of file EshelbianCore.hpp.

◆ frontVertices

boost::shared_ptr<Range> EshelbianCore::frontVertices
Examples
EshelbianPlasticity.cpp.

Definition at line 418 of file EshelbianCore.hpp.

◆ gradApproximator

enum RotSelector EshelbianCore::gradApproximator = LARGE_ROT
inlinestatic
Examples
EshelbianOperators.cpp, and EshelbianPlasticity.cpp.

Definition at line 16 of file EshelbianCore.hpp.

◆ griffithEnergy

double EshelbianCore::griffithEnergy = 1
inlinestatic

Griffith energy.

Examples
EshelbianPlasticity.cpp.

Definition at line 32 of file EshelbianCore.hpp.

◆ hybridSpatialDisp

const std::string EshelbianCore::hybridSpatialDisp = "hybridSpatialDisp"
Examples
EshelbianPlasticity.cpp.

Definition at line 198 of file EshelbianCore.hpp.

◆ internalStressInterpOrder

int EshelbianCore::internalStressInterpOrder
inlinestatic
Initial value:
=
1
Examples
EshelbianPlasticity.cpp.

Definition at line 37 of file EshelbianCore.hpp.

◆ internalStressTagName

std::string EshelbianCore::internalStressTagName
inlinestatic
Initial value:
=
""
Examples
EshelbianPlasticity.cpp.

Definition at line 35 of file EshelbianCore.hpp.

◆ internalStressVoigt

PetscBool EshelbianCore::internalStressVoigt
inlinestatic
Initial value:
=
PETSC_FALSE
Examples
EshelbianPlasticity.cpp.

Definition at line 39 of file EshelbianCore.hpp.

◆ inv_d_f

boost::function< double(const double)> EshelbianCore::inv_d_f
static
Initial value:
=
static double inv_d_f_log_e(const double v)
Examples
EshelbianPlasticity.cpp.

Definition at line 47 of file EshelbianCore.hpp.

◆ inv_dd_f

boost::function< double(const double)> EshelbianCore::inv_dd_f
static
Initial value:
=
static double inv_dd_f_log_e(const double v)
Examples
EshelbianPlasticity.cpp.

Definition at line 48 of file EshelbianCore.hpp.

◆ inv_f

boost::function< double(const double)> EshelbianCore::inv_f
static
Initial value:
=
static double inv_f_log_e(const double v)
Examples
EshelbianOperators.cpp, and EshelbianPlasticity.cpp.

Definition at line 46 of file EshelbianCore.hpp.

◆ l2UserBaseScale

PetscBool EshelbianCore::l2UserBaseScale = PETSC_TRUE
inlinestatic
Examples
EshelbianOperators.cpp, and EshelbianPlasticity.cpp.

Definition at line 30 of file EshelbianCore.hpp.

◆ listTagsToTransfer

std::vector<Tag> EshelbianCore::listTagsToTransfer

list of tags to transfer to postprocessor

Examples
EshelbianPlasticity.cpp.

Definition at line 441 of file EshelbianCore.hpp.

◆ materialH1Positions

const std::string EshelbianCore::materialH1Positions = "XH1"
Examples
EshelbianPlasticity.cpp.

Definition at line 197 of file EshelbianCore.hpp.

◆ materialOrder

int EshelbianCore::materialOrder = 1
Examples
EshelbianPlasticity.cpp.

Definition at line 218 of file EshelbianCore.hpp.

◆ materialSkeletonFaces

boost::shared_ptr<Range> EshelbianCore::materialSkeletonFaces

Definition at line 420 of file EshelbianCore.hpp.

◆ maxMovedFaces

boost::shared_ptr<Range> EshelbianCore::maxMovedFaces
Examples
EshelbianPlasticity.cpp.

Definition at line 421 of file EshelbianCore.hpp.

◆ mField

MoFEM::Interface& EshelbianCore::mField
Examples
EshelbianPlasticity.cpp.

Definition at line 175 of file EshelbianCore.hpp.

◆ naturalBcElement

const std::string EshelbianCore::naturalBcElement = "NATURAL_BC"
Examples
EshelbianPlasticity.cpp.

Definition at line 206 of file EshelbianCore.hpp.

◆ nbCrackFaces

int EshelbianCore::nbCrackFaces = 0
Examples
EshelbianPlasticity.cpp.

Definition at line 450 of file EshelbianCore.hpp.

◆ nbJIntegralLevels

int EshelbianCore::nbJIntegralLevels
inlinestatic
Initial value:
=
0
Examples
EshelbianPlasticity.cpp.

Definition at line 24 of file EshelbianCore.hpp.

◆ noStretch

PetscBool EshelbianCore::noStretch = PETSC_FALSE
inlinestatic
Examples
EshelbianPlasticity.cpp.

Definition at line 18 of file EshelbianCore.hpp.

◆ parentAdjSkeletonFunctionDim2

boost::shared_ptr<ParentFiniteElementAdjacencyFunctionSkeleton<2> > EshelbianCore::parentAdjSkeletonFunctionDim2
Examples
EshelbianPlasticity.cpp.

Definition at line 424 of file EshelbianCore.hpp.

◆ physicalEquations

boost::shared_ptr<PhysicalEquations> EshelbianCore::physicalEquations
Examples
EshelbianPlasticity.cpp.

Definition at line 178 of file EshelbianCore.hpp.

◆ piolaStress

const std::string EshelbianCore::piolaStress = "P"
Examples
EshelbianPlasticity.cpp.

Definition at line 192 of file EshelbianCore.hpp.

◆ rotAxis

const std::string EshelbianCore::rotAxis = "omega"
Examples
EshelbianPlasticity.cpp.

Definition at line 202 of file EshelbianCore.hpp.

◆ rotSelector

enum RotSelector EshelbianCore::rotSelector = LARGE_ROT
inlinestatic
Examples
EshelbianOperators.cpp, and EshelbianPlasticity.cpp.

Definition at line 15 of file EshelbianCore.hpp.

◆ S

Mat EshelbianCore::S = PETSC_NULLPTR

Definition at line 443 of file EshelbianCore.hpp.

◆ setSingularity

PetscBool EshelbianCore::setSingularity = PETSC_TRUE
inlinestatic
Examples
EshelbianOperators.cpp, and EshelbianPlasticity.cpp.

Definition at line 19 of file EshelbianCore.hpp.

◆ skeletonElement

const std::string EshelbianCore::skeletonElement = "SKELETON"
Examples
EshelbianPlasticity.cpp.

Definition at line 208 of file EshelbianCore.hpp.

◆ skeletonFaces

boost::shared_ptr<Range> EshelbianCore::skeletonFaces
Examples
EshelbianPlasticity.cpp.

Definition at line 419 of file EshelbianCore.hpp.

◆ skinElement

const std::string EshelbianCore::skinElement = "SKIN"
Examples
EshelbianPlasticity.cpp.

Definition at line 207 of file EshelbianCore.hpp.

◆ solTSStep

SmartPetscObj<Vec> EshelbianCore::solTSStep
Examples
EshelbianPlasticity.cpp.

Definition at line 433 of file EshelbianCore.hpp.

◆ spaceH1Order

int EshelbianCore::spaceH1Order = -1
Examples
EshelbianPlasticity.cpp.

Definition at line 217 of file EshelbianCore.hpp.

◆ spaceOrder

int EshelbianCore::spaceOrder = 2
Examples
EshelbianPlasticity.cpp.

Definition at line 216 of file EshelbianCore.hpp.

◆ spatialH1Disp

const std::string EshelbianCore::spatialH1Disp = "wH1"
Examples
EshelbianPlasticity.cpp.

Definition at line 196 of file EshelbianCore.hpp.

◆ spatialL2Disp

const std::string EshelbianCore::spatialL2Disp = "wL2"
Examples
EshelbianPlasticity.cpp.

Definition at line 194 of file EshelbianCore.hpp.

◆ stretchSelector

enum StretchSelector EshelbianCore::stretchSelector = LOG
inlinestatic
Examples
EshelbianOperators.cpp, and EshelbianPlasticity.cpp.

Definition at line 17 of file EshelbianCore.hpp.

◆ stretchTensor

const std::string EshelbianCore::stretchTensor = "u"
Examples
EshelbianPlasticity.cpp.

Definition at line 201 of file EshelbianCore.hpp.

◆ symmetrySelector

enum SymmetrySelector EshelbianCore::symmetrySelector = NOT_SYMMETRIC
inlinestatic
Examples
EshelbianOperators.cpp, and EshelbianPlasticity.cpp.

Definition at line 14 of file EshelbianCore.hpp.

◆ timeScaleMap

std::map<std::string, boost::shared_ptr<ScalingMethod> > EshelbianCore::timeScaleMap
Examples
EshelbianPlasticity.cpp.

Definition at line 240 of file EshelbianCore.hpp.

◆ use_quadratic_exp

constexpr bool EshelbianCore::use_quadratic_exp = true
inlinestaticconstexpr

Definition at line 50 of file EshelbianCore.hpp.

◆ v_max

constexpr double EshelbianCore::v_max = 12
inlinestaticconstexpr

Definition at line 51 of file EshelbianCore.hpp.

◆ v_min

constexpr double EshelbianCore::v_min = -v_max
inlinestaticconstexpr

Definition at line 52 of file EshelbianCore.hpp.

◆ vertexExchange

CommInterface::EntitiesPetscVector EshelbianCore::vertexExchange
Examples
EshelbianPlasticity.cpp.

Definition at line 438 of file EshelbianCore.hpp.

◆ volumeExchange

CommInterface::EntitiesPetscVector EshelbianCore::volumeExchange
Examples
EshelbianPlasticity.cpp.

Definition at line 435 of file EshelbianCore.hpp.


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