v0.15.0
Loading...
Searching...
No Matches
EshelbianPlasticity::EshelbianCore Struct Reference

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

Inheritance diagram for EshelbianPlasticity::EshelbianCore:
[legend]
Collaboration diagram for EshelbianPlasticity::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< PhysicalEquationsphysicalEquations
 
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< ContactTreecontactTreeRhs
 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< BcDispVecbcSpatialDispVecPtr
 
boost::shared_ptr< BcRotVecbcSpatialRotationVecPtr
 
boost::shared_ptr< TractionBcVecbcSpatialTractionVecPtr
 
boost::shared_ptr< TractionFreeBcbcSpatialFreeTractionVecPtr
 
boost::shared_ptr< NormalDisplacementBcVecbcSpatialNormalDisplacementVecPtr
 
boost::shared_ptr< AnalyticalDisplacementBcVecbcSpatialAnalyticalDisplacementVecPtr
 
boost::shared_ptr< AnalyticalTractionBcVecbcSpatialAnalyticalTractionVecPtr
 
boost::shared_ptr< PressureBcVecbcSpatialPressureVecPtr
 
boost::shared_ptr< ExternalStrainVecexternalStrainVecPtr
 
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

Definition at line 13 of file EshelbianPlasticity.hpp.

Constructor & Destructor Documentation

◆ EshelbianCore()

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

Definition at line 913 of file EshelbianPlasticity.cpp.

913 : mField(m_field) {
914 CHK_THROW_MESSAGE(getOptions(), "getOptions failed");
915}
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.

◆ ~EshelbianCore()

EshelbianCore::~EshelbianCore ( )
virtualdefault

Member Function Documentation

◆ addBoundaryFiniteElement()

MoFEMErrorCode EshelbianCore::addBoundaryFiniteElement ( const EntityHandle meshset = 0)

Definition at line 1593 of file EshelbianPlasticity.cpp.

1593 {
1595
1596 Range meshset_ents;
1597 CHKERR mField.get_moab().get_entities_by_handle(meshset, meshset_ents);
1598
1599 auto set_fe_adjacency = [&](auto fe_name) {
1602 boost::make_shared<ParentFiniteElementAdjacencyFunctionSkeleton<2>>(
1605 fe_name, MBTRI, *parentAdjSkeletonFunctionDim2);
1607 };
1608
1609 // set finite element fields
1610 auto add_field_to_fe = [this](const std::string fe,
1611 const std::string field_name) {
1618 };
1619
1621
1622 Range natural_bc_elements;
1623 if (bcSpatialDispVecPtr) {
1624 for (auto &v : *bcSpatialDispVecPtr) {
1625 natural_bc_elements.merge(v.faces);
1626 }
1627 }
1629 for (auto &v : *bcSpatialRotationVecPtr) {
1630 natural_bc_elements.merge(v.faces);
1631 }
1632 }
1634 for (auto &v : *bcSpatialNormalDisplacementVecPtr) {
1635 natural_bc_elements.merge(v.faces);
1636 }
1637 }
1640 natural_bc_elements.merge(v.faces);
1641 }
1642 }
1644 for (auto &v : *bcSpatialTractionVecPtr) {
1645 natural_bc_elements.merge(v.faces);
1646 }
1647 }
1649 for (auto &v : *bcSpatialAnalyticalTractionVecPtr) {
1650 natural_bc_elements.merge(v.faces);
1651 }
1652 }
1654 for (auto &v : *bcSpatialPressureVecPtr) {
1655 natural_bc_elements.merge(v.faces);
1656 }
1657 }
1658 natural_bc_elements = intersect(natural_bc_elements, meshset_ents);
1659
1661 CHKERR mField.add_ents_to_finite_element_by_type(natural_bc_elements, MBTRI,
1663 CHKERR add_field_to_fe(naturalBcElement, piolaStress);
1664 CHKERR add_field_to_fe(naturalBcElement, hybridSpatialDisp);
1665 CHKERR set_fe_adjacency(naturalBcElement);
1667 }
1668
1669 auto get_skin = [&](auto &body_ents) {
1670 Skinner skin(&mField.get_moab());
1671 Range skin_ents;
1672 CHKERR skin.find_skin(0, body_ents, false, skin_ents);
1673 return skin_ents;
1674 };
1675
1676 auto filter_true_skin = [&](auto &&skin) {
1677 Range boundary_ents;
1678 ParallelComm *pcomm =
1679 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
1680 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
1681 PSTATUS_NOT, -1, &boundary_ents);
1682 return boundary_ents;
1683 };
1684
1686
1687 Range body_ents;
1688 CHKERR mField.get_moab().get_entities_by_dimension(meshset, SPACE_DIM,
1689 body_ents);
1690 auto skin = filter_true_skin(get_skin(body_ents));
1691
1699 contactDisp);
1702 // CHKERR add_field_to_fe(skinElement, hybridSpatialDisp);
1703 // CHKERR add_field_to_fe(skinElement, hybridMaterialDisp);
1704
1706 }
1707
1709 if (contactFaces) {
1710 MOFEM_LOG("EP", Sev::inform)
1711 << "Contact elements " << contactFaces->size();
1715 CHKERR add_field_to_fe(contactElement, piolaStress);
1716 CHKERR add_field_to_fe(contactElement, hybridSpatialDisp);
1717 CHKERR add_field_to_fe(contactElement, contactDisp);
1718 CHKERR add_field_to_fe(contactElement, spatialH1Disp);
1719 CHKERR set_fe_adjacency(contactElement);
1721 }
1722 }
1723
1725 if (!skeletonFaces)
1726 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "No skeleton faces");
1727 MOFEM_LOG("EP", Sev::inform)
1728 << "Skeleton elements " << skeletonFaces->size();
1732 CHKERR add_field_to_fe(skeletonElement, piolaStress);
1733 CHKERR add_field_to_fe(skeletonElement, hybridSpatialDisp);
1734 CHKERR add_field_to_fe(skeletonElement, contactDisp);
1735 CHKERR add_field_to_fe(skeletonElement, spatialH1Disp);
1736 CHKERR set_fe_adjacency(skeletonElement);
1738 }
1739
1740 // if (!mField.check_finite_element(materialSkeletonElement)) {
1741
1742 // Range front_edges = get_range_from_block(mField, "FRONT", SPACE_DIM -
1743 // 2);
1744
1745 // Range front_elements;
1746 // for (auto l = 0; l != frontLayers; ++l) {
1747 // Range front_elements_layer;
1748 // CHKERR mField.get_moab().get_adjacencies(front_edges, SPACE_DIM,
1749 // true,
1750 // front_elements_layer,
1751 // moab::Interface::UNION);
1752 // front_elements.merge(front_elements_layer);
1753 // front_edges.clear();
1754 // CHKERR mField.get_moab().get_adjacencies(front_elements_layer,
1755 // SPACE_DIM - 2, true,
1756 // front_edges,
1757 // moab::Interface::UNION);
1758 // }
1759 // Range body_ents;
1760 // CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
1761 // body_ents); Range front_elements_faces; CHKERR
1762 // mField.get_moab().get_adjacencies(front_elements, SPACE_DIM - 1,
1763 // true, front_elements_faces,
1764 // moab::Interface::UNION);
1765 // auto body_skin = filter_true_skin(get_skin(body_ents));
1766 // auto front_elements_skin = filter_true_skin(get_skin(front_elements));
1767 // Range material_skeleton_faces =
1768 // subtract(front_elements_faces, front_elements_skin);
1769 // material_skeleton_faces.merge(intersect(front_elements_skin,
1770 // body_skin));
1771
1772 // #ifndef NDEBUG
1773 // CHKERR save_range(mField.get_moab(), "front_elements.vtk",
1774 // front_elements); CHKERR save_range(mField.get_moab(),
1775 // "front_elements_skin.vtk",
1776 // front_elements_skin);
1777 // CHKERR save_range(mField.get_moab(), "material_skeleton_faces.vtk",
1778 // material_skeleton_faces);
1779 // #endif
1780
1781 // CHKERR mField.add_finite_element(materialSkeletonElement, MF_ZERO);
1782 // CHKERR mField.add_ents_to_finite_element_by_type(
1783 // material_skeleton_faces, MBTRI, materialSkeletonElement);
1784 // // CHKERR add_field_to_fe(materialSkeletonElement, eshelbyStress);
1785 // // CHKERR add_field_to_fe(materialSkeletonElement, hybridMaterialDisp);
1786 // CHKERR set_fe_adjacency(materialSkeletonElement);
1787 // CHKERR mField.build_finite_elements(materialSkeletonElement);
1788 // }
1789
1791}
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
boost::shared_ptr< PressureBcVec > bcSpatialPressureVecPtr
BitRefLevel bitAdjEntMask
bit ref level for parent parent
boost::shared_ptr< Range > contactFaces
boost::shared_ptr< Range > skeletonFaces
boost::shared_ptr< NormalDisplacementBcVec > bcSpatialNormalDisplacementVecPtr
boost::shared_ptr< BcRotVec > bcSpatialRotationVecPtr
boost::shared_ptr< BcDispVec > bcSpatialDispVecPtr
BitRefLevel bitAdjParent
bit ref level for parent
BitRefLevel bitAdjEnt
bit ref level for parent
boost::shared_ptr< ParentFiniteElementAdjacencyFunctionSkeleton< 2 > > parentAdjSkeletonFunctionDim2
boost::shared_ptr< AnalyticalTractionBcVec > bcSpatialAnalyticalTractionVecPtr
boost::shared_ptr< TractionBcVec > bcSpatialTractionVecPtr
BitRefLevel bitAdjParentMask
bit ref level for parent parent
boost::shared_ptr< AnalyticalDisplacementBcVec > bcSpatialAnalyticalDisplacementVecPtr
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)

Definition at line 5941 of file EshelbianPlasticity.cpp.

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

Definition at line 1793 of file EshelbianPlasticity.cpp.

1794 {
1796
1797 // find adjacencies between finite elements and dofs
1799
1800 // Create coupled problem
1801 dM = createDM(mField.get_comm(), "DMMOFEM");
1802 CHKERR DMMoFEMCreateMoFEM(dM, &mField, "ESHELBY_PLASTICITY", bit,
1803 BitRefLevel().set());
1804 CHKERR DMMoFEMSetDestroyProblem(dM, PETSC_TRUE);
1805 CHKERR DMMoFEMSetIsPartitioned(dM, PETSC_TRUE);
1811
1812 mField.getInterface<ProblemsManager>()->buildProblemFromFields = PETSC_TRUE;
1813 CHKERR DMSetUp(dM);
1814 mField.getInterface<ProblemsManager>()->buildProblemFromFields = PETSC_FALSE;
1815
1816 auto remove_dofs_on_broken_skin = [&](const std::string prb_name) {
1818 for (int d : {0, 1, 2}) {
1819 std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_to_remove;
1821 ->getSideDofsOnBrokenSpaceEntities(
1822 dofs_to_remove, prb_name, ROW, piolaStress,
1824 // remove piola dofs, i.e. traction free boundary
1825 CHKERR mField.getInterface<ProblemsManager>()->removeDofs(prb_name, ROW,
1826 dofs_to_remove);
1827 CHKERR mField.getInterface<ProblemsManager>()->removeDofs(prb_name, COL,
1828 dofs_to_remove);
1829 }
1831 };
1832 CHKERR remove_dofs_on_broken_skin("ESHELBY_PLASTICITY");
1833
1834 // Create elastic sub-problem
1835 dmElastic = createDM(mField.get_comm(), "DMMOFEM");
1836 CHKERR DMMoFEMCreateSubDM(dmElastic, dM, "ELASTIC_PROBLEM");
1842 if (!noStretch) {
1844 }
1854 CHKERR DMSetUp(dmElastic);
1855
1856 // dmMaterial = createDM(mField.get_comm(), "DMMOFEM");
1857 // CHKERR DMMoFEMCreateSubDM(dmMaterial, dM, "MATERIAL_PROBLEM");
1858 // CHKERR DMMoFEMSetDestroyProblem(dmMaterial, PETSC_TRUE);
1859 // CHKERR DMMoFEMAddSubFieldRow(dmMaterial, eshelbyStress);
1860 // CHKERR DMMoFEMAddSubFieldRow(dmMaterial, materialL2Disp);
1861 // CHKERR DMMoFEMAddElement(dmMaterh elementVolumeName);
1862 // CHKERR DMMoFEMAddElement(dmMaterial, naturalBcElement);
1863 // CHKERR DMMoFEMAddElement(dmMaterial, skinElement);
1864 // CHKERR DMMoFEMSetSquareProblem(dmMaterial, PETSC_TRUE);
1865 // CHKERR DMMoFEMSetIsPartitioned(dmMaterial, PETSC_TRUE);
1866 // CHKERR DMSetUp(dmMaterial);
1867
1868 auto set_zero_block = [&]() {
1870 if (!noStretch) {
1871 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1872 "ELASTIC_PROBLEM", spatialL2Disp, stretchTensor);
1873 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1874 "ELASTIC_PROBLEM", stretchTensor, spatialL2Disp);
1875 }
1876 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1877 "ELASTIC_PROBLEM", spatialL2Disp, rotAxis);
1878 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1879 "ELASTIC_PROBLEM", rotAxis, spatialL2Disp);
1880 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1881 "ELASTIC_PROBLEM", spatialL2Disp, bubbleField);
1882 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1883 "ELASTIC_PROBLEM", bubbleField, spatialL2Disp);
1884 if (!noStretch) {
1885 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1886 "ELASTIC_PROBLEM", bubbleField, bubbleField);
1887 CHKERR
1888 mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1889 "ELASTIC_PROBLEM", piolaStress, piolaStress);
1890 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1891 "ELASTIC_PROBLEM", bubbleField, piolaStress);
1892 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1893 "ELASTIC_PROBLEM", piolaStress, bubbleField);
1894 }
1895
1898 };
1899
1900 auto set_section = [&]() {
1902 PetscSection section;
1903 CHKERR mField.getInterface<ISManager>()->sectionCreate("ELASTIC_PROBLEM",
1904 &section);
1905 CHKERR DMSetSection(dmElastic, section);
1906 CHKERR DMSetGlobalSection(dmElastic, section);
1907 CHKERR PetscSectionDestroy(&section);
1909 };
1910
1911 CHKERR set_zero_block();
1912 CHKERR set_section();
1913
1914 dmPrjSpatial = createDM(mField.get_comm(), "DMMOFEM");
1915 CHKERR DMMoFEMCreateSubDM(dmPrjSpatial, dM, "PROJECT_SPATIAL");
1921 CHKERR DMSetUp(dmPrjSpatial);
1922
1923 // CHKERR mField.getInterface<BcManager>()
1924 // ->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
1925 // "PROJECT_SPATIAL", spatialH1Disp, true, false);
1926
1928}
@ 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:1102
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.
boost::shared_ptr< TractionFreeBc > bcSpatialFreeTractionVecPtr
SmartPetscObj< DM > dM
Coupled problem all fields.
SmartPetscObj< DM > dmElastic
Elastic problem.
SmartPetscObj< DM > dmPrjSpatial
Projection spatial displacement.
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)

Definition at line 1154 of file EshelbianPlasticity.cpp.

1154 {
1156
1157 auto get_tets = [&]() {
1158 Range tets;
1159 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
1160 return tets;
1161 };
1162
1163 auto get_tets_skin = [&]() {
1164 Range tets_skin_part;
1165 Skinner skin(&mField.get_moab());
1166 CHKERR skin.find_skin(0, get_tets(), false, tets_skin_part);
1167 ParallelComm *pcomm =
1168 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
1169 Range tets_skin;
1170 CHKERR pcomm->filter_pstatus(tets_skin_part,
1171 PSTATUS_SHARED | PSTATUS_MULTISHARED,
1172 PSTATUS_NOT, -1, &tets_skin);
1173 return tets_skin;
1174 };
1175
1176 auto subtract_boundary_conditions = [&](auto &&tets_skin) {
1177 // That mean, that hybrid field on all faces on which traction is applied,
1178 // on other faces, or enforcing displacements as
1179 // natural boundary condition.
1181 for (auto &v : *bcSpatialTractionVecPtr) {
1182 tets_skin = subtract(tets_skin, v.faces);
1183 }
1185 for (auto &v : *bcSpatialAnalyticalTractionVecPtr) {
1186 tets_skin = subtract(tets_skin, v.faces);
1187 }
1188
1190 for (auto &v : *bcSpatialPressureVecPtr) {
1191 tets_skin = subtract(tets_skin, v.faces);
1192 }
1193
1194 return tets_skin;
1195 };
1196
1197 auto add_blockset = [&](auto block_name, auto &&tets_skin) {
1198 auto crack_faces =
1199 get_range_from_block(mField, "block_name", SPACE_DIM - 1);
1200 tets_skin.merge(crack_faces);
1201 return tets_skin;
1202 };
1203
1204 auto subtract_blockset = [&](auto block_name, auto &&tets_skin) {
1205 auto contact_range =
1206 get_range_from_block(mField, block_name, SPACE_DIM - 1);
1207 tets_skin = subtract(tets_skin, contact_range);
1208 return tets_skin;
1209 };
1210
1211 auto get_stress_trace_faces = [&](auto &&tets_skin) {
1212 Range faces;
1213 CHKERR mField.get_moab().get_adjacencies(get_tets(), SPACE_DIM - 1, true,
1214 faces, moab::Interface::UNION);
1215 Range trace_faces = subtract(faces, tets_skin);
1216 return trace_faces;
1217 };
1218
1219 auto tets = get_tets();
1220
1221 // remove also contact faces, i.e. that is also kind of hybrid field but
1222 // named but used to enforce contact conditions
1223 auto trace_faces = get_stress_trace_faces(
1224
1225 subtract_blockset("CONTACT",
1226 subtract_boundary_conditions(get_tets_skin()))
1227
1228 );
1229
1230 contactFaces = boost::make_shared<Range>(intersect(
1231 trace_faces, get_range_from_block(mField, "CONTACT", SPACE_DIM - 1)));
1233 boost::make_shared<Range>(subtract(trace_faces, *contactFaces));
1234 // materialSkeletonFaces =
1235 // boost::make_shared<Range>(get_stress_trace_faces(Range()));
1236
1237#ifndef NDEBUG
1238 if (contactFaces->size())
1240 "contact_faces_" +
1241 std::to_string(mField.get_comm_rank()) + ".vtk",
1242 *contactFaces);
1243 if (skeletonFaces->size())
1245 "skeleton_faces_" +
1246 std::to_string(mField.get_comm_rank()) + ".vtk",
1247 *skeletonFaces);
1248 // if (skeletonFaces->size())
1249 // CHKERR save_range(mField.get_moab(), "material_skeleton_faces.vtk",
1250 // *materialSkeletonFaces);
1251#endif
1252
1253 auto add_broken_hdiv_field = [this, meshset](const std::string field_name,
1254 const int order) {
1256
1258
1259 auto get_side_map_hdiv = [&]() {
1260 return std::vector<
1261
1262 std::pair<EntityType,
1264
1265 >>{
1266
1267 {MBTET,
1268 [&](BaseFunction::DofsSideMap &dofs_side_map) -> MoFEMErrorCode {
1269 return TetPolynomialBase::setDofsSideMap(HDIV, DISCONTINUOUS, base,
1270 dofs_side_map);
1271 }}
1272
1273 };
1274 };
1275
1277 get_side_map_hdiv(), MB_TAG_DENSE, MF_ZERO);
1279 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1281 };
1282
1283 auto add_l2_field = [this, meshset](const std::string field_name,
1284 const int order, const int dim) {
1287 MB_TAG_DENSE, MF_ZERO);
1289 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1291 };
1292
1293 auto add_h1_field = [this, meshset](const std::string field_name,
1294 const int order, const int dim) {
1297 MB_TAG_DENSE, MF_ZERO);
1299 CHKERR mField.set_field_order(meshset, MBVERTEX, field_name, 1);
1300 CHKERR mField.set_field_order(meshset, MBEDGE, field_name, order);
1301 CHKERR mField.set_field_order(meshset, MBTRI, field_name, order);
1302 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1304 };
1305
1306 auto add_l2_field_by_range = [this](const std::string field_name,
1307 const int order, const int dim,
1308 const int field_dim, Range &&r) {
1311 MB_TAG_DENSE, MF_ZERO);
1312 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(r);
1316 };
1317
1318 auto add_bubble_field = [this, meshset](const std::string field_name,
1319 const int order, const int dim) {
1321 CHKERR mField.add_field(field_name, HDIV, USER_BASE, dim, MB_TAG_DENSE,
1322 MF_ZERO);
1323 // Modify field
1324 auto field_ptr = mField.get_field_structure(field_name);
1325 auto field_order_table =
1326 const_cast<Field *>(field_ptr)->getFieldOrderTable();
1327 auto get_cgg_bubble_order_zero = [](int p) { return 0; };
1328 auto get_cgg_bubble_order_tet = [](int p) {
1329 return NBVOLUMETET_CCG_BUBBLE(p);
1330 };
1331 field_order_table[MBVERTEX] = get_cgg_bubble_order_zero;
1332 field_order_table[MBEDGE] = get_cgg_bubble_order_zero;
1333 field_order_table[MBTRI] = get_cgg_bubble_order_zero;
1334 field_order_table[MBTET] = get_cgg_bubble_order_tet;
1336 CHKERR mField.set_field_order(meshset, MBTRI, field_name, order);
1337 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1339 };
1340
1341 auto add_user_l2_field = [this, meshset](const std::string field_name,
1342 const int order, const int dim) {
1344 CHKERR mField.add_field(field_name, L2, USER_BASE, dim, MB_TAG_DENSE,
1345 MF_ZERO);
1346 // Modify field
1347 auto field_ptr = mField.get_field_structure(field_name);
1348 auto field_order_table =
1349 const_cast<Field *>(field_ptr)->getFieldOrderTable();
1350 auto zero_dofs = [](int p) { return 0; };
1351 auto dof_l2_tet = [](int p) { return NBVOLUMETET_L2(p); };
1352 field_order_table[MBVERTEX] = zero_dofs;
1353 field_order_table[MBEDGE] = zero_dofs;
1354 field_order_table[MBTRI] = zero_dofs;
1355 field_order_table[MBTET] = dof_l2_tet;
1357 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1359 };
1360
1361 // spatial fields
1362 CHKERR add_broken_hdiv_field(piolaStress, spaceOrder);
1363 CHKERR add_bubble_field(bubbleField, spaceOrder, 1);
1364 CHKERR add_l2_field(spatialL2Disp, spaceOrder - 1, 3);
1365 CHKERR add_l2_field(rotAxis, spaceOrder - 1, 3);
1366 CHKERR add_user_l2_field(stretchTensor, noStretch ? -1 : spaceOrder, 6);
1367
1368 if (!skeletonFaces)
1369 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "No skeleton faces");
1370 if (!contactFaces)
1371 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "No contact faces");
1372
1373 auto get_hybridised_disp = [&]() {
1374 auto faces = *skeletonFaces;
1375 auto skin = subtract_boundary_conditions(get_tets_skin());
1376 for (auto &bc : *bcSpatialNormalDisplacementVecPtr) {
1377 faces.merge(intersect(bc.faces, skin));
1378 }
1379 return faces;
1380 };
1381
1382 CHKERR add_l2_field_by_range(hybridSpatialDisp, spaceOrder - 1, 2, 3,
1383 get_hybridised_disp());
1384 CHKERR add_l2_field_by_range(contactDisp, spaceOrder - 1, 2, 3,
1386
1387 // spatial displacement
1388 CHKERR add_h1_field(spatialH1Disp, spaceH1Order, 3);
1389 // material positions
1390 CHKERR add_h1_field(materialH1Positions, 2, 3);
1391
1392 // Eshelby stress
1393 // CHKERR add_broken_hdiv_field(eshelbyStress, spaceOrder);
1394 // CHKERR add_l2_field(materialL2Disp, spaceOrder - 1, 3);
1395 // CHKERR add_l2_field_by_range(hybridMaterialDisp, spaceOrder - 1, 2, 3,
1396 // Range(*materialSkeletonFaces));
1397
1399
1401}
#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 nme:nme847.
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 )

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 )

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 )

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 )

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)

Definition at line 1530 of file EshelbianPlasticity.cpp.

1530 {
1532
1533 // set finite element fields
1534 auto add_field_to_fe = [this](const std::string fe,
1535 const std::string field_name) {
1541 };
1542
1547
1548 CHKERR add_field_to_fe(elementVolumeName, piolaStress);
1549 CHKERR add_field_to_fe(elementVolumeName, bubbleField);
1550 if (!noStretch)
1551 CHKERR add_field_to_fe(elementVolumeName, stretchTensor);
1552 CHKERR add_field_to_fe(elementVolumeName, rotAxis);
1553 CHKERR add_field_to_fe(elementVolumeName, spatialL2Disp);
1554 CHKERR add_field_to_fe(elementVolumeName, spatialH1Disp);
1555 CHKERR add_field_to_fe(elementVolumeName, contactDisp);
1558
1559 // build finite elements data structures
1561 }
1562
1563 // if (!mField.check_finite_element(materialVolumeElement)) {
1564
1565 // Range front_edges = get_range_from_block(mField, "FRONT", SPACE_DIM - 2);
1566
1567 // Range front_elements;
1568 // for (auto l = 0; l != frontLayers; ++l) {
1569 // Range front_elements_layer;
1570 // CHKERR mField.get_moab().get_adjacencies(front_edges, SPACE_DIM, true,
1571 // front_elements_layer,
1572 // moab::Interface::UNION);
1573 // front_elements.merge(front_elements_layer);
1574 // front_edges.clear();
1575 // CHKERR mField.get_moab().get_adjacencies(front_elements_layer,
1576 // SPACE_DIM - 2, true,
1577 // front_edges,
1578 // moab::Interface::UNION);
1579 // }
1580
1581 // CHKERR mField.add_finite_element(materialVolumeElement, MF_ZERO);
1582 // CHKERR mField.add_ents_to_finite_element_by_type(front_elements, MBTET,
1583 // materialVolumeElement);
1584 // // CHKERR add_field_to_fe(materialVolumeElement, eshelbyStress);
1585 // // CHKERR add_field_to_fe(materialVolumeElement, materialL2Disp);
1586 // CHKERR mField.build_finite_elements(materialVolumeElement);
1587 // }
1588
1590}

◆ calculateCrackArea()

MoFEMErrorCode EshelbianCore::calculateCrackArea ( boost::shared_ptr< double > area_ptr)

Definition at line 7035 of file EshelbianPlasticity.cpp.

7035 {
7037
7038 if (!area_ptr) {
7039 CHK_THROW_MESSAGE(MOFEM_INVALID_DATA, "area_ptr is null");
7040 }
7041
7042 int success;
7043 *area_ptr = 0;
7044 if (mField.get_comm_rank() == 0) {
7045 MOFEM_LOG("EP", Sev::inform) << "Calculate crack area";
7046 auto crack_faces = get_range_from_block(mField, "CRACK", SPACE_DIM - 1);
7047 for (auto f : crack_faces) {
7048 *area_ptr += mField.getInterface<Tools>()->getTriArea(f);
7049 }
7050 success = MPI_Bcast(area_ptr.get(), 1, MPI_DOUBLE, 0, mField.get_comm());
7051 } else {
7052 success = MPI_Bcast(area_ptr.get(), 1, MPI_DOUBLE, 0, mField.get_comm());
7053 }
7054 if (success != MPI_SUCCESS) {
7056 }
7058}
@ 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

Definition at line 4299 of file EshelbianPlasticity.cpp.

4299 {
4301
4302 constexpr bool debug = false;
4303
4304 auto get_tags_vec = [&](std::vector<std::pair<std::string, int>> names) {
4305 std::vector<Tag> tags;
4306 tags.reserve(names.size());
4307 auto create_and_clean = [&]() {
4309 for (auto n : names) {
4310 tags.push_back(Tag());
4311 auto &tag = tags.back();
4312 auto &moab = mField.get_moab();
4313 auto rval = moab.tag_get_handle(n.first.c_str(), tag);
4314 if (rval == MB_SUCCESS) {
4315 moab.tag_delete(tag);
4316 }
4317 double def_val[] = {0., 0., 0.};
4318 CHKERR moab.tag_get_handle(n.first.c_str(), n.second, MB_TYPE_DOUBLE,
4319 tag, MB_TAG_CREAT | MB_TAG_SPARSE, def_val);
4320 }
4322 };
4323 CHK_THROW_MESSAGE(create_and_clean(), "create_and_clean");
4324 return tags;
4325 };
4326
4327 enum ExhangeTags { MATERIALFORCE, AREAGROWTH, GRIFFITHFORCE, FACEPRESSURE };
4328
4329 auto tags = get_tags_vec({{"MaterialForce", 3},
4330 {"AreaGrowth", 3},
4331 {"GriffithForce", 1},
4332 {"FacePressure", 1}});
4333
4334 auto calculate_material_forces = [&]() {
4336
4337 /**
4338 * @brief Create element to integration faces energies
4339 */
4340 auto get_face_material_force_fe = [&]() {
4342 auto fe_ptr = boost::make_shared<FaceEle>(mField);
4343 fe_ptr->getRuleHook = [](int, int, int) { return -1; };
4344 fe_ptr->setRuleHook =
4345 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
4347 fe_ptr->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
4348 fe_ptr->getOpPtrVector().push_back(
4350 hybridSpatialDisp, dataAtPts->getGradHybridDispAtPts()));
4351
4352 auto op_loop_domain_side =
4354 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
4355 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
4356 boost::make_shared<CGGUserPolynomialBase>();
4358 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
4360 op_loop_domain_side->getOpPtrVector().push_back(
4362 dataAtPts->getApproxPAtPts()));
4363 op_loop_domain_side->getOpPtrVector().push_back(
4365 bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
4366 if (noStretch) {
4367 op_loop_domain_side->getOpPtrVector().push_back(
4368 physicalEquations->returnOpCalculateStretchFromStress(
4370 }
4371
4372 op_loop_domain_side->getOpPtrVector().push_back(
4374 fe_ptr->getOpPtrVector().push_back(op_loop_domain_side);
4375 fe_ptr->getOpPtrVector().push_back(new OpFaceMaterialForce(dataAtPts));
4376
4377 return fe_ptr;
4378 };
4379
4380 auto integrate_face_material_force_fe = [&](auto &&face_energy_fe) {
4383 dM, skeletonElement, face_energy_fe, 0, mField.get_comm_size());
4384
4385 auto face_exchange = CommInterface::createEntitiesPetscVector(
4386 mField.get_comm(), mField.get_moab(), 2, 3, Sev::inform);
4387
4388 auto print_loc_size = [this](auto v, auto str, auto sev) {
4390 int size;
4391 CHKERR VecGetLocalSize(v.second, &size);
4392 int low, high;
4393 CHKERR VecGetOwnershipRange(v.second, &low, &high);
4394 MOFEM_LOG("EPSYNC", sev) << str << " local size " << size << " ( "
4395 << low << " " << high << " ) ";
4398 };
4399 CHKERR print_loc_size(face_exchange, "material face_exchange",
4400 Sev::verbose);
4401
4403 mField.get_moab(), face_exchange, tags[ExhangeTags::MATERIALFORCE]);
4405 mField.get_moab(), faceExchange, tags[ExhangeTags::FACEPRESSURE]);
4406
4407 // #ifndef NDEBUG
4408 if (debug) {
4410 "front_skin_faces_material_force_" +
4411 std::to_string(mField.get_comm_rank()) + ".vtk",
4412 *skeletonFaces);
4413 }
4414 // #endif
4415
4417 };
4418
4419 CHKERR integrate_face_material_force_fe(get_face_material_force_fe());
4420
4422 };
4423
4424 auto calculate_front_material_force = [&]() {
4427
4428 auto get_conn = [&](auto e) {
4429 Range conn;
4430 CHK_MOAB_THROW(mField.get_moab().get_connectivity(&e, 1, conn, true),
4431 "get connectivity");
4432 return conn;
4433 };
4434
4435 auto get_conn_range = [&](auto e) {
4436 Range conn;
4437 CHK_MOAB_THROW(mField.get_moab().get_connectivity(e, conn, true),
4438 "get connectivity");
4439 return conn;
4440 };
4441
4442 auto get_adj = [&](auto e, auto dim) {
4443 Range adj;
4444 CHK_MOAB_THROW(mField.get_moab().get_adjacencies(&e, 1, dim, true, adj),
4445 "get adj");
4446 return adj;
4447 };
4448
4449 auto get_adj_range = [&](auto e, auto dim) {
4450 Range adj;
4451 CHK_MOAB_THROW(mField.get_moab().get_adjacencies(e, dim, true, adj,
4452 moab::Interface::UNION),
4453 "get adj");
4454 return adj;
4455 };
4456
4457 auto get_material_force = [&](auto r, auto th) {
4458 MatrixDouble material_forces(r.size(), 3, false);
4460 mField.get_moab().tag_get_data(th, r, material_forces.data().data()),
4461 "get data");
4462 return material_forces;
4463 };
4464
4465 if (mField.get_comm_rank() == 0) {
4466
4467 auto crack_edges = get_adj_range(*crackFaces, 1);
4468 auto front_nodes = get_conn_range(*frontEdges);
4469 auto body_edges = get_range_from_block(mField, "EDGES", 1);
4470 // auto front_block_edges = get_range_from_block(mField, "FRONT", 1);
4471 // front_block_edges = subtract(front_block_edges, crack_edges);
4472 // auto front_block_edges_conn = get_conn_range(front_block_edges);
4473
4474 // #ifndef NDEBUG
4475 Range all_skin_faces;
4476 Range all_front_faces;
4477 // #endif
4478
4479 auto calculate_edge_direction = [&](auto e) {
4480 const EntityHandle *conn;
4481 int num_nodes;
4483 mField.get_moab().get_connectivity(e, conn, num_nodes, true),
4484 "get connectivity");
4485 std::array<double, 6> coords;
4487 mField.get_moab().get_coords(conn, num_nodes, coords.data()),
4488 "get coords");
4490 &coords[0], &coords[1], &coords[2]};
4492 &coords[3], &coords[4], &coords[5]};
4495 t_dir(i) = t_p1(i) - t_p0(i);
4496 return t_dir;
4497 };
4498
4499 // take bubble tets at node, and then avarage over the edges
4500 auto calculate_force_through_node = [&]() {
4502
4507
4508 Range body_ents;
4509 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
4510 body_ents);
4511 auto body_skin = get_skin(mField, body_ents);
4512 auto body_skin_conn = get_conn_range(body_skin);
4513
4514 // calculate nodal material force
4515 for (auto n : front_nodes) {
4516 auto adj_tets = get_adj(n, 3);
4517 for (int ll = 0; ll < nbJIntegralLevels; ++ll) {
4518 auto conn = get_conn_range(adj_tets);
4519 adj_tets = get_adj_range(conn, 3);
4520 }
4521 auto skin_faces = get_skin(mField, adj_tets);
4522 auto material_forces = get_material_force(skin_faces, tags[0]);
4523
4524 // #ifndef NDEBUG
4525 if (debug) {
4526 all_skin_faces.merge(skin_faces);
4527 }
4528 // #endif
4529
4530 auto calculate_node_material_force = [&]() {
4531 auto t_face_T =
4532 getFTensor1FromPtr<SPACE_DIM>(material_forces.data().data());
4533 FTensor::Tensor1<double, SPACE_DIM> t_node_force{0., 0., 0.};
4534 for (auto face : skin_faces) {
4535
4536 FTensor::Tensor1<double, SPACE_DIM> t_face_force_tmp{0., 0., 0.};
4537 t_face_force_tmp(I) = t_face_T(I);
4538 ++t_face_T;
4539
4540 auto face_tets = intersect(get_adj(face, 3), adj_tets);
4541
4542 if (face_tets.empty()) {
4543 continue;
4544 }
4545
4546 if (face_tets.size() != 1) {
4548 "face_tets.size() != 1");
4549 }
4550
4551 int side_number, sense, offset;
4552 CHK_MOAB_THROW(mField.get_moab().side_number(face_tets[0], face,
4553 side_number, sense,
4554 offset),
4555 "moab side number");
4556 t_face_force_tmp(I) *= sense;
4557 t_node_force(I) += t_face_force_tmp(I);
4558 }
4559
4560 return t_node_force;
4561 };
4562
4563 auto calculate_crack_area_growth_direction = [&](auto n,
4564 auto &t_node_force) {
4565 // if skin is on body surface, project the direction on it
4566 FTensor::Tensor1<double, SPACE_DIM> t_project{0., 0., 0.};
4567 auto boundary_node = intersect(Range(n, n), body_skin_conn);
4568 if (boundary_node.size()) {
4569 auto faces = intersect(get_adj(n, 2), body_skin);
4570 for (auto f : faces) {
4571 FTensor::Tensor1<double, 3> t_normal_face;
4572 CHKERR mField.getInterface<Tools>()->getTriNormal(
4573 f, &t_normal_face(0));
4574 t_project(I) += t_normal_face(I);
4575 }
4576 t_project.normalize();
4577 }
4578
4579 auto adj_faces = intersect(get_adj(n, 2), *crackFaces);
4580 if (adj_faces.empty()) {
4581 auto adj_edges =
4582 intersect(get_adj(n, 1), unite(*frontEdges, body_edges));
4583 double l = 0;
4584 for (auto e : adj_edges) {
4585 auto t_dir = calculate_edge_direction(e);
4586 l += t_dir.l2();
4587 }
4588 l /= 2;
4589 FTensor::Tensor1<double, SPACE_DIM> t_area_dir{0., 0., 0.};
4590 t_area_dir(I) = -t_node_force(I) / t_node_force.l2();
4591 t_area_dir(I) *= l / 2;
4592 return t_area_dir;
4593 }
4594
4595 // calculate surface projection matrix
4598 t_Q(I, J) = t_kd(I, J);
4599 if (boundary_node.size()) {
4600 t_Q(I, J) -= t_project(I) * t_project(J);
4601 }
4602
4603 // calculate direction
4604 auto front_edges = get_adj(n, 1);
4605 FTensor::Tensor1<double, 3> t_area_dir{0., 0., 0.};
4606 for (auto f : adj_faces) {
4607 int num_nodes;
4608 const EntityHandle *conn;
4609 CHKERR mField.get_moab().get_connectivity(f, conn, num_nodes,
4610 true);
4611 std::array<double, 9> coords;
4612 CHKERR mField.get_moab().get_coords(conn, num_nodes,
4613 coords.data());
4614 FTensor::Tensor1<double, 3> t_face_normal;
4616 CHKERR mField.getInterface<Tools>()->getTriNormal(
4617 coords.data(), &t_face_normal(0), &t_d_normal(0, 0, 0));
4618 auto n_it = std::find(conn, conn + num_nodes, n);
4619 auto n_index = std::distance(conn, n_it);
4620
4621 FTensor::Tensor2<double, 3, 3> t_face_hessian{
4622 t_d_normal(0, n_index, 0), t_d_normal(0, n_index, 1),
4623 t_d_normal(0, n_index, 2),
4624
4625 t_d_normal(1, n_index, 0), t_d_normal(1, n_index, 1),
4626 t_d_normal(1, n_index, 2),
4627
4628 t_d_normal(2, n_index, 0), t_d_normal(2, n_index, 1),
4629 t_d_normal(2, n_index, 2)};
4630
4631 FTensor::Tensor2<double, 3, 3> t_projected_hessian;
4632 t_projected_hessian(I, J) =
4633 t_Q(I, K) * (t_face_hessian(K, L) * t_Q(L, J));
4634 t_face_normal.normalize();
4635 t_area_dir(K) +=
4636 t_face_normal(I) * t_projected_hessian(I, K) / 2.;
4637 }
4638
4639 return t_area_dir;
4640 };
4641
4642 auto t_node_force = calculate_node_material_force();
4643 t_node_force(I) /= griffithEnergy; // scale all by griffith energy
4645 mField.get_moab().tag_set_data(tags[ExhangeTags::MATERIALFORCE],
4646 &n, 1, &t_node_force(0)),
4647 "set data");
4648
4649 auto get_area_dir = [&]() {
4650 auto t_area_dir =
4651 calculate_crack_area_growth_direction(n, t_node_force);
4652 if (nbJIntegralLevels) {
4653 Range seed_n = Range(n, n);
4654 Range adj_edges;
4655 for (int l = 0; l < nbJIntegralLevels; ++l) {
4656 adj_edges.merge(intersect(get_adj_range(seed_n, 1),
4657 unite(*frontEdges, body_edges)));
4658 seed_n = get_conn_range(adj_edges);
4659 }
4660 auto skin_adj_edges = get_skin(mField, adj_edges);
4661 skin_adj_edges.merge(Range(n, n));
4662 seed_n = subtract(seed_n, skin_adj_edges);
4663 for (auto sn : seed_n) {
4664 auto t_area_dir_sn =
4665 calculate_crack_area_growth_direction(sn, t_node_force);
4666 t_area_dir(I) += t_area_dir_sn(I);
4667 }
4668 }
4669 return t_area_dir;
4670 };
4671
4672 auto t_area_dir = get_area_dir();
4673
4675 mField.get_moab().tag_set_data(tags[ExhangeTags::AREAGROWTH], &n,
4676 1, &t_area_dir(0)),
4677 "set data");
4678 auto griffith = -t_node_force(I) * t_area_dir(I) /
4679 (t_area_dir(K) * t_area_dir(K));
4681 mField.get_moab().tag_set_data(tags[ExhangeTags::GRIFFITHFORCE],
4682 &n, 1, &griffith),
4683 "set data");
4684 }
4685
4686 auto ave_node_force = [&](auto th) {
4688
4689 for (auto e : *frontEdges) {
4690
4691 auto conn = get_conn(e);
4692 auto data = get_material_force(conn, th);
4693 auto t_node = getFTensor1FromPtr<SPACE_DIM>(data.data().data());
4694 FTensor::Tensor1<double, SPACE_DIM> t_edge{0., 0., 0.};
4695 for (auto n : conn) {
4696 t_edge(I) += t_node(I);
4697 ++t_node;
4698 }
4699 t_edge(I) /= conn.size();
4700
4701 FTensor::Tensor1<double, SPACE_DIM> t_edge_direction =
4702 calculate_edge_direction(e);
4703 t_edge_direction.normalize();
4704
4709 t_cross(K) =
4710 FTensor::levi_civita(I, J, K) * t_edge_direction(I) * t_edge(J);
4711 t_edge(K) = FTensor::levi_civita(I, J, K) * t_edge_direction(J) *
4712 t_cross(I);
4713
4714 CHKERR mField.get_moab().tag_set_data(th, &e, 1, &t_edge(0));
4715 }
4717 };
4718
4719 auto ave_node_griffith_energy = [&](auto th) {
4721 for (auto e : *frontEdges) {
4723 CHKERR mField.get_moab().tag_get_data(
4724 tags[ExhangeTags::MATERIALFORCE], &e, 1, &t_edge_force(0));
4726 CHKERR mField.get_moab().tag_get_data(tags[ExhangeTags::AREAGROWTH],
4727 &e, 1, &t_edge_area_dir(0));
4728 double griffith_energy = -t_edge_force(I) * t_edge_area_dir(I) /
4729 (t_edge_area_dir(K) * t_edge_area_dir(K));
4730 CHKERR mField.get_moab().tag_set_data(th, &e, 1, &griffith_energy);
4731 }
4733 };
4734
4735 CHKERR ave_node_force(tags[ExhangeTags::MATERIALFORCE]);
4736 CHKERR ave_node_force(tags[ExhangeTags::AREAGROWTH]);
4737 CHKERR ave_node_griffith_energy(tags[ExhangeTags::GRIFFITHFORCE]);
4738
4740 };
4741
4742 CHKERR calculate_force_through_node();
4743
4744 // calculate face cross
4745 for (auto e : *frontEdges) {
4746 auto adj_faces = get_adj(e, 2);
4747 auto crack_face = intersect(get_adj(e, 2), *crackFaces);
4748
4749 // #ifndef NDEBUG
4750 if (debug) {
4751 all_front_faces.merge(adj_faces);
4752 }
4753 // #endif
4754
4756 CHKERR mField.get_moab().tag_get_data(tags[ExhangeTags::MATERIALFORCE],
4757 &e, 1, &t_edge_force(0));
4758 FTensor::Tensor1<double, SPACE_DIM> t_edge_direction =
4759 calculate_edge_direction(e);
4760 t_edge_direction.normalize();
4765 t_cross(K) = FTensor::levi_civita(I, J, K) * t_edge_direction(I) *
4766 t_edge_force(J);
4767
4768 for (auto f : adj_faces) {
4770 CHKERR mField.getInterface<Tools>()->getTriNormal(f, &t_normal(0));
4771 t_normal.normalize();
4772 int side_number, sense, offset;
4773 CHKERR mField.get_moab().side_number(f, e, side_number, sense,
4774 offset);
4775 auto dot = -sense * t_cross(I) * t_normal(I);
4776 CHK_MOAB_THROW(mField.get_moab().tag_set_data(
4777 tags[ExhangeTags::GRIFFITHFORCE], &f, 1, &dot),
4778 "set data");
4779 }
4780 }
4781
4782 // #ifndef NDEBUG
4783 if (debug) {
4784 int ts_step;
4785 CHKERR TSGetStepNumber(ts, &ts_step);
4787 "front_edges_material_force_" +
4788 std::to_string(ts_step) + ".vtk",
4789 *frontEdges);
4791 "front_skin_faces_material_force_" +
4792 std::to_string(ts_step) + ".vtk",
4793 all_skin_faces);
4795 "front_faces_material_force_" +
4796 std::to_string(ts_step) + ".vtk",
4797 all_front_faces);
4798 }
4799 // #endif
4800 }
4801
4802 auto edge_exchange = CommInterface::createEntitiesPetscVector(
4803 mField.get_comm(), mField.get_moab(), 1, 3, Sev::inform);
4805 mField.get_moab(), edge_exchange, tags[ExhangeTags::MATERIALFORCE]);
4807 mField.get_moab(), edge_exchange, tags[ExhangeTags::AREAGROWTH]);
4809 mField.get_moab(), edgeExchange, tags[ExhangeTags::GRIFFITHFORCE]);
4810
4812 };
4813
4814 auto print_results = [&]() {
4816
4817 auto get_conn_range = [&](auto e) {
4818 Range conn;
4819 CHK_MOAB_THROW(mField.get_moab().get_connectivity(e, conn, true),
4820 "get connectivity");
4821 return conn;
4822 };
4823
4824 auto get_tag_data = [&](auto &ents, auto tag, auto dim) {
4825 std::vector<double> data(ents.size() * dim);
4826 CHK_MOAB_THROW(mField.get_moab().tag_get_data(tag, ents, data.data()),
4827 "get data");
4828 return data;
4829 };
4830
4831 if (mField.get_comm_rank() == 0) {
4832 auto at_nodes = [&]() {
4834 auto conn = get_conn_range(*frontEdges);
4835 auto material_force =
4836 get_tag_data(conn, tags[ExhangeTags::MATERIALFORCE], 3);
4837 auto area_growth = get_tag_data(conn, tags[ExhangeTags::AREAGROWTH], 3);
4838 auto griffith_force =
4839 get_tag_data(conn, tags[ExhangeTags::GRIFFITHFORCE], 1);
4840 std::vector<double> coords(conn.size() * 3);
4841 CHK_MOAB_THROW(mField.get_moab().get_coords(conn, coords.data()),
4842 "get coords");
4843 if (conn.size())
4844 MOFEM_LOG("EPSELF", Sev::inform) << "Material force at nodes";
4845 for (size_t i = 0; i < conn.size(); ++i) {
4846 MOFEM_LOG("EPSELF", Sev::inform)
4847 << "Node " << conn[i] << " coords "
4848 << coords[i * 3 + 0] << " " << coords[i * 3 + 1] << " "
4849 << coords[i * 3 + 2] << " material force "
4850 << material_force[i * 3 + 0] << " "
4851 << material_force[i * 3 + 1] << " "
4852 << material_force[i * 3 + 2] << " area growth "
4853 << area_growth[i * 3 + 0] << " " << area_growth[i * 3 + 1]
4854 << " " << area_growth[i * 3 + 2] << " griffith force "
4855 << griffith_force[i];
4856 }
4858 };
4859
4860 at_nodes();
4861 }
4863 };
4864
4865 CHKERR calculate_material_forces();
4866 CHKERR calculate_front_material_force();
4867 CHKERR print_results();
4868
4870}
#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
FTensor::Tensor1< FTensor::PackPtr< double *, S >, DIM > getFTensor1FromPtr(double *ptr)
Make Tensor1 from pointer.
constexpr IntegrationType I
CommInterface::EntitiesPetscVector edgeExchange
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
static double griffithEnergy
Griffith energy.
boost::shared_ptr< Range > frontAdjEdges
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.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Element used to execute operators on side of the element.

◆ calculateOrientation()

MoFEMErrorCode EshelbianPlasticity::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

Definition at line 4872 of file EshelbianPlasticity.cpp.

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

Definition at line 6698 of file EshelbianPlasticity.cpp.

6698 {
6700 auto meshset_mng = mField.getInterface<MeshsetsManager>();
6701 while (meshset_mng->checkMeshset(addCrackMeshsetId, BLOCKSET))
6703 MOFEM_LOG("EP", Sev::inform)
6704 << "Crack added surface meshset " << addCrackMeshsetId;
6705 CHKERR meshset_mng->addMeshset(BLOCKSET, addCrackMeshsetId, "CRACK_COMPUTED");
6707};

◆ createExchangeVectors()

MoFEMErrorCode EshelbianCore::createExchangeVectors ( Sev sev)

Definition at line 7003 of file EshelbianPlasticity.cpp.

7003 {
7005
7006 auto print_loc_size = [this](auto v, auto str, auto sev) {
7008 int size;
7009 CHKERR VecGetLocalSize(v.second, &size);
7010 int low, high;
7011 CHKERR VecGetOwnershipRange(v.second, &low, &high);
7012 MOFEM_LOG("EPSYNC", sev) << str << " local size " << size << " ( " << low
7013 << " " << high << " ) ";
7016 };
7017
7019 mField.get_comm(), mField.get_moab(), 3, 1, sev);
7020 CHKERR print_loc_size(volumeExchange, "volumeExchange", sev);
7022 mField.get_comm(), mField.get_moab(), 2, 1, Sev::inform);
7023 CHKERR print_loc_size(faceExchange, "faceExchange", sev);
7025 mField.get_comm(), mField.get_moab(), 1, 1, Sev::inform);
7026 CHKERR print_loc_size(edgeExchange, "edgeExchange", sev);
7028 mField.get_comm(), mField.get_moab(), 0, 3, Sev::inform);
7029 CHKERR print_loc_size(vertexExchange, "vertexExchange", sev);
7030
7032}
CommInterface::EntitiesPetscVector volumeExchange

◆ d_f_linear()

static double EshelbianPlasticity::EshelbianCore::d_f_linear ( const double v)
inlinestatic

Definition at line 160 of file EshelbianPlasticity.hpp.

◆ d_f_log()

static double EshelbianPlasticity::EshelbianCore::d_f_log ( const double v)
inlinestatic

Definition at line 141 of file EshelbianPlasticity.hpp.

◆ d_f_log_e()

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

Definition at line 96 of file EshelbianPlasticity.hpp.

◆ d_f_log_e_quadratic()

static double EshelbianPlasticity::EshelbianCore::d_f_log_e_quadratic ( const double v)
inlinestatic

Definition at line 65 of file EshelbianPlasticity.hpp.

67
68using MatrixPtr = boost::shared_ptr<MatrixDouble>;
69using VectorPtr = boost::shared_ptr<VectorDouble>;
70
71using EntData = EntitiesFieldData::EntData;
72using UserDataOperator = ForcesAndSourcesCore::UserDataOperator;
73using VolUserDataOperator = VolumeElementForcesAndSourcesCore::UserDataOperator;
ForcesAndSourcesCore::UserDataOperator UserDataOperator
boost::shared_ptr< VectorDouble > VectorPtr
boost::shared_ptr< MatrixDouble > MatrixPtr
Data on single entity (This is passed as argument to DataOperator::doWork)

◆ dd_f_linear()

static double EshelbianPlasticity::EshelbianCore::dd_f_linear ( const double v)
inlinestatic

Definition at line 161 of file EshelbianPlasticity.hpp.

◆ dd_f_log()

static double EshelbianPlasticity::EshelbianCore::dd_f_log ( const double v)
inlinestatic

Definition at line 144 of file EshelbianPlasticity.hpp.

◆ dd_f_log_e()

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

Definition at line 106 of file EshelbianPlasticity.hpp.

◆ dd_f_log_e_quadratic()

static double EshelbianPlasticity::EshelbianCore::dd_f_log_e_quadratic ( const double v)
inlinestatic

Definition at line 75 of file EshelbianPlasticity.hpp.

◆ f_linear()

static double EshelbianPlasticity::EshelbianCore::f_linear ( const double v)
inlinestatic

Definition at line 159 of file EshelbianPlasticity.hpp.

◆ f_log()

static double EshelbianPlasticity::EshelbianCore::f_log ( const double v)
inlinestatic

Definition at line 138 of file EshelbianPlasticity.hpp.

◆ f_log_e()

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

Definition at line 83 of file EshelbianPlasticity.hpp.

83 : public boost::enable_shared_from_this<DataAtIntegrationPts> {
84
85 MatrixDouble approxPAtPts;
86 MatrixDouble approxSigmaAtPts;
87 MatrixDouble divPAtPts;
88 MatrixDouble divSigmaAtPts;
89 MatrixDouble wL2AtPts;
90 MatrixDouble wL2DotAtPts;
91 MatrixDouble wL2DotDotAtPts;
92 MatrixDouble logStretchTensorAtPts;
93 MatrixDouble stretchTensorAtPts;
94 VectorDouble jacobianAtPts;
95 MatrixDouble tractionAtPts;

◆ f_log_e_quadratic()

◆ getBc()

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

Definition at line 244 of file EshelbianPlasticity.hpp.

244 {
245 return boost::shared_ptr<MatrixDouble>(shared_from_this(), &matD);
246 }
247
248 inline MatrixPtr getMatInvDPtr() {
249 return boost::shared_ptr<MatrixDouble>(shared_from_this(), &matInvD);
250 }
251
252 inline MatrixPtr getMatAxiatorDPtr() {
253 return boost::shared_ptr<MatrixDouble>(shared_from_this(), &matAxiatorD);
254 }
255
256 inline MatrixPtr getMatDeviatorDPtr() {
257 return boost::shared_ptr<MatrixDouble>(shared_from_this(), &matDeviatorD);
258 }
259
260 inline MatrixPtr getSmallWH1AtPts() {
261 return boost::shared_ptr<MatrixDouble>(shared_from_this(), &wH1AtPts);
262 }
263
264 inline MatrixPtr getLargeXH1AtPts() {
265 return boost::shared_ptr<MatrixDouble>(shared_from_this(), &XH1AtPts);
266 }
267
268 inline MatrixPtr getContactL2AtPts() {

◆ getExternalStrain()

MoFEMErrorCode EshelbianCore::getExternalStrain ( )

Definition at line 6956 of file EshelbianPlasticity.cpp.

6956 {
6958
6959 auto getExternalStrain = [&](boost::shared_ptr<ExternalStrainVec> &ext_strain_vec_ptr,
6960 const std::string block_name,
6961 const int nb_attributes) {
6964 std::regex((boost::format("%s(.*)") % block_name).str()))
6965 ) {
6966 std::vector<double> block_attributes;
6967 CHKERR it->getAttributes(block_attributes);
6968 if (block_attributes.size() < nb_attributes) {
6969 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
6970 "In block %s expected %d attributes, but given %ld",
6971 it->getName().c_str(), nb_attributes, block_attributes.size());
6972 }
6973
6974 auto get_block_ents = [&]() {
6975 Range ents;
6976 CHKERR mField.get_moab().get_entities_by_handle(it->meshset, ents,
6977 true);
6978 return ents;
6979 };
6980 auto Ents = get_block_ents();
6981 ext_strain_vec_ptr->emplace_back(it->getName(), block_attributes,
6982 get_block_ents());
6983 }
6985 };
6986
6987 externalStrainVecPtr = boost::make_shared<ExternalStrainVec>();
6988 CHKERR getExternalStrain(externalStrainVecPtr, "EXTERNALSTRAIN", 2);
6989
6990 auto ts_pre_stretch =
6991 boost::make_shared<DynamicRelaxationTimeScale>("externalstrain_history.txt");
6992 for (auto &ext_strain_block: *externalStrainVecPtr) {
6993 MOFEM_LOG("EP", Sev::noisy)
6994 << "Add time scaling external strain: " << ext_strain_block.blockName;
6995 timeScaleMap[ext_strain_block.blockName] =
6997 ts_pre_stretch, "externalstrain_history", ".txt", ext_strain_block.blockName);
6998 }
6999
7001}
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
std::map< std::string, boost::shared_ptr< ScalingMethod > > timeScaleMap
boost::shared_ptr< ExternalStrainVec > externalStrainVecPtr
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 ( )

Definition at line 919 of file EshelbianPlasticity.cpp.

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

◆ getSpatialDispBc()

MoFEMErrorCode EshelbianPlasticity::EshelbianCore::getSpatialDispBc ( )

[Getting norms]

Definition at line 6778 of file EshelbianPlasticity.cpp.

6778 {
6780
6781 auto bc_mng = mField.getInterface<BcManager>();
6783 "", piolaStress, false, false);
6784
6785 bcSpatialDispVecPtr = boost::make_shared<BcDispVec>();
6786 for (auto bc : bc_mng->getBcMapByBlockName()) {
6787 if (auto disp_bc = bc.second->dispBcPtr) {
6788
6789 auto [field_name, block_name] =
6791 MOFEM_LOG("EP", Sev::inform)
6792 << "Field name: " << field_name << " Block name: " << block_name;
6793 MOFEM_LOG("EP", Sev::noisy) << "Displacement BC: " << *disp_bc;
6794
6795 std::vector<double> block_attributes(6, 0.);
6796 if (disp_bc->data.flag1 == 1) {
6797 block_attributes[0] = disp_bc->data.value1;
6798 block_attributes[3] = 1;
6799 }
6800 if (disp_bc->data.flag2 == 1) {
6801 block_attributes[1] = disp_bc->data.value2;
6802 block_attributes[4] = 1;
6803 }
6804 if (disp_bc->data.flag3 == 1) {
6805 block_attributes[2] = disp_bc->data.value3;
6806 block_attributes[5] = 1;
6807 }
6808 auto faces = bc.second->bcEnts.subset_by_dimension(2);
6809 bcSpatialDispVecPtr->emplace_back(block_name, block_attributes, faces);
6810 }
6811 }
6812 // old way of naming blocksets for displacement BCs
6813 CHKERR getBc(bcSpatialDispVecPtr, "SPATIAL_DISP_BC", 6);
6814
6816 boost::make_shared<NormalDisplacementBcVec>();
6817 for (auto bc : bc_mng->getBcMapByBlockName()) {
6818 auto block_name = "(.*)NORMAL_DISPLACEMENT(.*)";
6819 std::regex reg_name(block_name);
6820 if (std::regex_match(bc.first, reg_name)) {
6821 auto [field_name, block_name] =
6823 MOFEM_LOG("EP", Sev::inform)
6824 << "Field name: " << field_name << " Block name: " << block_name;
6826 block_name, bc.second->bcAttributes,
6827 bc.second->bcEnts.subset_by_dimension(2));
6828 }
6829 }
6830
6832 boost::make_shared<AnalyticalDisplacementBcVec>();
6833
6834 for (auto bc : bc_mng->getBcMapByBlockName()) {
6835 auto block_name = "(.*)ANALYTICAL_DISPLACEMENT(.*)";
6836 std::regex reg_name(block_name);
6837 if (std::regex_match(bc.first, reg_name)) {
6838 auto [field_name, block_name] =
6840 MOFEM_LOG("EP", Sev::inform)
6841 << "Field name: " << field_name << " Block name: " << block_name;
6843 block_name, bc.second->bcAttributes,
6844 bc.second->bcEnts.subset_by_dimension(2));
6845 }
6846 }
6847
6848 auto ts_displacement =
6849 boost::make_shared<DynamicRelaxationTimeScale>("disp_history.txt");
6850 for (auto &bc : *bcSpatialDispVecPtr) {
6851 MOFEM_LOG("EP", Sev::noisy)
6852 << "Add time scaling displacement BC: " << bc.blockName;
6853 timeScaleMap[bc.blockName] =
6855 ts_displacement, "disp_history", ".txt", bc.blockName);
6856 }
6857
6858 auto ts_normal_displacement =
6859 boost::make_shared<DynamicRelaxationTimeScale>("normal_disp_history.txt");
6860 for (auto &bc : *bcSpatialNormalDisplacementVecPtr) {
6861 MOFEM_LOG("EP", Sev::noisy)
6862 << "Add time scaling normal displacement BC: " << bc.blockName;
6863 timeScaleMap[bc.blockName] =
6865 ts_normal_displacement, "normal_disp_history", ".txt",
6866 bc.blockName);
6867 }
6868
6870}
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 EshelbianPlasticity::EshelbianCore::getSpatialRotationBc ( )
inline

Definition at line 272 of file EshelbianPlasticity.hpp.

272 {
273 return boost::shared_ptr<MatrixDouble>(shared_from_this(), &wGradH1AtPts);
274 }
275
276 inline VectorPtr getJacobianAtPts() {
277 return boost::shared_ptr<VectorDouble>(shared_from_this(), &jacobianAtPts);
278 }
279
280 inline MatrixPtr getLeviKirchhoffAtPts() {
281 return boost::shared_ptr<MatrixDouble>(shared_from_this(),
282 &leviKirchhoffAtPts);
283 };
284
285 inline MatrixPtr getVarRotAxisPts() {
286 return boost::shared_ptr<MatrixDouble>(shared_from_this(), &varRotAxis);
287 }

◆ getSpatialTractionBc()

MoFEMErrorCode EshelbianCore::getSpatialTractionBc ( )

Definition at line 6872 of file EshelbianPlasticity.cpp.

6872 {
6874
6875 auto bc_mng = mField.getInterface<BcManager>();
6877 false, false);
6878
6879 bcSpatialTractionVecPtr = boost::make_shared<TractionBcVec>();
6880
6881 for (auto bc : bc_mng->getBcMapByBlockName()) {
6882 if (auto force_bc = bc.second->forceBcPtr) {
6883
6884 auto [field_name, block_name] =
6886 MOFEM_LOG("EP", Sev::inform)
6887 << "Field name: " << field_name << " Block name: " << block_name;
6888 MOFEM_LOG("EP", Sev::noisy) << "Force BC: " << *force_bc;
6889
6890 std::vector<double> block_attributes(6, 0.);
6891 block_attributes[0] = -force_bc->data.value3 * force_bc->data.value1;
6892 block_attributes[3] = 1;
6893 block_attributes[1] = -force_bc->data.value4 * force_bc->data.value1;
6894 block_attributes[4] = 1;
6895 block_attributes[2] = -force_bc->data.value5 * force_bc->data.value1;
6896 block_attributes[5] = 1;
6897 auto faces = bc.second->bcEnts.subset_by_dimension(2);
6898 bcSpatialTractionVecPtr->emplace_back(block_name, block_attributes,
6899 faces);
6900 }
6901 }
6902 CHKERR getBc(bcSpatialTractionVecPtr, "SPATIAL_TRACTION_BC", 6);
6903
6904 bcSpatialPressureVecPtr = boost::make_shared<PressureBcVec>();
6905 for (auto bc : bc_mng->getBcMapByBlockName()) {
6906 auto block_name = "(.*)PRESSURE(.*)";
6907 std::regex reg_name(block_name);
6908 if (std::regex_match(bc.first, reg_name)) {
6909
6910 auto [field_name, block_name] =
6912 MOFEM_LOG("EP", Sev::inform)
6913 << "Field name: " << field_name << " Block name: " << block_name;
6914 bcSpatialPressureVecPtr->emplace_back(
6915 block_name, bc.second->bcAttributes,
6916 bc.second->bcEnts.subset_by_dimension(2));
6917 }
6918 }
6919
6921 boost::make_shared<AnalyticalTractionBcVec>();
6922
6923 for (auto bc : bc_mng->getBcMapByBlockName()) {
6924 auto block_name = "(.*)ANALYTICAL_TRACTION(.*)";
6925 std::regex reg_name(block_name);
6926 if (std::regex_match(bc.first, reg_name)) {
6927 auto [field_name, block_name] =
6929 MOFEM_LOG("EP", Sev::inform)
6930 << "Field name: " << field_name << " Block name: " << block_name;
6932 block_name, bc.second->bcAttributes,
6933 bc.second->bcEnts.subset_by_dimension(2));
6934 }
6935 }
6936
6937 auto ts_traction =
6938 boost::make_shared<DynamicRelaxationTimeScale>("traction_history.txt");
6939 for (auto &bc : *bcSpatialTractionVecPtr) {
6940 timeScaleMap[bc.blockName] =
6942 ts_traction, "traction_history", ".txt", bc.blockName);
6943 }
6944
6945 auto ts_pressure =
6946 boost::make_shared<DynamicRelaxationTimeScale>("pressure_history.txt");
6947 for (auto &bc : *bcSpatialPressureVecPtr) {
6948 timeScaleMap[bc.blockName] =
6950 ts_pressure, "pressure_history", ".txt", bc.blockName);
6951 }
6952
6954}
Definition of the force bc data structure.
Definition BCData.hpp:135

◆ getSpatialTractionFreeBc()

MoFEMErrorCode EshelbianPlasticity::EshelbianCore::getSpatialTractionFreeBc ( const EntityHandle meshset = 0)
inline

Definition at line 306 of file EshelbianPlasticity.hpp.

310 {

◆ gettingNorms()

MoFEMErrorCode EshelbianPlasticity::EshelbianCore::gettingNorms ( )

[Getting norms]

Definition at line 6710 of file EshelbianPlasticity.cpp.

6710 {
6712
6713 auto post_proc_norm_fe =
6714 boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
6715
6716 auto post_proc_norm_rule_hook = [](int, int, int p) -> int {
6717 return 2 * (p);
6718 };
6719 post_proc_norm_fe->getRuleHook = post_proc_norm_rule_hook;
6720
6721 post_proc_norm_fe->getUserPolynomialBase() =
6722 boost::shared_ptr<BaseFunction>(new CGGUserPolynomialBase());
6723
6725 post_proc_norm_fe->getOpPtrVector(), {L2, H1, HDIV}, materialH1Positions,
6727
6728 enum NORMS { U_NORM_L2 = 0, U_NORM_H1, PIOLA_NORM, U_ERROR_L2, LAST_NORM };
6729 auto norms_vec =
6730 createVectorMPI(mField.get_comm(), LAST_NORM, PETSC_DETERMINE);
6731 CHKERR VecZeroEntries(norms_vec);
6732
6733 auto u_l2_ptr = boost::make_shared<MatrixDouble>();
6734 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
6735 post_proc_norm_fe->getOpPtrVector().push_back(
6737 post_proc_norm_fe->getOpPtrVector().push_back(
6739 post_proc_norm_fe->getOpPtrVector().push_back(
6740 new OpCalcNormL2Tensor1<SPACE_DIM>(u_l2_ptr, norms_vec, U_NORM_L2));
6741 post_proc_norm_fe->getOpPtrVector().push_back(
6742 new OpCalcNormL2Tensor1<SPACE_DIM>(u_h1_ptr, norms_vec, U_NORM_H1));
6743 post_proc_norm_fe->getOpPtrVector().push_back(
6744 new OpCalcNormL2Tensor1<SPACE_DIM>(u_l2_ptr, norms_vec, U_ERROR_L2,
6745 u_h1_ptr));
6746
6747 auto piola_ptr = boost::make_shared<MatrixDouble>();
6748 post_proc_norm_fe->getOpPtrVector().push_back(
6750 post_proc_norm_fe->getOpPtrVector().push_back(
6752 MBMAXTYPE));
6753
6754 post_proc_norm_fe->getOpPtrVector().push_back(
6755 new OpCalcNormL2Tensor2<3, 3>(piola_ptr, norms_vec, PIOLA_NORM));
6756
6757 TetPolynomialBase::switchCacheBaseOn<HDIV>({post_proc_norm_fe.get()});
6759 *post_proc_norm_fe);
6760 TetPolynomialBase::switchCacheBaseOff<HDIV>({post_proc_norm_fe.get()});
6761
6762 CHKERR VecAssemblyBegin(norms_vec);
6763 CHKERR VecAssemblyEnd(norms_vec);
6764 const double *norms;
6765 CHKERR VecGetArrayRead(norms_vec, &norms);
6766 MOFEM_LOG("EP", Sev::inform) << "norm_u: " << std::sqrt(norms[U_NORM_L2]);
6767 MOFEM_LOG("EP", Sev::inform) << "norm_u_h1: " << std::sqrt(norms[U_NORM_H1]);
6768 MOFEM_LOG("EP", Sev::inform)
6769 << "norm_error_u_l2: " << std::sqrt(norms[U_ERROR_L2]);
6770 MOFEM_LOG("EP", Sev::inform)
6771 << "norm_piola: " << std::sqrt(norms[PIOLA_NORM]);
6772 CHKERR VecRestoreArrayRead(norms_vec, &norms);
6773
6775}
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.
Get values at integration pts for tensor field rank 1, i.e. vector field.

◆ 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

Definition at line 2083 of file EshelbianPlasticity.cpp.

2085 {
2087
2088 // get skin from all tets
2089 Range tets;
2090 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
2091 Range tets_skin_part;
2092 Skinner skin(&mField.get_moab());
2093 CHKERR skin.find_skin(0, tets, false, tets_skin_part);
2094 ParallelComm *pcomm =
2095 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
2096 Range tets_skin;
2097 CHKERR pcomm->filter_pstatus(tets_skin_part,
2098 PSTATUS_SHARED | PSTATUS_MULTISHARED,
2099 PSTATUS_NOT, -1, &tets_skin);
2100
2101 bc_ptr->resize(3);
2102 for (int dd = 0; dd != 3; ++dd)
2103 (*bc_ptr)[dd] = tets_skin;
2104
2105 // Do not remove dofs on which traction is applied
2107 for (auto &v : *bcSpatialDispVecPtr) {
2108 if (v.flags[0])
2109 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2110 if (v.flags[1])
2111 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2112 if (v.flags[2])
2113 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2114 }
2115
2116 // Do not remove dofs on which rotation is applied
2118 for (auto &v : *bcSpatialRotationVecPtr) {
2119 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2120 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2121 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2122 }
2123
2125 for (auto &v : *bcSpatialNormalDisplacementVecPtr) {
2126 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2127 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2128 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2129 }
2130
2133 if (v.flags[0])
2134 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2135 if (v.flags[1])
2136 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2137 if (v.flags[2])
2138 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2139 }
2140
2142 for (auto &v : *bcSpatialTractionVecPtr) {
2143 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2144 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2145 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2146 }
2147
2149 for (auto &v : *bcSpatialAnalyticalTractionVecPtr) {
2150 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2151 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2152 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2153 }
2154
2156 for (auto &v : *bcSpatialPressureVecPtr) {
2157 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2158 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2159 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2160 }
2161
2162 // remove contact
2164 std::regex((boost::format("%s(.*)") % contact_set_name).str()))) {
2165 Range faces;
2166 CHKERR m->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2, faces,
2167 true);
2168 (*bc_ptr)[0] = subtract((*bc_ptr)[0], faces);
2169 (*bc_ptr)[1] = subtract((*bc_ptr)[1], faces);
2170 (*bc_ptr)[2] = subtract((*bc_ptr)[2], faces);
2171 }
2172
2174}
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 EshelbianPlasticity::EshelbianCore::inv_d_f_linear ( const double v)
inlinestatic

Definition at line 164 of file EshelbianPlasticity.hpp.

◆ inv_d_f_log()

static double EshelbianPlasticity::EshelbianCore::inv_d_f_log ( const double v)
inlinestatic

Definition at line 152 of file EshelbianPlasticity.hpp.

◆ inv_d_f_log_e()

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

Definition at line 125 of file EshelbianPlasticity.hpp.

◆ inv_dd_f_linear()

static double EshelbianPlasticity::EshelbianCore::inv_dd_f_linear ( const double v)
inlinestatic

Definition at line 165 of file EshelbianPlasticity.hpp.

◆ inv_dd_f_log()

static double EshelbianPlasticity::EshelbianCore::inv_dd_f_log ( const double v)
inlinestatic

Definition at line 155 of file EshelbianPlasticity.hpp.

◆ inv_dd_f_log_e()

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

Definition at line 131 of file EshelbianPlasticity.hpp.

◆ inv_f_linear()

static double EshelbianPlasticity::EshelbianCore::inv_f_linear ( const double v)
inlinestatic

Definition at line 163 of file EshelbianPlasticity.hpp.

◆ inv_f_log()

static double EshelbianPlasticity::EshelbianCore::inv_f_log ( const double v)
inlinestatic

Definition at line 149 of file EshelbianPlasticity.hpp.

◆ inv_f_log_e()

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

Definition at line 116 of file EshelbianPlasticity.hpp.

◆ 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 = {} )

Definition at line 3723 of file EshelbianPlasticity.cpp.

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

Definition at line 4217 of file EshelbianPlasticity.cpp.

4219 {
4221
4223
4224 auto post_proc_mesh = boost::make_shared<moab::Core>();
4225 auto post_proc_ptr =
4226 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
4227 mField, post_proc_mesh);
4229 post_proc_ptr->getOpPtrVector(), {L2}, materialH1Positions,
4231
4232 auto hybrid_disp = boost::make_shared<MatrixDouble>();
4233 post_proc_ptr->getOpPtrVector().push_back(
4235
4236 auto hybrid_res = boost::make_shared<MatrixDouble>();
4237 post_proc_ptr->getOpPtrVector().push_back(
4239
4241 post_proc_ptr->getOpPtrVector().push_back(
4242
4243 new OpPPMap(
4244
4245 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4246
4247 {},
4248
4249 {{"hybrid_disp", hybrid_disp}},
4250
4251 {},
4252
4253 {}
4254
4255 )
4256
4257 );
4258
4259 if (f_residual) {
4260 auto hybrid_res = boost::make_shared<MatrixDouble>();
4261 post_proc_ptr->getOpPtrVector().push_back(
4263 hybridSpatialDisp, hybrid_res,
4264 SmartPetscObj<Vec>(f_residual, true)));
4266 post_proc_ptr->getOpPtrVector().push_back(
4267
4268 new OpPPMap(
4269
4270 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4271
4272 {},
4273
4274 {{"res_hybrid", hybrid_res}},
4275
4276 {},
4277
4278 {}
4279
4280 )
4281
4282 );
4283 }
4284
4285 post_proc_ptr->setTagsToTransfer(tags_to_transfer);
4286
4287 auto post_proc_begin =
4289 CHKERR DMoFEMPreProcessFiniteElements(dM, post_proc_begin.getFEMethod());
4291 auto post_proc_end = PostProcBrokenMeshInMoabBaseEnd(mField, post_proc_mesh);
4292 CHKERR DMoFEMPostProcessFiniteElements(dM, post_proc_end.getFEMethod());
4293
4294 CHKERR post_proc_end.writeFile(file.c_str());
4295
4297}

◆ projectGeometry()

MoFEMErrorCode EshelbianCore::projectGeometry ( const EntityHandle meshset = 0)

Definition at line 1403 of file EshelbianPlasticity.cpp.

1403 {
1405
1406 Range meshset_ents;
1407 CHKERR mField.get_moab().get_entities_by_handle(meshset, meshset_ents);
1408
1409 auto project_ho_geometry = [&](auto field) {
1411 return mField.loop_dofs(field, ent_method);
1412 };
1413 CHKERR project_ho_geometry(materialH1Positions);
1414
1415 auto get_adj_front_edges = [&](auto &front_edges) {
1416 Range front_crack_nodes;
1417 Range crack_front_edges_with_both_nodes_not_at_front;
1418
1419 if (mField.get_comm_rank() == 0) {
1420 auto &moab = mField.get_moab();
1421 CHKERR moab.get_connectivity(front_edges, front_crack_nodes, true);
1422 Range crack_front_edges;
1423 CHKERR moab.get_adjacencies(front_crack_nodes, SPACE_DIM - 2, false,
1424 crack_front_edges, moab::Interface::UNION);
1425 crack_front_edges =
1426 intersect(subtract(crack_front_edges, front_edges), meshset_ents);
1427 Range crack_front_edges_nodes;
1428 CHKERR moab.get_connectivity(crack_front_edges, crack_front_edges_nodes,
1429 true);
1430 crack_front_edges_nodes =
1431 subtract(crack_front_edges_nodes, front_crack_nodes);
1432 CHKERR moab.get_adjacencies(
1433 crack_front_edges_nodes, SPACE_DIM - 2, false,
1434 crack_front_edges_with_both_nodes_not_at_front,
1435 moab::Interface::UNION);
1436 crack_front_edges_with_both_nodes_not_at_front = intersect(
1437 crack_front_edges_with_both_nodes_not_at_front, meshset_ents);
1438 crack_front_edges_with_both_nodes_not_at_front = intersect(
1439 crack_front_edges_with_both_nodes_not_at_front, crack_front_edges);
1440 }
1441
1442 front_crack_nodes = send_type(mField, front_crack_nodes, MBVERTEX);
1443 crack_front_edges_with_both_nodes_not_at_front = send_type(
1444 mField, crack_front_edges_with_both_nodes_not_at_front, MBEDGE);
1445
1446 return std::make_pair(boost::make_shared<Range>(front_crack_nodes),
1447 boost::make_shared<Range>(
1448 crack_front_edges_with_both_nodes_not_at_front));
1449 };
1450
1451 crackFaces = boost::make_shared<Range>(
1452 get_range_from_block(mField, "CRACK", SPACE_DIM - 1));
1453 frontEdges =
1454 boost::make_shared<Range>(get_crack_front_edges(mField, *crackFaces));
1455 auto [front_vertices, front_adj_edges] = get_adj_front_edges(*frontEdges);
1456 frontVertices = front_vertices;
1457 frontAdjEdges = front_adj_edges;
1458
1459#ifndef NDEBUG
1460 if (crackingOn) {
1461 auto rank = mField.get_comm_rank();
1462 // CHKERR save_range(mField.get_moab(),
1463 // (boost::format("meshset_ents_%d.vtk") % rank).str(),
1464 // meshset_ents);
1466 (boost::format("crack_faces_%d.vtk") % rank).str(),
1467 *crackFaces);
1469 (boost::format("front_edges_%d.vtk") % rank).str(),
1470 *frontEdges);
1471 // CHKERR save_range(mField.get_moab(),
1472 // (boost::format("front_vertices_%d.vtk") % rank).str(),
1473 // *frontVertices);
1474 // CHKERR save_range(mField.get_moab(),
1475 // (boost::format("front_adj_edges_%d.vtk") % rank).str(),
1476 // *frontAdjEdges);
1477 }
1478#endif // NDEBUG
1479
1480 auto set_singular_dofs = [&](auto &front_adj_edges, auto &front_vertices) {
1482 auto &moab = mField.get_moab();
1483
1484 double eps = 1;
1485 double beta = 0;
1486 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "-singularity_eps", &beta,
1487 PETSC_NULLPTR);
1488 MOFEM_LOG("EP", Sev::inform) << "Singularity eps " << beta;
1489 eps -= beta;
1490
1491 for (auto edge : front_adj_edges) {
1492 int num_nodes;
1493 const EntityHandle *conn;
1494 CHKERR moab.get_connectivity(edge, conn, num_nodes, false);
1495 double coords[6];
1496 CHKERR moab.get_coords(conn, num_nodes, coords);
1497 const double dir[3] = {coords[3] - coords[0], coords[4] - coords[1],
1498 coords[5] - coords[2]};
1499 double dof[3] = {0, 0, 0};
1500 if (front_vertices.find(conn[0]) != front_vertices.end()) {
1501 for (int dd = 0; dd != 3; dd++) {
1502 dof[dd] = -dir[dd] * eps;
1503 }
1504 } else if (front_vertices.find(conn[1]) != front_vertices.end()) {
1505 for (int dd = 0; dd != 3; dd++) {
1506 dof[dd] = +dir[dd] * eps;
1507 }
1508 }
1510 mField, materialH1Positions, edge, dit)) {
1511 const int idx = dit->get()->getEntDofIdx();
1512 if (idx > 2) {
1513 dit->get()->getFieldData() = 0;
1514 } else {
1515 dit->get()->getFieldData() = dof[idx];
1516 }
1517 }
1518 }
1519
1521 };
1522
1523 if (setSingularity)
1524 CHKERR set_singular_dofs(*frontAdjEdges, *frontVertices);
1525
1527}
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 895 of file EshelbianPlasticity.cpp.

896 {
897 *iface = const_cast<EshelbianCore *>(this);
898 return 0;
899}

◆ saveOrgCoords()

MoFEMErrorCode EshelbianCore::saveOrgCoords ( )

Definition at line 6678 of file EshelbianPlasticity.cpp.

6678 {
6680 auto crack_faces =
6681 get_range_from_block(mField, "CRACK_COMPUTED", SPACE_DIM - 1);
6682 Range conn;
6683 CHKERR mField.get_moab().get_connectivity(crack_faces, conn, true);
6684 Range verts;
6685 CHKERR mField.get_moab().get_entities_by_type(0, MBVERTEX, verts);
6686 verts = subtract(verts, conn);
6687 std::vector<double> coords(3 * verts.size());
6688 CHKERR mField.get_moab().get_coords(verts, coords.data());
6689 double def_coords[] = {0., 0., 0.};
6690 Tag th_org_coords;
6691 CHKERR mField.get_moab().tag_get_handle(
6692 "ORG_COORDS", 3, MB_TYPE_DOUBLE, th_org_coords,
6693 MB_TAG_CREAT | MB_TAG_DENSE, def_coords);
6694 CHKERR mField.get_moab().tag_set_data(th_org_coords, verts, coords.data());
6696}

◆ setBaseVolumeElementOps()

MoFEMErrorCode EshelbianPlasticity::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 )

Definition at line 2317 of file EshelbianPlasticity.cpp.

2320 {
2322
2323 auto bubble_cache =
2324 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0, MatrixDouble());
2325 fe->getUserPolynomialBase() =
2326 boost::make_shared<CGGUserPolynomialBase>(bubble_cache);
2328 fe->getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions, frontAdjEdges);
2329
2330 // set integration rule
2331 fe->getRuleHook = [](int, int, int) { return -1; };
2332 fe->setRuleHook = SetIntegrationAtFrontVolume(frontVertices, frontAdjEdges);
2333 // fe->getRuleHook = VolRule();
2334
2335 if (!dataAtPts) {
2336 dataAtPts =
2337 boost::shared_ptr<DataAtIntegrationPts>(new DataAtIntegrationPts());
2338 dataAtPts->physicsPtr = physicalEquations;
2339 }
2340
2341 // calculate fields values
2342 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
2343 piolaStress, dataAtPts->getApproxPAtPts()));
2344 fe->getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
2345 bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
2346 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorDivergence<3, 3>(
2347 piolaStress, dataAtPts->getDivPAtPts()));
2348
2349 if (noStretch) {
2350 fe->getOpPtrVector().push_back(
2351 physicalEquations->returnOpCalculateStretchFromStress(
2353 } else {
2354 fe->getOpPtrVector().push_back(
2356 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
2357 }
2358
2359 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2360 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
2361 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2362 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
2363 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2364 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
2365
2366 // H1 displacements
2367 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2368 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
2369 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldGradient<3, 3>(
2370 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
2371
2372 // velocities
2373 if (calc_rates) {
2374 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValuesDot<3>(
2375 spatialL2Disp, dataAtPts->getSmallWL2DotAtPts(), MBTET));
2376 if (noStretch) {
2377 } else {
2378 fe->getOpPtrVector().push_back(
2380 stretchTensor, dataAtPts->getLogStretchDotTensorAtPts(), MBTET));
2381 fe->getOpPtrVector().push_back(
2383 stretchTensor, dataAtPts->getGradLogStretchDotTensorAtPts(),
2384 MBTET));
2385 }
2386 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValuesDot<3>(
2387 rotAxis, dataAtPts->getRotAxisDotAtPts(), MBTET));
2388 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldGradientDot<3, 3>(
2389 rotAxis, dataAtPts->getRotAxisGradDotAtPts(), MBTET));
2390
2391 // acceleration
2392 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
2393 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValuesDotDot<3>(
2394 spatialL2Disp, dataAtPts->getSmallWL2DotDotAtPts(), MBTET));
2395 }
2396 }
2397
2398 // variations
2399 if (var_vec.use_count()) {
2400 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
2401 piolaStress, dataAtPts->getVarPiolaPts(), boost::make_shared<double>(1),
2402 var_vec));
2403 fe->getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
2404 bubbleField, dataAtPts->getVarPiolaPts(), boost::make_shared<double>(1),
2405 var_vec, MBMAXTYPE));
2406 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2407 rotAxis, dataAtPts->getVarRotAxisPts(), var_vec, MBTET));
2408 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorDivergence<3, 3>(
2409 piolaStress, dataAtPts->getDivVarPiolaPts(), var_vec));
2410 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2411 spatialL2Disp, dataAtPts->getVarWL2Pts(), var_vec, MBTET));
2412
2413 if (noStretch) {
2414 fe->getOpPtrVector().push_back(
2415 physicalEquations->returnOpCalculateVarStretchFromStress(
2417 } else {
2418 fe->getOpPtrVector().push_back(
2420 stretchTensor, dataAtPts->getVarLogStreachPts(), var_vec, MBTET));
2421 }
2422 }
2423
2424 // calculate other derived quantities
2425 fe->getOpPtrVector().push_back(new OpCalculateRotationAndSpatialGradient(
2426 dataAtPts, ((do_rhs || do_lhs) && calc_rates) ? alphaOmega : 0.));
2427
2428 // evaluate integration points
2429 if (noStretch) {
2430 } else {
2431 fe->getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
2432 tag, do_rhs, do_lhs, dataAtPts, physicalEquations));
2433 }
2434
2436}
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 ( )

Definition at line 3662 of file EshelbianPlasticity.cpp.

3662 {
3664
3665 auto set_block = [&](auto name, int dim) {
3666 std::map<int, Range> map;
3667 auto set_tag_impl = [&](auto name) {
3669 auto mesh_mng = mField.getInterface<MeshsetsManager>();
3670 auto bcs = mesh_mng->getCubitMeshsetPtr(
3671
3672 std::regex((boost::format("%s(.*)") % name).str())
3673
3674 );
3675 for (auto bc : bcs) {
3676 Range r;
3677 CHKERR bc->getMeshsetIdEntitiesByDimension(mField.get_moab(), dim, r,
3678 true);
3679 map[bc->getMeshsetId()] = r;
3680 }
3682 };
3683
3684 CHKERR set_tag_impl(name);
3685
3686 return std::make_pair(name, map);
3687 };
3688
3689 auto set_skin = [&](auto &&map) {
3690 for (auto &m : map.second) {
3691 auto s = filter_true_skin(mField, get_skin(mField, m.second));
3692 m.second.swap(s);
3693 }
3694 return map;
3695 };
3696
3697 auto set_tag = [&](auto &&map) {
3698 Tag th;
3699 auto name = map.first;
3700 int def_val[] = {-1};
3702 mField.get_moab().tag_get_handle(name, 1, MB_TYPE_INTEGER, th,
3703 MB_TAG_SPARSE | MB_TAG_CREAT, def_val),
3704 "create tag");
3705 for (auto &m : map.second) {
3706 int id = m.first;
3707 CHK_MOAB_THROW(mField.get_moab().tag_clear_data(th, m.second, &id),
3708 "clear tag");
3709 }
3710 return th;
3711 };
3712
3713 listTagsToTransfer.push_back(set_tag(set_skin(set_block("BODY", 3))));
3714 listTagsToTransfer.push_back(set_tag(set_skin(set_block("MAT_ELASTIC", 3))));
3715 listTagsToTransfer.push_back(
3716 set_tag(set_skin(set_block("MAT_NEOHOOKEAN", 3))));
3717 listTagsToTransfer.push_back(set_tag(set_block("CONTACT", 2)));
3718
3720}

◆ setContactElementRhsOps()

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

Contact requires that body is marked

Definition at line 3089 of file EshelbianPlasticity.cpp.

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

◆ setElasticElementOps()

MoFEMErrorCode EshelbianPlasticity::EshelbianCore::setElasticElementOps ( const int tag)

Definition at line 3188 of file EshelbianPlasticity.cpp.

3188 {
3190
3191 // Add contact operators. Note that only for rhs. THe lhs is assembled with
3192 // volume element, to enable schur complement evaluation.
3194
3197
3198 auto adj_cache =
3199 boost::make_shared<ForcesAndSourcesCore::UserDataOperator::AdjCache>();
3200
3201 auto get_op_contact_bc = [&]() {
3203 auto op_loop_side = new OpLoopSide<SideEle>(
3204 mField, contactElement, SPACE_DIM - 1, Sev::noisy, adj_cache);
3205 return op_loop_side;
3206 };
3207
3209}
ElementsAndOps< SPACE_DIM >::SideEle SideEle
Definition plastic.cpp:61
boost::shared_ptr< FaceElementForcesAndSourcesCore > elasticBcLhs
boost::shared_ptr< VolumeElementForcesAndSourcesCore > elasticFeLhs
boost::shared_ptr< VolumeElementForcesAndSourcesCore > elasticFeRhs
MoFEMErrorCode setFaceElementOps(const bool add_elastic, const bool add_material, boost::shared_ptr< FaceElementForcesAndSourcesCore > &fe_rhs, boost::shared_ptr< FaceElementForcesAndSourcesCore > &fe_lhs)
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 setContactElementRhsOps(boost::shared_ptr< ContactTree > &fe_contact_tree)
boost::shared_ptr< FaceElementForcesAndSourcesCore > elasticBcRhs

◆ setElasticElementToTs()

MoFEMErrorCode EshelbianCore::setElasticElementToTs ( DM dm)

Definition at line 3211 of file EshelbianPlasticity.cpp.

3211 {
3213 boost::shared_ptr<FEMethod> null;
3214
3215 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
3216
3218 null);
3220 null);
3222 null);
3224 null);
3225
3226 } else {
3228 null);
3230 null);
3232 null);
3234 null);
3235 }
3236
3238}
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 EshelbianPlasticity::EshelbianCore::setFaceElementOps ( const bool add_elastic,
const bool add_material,
boost::shared_ptr< FaceElementForcesAndSourcesCore > & fe_rhs,
boost::shared_ptr< FaceElementForcesAndSourcesCore > & fe_lhs )

Definition at line 2930 of file EshelbianPlasticity.cpp.

2933 {
2935
2936 fe_rhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
2937 fe_lhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
2938
2939 // set integration rule
2940 // fe_rhs->getRuleHook = [](int, int, int p) { return 2 * (p + 1); };
2941 // fe_lhs->getRuleHook = [](int, int, int p) { return 2 * (p + 1); };
2942 fe_rhs->getRuleHook = [](int, int, int) { return -1; };
2943 fe_lhs->getRuleHook = [](int, int, int) { return -1; };
2944 fe_rhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
2945 fe_lhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
2946
2947 CHKERR
2949 fe_rhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
2950 CHKERR
2952 fe_lhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
2953
2954 if (add_elastic) {
2955
2956 auto get_broken_op_side = [this](auto &pip) {
2957 using EleOnSide =
2959 using SideEleOp = EleOnSide::UserDataOperator;
2960 // Iterate over domain FEs adjacent to boundary.
2961 auto broken_data_ptr =
2962 boost::make_shared<std::vector<BrokenBaseSideData>>();
2963 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
2964 auto op_loop_domain_side = new OpLoopSide<EleOnSide>(
2965 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
2966 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2967 boost::make_shared<CGGUserPolynomialBase>();
2968 CHKERR
2970 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2972 op_loop_domain_side->getOpPtrVector().push_back(
2973 new OpGetBrokenBaseSideData<SideEleOp>(piolaStress, broken_data_ptr));
2974 boost::shared_ptr<double> piola_scale_ptr(new double);
2975 op_loop_domain_side->getOpPtrVector().push_back(
2976 physicalEquations->returnOpSetScale(piola_scale_ptr,
2978
2979 auto piola_stress_mat_ptr = boost::make_shared<MatrixDouble>();
2980 op_loop_domain_side->getOpPtrVector().push_back(
2982 piola_stress_mat_ptr));
2983 pip.push_back(op_loop_domain_side);
2984 return std::make_tuple(broken_data_ptr, piola_scale_ptr,
2985 piola_stress_mat_ptr);
2986 };
2987
2988 auto set_rhs = [&]() {
2990
2991 auto [broken_data_ptr, piola_scale_ptr, piola_stress_mat_ptr] =
2992 get_broken_op_side(fe_rhs->getOpPtrVector());
2993
2994 fe_rhs->getOpPtrVector().push_back(
2995 new OpDispBc(broken_data_ptr, bcSpatialDispVecPtr, timeScaleMap));
2996 fe_rhs->getOpPtrVector().push_back(new OpAnalyticalDispBc(
2998 timeScaleMap));
2999 fe_rhs->getOpPtrVector().push_back(new OpRotationBc(
3000 broken_data_ptr, bcSpatialRotationVecPtr, timeScaleMap));
3001
3002 fe_rhs->getOpPtrVector().push_back(
3004 piola_scale_ptr, timeScaleMap));
3005 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
3006 // if you push gradient of L2 base to physical element, it will not work.
3007 fe_rhs->getOpPtrVector().push_back(
3009 hybridSpatialDisp, hybrid_grad_ptr));
3010 fe_rhs->getOpPtrVector().push_back(new OpBrokenPressureBc(
3012 hybrid_grad_ptr, timeScaleMap));
3013 fe_rhs->getOpPtrVector().push_back(new OpBrokenAnalyticalTractionBc(
3015 timeScaleMap));
3016
3017 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3018 fe_rhs->getOpPtrVector().push_back(
3020 hybrid_ptr));
3021 fe_rhs->getOpPtrVector().push_back(new OpNormalDispRhsBc(
3022 hybridSpatialDisp, hybrid_ptr, piola_stress_mat_ptr,
3024
3025 auto get_normal_disp_bc_faces = [&]() {
3026 auto faces =
3027 get_range_from_block(mField, "NORMAL_DISPLACEMENT", SPACE_DIM - 1);
3028 return boost::make_shared<Range>(faces);
3029 };
3030
3031 using BoundaryEle =
3033 using BdyEleOp = BoundaryEle::UserDataOperator;
3035 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
3036 fe_rhs->getOpPtrVector().push_back(new OpC_dBroken(
3037 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0),
3038 get_normal_disp_bc_faces()));
3039
3041 };
3042
3043 auto set_lhs = [&]() {
3045
3046 auto [broken_data_ptr, piola_scale_ptr, piola_stress_mat_ptr] =
3047 get_broken_op_side(fe_lhs->getOpPtrVector());
3048
3049 fe_lhs->getOpPtrVector().push_back(new OpNormalDispLhsBc_dU(
3051 fe_lhs->getOpPtrVector().push_back(new OpNormalDispLhsBc_dP(
3053 timeScaleMap));
3054
3055 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
3056 // if you push gradient of L2 base to physical element, it will not work.
3057 fe_rhs->getOpPtrVector().push_back(
3059 hybridSpatialDisp, hybrid_grad_ptr));
3060 fe_lhs->getOpPtrVector().push_back(new OpBrokenPressureBcLhs_dU(
3062 timeScaleMap));
3063
3064 auto get_normal_disp_bc_faces = [&]() {
3065 auto faces =
3066 get_range_from_block(mField, "NORMAL_DISPLACEMENT", SPACE_DIM - 1);
3067 return boost::make_shared<Range>(faces);
3068 };
3069
3070 using BoundaryEle =
3072 using BdyEleOp = BoundaryEle::UserDataOperator;
3074 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
3075 fe_lhs->getOpPtrVector().push_back(new OpC(
3076 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0),
3077 true, true, get_normal_disp_bc_faces()));
3078
3080 };
3081
3082 CHKERR set_rhs();
3083 CHKERR set_lhs();
3084 }
3085
3087}
Apply rotation boundary condition.
BoundaryEle::UserDataOperator BdyEleOp

◆ setNewFrontCoordinates()

MoFEMErrorCode EshelbianPlasticity::EshelbianCore::setNewFrontCoordinates ( )

Definition at line 5902 of file EshelbianPlasticity.cpp.

5902 {
5904
5905 if (!maxMovedFaces)
5907
5908 Tag th_front_position;
5909 auto rval =
5910 mField.get_moab().tag_get_handle("FrontPosition", th_front_position);
5911 if (rval == MB_SUCCESS && maxMovedFaces) {
5912 Range verts;
5913 CHKERR mField.get_moab().get_connectivity(*maxMovedFaces, verts, true);
5914 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(verts);
5915 std::vector<double> coords(3 * verts.size());
5916 CHKERR mField.get_moab().get_coords(verts, coords.data());
5917 std::vector<double> pos(3 * verts.size());
5918 CHKERR mField.get_moab().tag_get_data(th_front_position, verts, pos.data());
5919 for (int i = 0; i != 3 * verts.size(); ++i) {
5920 coords[i] += pos[i];
5921 }
5922 CHKERR mField.get_moab().set_coords(verts, coords.data());
5923 double zero[] = {0., 0., 0.};
5924 CHKERR mField.get_moab().tag_clear_data(th_front_position, verts, zero);
5925 }
5926
5927#ifndef NDEBUG
5928 constexpr bool debug = false;
5929 if (debug) {
5930
5932 mField.get_moab(),
5933 "set_coords_faces_" +
5934 boost::lexical_cast<std::string>(mField.get_comm_rank()) + ".vtk",
5935 *maxMovedFaces);
5936 }
5937#endif
5939}

◆ 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

Definition at line 2438 of file EshelbianPlasticity.cpp.

2441 {
2443
2444 /** Contact requires that body is marked */
2445 auto get_body_range = [this](auto name, int dim) {
2446 std::map<int, Range> map;
2447
2448 for (auto m_ptr :
2450
2451 (boost::format("%s(.*)") % name).str()
2452
2453 ))
2454
2455 ) {
2456 Range ents;
2457 CHK_MOAB_THROW(m_ptr->getMeshsetIdEntitiesByDimension(mField.get_moab(),
2458 dim, ents, true),
2459 "by dim");
2460 map[m_ptr->getMeshsetId()] = ents;
2461 }
2462
2463 return map;
2464 };
2465
2466 auto rule_contact = [](int, int, int o) { return -1; };
2468
2469 auto set_rule_contact = [refine](
2470
2471 ForcesAndSourcesCore *fe_raw_ptr, int order_row,
2472 int order_col, int order_data
2473
2474 ) {
2476 auto rule = 2 * order_data;
2477 fe_raw_ptr->gaussPts = Tools::refineTriangleIntegrationPts(rule, refine);
2479 };
2480
2481 // Right hand side
2482 fe_rhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
2483 CHKERR setBaseVolumeElementOps(tag, true, false, true, SmartPetscObj<Vec>(),
2484 fe_rhs);
2485
2486 // elastic
2487 if (add_elastic) {
2488
2489 fe_rhs->getOpPtrVector().push_back(
2491 fe_rhs->getOpPtrVector().push_back(
2493 if (noStretch) {
2494 // do nothing - no stretch approximation
2495 } else {
2496 if (!internalStressTagName.empty()) {
2497 switch (internalStressInterpOrder) {
2498 case 0:
2499 fe_rhs->getOpPtrVector().push_back(
2501 break;
2502 case 1:
2503 fe_rhs->getOpPtrVector().push_back(
2505 break;
2506 default:
2507 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
2508 "Unsupported internal stress interpolation order %d",
2510 }
2511 if (internalStressVoigt) {
2512 fe_rhs->getOpPtrVector().push_back(
2514 dataAtPts));
2515 } else {
2516 fe_rhs->getOpPtrVector().push_back(
2518 dataAtPts));
2519 }
2520 }
2521 if (auto op = physicalEquations->returnOpSpatialPhysicalExternalStrain(
2523 fe_rhs->getOpPtrVector().push_back(op);
2524 } else if (externalStrainVecPtr && !externalStrainVecPtr->empty()) {
2525 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
2526 "OpSpatialPhysicalExternalStrain not implemented for this "
2527 "material");
2528 }
2529
2530 fe_rhs->getOpPtrVector().push_back(
2531 physicalEquations->returnOpSpatialPhysical(stretchTensor, dataAtPts,
2532 alphaU));
2533 }
2534 fe_rhs->getOpPtrVector().push_back(
2536 fe_rhs->getOpPtrVector().push_back(
2538 fe_rhs->getOpPtrVector().push_back(
2540
2541 auto set_hybridisation = [&](auto &pip) {
2543
2544 using BoundaryEle =
2546 using EleOnSide =
2548 using SideEleOp = EleOnSide::UserDataOperator;
2549 using BdyEleOp = BoundaryEle::UserDataOperator;
2550
2551 // First: Iterate over skeleton FEs adjacent to Domain FEs
2552 // Note: BoundaryEle, i.e. uses skeleton interation rule
2553 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
2554 mField, skeletonElement, SPACE_DIM - 1, Sev::noisy);
2555 // op_loop_skeleton_side->getSideFEPtr()->getRuleHook = FaceRule();
2556 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
2557 return -1;
2558 };
2559 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
2560 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
2561
2562 CHKERR EshelbianPlasticity::
2563 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2564 op_loop_skeleton_side->getOpPtrVector(), {L2},
2566
2567 // Second: Iterate over domain FEs adjacent to skelton, particularly one
2568 // domain element.
2569 auto broken_data_ptr =
2570 boost::make_shared<std::vector<BrokenBaseSideData>>();
2571 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
2572 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
2573 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
2574 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2575 boost::make_shared<CGGUserPolynomialBase>();
2576 CHKERR
2578 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2580 op_loop_domain_side->getOpPtrVector().push_back(
2581 new OpGetBrokenBaseSideData<SideEleOp>(piolaStress, broken_data_ptr));
2582 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
2583 op_loop_domain_side->getOpPtrVector().push_back(
2585 flux_mat_ptr));
2586 op_loop_domain_side->getOpPtrVector().push_back(
2587 new OpSetFlux<SideEleOp>(broken_data_ptr, flux_mat_ptr));
2588
2589 // Assemble on skeleton
2590 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
2592 GAUSS>::OpBrokenSpaceConstrainDHybrid<SPACE_DIM>;
2594 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
2595 op_loop_skeleton_side->getOpPtrVector().push_back(new OpC_dHybrid(
2596 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0)));
2597 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
2598 op_loop_skeleton_side->getOpPtrVector().push_back(
2600 hybrid_ptr));
2601 op_loop_skeleton_side->getOpPtrVector().push_back(new OpC_dBroken(
2602 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0)));
2603
2604 // Add skeleton to domain pipeline
2605 pip.push_back(op_loop_skeleton_side);
2606
2608 };
2609
2610 auto set_contact = [&](auto &pip) {
2612
2613 using BoundaryEle =
2615 using EleOnSide =
2617 using SideEleOp = EleOnSide::UserDataOperator;
2618 using BdyEleOp = BoundaryEle::UserDataOperator;
2619
2620 // First: Iterate over skeleton FEs adjacent to Domain FEs
2621 // Note: BoundaryEle, i.e. uses skeleton interation rule
2622 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
2623 mField, contactElement, SPACE_DIM - 1, Sev::noisy);
2624
2625 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
2626 op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
2627 CHKERR EshelbianPlasticity::
2628 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2629 op_loop_skeleton_side->getOpPtrVector(), {L2},
2631
2632 // Second: Iterate over domain FEs adjacent to skelton, particularly
2633 // one domain element.
2634 auto broken_data_ptr =
2635 boost::make_shared<std::vector<BrokenBaseSideData>>();
2636
2637 // Data storing contact fields
2638 auto contact_common_data_ptr =
2639 boost::make_shared<ContactOps::CommonData>();
2640
2641 auto add_ops_domain_side = [&](auto &pip) {
2643 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
2644 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
2645 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
2646 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2647 boost::make_shared<CGGUserPolynomialBase>();
2648 CHKERR
2650 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2652 op_loop_domain_side->getOpPtrVector().push_back(
2654 broken_data_ptr));
2655 op_loop_domain_side->getOpPtrVector().push_back(
2657 piolaStress, contact_common_data_ptr->contactTractionPtr()));
2658 pip.push_back(op_loop_domain_side);
2660 };
2661
2662 auto add_ops_contact_rhs = [&](auto &pip) {
2664 // get body id and SDF range
2665 auto contact_sfd_map_range_ptr =
2666 boost::make_shared<std::map<int, Range>>(
2667 get_body_range("CONTACT_SDF", SPACE_DIM - 1));
2668
2669 pip.push_back(new OpCalculateVectorFieldValues<3>(
2670 contactDisp, contact_common_data_ptr->contactDispPtr()));
2671 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2672 pip.push_back(
2674 pip.push_back(new OpTreeSearch(
2675 contactTreeRhs, contact_common_data_ptr, u_h1_ptr,
2676 get_range_from_block(mField, "CONTACT", SPACE_DIM - 1), nullptr,
2677 nullptr));
2679 contactDisp, contact_common_data_ptr, contactTreeRhs,
2680 contact_sfd_map_range_ptr));
2681 pip.push_back(
2683 broken_data_ptr, contact_common_data_ptr, contactTreeRhs));
2684
2686 };
2687
2688 // push ops to face/side pipeline
2689 CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
2690 CHKERR add_ops_contact_rhs(op_loop_skeleton_side->getOpPtrVector());
2691
2692 // Add skeleton to domain pipeline
2693 pip.push_back(op_loop_skeleton_side);
2694
2696 };
2697
2698 CHKERR set_hybridisation(fe_rhs->getOpPtrVector());
2699 CHKERR set_contact(fe_rhs->getOpPtrVector());
2700
2701 // Body forces
2702 using BodyNaturalBC =
2704 Assembly<PETSC>::LinearForm<GAUSS>;
2705 using OpBodyForce =
2706 BodyNaturalBC::OpFlux<NaturalMeshsetType<BLOCKSET>, 1, 3>;
2707
2708 auto body_time_scale =
2709 boost::make_shared<DynamicRelaxationTimeScale>("body_force.txt");
2710 CHKERR BodyNaturalBC::AddFluxToPipeline<OpBodyForce>::add(
2711 fe_rhs->getOpPtrVector(), mField, spatialL2Disp, {body_time_scale},
2712 "BODY_FORCE", Sev::inform);
2713 }
2714
2715 // Left hand side
2716 fe_lhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
2717 CHKERR setBaseVolumeElementOps(tag, true, true, true, SmartPetscObj<Vec>(),
2718 fe_lhs);
2719
2720 // elastic
2721 if (add_elastic) {
2722
2723 if (noStretch) {
2724 fe_lhs->getOpPtrVector().push_back(
2726 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dBubble_dP(
2728 fe_lhs->getOpPtrVector().push_back(
2730 dataAtPts));
2731 } else {
2732 fe_lhs->getOpPtrVector().push_back(
2733 physicalEquations->returnOpSpatialPhysical_du_du(
2735 fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_dP(
2737 fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_dBubble(
2739 fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_domega(
2741 symmetrySelector == SYMMETRIC ? true : false));
2742 }
2743
2744 fe_lhs->getOpPtrVector().push_back(new OpSpatialEquilibrium_dw_dP(
2746 fe_lhs->getOpPtrVector().push_back(new OpSpatialEquilibrium_dw_dw(
2748
2749 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dP_domega(
2751 symmetrySelector == SYMMETRIC ? true : false));
2752 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dBubble_domega(
2754 symmetrySelector == SYMMETRIC ? true : false));
2755
2757 if (!noStretch) {
2758 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_du(
2759 rotAxis, stretchTensor, dataAtPts, false));
2760 }
2761 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_dP(
2762 rotAxis, piolaStress, dataAtPts, false));
2763 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_dBubble(
2764 rotAxis, bubbleField, dataAtPts, false));
2765 }
2766 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_domega(
2768
2769 // stabilise
2770 fe_lhs->getOpPtrVector().push_back(new OpAssembleVolumeStabilize());
2771
2772
2773 auto set_hybridisation = [&](auto &pip) {
2775
2776 using BoundaryEle =
2778 using EleOnSide =
2780 using SideEleOp = EleOnSide::UserDataOperator;
2781 using BdyEleOp = BoundaryEle::UserDataOperator;
2782
2783 // First: Iterate over skeleton FEs adjacent to Domain FEs
2784 // Note: BoundaryEle, i.e. uses skeleton interation rule
2785 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
2786 mField, skeletonElement, SPACE_DIM - 1, Sev::noisy);
2787 // op_loop_skeleton_side->getSideFEPtr()->getRuleHook = FaceRule();
2788 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
2789 return -1;
2790 };
2791 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
2792 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
2793 CHKERR EshelbianPlasticity::
2794 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2795 op_loop_skeleton_side->getOpPtrVector(), {L2},
2797
2798 // Second: Iterate over domain FEs adjacent to skelton, particularly one
2799 // domain element.
2800 auto broken_data_ptr =
2801 boost::make_shared<std::vector<BrokenBaseSideData>>();
2802 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
2803 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
2804 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
2805 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2806 boost::make_shared<CGGUserPolynomialBase>();
2807 CHKERR
2809 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2811 op_loop_domain_side->getOpPtrVector().push_back(
2812 new OpGetBrokenBaseSideData<SideEleOp>(piolaStress, broken_data_ptr));
2813
2814 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
2816 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
2817 op_loop_skeleton_side->getOpPtrVector().push_back(
2818 new OpC(hybridSpatialDisp, broken_data_ptr,
2819 boost::make_shared<double>(1.0), true, false));
2820
2821 pip.push_back(op_loop_skeleton_side);
2822
2824 };
2825
2826 auto set_contact = [&](auto &pip) {
2828
2829 using BoundaryEle =
2831 using EleOnSide =
2833 using SideEleOp = EleOnSide::UserDataOperator;
2834 using BdyEleOp = BoundaryEle::UserDataOperator;
2835
2836 // First: Iterate over skeleton FEs adjacent to Domain FEs
2837 // Note: BoundaryEle, i.e. uses skeleton interation rule
2838 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
2839 mField, contactElement, SPACE_DIM - 1, Sev::noisy);
2840
2841 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
2842 op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
2843 CHKERR EshelbianPlasticity::
2844 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2845 op_loop_skeleton_side->getOpPtrVector(), {L2},
2847
2848 // Second: Iterate over domain FEs adjacent to skelton, particularly
2849 // one domain element.
2850 auto broken_data_ptr =
2851 boost::make_shared<std::vector<BrokenBaseSideData>>();
2852
2853 // Data storing contact fields
2854 auto contact_common_data_ptr =
2855 boost::make_shared<ContactOps::CommonData>();
2856
2857 auto add_ops_domain_side = [&](auto &pip) {
2859 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
2860 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
2861 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
2862 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2863 boost::make_shared<CGGUserPolynomialBase>();
2864 CHKERR
2866 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2868 op_loop_domain_side->getOpPtrVector().push_back(
2870 broken_data_ptr));
2871 op_loop_domain_side->getOpPtrVector().push_back(
2873 piolaStress, contact_common_data_ptr->contactTractionPtr()));
2874 pip.push_back(op_loop_domain_side);
2876 };
2877
2878 auto add_ops_contact_lhs = [&](auto &pip) {
2880 pip.push_back(new OpCalculateVectorFieldValues<3>(
2881 contactDisp, contact_common_data_ptr->contactDispPtr()));
2882 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2883 pip.push_back(
2885 pip.push_back(new OpTreeSearch(
2886 contactTreeRhs, contact_common_data_ptr, u_h1_ptr,
2887 get_range_from_block(mField, "CONTACT", SPACE_DIM - 1), nullptr,
2888 nullptr));
2889
2890 // get body id and SDF range
2891 auto contact_sfd_map_range_ptr =
2892 boost::make_shared<std::map<int, Range>>(
2893 get_body_range("CONTACT_SDF", SPACE_DIM - 1));
2894
2896 contactDisp, contactDisp, contact_common_data_ptr, contactTreeRhs,
2897 contact_sfd_map_range_ptr));
2898 pip.push_back(
2900 contactDisp, broken_data_ptr, contact_common_data_ptr,
2901 contactTreeRhs, contact_sfd_map_range_ptr));
2902 pip.push_back(
2904 broken_data_ptr, contactDisp, contact_common_data_ptr,
2906
2908 };
2909
2910 // push ops to face/side pipeline
2911 CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
2912 CHKERR add_ops_contact_lhs(op_loop_skeleton_side->getOpPtrVector());
2913
2914 // Add skeleton to domain pipeline
2915 pip.push_back(op_loop_skeleton_side);
2916
2918 };
2919
2920 CHKERR set_hybridisation(fe_lhs->getOpPtrVector());
2921 CHKERR set_contact(fe_lhs->getOpPtrVector());
2922 }
2923
2924 if (add_material) {
2925 }
2926
2928}
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 )

Definition at line 3571 of file EshelbianPlasticity.cpp.

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

◆ solveElastic()

MoFEMErrorCode EshelbianCore::solveElastic ( TS ts,
Vec x )

Definition at line 3441 of file EshelbianPlasticity.cpp.

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

Member Data Documentation

◆ a00FieldList

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

Definition at line 447 of file EshelbianPlasticity.hpp.

◆ a00RangeList

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

Definition at line 449 of file EshelbianPlasticity.hpp.

◆ addCrackMeshsetId

int EshelbianPlasticity::EshelbianCore::addCrackMeshsetId = 1000
inlinestatic

Definition at line 32 of file EshelbianPlasticity.hpp.

◆ alphaOmega

double EshelbianPlasticity::EshelbianCore::alphaOmega = 0

Definition at line 222 of file EshelbianPlasticity.hpp.

◆ alphaRho

double EshelbianPlasticity::EshelbianCore::alphaRho = 0

Definition at line 223 of file EshelbianPlasticity.hpp.

◆ alphaU

double EshelbianPlasticity::EshelbianCore::alphaU = 0

Definition at line 220 of file EshelbianPlasticity.hpp.

◆ alphaW

double EshelbianPlasticity::EshelbianCore::alphaW = 0

Definition at line 221 of file EshelbianPlasticity.hpp.

◆ AnalyticalExprPythonPtr

boost::shared_ptr<AnalyticalExprPython> EshelbianPlasticity::EshelbianCore::AnalyticalExprPythonPtr

Definition at line 180 of file EshelbianPlasticity.hpp.

◆ aoS

AO EshelbianPlasticity::EshelbianCore::aoS = PETSC_NULLPTR

Definition at line 445 of file EshelbianPlasticity.hpp.

◆ bcSpatialAnalyticalDisplacementVecPtr

boost::shared_ptr<AnalyticalDisplacementBcVec> EshelbianPlasticity::EshelbianCore::bcSpatialAnalyticalDisplacementVecPtr

Definition at line 236 of file EshelbianPlasticity.hpp.

◆ bcSpatialAnalyticalTractionVecPtr

boost::shared_ptr<AnalyticalTractionBcVec> EshelbianPlasticity::EshelbianCore::bcSpatialAnalyticalTractionVecPtr

Definition at line 237 of file EshelbianPlasticity.hpp.

◆ bcSpatialDispVecPtr

boost::shared_ptr<BcDispVec> EshelbianPlasticity::EshelbianCore::bcSpatialDispVecPtr

Definition at line 230 of file EshelbianPlasticity.hpp.

◆ bcSpatialFreeTractionVecPtr

boost::shared_ptr<TractionFreeBc> EshelbianPlasticity::EshelbianCore::bcSpatialFreeTractionVecPtr

Definition at line 233 of file EshelbianPlasticity.hpp.

◆ bcSpatialNormalDisplacementVecPtr

boost::shared_ptr<NormalDisplacementBcVec> EshelbianPlasticity::EshelbianCore::bcSpatialNormalDisplacementVecPtr

Definition at line 234 of file EshelbianPlasticity.hpp.

◆ bcSpatialPressureVecPtr

boost::shared_ptr<PressureBcVec> EshelbianPlasticity::EshelbianCore::bcSpatialPressureVecPtr

Definition at line 238 of file EshelbianPlasticity.hpp.

◆ bcSpatialRotationVecPtr

boost::shared_ptr<BcRotVec> EshelbianPlasticity::EshelbianCore::bcSpatialRotationVecPtr

Definition at line 231 of file EshelbianPlasticity.hpp.

◆ bcSpatialTractionVecPtr

boost::shared_ptr<TractionBcVec> EshelbianPlasticity::EshelbianCore::bcSpatialTractionVecPtr

Definition at line 232 of file EshelbianPlasticity.hpp.

◆ bitAdjEnt

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

bit ref level for parent

Definition at line 430 of file EshelbianPlasticity.hpp.

◆ bitAdjEntMask

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

bit ref level for parent parent

Definition at line 431 of file EshelbianPlasticity.hpp.

◆ bitAdjParent

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

bit ref level for parent

Definition at line 427 of file EshelbianPlasticity.hpp.

◆ bitAdjParentMask

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

bit ref level for parent parent

Definition at line 428 of file EshelbianPlasticity.hpp.

◆ bubbleField

const std::string EshelbianPlasticity::EshelbianCore::bubbleField = "bubble"

Definition at line 204 of file EshelbianPlasticity.hpp.

◆ contactDisp

const std::string EshelbianPlasticity::EshelbianCore::contactDisp = "contactDisp"

Definition at line 201 of file EshelbianPlasticity.hpp.

◆ contactElement

const std::string EshelbianPlasticity::EshelbianCore::contactElement = "CONTACT"

Definition at line 210 of file EshelbianPlasticity.hpp.

◆ contactFaces

boost::shared_ptr<Range> EshelbianPlasticity::EshelbianCore::contactFaces

Definition at line 415 of file EshelbianPlasticity.hpp.

◆ contactRefinementLevels

int EshelbianPlasticity::EshelbianCore::contactRefinementLevels = 1

Definition at line 225 of file EshelbianPlasticity.hpp.

◆ contactTreeRhs

boost::shared_ptr<ContactTree> EshelbianPlasticity::EshelbianCore::contactTreeRhs

Make a contact tree.

Definition at line 186 of file EshelbianPlasticity.hpp.

◆ crackFaces

boost::shared_ptr<Range> EshelbianPlasticity::EshelbianCore::crackFaces

Definition at line 416 of file EshelbianPlasticity.hpp.

◆ crackHybridIs

SmartPetscObj<IS> EshelbianPlasticity::EshelbianCore::crackHybridIs

Definition at line 446 of file EshelbianPlasticity.hpp.

◆ crackingOn

PetscBool EshelbianPlasticity::EshelbianCore::crackingOn = PETSC_FALSE
inlinestatic

Definition at line 23 of file EshelbianPlasticity.hpp.

◆ crackingStartTime

double EshelbianPlasticity::EshelbianCore::crackingStartTime = 0
inlinestatic

Definition at line 24 of file EshelbianPlasticity.hpp.

◆ d_f

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

Definition at line 45 of file EshelbianPlasticity.hpp.

◆ dataAtPts

boost::shared_ptr<DataAtIntegrationPts> EshelbianPlasticity::EshelbianCore::dataAtPts

Definition at line 178 of file EshelbianPlasticity.hpp.

◆ dd_f

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

Definition at line 46 of file EshelbianPlasticity.hpp.

◆ dM

SmartPetscObj<DM> EshelbianPlasticity::EshelbianCore::dM

Coupled problem all fields.

Definition at line 188 of file EshelbianPlasticity.hpp.

◆ dmElastic

SmartPetscObj<DM> EshelbianPlasticity::EshelbianCore::dmElastic

Elastic problem.

Definition at line 189 of file EshelbianPlasticity.hpp.

◆ dmMaterial

SmartPetscObj<DM> EshelbianPlasticity::EshelbianCore::dmMaterial

Material problem.

Definition at line 190 of file EshelbianPlasticity.hpp.

◆ dmPrjSpatial

SmartPetscObj<DM> EshelbianPlasticity::EshelbianCore::dmPrjSpatial

Projection spatial displacement.

Definition at line 191 of file EshelbianPlasticity.hpp.

◆ dynamicRelaxation

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

Definition at line 21 of file EshelbianPlasticity.hpp.

◆ dynamicStep

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

Definition at line 29 of file EshelbianPlasticity.hpp.

◆ dynamicTime

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

Definition at line 27 of file EshelbianPlasticity.hpp.

◆ edgeExchange

CommInterface::EntitiesPetscVector EshelbianPlasticity::EshelbianCore::edgeExchange

Definition at line 438 of file EshelbianPlasticity.hpp.

◆ elasticBcLhs

boost::shared_ptr<FaceElementForcesAndSourcesCore> EshelbianPlasticity::EshelbianCore::elasticBcLhs

Definition at line 184 of file EshelbianPlasticity.hpp.

◆ elasticBcRhs

boost::shared_ptr<FaceElementForcesAndSourcesCore> EshelbianPlasticity::EshelbianCore::elasticBcRhs

Definition at line 185 of file EshelbianPlasticity.hpp.

◆ elasticFeLhs

boost::shared_ptr<VolumeElementForcesAndSourcesCore> EshelbianPlasticity::EshelbianCore::elasticFeLhs

Definition at line 183 of file EshelbianPlasticity.hpp.

◆ elasticFeRhs

boost::shared_ptr<VolumeElementForcesAndSourcesCore> EshelbianPlasticity::EshelbianCore::elasticFeRhs

Definition at line 182 of file EshelbianPlasticity.hpp.

◆ elementVolumeName

const std::string EshelbianPlasticity::EshelbianCore::elementVolumeName = "EP"

Definition at line 206 of file EshelbianPlasticity.hpp.

◆ energyReleaseSelector

enum EnergyReleaseSelector EshelbianPlasticity::EshelbianCore::energyReleaseSelector
inlinestatic
Initial value:
Examples
EshelbianOperators.cpp.

Definition at line 34 of file EshelbianPlasticity.hpp.

◆ exponentBase

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

Definition at line 43 of file EshelbianPlasticity.hpp.

◆ externalStrainVecPtr

boost::shared_ptr<ExternalStrainVec> EshelbianPlasticity::EshelbianCore::externalStrainVecPtr

Definition at line 239 of file EshelbianPlasticity.hpp.

◆ f

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

Definition at line 44 of file EshelbianPlasticity.hpp.

◆ faceExchange

CommInterface::EntitiesPetscVector EshelbianPlasticity::EshelbianCore::faceExchange

Definition at line 437 of file EshelbianPlasticity.hpp.

◆ frontAdjEdges

boost::shared_ptr<Range> EshelbianPlasticity::EshelbianCore::frontAdjEdges

Definition at line 418 of file EshelbianPlasticity.hpp.

◆ frontEdges

boost::shared_ptr<Range> EshelbianPlasticity::EshelbianCore::frontEdges

Definition at line 417 of file EshelbianPlasticity.hpp.

◆ frontLayers

int EshelbianPlasticity::EshelbianCore::frontLayers = 3

Definition at line 226 of file EshelbianPlasticity.hpp.

◆ frontVertices

boost::shared_ptr<Range> EshelbianPlasticity::EshelbianCore::frontVertices

Definition at line 419 of file EshelbianPlasticity.hpp.

◆ gradApproximator

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

Definition at line 17 of file EshelbianPlasticity.hpp.

◆ griffithEnergy

double EshelbianPlasticity::EshelbianCore::griffithEnergy = 1
inlinestatic

Griffith energy.

Definition at line 33 of file EshelbianPlasticity.hpp.

◆ hybridSpatialDisp

const std::string EshelbianPlasticity::EshelbianCore::hybridSpatialDisp = "hybridSpatialDisp"

Definition at line 199 of file EshelbianPlasticity.hpp.

◆ internalStressInterpOrder

int EshelbianPlasticity::EshelbianCore::internalStressInterpOrder
inlinestatic
Initial value:
=
1

Definition at line 38 of file EshelbianPlasticity.hpp.

◆ internalStressTagName

std::string EshelbianPlasticity::EshelbianCore::internalStressTagName
inlinestatic
Initial value:
=
""

Definition at line 36 of file EshelbianPlasticity.hpp.

◆ internalStressVoigt

PetscBool EshelbianPlasticity::EshelbianCore::internalStressVoigt
inlinestatic
Initial value:
=
PETSC_FALSE

Definition at line 40 of file EshelbianPlasticity.hpp.

◆ inv_d_f

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

Definition at line 48 of file EshelbianPlasticity.hpp.

◆ inv_dd_f

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

Definition at line 49 of file EshelbianPlasticity.hpp.

◆ inv_f

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

Definition at line 47 of file EshelbianPlasticity.hpp.

◆ l2UserBaseScale

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

Definition at line 31 of file EshelbianPlasticity.hpp.

◆ listTagsToTransfer

std::vector<Tag> EshelbianPlasticity::EshelbianCore::listTagsToTransfer

list of tags to transfer to postprocessor

Definition at line 442 of file EshelbianPlasticity.hpp.

◆ materialH1Positions

const std::string EshelbianPlasticity::EshelbianCore::materialH1Positions = "XH1"

Definition at line 198 of file EshelbianPlasticity.hpp.

◆ materialOrder

int EshelbianPlasticity::EshelbianCore::materialOrder = 1

Definition at line 219 of file EshelbianPlasticity.hpp.

◆ materialSkeletonFaces

boost::shared_ptr<Range> EshelbianPlasticity::EshelbianCore::materialSkeletonFaces

Definition at line 421 of file EshelbianPlasticity.hpp.

◆ maxMovedFaces

boost::shared_ptr<Range> EshelbianPlasticity::EshelbianCore::maxMovedFaces

Definition at line 422 of file EshelbianPlasticity.hpp.

◆ mField

MoFEM::Interface& EshelbianPlasticity::EshelbianCore::mField

Definition at line 176 of file EshelbianPlasticity.hpp.

◆ naturalBcElement

const std::string EshelbianPlasticity::EshelbianCore::naturalBcElement = "NATURAL_BC"

Definition at line 207 of file EshelbianPlasticity.hpp.

◆ nbCrackFaces

int EshelbianPlasticity::EshelbianCore::nbCrackFaces = 0

Definition at line 451 of file EshelbianPlasticity.hpp.

◆ nbJIntegralLevels

int EshelbianPlasticity::EshelbianCore::nbJIntegralLevels
inlinestatic
Initial value:
=
0

Definition at line 25 of file EshelbianPlasticity.hpp.

◆ noStretch

PetscBool EshelbianPlasticity::EshelbianCore::noStretch = PETSC_FALSE
inlinestatic

Definition at line 19 of file EshelbianPlasticity.hpp.

◆ parentAdjSkeletonFunctionDim2

boost::shared_ptr<ParentFiniteElementAdjacencyFunctionSkeleton<2> > EshelbianPlasticity::EshelbianCore::parentAdjSkeletonFunctionDim2

Definition at line 425 of file EshelbianPlasticity.hpp.

◆ physicalEquations

boost::shared_ptr<PhysicalEquations> EshelbianPlasticity::EshelbianCore::physicalEquations

Definition at line 179 of file EshelbianPlasticity.hpp.

◆ piolaStress

const std::string EshelbianPlasticity::EshelbianCore::piolaStress = "P"

Definition at line 193 of file EshelbianPlasticity.hpp.

◆ rotAxis

const std::string EshelbianPlasticity::EshelbianCore::rotAxis = "omega"

Definition at line 203 of file EshelbianPlasticity.hpp.

◆ rotSelector

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

Definition at line 16 of file EshelbianPlasticity.hpp.

◆ S

Mat EshelbianPlasticity::EshelbianCore::S = PETSC_NULLPTR

Definition at line 444 of file EshelbianPlasticity.hpp.

◆ setSingularity

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

Definition at line 20 of file EshelbianPlasticity.hpp.

◆ skeletonElement

const std::string EshelbianPlasticity::EshelbianCore::skeletonElement = "SKELETON"

Definition at line 209 of file EshelbianPlasticity.hpp.

◆ skeletonFaces

boost::shared_ptr<Range> EshelbianPlasticity::EshelbianCore::skeletonFaces

Definition at line 420 of file EshelbianPlasticity.hpp.

◆ skinElement

const std::string EshelbianPlasticity::EshelbianCore::skinElement = "SKIN"

Definition at line 208 of file EshelbianPlasticity.hpp.

◆ solTSStep

SmartPetscObj<Vec> EshelbianPlasticity::EshelbianCore::solTSStep

Definition at line 434 of file EshelbianPlasticity.hpp.

◆ spaceH1Order

int EshelbianPlasticity::EshelbianCore::spaceH1Order = -1

Definition at line 218 of file EshelbianPlasticity.hpp.

◆ spaceOrder

int EshelbianPlasticity::EshelbianCore::spaceOrder = 2

Definition at line 217 of file EshelbianPlasticity.hpp.

◆ spatialH1Disp

const std::string EshelbianPlasticity::EshelbianCore::spatialH1Disp = "wH1"

Definition at line 197 of file EshelbianPlasticity.hpp.

◆ spatialL2Disp

const std::string EshelbianPlasticity::EshelbianCore::spatialL2Disp = "wL2"

Definition at line 195 of file EshelbianPlasticity.hpp.

◆ stretchSelector

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

Definition at line 18 of file EshelbianPlasticity.hpp.

◆ stretchTensor

const std::string EshelbianPlasticity::EshelbianCore::stretchTensor = "u"

Definition at line 202 of file EshelbianPlasticity.hpp.

◆ symmetrySelector

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

Definition at line 15 of file EshelbianPlasticity.hpp.

◆ timeScaleMap

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

Definition at line 241 of file EshelbianPlasticity.hpp.

◆ use_quadratic_exp

bool EshelbianPlasticity::EshelbianCore::use_quadratic_exp = true
inlinestaticconstexpr

Definition at line 51 of file EshelbianPlasticity.hpp.

◆ v_max

double EshelbianPlasticity::EshelbianCore::v_max = 12
inlinestaticconstexpr

Definition at line 52 of file EshelbianPlasticity.hpp.

◆ v_min

double EshelbianPlasticity::EshelbianCore::v_min = -v_max
inlinestaticconstexpr

Definition at line 53 of file EshelbianPlasticity.hpp.

◆ vertexExchange

CommInterface::EntitiesPetscVector EshelbianPlasticity::EshelbianCore::vertexExchange

Definition at line 439 of file EshelbianPlasticity.hpp.

◆ volumeExchange

CommInterface::EntitiesPetscVector EshelbianPlasticity::EshelbianCore::volumeExchange

Definition at line 436 of file EshelbianPlasticity.hpp.


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