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

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

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

Classes

struct  DynamicRelaxationTimeScale
 
struct  SetUpSchur
 

Public Member Functions

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

Static Public Member Functions

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

Public Attributes

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

Static Public Attributes

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

Friends

struct solve_elastic_set_up
 

Detailed Description

Examples
ep.cpp, mofem/users_modules/eshelbian_plasticity/ep.cpp, and mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 12 of file EshelbianCore.hpp.

Constructor & Destructor Documentation

◆ EshelbianCore()

EshelbianCore::EshelbianCore ( MoFEM::Interface m_field)
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 916 of file EshelbianPlasticity.cpp.

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

◆ ~EshelbianCore()

EshelbianCore::~EshelbianCore ( )
virtualdefault

Member Function Documentation

◆ addBoundaryFiniteElement()

MoFEMErrorCode EshelbianCore::addBoundaryFiniteElement ( const EntityHandle  meshset = 0)
Examples
ep.cpp, mofem/users_modules/eshelbian_plasticity/ep.cpp, and mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 1656 of file EshelbianPlasticity.cpp.

1656 {
1658
1659 Range meshset_ents;
1660 CHKERR mField.get_moab().get_entities_by_handle(meshset, meshset_ents);
1661
1662 auto set_fe_adjacency = [&](auto fe_name) {
1665 boost::make_shared<ParentFiniteElementAdjacencyFunctionSkeleton<2>>(
1668 fe_name, MBTRI, *parentAdjSkeletonFunctionDim2);
1670 };
1671
1672 // set finite element fields
1673 auto add_field_to_fe = [this](const std::string fe,
1674 const std::string field_name) {
1681 };
1682
1684
1685 Range natural_bc_elements;
1686 if (bcSpatialDispVecPtr) {
1687 for (auto &v : *bcSpatialDispVecPtr) {
1688 natural_bc_elements.merge(v.faces);
1689 }
1690 }
1692 for (auto &v : *bcSpatialRotationVecPtr) {
1693 natural_bc_elements.merge(v.faces);
1694 }
1695 }
1697 for (auto &v : *bcSpatialNormalDisplacementVecPtr) {
1698 natural_bc_elements.merge(v.faces);
1699 }
1700 }
1703 natural_bc_elements.merge(v.faces);
1704 }
1705 }
1707 for (auto &v : *bcSpatialTractionVecPtr) {
1708 natural_bc_elements.merge(v.faces);
1709 }
1710 }
1712 for (auto &v : *bcSpatialAnalyticalTractionVecPtr) {
1713 natural_bc_elements.merge(v.faces);
1714 }
1715 }
1717 for (auto &v : *bcSpatialPressureVecPtr) {
1718 natural_bc_elements.merge(v.faces);
1719 }
1720 }
1721 natural_bc_elements = intersect(natural_bc_elements, meshset_ents);
1722
1724 CHKERR mField.add_ents_to_finite_element_by_type(natural_bc_elements, MBTRI,
1726 CHKERR add_field_to_fe(naturalBcElement, piolaStress);
1727 CHKERR add_field_to_fe(naturalBcElement, hybridSpatialDisp);
1728 CHKERR set_fe_adjacency(naturalBcElement);
1730 }
1731
1732 auto get_skin = [&](auto &body_ents) {
1733 Skinner skin(&mField.get_moab());
1734 Range skin_ents;
1735 CHKERR skin.find_skin(0, body_ents, false, skin_ents);
1736 return skin_ents;
1737 };
1738
1739 auto filter_true_skin = [&](auto &&skin) {
1740 Range boundary_ents;
1741 ParallelComm *pcomm =
1742 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
1743 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
1744 PSTATUS_NOT, -1, &boundary_ents);
1745 return boundary_ents;
1746 };
1747
1749
1750 Range body_ents;
1751 CHKERR mField.get_moab().get_entities_by_dimension(meshset, SPACE_DIM,
1752 body_ents);
1753 auto skin = filter_true_skin(get_skin(body_ents));
1754
1762 contactDisp);
1765 // CHKERR add_field_to_fe(skinElement, hybridSpatialDisp);
1766 // CHKERR add_field_to_fe(skinElement, hybridMaterialDisp);
1767
1769 }
1770
1772 if (contactFaces) {
1773 MOFEM_LOG("EP", Sev::inform)
1774 << "Contact elements " << contactFaces->size();
1778 CHKERR add_field_to_fe(contactElement, piolaStress);
1779 CHKERR add_field_to_fe(contactElement, hybridSpatialDisp);
1780 CHKERR add_field_to_fe(contactElement, contactDisp);
1781 CHKERR add_field_to_fe(contactElement, spatialH1Disp);
1782 CHKERR set_fe_adjacency(contactElement);
1784 }
1785 }
1786
1788 if (!skeletonFaces)
1789 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "No skeleton faces");
1790 MOFEM_LOG("EP", Sev::inform)
1791 << "Skeleton elements " << skeletonFaces->size();
1795 CHKERR add_field_to_fe(skeletonElement, piolaStress);
1796 CHKERR add_field_to_fe(skeletonElement, hybridSpatialDisp);
1797 CHKERR add_field_to_fe(skeletonElement, contactDisp);
1798 CHKERR add_field_to_fe(skeletonElement, spatialH1Disp);
1799 CHKERR set_fe_adjacency(skeletonElement);
1801 }
1802
1803 // if (!mField.check_finite_element(materialSkeletonElement)) {
1804
1805 // Range front_edges = get_range_from_block(mField, "FRONT", SPACE_DIM -
1806 // 2);
1807
1808 // Range front_elements;
1809 // for (auto l = 0; l != frontLayers; ++l) {
1810 // Range front_elements_layer;
1811 // CHKERR mField.get_moab().get_adjacencies(front_edges, SPACE_DIM,
1812 // true,
1813 // front_elements_layer,
1814 // moab::Interface::UNION);
1815 // front_elements.merge(front_elements_layer);
1816 // front_edges.clear();
1817 // CHKERR mField.get_moab().get_adjacencies(front_elements_layer,
1818 // SPACE_DIM - 2, true,
1819 // front_edges,
1820 // moab::Interface::UNION);
1821 // }
1822 // Range body_ents;
1823 // CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
1824 // body_ents); Range front_elements_faces; CHKERR
1825 // mField.get_moab().get_adjacencies(front_elements, SPACE_DIM - 1,
1826 // true, front_elements_faces,
1827 // moab::Interface::UNION);
1828 // auto body_skin = filter_true_skin(get_skin(body_ents));
1829 // auto front_elements_skin = filter_true_skin(get_skin(front_elements));
1830 // Range material_skeleton_faces =
1831 // subtract(front_elements_faces, front_elements_skin);
1832 // material_skeleton_faces.merge(intersect(front_elements_skin,
1833 // body_skin));
1834
1835 // #ifndef NDEBUG
1836 // CHKERR save_range(mField.get_moab(), "front_elements.vtk",
1837 // front_elements); CHKERR save_range(mField.get_moab(),
1838 // "front_elements_skin.vtk",
1839 // front_elements_skin);
1840 // CHKERR save_range(mField.get_moab(), "material_skeleton_faces.vtk",
1841 // material_skeleton_faces);
1842 // #endif
1843
1844 // CHKERR mField.add_finite_element(materialSkeletonElement, MF_ZERO);
1845 // CHKERR mField.add_ents_to_finite_element_by_type(
1846 // material_skeleton_faces, MBTRI, materialSkeletonElement);
1847 // // CHKERR add_field_to_fe(materialSkeletonElement, eshelbyStress);
1848 // // CHKERR add_field_to_fe(materialSkeletonElement, hybridMaterialDisp);
1849 // CHKERR set_fe_adjacency(materialSkeletonElement);
1850 // CHKERR mField.build_finite_elements(materialSkeletonElement);
1851 // }
1852
1854}
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
[Define dimension]
@ MF_ZERO
#define MYPCOMM_INDEX
default communicator number PCOMM
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
virtual MoFEMErrorCode add_finite_element(const std::string &fe_name, enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
add finite element
virtual MoFEMErrorCode build_finite_elements(int verb=DEFAULT_VERBOSITY)=0
Build finite elements.
virtual MoFEMErrorCode modify_finite_element_add_field_col(const std::string &fe_name, const std::string name_row)=0
set field col which finite element use
virtual MoFEMErrorCode modify_finite_element_adjacency_table(const std::string &fe_name, const EntityType type, ElementAdjacencyFunct function)=0
modify finite element table, only for advanced user
virtual MoFEMErrorCode add_ents_to_finite_element_by_type(const EntityHandle entities, const EntityType type, const std::string name, const bool recursive=true)=0
add entities to finite element
virtual MoFEMErrorCode modify_finite_element_add_field_row(const std::string &fe_name, const std::string name_row)=0
set field row which finite element use
virtual MoFEMErrorCode modify_finite_element_add_field_data(const std::string &fe_name, const std::string name_field)=0
set finite element field data
#define MOFEM_LOG(channel, severity)
Log.
const double v
phase velocity of light in medium (cm/ns)
constexpr auto field_name
const std::string skeletonElement
boost::shared_ptr< TractionBcVec > bcSpatialTractionVecPtr
boost::shared_ptr< Range > contactFaces
BitRefLevel bitAdjEnt
bit ref level for parent
const std::string materialH1Positions
boost::shared_ptr< BcRotVec > bcSpatialRotationVecPtr
const std::string spatialH1Disp
boost::shared_ptr< NormalDisplacementBcVec > bcSpatialNormalDisplacementVecPtr
const std::string piolaStress
boost::shared_ptr< AnalyticalDisplacementBcVec > bcSpatialAnalyticalDisplacementVecPtr
boost::shared_ptr< ParentFiniteElementAdjacencyFunctionSkeleton< 2 > > parentAdjSkeletonFunctionDim2
boost::shared_ptr< Range > skeletonFaces
BitRefLevel bitAdjParentMask
bit ref level for parent parent
const std::string contactDisp
boost::shared_ptr< BcDispVec > bcSpatialDispVecPtr
const std::string skinElement
boost::shared_ptr< AnalyticalTractionBcVec > bcSpatialAnalyticalTractionVecPtr
BitRefLevel bitAdjParent
bit ref level for parent
const std::string naturalBcElement
boost::shared_ptr< PressureBcVec > bcSpatialPressureVecPtr
const std::string hybridSpatialDisp
BitRefLevel bitAdjEntMask
bit ref level for parent parent
const std::string contactElement
virtual moab::Interface & get_moab()=0
virtual bool check_finite_element(const std::string &name) const =0
Check if finite element is in database.
virtual MPI_Comm & get_comm() const =0

◆ addCrackSurfaces()

MoFEMErrorCode EshelbianCore::addCrackSurfaces ( const bool  debug = false)
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 5968 of file EshelbianPlasticity.cpp.

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

◆ addDMs()

MoFEMErrorCode EshelbianCore::addDMs ( const BitRefLevel  bit = BitRefLevel().set(0),
const EntityHandle  meshset = 0 
)
Examples
ep.cpp, mofem/users_modules/eshelbian_plasticity/ep.cpp, and mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 1856 of file EshelbianPlasticity.cpp.

1857 {
1859
1860 // find adjacencies between finite elements and dofs
1862
1863 // Create coupled problem
1864 dM = createDM(mField.get_comm(), "DMMOFEM");
1865 CHKERR DMMoFEMCreateMoFEM(dM, &mField, "ESHELBY_PLASTICITY", bit,
1866 BitRefLevel().set());
1867 CHKERR DMMoFEMSetDestroyProblem(dM, PETSC_TRUE);
1868 CHKERR DMMoFEMSetIsPartitioned(dM, PETSC_TRUE);
1874
1875 mField.getInterface<ProblemsManager>()->buildProblemFromFields = PETSC_TRUE;
1876 CHKERR DMSetUp(dM);
1877 mField.getInterface<ProblemsManager>()->buildProblemFromFields = PETSC_FALSE;
1878
1879 auto remove_dofs_on_broken_skin = [&](const std::string prb_name) {
1881 for (int d : {0, 1, 2}) {
1882 std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_to_remove;
1884 ->getSideDofsOnBrokenSpaceEntities(
1885 dofs_to_remove, prb_name, ROW, piolaStress,
1887 // remove piola dofs, i.e. traction free boundary
1888 CHKERR mField.getInterface<ProblemsManager>()->removeDofs(prb_name, ROW,
1889 dofs_to_remove);
1890 CHKERR mField.getInterface<ProblemsManager>()->removeDofs(prb_name, COL,
1891 dofs_to_remove);
1892 }
1894 };
1895 CHKERR remove_dofs_on_broken_skin("ESHELBY_PLASTICITY");
1896
1897 // Create elastic sub-problem
1898 dmElastic = createDM(mField.get_comm(), "DMMOFEM");
1899 CHKERR DMMoFEMCreateSubDM(dmElastic, dM, "ELASTIC_PROBLEM");
1905 if (!noStretch) {
1907 }
1917 CHKERR DMSetUp(dmElastic);
1918
1919 // dmMaterial = createDM(mField.get_comm(), "DMMOFEM");
1920 // CHKERR DMMoFEMCreateSubDM(dmMaterial, dM, "MATERIAL_PROBLEM");
1921 // CHKERR DMMoFEMSetDestroyProblem(dmMaterial, PETSC_TRUE);
1922 // CHKERR DMMoFEMAddSubFieldRow(dmMaterial, eshelbyStress);
1923 // CHKERR DMMoFEMAddSubFieldRow(dmMaterial, materialL2Disp);
1924 // CHKERR DMMoFEMAddElement(dmMaterh elementVolumeName);
1925 // CHKERR DMMoFEMAddElement(dmMaterial, naturalBcElement);
1926 // CHKERR DMMoFEMAddElement(dmMaterial, skinElement);
1927 // CHKERR DMMoFEMSetSquareProblem(dmMaterial, PETSC_TRUE);
1928 // CHKERR DMMoFEMSetIsPartitioned(dmMaterial, PETSC_TRUE);
1929 // CHKERR DMSetUp(dmMaterial);
1930
1931 auto set_zero_block = [&]() {
1933 if (!noStretch) {
1934 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1935 "ELASTIC_PROBLEM", spatialL2Disp, stretchTensor);
1936 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1937 "ELASTIC_PROBLEM", stretchTensor, spatialL2Disp);
1938 }
1939 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1940 "ELASTIC_PROBLEM", spatialL2Disp, rotAxis);
1941 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1942 "ELASTIC_PROBLEM", rotAxis, spatialL2Disp);
1943 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1944 "ELASTIC_PROBLEM", spatialL2Disp, bubbleField);
1945 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1946 "ELASTIC_PROBLEM", bubbleField, spatialL2Disp);
1947 if (!noStretch) {
1948 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1949 "ELASTIC_PROBLEM", bubbleField, bubbleField);
1950 CHKERR
1951 mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1952 "ELASTIC_PROBLEM", piolaStress, piolaStress);
1953 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1954 "ELASTIC_PROBLEM", bubbleField, piolaStress);
1955 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
1956 "ELASTIC_PROBLEM", piolaStress, bubbleField);
1957 }
1958
1961 };
1962
1963 auto set_section = [&]() {
1965 PetscSection section;
1966 CHKERR mField.getInterface<ISManager>()->sectionCreate("ELASTIC_PROBLEM",
1967 &section);
1968 CHKERR DMSetSection(dmElastic, section);
1969 CHKERR DMSetGlobalSection(dmElastic, section);
1970 CHKERR PetscSectionDestroy(&section);
1972 };
1973
1974 CHKERR set_zero_block();
1975 CHKERR set_section();
1976
1977 dmPrjSpatial = createDM(mField.get_comm(), "DMMOFEM");
1978 CHKERR DMMoFEMCreateSubDM(dmPrjSpatial, dM, "PROJECT_SPATIAL");
1984 CHKERR DMSetUp(dmPrjSpatial);
1985
1986 // CHKERR mField.getInterface<BcManager>()
1987 // ->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
1988 // "PROJECT_SPATIAL", spatialH1Disp, true, false);
1989
1991}
@ 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:1234
auto bit
set bit
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
Definition Types.hpp:40
PetscErrorCode DMMoFEMSetDestroyProblem(DM dm, PetscBool destroy_problem)
Definition DMMoFEM.cpp:434
auto createDM(MPI_Comm comm, const std::string dm_type_name)
Creates smart DM object.
const std::string spatialL2Disp
SmartPetscObj< DM > dM
Coupled problem all fields.
boost::shared_ptr< TractionFreeBc > bcSpatialFreeTractionVecPtr
const std::string elementVolumeName
const std::string bubbleField
static PetscBool noStretch
const std::string rotAxis
SmartPetscObj< DM > dmPrjSpatial
Projection spatial displacement.
SmartPetscObj< Vec > solTSStep
SmartPetscObj< DM > dmElastic
Elastic problem.
const std::string stretchTensor
virtual MoFEMErrorCode build_adjacencies(const Range &ents, int verb=DEFAULT_VERBOSITY)=0
build adjacencies
Section manager is used to create indexes and sections.
Definition ISManager.hpp:23
Problem manager is used to build and partition problems.

◆ addFields()

MoFEMErrorCode EshelbianCore::addFields ( const EntityHandle  meshset = 0)
Examples
ep.cpp, mofem/users_modules/eshelbian_plasticity/ep.cpp, and mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 1161 of file EshelbianPlasticity.cpp.

1161 {
1163
1164 auto get_tets = [&]() {
1165 Range tets;
1166 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
1167 return tets;
1168 };
1169
1170 auto get_tets_skin = [&]() {
1171 Range tets_skin_part;
1172 Skinner skin(&mField.get_moab());
1173 CHKERR skin.find_skin(0, get_tets(), false, tets_skin_part);
1174 ParallelComm *pcomm =
1175 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
1176 Range tets_skin;
1177 CHKERR pcomm->filter_pstatus(tets_skin_part,
1178 PSTATUS_SHARED | PSTATUS_MULTISHARED,
1179 PSTATUS_NOT, -1, &tets_skin);
1180 return tets_skin;
1181 };
1182
1183 auto subtract_boundary_conditions = [&](auto &&tets_skin) {
1184 // That mean, that hybrid field on all faces on which traction is applied,
1185 // on other faces, or enforcing displacements as
1186 // natural boundary condition.
1188 for (auto &v : *bcSpatialTractionVecPtr) {
1189 tets_skin = subtract(tets_skin, v.faces);
1190 }
1192 for (auto &v : *bcSpatialAnalyticalTractionVecPtr) {
1193 tets_skin = subtract(tets_skin, v.faces);
1194 }
1195
1197 for (auto &v : *bcSpatialPressureVecPtr) {
1198 tets_skin = subtract(tets_skin, v.faces);
1199 }
1200
1201 return tets_skin;
1202 };
1203
1204 auto add_blockset = [&](auto block_name, auto &&tets_skin) {
1205 auto crack_faces =
1206 get_range_from_block(mField, "block_name", SPACE_DIM - 1);
1207 tets_skin.merge(crack_faces);
1208 return tets_skin;
1209 };
1210
1211 auto subtract_blockset = [&](auto block_name, auto &&tets_skin) {
1212 auto contact_range =
1213 get_range_from_block(mField, block_name, SPACE_DIM - 1);
1214 tets_skin = subtract(tets_skin, contact_range);
1215 return tets_skin;
1216 };
1217
1218 auto get_stress_trace_faces = [&](auto &&tets_skin) {
1219 Range faces;
1220 CHKERR mField.get_moab().get_adjacencies(get_tets(), SPACE_DIM - 1, true,
1221 faces, moab::Interface::UNION);
1222 Range trace_faces = subtract(faces, tets_skin);
1223 return trace_faces;
1224 };
1225
1226 auto tets = get_tets();
1227
1228 // remove also contact faces, i.e. that is also kind of hybrid field but
1229 // named but used to enforce contact conditions
1230 auto trace_faces = get_stress_trace_faces(
1231
1232 subtract_blockset("CONTACT",
1233 subtract_boundary_conditions(get_tets_skin()))
1234
1235 );
1236
1237 contactFaces = boost::make_shared<Range>(intersect(
1238 trace_faces, get_range_from_block(mField, "CONTACT", SPACE_DIM - 1)));
1240 boost::make_shared<Range>(subtract(trace_faces, *contactFaces));
1241 // materialSkeletonFaces =
1242 // boost::make_shared<Range>(get_stress_trace_faces(Range()));
1243
1244#ifndef NDEBUG
1245 if (contactFaces->size())
1247 "contact_faces_" +
1248 std::to_string(mField.get_comm_rank()) + ".vtk",
1249 *contactFaces);
1250 if (skeletonFaces->size())
1252 "skeleton_faces_" +
1253 std::to_string(mField.get_comm_rank()) + ".vtk",
1254 *skeletonFaces);
1255 // if (skeletonFaces->size())
1256 // CHKERR save_range(mField.get_moab(), "material_skeleton_faces.vtk",
1257 // *materialSkeletonFaces);
1258#endif
1259
1260 auto add_broken_hdiv_field = [this, meshset](const std::string field_name,
1261 const int order) {
1263
1265
1266 auto get_side_map_hdiv = [&]() {
1267 return std::vector<
1268
1269 std::pair<EntityType,
1271
1272 >>{
1273
1274 {MBTET,
1275 [&](BaseFunction::DofsSideMap &dofs_side_map) -> MoFEMErrorCode {
1276 return TetPolynomialBase::setDofsSideMap(HDIV, DISCONTINUOUS, base,
1277 dofs_side_map);
1278 }}
1279
1280 };
1281 };
1282
1284 get_side_map_hdiv(), MB_TAG_DENSE, MF_ZERO);
1286 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1288 };
1289
1290 auto add_l2_field = [this, meshset](const std::string field_name,
1291 const int order, const int dim) {
1294 MB_TAG_DENSE, MF_ZERO);
1296 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1298 };
1299
1300 auto add_h1_field = [this, meshset](const std::string field_name,
1301 const int order, const int dim) {
1304 MB_TAG_DENSE, MF_ZERO);
1306 CHKERR mField.set_field_order(meshset, MBVERTEX, field_name, 1);
1307 CHKERR mField.set_field_order(meshset, MBEDGE, field_name, order);
1308 CHKERR mField.set_field_order(meshset, MBTRI, field_name, order);
1309 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1311 };
1312
1313 auto add_l2_field_by_range = [this](const std::string field_name,
1314 const int order, const int dim,
1315 const int field_dim, Range &&r) {
1318 MB_TAG_DENSE, MF_ZERO);
1319 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(r);
1323 };
1324
1325 auto add_bubble_field = [this, meshset](const std::string field_name,
1326 const int order, const int dim) {
1328 CHKERR mField.add_field(field_name, HDIV, USER_BASE, dim, MB_TAG_DENSE,
1329 MF_ZERO);
1330 // Modify field
1331 auto field_ptr = mField.get_field_structure(field_name);
1332 auto field_order_table =
1333 const_cast<Field *>(field_ptr)->getFieldOrderTable();
1334 auto get_cgg_bubble_order_zero = [](int p) { return 0; };
1335 auto get_cgg_bubble_order_tet = [](int p) {
1336 return NBVOLUMETET_CCG_BUBBLE(p);
1337 };
1338 field_order_table[MBVERTEX] = get_cgg_bubble_order_zero;
1339 field_order_table[MBEDGE] = get_cgg_bubble_order_zero;
1340 field_order_table[MBTRI] = get_cgg_bubble_order_zero;
1341 field_order_table[MBTET] = get_cgg_bubble_order_tet;
1343 CHKERR mField.set_field_order(meshset, MBTRI, field_name, order);
1344 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1346 };
1347
1348 auto add_user_l2_field = [this, meshset](const std::string field_name,
1349 const int order, const int dim) {
1351 CHKERR mField.add_field(field_name, L2, USER_BASE, dim, MB_TAG_DENSE,
1352 MF_ZERO);
1353 // Modify field
1354 auto field_ptr = mField.get_field_structure(field_name);
1355 auto field_order_table =
1356 const_cast<Field *>(field_ptr)->getFieldOrderTable();
1357 auto zero_dofs = [](int p) { return 0; };
1358 auto dof_l2_tet = [](int p) { return NBVOLUMETET_L2(p); };
1359 field_order_table[MBVERTEX] = zero_dofs;
1360 field_order_table[MBEDGE] = zero_dofs;
1361 field_order_table[MBTRI] = zero_dofs;
1362 field_order_table[MBTET] = dof_l2_tet;
1364 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1366 };
1367
1368 // spatial fields
1369 CHKERR add_broken_hdiv_field(piolaStress, spaceOrder);
1370 CHKERR add_bubble_field(bubbleField, spaceOrder, 1);
1371 CHKERR add_l2_field(spatialL2Disp, spaceOrder - 1, 3);
1372 CHKERR add_user_l2_field(rotAxis, spaceOrder - 1, 3);
1373 CHKERR add_user_l2_field(stretchTensor, noStretch ? -1 : spaceOrder, 6);
1374
1375 if (!skeletonFaces)
1376 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "No skeleton faces");
1377 if (!contactFaces)
1378 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "No contact faces");
1379
1380 auto get_hybridised_disp = [&]() {
1381 auto faces = *skeletonFaces;
1382 auto skin = subtract_boundary_conditions(get_tets_skin());
1383 for (auto &bc : *bcSpatialNormalDisplacementVecPtr) {
1384 faces.merge(intersect(bc.faces, skin));
1385 }
1386 return faces;
1387 };
1388
1389 CHKERR add_l2_field_by_range(hybridSpatialDisp, spaceOrder - 1, 2, 3,
1390 get_hybridised_disp());
1391 CHKERR add_l2_field_by_range(contactDisp, spaceOrder - 1, 2, 3,
1393
1394 // spatial displacement
1395 CHKERR add_h1_field(spatialH1Disp, spaceH1Order, 3);
1396 // material positions
1397 CHKERR add_h1_field(materialH1Positions, 2, 3);
1398
1399 // Eshelby stress
1400 // CHKERR add_broken_hdiv_field(eshelbyStress, spaceOrder);
1401 // CHKERR add_l2_field(materialL2Disp, spaceOrder - 1, 3);
1402 // CHKERR add_l2_field_by_range(hybridMaterialDisp, spaceOrder - 1, 2, 3,
1403 // Range(*materialSkeletonFaces));
1404
1406
1408}
#define NBVOLUMETET_CCG_BUBBLE(P)
Bubble function for CGG H div space.
FieldApproximationBase
approximation base
Definition definitions.h:58
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
@ USER_BASE
user implemented approximation base
Definition definitions.h:68
@ DEMKOWICZ_JACOBI_BASE
Definition definitions.h:66
@ L2
field with C-1 continuity
Definition definitions.h:88
@ H1
continuous field
Definition definitions.h:85
@ HDIV
field with continuous normal traction
Definition definitions.h:87
@ DISCONTINUOUS
Broken continuity (No effect on L2 space)
constexpr int order
Order displacement.
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.
Field data structure for finite element approximation.

◆ addMaterial_Hencky()

MoFEMErrorCode EshelbianCore::addMaterial_Hencky ( double  E,
double  nu 
)
Examples
ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

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

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

◆ addMaterial_HMHHStVenantKirchhoff()

MoFEMErrorCode EshelbianCore::addMaterial_HMHHStVenantKirchhoff ( const int  tape,
const double  lambda,
const double  mu,
const double  sigma_y 
)
Examples
ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

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

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

◆ addMaterial_HMHMooneyRivlin()

MoFEMErrorCode EshelbianCore::addMaterial_HMHMooneyRivlin ( const int  tape,
const double  alpha,
const double  beta,
const double  lambda,
const double  sigma_y 
)
Examples
ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

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

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

◆ addMaterial_HMHNeohookean()

MoFEMErrorCode EshelbianCore::addMaterial_HMHNeohookean ( const int  tape,
const double  c10,
const double  K 
)
Examples
ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

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

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

◆ addVolumeFiniteElement()

MoFEMErrorCode EshelbianCore::addVolumeFiniteElement ( const EntityHandle  meshset = 0)
Examples
ep.cpp, mofem/users_modules/eshelbian_plasticity/ep.cpp, and mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 1593 of file EshelbianPlasticity.cpp.

1593 {
1595
1596 // set finite element fields
1597 auto add_field_to_fe = [this](const std::string fe,
1598 const std::string field_name) {
1604 };
1605
1610
1611 CHKERR add_field_to_fe(elementVolumeName, piolaStress);
1612 CHKERR add_field_to_fe(elementVolumeName, bubbleField);
1613 if (!noStretch)
1614 CHKERR add_field_to_fe(elementVolumeName, stretchTensor);
1615 CHKERR add_field_to_fe(elementVolumeName, rotAxis);
1616 CHKERR add_field_to_fe(elementVolumeName, spatialL2Disp);
1617 CHKERR add_field_to_fe(elementVolumeName, spatialH1Disp);
1618 CHKERR add_field_to_fe(elementVolumeName, contactDisp);
1621
1622 // build finite elements data structures
1624 }
1625
1626 // if (!mField.check_finite_element(materialVolumeElement)) {
1627
1628 // Range front_edges = get_range_from_block(mField, "FRONT", SPACE_DIM - 2);
1629
1630 // Range front_elements;
1631 // for (auto l = 0; l != frontLayers; ++l) {
1632 // Range front_elements_layer;
1633 // CHKERR mField.get_moab().get_adjacencies(front_edges, SPACE_DIM, true,
1634 // front_elements_layer,
1635 // moab::Interface::UNION);
1636 // front_elements.merge(front_elements_layer);
1637 // front_edges.clear();
1638 // CHKERR mField.get_moab().get_adjacencies(front_elements_layer,
1639 // SPACE_DIM - 2, true,
1640 // front_edges,
1641 // moab::Interface::UNION);
1642 // }
1643
1644 // CHKERR mField.add_finite_element(materialVolumeElement, MF_ZERO);
1645 // CHKERR mField.add_ents_to_finite_element_by_type(front_elements, MBTET,
1646 // materialVolumeElement);
1647 // // CHKERR add_field_to_fe(materialVolumeElement, eshelbyStress);
1648 // // CHKERR add_field_to_fe(materialVolumeElement, materialL2Disp);
1649 // CHKERR mField.build_finite_elements(materialVolumeElement);
1650 // }
1651
1653}

◆ calculateCrackArea()

MoFEMErrorCode EshelbianCore::calculateCrackArea ( boost::shared_ptr< double area_ptr)
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 7062 of file EshelbianPlasticity.cpp.

7062 {
7064
7065 if (!area_ptr) {
7066 CHK_THROW_MESSAGE(MOFEM_INVALID_DATA, "area_ptr is null");
7067 }
7068
7069 int success;
7070 *area_ptr = 0;
7071 if (mField.get_comm_rank() == 0) {
7072 MOFEM_LOG("EP", Sev::inform) << "Calculate crack area";
7073 auto crack_faces = get_range_from_block(mField, "CRACK", SPACE_DIM - 1);
7074 for (auto f : crack_faces) {
7075 *area_ptr += mField.getInterface<Tools>()->getTriArea(f);
7076 }
7077 success = MPI_Bcast(area_ptr.get(), 1, MPI_DOUBLE, 0, mField.get_comm());
7078 } else {
7079 success = MPI_Bcast(area_ptr.get(), 1, MPI_DOUBLE, 0, mField.get_comm());
7080 }
7081 if (success != MPI_SUCCESS) {
7083 }
7085}
@ MOFEM_OPERATION_UNSUCCESSFUL
Definition definitions.h:34
@ MOFEM_INVALID_DATA
Definition definitions.h:36

◆ calculateFaceMaterialForce()

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

Create element to integration faces energies

Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 4283 of file EshelbianPlasticity.cpp.

4283 {
4285
4286 constexpr bool debug = false;
4287
4288 auto get_tags_vec = [&](std::vector<std::pair<std::string, int>> names) {
4289 std::vector<Tag> tags;
4290 tags.reserve(names.size());
4291 auto create_and_clean = [&]() {
4293 for (auto n : names) {
4294 tags.push_back(Tag());
4295 auto &tag = tags.back();
4296 auto &moab = mField.get_moab();
4297 auto rval = moab.tag_get_handle(n.first.c_str(), tag);
4298 if (rval == MB_SUCCESS) {
4299 moab.tag_delete(tag);
4300 }
4301 double def_val[] = {0., 0., 0.};
4302 CHKERR moab.tag_get_handle(n.first.c_str(), n.second, MB_TYPE_DOUBLE,
4303 tag, MB_TAG_CREAT | MB_TAG_SPARSE, def_val);
4304 }
4306 };
4307 CHK_THROW_MESSAGE(create_and_clean(), "create_and_clean");
4308 return tags;
4309 };
4310
4311 enum ExhangeTags { MATERIALFORCE, AREAGROWTH, GRIFFITHFORCE, FACEPRESSURE };
4312
4313 auto tags = get_tags_vec({{"MaterialForce", 3},
4314 {"AreaGrowth", 3},
4315 {"GriffithForce", 1},
4316 {"FacePressure", 1}});
4317
4318 auto calculate_material_forces = [&]() {
4320
4321 /**
4322 * @brief Create element to integration faces energies
4323 */
4324 auto get_face_material_force_fe = [&]() {
4326 auto fe_ptr = boost::make_shared<FaceEle>(mField);
4327 fe_ptr->getRuleHook = [](int, int, int) { return -1; };
4328 fe_ptr->setRuleHook =
4329 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
4330
4331 // hybrid disp, evalated on face first
4332 EshelbianPlasticity::AddHOOps<2, 2, 3>::add(
4333 fe_ptr->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
4334 fe_ptr->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4335 hybridSpatialDisp, dataAtPts->getHybridDispAtPts()));
4336 fe_ptr->getOpPtrVector().push_back(
4338 hybridSpatialDisp, dataAtPts->getGradHybridDispAtPts()));
4339 auto op_loop_domain_side =
4341 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
4342 fe_ptr->getOpPtrVector().push_back(op_loop_domain_side);
4343 fe_ptr->getOpPtrVector().push_back(new OpFaceMaterialForce(dataAtPts));
4344
4345 // evaluated in side domain, that is op_loop_domain_side
4346 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
4347 boost::make_shared<CGGUserPolynomialBase>();
4348
4349 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4350 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
4351 materialH1Positions, frontAdjEdges, nullptr, nullptr, nullptr);
4352 op_loop_domain_side->getOpPtrVector().push_back(
4354 piolaStress, dataAtPts->getApproxPAtPts()));
4355 op_loop_domain_side->getOpPtrVector().push_back(
4357 bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
4358 // op_loop_domain_side->getOpPtrVector().push_back(
4359 // new OpCalculateHVecTensorGradient<3, 9, 3>(
4360 // piolaStress, dataAtPts->getGradPAtPts()));
4361 // op_loop_domain_side->getOpPtrVector().push_back(
4362 // new OpCalculateHVecTensorGradient<9, 9, 3>(
4363 // bubbleField, dataAtPts->getGradPAtPts(), MBMAXTYPE));
4364
4365 op_loop_domain_side->getOpPtrVector().push_back(
4367 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
4368 if (noStretch) {
4369 op_loop_domain_side->getOpPtrVector().push_back(
4370 physicalEquations->returnOpCalculateStretchFromStress(
4372 } else {
4373 op_loop_domain_side->getOpPtrVector().push_back(
4375 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
4376 }
4377
4378 op_loop_domain_side->getOpPtrVector().push_back(
4380
4381 return fe_ptr;
4382 };
4383
4384 auto integrate_face_material_force_fe = [&](auto &&face_energy_fe) {
4387 dM, skeletonElement, face_energy_fe, 0, mField.get_comm_size());
4388
4389 auto face_exchange = CommInterface::createEntitiesPetscVector(
4390 mField.get_comm(), mField.get_moab(), 2, 3, Sev::inform);
4391
4392 auto print_loc_size = [this](auto v, auto str, auto sev) {
4394 int size;
4395 CHKERR VecGetLocalSize(v.second, &size);
4396 int low, high;
4397 CHKERR VecGetOwnershipRange(v.second, &low, &high);
4398 MOFEM_LOG("EPSYNC", sev) << str << " local size " << size << " ( "
4399 << low << " " << high << " ) ";
4402 };
4403 CHKERR print_loc_size(face_exchange, "material face_exchange",
4404 Sev::verbose);
4405
4407 mField.get_moab(), face_exchange, tags[ExhangeTags::MATERIALFORCE]);
4409 mField.get_moab(), faceExchange, tags[ExhangeTags::FACEPRESSURE]);
4410
4411 // #ifndef NDEBUG
4412 if (debug) {
4414 "front_skin_faces_material_force_" +
4415 std::to_string(mField.get_comm_rank()) + ".vtk",
4416 *skeletonFaces);
4417 }
4418 // #endif
4419
4421 };
4422
4423 CHKERR integrate_face_material_force_fe(get_face_material_force_fe());
4424
4426 };
4427
4428 auto calculate_front_material_force = [&](auto nb_J_integral_contours) {
4431
4432 auto get_conn = [&](auto e) {
4433 Range conn;
4434 CHK_MOAB_THROW(mField.get_moab().get_connectivity(&e, 1, conn, true),
4435 "get connectivity");
4436 return conn;
4437 };
4438
4439 auto get_conn_range = [&](auto e) {
4440 Range conn;
4441 CHK_MOAB_THROW(mField.get_moab().get_connectivity(e, conn, true),
4442 "get connectivity");
4443 return conn;
4444 };
4445
4446 auto get_adj = [&](auto e, auto dim) {
4447 Range adj;
4448 CHK_MOAB_THROW(mField.get_moab().get_adjacencies(&e, 1, dim, true, adj),
4449 "get adj");
4450 return adj;
4451 };
4452
4453 auto get_adj_range = [&](auto e, auto dim) {
4454 Range adj;
4455 CHK_MOAB_THROW(mField.get_moab().get_adjacencies(e, dim, true, adj,
4456 moab::Interface::UNION),
4457 "get adj");
4458 return adj;
4459 };
4460
4461 auto get_material_force = [&](auto r, auto th) {
4462 MatrixDouble material_forces(r.size(), 3, false);
4464 mField.get_moab().tag_get_data(th, r, material_forces.data().data()),
4465 "get data");
4466 return material_forces;
4467 };
4468
4469 if (mField.get_comm_rank() == 0) {
4470
4471 auto crack_edges = get_adj_range(*crackFaces, 1);
4472 auto front_nodes = get_conn_range(*frontEdges);
4473 auto body_edges = get_range_from_block(mField, "EDGES", 1);
4474 // auto front_block_edges = get_range_from_block(mField, "FRONT", 1);
4475 // front_block_edges = subtract(front_block_edges, crack_edges);
4476 // auto front_block_edges_conn = get_conn_range(front_block_edges);
4477
4478 // #ifndef NDEBUG
4479 Range all_skin_faces;
4480 Range all_front_faces;
4481 // #endif
4482
4483 auto calculate_edge_direction = [&](auto e) {
4484 const EntityHandle *conn;
4485 int num_nodes;
4487 mField.get_moab().get_connectivity(e, conn, num_nodes, true),
4488 "get connectivity");
4489 std::array<double, 6> coords;
4491 mField.get_moab().get_coords(conn, num_nodes, coords.data()),
4492 "get coords");
4494 &coords[0], &coords[1], &coords[2]};
4496 &coords[3], &coords[4], &coords[5]};
4499 t_dir(i) = t_p1(i) - t_p0(i);
4500 return t_dir;
4501 };
4502
4503 // take bubble tets at node, and then avarage over the edges
4504 auto calculate_force_through_node = [&]() {
4506
4511
4512 Range body_ents;
4513 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
4514 body_ents);
4515 auto body_skin = get_skin(mField, body_ents);
4516 auto body_skin_conn = get_conn_range(body_skin);
4517
4518 // calculate nodal material force
4519 for (auto n : front_nodes) {
4520 auto adj_tets = get_adj(n, 3);
4521 for (int ll = 0; ll < nb_J_integral_contours; ++ll) {
4522 auto conn = get_conn_range(adj_tets);
4523 adj_tets = get_adj_range(conn, 3);
4524 }
4525 auto skin_faces = get_skin(mField, adj_tets);
4526 auto material_forces = get_material_force(skin_faces, tags[0]);
4527
4528 #ifndef NDEBUG
4529 if (debug) {
4530 all_skin_faces.merge(skin_faces);
4531 }
4532 #endif
4533
4534 auto calculate_node_material_force = [&]() {
4535 auto t_face_T =
4536 getFTensor1FromPtr<SPACE_DIM>(material_forces.data().data());
4537 FTensor::Tensor1<double, SPACE_DIM> t_node_force{0., 0., 0.};
4538 for (auto face : skin_faces) {
4539
4540 FTensor::Tensor1<double, SPACE_DIM> t_face_force_tmp{0., 0., 0.};
4541 t_face_force_tmp(I) = t_face_T(I);
4542 ++t_face_T;
4543
4544 auto face_tets = intersect(get_adj(face, 3), adj_tets);
4545
4546 if (face_tets.empty()) {
4547 continue;
4548 }
4549
4550 if (face_tets.size() != 1) {
4552 "face_tets.size() != 1");
4553 }
4554
4555 int side_number, sense, offset;
4556 CHK_MOAB_THROW(mField.get_moab().side_number(face_tets[0], face,
4557 side_number, sense,
4558 offset),
4559 "moab side number");
4560 t_face_force_tmp(I) *= sense;
4561 t_node_force(I) += t_face_force_tmp(I);
4562 }
4563
4564 return t_node_force;
4565 };
4566
4567 auto calculate_crack_area_growth_direction =
4568 [&](auto n, auto &t_node_force) {
4569 // if skin is on body surface, project the direction on it
4570 FTensor::Tensor1<double, SPACE_DIM> t_project{0., 0., 0.};
4571 auto boundary_node = intersect(Range(n, n), body_skin_conn);
4572 if (boundary_node.size()) {
4573 auto faces = intersect(get_adj(n, 2), body_skin);
4574 for (auto f : faces) {
4575 FTensor::Tensor1<double, 3> t_normal_face;
4576 CHKERR mField.getInterface<Tools>()->getTriNormal(
4577 f, &t_normal_face(0));
4578 t_project(I) += t_normal_face(I);
4579 }
4580 t_project.normalize();
4581 }
4582
4583 // calculate surface projection matrix
4586 t_Q(I, J) = t_kd(I, J);
4587 if (boundary_node.size()) {
4588 t_Q(I, J) -= t_project(I) * t_project(J);
4589 }
4590
4591 auto adj_faces = intersect(get_adj(n, 2), *crackFaces);
4592 if (adj_faces.empty()) {
4593 auto adj_edges =
4594 intersect(get_adj(n, 1), unite(*frontEdges, body_edges));
4595 double l = 0;
4596 for (auto e : adj_edges) {
4597 auto t_dir = calculate_edge_direction(e);
4598 l += t_dir.l2();
4599 }
4600 l /= 2;
4601 FTensor::Tensor1<double, SPACE_DIM> t_area_dir{0., 0., 0.};
4602 FTensor::Tensor1<double, SPACE_DIM> t_node_force_tmp;
4603 t_node_force_tmp(I) = t_node_force(I);
4604 t_node_force_tmp.normalize();
4605 t_area_dir(I) = -t_node_force_tmp(I);
4606 t_area_dir(I) *= l / 2;
4607 return t_area_dir;
4608 }
4609
4610 // calculate direction
4611 auto front_edges = get_adj(n, 1);
4612 FTensor::Tensor1<double, 3> t_area_dir{0., 0., 0.};
4613 for (auto f : adj_faces) {
4614 int num_nodes;
4615 const EntityHandle *conn;
4616 CHKERR mField.get_moab().get_connectivity(f, conn, num_nodes,
4617 true);
4618 std::array<double, 9> coords;
4619 CHKERR mField.get_moab().get_coords(conn, num_nodes,
4620 coords.data());
4621 FTensor::Tensor1<double, 3> t_face_normal;
4623 CHKERR mField.getInterface<Tools>()->getTriNormal(
4624 coords.data(), &t_face_normal(0), &t_d_normal(0, 0, 0));
4625 auto n_it = std::find(conn, conn + num_nodes, n);
4626 auto n_index = std::distance(conn, n_it);
4627
4628 FTensor::Tensor2<double, 3, 3> t_face_hessian{
4629 t_d_normal(0, n_index, 0), t_d_normal(0, n_index, 1),
4630 t_d_normal(0, n_index, 2),
4631
4632 t_d_normal(1, n_index, 0), t_d_normal(1, n_index, 1),
4633 t_d_normal(1, n_index, 2),
4634
4635 t_d_normal(2, n_index, 0), t_d_normal(2, n_index, 1),
4636 t_d_normal(2, n_index, 2)};
4637
4638 FTensor::Tensor2<double, 3, 3> t_projected_hessian;
4639 t_projected_hessian(I, J) =
4640 t_Q(I, K) * (t_face_hessian(K, L) * t_Q(L, J));
4641 t_face_normal.normalize();
4642 t_area_dir(K) +=
4643 t_face_normal(I) * t_projected_hessian(I, K) / 2.;
4644 }
4645
4646 return t_area_dir;
4647 };
4648
4649 auto t_node_force = calculate_node_material_force();
4650 t_node_force(I) /= griffithEnergy; // scale all by griffith energy
4652 mField.get_moab().tag_set_data(tags[ExhangeTags::MATERIALFORCE],
4653 &n, 1, &t_node_force(0)),
4654 "set data");
4655
4656 auto get_area_dir = [&]() {
4657 FTensor::Tensor1<double, SPACE_DIM> t_area_dir{0., 0., 0.};
4658 auto adj_edges = intersect(get_adj_range(adj_tets, 1),
4659 unite(*frontEdges, body_edges));
4660 auto seed_n = get_conn_range(adj_edges);
4661 auto skin_adj_edges = get_skin(mField, adj_edges);
4662 skin_adj_edges = subtract(skin_adj_edges, body_skin_conn);
4663 seed_n = subtract(seed_n, skin_adj_edges);
4664 t_area_dir(I) = 0;
4665 for (auto sn : seed_n) {
4666 auto t_area_dir_sn =
4667 calculate_crack_area_growth_direction(sn, t_node_force);
4668 t_area_dir(I) += t_area_dir_sn(I);
4669 }
4670 for (auto sn : skin_adj_edges) {
4671 auto t_area_dir_sn =
4672 calculate_crack_area_growth_direction(sn, t_node_force);
4673 t_area_dir(I) += t_area_dir_sn(I) / 2;
4674 }
4675 return t_area_dir;
4676 };
4677
4678 auto t_area_dir = get_area_dir();
4679
4681 mField.get_moab().tag_set_data(tags[ExhangeTags::AREAGROWTH], &n,
4682 1, &t_area_dir(0)),
4683 "set data");
4684 auto griffith = -t_node_force(I) * t_area_dir(I) /
4685 (t_area_dir(K) * t_area_dir(K));
4687 mField.get_moab().tag_set_data(tags[ExhangeTags::GRIFFITHFORCE],
4688 &n, 1, &griffith),
4689 "set data");
4690 }
4691
4692 // iterate over edges, and calculate average edge material force
4693 auto ave_node_force = [&](auto th) {
4695
4696 for (auto e : *frontEdges) {
4697
4698 auto conn = get_conn(e);
4699 auto data = get_material_force(conn, th);
4700 auto t_node = getFTensor1FromPtr<SPACE_DIM>(data.data().data());
4701 FTensor::Tensor1<double, SPACE_DIM> t_edge{0., 0., 0.};
4702 for (auto n : conn) {
4703 NOT_USED(n);
4704 t_edge(I) += t_node(I);
4705 ++t_node;
4706 }
4707 t_edge(I) /= conn.size();
4708
4709 FTensor::Tensor1<double, SPACE_DIM> t_edge_direction =
4710 calculate_edge_direction(e);
4711 t_edge_direction.normalize();
4712
4717 t_cross(K) =
4718 FTensor::levi_civita(I, J, K) * t_edge_direction(I) * t_edge(J);
4719 t_edge(K) = FTensor::levi_civita(I, J, K) * t_edge_direction(J) *
4720 t_cross(I);
4721
4722 CHKERR mField.get_moab().tag_set_data(th, &e, 1, &t_edge(0));
4723 }
4725 };
4726
4727 // iterate over edges, and calculate average edge griffith energy
4728 auto ave_node_griffith_energy = [&](auto th) {
4730 for (auto e : *frontEdges) {
4732 CHKERR mField.get_moab().tag_get_data(
4733 tags[ExhangeTags::MATERIALFORCE], &e, 1, &t_edge_force(0));
4735 CHKERR mField.get_moab().tag_get_data(tags[ExhangeTags::AREAGROWTH],
4736 &e, 1, &t_edge_area_dir(0));
4737 double griffith_energy = -t_edge_force(I) * t_edge_area_dir(I) /
4738 (t_edge_area_dir(K) * t_edge_area_dir(K));
4739 CHKERR mField.get_moab().tag_set_data(th, &e, 1, &griffith_energy);
4740 }
4742 };
4743
4744 CHKERR ave_node_force(tags[ExhangeTags::MATERIALFORCE]);
4745 CHKERR ave_node_force(tags[ExhangeTags::AREAGROWTH]);
4746 CHKERR ave_node_griffith_energy(tags[ExhangeTags::GRIFFITHFORCE]);
4747
4749 };
4750
4751 CHKERR calculate_force_through_node();
4752
4753 // calculate face cross
4754 for (auto e : *frontEdges) {
4755 auto adj_faces = get_adj(e, 2);
4756 auto crack_face = intersect(get_adj(e, 2), *crackFaces);
4757
4758 // #ifndef NDEBUG
4759 if (debug) {
4760 all_front_faces.merge(adj_faces);
4761 }
4762 // #endif
4763
4765 CHKERR mField.get_moab().tag_get_data(tags[ExhangeTags::MATERIALFORCE],
4766 &e, 1, &t_edge_force(0));
4767 FTensor::Tensor1<double, SPACE_DIM> t_edge_direction =
4768 calculate_edge_direction(e);
4769 t_edge_direction.normalize();
4774 t_cross(K) = FTensor::levi_civita(I, J, K) * t_edge_direction(I) *
4775 t_edge_force(J);
4776
4777 for (auto f : adj_faces) {
4779 CHKERR mField.getInterface<Tools>()->getTriNormal(f, &t_normal(0));
4780 t_normal.normalize();
4781 int side_number, sense, offset;
4782 CHKERR mField.get_moab().side_number(f, e, side_number, sense,
4783 offset);
4784 auto dot = -sense * t_cross(I) * t_normal(I);
4785 CHK_MOAB_THROW(mField.get_moab().tag_set_data(
4786 tags[ExhangeTags::GRIFFITHFORCE], &f, 1, &dot),
4787 "set data");
4788 }
4789 }
4790
4791 #ifndef NDEBUG
4792 if (debug) {
4793 int ts_step;
4794 CHKERR TSGetStepNumber(ts, &ts_step);
4796 "front_edges_material_force_" +
4797 std::to_string(ts_step) + ".vtk",
4798 *frontEdges);
4800 "front_skin_faces_material_force_" +
4801 std::to_string(ts_step) + ".vtk",
4802 all_skin_faces);
4804 "front_faces_material_force_" +
4805 std::to_string(ts_step) + ".vtk",
4806 all_front_faces);
4807 }
4808 #endif
4809 }
4810
4811 auto edge_exchange = CommInterface::createEntitiesPetscVector(
4812 mField.get_comm(), mField.get_moab(), 1, 3, Sev::inform);
4814 mField.get_moab(), edge_exchange, tags[ExhangeTags::MATERIALFORCE]);
4816 mField.get_moab(), edge_exchange, tags[ExhangeTags::AREAGROWTH]);
4818 mField.get_moab(), edgeExchange, tags[ExhangeTags::GRIFFITHFORCE]);
4819
4821 };
4822
4823 auto print_results = [&](auto nb_J_integral_conturs) {
4825
4826 auto get_conn_range = [&](auto e) {
4827 Range conn;
4828 CHK_MOAB_THROW(mField.get_moab().get_connectivity(e, conn, true),
4829 "get connectivity");
4830 return conn;
4831 };
4832
4833 auto get_tag_data = [&](auto &ents, auto tag, auto dim) {
4834 std::vector<double> data(ents.size() * dim);
4835 CHK_MOAB_THROW(mField.get_moab().tag_get_data(tag, ents, data.data()),
4836 "get data");
4837 return data;
4838 };
4839
4840 if (mField.get_comm_rank() == 0) {
4841 auto at_nodes = [&]() {
4843 auto conn = get_conn_range(*frontEdges);
4844 auto material_force =
4845 get_tag_data(conn, tags[ExhangeTags::MATERIALFORCE], 3);
4846 auto area_growth = get_tag_data(conn, tags[ExhangeTags::AREAGROWTH], 3);
4847 auto griffith_force =
4848 get_tag_data(conn, tags[ExhangeTags::GRIFFITHFORCE], 1);
4849 std::vector<double> coords(conn.size() * 3);
4850 CHK_MOAB_THROW(mField.get_moab().get_coords(conn, coords.data()),
4851 "get coords");
4852 if (conn.size())
4853 MOFEM_LOG("EPSELF", Sev::inform) << "Material force at nodes";
4854 for (size_t i = 0; i < conn.size(); ++i) {
4855 MOFEM_LOG("EPSELF", Sev::inform)
4856 << "Node " << conn[i] << " coords " << coords[i * 3 + 0] << " "
4857 << coords[i * 3 + 1] << " " << coords[i * 3 + 2]
4858 << " material force " << material_force[i * 3 + 0] << " "
4859 << material_force[i * 3 + 1] << " " << material_force[i * 3 + 2]
4860 << " area growth " << area_growth[i * 3 + 0] << " "
4861 << area_growth[i * 3 + 1] << " " << area_growth[i * 3 + 2]
4862 << " griffith force " << std::setprecision(12)
4863 << griffith_force[i] << " contour " << nb_J_integral_conturs;
4864 }
4866 };
4867
4868 at_nodes();
4869 }
4871 };
4872
4873 CHKERR calculate_material_forces();
4874
4875 PetscBool all_conturs = PETSC_FALSE;
4876 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "",
4877 "-calculate_J_integral_all_levels", &all_conturs,
4878 PETSC_NULLPTR); // for backward compatibility
4879 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "",
4880 "-calculate_J_integral_all_contours", &all_conturs,
4881 PETSC_NULLPTR); // new name
4882
4883
4884 if (all_conturs == PETSC_TRUE) {
4885 for (int l = 0; l < nbJIntegralContours; ++l) {
4886 CHKERR calculate_front_material_force(l);
4887 CHKERR print_results(l);
4888 }
4889 }
4890
4891 CHKERR calculate_front_material_force(nbJIntegralContours);
4892 CHKERR print_results(nbJIntegralContours);
4893
4894
4895
4897}
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
Kronecker Delta class.
Tensor1< T, Tensor_Dim > normalize()
#define NOT_USED(x)
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
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
constexpr IntegrationType I
boost::shared_ptr< Range > frontAdjEdges
static int nbJIntegralContours
static double griffithEnergy
Griffith energy.
CommInterface::EntitiesPetscVector edgeExchange
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
boost::shared_ptr< Range > frontVertices
CommInterface::EntitiesPetscVector faceExchange
static MoFEMErrorCode updateEntitiesPetscVector(moab::Interface &moab, EntitiesPetscVector &vec, Tag tag, UpdateGhosts update_gosts=defaultUpdateGhosts)
Exchange data between vector and data.
static EntitiesPetscVector createEntitiesPetscVector(MPI_Comm comm, moab::Interface &moab, int dim, const int nb_coeffs, Sev sev=Sev::verbose, int root_rank=0)
Create a ghost vector for exchanging data.
virtual int get_comm_size() const =0
Calculate tenor field using tensor base, i.e. Hdiv/Hcurl.
Calculate tenor field using vectorial base, i.e. Hdiv/Hcurl.
Calculate symmetric tensor field values at integration pts.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Specialization for double precision vector field values calculation.
Element used to execute operators on side of the element.

◆ calculateOrientation()

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

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

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

Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 4899 of file EshelbianPlasticity.cpp.

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

◆ createCrackSurfaceMeshset()

MoFEMErrorCode EshelbianCore::createCrackSurfaceMeshset ( )
Examples
ep.cpp, mofem/users_modules/eshelbian_plasticity/ep.cpp, and mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 6725 of file EshelbianPlasticity.cpp.

6725 {
6727 auto meshset_mng = mField.getInterface<MeshsetsManager>();
6728 while (meshset_mng->checkMeshset(addCrackMeshsetId, BLOCKSET))
6730 MOFEM_LOG("EP", Sev::inform)
6731 << "Crack added surface meshset " << addCrackMeshsetId;
6732 CHKERR meshset_mng->addMeshset(BLOCKSET, addCrackMeshsetId, "CRACK_COMPUTED");
6734};
MoFEMErrorCode addMeshset(const CubitBCType cubit_bc_type, const int ms_id, const std::string name="")
Add CUBIT meshset to manager.

◆ createExchangeVectors()

MoFEMErrorCode EshelbianCore::createExchangeVectors ( Sev  sev)
Examples
ep.cpp, mofem/users_modules/eshelbian_plasticity/ep.cpp, and mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 7030 of file EshelbianPlasticity.cpp.

7030 {
7032
7033 auto print_loc_size = [this](auto v, auto str, auto sev) {
7035 int size;
7036 CHKERR VecGetLocalSize(v.second, &size);
7037 int low, high;
7038 CHKERR VecGetOwnershipRange(v.second, &low, &high);
7039 MOFEM_LOG("EPSYNC", sev) << str << " local size " << size << " ( " << low
7040 << " " << high << " ) ";
7043 };
7044
7046 mField.get_comm(), mField.get_moab(), 3, 1, sev);
7047 CHKERR print_loc_size(volumeExchange, "volumeExchange", sev);
7049 mField.get_comm(), mField.get_moab(), 2, 1, Sev::inform);
7050 CHKERR print_loc_size(faceExchange, "faceExchange", sev);
7052 mField.get_comm(), mField.get_moab(), 1, 1, Sev::inform);
7053 CHKERR print_loc_size(edgeExchange, "edgeExchange", sev);
7055 mField.get_comm(), mField.get_moab(), 0, 3, Sev::inform);
7056 CHKERR print_loc_size(vertexExchange, "vertexExchange", sev);
7057
7059}
CommInterface::EntitiesPetscVector volumeExchange

◆ d_f_linear()

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

◆ d_f_log()

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

◆ d_f_log_e()

static double EshelbianCore::d_f_log_e ( const double  v)
inlinestatic
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 95 of file EshelbianCore.hpp.

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

◆ d_f_log_e_quadratic()

static double EshelbianCore::d_f_log_e_quadratic ( const double  v)
inlinestatic
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 64 of file EshelbianCore.hpp.

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

◆ dd_f_linear()

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

◆ dd_f_log()

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

◆ dd_f_log_e()

static double EshelbianCore::dd_f_log_e ( const double  v)
inlinestatic
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 105 of file EshelbianCore.hpp.

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

◆ dd_f_log_e_quadratic()

static double EshelbianCore::dd_f_log_e_quadratic ( const double  v)
inlinestatic
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 74 of file EshelbianCore.hpp.

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

◆ f_linear()

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

◆ f_log()

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

◆ f_log_e()

static double EshelbianCore::f_log_e ( const double  v)
inlinestatic
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 82 of file EshelbianCore.hpp.

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

◆ f_log_e_quadratic()

static double EshelbianCore::f_log_e_quadratic ( const double  v)
inlinestatic
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 54 of file EshelbianCore.hpp.

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

◆ getBc()

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

Definition at line 243 of file EshelbianCore.hpp.

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

◆ getExternalStrain()

MoFEMErrorCode EshelbianCore::getExternalStrain ( )
Examples
ep.cpp, mofem/users_modules/eshelbian_plasticity/ep.cpp, and mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 6983 of file EshelbianPlasticity.cpp.

6983 {
6985
6986 auto getExternalStrain = [&](boost::shared_ptr<ExternalStrainVec> &ext_strain_vec_ptr,
6987 const std::string block_name,
6988 const int nb_attributes) {
6990 for (auto it : mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
6991 std::regex((boost::format("%s(.*)") % block_name).str()))
6992 ) {
6993 std::vector<double> block_attributes;
6994 CHKERR it->getAttributes(block_attributes);
6995 if (block_attributes.size() < nb_attributes) {
6996 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
6997 "In block %s expected %d attributes, but given %ld",
6998 it->getName().c_str(), nb_attributes, block_attributes.size());
6999 }
7000
7001 auto get_block_ents = [&]() {
7002 Range ents;
7003 CHKERR mField.get_moab().get_entities_by_handle(it->meshset, ents,
7004 true);
7005 return ents;
7006 };
7007 auto Ents = get_block_ents();
7008 ext_strain_vec_ptr->emplace_back(it->getName(), block_attributes,
7009 get_block_ents());
7010 }
7012 };
7013
7014 externalStrainVecPtr = boost::make_shared<ExternalStrainVec>();
7015 CHKERR getExternalStrain(externalStrainVecPtr, "EXTERNALSTRAIN", 2);
7016
7017 auto ts_pre_stretch =
7018 boost::make_shared<DynamicRelaxationTimeScale>("externalstrain_history.txt");
7019 for (auto &ext_strain_block: *externalStrainVecPtr) {
7020 MOFEM_LOG("EP", Sev::noisy)
7021 << "Add time scaling external strain: " << ext_strain_block.blockName;
7022 timeScaleMap[ext_strain_block.blockName] =
7024 ts_pre_stretch, "externalstrain_history", ".txt", ext_strain_block.blockName);
7025 }
7026
7028}
boost::shared_ptr< ExternalStrainVec > externalStrainVecPtr
std::map< std::string, boost::shared_ptr< ScalingMethod > > timeScaleMap
MoFEMErrorCode getExternalStrain()
static boost::shared_ptr< ScalingMethod > get(boost::shared_ptr< ScalingMethod > ts, std::string file_prefix, std::string file_suffix, std::string block_name, Args &&...args)

◆ getOptions()

MoFEMErrorCode EshelbianCore::getOptions ( )
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 922 of file EshelbianPlasticity.cpp.

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

◆ getSpatialDispBc()

MoFEMErrorCode EshelbianCore::getSpatialDispBc ( )

[Getting norms]

Examples
ep.cpp, mofem/users_modules/eshelbian_plasticity/ep.cpp, and mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 6805 of file EshelbianPlasticity.cpp.

6805 {
6807
6808 auto bc_mng = mField.getInterface<BcManager>();
6810 "", piolaStress, false, false);
6811
6812 bcSpatialDispVecPtr = boost::make_shared<BcDispVec>();
6813 for (auto bc : bc_mng->getBcMapByBlockName()) {
6814 if (auto disp_bc = bc.second->dispBcPtr) {
6815
6816 auto [field_name, block_name] =
6818 MOFEM_LOG("EP", Sev::inform)
6819 << "Field name: " << field_name << " Block name: " << block_name;
6820 MOFEM_LOG("EP", Sev::noisy) << "Displacement BC: " << *disp_bc;
6821
6822 std::vector<double> block_attributes(6, 0.);
6823 if (disp_bc->data.flag1 == 1) {
6824 block_attributes[0] = disp_bc->data.value1;
6825 block_attributes[3] = 1;
6826 }
6827 if (disp_bc->data.flag2 == 1) {
6828 block_attributes[1] = disp_bc->data.value2;
6829 block_attributes[4] = 1;
6830 }
6831 if (disp_bc->data.flag3 == 1) {
6832 block_attributes[2] = disp_bc->data.value3;
6833 block_attributes[5] = 1;
6834 }
6835 auto faces = bc.second->bcEnts.subset_by_dimension(2);
6836 bcSpatialDispVecPtr->emplace_back(block_name, block_attributes, faces);
6837 }
6838 }
6839 // old way of naming blocksets for displacement BCs
6840 CHKERR getBc(bcSpatialDispVecPtr, "SPATIAL_DISP_BC", 6);
6841
6843 boost::make_shared<NormalDisplacementBcVec>();
6844 for (auto bc : bc_mng->getBcMapByBlockName()) {
6845 auto block_name = "(.*)NORMAL_DISPLACEMENT(.*)";
6846 std::regex reg_name(block_name);
6847 if (std::regex_match(bc.first, reg_name)) {
6848 auto [field_name, block_name] =
6850 MOFEM_LOG("EP", Sev::inform)
6851 << "Field name: " << field_name << " Block name: " << block_name;
6853 block_name, bc.second->bcAttributes,
6854 bc.second->bcEnts.subset_by_dimension(2));
6855 }
6856 }
6857
6859 boost::make_shared<AnalyticalDisplacementBcVec>();
6860
6861 for (auto bc : bc_mng->getBcMapByBlockName()) {
6862 auto block_name = "(.*)ANALYTICAL_DISPLACEMENT(.*)";
6863 std::regex reg_name(block_name);
6864 if (std::regex_match(bc.first, reg_name)) {
6865 auto [field_name, block_name] =
6867 MOFEM_LOG("EP", Sev::inform)
6868 << "Field name: " << field_name << " Block name: " << block_name;
6870 block_name, bc.second->bcAttributes,
6871 bc.second->bcEnts.subset_by_dimension(2));
6872 }
6873 }
6874
6875 auto ts_displacement =
6876 boost::make_shared<DynamicRelaxationTimeScale>("disp_history.txt");
6877 for (auto &bc : *bcSpatialDispVecPtr) {
6878 MOFEM_LOG("EP", Sev::noisy)
6879 << "Add time scaling displacement BC: " << bc.blockName;
6880 timeScaleMap[bc.blockName] =
6882 ts_displacement, "disp_history", ".txt", bc.blockName);
6883 }
6884
6885 auto ts_normal_displacement =
6886 boost::make_shared<DynamicRelaxationTimeScale>("normal_disp_history.txt");
6887 for (auto &bc : *bcSpatialNormalDisplacementVecPtr) {
6888 MOFEM_LOG("EP", Sev::noisy)
6889 << "Add time scaling normal displacement BC: " << bc.blockName;
6890 timeScaleMap[bc.blockName] =
6892 ts_normal_displacement, "normal_disp_history", ".txt",
6893 bc.blockName);
6894 }
6895
6897}
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 DOFs on block entities for boundary conditions.
MoFEMErrorCode getBc(boost::shared_ptr< BC > &bc_vec_ptr, const std::string block_name, const int nb_attributes)
Boundary condition manager for finite element problem setup.
static std::pair< std::string, std::string > extractStringFromBlockId(const std::string block_id, const std::string prb_name)
Extract block name and block name from block id.
Definition of the displacement bc data structure.
Definition BCData.hpp:72

◆ getSpatialRotationBc()

MoFEMErrorCode EshelbianCore::getSpatialRotationBc ( )
inline
Examples
ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

Definition at line 271 of file EshelbianCore.hpp.

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

◆ getSpatialTractionBc()

MoFEMErrorCode EshelbianCore::getSpatialTractionBc ( )
Examples
ep.cpp, mofem/users_modules/eshelbian_plasticity/ep.cpp, and mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 6899 of file EshelbianPlasticity.cpp.

6899 {
6901
6902 auto bc_mng = mField.getInterface<BcManager>();
6904 false, false);
6905
6906 bcSpatialTractionVecPtr = boost::make_shared<TractionBcVec>();
6907
6908 for (auto bc : bc_mng->getBcMapByBlockName()) {
6909 if (auto force_bc = bc.second->forceBcPtr) {
6910
6911 auto [field_name, block_name] =
6913 MOFEM_LOG("EP", Sev::inform)
6914 << "Field name: " << field_name << " Block name: " << block_name;
6915 MOFEM_LOG("EP", Sev::noisy) << "Force BC: " << *force_bc;
6916
6917 std::vector<double> block_attributes(6, 0.);
6918 block_attributes[0] = -force_bc->data.value3 * force_bc->data.value1;
6919 block_attributes[3] = 1;
6920 block_attributes[1] = -force_bc->data.value4 * force_bc->data.value1;
6921 block_attributes[4] = 1;
6922 block_attributes[2] = -force_bc->data.value5 * force_bc->data.value1;
6923 block_attributes[5] = 1;
6924 auto faces = bc.second->bcEnts.subset_by_dimension(2);
6925 bcSpatialTractionVecPtr->emplace_back(block_name, block_attributes,
6926 faces);
6927 }
6928 }
6929 CHKERR getBc(bcSpatialTractionVecPtr, "SPATIAL_TRACTION_BC", 6);
6930
6931 bcSpatialPressureVecPtr = boost::make_shared<PressureBcVec>();
6932 for (auto bc : bc_mng->getBcMapByBlockName()) {
6933 auto block_name = "(.*)PRESSURE(.*)";
6934 std::regex reg_name(block_name);
6935 if (std::regex_match(bc.first, reg_name)) {
6936
6937 auto [field_name, block_name] =
6939 MOFEM_LOG("EP", Sev::inform)
6940 << "Field name: " << field_name << " Block name: " << block_name;
6941 bcSpatialPressureVecPtr->emplace_back(
6942 block_name, bc.second->bcAttributes,
6943 bc.second->bcEnts.subset_by_dimension(2));
6944 }
6945 }
6946
6948 boost::make_shared<AnalyticalTractionBcVec>();
6949
6950 for (auto bc : bc_mng->getBcMapByBlockName()) {
6951 auto block_name = "(.*)ANALYTICAL_TRACTION(.*)";
6952 std::regex reg_name(block_name);
6953 if (std::regex_match(bc.first, reg_name)) {
6954 auto [field_name, block_name] =
6956 MOFEM_LOG("EP", Sev::inform)
6957 << "Field name: " << field_name << " Block name: " << block_name;
6959 block_name, bc.second->bcAttributes,
6960 bc.second->bcEnts.subset_by_dimension(2));
6961 }
6962 }
6963
6964 auto ts_traction =
6965 boost::make_shared<DynamicRelaxationTimeScale>("traction_history.txt");
6966 for (auto &bc : *bcSpatialTractionVecPtr) {
6967 timeScaleMap[bc.blockName] =
6969 ts_traction, "traction_history", ".txt", bc.blockName);
6970 }
6971
6972 auto ts_pressure =
6973 boost::make_shared<DynamicRelaxationTimeScale>("pressure_history.txt");
6974 for (auto &bc : *bcSpatialPressureVecPtr) {
6975 timeScaleMap[bc.blockName] =
6977 ts_pressure, "pressure_history", ".txt", bc.blockName);
6978 }
6979
6981}
Definition of the force bc data structure.
Definition BCData.hpp:135

◆ getSpatialTractionFreeBc()

MoFEMErrorCode EshelbianCore::getSpatialTractionFreeBc ( const EntityHandle  meshset = 0)
inline
Examples
ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

Definition at line 305 of file EshelbianCore.hpp.

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

◆ gettingNorms()

MoFEMErrorCode EshelbianCore::gettingNorms ( )

[Getting norms]

Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 6737 of file EshelbianPlasticity.cpp.

6737 {
6739
6740 auto post_proc_norm_fe =
6741 boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
6742
6743 auto post_proc_norm_rule_hook = [](int, int, int p) -> int {
6744 return 2 * (p);
6745 };
6746 post_proc_norm_fe->getRuleHook = post_proc_norm_rule_hook;
6747
6748 post_proc_norm_fe->getUserPolynomialBase() =
6749 boost::shared_ptr<BaseFunction>(new CGGUserPolynomialBase());
6750
6751 CHKERR EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
6752 post_proc_norm_fe->getOpPtrVector(), {L2, H1, HDIV}, materialH1Positions,
6754
6755 enum NORMS { U_NORM_L2 = 0, U_NORM_H1, PIOLA_NORM, U_ERROR_L2, LAST_NORM };
6756 auto norms_vec =
6757 createVectorMPI(mField.get_comm(), LAST_NORM, PETSC_DETERMINE);
6758 CHKERR VecZeroEntries(norms_vec);
6759
6760 auto u_l2_ptr = boost::make_shared<MatrixDouble>();
6761 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
6762 post_proc_norm_fe->getOpPtrVector().push_back(
6764 post_proc_norm_fe->getOpPtrVector().push_back(
6766 post_proc_norm_fe->getOpPtrVector().push_back(
6767 new OpCalcNormL2Tensor1<SPACE_DIM>(u_l2_ptr, norms_vec, U_NORM_L2));
6768 post_proc_norm_fe->getOpPtrVector().push_back(
6769 new OpCalcNormL2Tensor1<SPACE_DIM>(u_h1_ptr, norms_vec, U_NORM_H1));
6770 post_proc_norm_fe->getOpPtrVector().push_back(
6771 new OpCalcNormL2Tensor1<SPACE_DIM>(u_l2_ptr, norms_vec, U_ERROR_L2,
6772 u_h1_ptr));
6773
6774 auto piola_ptr = boost::make_shared<MatrixDouble>();
6775 post_proc_norm_fe->getOpPtrVector().push_back(
6777 post_proc_norm_fe->getOpPtrVector().push_back(
6779 MBMAXTYPE));
6780
6781 post_proc_norm_fe->getOpPtrVector().push_back(
6782 new OpCalcNormL2Tensor2<3, 3>(piola_ptr, norms_vec, PIOLA_NORM));
6783
6784 TetPolynomialBase::switchCacheBaseOn<HDIV>({post_proc_norm_fe.get()});
6786 *post_proc_norm_fe);
6787 TetPolynomialBase::switchCacheBaseOff<HDIV>({post_proc_norm_fe.get()});
6788
6789 CHKERR VecAssemblyBegin(norms_vec);
6790 CHKERR VecAssemblyEnd(norms_vec);
6791 const double *norms;
6792 CHKERR VecGetArrayRead(norms_vec, &norms);
6793 MOFEM_LOG("EP", Sev::inform) << "norm_u: " << std::sqrt(norms[U_NORM_L2]);
6794 MOFEM_LOG("EP", Sev::inform) << "norm_u_h1: " << std::sqrt(norms[U_NORM_H1]);
6795 MOFEM_LOG("EP", Sev::inform)
6796 << "norm_error_u_l2: " << std::sqrt(norms[U_ERROR_L2]);
6797 MOFEM_LOG("EP", Sev::inform)
6798 << "norm_piola: " << std::sqrt(norms[PIOLA_NORM]);
6799 CHKERR VecRestoreArrayRead(norms_vec, &norms);
6800
6802}
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.
CGG User Polynomial Base.
Get norm of input MatrixDouble for Tensor1.
Get norm of input MatrixDouble for Tensor2.

◆ getTractionFreeBc()

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

Remove all, but entities where kinematic constrains are applied.

Parameters
meshset
bc_ptr
disp_block_set_name
rot_block_set_name
contact_set_name
Returns
MoFEMErrorCode
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 2146 of file EshelbianPlasticity.cpp.

2148 {
2150
2151 // get skin from all tets
2152 Range tets;
2153 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
2154 Range tets_skin_part;
2155 Skinner skin(&mField.get_moab());
2156 CHKERR skin.find_skin(0, tets, false, tets_skin_part);
2157 ParallelComm *pcomm =
2158 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
2159 Range tets_skin;
2160 CHKERR pcomm->filter_pstatus(tets_skin_part,
2161 PSTATUS_SHARED | PSTATUS_MULTISHARED,
2162 PSTATUS_NOT, -1, &tets_skin);
2163
2164 bc_ptr->resize(3);
2165 for (int dd = 0; dd != 3; ++dd)
2166 (*bc_ptr)[dd] = tets_skin;
2167
2168 // Do not remove dofs on which traction is applied
2170 for (auto &v : *bcSpatialDispVecPtr) {
2171 if (v.flags[0])
2172 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2173 if (v.flags[1])
2174 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2175 if (v.flags[2])
2176 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2177 }
2178
2179 // Do not remove dofs on which rotation is applied
2181 for (auto &v : *bcSpatialRotationVecPtr) {
2182 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2183 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2184 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2185 }
2186
2188 for (auto &v : *bcSpatialNormalDisplacementVecPtr) {
2189 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2190 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2191 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2192 }
2193
2196 if (v.flags[0])
2197 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2198 if (v.flags[1])
2199 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2200 if (v.flags[2])
2201 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2202 }
2203
2205 for (auto &v : *bcSpatialTractionVecPtr) {
2206 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2207 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2208 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2209 }
2210
2212 for (auto &v : *bcSpatialAnalyticalTractionVecPtr) {
2213 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2214 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2215 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2216 }
2217
2219 for (auto &v : *bcSpatialPressureVecPtr) {
2220 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2221 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2222 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2223 }
2224
2225 // remove contact
2226 for (auto m : mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
2227 std::regex((boost::format("%s(.*)") % contact_set_name).str()))) {
2228 Range faces;
2229 CHKERR m->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2, faces,
2230 true);
2231 (*bc_ptr)[0] = subtract((*bc_ptr)[0], faces);
2232 (*bc_ptr)[1] = subtract((*bc_ptr)[1], faces);
2233 (*bc_ptr)[2] = subtract((*bc_ptr)[2], faces);
2234 }
2235
2237}
const Tensor2_symmetric_Expr< const ddTensor0< T, Dim, i, j >, typename promote< T, double >::V, Dim, i, j > dd(const Tensor0< T * > &a, const Index< i, Dim > index1, const Index< j, Dim > index2, const Tensor1< int, Dim > &d_ijk, const Tensor1< double, Dim > &d_xyz)
Definition ddTensor0.hpp:33

◆ inv_d_f_linear()

static double EshelbianCore::inv_d_f_linear ( const double  v)
inlinestatic

◆ inv_d_f_log()

static double EshelbianCore::inv_d_f_log ( const double  v)
inlinestatic
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 151 of file EshelbianCore.hpp.

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

◆ inv_d_f_log_e()

static double EshelbianCore::inv_d_f_log_e ( const double  v)
inlinestatic
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 124 of file EshelbianCore.hpp.

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

◆ inv_dd_f_linear()

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

◆ inv_dd_f_log()

static double EshelbianCore::inv_dd_f_log ( const double  v)
inlinestatic
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 154 of file EshelbianCore.hpp.

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

◆ inv_dd_f_log_e()

static double EshelbianCore::inv_dd_f_log_e ( const double  v)
inlinestatic
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 130 of file EshelbianCore.hpp.

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

◆ inv_f_linear()

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

◆ inv_f_log()

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

◆ inv_f_log_e()

static double EshelbianCore::inv_f_log_e ( const double  v)
inlinestatic
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 115 of file EshelbianCore.hpp.

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

◆ postProcessResults()

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

Definition at line 3667 of file EshelbianPlasticity.cpp.

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

◆ postProcessSkeletonResults()

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

Definition at line 4161 of file EshelbianPlasticity.cpp.

4163 {
4165
4167
4168 auto post_proc_mesh = boost::make_shared<moab::Core>();
4169 auto post_proc_ptr =
4170 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
4171 mField, post_proc_mesh);
4172 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM - 1, SPACE_DIM>::add(
4173 post_proc_ptr->getOpPtrVector(), {L2}, materialH1Positions,
4175
4176 auto hybrid_disp = boost::make_shared<MatrixDouble>();
4177 post_proc_ptr->getOpPtrVector().push_back(
4179 post_proc_ptr->getOpPtrVector().push_back(
4181 hybridSpatialDisp, dataAtPts->getGradHybridDispAtPts()));
4182
4183 auto op_loop_domain_side =
4185 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
4186 post_proc_ptr->getOpPtrVector().push_back(op_loop_domain_side);
4187
4188 // evaluated in side domain, that is op_loop_domain_side
4189 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
4190 boost::make_shared<CGGUserPolynomialBase>();
4191 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4192 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
4194 op_loop_domain_side->getOpPtrVector().push_back(
4196 piolaStress, dataAtPts->getApproxPAtPts()));
4197 op_loop_domain_side->getOpPtrVector().push_back(
4199 bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
4200 op_loop_domain_side->getOpPtrVector().push_back(
4202 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
4203 if (noStretch) {
4204 op_loop_domain_side->getOpPtrVector().push_back(
4205 physicalEquations->returnOpCalculateStretchFromStress(
4207 } else {
4208 op_loop_domain_side->getOpPtrVector().push_back(
4210 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
4211 }
4212
4214
4215 OpPPMap::DataMapMat vec_fields;
4216 vec_fields["HybridDisplacement"] = hybrid_disp;
4217 vec_fields["Omega"] = dataAtPts->getRotAxisAtPts();
4218 OpPPMap::DataMapMat mat_fields;
4219 mat_fields["PiolaStress"] = dataAtPts->getApproxPAtPts();
4220 mat_fields["HybridDisplacementGradient"] =
4221 dataAtPts->getGradHybridDispAtPts();
4222 OpPPMap::DataMapMat mat_fields_symm;
4223 mat_fields_symm["LogSpatialStretch"] = dataAtPts->getLogStretchTensorAtPts();
4224
4225 post_proc_ptr->getOpPtrVector().push_back(
4226
4227 new OpPPMap(
4228
4229 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4230
4231 {},
4232
4233 vec_fields,
4234
4235 mat_fields,
4236
4237 mat_fields_symm
4238
4239 )
4240
4241 );
4242
4243 if (f_residual) {
4244 auto hybrid_res = boost::make_shared<MatrixDouble>();
4245 post_proc_ptr->getOpPtrVector().push_back(
4247 hybridSpatialDisp, hybrid_res,
4248 SmartPetscObj<Vec>(f_residual, true)));
4250 post_proc_ptr->getOpPtrVector().push_back(
4251
4252 new OpPPMap(
4253
4254 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4255
4256 {},
4257
4258 {{"res_hybrid", hybrid_res}},
4259
4260 {},
4261
4262 {}
4263
4264 )
4265
4266 );
4267 }
4268
4269 post_proc_ptr->setTagsToTransfer(tags_to_transfer);
4270
4271 auto post_proc_begin =
4273 CHKERR DMoFEMPreProcessFiniteElements(dM, post_proc_begin.getFEMethod());
4275 auto post_proc_end = PostProcBrokenMeshInMoabBaseEnd(mField, post_proc_mesh);
4276 CHKERR DMoFEMPostProcessFiniteElements(dM, post_proc_end.getFEMethod());
4277
4278 CHKERR post_proc_end.writeFile(file.c_str());
4279
4281}

◆ projectGeometry()

MoFEMErrorCode EshelbianCore::projectGeometry ( const EntityHandle  meshset = 0)
Examples
ep.cpp, mofem/users_modules/eshelbian_plasticity/ep.cpp, and mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 1410 of file EshelbianPlasticity.cpp.

1410 {
1412
1413 Range meshset_ents;
1414 CHKERR mField.get_moab().get_entities_by_handle(meshset, meshset_ents);
1415
1416 auto project_ho_geometry = [&](auto field) {
1418 return mField.loop_dofs(field, ent_method);
1419 };
1420 CHKERR project_ho_geometry(materialH1Positions);
1421
1422 auto get_adj_front_edges = [&](auto &front_edges) {
1423 Range front_crack_nodes;
1424 Range crack_front_edges_with_both_nodes_not_at_front;
1425
1426 if (mField.get_comm_rank() == 0) {
1427 auto &moab = mField.get_moab();
1429 moab.get_connectivity(front_edges, front_crack_nodes, true),
1430 "get_connectivity failed");
1431 Range crack_front_edges;
1432 CHK_MOAB_THROW(moab.get_adjacencies(front_crack_nodes, SPACE_DIM - 2,
1433 false, crack_front_edges,
1434 moab::Interface::UNION),
1435 "get_adjacencies failed");
1436 Range crack_front_edges_nodes;
1437 CHK_MOAB_THROW(moab.get_connectivity(crack_front_edges,
1438 crack_front_edges_nodes, true),
1439 "get_connectivity failed");
1440 // those nodes are hannging nodes
1441 crack_front_edges_nodes =
1442 subtract(crack_front_edges_nodes, front_crack_nodes);
1443 Range crack_front_edges_with_both_nodes_not_at_front;
1445 moab.get_adjacencies(crack_front_edges_nodes, 1, false,
1446 crack_front_edges_with_both_nodes_not_at_front,
1447 moab::Interface::UNION),
1448 "get_adjacencies failed");
1449 // those edges are have one node not at the crack front
1450 crack_front_edges_with_both_nodes_not_at_front =
1451 intersect(crack_front_edges,
1452 crack_front_edges_with_both_nodes_not_at_front);
1453 }
1454
1455 front_crack_nodes = send_type(mField, front_crack_nodes, MBVERTEX);
1456 crack_front_edges_with_both_nodes_not_at_front = send_type(
1457 mField, crack_front_edges_with_both_nodes_not_at_front, MBEDGE);
1458
1459 return std::make_pair(boost::make_shared<Range>(front_crack_nodes),
1460 boost::make_shared<Range>(
1461 crack_front_edges_with_both_nodes_not_at_front));
1462 };
1463
1464 crackFaces = boost::make_shared<Range>(
1465 get_range_from_block(mField, "CRACK", SPACE_DIM - 1));
1466 frontEdges =
1467 boost::make_shared<Range>(get_crack_front_edges(mField, *crackFaces));
1468 auto [front_vertices, front_adj_edges] = get_adj_front_edges(*frontEdges);
1469 frontVertices = front_vertices;
1470 frontAdjEdges = front_adj_edges;
1471
1472 MOFEM_LOG("EP", Sev::inform)
1473 << "Number of crack faces: " << crackFaces->size();
1474 MOFEM_LOG("EP", Sev::inform)
1475 << "Number of front edges: " << frontEdges->size();
1476 MOFEM_LOG("EP", Sev::inform)
1477 << "Number of front vertices: " << frontVertices->size();
1478 MOFEM_LOG("EP", Sev::inform)
1479 << "Number of front adjacent edges: " << frontAdjEdges->size();
1480
1481#ifndef NDEBUG
1482 if (crackingOn) {
1483 auto rank = mField.get_comm_rank();
1484 // CHKERR save_range(mField.get_moab(),
1485 // (boost::format("meshset_ents_%d.vtk") % rank).str(),
1486 // meshset_ents);
1488 (boost::format("crack_faces_%d.vtk") % rank).str(),
1489 *crackFaces);
1491 (boost::format("front_edges_%d.vtk") % rank).str(),
1492 *frontEdges);
1493 // CHKERR save_range(mField.get_moab(),
1494 // (boost::format("front_vertices_%d.vtk") % rank).str(),
1495 // *frontVertices);
1496 // CHKERR save_range(mField.get_moab(),
1497 // (boost::format("front_adj_edges_%d.vtk") % rank).str(),
1498 // *frontAdjEdges);
1499 }
1500#endif // NDEBUG
1501
1502 auto set_singular_dofs = [&](auto &front_adj_edges, auto &front_vertices) {
1504 auto &moab = mField.get_moab();
1505
1506 double eps = 1;
1507 double beta = 0;
1508 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "-singularity_eps", &beta,
1509 PETSC_NULLPTR);
1510 MOFEM_LOG("EP", Sev::inform) << "Singularity eps " << beta;
1511 eps -= beta;
1512
1513 auto field_blas = mField.getInterface<FieldBlas>();
1514 auto lambda =
1515 [&](boost::shared_ptr<FieldEntity> field_entity_ptr) -> MoFEMErrorCode {
1517 FTENSOR_INDEX(3, i);
1518 FTENSOR_INDEX(3, j);
1519
1520 auto nb_dofs = field_entity_ptr->getEntFieldData().size();
1521 if (nb_dofs == 0) {
1523 }
1524
1525#ifndef NDEBUG
1526 if (field_entity_ptr->getNbOfCoeffs() != 3)
1528 "Expected 3 coefficients per edge");
1529 if (nb_dofs % 3 != 0)
1531 "Expected multiple of 3 coefficients per edge");
1532#endif // NDEBUG
1533
1534 auto get_conn = [&]() {
1535 int num_nodes;
1536 const EntityHandle *conn;
1537 CHKERR moab.get_connectivity(field_entity_ptr->getEnt(), conn,
1538 num_nodes, false);
1539 return std::make_pair(conn, num_nodes);
1540 };
1541
1542 auto get_dir = [&](auto &&conn_p) {
1543 auto [conn, num_nodes] = conn_p;
1544 double coords[6];
1545 CHKERR moab.get_coords(conn, num_nodes, coords);
1546 FTensor::Tensor1<double, 3> t_edge_dir{coords[3] - coords[0],
1547 coords[4] - coords[1],
1548 coords[5] - coords[2]};
1549 return t_edge_dir;
1550 };
1551
1552 auto get_singularity_dof = [&](auto &&conn_p, auto &&t_edge_dir) {
1553 auto [conn, num_nodes] = conn_p;
1554 FTensor::Tensor1<double, 3> t_singularity_dof{0., 0., 0.};
1555 if (front_vertices.find(conn[0]) != front_vertices.end()) {
1556 t_singularity_dof(i) = t_edge_dir(i) * (-eps);
1557 } else if (front_vertices.find(conn[1]) != front_vertices.end()) {
1558 t_singularity_dof(i) = t_edge_dir(i) * eps;
1559 }
1560 return t_singularity_dof;
1561 };
1562
1563 auto t_singularity_dof =
1564 get_singularity_dof(get_conn(), get_dir(get_conn()));
1565
1566 auto field_data = field_entity_ptr->getEntFieldData();
1568 &field_data[0], &field_data[1], &field_data[2]};
1569
1570 t_dof(i) = t_singularity_dof(i);
1571 ++t_dof;
1572 for (auto n = 1; n < field_data.size() / 3; ++n) {
1573 t_dof(i) = 0;
1574 ++t_dof;
1575 }
1576
1578 };
1579
1580 CHKERR field_blas->fieldLambdaOnEntities(lambda, materialH1Positions,
1581 &front_adj_edges);
1582
1584 };
1585
1586 if (setSingularity)
1587 CHKERR set_singular_dofs(*frontAdjEdges, *frontVertices);
1588
1590}
static auto get_crack_front_edges(MoFEM::Interface &m_field, Range crack_faces)
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)
Basic algebra on fields.
Definition FieldBlas.hpp:21
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
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 898 of file EshelbianPlasticity.cpp.

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

◆ saveOrgCoords()

MoFEMErrorCode EshelbianCore::saveOrgCoords ( )
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 6705 of file EshelbianPlasticity.cpp.

6705 {
6707 auto crack_faces =
6708 get_range_from_block(mField, "CRACK_COMPUTED", SPACE_DIM - 1);
6709 Range conn;
6710 CHKERR mField.get_moab().get_connectivity(crack_faces, conn, true);
6711 Range verts;
6712 CHKERR mField.get_moab().get_entities_by_type(0, MBVERTEX, verts);
6713 verts = subtract(verts, conn);
6714 std::vector<double> coords(3 * verts.size());
6715 CHKERR mField.get_moab().get_coords(verts, coords.data());
6716 double def_coords[] = {0., 0., 0.};
6717 Tag th_org_coords;
6718 CHKERR mField.get_moab().tag_get_handle(
6719 "ORG_COORDS", 3, MB_TYPE_DOUBLE, th_org_coords,
6720 MB_TAG_CREAT | MB_TAG_DENSE, def_coords);
6721 CHKERR mField.get_moab().tag_set_data(th_org_coords, verts, coords.data());
6723}

◆ setBaseVolumeElementOps()

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

Definition at line 2262 of file EshelbianPlasticity.cpp.

2265 {
2267
2268 auto bubble_cache =
2269 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0, MatrixDouble());
2270 fe->getUserPolynomialBase() =
2271 boost::make_shared<CGGUserPolynomialBase>(bubble_cache);
2272 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2273 fe->getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions, frontAdjEdges);
2274
2275 // set integration rule
2276 fe->getRuleHook = [](int, int, int) { return -1; };
2277 fe->setRuleHook = SetIntegrationAtFrontVolume(frontVertices, frontAdjEdges);
2278 // fe->getRuleHook = VolRule();
2279
2280 if (!dataAtPts) {
2281 dataAtPts =
2282 boost::shared_ptr<DataAtIntegrationPts>(new DataAtIntegrationPts());
2283 dataAtPts->physicsPtr = physicalEquations;
2284 }
2285
2286 // calculate fields values
2287 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
2288 piolaStress, dataAtPts->getApproxPAtPts()));
2289 fe->getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
2290 bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
2291 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorDivergence<3, 3>(
2292 piolaStress, dataAtPts->getDivPAtPts()));
2293
2294 if (noStretch) {
2295 fe->getOpPtrVector().push_back(
2296 physicalEquations->returnOpCalculateStretchFromStress(
2298 } else {
2299 fe->getOpPtrVector().push_back(
2301 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
2302 }
2303
2304 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2305 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
2306 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2307 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
2308 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2309 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
2310
2311 // H1 displacements
2312 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2313 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
2314 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldGradient<3, 3>(
2315 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
2316
2317 // velocities
2318 if (calc_rates) {
2319 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValuesDot<3>(
2320 spatialL2Disp, dataAtPts->getSmallWL2DotAtPts(), MBTET));
2321 if (noStretch) {
2322 } else {
2323 fe->getOpPtrVector().push_back(
2325 stretchTensor, dataAtPts->getLogStretchDotTensorAtPts(), MBTET));
2326 fe->getOpPtrVector().push_back(
2328 stretchTensor, dataAtPts->getGradLogStretchDotTensorAtPts(),
2329 MBTET));
2330 }
2331 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValuesDot<3>(
2332 rotAxis, dataAtPts->getRotAxisDotAtPts(), MBTET));
2333 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldGradientDot<3, 3>(
2334 rotAxis, dataAtPts->getRotAxisGradDotAtPts(), MBTET));
2335
2336 // acceleration
2337 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
2338 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValuesDotDot<3>(
2339 spatialL2Disp, dataAtPts->getSmallWL2DotDotAtPts(), MBTET));
2340 }
2341 }
2342
2343 // variations
2344 if (var_vec.use_count()) {
2345 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
2346 piolaStress, dataAtPts->getVarPiolaPts(), boost::make_shared<double>(1),
2347 var_vec));
2348 fe->getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
2349 bubbleField, dataAtPts->getVarPiolaPts(), boost::make_shared<double>(1),
2350 var_vec, MBMAXTYPE));
2351 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2352 rotAxis, dataAtPts->getVarRotAxisPts(), var_vec, MBTET));
2353 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorDivergence<3, 3>(
2354 piolaStress, dataAtPts->getDivVarPiolaPts(), var_vec));
2355 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2356 spatialL2Disp, dataAtPts->getVarWL2Pts(), var_vec, MBTET));
2357
2358 if (noStretch) {
2359 fe->getOpPtrVector().push_back(
2360 physicalEquations->returnOpCalculateVarStretchFromStress(
2362 } else {
2363 fe->getOpPtrVector().push_back(
2365 stretchTensor, dataAtPts->getVarLogStreachPts(), var_vec, MBTET));
2366 }
2367 }
2368
2369 // calculate other derived quantities
2370 fe->getOpPtrVector().push_back(new OpCalculateRotationAndSpatialGradient(
2371 dataAtPts, ((do_rhs || do_lhs) && calc_rates) ? alphaOmega : 0.));
2372
2373 // evaluate integration points
2374 if (noStretch) {
2375 } else {
2376 fe->getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
2377 tag, do_rhs, do_lhs, dataAtPts, physicalEquations));
2378 }
2379
2381}
UBlasMatrix< double > MatrixDouble
Definition Types.hpp:77
Calculate divergence of tonsorial field using vectorial base.
Calculate symmetric tensor field rates ant integratio pts.
Get field gradients time derivative at integration pts for scalar field rank 0, i....
Approximate field values for given petsc vector.

◆ setBlockTagsOnSkin()

MoFEMErrorCode EshelbianCore::setBlockTagsOnSkin ( )
Examples
ep.cpp, mofem/users_modules/eshelbian_plasticity/ep.cpp, and mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 3606 of file EshelbianPlasticity.cpp.

3606 {
3608
3609 auto set_block = [&](auto name, int dim) {
3610 std::map<int, Range> map;
3611 auto set_tag_impl = [&](auto name) {
3613 auto mesh_mng = mField.getInterface<MeshsetsManager>();
3614 auto bcs = mesh_mng->getCubitMeshsetPtr(
3615
3616 std::regex((boost::format("%s(.*)") % name).str())
3617
3618 );
3619 for (auto bc : bcs) {
3620 Range r;
3621 CHKERR bc->getMeshsetIdEntitiesByDimension(mField.get_moab(), dim, r,
3622 true);
3623 map[bc->getMeshsetId()] = r;
3624 }
3626 };
3627
3628 CHKERR set_tag_impl(name);
3629
3630 return std::make_pair(name, map);
3631 };
3632
3633 auto set_skin = [&](auto &&map) {
3634 for (auto &m : map.second) {
3635 auto s = filter_true_skin(mField, get_skin(mField, m.second));
3636 m.second.swap(s);
3637 }
3638 return map;
3639 };
3640
3641 auto set_tag = [&](auto &&map) {
3642 Tag th;
3643 auto name = map.first;
3644 int def_val[] = {-1};
3646 mField.get_moab().tag_get_handle(name, 1, MB_TYPE_INTEGER, th,
3647 MB_TAG_SPARSE | MB_TAG_CREAT, def_val),
3648 "create tag");
3649 for (auto &m : map.second) {
3650 int id = m.first;
3651 CHK_MOAB_THROW(mField.get_moab().tag_clear_data(th, m.second, &id),
3652 "clear tag");
3653 }
3654 return th;
3655 };
3656
3657 listTagsToTransfer.push_back(set_tag(set_skin(set_block("BODY", 3))));
3658 listTagsToTransfer.push_back(set_tag(set_skin(set_block("MAT_ELASTIC", 3))));
3659 listTagsToTransfer.push_back(
3660 set_tag(set_skin(set_block("MAT_NEOHOOKEAN", 3))));
3661 listTagsToTransfer.push_back(set_tag(set_block("CONTACT", 2)));
3662
3664}
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset

◆ setContactElementRhsOps()

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

Contact requires that body is marked

Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 3030 of file EshelbianPlasticity.cpp.

3034 {
3036
3037 /** Contact requires that body is marked */
3038 auto get_body_range = [this](auto name, int dim, auto sev) {
3039 std::map<int, Range> map;
3040
3041 for (auto m_ptr :
3042 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
3043
3044 (boost::format("%s(.*)") % name).str()
3045
3046 ))
3047
3048 ) {
3049 Range ents;
3050 CHK_MOAB_THROW(m_ptr->getMeshsetIdEntitiesByDimension(mField.get_moab(),
3051 dim, ents, true),
3052 "by dim");
3053 map[m_ptr->getMeshsetId()] = ents;
3054 MOFEM_LOG("EPSYNC", sev) << "Meshset: " << m_ptr->getMeshsetId() << " "
3055 << ents.size() << " entities";
3056 }
3057
3059 return map;
3060 };
3061
3062 auto get_map_skin = [this](auto &&map) {
3063 ParallelComm *pcomm =
3064 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
3065
3066 Skinner skin(&mField.get_moab());
3067 for (auto &m : map) {
3068 Range skin_faces;
3069 CHKERR skin.find_skin(0, m.second, false, skin_faces);
3070 CHK_MOAB_THROW(pcomm->filter_pstatus(skin_faces,
3071 PSTATUS_SHARED | PSTATUS_MULTISHARED,
3072 PSTATUS_NOT, -1, nullptr),
3073 "filter");
3074 m.second.swap(skin_faces);
3075 }
3076 return map;
3077 };
3078
3079 /* The above code is written in C++ and it appears to be defining and using
3080 various operations on boundary elements and side elements. */
3082 using BoundaryEleOp = BoundaryEle::UserDataOperator;
3083
3084 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
3085
3086 auto calcs_side_traction = [&](auto &pip) {
3088 using EleOnSide =
3090 using SideEleOp = EleOnSide::UserDataOperator;
3091 auto op_loop_domain_side = new OpLoopSide<EleOnSide>(
3092 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
3093 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3094 boost::make_shared<CGGUserPolynomialBase>();
3095 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3096 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3098 op_loop_domain_side->getOpPtrVector().push_back(
3100 piolaStress, contact_common_data_ptr->contactTractionPtr(),
3101 boost::make_shared<double>(1.0)));
3102 pip.push_back(op_loop_domain_side);
3104 };
3105
3106 auto add_contact_three = [&]() {
3108 auto tree_moab_ptr = boost::make_shared<moab::Core>();
3109 fe_contact_tree = boost::make_shared<ContactTree>(
3110 mField, tree_moab_ptr, spaceOrder,
3111 get_body_range("CONTACT", SPACE_DIM - 1, Sev::inform));
3112 fe_contact_tree->getOpPtrVector().push_back(
3114 contactDisp, contact_common_data_ptr->contactDispPtr()));
3115 CHKERR calcs_side_traction(fe_contact_tree->getOpPtrVector());
3116 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
3117 fe_contact_tree->getOpPtrVector().push_back(
3119 fe_contact_tree->getOpPtrVector().push_back(
3120 new OpMoveNode(fe_contact_tree, contact_common_data_ptr, u_h1_ptr));
3122 };
3123
3124 CHKERR add_contact_three();
3125
3127}

◆ setElasticElementOps()

MoFEMErrorCode EshelbianCore::setElasticElementOps ( const int  tag)
Examples
ep.cpp, mofem/users_modules/eshelbian_plasticity/ep.cpp, and mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 3129 of file EshelbianPlasticity.cpp.

3129 {
3131
3132 // Add contact operators. Note that only for rhs. THe lhs is assembled with
3133 // volume element, to enable schur complement evaluation.
3135
3138
3139 auto adj_cache =
3140 boost::make_shared<ForcesAndSourcesCore::UserDataOperator::AdjCache>();
3141
3142 auto get_op_contact_bc = [&]() {
3144 auto op_loop_side = new OpLoopSide<SideEle>(
3145 mField, contactElement, SPACE_DIM - 1, Sev::noisy, adj_cache);
3146 return op_loop_side;
3147 };
3148
3150}
boost::shared_ptr< FaceElementForcesAndSourcesCore > elasticBcRhs
boost::shared_ptr< FaceElementForcesAndSourcesCore > elasticBcLhs
boost::shared_ptr< VolumeElementForcesAndSourcesCore > elasticFeRhs
MoFEMErrorCode setVolumeElementOps(const int tag, const bool add_elastic, const bool add_material, boost::shared_ptr< VolumeElementForcesAndSourcesCore > &fe_rhs, boost::shared_ptr< VolumeElementForcesAndSourcesCore > &fe_lhs)
boost::shared_ptr< VolumeElementForcesAndSourcesCore > elasticFeLhs
MoFEMErrorCode setContactElementRhsOps(boost::shared_ptr< ContactTree > &fe_contact_tree)
MoFEMErrorCode setFaceElementOps(const bool add_elastic, const bool add_material, boost::shared_ptr< FaceElementForcesAndSourcesCore > &fe_rhs, boost::shared_ptr< FaceElementForcesAndSourcesCore > &fe_lhs)
ElementsAndOps< SPACE_DIM >::SideEle SideEle
Definition plastic.cpp:61

◆ setElasticElementToTs()

MoFEMErrorCode EshelbianCore::setElasticElementToTs ( DM  dm)
Examples
ep.cpp, mofem/users_modules/eshelbian_plasticity/ep.cpp, and mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 3152 of file EshelbianPlasticity.cpp.

3152 {
3154 boost::shared_ptr<FEMethod> null;
3155
3156 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
3157
3159 null);
3161 null);
3163 null);
3165 null);
3166
3167 } else {
3169 null);
3171 null);
3173 null);
3175 null);
3176 }
3177
3179}
PetscErrorCode DMMoFEMTSSetIFunction(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
set TS implicit function evaluation function
Definition DMMoFEM.cpp:790
PetscErrorCode DMMoFEMTSSetIJacobian(DM dm, const std::string fe_name, boost::shared_ptr< MoFEM::FEMethod > method, boost::shared_ptr< MoFEM::BasicMethod > pre_only, boost::shared_ptr< MoFEM::BasicMethod > post_only)
set TS Jacobian evaluation function
Definition DMMoFEM.cpp:843
PetscErrorCode DMMoFEMTSSetI2Jacobian(DM dm, const std::string fe_name, boost::shared_ptr< MoFEM::FEMethod > method, boost::shared_ptr< MoFEM::BasicMethod > pre_only, boost::shared_ptr< MoFEM::BasicMethod > post_only)
set TS Jacobian evaluation function
Definition DMMoFEM.cpp:1007
PetscErrorCode DMMoFEMTSSetI2Function(DM dm, const std::string fe_name, boost::shared_ptr< MoFEM::FEMethod > method, boost::shared_ptr< MoFEM::BasicMethod > pre_only, boost::shared_ptr< MoFEM::BasicMethod > post_only)
set TS implicit function evaluation function
Definition DMMoFEM.cpp:965

◆ setFaceElementOps()

MoFEMErrorCode EshelbianCore::setFaceElementOps ( const bool  add_elastic,
const bool  add_material,
boost::shared_ptr< FaceElementForcesAndSourcesCore > &  fe_rhs,
boost::shared_ptr< FaceElementForcesAndSourcesCore > &  fe_lhs 
)
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 2871 of file EshelbianPlasticity.cpp.

2874 {
2876
2877 fe_rhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
2878 fe_lhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
2879
2880 // set integration rule
2881 // fe_rhs->getRuleHook = [](int, int, int p) { return 2 * (p + 1); };
2882 // fe_lhs->getRuleHook = [](int, int, int p) { return 2 * (p + 1); };
2883 fe_rhs->getRuleHook = [](int, int, int) { return -1; };
2884 fe_lhs->getRuleHook = [](int, int, int) { return -1; };
2885 fe_rhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
2886 fe_lhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
2887
2888 CHKERR
2889 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2890 fe_rhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
2891 CHKERR
2892 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2893 fe_lhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
2894
2895 if (add_elastic) {
2896
2897 auto get_broken_op_side = [this](auto &pip) {
2898 using EleOnSide =
2900 using SideEleOp = EleOnSide::UserDataOperator;
2901 // Iterate over domain FEs adjacent to boundary.
2902 auto broken_data_ptr =
2903 boost::make_shared<std::vector<BrokenBaseSideData>>();
2904 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
2905 auto op_loop_domain_side = new OpLoopSide<EleOnSide>(
2906 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
2907 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2908 boost::make_shared<CGGUserPolynomialBase>();
2909 CHKERR
2910 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2911 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2913 op_loop_domain_side->getOpPtrVector().push_back(
2914 new OpGetBrokenBaseSideData<SideEleOp>(piolaStress, broken_data_ptr));
2915 boost::shared_ptr<double> piola_scale_ptr(new double);
2916 op_loop_domain_side->getOpPtrVector().push_back(
2917 physicalEquations->returnOpSetScale(piola_scale_ptr,
2919
2920 auto piola_stress_mat_ptr = boost::make_shared<MatrixDouble>();
2921 op_loop_domain_side->getOpPtrVector().push_back(
2923 piola_stress_mat_ptr));
2924 pip.push_back(op_loop_domain_side);
2925 return std::make_tuple(broken_data_ptr, piola_scale_ptr,
2926 piola_stress_mat_ptr);
2927 };
2928
2929 auto set_rhs = [&]() {
2931
2932 auto [broken_data_ptr, piola_scale_ptr, piola_stress_mat_ptr] =
2933 get_broken_op_side(fe_rhs->getOpPtrVector());
2934
2935 fe_rhs->getOpPtrVector().push_back(
2936 new OpDispBc(broken_data_ptr, bcSpatialDispVecPtr, timeScaleMap));
2937 fe_rhs->getOpPtrVector().push_back(new OpAnalyticalDispBc(
2939 timeScaleMap));
2940 fe_rhs->getOpPtrVector().push_back(new OpRotationBc(
2941 broken_data_ptr, bcSpatialRotationVecPtr, timeScaleMap));
2942
2943 fe_rhs->getOpPtrVector().push_back(
2945 piola_scale_ptr, timeScaleMap));
2946 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
2947 // if you push gradient of L2 base to physical element, it will not work.
2948 fe_rhs->getOpPtrVector().push_back(
2950 hybridSpatialDisp, hybrid_grad_ptr));
2951 fe_rhs->getOpPtrVector().push_back(new OpBrokenPressureBc(
2953 hybrid_grad_ptr, timeScaleMap));
2954 fe_rhs->getOpPtrVector().push_back(new OpBrokenAnalyticalTractionBc(
2956 timeScaleMap));
2957
2958 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
2959 fe_rhs->getOpPtrVector().push_back(
2961 hybrid_ptr));
2962 fe_rhs->getOpPtrVector().push_back(new OpNormalDispRhsBc(
2963 hybridSpatialDisp, hybrid_ptr, piola_stress_mat_ptr,
2965
2966 auto get_normal_disp_bc_faces = [&]() {
2967 auto faces =
2968 get_range_from_block(mField, "NORMAL_DISPLACEMENT", SPACE_DIM - 1);
2969 return boost::make_shared<Range>(faces);
2970 };
2971
2972 using BoundaryEle =
2974 using BdyEleOp = BoundaryEle::UserDataOperator;
2976 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
2977 fe_rhs->getOpPtrVector().push_back(new OpC_dBroken(
2978 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0),
2979 get_normal_disp_bc_faces()));
2980
2982 };
2983
2984 auto set_lhs = [&]() {
2986
2987 auto [broken_data_ptr, piola_scale_ptr, piola_stress_mat_ptr] =
2988 get_broken_op_side(fe_lhs->getOpPtrVector());
2989
2990 fe_lhs->getOpPtrVector().push_back(new OpNormalDispLhsBc_dU(
2992 fe_lhs->getOpPtrVector().push_back(new OpNormalDispLhsBc_dP(
2994 timeScaleMap));
2995
2996 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
2997 // if you push gradient of L2 base to physical element, it will not work.
2998 fe_rhs->getOpPtrVector().push_back(
3000 hybridSpatialDisp, hybrid_grad_ptr));
3001 fe_lhs->getOpPtrVector().push_back(new OpBrokenPressureBcLhs_dU(
3003 timeScaleMap));
3004
3005 auto get_normal_disp_bc_faces = [&]() {
3006 auto faces =
3007 get_range_from_block(mField, "NORMAL_DISPLACEMENT", SPACE_DIM - 1);
3008 return boost::make_shared<Range>(faces);
3009 };
3010
3011 using BoundaryEle =
3013 using BdyEleOp = BoundaryEle::UserDataOperator;
3015 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
3016 fe_lhs->getOpPtrVector().push_back(new OpC(
3017 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0),
3018 true, true, get_normal_disp_bc_faces()));
3019
3021 };
3022
3023 CHKERR set_rhs();
3024 CHKERR set_lhs();
3025 }
3026
3028}
@ GAUSS
Gaussian quadrature integration.
constexpr AssemblyType A
[Define dimension]
Apply rotation boundary condition.
BoundaryEle::UserDataOperator BdyEleOp

◆ setNewFrontCoordinates()

MoFEMErrorCode EshelbianCore::setNewFrontCoordinates ( )
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 5929 of file EshelbianPlasticity.cpp.

5929 {
5931
5932 if (!maxMovedFaces)
5934
5935 Tag th_front_position;
5936 auto rval =
5937 mField.get_moab().tag_get_handle("FrontPosition", th_front_position);
5938 if (rval == MB_SUCCESS && maxMovedFaces) {
5939 Range verts;
5940 CHKERR mField.get_moab().get_connectivity(*maxMovedFaces, verts, true);
5941 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(verts);
5942 std::vector<double> coords(3 * verts.size());
5943 CHKERR mField.get_moab().get_coords(verts, coords.data());
5944 std::vector<double> pos(3 * verts.size());
5945 CHKERR mField.get_moab().tag_get_data(th_front_position, verts, pos.data());
5946 for (int i = 0; i != 3 * verts.size(); ++i) {
5947 coords[i] += pos[i];
5948 }
5949 CHKERR mField.get_moab().set_coords(verts, coords.data());
5950 double zero[] = {0., 0., 0.};
5951 CHKERR mField.get_moab().tag_clear_data(th_front_position, verts, zero);
5952 }
5953
5954#ifndef NDEBUG
5955 constexpr bool debug = false;
5956 if (debug) {
5957
5959 mField.get_moab(),
5960 "set_coords_faces_" +
5961 boost::lexical_cast<std::string>(mField.get_comm_rank()) + ".vtk",
5962 *maxMovedFaces);
5963 }
5964#endif
5966}

◆ setVolumeElementOps()

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

Contact requires that body is marked

Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 2383 of file EshelbianPlasticity.cpp.

2386 {
2388
2389 /** Contact requires that body is marked */
2390 auto get_body_range = [this](auto name, int dim) {
2391 std::map<int, Range> map;
2392
2393 for (auto m_ptr :
2394 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
2395
2396 (boost::format("%s(.*)") % name).str()
2397
2398 ))
2399
2400 ) {
2401 Range ents;
2402 CHK_MOAB_THROW(m_ptr->getMeshsetIdEntitiesByDimension(mField.get_moab(),
2403 dim, ents, true),
2404 "by dim");
2405 map[m_ptr->getMeshsetId()] = ents;
2406 }
2407
2408 return map;
2409 };
2410
2411 auto rule_contact = [](int, int, int o) { return -1; };
2413
2414 auto set_rule_contact = [refine](
2415
2416 ForcesAndSourcesCore *fe_raw_ptr, int order_row,
2417 int order_col, int order_data
2418
2419 ) {
2421 auto rule = 2 * order_data;
2422 fe_raw_ptr->gaussPts = Tools::refineTriangleIntegrationPts(rule, refine);
2424 };
2425
2426 // Right hand side
2427 fe_rhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
2428 CHKERR setBaseVolumeElementOps(tag, true, false, true, SmartPetscObj<Vec>(),
2429 fe_rhs);
2430
2431 // elastic
2432 if (add_elastic) {
2433
2434 fe_rhs->getOpPtrVector().push_back(
2436 fe_rhs->getOpPtrVector().push_back(
2438 if (noStretch) {
2439 // do nothing - no stretch approximation
2440 } else {
2441 if (!internalStressTagName.empty()) {
2442 switch (internalStressInterpOrder) {
2443 case 0:
2444 fe_rhs->getOpPtrVector().push_back(
2446 break;
2447 case 1:
2448 fe_rhs->getOpPtrVector().push_back(
2450 break;
2451 default:
2452 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
2453 "Unsupported internal stress interpolation order %d",
2455 }
2456 if (internalStressVoigt) {
2457 fe_rhs->getOpPtrVector().push_back(
2459 dataAtPts));
2460 } else {
2461 fe_rhs->getOpPtrVector().push_back(
2463 dataAtPts));
2464 }
2465 }
2466 if (auto op = physicalEquations->returnOpSpatialPhysicalExternalStrain(
2468 fe_rhs->getOpPtrVector().push_back(op);
2469 } else if (externalStrainVecPtr && !externalStrainVecPtr->empty()) {
2470 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
2471 "OpSpatialPhysicalExternalStrain not implemented for this "
2472 "material");
2473 }
2474
2475 fe_rhs->getOpPtrVector().push_back(
2476 physicalEquations->returnOpSpatialPhysical(stretchTensor, dataAtPts,
2477 alphaU));
2478 }
2479 fe_rhs->getOpPtrVector().push_back(
2481 fe_rhs->getOpPtrVector().push_back(
2483 fe_rhs->getOpPtrVector().push_back(
2485
2486 auto set_hybridisation = [&](auto &pip) {
2488
2489 using BoundaryEle =
2491 using EleOnSide =
2493 using SideEleOp = EleOnSide::UserDataOperator;
2494 using BdyEleOp = BoundaryEle::UserDataOperator;
2495
2496 // First: Iterate over skeleton FEs adjacent to Domain FEs
2497 // Note: BoundaryEle, i.e. uses skeleton interation rule
2498 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
2499 mField, skeletonElement, SPACE_DIM - 1, Sev::noisy);
2500 // op_loop_skeleton_side->getSideFEPtr()->getRuleHook = FaceRule();
2501 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
2502 return -1;
2503 };
2504 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
2505 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
2506
2507 CHKERR EshelbianPlasticity::
2508 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2509 op_loop_skeleton_side->getOpPtrVector(), {L2},
2511
2512 // Second: Iterate over domain FEs adjacent to skelton, particularly one
2513 // domain element.
2514 auto broken_data_ptr =
2515 boost::make_shared<std::vector<BrokenBaseSideData>>();
2516 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
2517 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
2518 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
2519 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2520 boost::make_shared<CGGUserPolynomialBase>();
2521 CHKERR
2522 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2523 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2525 op_loop_domain_side->getOpPtrVector().push_back(
2526 new OpGetBrokenBaseSideData<SideEleOp>(piolaStress, broken_data_ptr));
2527 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
2528 op_loop_domain_side->getOpPtrVector().push_back(
2530 flux_mat_ptr));
2531 op_loop_domain_side->getOpPtrVector().push_back(
2532 new OpSetFlux<SideEleOp>(broken_data_ptr, flux_mat_ptr));
2533
2534 // Assemble on skeleton
2535 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
2537 GAUSS>::OpBrokenSpaceConstrainDHybrid<SPACE_DIM>;
2539 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
2540 op_loop_skeleton_side->getOpPtrVector().push_back(new OpC_dHybrid(
2541 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0)));
2542 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
2543 op_loop_skeleton_side->getOpPtrVector().push_back(
2545 hybrid_ptr));
2546 op_loop_skeleton_side->getOpPtrVector().push_back(new OpC_dBroken(
2547 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0)));
2548
2549 // Add skeleton to domain pipeline
2550 pip.push_back(op_loop_skeleton_side);
2551
2553 };
2554
2555 auto set_contact = [&](auto &pip) {
2557
2558 using BoundaryEle =
2560 using EleOnSide =
2562 using SideEleOp = EleOnSide::UserDataOperator;
2563 using BdyEleOp = BoundaryEle::UserDataOperator;
2564
2565 // First: Iterate over skeleton FEs adjacent to Domain FEs
2566 // Note: BoundaryEle, i.e. uses skeleton interation rule
2567 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
2568 mField, contactElement, SPACE_DIM - 1, Sev::noisy);
2569
2570 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
2571 op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
2572 CHKERR EshelbianPlasticity::
2573 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2574 op_loop_skeleton_side->getOpPtrVector(), {L2},
2576
2577 // Second: Iterate over domain FEs adjacent to skelton, particularly
2578 // one domain element.
2579 auto broken_data_ptr =
2580 boost::make_shared<std::vector<BrokenBaseSideData>>();
2581
2582 // Data storing contact fields
2583 auto contact_common_data_ptr =
2584 boost::make_shared<ContactOps::CommonData>();
2585
2586 auto add_ops_domain_side = [&](auto &pip) {
2588 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
2589 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
2590 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
2591 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2592 boost::make_shared<CGGUserPolynomialBase>();
2593 CHKERR
2594 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2595 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2597 op_loop_domain_side->getOpPtrVector().push_back(
2599 broken_data_ptr));
2600 op_loop_domain_side->getOpPtrVector().push_back(
2602 piolaStress, contact_common_data_ptr->contactTractionPtr()));
2603 pip.push_back(op_loop_domain_side);
2605 };
2606
2607 auto add_ops_contact_rhs = [&](auto &pip) {
2609 // get body id and SDF range
2610 auto contact_sfd_map_range_ptr =
2611 boost::make_shared<std::map<int, Range>>(
2612 get_body_range("CONTACT_SDF", SPACE_DIM - 1));
2613
2614 pip.push_back(new OpCalculateVectorFieldValues<3>(
2615 contactDisp, contact_common_data_ptr->contactDispPtr()));
2616 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2617 pip.push_back(
2619 pip.push_back(new OpTreeSearch(
2620 contactTreeRhs, contact_common_data_ptr, u_h1_ptr,
2621 get_range_from_block(mField, "CONTACT", SPACE_DIM - 1), nullptr,
2622 nullptr));
2624 contactDisp, contact_common_data_ptr, contactTreeRhs,
2625 contact_sfd_map_range_ptr));
2626 pip.push_back(
2628 broken_data_ptr, contact_common_data_ptr, contactTreeRhs));
2629
2631 };
2632
2633 // push ops to face/side pipeline
2634 CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
2635 CHKERR add_ops_contact_rhs(op_loop_skeleton_side->getOpPtrVector());
2636
2637 // Add skeleton to domain pipeline
2638 pip.push_back(op_loop_skeleton_side);
2639
2641 };
2642
2643 CHKERR set_hybridisation(fe_rhs->getOpPtrVector());
2644 CHKERR set_contact(fe_rhs->getOpPtrVector());
2645
2646 // Body forces
2647 using BodyNaturalBC =
2649 Assembly<PETSC>::LinearForm<GAUSS>;
2650 using OpBodyForce =
2651 BodyNaturalBC::OpFlux<NaturalMeshsetType<BLOCKSET>, 1, 3>;
2652
2653 auto body_time_scale =
2654 boost::make_shared<DynamicRelaxationTimeScale>("body_force.txt");
2655 CHKERR BodyNaturalBC::AddFluxToPipeline<OpBodyForce>::add(
2656 fe_rhs->getOpPtrVector(), mField, spatialL2Disp, {body_time_scale},
2657 "BODY_FORCE", Sev::inform);
2658 }
2659
2660 // Left hand side
2661 fe_lhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
2662 CHKERR setBaseVolumeElementOps(tag, true, true, true, SmartPetscObj<Vec>(),
2663 fe_lhs);
2664
2665 // elastic
2666 if (add_elastic) {
2667
2668 if (noStretch) {
2669 fe_lhs->getOpPtrVector().push_back(
2671 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dBubble_dP(
2673 fe_lhs->getOpPtrVector().push_back(
2675 dataAtPts));
2676 } else {
2677 fe_lhs->getOpPtrVector().push_back(
2678 physicalEquations->returnOpSpatialPhysical_du_du(
2680 fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_dP(
2682 fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_dBubble(
2684 fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_domega(
2686 symmetrySelector == SYMMETRIC ? true : false));
2687 }
2688
2689 fe_lhs->getOpPtrVector().push_back(new OpSpatialEquilibrium_dw_dP(
2691 fe_lhs->getOpPtrVector().push_back(new OpSpatialEquilibrium_dw_dw(
2693
2694 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dP_domega(
2696 symmetrySelector == SYMMETRIC ? true : false));
2697 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dBubble_domega(
2699 symmetrySelector == SYMMETRIC ? true : false));
2700
2701 if (symmetrySelector > SYMMETRIC) {
2702 if (!noStretch) {
2703 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_du(
2704 rotAxis, stretchTensor, dataAtPts, false));
2705 }
2706 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_dP(
2707 rotAxis, piolaStress, dataAtPts, false));
2708 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_dBubble(
2709 rotAxis, bubbleField, dataAtPts, false));
2710 }
2711 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_domega(
2713
2714 auto set_hybridisation = [&](auto &pip) {
2716
2717 using BoundaryEle =
2719 using EleOnSide =
2721 using SideEleOp = EleOnSide::UserDataOperator;
2722 using BdyEleOp = BoundaryEle::UserDataOperator;
2723
2724 // First: Iterate over skeleton FEs adjacent to Domain FEs
2725 // Note: BoundaryEle, i.e. uses skeleton interation rule
2726 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
2727 mField, skeletonElement, SPACE_DIM - 1, Sev::noisy);
2728 // op_loop_skeleton_side->getSideFEPtr()->getRuleHook = FaceRule();
2729 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
2730 return -1;
2731 };
2732 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
2733 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
2734 CHKERR EshelbianPlasticity::
2735 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2736 op_loop_skeleton_side->getOpPtrVector(), {L2},
2738
2739 // Second: Iterate over domain FEs adjacent to skelton, particularly one
2740 // domain element.
2741 auto broken_data_ptr =
2742 boost::make_shared<std::vector<BrokenBaseSideData>>();
2743 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
2744 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
2745 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
2746 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2747 boost::make_shared<CGGUserPolynomialBase>();
2748 CHKERR
2749 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2750 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2752 op_loop_domain_side->getOpPtrVector().push_back(
2753 new OpGetBrokenBaseSideData<SideEleOp>(piolaStress, broken_data_ptr));
2754
2755 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
2757 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
2758 op_loop_skeleton_side->getOpPtrVector().push_back(
2759 new OpC(hybridSpatialDisp, broken_data_ptr,
2760 boost::make_shared<double>(1.0), true, false));
2761
2762 pip.push_back(op_loop_skeleton_side);
2763
2765 };
2766
2767 auto set_contact = [&](auto &pip) {
2769
2770 using BoundaryEle =
2772 using EleOnSide =
2774 using SideEleOp = EleOnSide::UserDataOperator;
2775 using BdyEleOp = BoundaryEle::UserDataOperator;
2776
2777 // First: Iterate over skeleton FEs adjacent to Domain FEs
2778 // Note: BoundaryEle, i.e. uses skeleton interation rule
2779 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
2780 mField, contactElement, SPACE_DIM - 1, Sev::noisy);
2781
2782 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
2783 op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
2784 CHKERR EshelbianPlasticity::
2785 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2786 op_loop_skeleton_side->getOpPtrVector(), {L2},
2788
2789 // Second: Iterate over domain FEs adjacent to skelton, particularly
2790 // one domain element.
2791 auto broken_data_ptr =
2792 boost::make_shared<std::vector<BrokenBaseSideData>>();
2793
2794 // Data storing contact fields
2795 auto contact_common_data_ptr =
2796 boost::make_shared<ContactOps::CommonData>();
2797
2798 auto add_ops_domain_side = [&](auto &pip) {
2800 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
2801 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
2802 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
2803 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2804 boost::make_shared<CGGUserPolynomialBase>();
2805 CHKERR
2806 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2807 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2809 op_loop_domain_side->getOpPtrVector().push_back(
2811 broken_data_ptr));
2812 op_loop_domain_side->getOpPtrVector().push_back(
2814 piolaStress, contact_common_data_ptr->contactTractionPtr()));
2815 pip.push_back(op_loop_domain_side);
2817 };
2818
2819 auto add_ops_contact_lhs = [&](auto &pip) {
2821 pip.push_back(new OpCalculateVectorFieldValues<3>(
2822 contactDisp, contact_common_data_ptr->contactDispPtr()));
2823 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2824 pip.push_back(
2826 pip.push_back(new OpTreeSearch(
2827 contactTreeRhs, contact_common_data_ptr, u_h1_ptr,
2828 get_range_from_block(mField, "CONTACT", SPACE_DIM - 1), nullptr,
2829 nullptr));
2830
2831 // get body id and SDF range
2832 auto contact_sfd_map_range_ptr =
2833 boost::make_shared<std::map<int, Range>>(
2834 get_body_range("CONTACT_SDF", SPACE_DIM - 1));
2835
2837 contactDisp, contactDisp, contact_common_data_ptr, contactTreeRhs,
2838 contact_sfd_map_range_ptr));
2839 pip.push_back(
2841 contactDisp, broken_data_ptr, contact_common_data_ptr,
2842 contactTreeRhs, contact_sfd_map_range_ptr));
2843 pip.push_back(
2845 broken_data_ptr, contactDisp, contact_common_data_ptr,
2847
2849 };
2850
2851 // push ops to face/side pipeline
2852 CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
2853 CHKERR add_ops_contact_lhs(op_loop_skeleton_side->getOpPtrVector());
2854
2855 // Add skeleton to domain pipeline
2856 pip.push_back(op_loop_skeleton_side);
2857
2859 };
2860
2861 CHKERR set_hybridisation(fe_lhs->getOpPtrVector());
2862 CHKERR set_contact(fe_lhs->getOpPtrVector());
2863 }
2864
2865 if (add_material) {
2866 }
2867
2869}
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 from 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,
int  start_step,
double  start_time 
)

Solve problem using dynamic relaxation method.

Parameters
tssolver time stepper
xsolution vector
start_stepstarting step number
start_timestarting time
Returns
MoFEMErrorCode
Examples
ep.cpp, mofem/users_modules/eshelbian_plasticity/ep.cpp, and mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 3513 of file EshelbianPlasticity.cpp.

3515 {
3517
3518 auto storage = solve_elastic_setup::setup(this, ts, x, false);
3519
3520 double final_time = 1;
3521 double delta_time = 0.1;
3522 int max_it = 10;
3523 PetscBool ts_h1_update = PETSC_FALSE;
3524
3525 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Dynamic Relaxation Options",
3526 "none");
3527
3528 CHKERR PetscOptionsScalar("-dynamic_final_time",
3529 "dynamic relaxation final time", "", final_time,
3530 &final_time, PETSC_NULLPTR);
3531 CHKERR PetscOptionsScalar("-dynamic_delta_time",
3532 "dynamic relaxation final time", "", delta_time,
3533 &delta_time, PETSC_NULLPTR);
3534 CHKERR PetscOptionsInt("-dynamic_max_it", "dynamic relaxation iterations", "",
3535 max_it, &max_it, PETSC_NULLPTR);
3536 CHKERR PetscOptionsBool("-dynamic_h1_update", "update each ts step", "",
3537 ts_h1_update, &ts_h1_update, PETSC_NULLPTR);
3538
3539 PetscOptionsEnd();
3540
3541 auto setup_ts_monitor = [&]() {
3542 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*this);
3543 return monitor_ptr;
3544 };
3545 auto monitor_ptr = setup_ts_monitor();
3546
3547 TetPolynomialBase::switchCacheBaseOn<HDIV>(
3548 {elasticFeLhs.get(), elasticFeRhs.get()});
3549 CHKERR TSSetUp(ts);
3551
3552 double ts_delta_time;
3553 CHKERR TSGetTimeStep(ts, &ts_delta_time);
3554
3555 if (ts_h1_update) {
3556 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
3557 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
3558 }
3559
3562
3563 dynamicTime = start_time;
3564 dynamicStep = start_step;
3565 monitor_ptr->ts_u = PETSC_NULLPTR;
3566 monitor_ptr->ts_t = dynamicTime;
3567 monitor_ptr->ts_step = dynamicStep;
3569 MOFEM_LOG("EP", Sev::inform) << "IT " << dynamicStep << " Time "
3570 << dynamicTime << " delta time " << delta_time;
3571 dynamicTime += delta_time;
3572 ++dynamicStep;
3573
3574 for (; dynamicTime < final_time; dynamicTime += delta_time) {
3575 MOFEM_LOG("EP", Sev::inform) << "IT " << dynamicStep << " Time "
3576 << dynamicTime << " delta time " << delta_time;
3577
3578 CHKERR TSSetStepNumber(ts, 0);
3579 CHKERR TSSetTime(ts, 0);
3580 CHKERR TSSetTimeStep(ts, ts_delta_time);
3581 if (!ts_h1_update) {
3583 }
3584 CHKERR TSSolve(ts, PETSC_NULLPTR);
3585 if (!ts_h1_update) {
3587 }
3588
3589 monitor_ptr->ts_u = PETSC_NULLPTR;
3590 monitor_ptr->ts_t = dynamicTime;
3591 monitor_ptr->ts_step = dynamicStep;
3593
3594 ++dynamicStep;
3595 if (dynamicStep > max_it)
3596 break;
3597 }
3598
3600 TetPolynomialBase::switchCacheBaseOff<HDIV>(
3601 {elasticFeLhs.get(), elasticFeRhs.get()});
3602
3604}
static double dynamicTime
static int dynamicStep
static MoFEMErrorCode postStepInitialise(EshelbianCore *ep_ptr)
static MoFEMErrorCode postStepDestroy()
static MoFEMErrorCode preStepFun(TS ts)
static MoFEMErrorCode postStepFun(TS ts)

◆ solveElastic()

MoFEMErrorCode EshelbianCore::solveElastic ( TS  ts,
Vec  x 
)
Examples
ep.cpp, mofem/users_modules/eshelbian_plasticity/ep.cpp, and mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 3383 of file EshelbianPlasticity.cpp.

3383 {
3385
3386 PetscBool debug_model = PETSC_FALSE;
3387 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-debug_model", &debug_model,
3388 PETSC_NULLPTR);
3389
3390 if (debug_model == PETSC_TRUE) {
3391 auto ts_ctx_ptr = getDMTsCtx(dmElastic);
3392 auto post_proc = [&](TS ts, PetscReal t, Vec u, Vec u_t, Vec u_tt, Vec F,
3393 void *ctx) {
3395
3396 SNES snes;
3397 CHKERR TSGetSNES(ts, &snes);
3398 int it;
3399 CHKERR SNESGetIterationNumber(snes, &it);
3400 std::string file_name = "snes_iteration_" + std::to_string(it) + ".h5m";
3401 CHKERR postProcessResults(1, file_name, F, u_t);
3402 std::string file_skel_name =
3403 "snes_iteration_skel_" + std::to_string(it) + ".h5m";
3404
3405 auto get_material_force_tag = [&]() {
3406 auto &moab = mField.get_moab();
3407 Tag tag;
3408 CHK_MOAB_THROW(moab.tag_get_handle("MaterialForce", tag),
3409 "can't get tag");
3410 return tag;
3411 };
3412
3414 CHKERR postProcessSkeletonResults(1, file_skel_name, F,
3415 {get_material_force_tag()});
3416
3418 };
3419 ts_ctx_ptr->tsDebugHook = post_proc;
3420 }
3421
3422 auto storage = solve_elastic_setup::setup(this, ts, x, true);
3423
3424 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
3425 Vec xx;
3426 CHKERR VecDuplicate(x, &xx);
3427 CHKERR VecZeroEntries(xx);
3428 CHKERR TS2SetSolution(ts, x, xx);
3429 CHKERR VecDestroy(&xx);
3430 } else {
3431 CHKERR TSSetSolution(ts, x);
3432 }
3433
3434 TetPolynomialBase::switchCacheBaseOn<HDIV>(
3435 {elasticFeLhs.get(), elasticFeRhs.get()});
3436 CHKERR TSSetUp(ts);
3437 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
3438 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
3440 CHKERR TSSolve(ts, PETSC_NULLPTR);
3442 TetPolynomialBase::switchCacheBaseOff<HDIV>(
3443 {elasticFeLhs.get(), elasticFeRhs.get()});
3444
3445 SNES snes;
3446 CHKERR TSGetSNES(ts, &snes);
3447 int lin_solver_iterations;
3448 CHKERR SNESGetLinearSolveIterations(snes, &lin_solver_iterations);
3449 MOFEM_LOG("EP", Sev::inform)
3450 << "Number of linear solver iterations " << lin_solver_iterations;
3451
3452 PetscBool test_cook_flg = PETSC_FALSE;
3453 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-test_cook", &test_cook_flg,
3454 PETSC_NULLPTR);
3455 if (test_cook_flg) {
3456 constexpr int expected_lin_solver_iterations = 11;
3457 if (lin_solver_iterations > expected_lin_solver_iterations)
3458 SETERRQ(
3459 PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
3460 "Expected number of iterations is different than expected %d > %d",
3461 lin_solver_iterations, expected_lin_solver_iterations);
3462 }
3463
3464 PetscBool test_sslv116_flag = PETSC_FALSE;
3465 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-test_sslv116",
3466 &test_sslv116_flag, PETSC_NULLPTR);
3467
3468 if (test_sslv116_flag) {
3469 double max_val = 0.0;
3470 double min_val = 0.0;
3471 auto field_min_max = [&](boost::shared_ptr<FieldEntity> ent_ptr) {
3473 auto ent_type = ent_ptr->getEntType();
3474 if (ent_type == MBVERTEX) {
3475 max_val = std::max(ent_ptr->getEntFieldData()[SPACE_DIM - 1], max_val);
3476 min_val = std::min(ent_ptr->getEntFieldData()[SPACE_DIM - 1], min_val);
3477 }
3479 };
3480 CHKERR mField.getInterface<FieldBlas>()->fieldLambdaOnEntities(
3481 field_min_max, spatialH1Disp);
3482
3483 double global_max_val = 0.0;
3484 double global_min_val = 0.0;
3485 MPI_Allreduce(&max_val, &global_max_val, 1, MPI_DOUBLE, MPI_MAX,
3486 mField.get_comm());
3487 MPI_Allreduce(&min_val, &global_min_val, 1, MPI_DOUBLE, MPI_MIN,
3488 mField.get_comm());
3489 MOFEM_LOG("EP", Sev::inform)
3490 << "Max " << spatialH1Disp << " value: " << global_max_val;
3491 MOFEM_LOG("EP", Sev::inform)
3492 << "Min " << spatialH1Disp << " value: " << global_min_val;
3493
3494 double ref_max_val = 0.00767;
3495 double ref_min_val = -0.00329;
3496 if (std::abs(global_max_val - ref_max_val) > 1e-5) {
3497 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
3498 "Incorrect max value of the displacement field: %f != %f",
3499 global_max_val, ref_max_val);
3500 }
3501 if (std::abs(global_min_val - ref_min_val) > 4e-5) {
3502 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
3503 "Incorrect min value of the displacement field: %f != %f",
3504 global_min_val, ref_min_val);
3505 }
3506 }
3507
3509
3511}
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ F
const FTensor::Tensor2< T, Dim, Dim > Vec
auto getDMTsCtx(DM dm)
Get TS context data structure used by DM.
Definition DMMoFEM.hpp:1276
MoFEMErrorCode calculateFaceMaterialForce(const int tag, TS ts)
MoFEMErrorCode gettingNorms()
[Getting norms]
MoFEMErrorCode postProcessSkeletonResults(const int tag, const std::string file, Vec f_residual=PETSC_NULLPTR, std::vector< Tag > tags_to_transfer={})
MoFEMErrorCode postProcessResults(const int tag, const std::string file, Vec f_residual=PETSC_NULLPTR, Vec var_vec=PETSC_NULLPTR, std::vector< Tag > tags_to_transfer={})

Friends And Related Symbol Documentation

◆ solve_elastic_set_up

friend struct solve_elastic_set_up
friend

Definition at line 362 of file EshelbianCore.hpp.

Member Data Documentation

◆ a00FieldList

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

Definition at line 457 of file EshelbianCore.hpp.

◆ a00RangeList

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

Definition at line 459 of file EshelbianCore.hpp.

◆ addCrackMeshsetId

int EshelbianCore::addCrackMeshsetId = 1000
inlinestatic

◆ alphaOmega

double EshelbianCore::alphaOmega = 0

◆ alphaRho

double EshelbianCore::alphaRho = 0

◆ alphaU

double EshelbianCore::alphaU = 0

◆ alphaW

double EshelbianCore::alphaW = 0

◆ AnalyticalExprPythonPtr

boost::shared_ptr<AnalyticalExprPython> EshelbianCore::AnalyticalExprPythonPtr

◆ aoS

AO EshelbianCore::aoS = PETSC_NULLPTR

Definition at line 455 of file EshelbianCore.hpp.

◆ bcSpatialAnalyticalDisplacementVecPtr

boost::shared_ptr<AnalyticalDisplacementBcVec> EshelbianCore::bcSpatialAnalyticalDisplacementVecPtr

◆ bcSpatialAnalyticalTractionVecPtr

boost::shared_ptr<AnalyticalTractionBcVec> EshelbianCore::bcSpatialAnalyticalTractionVecPtr

◆ bcSpatialDispVecPtr

boost::shared_ptr<BcDispVec> EshelbianCore::bcSpatialDispVecPtr

◆ bcSpatialFreeTractionVecPtr

boost::shared_ptr<TractionFreeBc> EshelbianCore::bcSpatialFreeTractionVecPtr

◆ bcSpatialNormalDisplacementVecPtr

boost::shared_ptr<NormalDisplacementBcVec> EshelbianCore::bcSpatialNormalDisplacementVecPtr

◆ bcSpatialPressureVecPtr

boost::shared_ptr<PressureBcVec> EshelbianCore::bcSpatialPressureVecPtr

◆ bcSpatialRotationVecPtr

boost::shared_ptr<BcRotVec> EshelbianCore::bcSpatialRotationVecPtr

◆ bcSpatialTractionVecPtr

boost::shared_ptr<TractionBcVec> EshelbianCore::bcSpatialTractionVecPtr

◆ bitAdjEnt

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

bit ref level for parent

Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 440 of file EshelbianCore.hpp.

◆ bitAdjEntMask

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

bit ref level for parent parent

Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 441 of file EshelbianCore.hpp.

◆ bitAdjParent

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

bit ref level for parent

Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 437 of file EshelbianCore.hpp.

◆ bitAdjParentMask

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

bit ref level for parent parent

Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 438 of file EshelbianCore.hpp.

◆ bubbleField

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

◆ contactDisp

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

◆ contactElement

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

◆ contactFaces

boost::shared_ptr<Range> EshelbianCore::contactFaces

◆ contactRefinementLevels

int EshelbianCore::contactRefinementLevels = 1

◆ contactTreeRhs

boost::shared_ptr<ContactTree> EshelbianCore::contactTreeRhs

Make a contact tree.

Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 185 of file EshelbianCore.hpp.

◆ crackFaces

boost::shared_ptr<Range> EshelbianCore::crackFaces

◆ crackHybridIs

SmartPetscObj<IS> EshelbianCore::crackHybridIs

Definition at line 456 of file EshelbianCore.hpp.

◆ crackingOn

PetscBool EshelbianCore::crackingOn = PETSC_FALSE
inlinestatic

◆ crackingStartTime

double EshelbianCore::crackingStartTime = 0
inlinestatic

◆ d_f

boost::function< double(const double)> EshelbianCore::d_f
static

◆ dataAtPts

boost::shared_ptr<DataAtIntegrationPts> EshelbianCore::dataAtPts

◆ dd_f

boost::function< double(const double)> EshelbianCore::dd_f
static

◆ dM

SmartPetscObj<DM> EshelbianCore::dM

Coupled problem all fields.

Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 187 of file EshelbianCore.hpp.

◆ dmElastic

SmartPetscObj<DM> EshelbianCore::dmElastic

◆ dmMaterial

SmartPetscObj<DM> EshelbianCore::dmMaterial

Material problem.

Definition at line 189 of file EshelbianCore.hpp.

◆ dmPrjSpatial

SmartPetscObj<DM> EshelbianCore::dmPrjSpatial

Projection spatial displacement.

Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 190 of file EshelbianCore.hpp.

◆ dynamicRelaxation

PetscBool EshelbianCore::dynamicRelaxation
inlinestatic

◆ dynamicStep

int EshelbianCore::dynamicStep
inlinestatic

◆ dynamicTime

double EshelbianCore::dynamicTime
inlinestatic

◆ edgeExchange

CommInterface::EntitiesPetscVector EshelbianCore::edgeExchange

◆ elasticBcLhs

boost::shared_ptr<FaceElementForcesAndSourcesCore> EshelbianCore::elasticBcLhs

◆ elasticBcRhs

boost::shared_ptr<FaceElementForcesAndSourcesCore> EshelbianCore::elasticBcRhs

◆ elasticFeLhs

boost::shared_ptr<VolumeElementForcesAndSourcesCore> EshelbianCore::elasticFeLhs

◆ elasticFeRhs

boost::shared_ptr<VolumeElementForcesAndSourcesCore> EshelbianCore::elasticFeRhs

◆ elementVolumeName

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

◆ energyReleaseSelector

enum EnergyReleaseSelector EshelbianCore::energyReleaseSelector
inlinestatic

◆ exponentBase

double EshelbianCore::exponentBase = exp(1)
static

◆ externalStrainVecPtr

boost::shared_ptr<ExternalStrainVec> EshelbianCore::externalStrainVecPtr

◆ f

boost::function< double(const double)> EshelbianCore::f = EshelbianCore::f_log_e
static

◆ faceExchange

CommInterface::EntitiesPetscVector EshelbianCore::faceExchange

◆ frontAdjEdges

boost::shared_ptr<Range> EshelbianCore::frontAdjEdges

◆ frontEdges

boost::shared_ptr<Range> EshelbianCore::frontEdges

◆ frontLayers

int EshelbianCore::frontLayers = 3

Definition at line 225 of file EshelbianCore.hpp.

◆ frontVertices

boost::shared_ptr<Range> EshelbianCore::frontVertices

◆ gradApproximator

enum RotSelector EshelbianCore::gradApproximator = LARGE_ROT
inlinestatic

◆ griffithEnergy

double EshelbianCore::griffithEnergy = 1
inlinestatic

◆ hybridSpatialDisp

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

◆ internalStressInterpOrder

int EshelbianCore::internalStressInterpOrder
inlinestatic

◆ internalStressTagName

std::string EshelbianCore::internalStressTagName
inlinestatic

◆ internalStressVoigt

PetscBool EshelbianCore::internalStressVoigt
inlinestatic
Initial value:
=
PETSC_FALSE
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 39 of file EshelbianCore.hpp.

◆ inv_d_f

boost::function< double(const double)> EshelbianCore::inv_d_f
static
Initial value:
=
static double inv_d_f_log_e(const double v)
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 47 of file EshelbianCore.hpp.

◆ inv_dd_f

boost::function< double(const double)> EshelbianCore::inv_dd_f
static
Initial value:
=
static double inv_dd_f_log_e(const double v)
Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 48 of file EshelbianCore.hpp.

◆ inv_f

boost::function< double(const double)> EshelbianCore::inv_f
static

◆ l2UserBaseScale

PetscBool EshelbianCore::l2UserBaseScale = PETSC_TRUE
inlinestatic

◆ listTagsToTransfer

std::vector<Tag> EshelbianCore::listTagsToTransfer

list of tags to transfer to postprocessor

Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 452 of file EshelbianCore.hpp.

◆ materialH1Positions

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

◆ materialOrder

int EshelbianCore::materialOrder = 1

◆ materialSkeletonFaces

boost::shared_ptr<Range> EshelbianCore::materialSkeletonFaces

Definition at line 431 of file EshelbianCore.hpp.

◆ maxMovedFaces

boost::shared_ptr<Range> EshelbianCore::maxMovedFaces

◆ mField

MoFEM::Interface& EshelbianCore::mField

◆ naturalBcElement

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

◆ nbCrackFaces

int EshelbianCore::nbCrackFaces = 0

◆ nbJIntegralContours

int EshelbianCore::nbJIntegralContours
inlinestatic

◆ noStretch

PetscBool EshelbianCore::noStretch = PETSC_FALSE
inlinestatic

◆ parentAdjSkeletonFunctionDim2

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

◆ physicalEquations

boost::shared_ptr<PhysicalEquations> EshelbianCore::physicalEquations

◆ piolaStress

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

◆ rotAxis

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

◆ rotSelector

enum RotSelector EshelbianCore::rotSelector = LARGE_ROT
inlinestatic

◆ S

Mat EshelbianCore::S = PETSC_NULLPTR

Definition at line 454 of file EshelbianCore.hpp.

◆ setSingularity

PetscBool EshelbianCore::setSingularity = PETSC_FALSE
inlinestatic

◆ skeletonElement

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

◆ skeletonFaces

boost::shared_ptr<Range> EshelbianCore::skeletonFaces

◆ skinElement

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

◆ solTSStep

SmartPetscObj<Vec> EshelbianCore::solTSStep

◆ spaceH1Order

int EshelbianCore::spaceH1Order = -1

◆ spaceOrder

int EshelbianCore::spaceOrder = 2

◆ spatialH1Disp

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

◆ spatialL2Disp

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

◆ stretchSelector

enum StretchSelector EshelbianCore::stretchSelector = LOG
inlinestatic

◆ stretchTensor

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

◆ symmetrySelector

enum SymmetrySelector EshelbianCore::symmetrySelector = NOT_SYMMETRIC
inlinestatic

◆ timeScaleMap

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

◆ use_quadratic_exp

constexpr bool EshelbianCore::use_quadratic_exp = true
inlinestaticconstexpr

Definition at line 50 of file EshelbianCore.hpp.

◆ v_max

constexpr double EshelbianCore::v_max = 12
inlinestaticconstexpr

Definition at line 51 of file EshelbianCore.hpp.

◆ v_min

constexpr double EshelbianCore::v_min = -v_max
inlinestaticconstexpr

Definition at line 52 of file EshelbianCore.hpp.

◆ vertexExchange

CommInterface::EntitiesPetscVector EshelbianCore::vertexExchange

◆ volumeExchange

CommInterface::EntitiesPetscVector EshelbianCore::volumeExchange

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