v0.15.4
Loading...
Searching...
No Matches
Classes | Public Types | 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 Types

enum  MaterialModel {
  StVenantKirchhoff , MooneyRivlin , Hencky , Neohookean ,
  LastMaterial
}
 
enum  SolverType { TimeSolver , DynamicRelaxation , Cohesive , LastSolver }
 

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 projectInternalStress (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 setFaceInterfaceOps (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< ForcesAndSourcesCore > &fe_contact_tree)
 
MoFEMErrorCode setElasticElementOps (const int tag)
 
MoFEMErrorCode setElasticElementToTs (DM dm)
 
MoFEMErrorCode addDebugModel (TS ts)
 Add debug to model.
 
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 solveCohesiveCrackGrowth (TS ts, Vec x, int start_step, double start_time)
 Solve cohesive crack growth problem.
 
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< ForcesAndSourcesCorecontactTreeRhs
 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
 
double alphaTau = 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< RangemaxMovedFaces
 
boost::shared_ptr< RangeinterfaceFaces
 
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 SolverType solverType = TimeSolver
 
static enum MaterialModel materialModel = MooneyRivlin
 
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 PetscBool intefaceCrack
 
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 = 24
 
static constexpr double v_min = -v_max
 

Friends

struct solve_elastic_set_up
 

Detailed Description

Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp, ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

Definition at line 12 of file EshelbianCore.hpp.

Member Enumeration Documentation

◆ MaterialModel

Enumerator
StVenantKirchhoff 
MooneyRivlin 
Hencky 
Neohookean 
LastMaterial 

Definition at line 14 of file EshelbianCore.hpp.

◆ SolverType

Constructor & Destructor Documentation

◆ EshelbianCore()

EshelbianCore::EshelbianCore ( MoFEM::Interface m_field)
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 944 of file EshelbianPlasticity.cpp.

944 : mField(m_field) {
945 CHK_THROW_MESSAGE(getOptions(), "getOptions failed");
946}
#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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp, ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

Definition at line 2146 of file EshelbianPlasticity.cpp.

2146 {
2148
2149 Range meshset_ents;
2150 CHKERR mField.get_moab().get_entities_by_handle(meshset, meshset_ents);
2151
2152 auto set_fe_adjacency = [&](auto fe_name) {
2155 boost::make_shared<ParentFiniteElementAdjacencyFunctionSkeleton<2>>(
2158 fe_name, MBTRI, *parentAdjSkeletonFunctionDim2);
2160 };
2161
2162 // set finite element fields
2163 auto add_field_to_fe = [this](const std::string fe,
2164 const std::string field_name) {
2171 };
2172
2174
2175 Range natural_bc_elements;
2176 if (bcSpatialDispVecPtr) {
2177 for (auto &v : *bcSpatialDispVecPtr) {
2178 natural_bc_elements.merge(v.faces);
2179 }
2180 }
2182 for (auto &v : *bcSpatialRotationVecPtr) {
2183 natural_bc_elements.merge(v.faces);
2184 }
2185 }
2187 for (auto &v : *bcSpatialNormalDisplacementVecPtr) {
2188 natural_bc_elements.merge(v.faces);
2189 }
2190 }
2193 natural_bc_elements.merge(v.faces);
2194 }
2195 }
2197 for (auto &v : *bcSpatialTractionVecPtr) {
2198 natural_bc_elements.merge(v.faces);
2199 }
2200 }
2202 for (auto &v : *bcSpatialAnalyticalTractionVecPtr) {
2203 natural_bc_elements.merge(v.faces);
2204 }
2205 }
2207 for (auto &v : *bcSpatialPressureVecPtr) {
2208 natural_bc_elements.merge(v.faces);
2209 }
2210 }
2211 natural_bc_elements = intersect(natural_bc_elements, meshset_ents);
2212
2214 CHKERR mField.add_ents_to_finite_element_by_type(natural_bc_elements, MBTRI,
2216 CHKERR add_field_to_fe(naturalBcElement, piolaStress);
2217 CHKERR add_field_to_fe(naturalBcElement, hybridSpatialDisp);
2218 CHKERR set_fe_adjacency(naturalBcElement);
2220 }
2221
2222 auto get_skin = [&](auto &body_ents) {
2223 Skinner skin(&mField.get_moab());
2224 Range skin_ents;
2225 CHKERR skin.find_skin(0, body_ents, false, skin_ents);
2226 return skin_ents;
2227 };
2228
2229 auto filter_true_skin = [&](auto &&skin) {
2230 Range boundary_ents;
2231 ParallelComm *pcomm =
2232 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
2233 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
2234 PSTATUS_NOT, -1, &boundary_ents);
2235 return boundary_ents;
2236 };
2237
2239
2240 Range body_ents;
2241 CHKERR mField.get_moab().get_entities_by_dimension(meshset, SPACE_DIM,
2242 body_ents);
2243 auto skin = filter_true_skin(get_skin(body_ents));
2244
2252 contactDisp);
2255
2257 }
2258
2260 if (contactFaces) {
2261 MOFEM_LOG("EP", Sev::inform)
2262 << "Contact elements " << contactFaces->size();
2266 CHKERR add_field_to_fe(contactElement, piolaStress);
2267 CHKERR add_field_to_fe(contactElement, contactDisp);
2268 CHKERR add_field_to_fe(contactElement, spatialL2Disp);
2269 CHKERR add_field_to_fe(contactElement, spatialH1Disp);
2270 CHKERR set_fe_adjacency(contactElement);
2272 }
2273 }
2274
2276 if (!skeletonFaces)
2277 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "No skeleton faces");
2278 MOFEM_LOG("EP", Sev::inform)
2279 << "Skeleton elements " << skeletonFaces->size();
2283 CHKERR add_field_to_fe(skeletonElement, piolaStress);
2284 CHKERR add_field_to_fe(skeletonElement, hybridSpatialDisp);
2285 CHKERR add_field_to_fe(skeletonElement, spatialL2Disp);
2286 CHKERR add_field_to_fe(skeletonElement, spatialH1Disp);
2287 CHKERR set_fe_adjacency(skeletonElement);
2289 }
2290
2292}
static auto filter_true_skin(MoFEM::Interface &m_field, Range &&skin)
static auto get_skin(MoFEM::Interface &m_field, Range body_ents)
constexpr int SPACE_DIM
@ MF_ZERO
#define MYPCOMM_INDEX
default communicator number PCOMM
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
virtual MoFEMErrorCode add_finite_element(const std::string &fe_name, enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
add finite element
virtual MoFEMErrorCode build_finite_elements(int verb=DEFAULT_VERBOSITY)=0
Build finite elements.
virtual MoFEMErrorCode modify_finite_element_add_field_col(const std::string &fe_name, const std::string name_row)=0
set field col which finite element use
virtual MoFEMErrorCode modify_finite_element_adjacency_table(const std::string &fe_name, const EntityType type, ElementAdjacencyFunct function)=0
modify finite element table, only for advanced user
virtual MoFEMErrorCode add_ents_to_finite_element_by_type(const EntityHandle entities, const EntityType type, const std::string name, const bool recursive=true)=0
add entities to finite element
virtual MoFEMErrorCode modify_finite_element_add_field_row(const std::string &fe_name, const std::string name_row)=0
set field row which finite element use
virtual MoFEMErrorCode modify_finite_element_add_field_data(const std::string &fe_name, const std::string name_field)=0
set finite element field data
#define MOFEM_LOG(channel, severity)
Log.
const double v
phase velocity of light in medium (cm/ns)
constexpr auto field_name
const std::string skeletonElement
boost::shared_ptr< TractionBcVec > bcSpatialTractionVecPtr
boost::shared_ptr< Range > contactFaces
BitRefLevel bitAdjEnt
bit ref level for parent
const std::string spatialL2Disp
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)

Definition at line 1698 of file EshelbianFracture.cpp.

1698 {
1700
1701 constexpr bool potential_crack_debug = false;
1702 if constexpr (potential_crack_debug) {
1703
1704 auto add_ents = get_range_from_block(mField, "POTENTIAL", SPACE_DIM - 1);
1705 Range crack_front_verts;
1706 CHKERR mField.get_moab().get_connectivity(*frontEdges, crack_front_verts,
1707 true);
1708 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
1709 crack_front_verts);
1710 Range crack_front_faces;
1711 CHKERR mField.get_moab().get_adjacencies(crack_front_verts, SPACE_DIM - 1,
1712 true, crack_front_faces,
1713 moab::Interface::UNION);
1714 crack_front_faces = intersect(crack_front_faces, add_ents);
1715 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
1716 crack_front_faces);
1717 CHKERR mField.getInterface<MeshsetsManager>()->addEntitiesToMeshset(
1718 BLOCKSET, addCrackMeshsetId, crack_front_faces);
1719 }
1720
1721 auto get_crack_faces = [&]() {
1722 if (maxMovedFaces) {
1723 return unite(*crackFaces, *maxMovedFaces);
1724 } else {
1725 return *crackFaces;
1726 }
1727 };
1728
1729 auto get_extended_crack_faces = [&]() {
1730 auto get_faces_of_crack_front_verts = [&](auto crack_faces_org) {
1731 ParallelComm *pcomm =
1732 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
1733
1734 Range crack_faces;
1735
1736 if (!pcomm->rank()) {
1737
1738 auto get_nodes = [&](auto &&e) {
1739 Range nodes;
1740 CHK_MOAB_THROW(mField.get_moab().get_connectivity(e, nodes, true),
1741 "get connectivity");
1742 return nodes;
1743 };
1744
1745 auto get_adj = [&](auto &&e, auto dim,
1746 auto t = moab::Interface::UNION) {
1747 Range adj;
1749 mField.get_moab().get_adjacencies(e, dim, true, adj, t),
1750 "get adj");
1751 return adj;
1752 };
1753
1754 Range body_ents;
1755 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
1756 body_ents);
1757 auto body_skin = get_skin(mField, body_ents);
1758 auto body_skin_edges = get_adj(body_skin, 1, moab::Interface::UNION);
1759 auto geometry_edges = get_range_from_block(mField, "EDGES", 1);
1760 auto front_block_edges = get_range_from_block(mField, "FRONT", 1);
1761 auto front_block_nodes = get_nodes(front_block_edges);
1762
1763 size_t s;
1764 do {
1765 s = crack_faces.size();
1766
1767 auto crack_face_nodes = get_nodes(crack_faces_org);
1768 auto crack_faces_edges =
1769 get_adj(crack_faces_org, 1, moab::Interface::UNION);
1770
1771 auto crack_skin = get_skin(mField, crack_faces_org);
1772 front_block_edges = subtract(front_block_edges, crack_skin);
1773 auto crack_skin_nodes = get_nodes(crack_skin);
1774 crack_skin_nodes.merge(front_block_nodes);
1775
1776 auto crack_skin_faces =
1777 get_adj(crack_skin, 2, moab::Interface::UNION);
1778 crack_skin_faces =
1779 subtract(subtract(crack_skin_faces, crack_faces_org), body_skin);
1780
1781 crack_faces = crack_faces_org;
1782 for (auto f : crack_skin_faces) {
1783 auto edges = intersect(
1784 get_adj(Range(f, f), 1, moab::Interface::UNION), crack_skin);
1785
1786 // if other edge is part of body skin, e.g. crack punching through
1787 // body surface
1788 if (edges.size() == 2) {
1789 edges.merge(
1790 intersect(get_adj(Range(f, f), 1, moab::Interface::UNION),
1791 body_skin_edges));
1792 }
1793
1794 if (edges.size() == 2) {
1795 auto edge_conn = get_nodes(Range(edges));
1796 auto faces = intersect(get_adj(edges, 2, moab::Interface::UNION),
1797 crack_faces_org);
1798 if (faces.size() == 2) {
1799 auto edge0_conn = get_nodes(Range(edges[0], edges[0]));
1800 auto edge1_conn = get_nodes(Range(edges[1], edges[1]));
1801 auto edges_conn = intersect(intersect(edge0_conn, edge1_conn),
1802 crack_skin_nodes); // node at apex
1803 if (edges_conn.size() == 1) {
1804
1805 auto node_edges =
1806 subtract(intersect(get_adj(edges_conn, 1,
1807 moab::Interface::INTERSECT),
1808 crack_faces_edges),
1809 crack_skin); // nodes on crack surface, but not
1810 // at the skin
1811
1812 if (node_edges.size()) {
1815 CHKERR mField.get_moab().get_coords(edges_conn, &t_v0(0));
1816
1817 auto get_t_dir = [&](auto e_conn) {
1818 auto other_node = subtract(e_conn, edges_conn);
1820 CHKERR mField.get_moab().get_coords(other_node,
1821 &t_dir(0));
1822 t_dir(i) -= t_v0(i);
1823 return t_dir;
1824 };
1825
1827 t_ave_dir(i) =
1828 get_t_dir(edge0_conn)(i) + get_t_dir(edge1_conn)(i);
1829
1830 FTensor::Tensor1<double, SPACE_DIM> t_crack_surface_ave_dir;
1831 t_crack_surface_ave_dir(i) = 0;
1832 for (auto e : node_edges) {
1833 auto e_conn = get_nodes(Range(e, e));
1834 auto t_dir = get_t_dir(e_conn);
1835 t_crack_surface_ave_dir(i) += t_dir(i);
1836 }
1837
1838 auto dot = t_ave_dir(i) * t_crack_surface_ave_dir(i);
1839 // ave edges is in opposite direction to crack surface, so
1840 // thus crack is not turning back
1841 if (dot < -std::numeric_limits<double>::epsilon()) {
1842 crack_faces.insert(f);
1843 }
1844 } else {
1845 crack_faces.insert(f);
1846 }
1847 }
1848 }
1849 } else if (edges.size() == 3) {
1850 crack_faces.insert(f);
1851 }
1852
1853 // if other edge is part of geometry edge, e.g. keyway
1854 if (edges.size() == 1) {
1855 edges.merge(
1856 intersect(get_adj(Range(f, f), 1, moab::Interface::UNION),
1857 geometry_edges));
1858 edges.merge(
1859 intersect(get_adj(Range(f, f), 1, moab::Interface::UNION),
1860 front_block_edges));
1861 if (edges.size() == 2) {
1862 crack_faces.insert(f);
1863 continue;
1864 }
1865 }
1866 }
1867
1868 crack_faces_org = crack_faces;
1869
1870 } while (s != crack_faces.size());
1871 };
1872
1873 return crack_faces; // send_type(mField, crack_faces, MBTRI);
1874 };
1875
1876 return get_faces_of_crack_front_verts(get_crack_faces());
1877 };
1878
1879 if (debug) {
1880 CHKERR save_range(mField.get_moab(), "new_crack_surface_debug.vtk",
1881 get_extended_crack_faces());
1882 }
1883
1884 auto reconstruct_crack_faces = [&](auto crack_faces) {
1885 ParallelComm *pcomm =
1886 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
1887
1888 auto impl = [&]() {
1890
1891 Range new_crack_faces;
1892 if (!pcomm->rank()) {
1893
1894 auto get_nodes = [&](auto &&e) {
1895 Range nodes;
1896 CHK_MOAB_THROW(mField.get_moab().get_connectivity(e, nodes, true),
1897 "get connectivity");
1898 return nodes;
1899 };
1900
1901 auto get_adj = [&](auto &&e, auto dim,
1902 auto t = moab::Interface::UNION) {
1903 Range adj;
1905 mField.get_moab().get_adjacencies(e, dim, true, adj, t),
1906 "get adj");
1907 return adj;
1908 };
1909
1910 auto get_test_on_crack_surface = [&]() {
1911 auto crack_faces_nodes =
1912 get_nodes(crack_faces); // nodes on crac faces
1913 auto crack_faces_tets =
1914 get_adj(crack_faces_nodes, 3,
1915 moab::Interface::UNION); // adjacent
1916 // tets to
1917 // crack
1918 // faces throug nodes
1919 auto crack_faces_tets_nodes =
1920 get_nodes(crack_faces_tets); // nodes on crack faces tets
1921 crack_faces_tets_nodes =
1922 subtract(crack_faces_tets_nodes, crack_faces_nodes);
1923 crack_faces_tets =
1924 subtract(crack_faces_tets, get_adj(crack_faces_tets_nodes, 3,
1925 moab::Interface::UNION));
1926 new_crack_faces =
1927 get_adj(crack_faces_tets, 2,
1928 moab::Interface::UNION); // adjacency faces to crack
1929 // faces through tets
1930 new_crack_faces.merge(crack_faces); // add original crack faces
1931
1932 return std::make_tuple(new_crack_faces, crack_faces_tets);
1933 };
1934
1935 auto carck_faces_test_edges = [&](auto faces, auto tets) {
1936 auto adj_tets_faces = get_adj(tets, 2, moab::Interface::UNION);
1937 auto adj_faces_edges = get_adj(subtract(faces, adj_tets_faces), 1,
1938 moab::Interface::UNION);
1939 auto adj_tets_edges = get_adj(tets, 1, moab::Interface::UNION);
1940 auto geometry_edges = get_range_from_block(mField, "EDGES", 1);
1941 auto front_block_edges = get_range_from_block(mField, "FRONT", 1);
1942 adj_faces_edges.merge(geometry_edges); // geometry edges
1943 adj_faces_edges.merge(front_block_edges); // front block edges
1944
1945 auto boundary_tets_edges = intersect(adj_tets_edges, adj_faces_edges);
1946 auto boundary_test_nodes = get_nodes(boundary_tets_edges);
1947 auto boundary_test_nodes_edges =
1948 get_adj(boundary_test_nodes, 1, moab::Interface::UNION);
1949 auto boundary_test_nodes_edges_nodes = subtract(
1950 get_nodes(boundary_test_nodes_edges), boundary_test_nodes);
1951
1952 boundary_tets_edges =
1953 subtract(boundary_test_nodes_edges,
1954 get_adj(boundary_test_nodes_edges_nodes, 1,
1955 moab::Interface::UNION));
1956
1957 Range body_ents;
1958 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
1959 body_ents);
1960 auto body_skin = get_skin(mField, body_ents);
1961
1962 auto body_skin_edges = get_adj(body_skin, 1, moab::Interface::UNION);
1963 body_skin_edges = intersect(get_adj(tets, 1, moab::Interface::UNION),
1964 body_skin_edges);
1965 body_skin = intersect(body_skin, adj_tets_faces);
1966 body_skin_edges = subtract(
1967 body_skin_edges, get_adj(body_skin, 1, moab::Interface::UNION));
1968
1969 save_range(mField.get_moab(), "body_skin_edges.vtk", body_skin_edges);
1970 for (auto e : body_skin_edges) {
1971 auto adj_tet = intersect(
1972 get_adj(Range(e, e), 3, moab::Interface::INTERSECT), tets);
1973 if (adj_tet.size() == 1) {
1974 boundary_tets_edges.insert(e);
1975 }
1976 }
1977
1978 return boundary_tets_edges;
1979 };
1980
1981 auto p = get_test_on_crack_surface();
1982 auto &[new_crack_faces, crack_faces_tets] = p;
1983
1984 if (debug) {
1985 CHKERR save_range(mField.get_moab(), "hole_crack_faces_debug.vtk",
1986 crack_faces);
1987 CHKERR save_range(mField.get_moab(), "new_crack_faces_debug.vtk",
1988 new_crack_faces);
1989 CHKERR save_range(mField.get_moab(), "new_crack_tets_debug.vtk",
1990 crack_faces_tets);
1991 }
1992
1993 auto boundary_tets_edges =
1994 carck_faces_test_edges(new_crack_faces, crack_faces_tets);
1995 CHKERR save_range(mField.get_moab(), "boundary_tets_edges.vtk",
1996 boundary_tets_edges);
1997
1998 auto resolve_surface = [&](auto boundary_tets_edges,
1999 auto crack_faces_tets) {
2000 auto boundary_tets_edges_nodes = get_nodes(boundary_tets_edges);
2001 auto crack_faces_tets_faces =
2002 get_adj(crack_faces_tets, 2, moab::Interface::UNION);
2003
2004 Range all_removed_faces;
2005 Range all_removed_tets;
2006 int counter = 0;
2007
2008 int size = 0;
2009 while (size != crack_faces_tets.size()) {
2010 auto tets_faces =
2011 get_adj(crack_faces_tets, 2, moab::Interface::UNION);
2012 auto skin_tets = get_skin(mField, crack_faces_tets);
2013 auto skin_skin =
2014 get_skin(mField, subtract(crack_faces_tets_faces, tets_faces));
2015 auto skin_skin_nodes = get_nodes(skin_skin);
2016
2017 size = crack_faces_tets.size();
2018 MOFEM_LOG("SELF", Sev::inform)
2019 << "Crack faces tets size " << crack_faces_tets.size()
2020 << " crack faces size " << crack_faces_tets_faces.size();
2021 auto skin_tets_nodes = subtract(
2022 get_nodes(skin_tets),
2023 boundary_tets_edges_nodes); // not remove tets which are
2024 // adjagasent to crack faces nodes
2025 skin_tets_nodes = subtract(skin_tets_nodes, skin_skin_nodes);
2026
2027 Range removed_nodes;
2028 Range tets_to_remove;
2029 Range faces_to_remove;
2030 for (auto n : skin_tets_nodes) {
2031 auto tets =
2032 intersect(get_adj(Range(n, n), 3, moab::Interface::INTERSECT),
2033 crack_faces_tets);
2034 if (tets.size() == 0) {
2035 continue;
2036 }
2037
2038 auto hole_detetction = [&]() {
2039 auto adj_tets =
2040 get_adj(Range(n, n), 3, moab::Interface::INTERSECT);
2041 adj_tets =
2042 subtract(adj_tets,
2043 crack_faces_tets); // tetst adjacent to the node
2044 // but not part of crack surface
2045 if (adj_tets.size() == 0) {
2046 return std::make_pair(
2047 intersect(
2048 get_adj(Range(n, n), 2, moab::Interface::INTERSECT),
2049 tets_faces),
2050 tets);
2051 }
2052
2053 std::vector<Range> tets_groups;
2054 auto test_adj_tets = adj_tets;
2055 while (test_adj_tets.size()) {
2056 auto seed_size = 0;
2057 Range seed = Range(test_adj_tets[0], test_adj_tets[0]);
2058 while (seed.size() != seed_size) {
2059 auto adj_faces =
2060 subtract(get_adj(seed, 2, moab::Interface::UNION),
2061 tets_faces); // edges which are not
2062 // part of the node
2063 seed_size = seed.size();
2064 seed.merge(
2065 intersect(get_adj(adj_faces, 3, moab::Interface::UNION),
2066 test_adj_tets));
2067 }
2068 tets_groups.push_back(seed);
2069 test_adj_tets = subtract(test_adj_tets, seed);
2070 }
2071 if (tets_groups.size() == 1) {
2072
2073 return std::make_pair(
2074 intersect(
2075 get_adj(Range(n, n), 2, moab::Interface::INTERSECT),
2076 tets_faces),
2077 tets);
2078 }
2079
2080 Range tets_to_remove;
2081 Range faces_to_remove;
2082 for (auto &r : tets_groups) {
2083 auto f = get_adj(r, 2, moab::Interface::UNION);
2084 auto t = intersect(get_adj(f, 3, moab::Interface::UNION),
2085 crack_faces_tets); // tets
2086
2087 if (f.size() > faces_to_remove.size() ||
2088 faces_to_remove.size() == 0) {
2089 faces_to_remove = f;
2090 tets_to_remove = t; // largest group of tets
2091 }
2092 }
2093 MOFEM_LOG("EPSELF", Sev::inform)
2094 << "Hole detection: faces to remove "
2095 << faces_to_remove.size() << " tets to remove "
2096 << tets_to_remove.size();
2097 return std::make_pair(faces_to_remove, tets_to_remove);
2098 };
2099
2100 if (tets.size() < tets_to_remove.size() ||
2101 tets_to_remove.size() == 0) {
2102 removed_nodes = Range(n, n);
2103 auto [h_faces_to_remove, h_tets_to_remove] =
2104 hole_detetction(); // find faces and tets to remove
2105 faces_to_remove = h_faces_to_remove;
2106 tets_to_remove = h_tets_to_remove;
2107
2108 // intersect(
2109 // get_adj(Range(n, n), 2, moab::Interface::INTERSECT),
2110 // tets_faces);
2111
2112 } // find tets which is largest adjacencty size, so that it is
2113 // removed first, and then faces are removed
2114 all_removed_faces.merge(faces_to_remove);
2115 all_removed_tets.merge(tets_to_remove);
2116 }
2117
2118 crack_faces_tets = subtract(crack_faces_tets, tets_to_remove);
2119 crack_faces_tets_faces =
2120 subtract(crack_faces_tets_faces, faces_to_remove);
2121
2122 if (debug) {
2124 "removed_nodes_" +
2125 boost::lexical_cast<std::string>(counter) + ".vtk",
2126 removed_nodes);
2128 "faces_to_remove_" +
2129 boost::lexical_cast<std::string>(counter) + ".vtk",
2130 faces_to_remove);
2132 "tets_to_remove_" +
2133 boost::lexical_cast<std::string>(counter) + ".vtk",
2134 tets_to_remove);
2136 "crack_faces_tets_faces_" +
2137 boost::lexical_cast<std::string>(counter) + ".vtk",
2138 crack_faces_tets_faces);
2140 "crack_faces_tets_" +
2141 boost::lexical_cast<std::string>(counter) + ".vtk",
2142 crack_faces_tets);
2143 }
2144 counter++;
2145 }
2146
2147 auto cese_internal_faces = [&]() {
2149 auto skin_tets = get_skin(mField, crack_faces_tets);
2150 auto adj_faces = get_adj(skin_tets, 2, moab::Interface::UNION);
2151 adj_faces =
2152 subtract(adj_faces, skin_tets); // remove skin tets faces
2153 auto adj_tets = get_adj(adj_faces, 3,
2154 moab::Interface::UNION); // tets which are
2155 // adjacent to skin
2156 crack_faces_tets =
2157 subtract(crack_faces_tets,
2158 adj_tets); // remove tets which are adjacent to
2159 // skin, so that they are not removed
2160 crack_faces_tets_faces =
2161 subtract(crack_faces_tets_faces, adj_faces);
2162
2163 all_removed_faces.merge(adj_faces);
2164 all_removed_tets.merge(adj_tets);
2165
2166 MOFEM_LOG("EPSELF", Sev::inform)
2167 << "Remove internal faces size " << adj_faces.size()
2168 << " tets size " << adj_tets.size();
2170 };
2171
2172 auto case_only_one_free_edge = [&]() {
2174
2175 for (auto t : Range(crack_faces_tets)) {
2176
2177 auto adj_faces = get_adj(
2178 Range(t, t), 2,
2179 moab::Interface::UNION); // faces of tet which can be removed
2180 auto crack_surface_edges =
2181 get_adj(subtract(unite(crack_faces_tets_faces, crack_faces),
2182 adj_faces),
2183 1,
2184 moab::Interface::UNION); // edges not on the tet but
2185 // on crack surface
2186 auto adj_edges =
2187 subtract(get_adj(Range(t, t), 1, moab::Interface::INTERSECT),
2188 crack_surface_edges); // free edges
2189 adj_edges = subtract(
2190 adj_edges,
2191 boundary_tets_edges); // edges which are not part of gemetry
2192
2193 if (adj_edges.size() == 1) {
2194 crack_faces_tets =
2195 subtract(crack_faces_tets,
2196 Range(t, t)); // remove tets which are adjacent to
2197 // skin, so that they are not removed
2198
2199 auto faces_to_remove =
2200 get_adj(adj_edges, 2, moab::Interface::UNION); // faces
2201 // which can
2202 // be removed
2203 crack_faces_tets_faces =
2204 subtract(crack_faces_tets_faces, faces_to_remove);
2205
2206 all_removed_faces.merge(faces_to_remove);
2207 all_removed_tets.merge(Range(t, t));
2208
2209 MOFEM_LOG("EPSELF", Sev::inform) << "Remove free one edges ";
2210 }
2211 }
2212
2213 crack_faces_tets = subtract(crack_faces_tets, all_removed_tets);
2214 crack_faces_tets_faces =
2215 subtract(crack_faces_tets_faces, all_removed_faces);
2216
2218 };
2219
2220 auto cese_flat_tet = [&](auto max_adj_edges) {
2222
2223 Range body_ents;
2224 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
2225 body_ents);
2226 auto body_skin = get_skin(mField, body_ents);
2227 auto body_skin_edges =
2228 get_adj(body_skin, 1, moab::Interface::UNION);
2229
2230 for (auto t : Range(crack_faces_tets)) {
2231
2232 auto adj_faces = get_adj(
2233 Range(t, t), 2,
2234 moab::Interface::UNION); // faces of tet which can be removed
2235 auto crack_surface_edges =
2236 get_adj(subtract(unite(crack_faces_tets_faces, crack_faces),
2237 adj_faces),
2238 1,
2239 moab::Interface::UNION); // edges not on the tet but
2240 // on crack surface
2241 auto adj_edges =
2242 subtract(get_adj(Range(t, t), 1, moab::Interface::INTERSECT),
2243 crack_surface_edges); // free edges
2244 adj_edges = subtract(adj_edges, body_skin_edges);
2245
2246 auto tet_edges = get_adj(Range(t, t), 1,
2247 moab::Interface::UNION); // edges of
2248 // tet
2249 tet_edges = subtract(tet_edges, adj_edges);
2250
2251 for (auto e : tet_edges) {
2252 constexpr int opposite_edge[] = {5, 3, 4, 1, 2, 0};
2253 auto get_side = [&](auto e) {
2254 int side, sense, offset;
2256 mField.get_moab().side_number(t, e, side, sense, offset),
2257 "get side number failed");
2258 return side;
2259 };
2260 auto get_side_ent = [&](auto side) {
2261 EntityHandle side_edge;
2263 mField.get_moab().side_element(t, 1, side, side_edge),
2264 "get side failed");
2265 return side_edge;
2266 };
2267 adj_edges.erase(get_side_ent(opposite_edge[get_side(e)]));
2268 }
2269
2270 if (adj_edges.size() <= max_adj_edges) {
2271
2272 double dot = 1;
2273 Range faces_to_remove;
2274 for (auto e : adj_edges) {
2275 auto edge_adj_faces =
2276 get_adj(Range(e, e), 2, moab::Interface::UNION);
2277 edge_adj_faces = intersect(edge_adj_faces, adj_faces);
2278 if (edge_adj_faces.size() != 2) {
2280 "Adj faces size is not 2 for edge " +
2281 boost::lexical_cast<std::string>(e));
2282 }
2283
2284 auto get_normal = [&](auto f) {
2287 mField.getInterface<Tools>()->getTriNormal(f, &t_n(0)),
2288 "get tri normal failed");
2289 return t_n;
2290 };
2291 auto t_n0 = get_normal(edge_adj_faces[0]);
2292 auto t_n1 = get_normal(edge_adj_faces[1]);
2293 auto get_sense = [&](auto f) {
2294 int side, sense, offset;
2295 CHK_MOAB_THROW(mField.get_moab().side_number(t, f, side,
2296 sense, offset),
2297 "get side number failed");
2298 return sense;
2299 };
2300 auto sense0 = get_sense(edge_adj_faces[0]);
2301 auto sense1 = get_sense(edge_adj_faces[1]);
2302 t_n0.normalize();
2303 t_n1.normalize();
2304
2306 auto dot_e = (sense0 * sense1) * t_n0(i) * t_n1(i);
2307 if (dot_e < dot || e == adj_edges[0]) {
2308 dot = dot_e;
2309 faces_to_remove = edge_adj_faces;
2310 }
2311 }
2312
2313 all_removed_faces.merge(faces_to_remove);
2314 all_removed_tets.merge(Range(t, t));
2315
2316 MOFEM_LOG("EPSELF", Sev::inform)
2317 << "Remove free edges on flat tet, with considered nb. of "
2318 "edges "
2319 << adj_edges.size();
2320 }
2321 }
2322
2323 crack_faces_tets = subtract(crack_faces_tets, all_removed_tets);
2324 crack_faces_tets_faces =
2325 subtract(crack_faces_tets_faces, all_removed_faces);
2326
2328 };
2329
2330 CHK_THROW_MESSAGE(case_only_one_free_edge(),
2331 "Case only one free edge failed");
2332 for (auto max_adj_edges : {0, 1, 2, 3}) {
2333 CHK_THROW_MESSAGE(cese_flat_tet(max_adj_edges),
2334 "Case only one free edge failed");
2335 }
2336 CHK_THROW_MESSAGE(cese_internal_faces(),
2337 "Case internal faces failed");
2338
2339 if (debug) {
2341 "crack_faces_tets_faces_" +
2342 boost::lexical_cast<std::string>(counter) + ".vtk",
2343 crack_faces_tets_faces);
2345 "crack_faces_tets_" +
2346 boost::lexical_cast<std::string>(counter) + ".vtk",
2347 crack_faces_tets);
2348 }
2349
2350 return std::make_tuple(crack_faces_tets_faces, crack_faces_tets,
2351 all_removed_faces, all_removed_tets);
2352 };
2353
2354 auto [resolved_faces, resolved_tets, all_removed_faces,
2355 all_removed_tets] =
2356 resolve_surface(boundary_tets_edges, crack_faces_tets);
2357 resolved_faces.merge(subtract(crack_faces, all_removed_faces));
2358 if (debug) {
2359 CHKERR save_range(mField.get_moab(), "resolved_faces.vtk",
2360 resolved_faces);
2361 CHKERR save_range(mField.get_moab(), "resolved_tets.vtk",
2362 resolved_tets);
2363 }
2364
2365 crack_faces = resolved_faces;
2366 }
2367
2369 };
2370
2371 CHK_THROW_MESSAGE(impl(), "resolve new crack surfaces");
2372
2373 return crack_faces; // send_type(mField, crack_faces, MBTRI);
2374 };
2375
2376 auto resolve_consisten_crack_extension = [&]() {
2378 auto crack_meshset =
2379 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
2381 auto meshset = crack_meshset->getMeshset();
2382
2383 if (!mField.get_comm_rank()) {
2384 Range old_crack_faces;
2385 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTRI,
2386 old_crack_faces);
2387 auto extendeded_crack_faces = get_extended_crack_faces();
2388 auto reconstructed_crack_faces =
2389 subtract(reconstruct_crack_faces(extendeded_crack_faces),
2390 subtract(*crackFaces, old_crack_faces));
2391 if (nbCrackFaces >= reconstructed_crack_faces.size()) {
2392 MOFEM_LOG("EPSELF", Sev::warning)
2393 << "No new crack faces to add, skipping adding to meshset";
2394 extendeded_crack_faces = subtract(
2395 extendeded_crack_faces, subtract(*crackFaces, old_crack_faces));
2396 MOFEM_LOG("EPSELF", Sev::inform)
2397 << "Number crack faces size (extended) "
2398 << extendeded_crack_faces.size();
2399 CHKERR mField.get_moab().clear_meshset(&meshset, 1);
2400 CHKERR mField.get_moab().add_entities(meshset, extendeded_crack_faces);
2401 } else {
2402 CHKERR mField.get_moab().clear_meshset(&meshset, 1);
2403 CHKERR mField.get_moab().add_entities(meshset,
2404 reconstructed_crack_faces);
2405 MOFEM_LOG("EPSELF", Sev::inform)
2406 << "Number crack faces size (reconstructed) "
2407 << reconstructed_crack_faces.size();
2408 nbCrackFaces = reconstructed_crack_faces.size();
2409 }
2410 }
2411
2412 Range crack_faces;
2413 if (!mField.get_comm_rank()) {
2414 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTRI,
2415 crack_faces);
2416 }
2417 crack_faces = send_type(mField, crack_faces, MBTRI);
2418 if (mField.get_comm_rank()) {
2419 CHKERR mField.get_moab().clear_meshset(&meshset, 1);
2420 CHKERR mField.get_moab().add_entities(meshset, crack_faces);
2421 }
2422
2424 };
2425
2426 CHKERR resolve_consisten_crack_extension();
2427
2429};
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
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
virtual int get_comm_rank() const =0
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
auto save_range

◆ addDebugModel()

MoFEMErrorCode EshelbianCore::addDebugModel ( TS  ts)

Add debug to model.

That prints information every SNES step

Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 3748 of file EshelbianPlasticity.cpp.

3748 {
3750
3751 PetscBool debug_model = PETSC_FALSE;
3752 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-debug_model", &debug_model,
3753 PETSC_NULLPTR);
3754 MOFEM_LOG("EP", Sev::inform)
3755 << "Debug model flag is " << (debug_model ? "ON" : "OFF");
3756
3757 if (debug_model == PETSC_TRUE) {
3758 auto ts_ctx_ptr = getDMTsCtx(dmElastic);
3759 auto post_proc = [&](TS ts, PetscReal t, Vec u, Vec u_t, Vec u_tt, Vec F,
3760 void *ctx) {
3762
3763 SNES snes;
3764 CHKERR TSGetSNES(ts, &snes);
3765 int it;
3766 CHKERR SNESGetIterationNumber(snes, &it);
3767 std::string file_name = "snes_iteration_" + std::to_string(it) + ".h5m";
3768 CHKERR postProcessResults(1, file_name, F, u_t);
3769 std::string file_skel_name =
3770 "snes_iteration_skel_" + std::to_string(it) + ".h5m";
3771
3772 auto get_material_force_tag = [&]() {
3773 auto &moab = mField.get_moab();
3774 Tag tag;
3775 CHK_MOAB_THROW(moab.tag_get_handle("MaterialForce", tag),
3776 "can't get tag");
3777 return tag;
3778 };
3779
3781 CHKERR postProcessSkeletonResults(1, file_skel_name, F,
3782 {get_material_force_tag()});
3783
3785 };
3786 ts_ctx_ptr->tsDebugHook = post_proc;
3787 }
3788
3790}
@ F
const FTensor::Tensor2< T, Dim, Dim > Vec
auto getDMTsCtx(DM dm)
Get TS context data structure used by DM.
Definition DMMoFEM.hpp:1276
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
MoFEMErrorCode calculateFaceMaterialForce(const int tag, TS ts)
MoFEMErrorCode postProcessSkeletonResults(const int tag, const std::string file, Vec f_residual=PETSC_NULLPTR, std::vector< Tag > tags_to_transfer={})
MoFEMErrorCode postProcessResults(const int tag, const std::string file, Vec f_residual=PETSC_NULLPTR, Vec var_vec=PETSC_NULLPTR, std::vector< Tag > tags_to_transfer={})
SmartPetscObj< DM > dmElastic
Elastic problem.

◆ addDMs()

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

Definition at line 2294 of file EshelbianPlasticity.cpp.

2295 {
2297
2298 // find adjacencies between finite elements and dofs
2300
2301 // Create coupled problem
2302 dM = createDM(mField.get_comm(), "DMMOFEM");
2303 CHKERR DMMoFEMCreateMoFEM(dM, &mField, "ESHELBY_PLASTICITY", bit,
2304 BitRefLevel().set());
2305 CHKERR DMMoFEMSetDestroyProblem(dM, PETSC_TRUE);
2306 CHKERR DMMoFEMSetIsPartitioned(dM, PETSC_TRUE);
2312
2313 mField.getInterface<ProblemsManager>()->buildProblemFromFields = PETSC_TRUE;
2314 CHKERR DMSetUp(dM);
2315 mField.getInterface<ProblemsManager>()->buildProblemFromFields = PETSC_FALSE;
2316
2317 auto remove_dofs_on_broken_skin = [&](const std::string prb_name) {
2319 for (int d : {0, 1, 2}) {
2320 std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_to_remove;
2322 ->getSideDofsOnBrokenSpaceEntities(
2323 dofs_to_remove, prb_name, ROW, piolaStress,
2325 // remove piola dofs, i.e. traction free boundary
2326 CHKERR mField.getInterface<ProblemsManager>()->removeDofs(prb_name, ROW,
2327 dofs_to_remove);
2328 CHKERR mField.getInterface<ProblemsManager>()->removeDofs(prb_name, COL,
2329 dofs_to_remove);
2330 }
2332 };
2333 CHKERR remove_dofs_on_broken_skin("ESHELBY_PLASTICITY");
2334
2335 // Create elastic sub-problem
2336 dmElastic = createDM(mField.get_comm(), "DMMOFEM");
2337 CHKERR DMMoFEMCreateSubDM(dmElastic, dM, "ELASTIC_PROBLEM");
2343 if (!noStretch) {
2345 }
2355 CHKERR DMSetUp(dmElastic);
2356
2357 // dmMaterial = createDM(mField.get_comm(), "DMMOFEM");
2358 // CHKERR DMMoFEMCreateSubDM(dmMaterial, dM, "MATERIAL_PROBLEM");
2359 // CHKERR DMMoFEMSetDestroyProblem(dmMaterial, PETSC_TRUE);
2360 // CHKERR DMMoFEMAddSubFieldRow(dmMaterial, eshelbyStress);
2361 // CHKERR DMMoFEMAddSubFieldRow(dmMaterial, materialL2Disp);
2362 // CHKERR DMMoFEMAddElement(dmMaterh elementVolumeName);
2363 // CHKERR DMMoFEMAddElement(dmMaterial, naturalBcElement);
2364 // CHKERR DMMoFEMAddElement(dmMaterial, skinElement);
2365 // CHKERR DMMoFEMSetSquareProblem(dmMaterial, PETSC_TRUE);
2366 // CHKERR DMMoFEMSetIsPartitioned(dmMaterial, PETSC_TRUE);
2367 // CHKERR DMSetUp(dmMaterial);
2368
2369 auto set_zero_block = [&]() {
2371 if (!noStretch) {
2372 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2373 "ELASTIC_PROBLEM", spatialL2Disp, stretchTensor);
2374 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2375 "ELASTIC_PROBLEM", stretchTensor, spatialL2Disp);
2376 }
2377 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2378 "ELASTIC_PROBLEM", spatialL2Disp, rotAxis);
2379 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2380 "ELASTIC_PROBLEM", rotAxis, spatialL2Disp);
2381 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2382 "ELASTIC_PROBLEM", spatialL2Disp, bubbleField);
2383 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2384 "ELASTIC_PROBLEM", bubbleField, spatialL2Disp);
2385 if (!noStretch) {
2386 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2387 "ELASTIC_PROBLEM", bubbleField, bubbleField);
2388 CHKERR
2389 mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2390 "ELASTIC_PROBLEM", piolaStress, piolaStress);
2391 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2392 "ELASTIC_PROBLEM", bubbleField, piolaStress);
2393 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2394 "ELASTIC_PROBLEM", piolaStress, bubbleField);
2395 }
2396
2399 };
2400
2401 auto set_section = [&]() {
2403 PetscSection section;
2404 CHKERR mField.getInterface<ISManager>()->sectionCreate("ELASTIC_PROBLEM",
2405 &section);
2406 CHKERR DMSetSection(dmElastic, section);
2407 CHKERR DMSetGlobalSection(dmElastic, section);
2408 CHKERR PetscSectionDestroy(&section);
2410 };
2411
2412 CHKERR set_zero_block();
2413 CHKERR set_section();
2414
2415 dmPrjSpatial = createDM(mField.get_comm(), "DMMOFEM");
2416 CHKERR DMMoFEMCreateSubDM(dmPrjSpatial, dM, "PROJECT_SPATIAL");
2422 CHKERR DMSetUp(dmPrjSpatial);
2423
2424 // CHKERR mField.getInterface<BcManager>()
2425 // ->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
2426 // "PROJECT_SPATIAL", spatialH1Disp, true, false);
2427
2429}
@ 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.
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
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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp, ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

Definition at line 1235 of file EshelbianPlasticity.cpp.

1235 {
1237
1238 auto get_tets = [&]() {
1239 Range tets;
1240 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
1241 return tets;
1242 };
1243
1244 auto get_tets_skin = [&]() {
1245 Range tets_skin_part;
1246 Skinner skin(&mField.get_moab());
1247 CHKERR skin.find_skin(0, get_tets(), false, tets_skin_part);
1248 ParallelComm *pcomm =
1249 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
1250 Range tets_skin;
1251 CHKERR pcomm->filter_pstatus(tets_skin_part,
1252 PSTATUS_SHARED | PSTATUS_MULTISHARED,
1253 PSTATUS_NOT, -1, &tets_skin);
1254 return tets_skin;
1255 };
1256
1257 auto subtract_boundary_conditions = [&](auto &&tets_skin) {
1258 // That mean, that hybrid field on all faces on which traction is applied,
1259 // on other faces, or enforcing displacements as
1260 // natural boundary condition.
1262 for (auto &v : *bcSpatialTractionVecPtr) {
1263 tets_skin = subtract(tets_skin, v.faces);
1264 }
1266 for (auto &v : *bcSpatialAnalyticalTractionVecPtr) {
1267 tets_skin = subtract(tets_skin, v.faces);
1268 }
1269
1271 for (auto &v : *bcSpatialPressureVecPtr) {
1272 tets_skin = subtract(tets_skin, v.faces);
1273 }
1274
1275 return tets_skin;
1276 };
1277
1278 auto add_blockset = [&](auto block_name, auto &&tets_skin) {
1279 auto crack_faces =
1280 get_range_from_block(mField, "block_name", SPACE_DIM - 1);
1281 tets_skin.merge(crack_faces);
1282 return tets_skin;
1283 };
1284
1285 auto subtract_blockset = [&](auto block_name, auto &&tets_skin) {
1286 auto contact_range =
1287 get_range_from_block(mField, block_name, SPACE_DIM - 1);
1288 tets_skin = subtract(tets_skin, contact_range);
1289 return tets_skin;
1290 };
1291
1292 auto get_stress_trace_faces = [&](auto &&tets_skin) {
1293 Range faces;
1294 CHKERR mField.get_moab().get_adjacencies(get_tets(), SPACE_DIM - 1, true,
1295 faces, moab::Interface::UNION);
1296 Range trace_faces = subtract(faces, tets_skin);
1297 return trace_faces;
1298 };
1299
1300 auto tets = get_tets();
1301
1302 // remove also contact faces, i.e. that is also kind of hybrid field but
1303 // named but used to enforce contact conditions
1304 auto trace_faces = get_stress_trace_faces(
1305
1306 subtract_blockset("CONTACT",
1307 subtract_boundary_conditions(get_tets_skin()))
1308
1309 );
1310
1311 contactFaces = boost::make_shared<Range>(intersect(
1312 trace_faces, get_range_from_block(mField, "CONTACT", SPACE_DIM - 1)));
1314 boost::make_shared<Range>(subtract(trace_faces, *contactFaces));
1315
1316#ifndef NDEBUG
1317 if (contactFaces->size())
1319 "contact_faces_" +
1320 std::to_string(mField.get_comm_rank()) + ".vtk",
1321 *contactFaces);
1322 if (skeletonFaces->size())
1324 "skeleton_faces_" +
1325 std::to_string(mField.get_comm_rank()) + ".vtk",
1326 *skeletonFaces);
1327#endif
1328
1329 auto add_broken_hdiv_field = [this, meshset](const std::string field_name,
1330 const int order) {
1332
1334
1335 auto get_side_map_hdiv = [&]() {
1336 return std::vector<
1337
1338 std::pair<EntityType,
1340
1341 >>{
1342
1343 {MBTET,
1344 [&](BaseFunction::DofsSideMap &dofs_side_map) -> MoFEMErrorCode {
1345 return TetPolynomialBase::setDofsSideMap(HDIV, DISCONTINUOUS, base,
1346 dofs_side_map);
1347 }}
1348
1349 };
1350 };
1351
1353 get_side_map_hdiv(), MB_TAG_DENSE, MF_ZERO);
1355 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1357 };
1358
1359 auto add_l2_field = [this, meshset](const std::string field_name,
1360 const int order, const int dim) {
1363 MB_TAG_DENSE, MF_ZERO);
1365 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1367 };
1368
1369 auto add_h1_field = [this, meshset](const std::string field_name,
1370 const int order, const int dim) {
1373 MB_TAG_DENSE, MF_ZERO);
1375 CHKERR mField.set_field_order(meshset, MBVERTEX, field_name, 1);
1376 CHKERR mField.set_field_order(meshset, MBEDGE, field_name, order);
1377 CHKERR mField.set_field_order(meshset, MBTRI, field_name, order);
1378 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1380 };
1381
1382 auto add_l2_field_by_range = [this](const std::string field_name,
1383 const int order, const int dim,
1384 const int field_dim, Range &&r) {
1387 MB_TAG_DENSE, MF_ZERO);
1388 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(r);
1392 };
1393
1394 auto add_bubble_field = [this, meshset](const std::string field_name,
1395 const int order, const int dim) {
1397 CHKERR mField.add_field(field_name, HDIV, USER_BASE, dim, MB_TAG_DENSE,
1398 MF_ZERO);
1399 // Modify field
1400 auto field_ptr = mField.get_field_structure(field_name);
1401 auto field_order_table =
1402 const_cast<Field *>(field_ptr)->getFieldOrderTable();
1403 auto get_cgg_bubble_order_zero = [](int p) { return 0; };
1404 auto get_cgg_bubble_order_tet = [](int p) {
1405 return NBVOLUMETET_CCG_BUBBLE(p);
1406 };
1407 field_order_table[MBVERTEX] = get_cgg_bubble_order_zero;
1408 field_order_table[MBEDGE] = get_cgg_bubble_order_zero;
1409 field_order_table[MBTRI] = get_cgg_bubble_order_zero;
1410 field_order_table[MBTET] = get_cgg_bubble_order_tet;
1412 CHKERR mField.set_field_order(meshset, MBTRI, field_name, order);
1413 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1415 };
1416
1417 auto add_user_l2_field = [this, meshset](const std::string field_name,
1418 const int order, const int dim) {
1420 CHKERR mField.add_field(field_name, L2, USER_BASE, dim, MB_TAG_DENSE,
1421 MF_ZERO);
1422 // Modify field
1423 auto field_ptr = mField.get_field_structure(field_name);
1424 auto field_order_table =
1425 const_cast<Field *>(field_ptr)->getFieldOrderTable();
1426 auto zero_dofs = [](int p) { return 0; };
1427 auto dof_l2_tet = [](int p) { return NBVOLUMETET_L2(p); };
1428 field_order_table[MBVERTEX] = zero_dofs;
1429 field_order_table[MBEDGE] = zero_dofs;
1430 field_order_table[MBTRI] = zero_dofs;
1431 field_order_table[MBTET] = dof_l2_tet;
1433 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1435 };
1436
1437 // spatial fields
1438 CHKERR add_broken_hdiv_field(piolaStress, spaceOrder);
1439 CHKERR add_bubble_field(bubbleField, spaceOrder, 1);
1440 CHKERR add_l2_field(spatialL2Disp, spaceOrder - 1, 3);
1441 CHKERR add_user_l2_field(rotAxis, spaceOrder - 1, 3);
1442 CHKERR add_user_l2_field(stretchTensor, noStretch ? -1 : spaceOrder, 6);
1443
1444 if (!skeletonFaces)
1445 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "No skeleton faces");
1446 if (!contactFaces)
1447 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "No contact faces");
1448
1449 auto get_hybridised_disp = [&]() {
1450 auto faces = *skeletonFaces;
1451 auto skin = subtract_boundary_conditions(get_tets_skin());
1452 for (auto &bc : *bcSpatialNormalDisplacementVecPtr) {
1453 faces.merge(intersect(bc.faces, skin));
1454 }
1455 return faces;
1456 };
1457
1458 CHKERR add_l2_field_by_range(hybridSpatialDisp, spaceOrder - 1, 2, 3,
1459 get_hybridised_disp());
1460 CHKERR add_l2_field_by_range(contactDisp, spaceOrder - 1, 2, 3,
1462
1463 // spatial displacement
1464 CHKERR add_h1_field(spatialH1Disp, spaceH1Order, 3);
1465 // material positions
1466 CHKERR add_h1_field(materialH1Positions, 2, 3);
1467
1468 // Eshelby stress
1469 // CHKERR add_broken_hdiv_field(eshelbyStress, spaceOrder);
1470 // CHKERR add_l2_field(materialL2Disp, spaceOrder - 1, 3);
1471 // CHKERR add_l2_field_by_range(hybridMaterialDisp, spaceOrder - 1, 2, 3,
1472 // Range(*materialSkeletonFaces));
1473
1475
1477}
#define NBVOLUMETET_CCG_BUBBLE(P)
Bubble function for CGG H div space.
FieldApproximationBase
approximation base
Definition definitions.h:58
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
@ USER_BASE
user implemented approximation base
Definition definitions.h:68
@ DEMKOWICZ_JACOBI_BASE
Definition definitions.h:66
@ L2
field with C-1 continuity
Definition definitions.h:88
@ H1
continuous field
Definition definitions.h:85
@ HDIV
field with continuous normal traction
Definition definitions.h:87
@ DISCONTINUOUS
Broken continuity (No effect on L2 space)
constexpr int order
virtual const Field * get_field_structure(const std::string &name, enum MoFEMTypes bh=MF_EXIST) const =0
get field structure
virtual MoFEMErrorCode build_fields(int verb=DEFAULT_VERBOSITY)=0
virtual MoFEMErrorCode add_ents_to_field_by_dim(const Range &ents, const int dim, const std::string &name, int verb=DEFAULT_VERBOSITY)=0
Add entities to field meshset.
virtual MoFEMErrorCode set_field_order(const EntityHandle meshset, const EntityType type, const std::string &name, const ApproximationOrder order, int verb=DEFAULT_VERBOSITY)=0
Set order approximation of the entities in the field.
virtual MoFEMErrorCode add_ents_to_field_by_type(const Range &ents, const EntityType type, const std::string &name, int verb=DEFAULT_VERBOSITY)=0
Add entities to field meshset.
#define NBVOLUMETET_L2(P)
Number of base functions on tetrahedron for L2 space.
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
int r
Definition sdf.py:205
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.
Managing BitRefLevels.
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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp, ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

Definition at line 2109 of file EshelbianPlasticity.cpp.

2109 {
2111
2112 // set finite element fields
2113 auto add_field_to_fe = [this](const std::string fe,
2114 const std::string field_name) {
2120 };
2121
2126
2127 CHKERR add_field_to_fe(elementVolumeName, piolaStress);
2128 CHKERR add_field_to_fe(elementVolumeName, bubbleField);
2129 if (!noStretch)
2130 CHKERR add_field_to_fe(elementVolumeName, stretchTensor);
2131 CHKERR add_field_to_fe(elementVolumeName, rotAxis);
2132 CHKERR add_field_to_fe(elementVolumeName, spatialL2Disp);
2133 CHKERR add_field_to_fe(elementVolumeName, spatialH1Disp);
2134 CHKERR add_field_to_fe(elementVolumeName, contactDisp);
2137
2138 // build finite elements data structures
2140 }
2141
2143}

◆ calculateCrackArea()

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

Definition at line 2463 of file EshelbianFracture.cpp.

2463 {
2465
2466 if (!area_ptr) {
2467 CHK_THROW_MESSAGE(MOFEM_INVALID_DATA, "area_ptr is null");
2468 }
2469
2470 int success;
2471 *area_ptr = 0;
2472 if (mField.get_comm_rank() == 0) {
2473 MOFEM_LOG("EP", Sev::inform) << "Calculate crack area";
2474 auto crack_faces = get_range_from_block(mField, "CRACK", SPACE_DIM - 1);
2475 for (auto f : crack_faces) {
2476 *area_ptr += mField.getInterface<Tools>()->getTriArea(f);
2477 }
2478 success = MPI_Bcast(area_ptr.get(), 1, MPI_DOUBLE, 0, mField.get_comm());
2479 } else {
2480 success = MPI_Bcast(area_ptr.get(), 1, MPI_DOUBLE, 0, mField.get_comm());
2481 }
2482 if (success != MPI_SUCCESS) {
2484 }
2486}
@ 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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 14 of file EshelbianFracture.cpp.

14 {
16
17 constexpr bool debug = false;
18
19 auto get_tags_vec = [&](std::vector<std::pair<std::string, int>> names) {
20 std::vector<Tag> tags;
21 tags.reserve(names.size());
22 auto create_and_clean = [&]() {
24 for (auto n : names) {
25 tags.push_back(Tag());
26 auto &tag = tags.back();
27 auto &moab = mField.get_moab();
28 auto rval = moab.tag_get_handle(n.first.c_str(), tag);
29 if (rval == MB_SUCCESS) {
30 moab.tag_delete(tag);
31 }
32 double def_val[] = {0., 0., 0.};
33 CHKERR moab.tag_get_handle(n.first.c_str(), n.second, MB_TYPE_DOUBLE,
34 tag, MB_TAG_CREAT | MB_TAG_SPARSE, def_val);
35 }
37 };
38 CHK_THROW_MESSAGE(create_and_clean(), "create_and_clean");
39 return tags;
40 };
41
42 enum ExhangeTags { MATERIALFORCE, AREAGROWTH, GRIFFITHFORCE, FACEPRESSURE };
43
44 auto tags = get_tags_vec({{"MaterialForce", 3},
45 {"AreaGrowth", 3},
46 {"GriffithForce", 1},
47 {"FacePressure", 1}});
48
49 auto calculate_material_forces = [&]() {
51
52 /**
53 * @brief Create element to integration faces energies
54 */
55 auto get_face_material_force_fe = [&]() {
57 auto fe_ptr = boost::make_shared<FaceEle>(mField);
58 fe_ptr->getRuleHook = [](int, int, int) { return -1; };
59 fe_ptr->setRuleHook =
60 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
61
62 // hybrid disp, evalated on face first
63 EshelbianPlasticity::AddHOOps<2, 2, 3>::add(
64 fe_ptr->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
65 fe_ptr->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
66 hybridSpatialDisp, dataAtPts->getHybridDispAtPts()));
67 fe_ptr->getOpPtrVector().push_back(
68 new OpCalculateVectorFieldGradient<SPACE_DIM, SPACE_DIM>(
69 hybridSpatialDisp, dataAtPts->getGradHybridDispAtPts()));
70 auto op_loop_domain_side =
71 new OpLoopSide<VolumeElementForcesAndSourcesCoreOnSide>(
72 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
73 fe_ptr->getOpPtrVector().push_back(op_loop_domain_side);
74 fe_ptr->getOpPtrVector().push_back(new OpFaceMaterialForce(dataAtPts));
75
76 // evaluated in side domain, that is op_loop_domain_side
77 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
78 boost::make_shared<CGGUserPolynomialBase>();
79
80 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
81 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
82 materialH1Positions, frontAdjEdges, nullptr, nullptr, nullptr);
83 op_loop_domain_side->getOpPtrVector().push_back(
84 new OpCalculateHVecTensorField<SPACE_DIM, SPACE_DIM>(
85 piolaStress, dataAtPts->getApproxPAtPts()));
86 op_loop_domain_side->getOpPtrVector().push_back(
87 new OpCalculateHTensorTensorField<SPACE_DIM, SPACE_DIM>(
88 bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
89
90 op_loop_domain_side->getOpPtrVector().push_back(
91 new OpCalculateVectorFieldValues<SPACE_DIM>(
92 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
94 // We have to use actual strains to evaluate J integral and energy,
95 // in this case. Note actual stresses, and actual energy can only drive
96 // crack growth
97
98 op_loop_domain_side->getOpPtrVector().push_back(
99 physicalEquations->returnOpCalculateStretchFromStress(
101 } else {
102 // That will not work for problem with internal stress or strain, since
103 // we approximate mechanical stretch, not actual stretch. At some point
104 // in time we can change formulation so that actual stretch is
105 // approximated. However, the way how to do it is not clear.
106
107 op_loop_domain_side->getOpPtrVector().push_back(
108 new OpCalculateTensor2SymmetricFieldValues<SPACE_DIM>(
109 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
110 }
111
112 op_loop_domain_side->getOpPtrVector().push_back(
114
115 return fe_ptr;
116 };
117
118 auto integrate_face_material_force_fe = [&](auto &&face_energy_fe) {
121 dM, skeletonElement, face_energy_fe, 0, mField.get_comm_size());
122
123 auto face_exchange = CommInterface::createEntitiesPetscVector(
124 mField.get_comm(), mField.get_moab(), 2, 3, Sev::inform);
125
126 auto print_loc_size = [this](auto v, auto str, auto sev) {
128 int size;
129 CHKERR VecGetLocalSize(v.second, &size);
130 int low, high;
131 CHKERR VecGetOwnershipRange(v.second, &low, &high);
132 MOFEM_LOG("EPSYNC", sev) << str << " local size " << size << " ( "
133 << low << " " << high << " ) ";
136 };
137 CHKERR print_loc_size(face_exchange, "material face_exchange",
138 Sev::verbose);
139
140 CHKERR CommInterface::updateEntitiesPetscVector(
141 mField.get_moab(), face_exchange, tags[ExhangeTags::MATERIALFORCE]);
142 CHKERR CommInterface::updateEntitiesPetscVector(
143 mField.get_moab(), faceExchange, tags[ExhangeTags::FACEPRESSURE]);
144
145 // #ifndef NDEBUG
146 if (debug) {
148 "front_skin_faces_material_force_" +
149 std::to_string(mField.get_comm_rank()) + ".vtk",
151 }
152 // #endif
153
155 };
156
157 CHKERR integrate_face_material_force_fe(get_face_material_force_fe());
158
160 };
161
162 auto calculate_front_material_force = [&](auto nb_J_integral_contours) {
165
166 auto get_conn = [&](auto e) {
167 Range conn;
168 CHK_MOAB_THROW(mField.get_moab().get_connectivity(&e, 1, conn, true),
169 "get connectivity");
170 return conn;
171 };
172
173 auto get_conn_range = [&](auto e) {
174 Range conn;
175 CHK_MOAB_THROW(mField.get_moab().get_connectivity(e, conn, true),
176 "get connectivity");
177 return conn;
178 };
179
180 auto get_adj = [&](auto e, auto dim) {
181 Range adj;
182 CHK_MOAB_THROW(mField.get_moab().get_adjacencies(&e, 1, dim, true, adj),
183 "get adj");
184 return adj;
185 };
186
187 auto get_adj_range = [&](auto e, auto dim) {
188 Range adj;
189 CHK_MOAB_THROW(mField.get_moab().get_adjacencies(e, dim, true, adj,
190 moab::Interface::UNION),
191 "get adj");
192 return adj;
193 };
194
195 auto get_material_force = [&](auto r, auto th) {
196 MatrixDouble material_forces(r.size(), 3, false);
198 mField.get_moab().tag_get_data(th, r, material_forces.data().data()),
199 "get data");
200 return material_forces;
201 };
202
203 if (mField.get_comm_rank() == 0) {
204
205 auto crack_edges = get_adj_range(*crackFaces, 1);
206 auto front_nodes = get_conn_range(*frontEdges);
207 auto body_edges = get_range_from_block(mField, "EDGES", 1);
208 // auto front_block_edges = get_range_from_block(mField, "FRONT", 1);
209 // front_block_edges = subtract(front_block_edges, crack_edges);
210 // auto front_block_edges_conn = get_conn_range(front_block_edges);
211
212 // #ifndef NDEBUG
213 Range all_skin_faces;
214 Range all_front_faces;
215 // #endif
216
217 auto calculate_edge_direction = [&](auto e) {
218 const EntityHandle *conn;
219 int num_nodes;
221 mField.get_moab().get_connectivity(e, conn, num_nodes, true),
222 "get connectivity");
223 std::array<double, 6> coords;
225 mField.get_moab().get_coords(conn, num_nodes, coords.data()),
226 "get coords");
228 &coords[0], &coords[1], &coords[2]};
230 &coords[3], &coords[4], &coords[5]};
233 t_dir(i) = t_p1(i) - t_p0(i);
234 return t_dir;
235 };
236
237 // take bubble tets at node, and then avarage over the edges
238 auto calculate_force_through_node = [&]() {
240
245
246 Range body_ents;
247 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
248 body_ents);
249 auto body_skin = get_skin(mField, body_ents);
250 auto body_skin_conn = get_conn_range(body_skin);
251
252 // calculate nodal material force
253 for (auto n : front_nodes) {
254 auto adj_tets = get_adj(n, 3);
255 for (int ll = 0; ll < nb_J_integral_contours; ++ll) {
256 auto conn = get_conn_range(adj_tets);
257 adj_tets = get_adj_range(conn, 3);
258 }
259 auto skin_faces = get_skin(mField, adj_tets);
260 auto material_forces = get_material_force(skin_faces, tags[0]);
261
262#ifndef NDEBUG
263 if (debug) {
264 all_skin_faces.merge(skin_faces);
265 }
266#endif
267
268 auto calculate_node_material_force = [&]() {
269 auto t_face_T =
270 getFTensor1FromPtr<SPACE_DIM>(material_forces.data().data());
271 FTensor::Tensor1<double, SPACE_DIM> t_node_force{0., 0., 0.};
272 for (auto face : skin_faces) {
273
274 FTensor::Tensor1<double, SPACE_DIM> t_face_force_tmp{0., 0., 0.};
275 t_face_force_tmp(I) = t_face_T(I);
276 ++t_face_T;
277
278 auto face_tets = intersect(get_adj(face, 3), adj_tets);
279
280 if (face_tets.empty()) {
281 continue;
282 }
283
284 if (face_tets.size() != 1) {
286 "face_tets.size() != 1");
287 }
288
289 int side_number, sense, offset;
290 CHK_MOAB_THROW(mField.get_moab().side_number(face_tets[0], face,
291 side_number, sense,
292 offset),
293 "moab side number");
294 t_face_force_tmp(I) *= sense;
295 t_node_force(I) += t_face_force_tmp(I);
296 }
297
298 return t_node_force;
299 };
300
301 auto calculate_crack_area_growth_direction = [&](auto n,
302 auto &t_node_force) {
303 // if skin is on body surface, project the direction on it
304 FTensor::Tensor1<double, SPACE_DIM> t_project{0., 0., 0.};
305 auto boundary_node = intersect(Range(n, n), body_skin_conn);
306 if (boundary_node.size()) {
307 auto faces = intersect(get_adj(n, 2), body_skin);
308 for (auto f : faces) {
309 FTensor::Tensor1<double, 3> t_normal_face;
310 CHKERR mField.getInterface<Tools>()->getTriNormal(
311 f, &t_normal_face(0));
312 t_project(I) += t_normal_face(I);
313 }
314 t_project.normalize();
315 }
316
317 // calculate surface projection matrix
320 t_Q(I, J) = t_kd(I, J);
321 if (boundary_node.size()) {
322 t_Q(I, J) -= t_project(I) * t_project(J);
323 }
324
325 auto adj_faces = intersect(get_adj(n, 2), *crackFaces);
326 if (adj_faces.empty()) {
327 auto adj_edges =
328 intersect(get_adj(n, 1), unite(*frontEdges, body_edges));
329 double l = 0;
330 for (auto e : adj_edges) {
331 auto t_dir = calculate_edge_direction(e);
332 l += t_dir.l2();
333 }
334 l /= 2;
335 FTensor::Tensor1<double, SPACE_DIM> t_area_dir{0., 0., 0.};
337 t_node_force_tmp(I) = t_node_force(I);
338 t_node_force_tmp.normalize();
339 t_area_dir(I) = -t_node_force_tmp(I);
340 t_area_dir(I) *= l / 2;
341 return t_area_dir;
342 }
343
344 // calculate direction
345 auto front_edges = get_adj(n, 1);
346 FTensor::Tensor1<double, 3> t_area_dir{0., 0., 0.};
347 for (auto f : adj_faces) {
348 int num_nodes;
349 const EntityHandle *conn;
350 CHKERR mField.get_moab().get_connectivity(f, conn, num_nodes,
351 true);
352 std::array<double, 9> coords;
353 CHKERR mField.get_moab().get_coords(conn, num_nodes,
354 coords.data());
355 FTensor::Tensor1<double, 3> t_face_normal;
357 CHKERR mField.getInterface<Tools>()->getTriNormal(
358 coords.data(), &t_face_normal(0), &t_d_normal(0, 0, 0));
359 auto n_it = std::find(conn, conn + num_nodes, n);
360 auto n_index = std::distance(conn, n_it);
361
362 FTensor::Tensor2<double, 3, 3> t_face_hessian{
363 t_d_normal(0, n_index, 0), t_d_normal(0, n_index, 1),
364 t_d_normal(0, n_index, 2),
365
366 t_d_normal(1, n_index, 0), t_d_normal(1, n_index, 1),
367 t_d_normal(1, n_index, 2),
368
369 t_d_normal(2, n_index, 0), t_d_normal(2, n_index, 1),
370 t_d_normal(2, n_index, 2)};
371
372 FTensor::Tensor2<double, 3, 3> t_projected_hessian;
373 t_projected_hessian(I, J) =
374 t_Q(I, K) * (t_face_hessian(K, L) * t_Q(L, J));
375 t_face_normal.normalize();
376 t_area_dir(K) +=
377 t_face_normal(I) * t_projected_hessian(I, K) / 2.;
378 }
379
380 return t_area_dir;
381 };
382
383 auto t_node_force = calculate_node_material_force();
384 t_node_force(I) /= griffithEnergy; // scale all by griffith energy
386 mField.get_moab().tag_set_data(tags[ExhangeTags::MATERIALFORCE],
387 &n, 1, &t_node_force(0)),
388 "set data");
389
390 auto get_area_dir = [&]() {
391 FTensor::Tensor1<double, SPACE_DIM> t_area_dir{0., 0., 0.};
392 auto adj_edges = intersect(get_adj_range(adj_tets, 1),
393 unite(*frontEdges, body_edges));
394 auto seed_n = get_conn_range(adj_edges);
395 auto skin_adj_edges = get_skin(mField, adj_edges);
396 skin_adj_edges = subtract(skin_adj_edges, body_skin_conn);
397 seed_n = subtract(seed_n, skin_adj_edges);
398 t_area_dir(I) = 0;
399 for (auto sn : seed_n) {
400 auto t_area_dir_sn =
401 calculate_crack_area_growth_direction(sn, t_node_force);
402 t_area_dir(I) += t_area_dir_sn(I);
403 }
404 for (auto sn : skin_adj_edges) {
405 auto t_area_dir_sn =
406 calculate_crack_area_growth_direction(sn, t_node_force);
407 t_area_dir(I) += t_area_dir_sn(I) / 2;
408 }
409 return t_area_dir;
410 };
411
412 auto t_area_dir = get_area_dir();
413
415 mField.get_moab().tag_set_data(tags[ExhangeTags::AREAGROWTH], &n,
416 1, &t_area_dir(0)),
417 "set data");
418 auto griffith = -t_node_force(I) * t_area_dir(I) /
419 (t_area_dir(K) * t_area_dir(K));
421 mField.get_moab().tag_set_data(tags[ExhangeTags::GRIFFITHFORCE],
422 &n, 1, &griffith),
423 "set data");
424 }
425
426 // iterate over edges, and calculate average edge material force
427 auto ave_node_force = [&](auto th) {
429
430 for (auto e : *frontEdges) {
431
432 auto conn = get_conn(e);
433 auto data = get_material_force(conn, th);
434 auto t_node = getFTensor1FromPtr<SPACE_DIM>(data.data().data());
435 FTensor::Tensor1<double, SPACE_DIM> t_edge{0., 0., 0.};
436 for (auto n : conn) {
437 NOT_USED(n);
438 t_edge(I) += t_node(I);
439 ++t_node;
440 }
441 t_edge(I) /= conn.size();
442
443 FTensor::Tensor1<double, SPACE_DIM> t_edge_direction =
444 calculate_edge_direction(e);
445 t_edge_direction.normalize();
446
451 t_cross(K) =
452 FTensor::levi_civita(I, J, K) * t_edge_direction(I) * t_edge(J);
453 t_edge(K) = FTensor::levi_civita(I, J, K) * t_edge_direction(J) *
454 t_cross(I);
455
456 CHKERR mField.get_moab().tag_set_data(th, &e, 1, &t_edge(0));
457 }
459 };
460
461 // iterate over edges, and calculate average edge griffith energy
462 auto ave_node_griffith_energy = [&](auto th) {
464 for (auto e : *frontEdges) {
466 CHKERR mField.get_moab().tag_get_data(
467 tags[ExhangeTags::MATERIALFORCE], &e, 1, &t_edge_force(0));
469 CHKERR mField.get_moab().tag_get_data(tags[ExhangeTags::AREAGROWTH],
470 &e, 1, &t_edge_area_dir(0));
471 double griffith_energy = -t_edge_force(I) * t_edge_area_dir(I) /
472 (t_edge_area_dir(K) * t_edge_area_dir(K));
473 CHKERR mField.get_moab().tag_set_data(th, &e, 1, &griffith_energy);
474 }
476 };
477
478 CHKERR ave_node_force(tags[ExhangeTags::MATERIALFORCE]);
479 CHKERR ave_node_force(tags[ExhangeTags::AREAGROWTH]);
480 CHKERR ave_node_griffith_energy(tags[ExhangeTags::GRIFFITHFORCE]);
481
483 };
484
485 CHKERR calculate_force_through_node();
486
487 // calculate face cross
488 for (auto e : *frontEdges) {
489 auto adj_faces = get_adj(e, 2);
490 auto crack_face = intersect(get_adj(e, 2), *crackFaces);
491
492 // #ifndef NDEBUG
493 if (debug) {
494 all_front_faces.merge(adj_faces);
495 }
496 // #endif
497
499 CHKERR mField.get_moab().tag_get_data(tags[ExhangeTags::MATERIALFORCE],
500 &e, 1, &t_edge_force(0));
501 FTensor::Tensor1<double, SPACE_DIM> t_edge_direction =
502 calculate_edge_direction(e);
503 t_edge_direction.normalize();
508 t_cross(K) = FTensor::levi_civita(I, J, K) * t_edge_direction(I) *
509 t_edge_force(J);
510
511 for (auto f : adj_faces) {
513 CHKERR mField.getInterface<Tools>()->getTriNormal(f, &t_normal(0));
514 t_normal.normalize();
515 int side_number, sense, offset;
516 CHKERR mField.get_moab().side_number(f, e, side_number, sense,
517 offset);
518 auto dot = -sense * t_cross(I) * t_normal(I);
519 CHK_MOAB_THROW(mField.get_moab().tag_set_data(
520 tags[ExhangeTags::GRIFFITHFORCE], &f, 1, &dot),
521 "set data");
522 }
523 }
524
525#ifndef NDEBUG
526 if (debug) {
527 int ts_step;
528 CHKERR TSGetStepNumber(ts, &ts_step);
530 "front_edges_material_force_" +
531 std::to_string(ts_step) + ".vtk",
532 *frontEdges);
534 "front_skin_faces_material_force_" +
535 std::to_string(ts_step) + ".vtk",
536 all_skin_faces);
538 "front_faces_material_force_" +
539 std::to_string(ts_step) + ".vtk",
540 all_front_faces);
541 }
542#endif
543 }
544
545 auto edge_exchange = CommInterface::createEntitiesPetscVector(
546 mField.get_comm(), mField.get_moab(), 1, 3, Sev::inform);
547 CHKERR CommInterface::updateEntitiesPetscVector(
548 mField.get_moab(), edge_exchange, tags[ExhangeTags::MATERIALFORCE]);
549 CHKERR CommInterface::updateEntitiesPetscVector(
550 mField.get_moab(), edge_exchange, tags[ExhangeTags::AREAGROWTH]);
551 CHKERR CommInterface::updateEntitiesPetscVector(
552 mField.get_moab(), edgeExchange, tags[ExhangeTags::GRIFFITHFORCE]);
553
555 };
556
557 auto print_results = [&](auto nb_J_integral_conturs) {
559
560 auto get_conn_range = [&](auto e) {
561 Range conn;
562 CHK_MOAB_THROW(mField.get_moab().get_connectivity(e, conn, true),
563 "get connectivity");
564 return conn;
565 };
566
567 auto get_tag_data = [&](auto &ents, auto tag, auto dim) {
568 std::vector<double> data(ents.size() * dim);
569 CHK_MOAB_THROW(mField.get_moab().tag_get_data(tag, ents, data.data()),
570 "get data");
571 return data;
572 };
573
574 if (mField.get_comm_rank() == 0) {
575 auto at_nodes = [&]() {
577 auto conn = get_conn_range(*frontEdges);
578 auto material_force =
579 get_tag_data(conn, tags[ExhangeTags::MATERIALFORCE], 3);
580 auto area_growth = get_tag_data(conn, tags[ExhangeTags::AREAGROWTH], 3);
581 auto griffith_force =
582 get_tag_data(conn, tags[ExhangeTags::GRIFFITHFORCE], 1);
583 std::vector<double> coords(conn.size() * 3);
584 CHK_MOAB_THROW(mField.get_moab().get_coords(conn, coords.data()),
585 "get coords");
586 if (conn.size())
587 MOFEM_LOG("EPSELF", Sev::inform) << "Material force at nodes";
588 for (size_t i = 0; i < conn.size(); ++i) {
589 MOFEM_LOG("EPSELF", Sev::inform)
590 << "Node " << conn[i] << " coords " << coords[i * 3 + 0] << " "
591 << coords[i * 3 + 1] << " " << coords[i * 3 + 2]
592 << " material force " << material_force[i * 3 + 0] << " "
593 << material_force[i * 3 + 1] << " " << material_force[i * 3 + 2]
594 << " area growth " << area_growth[i * 3 + 0] << " "
595 << area_growth[i * 3 + 1] << " " << area_growth[i * 3 + 2]
596 << " griffith force " << std::setprecision(12)
597 << griffith_force[i] << " contour " << nb_J_integral_conturs;
598 }
600 };
601
602 at_nodes();
603 }
605 };
606
607 CHKERR calculate_material_forces();
608
609 PetscBool all_contours = PETSC_FALSE;
610 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "",
611 "-calculate_J_integral_all_levels", &all_contours,
612 PETSC_NULLPTR); // for backward compatibility
614 PETSC_NULLPTR, "", "-calculate_J_integral_all_contours", &all_contours,
615 PETSC_NULLPTR); // new name
616
617 if (all_contours == PETSC_TRUE) {
618 for (int l = 0; l < nbJIntegralContours; ++l) {
619 CHKERR calculate_front_material_force(l);
620 CHKERR print_results(l);
621 }
622 }
623
624 CHKERR calculate_front_material_force(nbJIntegralContours);
625 CHKERR print_results(nbJIntegralContours);
626
628}
#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
UBlasMatrix< double > MatrixDouble
Definition Types.hpp:77
constexpr IntegrationType I
boost::shared_ptr< Range > frontAdjEdges
static int nbJIntegralContours
static double griffithEnergy
Griffith energy.
static enum MaterialModel materialModel
CommInterface::EntitiesPetscVector edgeExchange
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
boost::shared_ptr< Range > frontVertices
CommInterface::EntitiesPetscVector faceExchange
virtual int get_comm_size() const =0

◆ 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

Definition at line 630 of file EshelbianFracture.cpp.

631 {
633
634 constexpr bool debug = false;
635 constexpr auto sev = Sev::verbose;
636
637 Range body_ents;
638 CHKERR mField.get_moab().get_entities_by_dimension(0, 3, body_ents);
639 auto body_skin = get_skin(mField, body_ents);
640 Range body_skin_edges;
641 CHKERR mField.get_moab().get_adjacencies(body_skin, 1, false, body_skin_edges,
642 moab::Interface::UNION);
643 Range boundary_skin_verts;
644 CHKERR mField.get_moab().get_connectivity(body_skin_edges,
645 boundary_skin_verts, true);
646
647 auto geometry_edges = get_range_from_block(mField, "EDGES", 1);
648 Range geometry_edges_verts;
649 CHKERR mField.get_moab().get_connectivity(geometry_edges,
650 geometry_edges_verts, true);
651 Range crack_faces_verts;
652 CHKERR mField.get_moab().get_connectivity(*crackFaces, crack_faces_verts,
653 true);
654 Range crack_faces_edges;
655 CHKERR mField.get_moab().get_adjacencies(
656 *crackFaces, 1, true, crack_faces_edges, moab::Interface::UNION);
657 Range crack_faces_tets;
658 CHKERR mField.get_moab().get_adjacencies(
659 *crackFaces, 3, true, crack_faces_tets, moab::Interface::UNION);
660
661 Range front_verts;
662 CHKERR mField.get_moab().get_connectivity(*frontEdges, front_verts, true);
663 Range front_faces;
664 CHKERR mField.get_moab().get_adjacencies(*frontEdges, 2, true, front_faces,
665 moab::Interface::UNION);
666 Range front_verts_edges;
667 CHKERR mField.get_moab().get_adjacencies(
668 front_verts, 1, true, front_verts_edges, moab::Interface::UNION);
669
670 auto get_tags_vec = [&](auto tag_name, int dim) {
671 std::vector<Tag> tags(1);
672
673 if (dim > 3)
675
676 auto create_and_clean = [&]() {
678 auto &moab = mField.get_moab();
679 auto rval = moab.tag_get_handle(tag_name, tags[0]);
680 if (rval == MB_SUCCESS) {
681 moab.tag_delete(tags[0]);
682 }
683 double def_val[] = {0., 0., 0.};
684 CHKERR moab.tag_get_handle(tag_name, dim, MB_TYPE_DOUBLE, tags[0],
685 MB_TAG_CREAT | MB_TAG_SPARSE, def_val);
687 };
688
689 CHK_THROW_MESSAGE(create_and_clean(), "create_and_clean");
690
691 return tags;
692 };
693
694 auto get_adj_front = [&](bool subtract_crack) {
695 Range adj_front;
696 CHKERR mField.get_moab().get_adjacencies(*frontEdges, SPACE_DIM - 1, true,
697 adj_front, moab::Interface::UNION);
698 if (subtract_crack)
699 adj_front = subtract(adj_front, *crackFaces);
700 return adj_front;
701 };
702
703 MOFEM_LOG_CHANNEL("SELF");
704
705 auto th_front_position = get_tags_vec("FrontPosition", 3);
706 auto th_max_face_energy = get_tags_vec("MaxFaceEnergy", 1);
707
708 if (mField.get_comm_rank() == 0) {
709
710 auto get_crack_adj_tets = [&](auto r) {
711 Range crack_faces_conn;
712 CHKERR mField.get_moab().get_connectivity(r, crack_faces_conn);
713 Range crack_faces_conn_tets;
714 CHKERR mField.get_moab().get_adjacencies(crack_faces_conn, SPACE_DIM,
715 true, crack_faces_conn_tets,
716 moab::Interface::UNION);
717 return crack_faces_conn_tets;
718 };
719
720 auto get_layers_for_sides = [&](auto &side) {
721 std::vector<Range> layers;
722 auto get = [&]() {
724
725 auto get_adj = [&](auto &r, int dim) {
726 Range adj;
727 CHKERR mField.get_moab().get_adjacencies(r, dim, true, adj,
728 moab::Interface::UNION);
729 return adj;
730 };
731
732 auto get_tets = [&](auto r) { return get_adj(r, SPACE_DIM); };
733
734 Range front_nodes;
735 CHKERR mField.get_moab().get_connectivity(*frontEdges, front_nodes,
736 true);
737 Range front_faces = get_adj(front_nodes, 2);
738 front_faces = subtract(front_faces, *crackFaces);
739 auto front_tets = get_tets(front_nodes);
740 auto front_side = intersect(side, front_tets);
741 layers.push_back(front_side);
742 for (;;) {
743 auto adj_faces = get_skin(mField, layers.back());
744 adj_faces = intersect(adj_faces, front_faces);
745 auto adj_faces_tets = get_tets(adj_faces);
746 adj_faces_tets = intersect(adj_faces_tets, front_tets);
747 layers.push_back(unite(layers.back(), adj_faces_tets));
748 if (layers.back().size() == layers[layers.size() - 2].size()) {
749 break;
750 }
751 }
753 };
754 CHK_THROW_MESSAGE(get(), "get_layers_for_sides");
755 return layers;
756 };
757
759 auto layers_top = get_layers_for_sides(sides_pair.first);
760 auto layers_bottom = get_layers_for_sides(sides_pair.second);
761
762#ifndef NDEBUG
763 if (debug) {
766 "crack_tets_" +
767 boost::lexical_cast<std::string>(mField.get_comm_rank()) + ".vtk",
768 get_crack_adj_tets(*crackFaces));
769 CHKERR save_range(mField.get_moab(), "sides_first.vtk", sides_pair.first);
770 CHKERR save_range(mField.get_moab(), "sides_second.vtk",
771 sides_pair.second);
772 MOFEM_LOG("EP", sev) << "Nb. layers " << layers_top.size();
773 int l = 0;
774 for (auto &r : layers_top) {
775 MOFEM_LOG("EP", sev) << "Layer " << l << " size " << r.size();
778 "layers_top_" + boost::lexical_cast<std::string>(l) + ".vtk", r);
779 ++l;
780 }
781
782 l = 0;
783 for (auto &r : layers_bottom) {
784 MOFEM_LOG("EP", sev) << "Layer " << l << " size " << r.size();
787 "layers_bottom_" + boost::lexical_cast<std::string>(l) + ".vtk", r);
788 ++l;
789 }
790 }
791#endif
792
793 auto get_cross = [&](auto t_dir, auto f) {
795 CHKERR mField.getInterface<Tools>()->getTriNormal(f, &t_normal(0));
796 t_normal.normalize();
801 t_cross(i) = FTensor::levi_civita(i, j, k) * t_normal(j) * t_dir(k);
802 return t_cross;
803 };
804
805 auto get_sense = [&](auto f, auto e) {
806 int side, sense, offset;
807 CHK_MOAB_THROW(mField.get_moab().side_number(f, e, side, sense, offset),
808 "get sense");
809 return std::make_tuple(side, sense, offset);
810 };
811
812 auto calculate_edge_direction = [&](auto e, auto normalize = true) {
813 const EntityHandle *conn;
814 int num_nodes;
815 CHKERR mField.get_moab().get_connectivity(e, conn, num_nodes, true);
816 std::array<double, 6> coords;
817 CHKERR mField.get_moab().get_coords(conn, num_nodes, coords.data());
819 &coords[0], &coords[1], &coords[2]};
821 &coords[3], &coords[4], &coords[5]};
824 t_dir(i) = t_p1(i) - t_p0(i);
825 if (normalize)
826 t_dir.normalize();
827 return t_dir;
828 };
829
830 auto evaluate_face_energy_and_set_orientation = [&](auto front_edges,
831 auto front_faces,
832 auto &sides_pair,
833 auto th_position) {
835
836 Tag th_face_energy;
837 Tag th_material_force;
838 switch (energyReleaseSelector) {
839 case GRIFFITH_FORCE:
841 CHKERR mField.get_moab().tag_get_handle("GriffithForce",
842 th_face_energy);
843 CHKERR mField.get_moab().tag_get_handle("MaterialForce",
844 th_material_force);
845 break;
846 default:
847 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
848 "Unknown energy release selector");
849 };
850
851 /**
852 * Iterate over front edges, get adjacent faces, find maximal face energy.
853 * Maximal face energy is stored in the edge. Maximal face energy is
854 * magnitude of edge Griffith force.
855 */
856 auto find_maximal_face_energy = [&](auto front_edges, auto front_faces,
857 auto &edge_face_max_energy_map) {
859
860 Range body_ents;
861 CHKERR mField.get_moab().get_entities_by_dimension(0, 3, body_ents);
862 auto body_skin = get_skin(mField, body_ents);
863
864 Range max_faces;
865
866 for (auto e : front_edges) {
867
868 double griffith_force;
869 CHKERR mField.get_moab().tag_get_data(th_face_energy, &e, 1,
870 &griffith_force);
871
872 Range faces;
873 CHKERR mField.get_moab().get_adjacencies(&e, 1, 2, false, faces);
874 faces = subtract(intersect(faces, front_faces), body_skin);
875 std::vector<double> face_energy(faces.size());
876 CHKERR mField.get_moab().tag_get_data(th_face_energy, faces,
877 face_energy.data());
878 auto max_energy_it =
879 std::max_element(face_energy.begin(), face_energy.end());
880 double max_energy =
881 max_energy_it != face_energy.end() ? *max_energy_it : 0;
882
883 edge_face_max_energy_map[e] =
884 std::make_tuple(faces[max_energy_it - face_energy.begin()],
885 griffith_force, static_cast<double>(0));
886 MOFEM_LOG("EP", Sev::inform)
887 << "Edge " << e << " griffith force " << griffith_force
888 << " max face energy " << max_energy << " factor "
889 << max_energy / griffith_force;
890
891 max_faces.insert(faces[max_energy_it - face_energy.begin()]);
892 }
893
894#ifndef NDEBUG
895 if (debug) {
898 "max_faces_" +
899 boost::lexical_cast<std::string>(mField.get_comm_rank()) +
900 ".vtk",
901 max_faces);
902 }
903#endif
904
906 };
907
908 /**
909 * For each front edge, find maximal face energy and orientation. This is
910 * by finding angle between edge material force and maximal face normal
911 *
912 */
913 auto calculate_face_orientation = [&](auto &edge_face_max_energy_map) {
915
916 auto up_down_face = [&](
917
918 auto &face_angle_map_up,
919 auto &face_angle_map_down
920
921 ) {
923
924 for (auto &m : edge_face_max_energy_map) {
925 auto e = m.first;
926 auto [max_face, energy, opt_angle] = m.second;
927
928 Range faces;
929 CHKERR mField.get_moab().get_adjacencies(&e, 1, 2, false, faces);
930 faces = intersect(faces, front_faces);
931 Range adj_tets; // tetrahedrons adjacent to the face
932 CHKERR mField.get_moab().get_adjacencies(&max_face, 1, SPACE_DIM,
933 false, adj_tets,
934 moab::Interface::UNION);
935 if (adj_tets.size()) {
936
937 Range adj_tets; // tetrahedrons adjacent to the face
938 CHKERR mField.get_moab().get_adjacencies(&max_face, 1, SPACE_DIM,
939 false, adj_tets,
940 moab::Interface::UNION);
941 if (adj_tets.size()) {
942
943 Range adj_tets_faces;
944 // get faces
945 CHKERR mField.get_moab().get_adjacencies(
946 adj_tets, SPACE_DIM - 1, false, adj_tets_faces,
947 moab::Interface::UNION);
948 adj_tets_faces = intersect(adj_tets_faces, faces);
950
951 // cross product of face normal and edge direction
952 auto t_cross_max =
953 get_cross(calculate_edge_direction(e, true), max_face);
954 auto [side_max, sense_max, offset_max] = get_sense(max_face, e);
955 t_cross_max(i) *= sense_max;
956
957 for (auto t : adj_tets) {
958 Range adj_tets_faces;
959 CHKERR mField.get_moab().get_adjacencies(
960 &t, 1, SPACE_DIM - 1, false, adj_tets_faces);
961 adj_tets_faces = intersect(adj_tets_faces, faces);
962 adj_tets_faces =
963 subtract(adj_tets_faces, Range(max_face, max_face));
964
965 if (adj_tets_faces.size() == 1) {
966
967 // cross product of adjacent face normal and edge
968 // direction
969 auto t_cross = get_cross(calculate_edge_direction(e, true),
970 adj_tets_faces[0]);
971 auto [side, sense, offset] =
972 get_sense(adj_tets_faces[0], e);
973 t_cross(i) *= sense;
974 double dot = t_cross(i) * t_cross_max(i);
975 auto angle = std::acos(dot);
976
977 double face_energy;
978 CHKERR mField.get_moab().tag_get_data(
979 th_face_energy, adj_tets_faces, &face_energy);
980
981 auto [side_face, sense_face, offset_face] =
982 get_sense(t, max_face);
983
984 if (sense_face > 0) {
985 face_angle_map_up[e] = std::make_tuple(face_energy, angle,
986 adj_tets_faces[0]);
987
988 } else {
989 face_angle_map_down[e] = std::make_tuple(
990 face_energy, -angle, adj_tets_faces[0]);
991 }
992 }
993 }
994 }
995 }
996 }
997
999 };
1000
1001 auto calc_optimal_angle = [&](
1002
1003 auto &face_angle_map_up,
1004 auto &face_angle_map_down
1005
1006 ) {
1008
1009 for (auto &m : edge_face_max_energy_map) {
1010 auto e = m.first;
1011 auto &[max_face, e0, a0] = m.second;
1012
1013 if (std::abs(e0) > std::numeric_limits<double>::epsilon()) {
1014
1015 if (face_angle_map_up.find(e) == face_angle_map_up.end() ||
1016 face_angle_map_down.find(e) == face_angle_map_down.end()) {
1017 // Do nothing
1018 } else {
1019
1020 switch (energyReleaseSelector) {
1021 case GRIFFITH_FORCE:
1022 case GRIFFITH_SKELETON: {
1023
1024 Tag th_material_force;
1025 CHKERR mField.get_moab().tag_get_handle("MaterialForce",
1026 th_material_force);
1027 FTensor::Tensor1<double, SPACE_DIM> t_material_force;
1028 CHKERR mField.get_moab().tag_get_data(
1029 th_material_force, &e, 1, &t_material_force(0));
1030 auto material_force_magnitude = t_material_force.l2();
1031 if (material_force_magnitude <
1032 std::numeric_limits<double>::epsilon()) {
1033 a0 = 0;
1034
1035 } else {
1036
1037 auto t_edge_dir = calculate_edge_direction(e, true);
1038 auto t_cross_max = get_cross(t_edge_dir, max_face);
1039 auto [side, sense, offset] = get_sense(max_face, e);
1040 t_cross_max(sense) *= sense;
1041
1045
1046 t_material_force.normalize();
1047 t_cross_max.normalize();
1049 t_cross(I) = FTensor::levi_civita(I, J, K) *
1050 t_material_force(J) * t_cross_max(K);
1051 a0 = -std::asin(t_cross(I) * t_edge_dir(I));
1052
1053 MOFEM_LOG("EP", sev)
1054 << "Optimal angle " << a0 << " energy " << e0;
1055 }
1056 break;
1057 }
1058 default: {
1059
1060 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
1061 "Unknown energy release selector");
1062 }
1063 }
1064 }
1065 }
1066 }
1067
1069 };
1070
1071 std::map<EntityHandle, std::tuple<double, double, EntityHandle>>
1072 face_angle_map_up;
1073 std::map<EntityHandle, std::tuple<double, double, EntityHandle>>
1074 face_angle_map_down;
1075 CHKERR up_down_face(face_angle_map_up, face_angle_map_down);
1076 CHKERR calc_optimal_angle(face_angle_map_up, face_angle_map_down);
1077
1078#ifndef NDEBUG
1079 if (debug) {
1080 auto th_angle = get_tags_vec("Angle", 1);
1081 Range up;
1082 for (auto &m : face_angle_map_up) {
1083 auto [e, a, face] = m.second;
1084 up.insert(face);
1085 CHKERR mField.get_moab().tag_set_data(th_angle[0], &face, 1, &a);
1086 }
1087 Range down;
1088 for (auto &m : face_angle_map_down) {
1089 auto [e, a, face] = m.second;
1090 down.insert(face);
1091 CHKERR mField.get_moab().tag_set_data(th_angle[0], &face, 1, &a);
1092 }
1093
1094 Range max_energy_faces;
1095 for (auto &m : edge_face_max_energy_map) {
1096 auto [face, e, angle] = m.second;
1097 max_energy_faces.insert(face);
1098 CHKERR mField.get_moab().tag_set_data(th_angle[0], &face, 1,
1099 &angle);
1100 }
1101 if (mField.get_comm_rank() == 0) {
1102 CHKERR save_range(mField.get_moab(), "up_faces.vtk", up);
1103 CHKERR save_range(mField.get_moab(), "down_faces.vtk", down);
1104 CHKERR save_range(mField.get_moab(), "max_energy_faces.vtk",
1105 max_energy_faces);
1106 }
1107 }
1108#endif // NDEBUG
1109
1111 };
1112
1113 auto get_conn = [&](auto e) {
1114 Range conn;
1115 CHK_MOAB_THROW(mField.get_moab().get_connectivity(e, conn, true),
1116 "get conn");
1117 return conn;
1118 };
1119
1120 auto get_adj = [&](auto e, auto dim) {
1121 Range adj;
1122 CHK_MOAB_THROW(mField.get_moab().get_adjacencies(
1123 e, dim, false, adj, moab::Interface::UNION),
1124 "get adj");
1125 return adj;
1126 };
1127
1128 auto get_coords = [&](auto v) {
1130 CHK_MOAB_THROW(mField.get_moab().get_coords(v, &t_coords(0)),
1131 "get coords");
1132 return t_coords;
1133 };
1134
1135 // calulate normal of the max energy face
1136 auto get_rotated_normal = [&](auto e, auto f, auto angle) {
1139 auto t_edge_dir = calculate_edge_direction(e, true);
1140 auto [side, sense, offset] = get_sense(f, e);
1141 t_edge_dir(i) *= sense;
1142 t_edge_dir.normalize();
1143 t_edge_dir(i) *= angle;
1144 auto t_R = LieGroups::SO3::exp(t_edge_dir, angle);
1146 mField.getInterface<Tools>()->getTriNormal(f, &t_normal(0));
1147 FTensor::Tensor1<double, SPACE_DIM> t_rotated_normal;
1148 t_rotated_normal(i) = t_R(i, j) * t_normal(j);
1149 return std::make_tuple(t_normal, t_rotated_normal);
1150 };
1151
1152 auto set_coord = [&](auto v, auto &adj_vertex_tets_verts, auto &coords,
1153 auto &t_move, auto gamma) {
1154 auto index = adj_vertex_tets_verts.index(v);
1155 if (index >= 0) {
1156 for (auto ii : {0, 1, 2}) {
1157 coords[3 * index + ii] += gamma * t_move(ii);
1158 }
1159 return true;
1160 }
1161 return false;
1162 };
1163
1164 auto tets_quality = [&](auto quality, auto &adj_vertex_tets_verts,
1165 auto &adj_vertex_tets, auto &coords) {
1166 for (auto t : adj_vertex_tets) {
1167 const EntityHandle *conn;
1168 int num_nodes;
1169 CHKERR mField.get_moab().get_connectivity(t, conn, num_nodes, true);
1170 std::array<double, 12> tet_coords;
1171 for (auto n = 0; n != 4; ++n) {
1172 auto index = adj_vertex_tets_verts.index(conn[n]);
1173 if (index < 0) {
1175 }
1176 for (auto ii = 0; ii != 3; ++ii) {
1177 tet_coords[3 * n + ii] = coords[3 * index + ii];
1178 }
1179 }
1180 double q = Tools::volumeLengthQuality(tet_coords.data());
1181 if (!std::isnormal(q))
1182 q = -2;
1183 quality = std::min(quality, q);
1184 };
1185
1186 return quality;
1187 };
1188
1189 auto calculate_free_face_node_displacement =
1190 [&](auto &edge_face_max_energy_map) {
1191 // get edges adjacent to vertex along which nodes are moving
1192 auto get_vertex_edges = [&](auto vertex) {
1193 Range vertex_edges; // edges adjacent to vertex
1194
1195 auto impl = [&]() {
1197 CHKERR mField.get_moab().get_adjacencies(vertex, 1, false,
1198 vertex_edges);
1199 vertex_edges = subtract(vertex_edges, front_verts_edges);
1200
1201 if (boundary_skin_verts.size() &&
1202 boundary_skin_verts.find(vertex[0]) !=
1203 boundary_skin_verts.end()) {
1204 MOFEM_LOG("EP", sev) << "Boundary vertex";
1205 vertex_edges = intersect(vertex_edges, body_skin_edges);
1206 }
1207 if (geometry_edges_verts.size() &&
1208 geometry_edges_verts.find(vertex[0]) !=
1209 geometry_edges_verts.end()) {
1210 MOFEM_LOG("EP", sev) << "Geometry edge vertex";
1211 vertex_edges = intersect(vertex_edges, geometry_edges);
1212 }
1213 if (crack_faces_verts.size() &&
1214 crack_faces_verts.find(vertex[0]) !=
1215 crack_faces_verts.end()) {
1216 MOFEM_LOG("EP", sev) << "Crack face vertex";
1217 vertex_edges = intersect(vertex_edges, crack_faces_edges);
1218 }
1220 };
1221
1222 CHK_THROW_MESSAGE(impl(), "get_vertex_edges");
1223
1224 return vertex_edges;
1225 };
1226
1227 // vector of rotated faces, edge along node is moved, moved edge,
1228 // moved displacement, quality, cardinality, gamma
1229 using Bundle = std::vector<
1230
1233
1234 >;
1235 std::map<EntityHandle, Bundle> edge_bundle_map;
1236
1237 for (auto &m : edge_face_max_energy_map) {
1238
1239 auto edge = m.first;
1240 auto &[max_face, energy, opt_angle] = m.second;
1241
1242 // calculate rotation of max energy face
1243 auto [t_normal, t_rotated_normal] =
1244 get_rotated_normal(edge, max_face, opt_angle);
1245
1246 auto front_vertex = get_conn(Range(m.first, m.first));
1247 auto adj_tets = get_adj(Range(max_face, max_face), 3);
1248 auto adj_tets_faces = get_adj(adj_tets, 2);
1249 auto adj_front_faces = subtract(
1250 intersect(get_adj(Range(edge, edge), 2), adj_tets_faces),
1251 *crackFaces);
1252 if (adj_front_faces.size() > 3)
1254 "adj_front_faces.size()>3");
1255
1256 FTensor::Tensor1<double, SPACE_DIM> t_material_force;
1257 CHKERR mField.get_moab().tag_get_data(th_material_force, &edge, 1,
1258 &t_material_force(0));
1259 std::vector<double> griffith_energy(adj_front_faces.size());
1260 CHKERR mField.get_moab().tag_get_data(
1261 th_face_energy, adj_front_faces, griffith_energy.data());
1262
1263 auto set_edge_bundle = [&](auto min_gamma) {
1264 for (auto rotated_f : adj_front_faces) {
1265
1266 double rotated_face_energy =
1267 griffith_energy[adj_front_faces.index(rotated_f)];
1268
1269 auto vertex = subtract(get_conn(Range(rotated_f, rotated_f)),
1270 front_vertex);
1271 if (vertex.size() != 1) {
1273 "Wrong number of vertex to move");
1274 }
1275 auto front_vertex_edges_vertex = get_conn(
1276 intersect(get_adj(front_vertex, 1), crack_faces_edges));
1277 vertex = subtract(
1278 vertex, front_vertex_edges_vertex); // vertex free to move
1279 if (vertex.empty()) {
1280 continue;
1281 }
1282
1283 auto face_cardinality = [&](auto f, auto &seen_front_edges) {
1284 auto whole_front =
1285 unite(*frontEdges,
1286 subtract(body_skin_edges, crack_faces_edges));
1287 auto faces = Range(f, f);
1288 int c = 0;
1289 for (; c < 10; ++c) {
1290 auto front_edges =
1291 subtract(get_adj(faces, 1), seen_front_edges);
1292 if (front_edges.size() == 0) {
1293 return 0;
1294 }
1295 auto front_connected_edges =
1296 intersect(front_edges, whole_front);
1297 if (front_connected_edges.size()) {
1298 seen_front_edges.merge(front_connected_edges);
1299 return c;
1300 }
1301 faces.merge(get_adj(front_edges, 2));
1302 ++c;
1303 }
1304 return c;
1305 };
1306
1307 Range seen_edges = Range(edge, edge);
1308 double rotated_face_cardinality = face_cardinality(
1309 rotated_f,
1310 seen_edges); // add cardinality of max energy
1311 // face to rotated face cardinality
1312 // rotated_face_cardinality +=
1313 // face_cardinality(max_face, seen_edges);
1314 rotated_face_cardinality = std::max(rotated_face_cardinality,
1315 1.); // at least one edge
1316
1317 auto t_vertex_coords = get_coords(vertex);
1318 auto vertex_edges = get_vertex_edges(vertex);
1319
1320 EntityHandle f0 = front_vertex[0];
1321 EntityHandle f1 = front_vertex[1];
1322 FTensor::Tensor1<double, 3> t_v_e0, t_v_e1;
1323 CHKERR mField.get_moab().get_coords(&f0, 1, &t_v_e0(0));
1324 CHKERR mField.get_moab().get_coords(&f1, 1, &t_v_e1(0));
1325
1327 for (auto e_used_to_move_detection : vertex_edges) {
1328 auto edge_conn = get_conn(Range(e_used_to_move_detection,
1329 e_used_to_move_detection));
1330 edge_conn = subtract(edge_conn, vertex);
1331 // Find displacement of the edge such that dot porduct with
1332 // normal is zero.
1333 //
1334 // { (t_v0 - t_vertex_coords) + gamma * (t_v3 -
1335 // t_vertex_coords) } * n = 0
1336 // where t_v0 is the edge vertex, t_v3 is the edge end
1337 // point, n is the rotated normal of the face gamma is the
1338 // factor by which the edge is moved
1340 t_v0(i) = (t_v_e0(i) + t_v_e1(i)) / 2;
1342 CHKERR mField.get_moab().get_coords(edge_conn, &t_v3(0));
1343 auto a =
1344 (t_v0(i) - t_vertex_coords(i)) * t_rotated_normal(i);
1345 auto b =
1346 (t_v3(i) - t_vertex_coords(i)) * t_rotated_normal(i);
1347 auto gamma = a / b;
1348
1349 constexpr double eps =
1350 std::numeric_limits<double>::epsilon();
1351 if (std::isnormal(gamma) && gamma < 1.0 - eps &&
1352 gamma > -0.1) {
1354 t_move(i) = gamma * (t_v3(i) - t_vertex_coords(i));
1355
1356 auto check_rotated_face_directoon = [&]() {
1358 t_delta(i) = t_vertex_coords(i) + t_move(i) - t_v0(i);
1359 t_delta.normalize();
1360 auto dot =
1361 (t_material_force(i) / t_material_force.l2()) *
1362 t_delta(i);
1363 return -dot > 0 ? true : false;
1364 };
1365
1366 if (check_rotated_face_directoon()) {
1367
1368 MOFEM_LOG("EP", Sev::inform)
1369 << "Crack edge " << edge << " moved face "
1370 << rotated_f
1371 << " edge: " << e_used_to_move_detection
1372 << " face direction/energy " << rotated_face_energy
1373 << " face cardinality " << rotated_face_cardinality
1374 << " gamma: " << gamma;
1375
1376 auto &bundle = edge_bundle_map[edge];
1377 bundle.emplace_back(rotated_f, e_used_to_move_detection,
1378 vertex[0], t_move, 1,
1379 rotated_face_cardinality, gamma);
1380 }
1381 }
1382 }
1383 }
1384 };
1385
1386 set_edge_bundle(std::numeric_limits<double>::epsilon());
1387 if (edge_bundle_map[edge].empty()) {
1388 set_edge_bundle(-1.);
1389 }
1390 }
1391
1392 return edge_bundle_map;
1393 };
1394
1395 auto get_sort_by_energy = [&](auto &edge_face_max_energy_map) {
1396 std::map<double, std::tuple<EntityHandle, EntityHandle, double>>
1397 sort_by_energy;
1398
1399 for (auto &m : edge_face_max_energy_map) {
1400 auto e = m.first;
1401 auto &[max_face, energy, opt_angle] = m.second;
1402 sort_by_energy[energy] = std::make_tuple(e, max_face, opt_angle);
1403 }
1404
1405 return sort_by_energy;
1406 };
1407
1408 auto set_tag = [&](auto &&adj_edges_map, auto &&sort_by_energy) {
1410
1411 Tag th_face_pressure;
1413 mField.get_moab().tag_get_handle("FacePressure", th_face_pressure),
1414 "get tag");
1415 auto get_face_pressure = [&](auto face) {
1416 double pressure;
1417 CHK_MOAB_THROW(mField.get_moab().tag_get_data(th_face_pressure, &face,
1418 1, &pressure),
1419 "get rag data");
1420 return pressure;
1421 };
1422
1423 MOFEM_LOG("EPSELF", Sev::inform)
1424 << "Number of edges to check " << sort_by_energy.size();
1425
1426 enum face_energy { POSITIVE, NEGATIVE };
1427 constexpr bool skip_negative = true;
1428
1429 for (auto fe : {face_energy::POSITIVE, face_energy::NEGATIVE}) {
1430
1431 // iterate edges wih maximal energy, and make them seed. Such edges,
1432 // will most likely will have also smallest node displacement
1433 for (auto it = sort_by_energy.rbegin(); it != sort_by_energy.rend();
1434 ++it) {
1435
1436 auto energy = it->first;
1437 auto [max_edge, max_face, opt_angle] = it->second;
1438
1439 auto face_pressure = get_face_pressure(max_face);
1440 if (skip_negative) {
1441 if (fe == face_energy::POSITIVE) {
1442 if (face_pressure < 0) {
1443 MOFEM_LOG("EPSELF", Sev::inform)
1444 << "Skip negative face " << max_face << " with energy "
1445 << energy << " and pressure " << face_pressure;
1446 continue;
1447 }
1448 }
1449 }
1450
1451 MOFEM_LOG("EPSELF", Sev::inform)
1452 << "Check face " << max_face << " edge " << max_edge
1453 << " energy " << energy << " optimal angle " << opt_angle
1454 << " face pressure " << face_pressure;
1455
1456 auto jt = adj_edges_map.find(max_edge);
1457 if (jt == adj_edges_map.end()) {
1458 MOFEM_LOG("EPSELF", Sev::warning)
1459 << "Edge " << max_edge << " not found in adj_edges_map";
1460 continue;
1461 }
1462 auto &bundle = jt->second;
1463
1464 auto find_max_in_bundle_impl = [&](auto edge, auto &bundle,
1465 auto gamma) {
1467
1468 EntityHandle vertex_max = 0;
1469 EntityHandle face_max = 0;
1470 EntityHandle move_edge_max = 0;
1471 double max_quality = -2;
1472 double max_quality_evaluated = -2;
1473 double min_cardinality = std::numeric_limits<double>::max();
1474
1475 FTensor::Tensor1<double, SPACE_DIM> t_move_last{0., 0., 0.};
1476
1477 for (auto &b : bundle) {
1478 auto &[face, move_edge, vertex, t_move, quality, cardinality,
1479 edge_gamma] = b;
1480
1481 auto adj_vertex_tets = get_adj(Range(vertex, vertex), 3);
1482 auto adj_vertex_tets_verts = get_conn(adj_vertex_tets);
1483 std::vector<double> coords(3 * adj_vertex_tets_verts.size());
1484 CHK_MOAB_THROW(mField.get_moab().get_coords(
1485 adj_vertex_tets_verts, coords.data()),
1486 "get coords");
1487
1488 set_coord(vertex, adj_vertex_tets_verts, coords, t_move, gamma);
1489 quality = tets_quality(quality, adj_vertex_tets_verts,
1490 adj_vertex_tets, coords);
1491
1492 auto eval_quality = [](auto q, auto c, auto edge_gamma) {
1493 if (q < 0) {
1494 return q;
1495 } else {
1496 return ((edge_gamma < 0) ? (q / 2) : q) / pow(c, 2);
1497 }
1498 };
1499
1500 if (eval_quality(quality, cardinality, edge_gamma) >=
1501 max_quality_evaluated) {
1502 max_quality = quality;
1503 min_cardinality = cardinality;
1504 vertex_max = vertex;
1505 face_max = face;
1506 move_edge_max = move_edge;
1507 t_move_last(i) = t_move(i);
1508 max_quality_evaluated =
1509 eval_quality(max_quality, min_cardinality, edge_gamma);
1510 }
1511 }
1512
1513 return std::make_tuple(vertex_max, face_max, t_move_last,
1514 max_quality, min_cardinality);
1515 };
1516
1517 auto find_max_in_bundle = [&](auto edge, auto &bundle) {
1518 auto b_org_bundle = bundle;
1519 auto r = find_max_in_bundle_impl(edge, bundle, 1.);
1520 auto &[vertex_max, face_max, t_move_last, max_quality,
1521 cardinality] = r;
1522 if (max_quality < 0) {
1523 for (double gamma = 0.95; gamma >= 0.45; gamma -= 0.05) {
1524 bundle = b_org_bundle;
1525 r = find_max_in_bundle_impl(edge, bundle, gamma);
1526 auto &[vertex_max, face_max, t_move_last, max_quality,
1527 cardinality] = r;
1528 MOFEM_LOG("EPSELF", Sev::warning)
1529 << "Back tracking: gamma " << gamma << " edge " << edge
1530 << " quality " << max_quality << " cardinality "
1531 << cardinality;
1532 if (max_quality > 0.01) {
1534 t_move_last(I) *= gamma;
1535 return r;
1536 }
1537 }
1539 t_move_last(I) = 0;
1540 }
1541 return r;
1542 };
1543
1544 // set tags with displacement of node and face energy
1545 auto set_tag_to_vertex_and_face = [&](auto &&r, auto &quality) {
1547 auto &[v, f, t_move, q, cardinality] = r;
1548
1549 if ((q > 0 && std::isnormal(q)) && energy > 0) {
1550
1551 MOFEM_LOG("EPSELF", Sev::inform)
1552 << "Set tag: vertex " << v << " face " << f << " "
1553 << max_edge << " move " << t_move << " energy " << energy
1554 << " quality " << q << " cardinality " << cardinality;
1555 CHKERR mField.get_moab().tag_set_data(th_position[0], &v, 1,
1556 &t_move(0));
1557 CHKERR mField.get_moab().tag_set_data(th_max_face_energy[0], &f,
1558 1, &energy);
1559 }
1560
1561 quality = q;
1563 };
1564
1565 double quality = -2;
1566 CHKERR set_tag_to_vertex_and_face(
1567
1568 find_max_in_bundle(max_edge, bundle),
1569
1570 quality
1571
1572 );
1573
1574 if (quality > 0 && std::isnormal(quality) && energy > 0) {
1575 MOFEM_LOG("EPSELF", Sev::inform)
1576 << "Crack face set with quality: " << quality;
1578 }
1579 }
1580
1581 if (!skip_negative)
1582 break;
1583 }
1584
1586 };
1587
1588 // map: {edge, {face, energy, optimal_angle}}
1589 MOFEM_LOG("EP", sev) << "Calculate orientation";
1590 std::map<EntityHandle, std::tuple<EntityHandle, double, double>>
1591 edge_face_max_energy_map;
1592 CHKERR find_maximal_face_energy(front_edges, front_faces,
1593 edge_face_max_energy_map);
1594 CHKERR calculate_face_orientation(edge_face_max_energy_map);
1595
1596 MOFEM_LOG("EP", sev) << "Calculate node positions";
1597 CHKERR set_tag(
1598
1599 calculate_free_face_node_displacement(edge_face_max_energy_map),
1600 get_sort_by_energy(edge_face_max_energy_map)
1601
1602 );
1603
1605 };
1606
1607 MOFEM_LOG("EP", sev) << "Front edges " << frontEdges->size();
1608 CHKERR evaluate_face_energy_and_set_orientation(
1609 *frontEdges, get_adj_front(false), sides_pair, th_front_position);
1610 }
1611
1612 // exchange positions and energies from processor zero to all other
1613 CHKERR VecZeroEntries(vertexExchange.second);
1614 CHKERR VecGhostUpdateBegin(vertexExchange.second, INSERT_VALUES,
1615 SCATTER_FORWARD);
1616 CHKERR VecGhostUpdateEnd(vertexExchange.second, INSERT_VALUES,
1617 SCATTER_FORWARD);
1618 CHKERR mField.getInterface<CommInterface>()->updateEntitiesPetscVector(
1619 mField.get_moab(), vertexExchange, th_front_position[0]);
1620 CHKERR VecZeroEntries(faceExchange.second);
1621 CHKERR VecGhostUpdateBegin(faceExchange.second, INSERT_VALUES,
1622 SCATTER_FORWARD);
1623 CHKERR VecGhostUpdateEnd(faceExchange.second, INSERT_VALUES, SCATTER_FORWARD);
1624 CHKERR mField.getInterface<CommInterface>()->updateEntitiesPetscVector(
1625 mField.get_moab(), faceExchange, th_max_face_energy[0]);
1626
1627 auto get_max_moved_faces = [&]() {
1628 Range max_moved_faces;
1629 auto adj_front = get_adj_front(false);
1630 std::vector<double> face_energy(adj_front.size());
1631 CHKERR mField.get_moab().tag_get_data(th_max_face_energy[0], adj_front,
1632 face_energy.data());
1633 for (int i = 0; i != adj_front.size(); ++i) {
1634 if (face_energy[i] > std::numeric_limits<double>::epsilon()) {
1635 max_moved_faces.insert(adj_front[i]);
1636 }
1637 }
1638
1639 return boost::make_shared<Range>(max_moved_faces);
1640 };
1641
1642 // move all faces with energy larger than 0
1643 maxMovedFaces = get_max_moved_faces();
1644 MOFEM_LOG("EP", sev) << "Number of of moved faces: " << maxMovedFaces->size();
1645
1646#ifndef NDEBUG
1647 if (debug) {
1649 mField.get_moab(),
1650 "max_moved_faces_" +
1651 boost::lexical_cast<std::string>(mField.get_comm_rank()) + ".vtk",
1652 *maxMovedFaces);
1653 }
1654#endif
1655
1657}
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

◆ createCrackSurfaceMeshset()

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

Definition at line 2451 of file EshelbianFracture.cpp.

2451 {
2453 auto meshset_mng = mField.getInterface<MeshsetsManager>();
2454 while (meshset_mng->checkMeshset(addCrackMeshsetId, BLOCKSET))
2456 MOFEM_LOG("EP", Sev::inform)
2457 << "Crack added surface meshset " << addCrackMeshsetId;
2458 CHKERR meshset_mng->addMeshset(BLOCKSET, addCrackMeshsetId, "CRACK_COMPUTED");
2460};

◆ createExchangeVectors()

MoFEMErrorCode EshelbianCore::createExchangeVectors ( Sev  sev)
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp, ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

Definition at line 4990 of file EshelbianPlasticity.cpp.

4990 {
4992
4993 auto print_loc_size = [this](auto v, auto str, auto sev) {
4995 int size;
4996 CHKERR VecGetLocalSize(v.second, &size);
4997 int low, high;
4998 CHKERR VecGetOwnershipRange(v.second, &low, &high);
4999 MOFEM_LOG("EPSYNC", sev) << str << " local size " << size << " ( " << low
5000 << " " << high << " ) ";
5003 };
5004
5006 mField.get_comm(), mField.get_moab(), 3, 1, sev);
5007 CHKERR print_loc_size(volumeExchange, "volumeExchange", sev);
5009 mField.get_comm(), mField.get_moab(), 2, 1, Sev::inform);
5010 CHKERR print_loc_size(faceExchange, "faceExchange", sev);
5012 mField.get_comm(), mField.get_moab(), 1, 1, Sev::inform);
5013 CHKERR print_loc_size(edgeExchange, "edgeExchange", sev);
5015 mField.get_comm(), mField.get_moab(), 0, 3, Sev::inform);
5016 CHKERR print_loc_size(vertexExchange, "vertexExchange", sev);
5017
5019}
CommInterface::EntitiesPetscVector volumeExchange
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.

◆ 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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 109 of file EshelbianCore.hpp.

109 {
110 if constexpr (use_quadratic_exp) {
111 return d_f_log_e_quadratic(v);
112 } else {
113 if (v > v_max)
114 return std::exp(v_max);
115 else
116 return std::exp(v);
117 }
118 }
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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 78 of file EshelbianCore.hpp.

78 {
79 if (v > v_max) {
80 double e = static_cast<double>(std::exp(v_max));
81 double dv = v - v_max;
82 return e * dv + e;
83 } else {
84 return static_cast<double>(std::exp(v));
85 }
86 }

◆ 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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 119 of file EshelbianCore.hpp.

119 {
120 if constexpr (use_quadratic_exp) {
121 return dd_f_log_e_quadratic(v);
122 } else {
123 if (v > v_max)
124 return 0.;
125 else
126 return std::exp(v);
127 }
128 }
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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 88 of file EshelbianCore.hpp.

88 {
89 if (v > v_max) {
90 return static_cast<double>(std::exp(v_max));
91 } else {
92 return static_cast<double>(std::exp(v));
93 }
94 }

◆ 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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 96 of file EshelbianCore.hpp.

96 {
97 if constexpr(use_quadratic_exp) {
98 return f_log_e_quadratic(v);
99 } else {
100 if (v > v_max)
101 // y = exp(v_max) * v + exp(v_max) * (1 - v_max);
102 // y/exp(v_max) = v + (1 - v_max);
103 // y/exp(v_max) - (1 - v_max) = v;
104 return std::exp(v_max) * v + std::exp(v_max) * (1 - v_max);
105 else
106 return std::exp(v);
107 }
108 }
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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 68 of file EshelbianCore.hpp.

68 {
69 if (v > v_max) {
70 double e = static_cast<double>(std::exp(v_max));
71 double dv = v - v_max;
72 return 0.5 * e * dv * dv + e * dv + e;
73 } else {
74 return static_cast<double>(std::exp(v));
75 }
76 }

◆ 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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 257 of file EshelbianCore.hpp.

258 {
260 for (auto it :
261 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
262
263 (boost::format("%s(.*)") % block_name).str()
264
265 ))
266
267 ) {
268 std::vector<double> block_attributes;
269 CHKERR it->getAttributes(block_attributes);
270 if (block_attributes.size() < nb_attributes) {
271 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
272 "In block %s expected %d attributes, but given %ld",
273 it->getName().c_str(), nb_attributes, block_attributes.size());
274 }
275 Range faces;
276 CHKERR it->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2, faces,
277 true);
278 bc_vec_ptr->emplace_back(it->getName(), block_attributes, faces);
279 }
281 }
IFACE getInterface() const
Get interface pointer to pointer of interface.

◆ getExternalStrain()

MoFEMErrorCode EshelbianCore::getExternalStrain ( )
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp, ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

Definition at line 4941 of file EshelbianPlasticity.cpp.

4941 {
4943
4944 auto getExternalStrain = [&](boost::shared_ptr<ExternalStrainVec>
4945 &ext_strain_vec_ptr,
4946 const std::string block_name,
4947 const int nb_attributes) {
4949 for (auto it : mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
4950 std::regex((boost::format("(.*)%s(.*)") % block_name).str()))) {
4951 std::vector<double> block_attributes;
4952 CHKERR it->getAttributes(block_attributes);
4953 if (block_attributes.size() < nb_attributes) {
4954 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
4955 "In block %s expected %d attributes, but given %ld",
4956 it->getName().c_str(), nb_attributes, block_attributes.size());
4957 }
4958
4959 auto get_block_ents = [&]() {
4960 Range ents;
4961 CHKERR mField.get_moab().get_entities_by_handle(it->meshset, ents,
4962 true);
4963 return ents;
4964 };
4965 auto Ents = get_block_ents();
4966 ext_strain_vec_ptr->emplace_back(it->getName(), block_attributes,
4967 get_block_ents());
4968 }
4970 };
4971
4972 externalStrainVecPtr = boost::make_shared<ExternalStrainVec>();
4973
4974 CHKERR getExternalStrain(externalStrainVecPtr, "EXTERNALSTRAIN", 2);
4975
4976 auto ts_pre_stretch = boost::make_shared<DynamicRelaxationTimeScale>(
4977 "externalstrain_history.txt");
4978 for (auto &ext_strain_block : *externalStrainVecPtr) {
4979 MOFEM_LOG("EP", Sev::noisy)
4980 << "Add time scaling external strain: " << ext_strain_block.blockName;
4981 timeScaleMap[ext_strain_block.blockName] =
4983 ts_pre_stretch, "externalstrain_history", ".txt",
4984 ext_strain_block.blockName);
4985 }
4986
4988}
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)
Interface for managing meshsets containing materials and boundary conditions.

◆ getOptions()

MoFEMErrorCode EshelbianCore::getOptions ( )
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 950 of file EshelbianPlasticity.cpp.

950 {
952 const char *list_rots[] = {"small", "moderate", "large", "no_h1"};
953 const char *list_symm[] = {"symm", "not_symm"};
954 const char *list_release[] = {"griffith_force", "griffith_skeleton"};
955 const char *list_stretches[] = {"linear", "log", "log_quadratic"};
956 const char *list_solvers[] = {"time_solver", "dynamic_relaxation",
957 "cohesive"};
958 PetscInt choice_rot = EshelbianCore::rotSelector;
959 PetscInt choice_grad = EshelbianCore::gradApproximator;
960 PetscInt choice_symm = EshelbianCore::symmetrySelector;
961 PetscInt choice_release = EshelbianCore::energyReleaseSelector;
962 PetscInt choice_stretch = StretchSelector::LOG;
963 PetscInt choice_solver = SolverType::TimeSolver;
964 char analytical_expr_file_name[255] = "analytical_expr.py";
965
966 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Eshelbian plasticity", "none");
967 CHKERR PetscOptionsInt("-space_order", "approximation oder for space", "",
968 spaceOrder, &spaceOrder, PETSC_NULLPTR);
969 CHKERR PetscOptionsInt("-space_h1_order", "approximation oder for space", "",
970 spaceH1Order, &spaceH1Order, PETSC_NULLPTR);
971 CHKERR PetscOptionsInt("-material_order", "approximation oder for material",
972 "", materialOrder, &materialOrder, PETSC_NULLPTR);
973 CHKERR PetscOptionsScalar("-viscosity_alpha_u", "viscosity", "", alphaU,
974 &alphaU, PETSC_NULLPTR);
975 CHKERR PetscOptionsScalar("-viscosity_alpha_w", "viscosity", "", alphaW,
976 &alphaW, PETSC_NULLPTR);
977 CHKERR PetscOptionsScalar("-viscosity_alpha_omega", "rot viscosity", "",
978 alphaOmega, &alphaOmega, PETSC_NULLPTR);
979 CHKERR PetscOptionsScalar("-density_alpha_rho", "density", "", alphaRho,
980 &alphaRho, PETSC_NULLPTR);
981 CHKERR PetscOptionsScalar("-alpha_tau", "tau", "", alphaTau, &alphaTau,
982 PETSC_NULLPTR);
983 CHKERR PetscOptionsEList("-rotations", "rotations", "", list_rots,
984 LARGE_ROT + 1, list_rots[choice_rot], &choice_rot,
985 PETSC_NULLPTR);
986 CHKERR PetscOptionsEList("-grad", "gradient of defamation approximate", "",
987 list_rots, NO_H1_CONFIGURATION + 1,
988 list_rots[choice_grad], &choice_grad, PETSC_NULLPTR);
989 CHKERR PetscOptionsEList("-symm", "symmetric variant", "", list_symm, 2,
990 list_symm[choice_symm], &choice_symm, PETSC_NULLPTR);
991
992 CHKERR PetscOptionsScalar("-exponent_base", "exponent_base", "", exponentBase,
993 &EshelbianCore::exponentBase, PETSC_NULLPTR);
994 CHKERR PetscOptionsEList("-stretches", "stretches", "", list_stretches,
995 StretchSelector::STRETCH_SELECTOR_LAST,
996 list_stretches[choice_stretch], &choice_stretch,
997 PETSC_NULLPTR);
998
999 CHKERR PetscOptionsBool("-no_stretch", "do not solve for stretch", "",
1000 noStretch, &noStretch, PETSC_NULLPTR);
1001 CHKERR PetscOptionsBool("-set_singularity", "set singularity", "",
1002 setSingularity, &setSingularity, PETSC_NULLPTR);
1003 CHKERR PetscOptionsBool("-l2_user_base_scale", "streach scale", "",
1004 l2UserBaseScale, &l2UserBaseScale, PETSC_NULLPTR);
1005
1006 // dynamic relaxation
1007
1008 // @deprecate this option
1009 CHKERR PetscOptionsBool("-dynamic_relaxation", "dynamic time relaxation", "",
1010 dynamicRelaxation, &dynamicRelaxation, PETSC_NULLPTR);
1011 CHKERR PetscOptionsEList("-solver_type", "solver type", "", list_solvers,
1012 SolverType::LastSolver, list_solvers[choice_solver],
1013 &choice_solver, PETSC_NULLPTR);
1014
1015 // contact parameters
1016 CHKERR PetscOptionsInt("-contact_max_post_proc_ref_level", "refinement level",
1018 PETSC_NULLPTR);
1019 // cohesive interfae
1020 CHKERR PetscOptionsBool("-cohesive_interface_on", "cohesive interface ON", "",
1021 intefaceCrack, &intefaceCrack, PETSC_NULLPTR);
1022
1023 // cracking parameters
1024 CHKERR PetscOptionsBool("-cracking_on", "cracking ON", "", crackingOn,
1025 &crackingOn, PETSC_NULLPTR);
1026 CHKERR PetscOptionsScalar("-cracking_start_time", "cracking start time", "",
1028 PETSC_NULLPTR);
1029 CHKERR PetscOptionsScalar("-griffith_energy", "Griffith energy", "",
1030 griffithEnergy, &griffithEnergy, PETSC_NULLPTR);
1031 CHKERR PetscOptionsEList("-energy_release_variant", "energy release variant",
1032 "", list_release, 2, list_release[choice_release],
1033 &choice_release, PETSC_NULLPTR);
1034 CHKERR PetscOptionsInt("-nb_J_integral_levels", "Number of J integarl levels",
1036 PETSC_NULLPTR); // backward compatibility
1037 CHKERR PetscOptionsInt(
1038 "-nb_J_integral_contours", "Number of J integral contours", "",
1039 nbJIntegralContours, &nbJIntegralContours, PETSC_NULLPTR);
1040
1041 // internal stress
1042 char tag_name[255] = "";
1043 CHKERR PetscOptionsString("-internal_stress_tag_name",
1044 "internal stress tag name", "", "", tag_name, 255,
1045 PETSC_NULLPTR);
1046 internalStressTagName = string(tag_name);
1047 CHKERR PetscOptionsInt(
1048 "-internal_stress_interp_order", "internal stress interpolation order",
1050 CHKERR PetscOptionsBool("-internal_stress_voigt", "Voigt index notation", "",
1052 PETSC_NULLPTR);
1053
1054 CHKERR PetscOptionsGetString(PETSC_NULLPTR, PETSC_NULLPTR,
1055 "-analytical_expr_file",
1056 analytical_expr_file_name, 255, PETSC_NULLPTR);
1057
1058 PetscOptionsEnd();
1059
1061 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
1062 "Unsupported internal stress interpolation order %d",
1064 }
1065
1066 if (setSingularity) {
1067 l2UserBaseScale = PETSC_TRUE;
1068 }
1069
1070 EshelbianCore::rotSelector = static_cast<RotSelector>(choice_rot);
1071 EshelbianCore::gradApproximator = static_cast<RotSelector>(choice_grad);
1072 EshelbianCore::stretchSelector = static_cast<StretchSelector>(choice_stretch);
1073 EshelbianCore::symmetrySelector = static_cast<SymmetrySelector>(choice_symm);
1075 static_cast<EnergyReleaseSelector>(choice_release);
1076
1078 case StretchSelector::LINEAR:
1085 break;
1086 case StretchSelector::LOG:
1087 if (std::fabs(EshelbianCore::exponentBase - exp(1)) >
1088 std::numeric_limits<float>::epsilon()) {
1095 } else {
1102 }
1103 break;
1104 case StretchSelector::LOG_QUADRATIC:
1108 EshelbianCore::inv_f = [](const double x) {
1110 "No logarithmic quadratic stretch for this case");
1111 return 0;
1112 };
1115 break; // no stretch, do not use stretch functions
1116 default:
1117 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "Unknown stretch");
1118 break;
1119 };
1120
1121 if (dynamicRelaxation) {
1122 MOFEM_LOG("EP", Sev::warning)
1123 << "-dynamic_relaxation option is deprecated, use -solver_type "
1124 "dynamic_relaxation instead.";
1125 choice_solver = SolverType::DynamicRelaxation;
1126 }
1127
1128 switch (choice_solver) {
1131 break;
1135 dynamicRelaxation = PETSC_TRUE;
1136 break;
1139 break;
1140 default:
1141 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "Unknown solver");
1142 break;
1143 };
1144
1145 MOFEM_LOG("EP", Sev::inform) << "spaceOrder: -space_order " << spaceOrder;
1146 MOFEM_LOG("EP", Sev::inform)
1147 << "spaceH1Order: -space_h1_order " << spaceH1Order;
1148 MOFEM_LOG("EP", Sev::inform)
1149 << "materialOrder: -material_order " << materialOrder;
1150 MOFEM_LOG("EP", Sev::inform) << "alphaU: -viscosity_alpha_u " << alphaU;
1151 MOFEM_LOG("EP", Sev::inform) << "alphaW: -viscosity_alpha_w " << alphaW;
1152 MOFEM_LOG("EP", Sev::inform)
1153 << "alphaOmega: -viscosity_alpha_omega " << alphaOmega;
1154 MOFEM_LOG("EP", Sev::inform) << "alphaRho: -density_alpha_rho " << alphaRho;
1155 MOFEM_LOG("EP", Sev::inform) << "alphaTau: -alpha_tau " << alphaTau;
1156 MOFEM_LOG("EP", Sev::inform)
1157 << "Rotations: -rotations " << list_rots[EshelbianCore::rotSelector];
1158 MOFEM_LOG("EP", Sev::inform) << "Gradient of deformation "
1159 << list_rots[EshelbianCore::gradApproximator];
1160 MOFEM_LOG("EP", Sev::inform)
1161 << "Symmetry: -symm " << list_symm[EshelbianCore::symmetrySelector];
1162 if (exponentBase != exp(1))
1163 MOFEM_LOG("EP", Sev::inform)
1164 << "Base exponent: -exponent_base " << EshelbianCore::exponentBase;
1165 else
1166 MOFEM_LOG("EP", Sev::inform) << "Base exponent e";
1167 MOFEM_LOG("EP", Sev::inform)
1168 << "Stretch: -stretches " << list_stretches[choice_stretch];
1169 MOFEM_LOG("EP", Sev::inform) << "No stretch: -no_stretch " << (noStretch)
1170 ? "yes"
1171 : "no";
1172
1173 MOFEM_LOG("EP", Sev::inform)
1174 << "Dynamic relaxation: -dynamic_relaxation " << (dynamicRelaxation)
1175 ? "yes"
1176 : "no";
1177 MOFEM_LOG("EP", Sev::inform)
1178 << "Solver type: -solver_type " << list_solvers[choice_solver];
1179 MOFEM_LOG("EP", Sev::inform)
1180 << "Singularity: -set_singularity " << (setSingularity)
1181 ? "yes"
1182 : "no";
1183 MOFEM_LOG("EP", Sev::inform)
1184 << "L2 user base scale: -l2_user_base_scale " << (l2UserBaseScale)
1185 ? "yes"
1186 : "no";
1187
1188 MOFEM_LOG("EP", Sev::inform) << "Cracking on: -cracking_on " << (crackingOn)
1189 ? "yes"
1190 : "no";
1191 MOFEM_LOG("EP", Sev::inform)
1192 << "Cracking start time: -cracking_start_time " << crackingStartTime;
1193 MOFEM_LOG("EP", Sev::inform)
1194 << "Griffith energy: -griffith_energy " << griffithEnergy;
1195 MOFEM_LOG("EP", Sev::inform)
1196 << "Energy release variant: -energy_release_variant "
1197 << list_release[EshelbianCore::energyReleaseSelector];
1198 MOFEM_LOG("EP", Sev::inform)
1199 << "Number of J integral contours: -nb_J_integral_contours "
1201 MOFEM_LOG("EP", Sev::inform)
1202 << "Cohesive interface on: -cohesive_interface_on "
1203 << (intefaceCrack == PETSC_TRUE)
1204 ? "yes"
1205 : "no";
1206
1207#ifdef ENABLE_PYTHON_BINDING
1208 auto file_exists = [](std::string myfile) {
1209 std::ifstream file(myfile.c_str());
1210 if (file) {
1211 return true;
1212 }
1213 return false;
1214 };
1215
1216 if (file_exists(analytical_expr_file_name)) {
1217 MOFEM_LOG("EP", Sev::inform) << analytical_expr_file_name << " file found";
1218
1219 AnalyticalExprPythonPtr = boost::make_shared<AnalyticalExprPython>();
1220 CHKERR AnalyticalExprPythonPtr->analyticalExprInit(
1221 analytical_expr_file_name);
1222 AnalyticalExprPythonWeakPtr = AnalyticalExprPythonPtr;
1223 } else {
1224 MOFEM_LOG("EP", Sev::warning)
1225 << analytical_expr_file_name << " file NOT found";
1226 }
1227#endif
1228
1229 if (spaceH1Order == -1)
1231
1233}
@ 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 enum SolverType solverType
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 PetscBool intefaceCrack
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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp, ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

Definition at line 4763 of file EshelbianPlasticity.cpp.

4763 {
4765
4766 auto bc_mng = mField.getInterface<BcManager>();
4768 "", piolaStress, false, false);
4769
4770 bcSpatialDispVecPtr = boost::make_shared<BcDispVec>();
4771 for (auto bc : bc_mng->getBcMapByBlockName()) {
4772 if (auto disp_bc = bc.second->dispBcPtr) {
4773
4774 auto [field_name, block_name] =
4776 MOFEM_LOG("EP", Sev::inform)
4777 << "Field name: " << field_name << " Block name: " << block_name;
4778 MOFEM_LOG("EP", Sev::noisy) << "Displacement BC: " << *disp_bc;
4779
4780 std::vector<double> block_attributes(6, 0.);
4781 if (disp_bc->data.flag1 == 1) {
4782 block_attributes[0] = disp_bc->data.value1;
4783 block_attributes[3] = 1;
4784 }
4785 if (disp_bc->data.flag2 == 1) {
4786 block_attributes[1] = disp_bc->data.value2;
4787 block_attributes[4] = 1;
4788 }
4789 if (disp_bc->data.flag3 == 1) {
4790 block_attributes[2] = disp_bc->data.value3;
4791 block_attributes[5] = 1;
4792 }
4793 auto faces = bc.second->bcEnts.subset_by_dimension(2);
4794 bcSpatialDispVecPtr->emplace_back(block_name, block_attributes, faces);
4795 }
4796 }
4797 // old way of naming blocksets for displacement BCs
4798 CHKERR getBc(bcSpatialDispVecPtr, "SPATIAL_DISP_BC", 6);
4799
4801 boost::make_shared<NormalDisplacementBcVec>();
4802 for (auto bc : bc_mng->getBcMapByBlockName()) {
4803 auto block_name = "(.*)NORMAL_DISPLACEMENT(.*)";
4804 std::regex reg_name(block_name);
4805 if (std::regex_match(bc.first, reg_name)) {
4806 auto [field_name, block_name] =
4808 MOFEM_LOG("EP", Sev::inform)
4809 << "Field name: " << field_name << " Block name: " << block_name;
4811 block_name, bc.second->bcAttributes,
4812 bc.second->bcEnts.subset_by_dimension(2));
4813 }
4814 }
4815
4817 boost::make_shared<AnalyticalDisplacementBcVec>();
4818
4819 for (auto bc : bc_mng->getBcMapByBlockName()) {
4820 auto block_name = "(.*)ANALYTICAL_DISPLACEMENT(.*)";
4821 std::regex reg_name(block_name);
4822 if (std::regex_match(bc.first, reg_name)) {
4823 auto [field_name, block_name] =
4825 MOFEM_LOG("EP", Sev::inform)
4826 << "Field name: " << field_name << " Block name: " << block_name;
4828 block_name, bc.second->bcAttributes,
4829 bc.second->bcEnts.subset_by_dimension(2));
4830 }
4831 }
4832
4833 auto ts_displacement =
4834 boost::make_shared<DynamicRelaxationTimeScale>("disp_history.txt");
4835 for (auto &bc : *bcSpatialDispVecPtr) {
4836 MOFEM_LOG("EP", Sev::noisy)
4837 << "Add time scaling displacement BC: " << bc.blockName;
4838 timeScaleMap[bc.blockName] =
4840 ts_displacement, "disp_history", ".txt", bc.blockName);
4841 }
4842
4843 auto ts_normal_displacement =
4844 boost::make_shared<DynamicRelaxationTimeScale>("normal_disp_history.txt");
4845 for (auto &bc : *bcSpatialNormalDisplacementVecPtr) {
4846 MOFEM_LOG("EP", Sev::noisy)
4847 << "Add time scaling normal displacement BC: " << bc.blockName;
4848 timeScaleMap[bc.blockName] =
4850 ts_normal_displacement, "normal_disp_history", ".txt",
4851 bc.blockName);
4852 }
4853
4855}
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 285 of file EshelbianCore.hpp.

285 {
287 bcSpatialRotationVecPtr = boost::make_shared<BcRotVec>();
288 CHKERR getBc(bcSpatialRotationVecPtr, "SPATIAL_ROTATION_BC", 4);
289 CHKERR getBc(bcSpatialRotationVecPtr, "SPATIAL_ROTATION_AXIS_BC", 7);
290
291 auto ts_rotation =
292 boost::make_shared<DynamicRelaxationTimeScale>("rotation_history.txt");
293 for (auto &bc : *bcSpatialRotationVecPtr) {
294 timeScaleMap[bc.blockName] =
295 GetBlockScalingMethod<DynamicRelaxationTimeScale>::get(
296 ts_rotation, "rotation_history", ".txt", bc.blockName);
297 }
298
300 }

◆ getSpatialTractionBc()

MoFEMErrorCode EshelbianCore::getSpatialTractionBc ( )
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp, ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

Definition at line 4857 of file EshelbianPlasticity.cpp.

4857 {
4859
4860 auto bc_mng = mField.getInterface<BcManager>();
4862 false, false);
4863
4864 bcSpatialTractionVecPtr = boost::make_shared<TractionBcVec>();
4865
4866 for (auto bc : bc_mng->getBcMapByBlockName()) {
4867 if (auto force_bc = bc.second->forceBcPtr) {
4868
4869 auto [field_name, block_name] =
4871 MOFEM_LOG("EP", Sev::inform)
4872 << "Field name: " << field_name << " Block name: " << block_name;
4873 MOFEM_LOG("EP", Sev::noisy) << "Force BC: " << *force_bc;
4874
4875 std::vector<double> block_attributes(6, 0.);
4876 block_attributes[0] = -force_bc->data.value3 * force_bc->data.value1;
4877 block_attributes[3] = 1;
4878 block_attributes[1] = -force_bc->data.value4 * force_bc->data.value1;
4879 block_attributes[4] = 1;
4880 block_attributes[2] = -force_bc->data.value5 * force_bc->data.value1;
4881 block_attributes[5] = 1;
4882 auto faces = bc.second->bcEnts.subset_by_dimension(2);
4883 bcSpatialTractionVecPtr->emplace_back(block_name, block_attributes,
4884 faces);
4885 }
4886 }
4887 CHKERR getBc(bcSpatialTractionVecPtr, "SPATIAL_TRACTION_BC", 6);
4888
4889 bcSpatialPressureVecPtr = boost::make_shared<PressureBcVec>();
4890 for (auto bc : bc_mng->getBcMapByBlockName()) {
4891 auto block_name = "(.*)PRESSURE(.*)";
4892 std::regex reg_name(block_name);
4893 if (std::regex_match(bc.first, reg_name)) {
4894
4895 auto [field_name, block_name] =
4897 MOFEM_LOG("EP", Sev::inform)
4898 << "Field name: " << field_name << " Block name: " << block_name;
4899 bcSpatialPressureVecPtr->emplace_back(
4900 block_name, bc.second->bcAttributes,
4901 bc.second->bcEnts.subset_by_dimension(2));
4902 }
4903 }
4904
4906 boost::make_shared<AnalyticalTractionBcVec>();
4907
4908 for (auto bc : bc_mng->getBcMapByBlockName()) {
4909 auto block_name = "(.*)ANALYTICAL_TRACTION(.*)";
4910 std::regex reg_name(block_name);
4911 if (std::regex_match(bc.first, reg_name)) {
4912 auto [field_name, block_name] =
4914 MOFEM_LOG("EP", Sev::inform)
4915 << "Field name: " << field_name << " Block name: " << block_name;
4917 block_name, bc.second->bcAttributes,
4918 bc.second->bcEnts.subset_by_dimension(2));
4919 }
4920 }
4921
4922 auto ts_traction =
4923 boost::make_shared<DynamicRelaxationTimeScale>("traction_history.txt");
4924 for (auto &bc : *bcSpatialTractionVecPtr) {
4925 timeScaleMap[bc.blockName] =
4927 ts_traction, "traction_history", ".txt", bc.blockName);
4928 }
4929
4930 auto ts_pressure =
4931 boost::make_shared<DynamicRelaxationTimeScale>("pressure_history.txt");
4932 for (auto &bc : *bcSpatialPressureVecPtr) {
4933 timeScaleMap[bc.blockName] =
4935 ts_pressure, "pressure_history", ".txt", bc.blockName);
4936 }
4937
4939}
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 319 of file EshelbianCore.hpp.

319 {
321 boost::shared_ptr<TractionFreeBc>(new TractionFreeBc());
322 return getTractionFreeBc(meshset, bcSpatialFreeTractionVecPtr, "CONTACT");
323 }
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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 4695 of file EshelbianPlasticity.cpp.

4695 {
4697
4698 auto post_proc_norm_fe =
4699 boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
4700
4701 auto post_proc_norm_rule_hook = [](int, int, int p) -> int {
4702 return 2 * (p);
4703 };
4704 post_proc_norm_fe->getRuleHook = post_proc_norm_rule_hook;
4705
4706 post_proc_norm_fe->getUserPolynomialBase() =
4707 boost::shared_ptr<BaseFunction>(new CGGUserPolynomialBase());
4708
4709 CHKERR EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4710 post_proc_norm_fe->getOpPtrVector(), {L2, H1, HDIV}, materialH1Positions,
4712
4713 enum NORMS { U_NORM_L2 = 0, U_NORM_H1, PIOLA_NORM, U_ERROR_L2, LAST_NORM };
4714 auto norms_vec =
4715 createVectorMPI(mField.get_comm(), LAST_NORM, PETSC_DETERMINE);
4716 CHKERR VecZeroEntries(norms_vec);
4717
4718 auto u_l2_ptr = boost::make_shared<MatrixDouble>();
4719 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
4720 post_proc_norm_fe->getOpPtrVector().push_back(
4722 post_proc_norm_fe->getOpPtrVector().push_back(
4724 post_proc_norm_fe->getOpPtrVector().push_back(
4725 new OpCalcNormL2Tensor1<SPACE_DIM>(u_l2_ptr, norms_vec, U_NORM_L2));
4726 post_proc_norm_fe->getOpPtrVector().push_back(
4727 new OpCalcNormL2Tensor1<SPACE_DIM>(u_h1_ptr, norms_vec, U_NORM_H1));
4728 post_proc_norm_fe->getOpPtrVector().push_back(
4729 new OpCalcNormL2Tensor1<SPACE_DIM>(u_l2_ptr, norms_vec, U_ERROR_L2,
4730 u_h1_ptr));
4731
4732 auto piola_ptr = boost::make_shared<MatrixDouble>();
4733 post_proc_norm_fe->getOpPtrVector().push_back(
4735 post_proc_norm_fe->getOpPtrVector().push_back(
4737 MBMAXTYPE));
4738
4739 post_proc_norm_fe->getOpPtrVector().push_back(
4740 new OpCalcNormL2Tensor2<3, 3>(piola_ptr, norms_vec, PIOLA_NORM));
4741
4742 TetPolynomialBase::switchCacheBaseOn<HDIV>({post_proc_norm_fe.get()});
4744 *post_proc_norm_fe);
4745 TetPolynomialBase::switchCacheBaseOff<HDIV>({post_proc_norm_fe.get()});
4746
4747 CHKERR VecAssemblyBegin(norms_vec);
4748 CHKERR VecAssemblyEnd(norms_vec);
4749 const double *norms;
4750 CHKERR VecGetArrayRead(norms_vec, &norms);
4751 MOFEM_LOG("EP", Sev::inform) << "norm_u: " << std::sqrt(norms[U_NORM_L2]);
4752 MOFEM_LOG("EP", Sev::inform) << "norm_u_h1: " << std::sqrt(norms[U_NORM_H1]);
4753 MOFEM_LOG("EP", Sev::inform)
4754 << "norm_error_u_l2: " << std::sqrt(norms[U_ERROR_L2]);
4755 MOFEM_LOG("EP", Sev::inform)
4756 << "norm_piola: " << std::sqrt(norms[PIOLA_NORM]);
4757 CHKERR VecRestoreArrayRead(norms_vec, &norms);
4758
4760}
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.
Calculate tenor field using tensor base, i.e. Hdiv/Hcurl.
Calculate tenor field using vectorial base, i.e. Hdiv/Hcurl.
Specialization for double precision vector field values calculation.

◆ 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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 2579 of file EshelbianPlasticity.cpp.

2581 {
2583
2584 // get skin from all tets
2585 Range tets;
2586 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
2587 Range tets_skin_part;
2588 Skinner skin(&mField.get_moab());
2589 CHKERR skin.find_skin(0, tets, false, tets_skin_part);
2590 ParallelComm *pcomm =
2591 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
2592 Range tets_skin;
2593 CHKERR pcomm->filter_pstatus(tets_skin_part,
2594 PSTATUS_SHARED | PSTATUS_MULTISHARED,
2595 PSTATUS_NOT, -1, &tets_skin);
2596
2597 bc_ptr->resize(3);
2598 for (int dd = 0; dd != 3; ++dd)
2599 (*bc_ptr)[dd] = tets_skin;
2600
2601 // Do not remove dofs on which traction is applied
2603 for (auto &v : *bcSpatialDispVecPtr) {
2604 if (v.flags[0])
2605 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2606 if (v.flags[1])
2607 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2608 if (v.flags[2])
2609 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2610 }
2611
2612 // Do not remove dofs on which rotation is applied
2614 for (auto &v : *bcSpatialRotationVecPtr) {
2615 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2616 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2617 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2618 }
2619
2621 for (auto &v : *bcSpatialNormalDisplacementVecPtr) {
2622 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2623 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2624 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2625 }
2626
2629 if (v.flags[0])
2630 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2631 if (v.flags[1])
2632 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2633 if (v.flags[2])
2634 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2635 }
2636
2638 for (auto &v : *bcSpatialTractionVecPtr) {
2639 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2640 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2641 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2642 }
2643
2645 for (auto &v : *bcSpatialAnalyticalTractionVecPtr) {
2646 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2647 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2648 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2649 }
2650
2652 for (auto &v : *bcSpatialPressureVecPtr) {
2653 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2654 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2655 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2656 }
2657
2658 // remove contact
2659 for (auto m : mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
2660 std::regex((boost::format("%s(.*)") % contact_set_name).str()))) {
2661 Range faces;
2662 CHKERR m->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2, faces,
2663 true);
2664 (*bc_ptr)[0] = subtract((*bc_ptr)[0], faces);
2665 (*bc_ptr)[1] = subtract((*bc_ptr)[1], faces);
2666 (*bc_ptr)[2] = subtract((*bc_ptr)[2], faces);
2667 }
2668
2670}
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

◆ inv_d_f_log_e()

static double EshelbianCore::inv_d_f_log_e ( const double  v)
inlinestatic
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 138 of file EshelbianCore.hpp.

138 {
139 if (v > std::exp(v_min))
140 return 1. / v;
141 else
142 return 1. / exp(v_min);
143 }
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

◆ inv_dd_f_log_e()

static double EshelbianCore::inv_dd_f_log_e ( const double  v)
inlinestatic
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 144 of file EshelbianCore.hpp.

144 {
145 if (v > std::exp(v_min))
146 return -1. / (v * v);
147 else
148 return 0.;
149 }

◆ 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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 129 of file EshelbianCore.hpp.

129 {
130 if (v > std::exp(v_min))
131 return std::log(v);
132 else
133 // y = exp(v_min) * v + exp(v_min) * (1 - v_min);
134 // y/exp(v_min) = v + (1 - v_min);
135 // y/exp(v_min) - (1 - v_min) = v;
136 return v / exp(v_min) - (1 - v_min);
137 }

◆ 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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 4070 of file EshelbianPlasticity.cpp.

4072 {
4074
4075 // mark crack surface
4076 if (crackingOn) {
4077 auto get_tag = [&](auto name, auto dim) {
4078 auto &mob = mField.get_moab();
4079 Tag tag;
4080 double def_val[] = {0., 0., 0.};
4081 CHK_MOAB_THROW(mob.tag_get_handle(name, dim, MB_TYPE_DOUBLE, tag,
4082 MB_TAG_CREAT | MB_TAG_SPARSE, def_val),
4083 "create tag");
4084 return tag;
4085 };
4086 tags_to_transfer.push_back(get_tag("MaterialForce", 3));
4087 }
4088
4089 {
4090 auto get_crack_tag = [&]() {
4091 Tag th;
4092 rval = mField.get_moab().tag_get_handle("CRACK", th);
4093 if (rval == MB_SUCCESS) {
4094 MOAB_THROW(mField.get_moab().tag_delete(th));
4095 }
4096 int def_val[] = {0};
4097 MOAB_THROW(mField.get_moab().tag_get_handle(
4098 "CRACK", 1, MB_TYPE_INTEGER, th, MB_TAG_SPARSE | MB_TAG_CREAT,
4099 def_val));
4100 return th;
4101 };
4102
4103 Tag th = get_crack_tag();
4104 tags_to_transfer.push_back(th);
4105 int mark[] = {1};
4106 Range mark_faces;
4107 if (crackFaces)
4108 mark_faces.merge(*crackFaces);
4109 if (interfaceFaces)
4110 mark_faces.merge(*interfaceFaces);
4111 CHKERR mField.get_moab().tag_clear_data(th, mark_faces, mark);
4112 }
4113
4114 // add tags to transfer
4115 for (auto t : listTagsToTransfer) {
4116 tags_to_transfer.push_back(t);
4117 }
4118
4119 if (!dataAtPts) {
4120 dataAtPts =
4121 boost::shared_ptr<DataAtIntegrationPts>(new DataAtIntegrationPts());
4122 }
4123
4125
4126 auto get_post_proc = [&](auto &post_proc_mesh, auto sense) {
4128 auto post_proc_ptr =
4129 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
4130 mField, post_proc_mesh);
4131 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
4132 post_proc_ptr->getOpPtrVector(), {L2}, materialH1Positions,
4134
4135 auto domain_ops = [&](auto &fe, int sense) {
4137 fe.getUserPolynomialBase() =
4138 boost::shared_ptr<BaseFunction>(new CGGUserPolynomialBase());
4139 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4140 fe.getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions,
4142 auto piola_scale_ptr = boost::make_shared<double>(1.0);
4143 fe.getOpPtrVector().push_back(physicalEquations->returnOpSetScale(
4144 piola_scale_ptr, physicalEquations));
4145 fe.getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
4146 piolaStress, dataAtPts->getApproxPAtPts(), piola_scale_ptr));
4147 fe.getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
4148 bubbleField, dataAtPts->getApproxPAtPts(), piola_scale_ptr,
4149 SmartPetscObj<Vec>(), MBMAXTYPE));
4150 if (noStretch) {
4151 fe.getOpPtrVector().push_back(
4152 physicalEquations->returnOpCalculateStretchFromStress(
4154 } else {
4155 fe.getOpPtrVector().push_back(
4157 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
4158 }
4159 if (var_vector) {
4160 auto vec = SmartPetscObj<Vec>(var_vector, true);
4161 fe.getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
4162 piolaStress, dataAtPts->getVarPiolaPts(),
4163 boost::make_shared<double>(1), vec));
4164 fe.getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
4165 bubbleField, dataAtPts->getVarPiolaPts(),
4166 boost::make_shared<double>(1), vec, MBMAXTYPE));
4167 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4168 rotAxis, dataAtPts->getVarRotAxisPts(), vec, MBTET));
4169 if (noStretch) {
4170 fe.getOpPtrVector().push_back(
4171 physicalEquations->returnOpCalculateVarStretchFromStress(
4173 } else {
4174 fe.getOpPtrVector().push_back(
4176 stretchTensor, dataAtPts->getVarLogStreachPts(), vec, MBTET));
4177 }
4178 }
4179
4180 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4181 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
4182 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4183 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
4184
4185 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4186 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
4187 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4188 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
4189 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldGradient<3, 3>(
4190 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
4191 // evaluate derived quantities
4192 fe.getOpPtrVector().push_back(
4194
4195 // evaluate integration points
4196 fe.getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
4197 tag, true, false, dataAtPts, physicalEquations));
4198 if (auto op =
4199 physicalEquations->returnOpCalculateEnergy(dataAtPts, nullptr)) {
4200 fe.getOpPtrVector().push_back(op);
4201 fe.getOpPtrVector().push_back(new OpCalculateEshelbyStress(dataAtPts));
4202 }
4203
4204 // // post-proc
4207 VolumeElementForcesAndSourcesCoreOnSide::UserDataOperator>;
4208
4209 struct OpSidePPMap : public OpPPMap {
4210 OpSidePPMap(moab::Interface &post_proc_mesh,
4211 std::vector<EntityHandle> &map_gauss_pts,
4212 DataMapVec data_map_scalar, DataMapMat data_map_vec,
4213 DataMapMat data_map_mat, DataMapMat data_symm_map_mat,
4214 int sense)
4215 : OpPPMap(post_proc_mesh, map_gauss_pts, data_map_scalar,
4216 data_map_vec, data_map_mat, data_symm_map_mat),
4217 tagSense(sense) {}
4218
4219 MoFEMErrorCode doWork(int side, EntityType type,
4222
4223 if (tagSense != 0) {
4224 if (tagSense != OpPPMap::getSkeletonSense())
4226 }
4227
4228 CHKERR OpPPMap::doWork(side, type, data);
4230 }
4231
4232 private:
4233 int tagSense;
4234 };
4235
4236 OpPPMap::DataMapMat vec_fields;
4237 vec_fields["SpatialDisplacementL2"] = dataAtPts->getSmallWL2AtPts();
4238 vec_fields["SpatialDisplacementH1"] = dataAtPts->getSmallWH1AtPts();
4239 vec_fields["Omega"] = dataAtPts->getRotAxisAtPts();
4240 vec_fields["AngularMomentum"] = dataAtPts->getLeviKirchhoffAtPts();
4241 vec_fields["X"] = dataAtPts->getLargeXH1AtPts();
4242 if (!noStretch) {
4243 vec_fields["EiegnLogStreach"] = dataAtPts->getEigenValsAtPts();
4244 }
4245 if (var_vector) {
4246 auto vec = SmartPetscObj<Vec>(var_vector, true);
4247 vec_fields["VarOmega"] = dataAtPts->getVarRotAxisPts();
4248 vec_fields["VarSpatialDisplacementL2"] =
4249 boost::make_shared<MatrixDouble>();
4250 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4251 spatialL2Disp, vec_fields["VarSpatialDisplacementL2"], vec, MBTET));
4252 }
4253 if (f_residual) {
4254 auto vec = SmartPetscObj<Vec>(f_residual, true);
4255 vec_fields["ResSpatialDisplacementL2"] =
4256 boost::make_shared<MatrixDouble>();
4257 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4258 spatialL2Disp, vec_fields["ResSpatialDisplacementL2"], vec, MBTET));
4259 vec_fields["ResOmega"] = boost::make_shared<MatrixDouble>();
4260 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4261 rotAxis, vec_fields["ResOmega"], vec, MBTET));
4262 }
4263
4264 OpPPMap::DataMapMat mat_fields;
4265 mat_fields["PiolaStress"] = dataAtPts->getApproxPAtPts();
4266 if (var_vector) {
4267 mat_fields["VarPiolaStress"] = dataAtPts->getVarPiolaPts();
4268 }
4269 if (f_residual) {
4270 auto vec = SmartPetscObj<Vec>(f_residual, true);
4271 mat_fields["ResPiolaStress"] = boost::make_shared<MatrixDouble>();
4272 fe.getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
4273 piolaStress, mat_fields["ResPiolaStress"],
4274 boost::make_shared<double>(1), vec));
4275 fe.getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
4276 bubbleField, mat_fields["ResPiolaStress"],
4277 boost::make_shared<double>(1), vec, MBMAXTYPE));
4278 }
4279 if (!internalStressTagName.empty()) {
4280 mat_fields[internalStressTagName] = dataAtPts->getInternalStressAtPts();
4281 switch (internalStressInterpOrder) {
4282 case 0:
4283 fe.getOpPtrVector().push_back(
4285 break;
4286 case 1:
4287 fe.getOpPtrVector().push_back(
4289 break;
4290 default:
4291 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
4292 "Unsupported internal stress interpolation order %d",
4294 }
4295 }
4296
4297 OpPPMap::DataMapMat mat_fields_symm;
4298 mat_fields_symm["LogSpatialStretch"] =
4299 dataAtPts->getLogStretchTensorAtPts();
4300 mat_fields_symm["SpatialStretch"] = dataAtPts->getStretchTensorAtPts();
4301 if (var_vector) {
4302 mat_fields_symm["VarLogSpatialStretch"] =
4303 dataAtPts->getVarLogStreachPts();
4304 }
4305 if (f_residual) {
4306 auto vec = SmartPetscObj<Vec>(f_residual, true);
4307 if (!noStretch) {
4308 mat_fields_symm["ResLogSpatialStretch"] =
4309 boost::make_shared<MatrixDouble>();
4310 fe.getOpPtrVector().push_back(
4312 stretchTensor, mat_fields_symm["ResLogSpatialStretch"], vec,
4313 MBTET));
4314 }
4315 }
4316
4317 fe.getOpPtrVector().push_back(
4318
4319 new OpSidePPMap(
4320
4321 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4322
4323 {},
4324
4325 vec_fields,
4326
4327 mat_fields,
4328
4329 mat_fields_symm,
4330
4331 sense
4332
4333 )
4334
4335 );
4336
4337 fe.getOpPtrVector().push_back(new OpPostProcDataStructure(
4338 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4339 dataAtPts, sense));
4340
4342 };
4343
4344 auto X_h1_ptr = boost::make_shared<MatrixDouble>();
4345 // H1 material positions
4346 post_proc_ptr->getOpPtrVector().push_back(
4348 dataAtPts->getLargeXH1AtPts()));
4349
4350 // domain
4353 domain_ops(*(op_loop_side->getSideFEPtr()), sense);
4354 post_proc_ptr->getOpPtrVector().push_back(op_loop_side);
4355
4356 return post_proc_ptr;
4357 };
4358
4359 // contact
4360 auto calcs_side_traction_and_displacements = [&](auto &post_proc_ptr,
4361 auto &pip) {
4363 // evaluate traction
4364 using EleOnSide =
4366 using SideEleOp = EleOnSide::UserDataOperator;
4367 auto op_loop_domain_side = new OpLoopSide<EleOnSide>(
4368 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
4369 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
4370 boost::shared_ptr<BaseFunction>(new CGGUserPolynomialBase());
4371 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4372 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
4374 auto traction_ptr = boost::make_shared<MatrixDouble>();
4375 op_loop_domain_side->getOpPtrVector().push_back(
4377 piolaStress, traction_ptr, boost::make_shared<double>(1.0)));
4378
4379 pip.push_back(new OpCalculateVectorFieldValues<3>(
4380 contactDisp, dataAtPts->getContactL2AtPts()));
4381 pip.push_back(op_loop_domain_side);
4382 // evaluate contact displacement and contact conditions
4383 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
4384 pip.push_back(new OpCalculateVectorFieldValues<3>(spatialH1Disp, u_h1_ptr));
4385 pip.push_back(getOpContactDetection(
4386 *this, contactTreeRhs, u_h1_ptr, traction_ptr,
4387 get_range_from_block(mField, "CONTACT", SPACE_DIM - 1),
4388 &post_proc_ptr->getPostProcMesh(), &post_proc_ptr->getMapGaussPts()));
4389
4391 using BoundaryEle =
4393 auto op_this = new OpLoopThis<BoundaryEle>(mField, contactElement);
4394 op_this->getOpPtrVector().push_back(
4395
4396 new OpPPMap(
4397
4398 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4399
4400 {},
4401
4402 {{"ContactDisplacement", dataAtPts->getContactL2AtPts()}},
4403
4404 {},
4405
4406 {}
4407
4408 )
4409
4410 );
4411
4412 if (f_residual) {
4413
4414 pip.push_back(op_this);
4415 auto contact_residual = boost::make_shared<MatrixDouble>();
4416 op_this->getOpPtrVector().push_back(
4418 contactDisp, contact_residual,
4419 SmartPetscObj<Vec>(f_residual, true)));
4420 op_this->getOpPtrVector().push_back(
4421
4422 new OpPPMap(
4423
4424 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4425
4426 {},
4427
4428 {{"res_contact", contact_residual}},
4429
4430 {},
4431
4432 {}
4433
4434 )
4435
4436 );
4437 }
4438
4440 };
4441
4442 auto post_proc_mesh = boost::make_shared<moab::Core>();
4443 auto post_proc_ptr = get_post_proc(post_proc_mesh, /*positive sense*/ 1);
4444 auto post_proc_negative_sense_ptr =
4445 get_post_proc(post_proc_mesh, /*negative sense*/ -1);
4446 auto skin_post_proc_ptr = get_post_proc(post_proc_mesh, /*positive sense*/ 1);
4447 CHKERR calcs_side_traction_and_displacements(
4448 skin_post_proc_ptr, skin_post_proc_ptr->getOpPtrVector());
4449
4450 auto own_tets =
4452 .subset_by_dimension(SPACE_DIM);
4453 Range own_faces;
4454 CHKERR mField.get_moab().get_adjacencies(own_tets, SPACE_DIM - 1, true,
4455 own_faces, moab::Interface::UNION);
4456
4457 auto get_crack_faces = [&](auto crack_faces) {
4458 auto get_adj = [&](auto e, auto dim) {
4459 Range adj;
4460 CHKERR mField.get_moab().get_adjacencies(e, dim, true, adj,
4461 moab::Interface::UNION);
4462 return adj;
4463 };
4464 // this removes faces
4465 auto tets = get_adj(crack_faces, 3);
4466 // faces adjacent to tets not in crack_faces
4467 auto faces = subtract(get_adj(tets, 2), crack_faces);
4468 // what is left from below, are tets fully inside crack_faces
4469 tets = subtract(tets, get_adj(faces, 3));
4470 return subtract(crack_faces, get_adj(tets, 2));
4471 };
4472
4473 auto side_one_faces = [&](auto &faces) {
4474 std::pair<Range, Range> sides;
4475 for (auto f : faces) {
4476 Range adj;
4477 MOAB_THROW(mField.get_moab().get_adjacencies(&f, 1, 3, false, adj));
4478 adj = intersect(own_tets, adj);
4479 for (auto t : adj) {
4480 int side, sense, offset;
4481 MOAB_THROW(mField.get_moab().side_number(t, f, side, sense, offset));
4482 if (sense == 1) {
4483 sides.first.insert(f);
4484 } else {
4485 sides.second.insert(f);
4486 }
4487 }
4488 }
4489 return sides;
4490 };
4491
4492 auto crack_faces =
4493 unite(get_crack_faces(*crackFaces), get_crack_faces(*interfaceFaces));
4494 auto crack_side_faces = side_one_faces(crack_faces);
4495 auto side_one_crack_faces = [crack_side_faces](FEMethod *fe_method_ptr) {
4496 auto ent = fe_method_ptr->getFEEntityHandle();
4497 if (crack_side_faces.first.find(ent) == crack_side_faces.first.end()) {
4498 return false;
4499 }
4500 return true;
4501 };
4502 auto side_minus_crack_faces = [crack_side_faces](FEMethod *fe_method_ptr) {
4503 auto ent = fe_method_ptr->getFEEntityHandle();
4504 if (crack_side_faces.second.find(ent) == crack_side_faces.second.end()) {
4505 return false;
4506 }
4507 return true;
4508 };
4509
4510 skin_post_proc_ptr->setTagsToTransfer(tags_to_transfer);
4511 post_proc_ptr->setTagsToTransfer(tags_to_transfer);
4512 post_proc_negative_sense_ptr->setTagsToTransfer(tags_to_transfer);
4513
4514 auto post_proc_begin =
4516 CHKERR DMoFEMPreProcessFiniteElements(dM, post_proc_begin.getFEMethod());
4517 CHKERR DMoFEMLoopFiniteElements(dM, skinElement, skin_post_proc_ptr);
4518 post_proc_ptr->exeTestHook = side_one_crack_faces;
4520 dM, skeletonElement, post_proc_ptr, 0, mField.get_comm_size());
4521 post_proc_negative_sense_ptr->exeTestHook = side_minus_crack_faces;
4523 post_proc_negative_sense_ptr, 0,
4525
4526 constexpr bool debug = false;
4527 if (debug) {
4528
4529 auto get_adj_front = [&]() {
4530 auto skeleton_faces = *skeletonFaces;
4531 Range adj_front;
4532 CHKERR mField.get_moab().get_adjacencies(*frontEdges, 2, true, adj_front,
4533 moab::Interface::UNION);
4534
4535 adj_front = intersect(adj_front, skeleton_faces);
4536 adj_front = subtract(adj_front, *crackFaces);
4537 adj_front = intersect(own_faces, adj_front);
4538 return adj_front;
4539 };
4540
4541 auto adj_front = filter_owners(mField, get_adj_front());
4542 auto only_front_faces = [adj_front](FEMethod *fe_method_ptr) {
4543 auto ent = fe_method_ptr->getFEEntityHandle();
4544 if (adj_front.find(ent) == adj_front.end()) {
4545 return false;
4546 }
4547 return true;
4548 };
4549
4550 post_proc_ptr->exeTestHook = only_front_faces;
4552 dM, skeletonElement, post_proc_ptr, 0, mField.get_comm_size());
4553 post_proc_negative_sense_ptr->exeTestHook = only_front_faces;
4555 post_proc_negative_sense_ptr, 0,
4557 }
4558 auto post_proc_end = PostProcBrokenMeshInMoabBaseEnd(mField, post_proc_mesh);
4559 CHKERR DMoFEMPostProcessFiniteElements(dM, post_proc_end.getFEMethod());
4560
4561 CHKERR post_proc_end.writeFile(file.c_str());
4563}
static auto filter_owners(MoFEM::Interface &m_field, Range skin)
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
#define MOAB_THROW(err)
Check error code of MoAB function and throw MoFEM exception.
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
ForcesAndSourcesCore::UserDataOperator * getOpContactDetection(EshelbianCore &ep, boost::shared_ptr< ForcesAndSourcesCore > contact_tree_ptr, boost::shared_ptr< MatrixDouble > u_h1_ptr, boost::shared_ptr< MatrixDouble > contact_traction_ptr, Range r, moab::Interface *post_proc_mesh_ptr, std::vector< EntityHandle > *map_gauss_pts_ptr)
Push operator for contact detection.
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
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< Range > interfaceFaces
boost::shared_ptr< ForcesAndSourcesCore > 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.
Calculate trace of vector (Hdiv/Hcurl) space.
Calculate symmetric tensor field values at integration pts.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Element used to execute operators on side of the element.
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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 4566 of file EshelbianPlasticity.cpp.

4568 {
4570
4572
4573 auto post_proc_mesh = boost::make_shared<moab::Core>();
4574 auto post_proc_ptr =
4575 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
4576 mField, post_proc_mesh);
4577 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM - 1, SPACE_DIM>::add(
4578 post_proc_ptr->getOpPtrVector(), {L2}, materialH1Positions,
4580
4581 auto hybrid_disp = boost::make_shared<MatrixDouble>();
4582 post_proc_ptr->getOpPtrVector().push_back(
4584 post_proc_ptr->getOpPtrVector().push_back(
4586 hybridSpatialDisp, dataAtPts->getGradHybridDispAtPts()));
4587
4588 auto op_loop_domain_side =
4590 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
4591 post_proc_ptr->getOpPtrVector().push_back(op_loop_domain_side);
4592
4593 // evaluated in side domain, that is op_loop_domain_side
4594 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
4595 boost::make_shared<CGGUserPolynomialBase>();
4596 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4597 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
4599 op_loop_domain_side->getOpPtrVector().push_back(
4601 piolaStress, dataAtPts->getApproxPAtPts()));
4602 op_loop_domain_side->getOpPtrVector().push_back(
4604 bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
4605 op_loop_domain_side->getOpPtrVector().push_back(
4607 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
4608 op_loop_domain_side->getOpPtrVector().push_back(
4610 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
4611
4612 if (noStretch) {
4613 op_loop_domain_side->getOpPtrVector().push_back(
4614 physicalEquations->returnOpCalculateStretchFromStress(
4616 } else {
4617 op_loop_domain_side->getOpPtrVector().push_back(
4619 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
4620 }
4621
4623
4624 OpPPMap::DataMapMat vec_fields;
4625 vec_fields["HybridDisplacement"] = hybrid_disp;
4626 // note that grad and omega have not trace, so this is only other side value
4627 vec_fields["spatialL2Disp"] = dataAtPts->getSmallWL2AtPts();
4628 vec_fields["Omega"] = dataAtPts->getRotAxisAtPts();
4629 OpPPMap::DataMapMat mat_fields;
4630 mat_fields["PiolaStress"] = dataAtPts->getApproxPAtPts();
4631 mat_fields["HybridDisplacementGradient"] =
4632 dataAtPts->getGradHybridDispAtPts();
4633 OpPPMap::DataMapMat mat_fields_symm;
4634 mat_fields_symm["LogSpatialStretch"] = dataAtPts->getLogStretchTensorAtPts();
4635
4636 post_proc_ptr->getOpPtrVector().push_back(
4637
4638 new OpPPMap(
4639
4640 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4641
4642 {},
4643
4644 vec_fields,
4645
4646 mat_fields,
4647
4648 mat_fields_symm
4649
4650 )
4651
4652 );
4653
4654 if (f_residual) {
4655 auto hybrid_res = boost::make_shared<MatrixDouble>();
4656 post_proc_ptr->getOpPtrVector().push_back(
4658 hybridSpatialDisp, hybrid_res,
4659 SmartPetscObj<Vec>(f_residual, true)));
4661 post_proc_ptr->getOpPtrVector().push_back(
4662
4663 new OpPPMap(
4664
4665 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4666
4667 {},
4668
4669 {{"res_hybrid", hybrid_res}},
4670
4671 {},
4672
4673 {}
4674
4675 )
4676
4677 );
4678 }
4679
4680 post_proc_ptr->setTagsToTransfer(tags_to_transfer);
4681
4682 auto post_proc_begin =
4684 CHKERR DMoFEMPreProcessFiniteElements(dM, post_proc_begin.getFEMethod());
4686 auto post_proc_end = PostProcBrokenMeshInMoabBaseEnd(mField, post_proc_mesh);
4687 CHKERR DMoFEMPostProcessFiniteElements(dM, post_proc_end.getFEMethod());
4688
4689 CHKERR post_proc_end.writeFile(file.c_str());
4690
4692}

◆ projectGeometry()

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

Definition at line 1479 of file EshelbianPlasticity.cpp.

1479 {
1481
1482 Range meshset_ents;
1483 CHKERR mField.get_moab().get_entities_by_handle(meshset, meshset_ents);
1484
1485 auto project_ho_geometry = [&](auto field) {
1487 return mField.loop_dofs(field, ent_method);
1488 };
1489 CHKERR project_ho_geometry(materialH1Positions);
1490
1491 auto get_adj_front_edges = [&](auto &front_edges) {
1492 Range front_crack_nodes;
1493 Range crack_front_edges_with_both_nodes_not_at_front;
1494
1495 if (mField.get_comm_rank() == 0) {
1496 auto &moab = mField.get_moab();
1498 moab.get_connectivity(front_edges, front_crack_nodes, true),
1499 "get_connectivity failed");
1500 Range crack_front_edges;
1501 CHK_MOAB_THROW(moab.get_adjacencies(front_crack_nodes, SPACE_DIM - 2,
1502 false, crack_front_edges,
1503 moab::Interface::UNION),
1504 "get_adjacencies failed");
1505 Range crack_front_edges_nodes;
1506 CHK_MOAB_THROW(moab.get_connectivity(crack_front_edges,
1507 crack_front_edges_nodes, true),
1508 "get_connectivity failed");
1509 // those nodes are hannging nodes
1510 crack_front_edges_nodes =
1511 subtract(crack_front_edges_nodes, front_crack_nodes);
1512 Range crack_front_edges_with_both_nodes_not_at_front;
1514 moab.get_adjacencies(crack_front_edges_nodes, 1, false,
1515 crack_front_edges_with_both_nodes_not_at_front,
1516 moab::Interface::UNION),
1517 "get_adjacencies failed");
1518 // those edges are have one node not at the crack front
1519 crack_front_edges_with_both_nodes_not_at_front = intersect(
1520 crack_front_edges, crack_front_edges_with_both_nodes_not_at_front);
1521 }
1522
1523 front_crack_nodes = send_type(mField, front_crack_nodes, MBVERTEX);
1524 crack_front_edges_with_both_nodes_not_at_front = send_type(
1525 mField, crack_front_edges_with_both_nodes_not_at_front, MBEDGE);
1526
1527 return std::make_pair(boost::make_shared<Range>(front_crack_nodes),
1528 boost::make_shared<Range>(
1529 crack_front_edges_with_both_nodes_not_at_front));
1530 };
1531
1532 crackFaces = boost::make_shared<Range>(
1533 get_range_from_block(mField, "CRACK", SPACE_DIM - 1));
1534 frontEdges =
1535 boost::make_shared<Range>(get_crack_front_edges(mField, *crackFaces));
1536 auto [front_vertices, front_adj_edges] = get_adj_front_edges(*frontEdges);
1537 frontVertices = front_vertices;
1538 frontAdjEdges = front_adj_edges;
1539
1540 MOFEM_LOG("EP", Sev::inform)
1541 << "Number of crack faces: " << crackFaces->size();
1542 MOFEM_LOG("EP", Sev::inform)
1543 << "Number of front edges: " << frontEdges->size();
1544 MOFEM_LOG("EP", Sev::inform)
1545 << "Number of front vertices: " << frontVertices->size();
1546 MOFEM_LOG("EP", Sev::inform)
1547 << "Number of front adjacent edges: " << frontAdjEdges->size();
1548
1549#ifndef NDEBUG
1550 if (crackingOn) {
1551 auto rank = mField.get_comm_rank();
1552 // CHKERR save_range(mField.get_moab(),
1553 // (boost::format("meshset_ents_%d.vtk") % rank).str(),
1554 // meshset_ents);
1556 (boost::format("crack_faces_%d.vtk") % rank).str(),
1557 *crackFaces);
1559 (boost::format("front_edges_%d.vtk") % rank).str(),
1560 *frontEdges);
1561 // CHKERR save_range(mField.get_moab(),
1562 // (boost::format("front_vertices_%d.vtk") % rank).str(),
1563 // *frontVertices);
1564 // CHKERR save_range(mField.get_moab(),
1565 // (boost::format("front_adj_edges_%d.vtk") % rank).str(),
1566 // *frontAdjEdges);
1567 }
1568#endif // NDEBUG
1569
1570 auto set_singular_dofs = [&](auto &front_adj_edges, auto &front_vertices) {
1572 auto &moab = mField.get_moab();
1573
1574 double eps = 1;
1575 double beta = 0;
1576 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "-singularity_eps", &beta,
1577 PETSC_NULLPTR);
1578 MOFEM_LOG("EP", Sev::inform) << "Singularity eps " << beta;
1579 eps -= beta;
1580
1581 auto field_blas = mField.getInterface<FieldBlas>();
1582 auto lambda =
1583 [&](boost::shared_ptr<FieldEntity> field_entity_ptr) -> MoFEMErrorCode {
1585 FTENSOR_INDEX(3, i);
1586 FTENSOR_INDEX(3, j);
1587
1588 auto nb_dofs = field_entity_ptr->getEntFieldData().size();
1589 if (nb_dofs == 0) {
1591 }
1592
1593#ifndef NDEBUG
1594 if (field_entity_ptr->getNbOfCoeffs() != 3)
1596 "Expected 3 coefficients per edge");
1597 if (nb_dofs % 3 != 0)
1599 "Expected multiple of 3 coefficients per edge");
1600#endif // NDEBUG
1601
1602 auto get_conn = [&]() {
1603 int num_nodes;
1604 const EntityHandle *conn;
1605 CHKERR moab.get_connectivity(field_entity_ptr->getEnt(), conn,
1606 num_nodes, false);
1607 return std::make_pair(conn, num_nodes);
1608 };
1609
1610 auto get_dir = [&](auto &&conn_p) {
1611 auto [conn, num_nodes] = conn_p;
1612 double coords[6];
1613 CHKERR moab.get_coords(conn, num_nodes, coords);
1614 FTensor::Tensor1<double, 3> t_edge_dir{coords[3] - coords[0],
1615 coords[4] - coords[1],
1616 coords[5] - coords[2]};
1617 return t_edge_dir;
1618 };
1619
1620 auto get_singularity_dof = [&](auto &&conn_p, auto &&t_edge_dir) {
1621 auto [conn, num_nodes] = conn_p;
1622 FTensor::Tensor1<double, 3> t_singularity_dof{0., 0., 0.};
1623 if (front_vertices.find(conn[0]) != front_vertices.end()) {
1624 t_singularity_dof(i) = t_edge_dir(i) * (-eps);
1625 } else if (front_vertices.find(conn[1]) != front_vertices.end()) {
1626 t_singularity_dof(i) = t_edge_dir(i) * eps;
1627 }
1628 return t_singularity_dof;
1629 };
1630
1631 auto t_singularity_dof =
1632 get_singularity_dof(get_conn(), get_dir(get_conn()));
1633
1634 auto field_data = field_entity_ptr->getEntFieldData();
1636 &field_data[0], &field_data[1], &field_data[2]};
1637
1638 t_dof(i) = t_singularity_dof(i);
1639 ++t_dof;
1640 for (auto n = 1; n < field_data.size() / 3; ++n) {
1641 t_dof(i) = 0;
1642 ++t_dof;
1643 }
1644
1646 };
1647
1648 CHKERR field_blas->fieldLambdaOnEntities(lambda, materialH1Positions,
1649 &front_adj_edges);
1650
1652 };
1653
1654 if (setSingularity)
1655 CHKERR set_singular_dofs(*frontAdjEdges, *frontVertices);
1656
1657 interfaceFaces = boost::make_shared<Range>(
1658 get_range_from_block(mField, "INTERFACE", SPACE_DIM - 1));
1659 MOFEM_LOG("EP", Sev::inform)
1660 << "Number of interface elements: " << interfaceFaces->size();
1661
1663}
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.

◆ projectInternalStress()

MoFEMErrorCode EshelbianCore::projectInternalStress ( const EntityHandle  meshset = 0)
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp, ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

Definition at line 1666 of file EshelbianPlasticity.cpp.

1666 {
1668#ifdef INCLUDE_MBCOUPLER
1669
1670 char mesh_source_file[255] = "source.h5m";
1671 char iterp_tag_name[255] = "INTERNAL_STRESS";
1672
1673 int interp_order = 1;
1674 PetscBool hybrid_interp = PETSC_TRUE;
1675 PetscBool project_internal_stress = PETSC_FALSE;
1676
1677 double toler = 5.e-10;
1678 PetscOptionsBegin(PETSC_COMM_WORLD, "mesh_transfer_", "mesh data transfer",
1679 "none");
1680 CHKERR PetscOptionsString("-source_file", "source mesh file name", "",
1681 "source.h5m", mesh_source_file, 255,
1682 &project_internal_stress);
1683 CHKERR PetscOptionsString("-interp_tag", "interpolation tag name", "",
1684 "INTERNAL_STRESS", iterp_tag_name, 255,
1685 PETSC_NULLPTR);
1686 CHKERR PetscOptionsInt("-interp_order", "interpolation order", "", 0,
1687 &interp_order, PETSC_NULLPTR);
1688 CHKERR PetscOptionsBool("-hybrid_interp", "use hybrid interpolation", "",
1689 hybrid_interp, &hybrid_interp, PETSC_NULLPTR);
1690 PetscOptionsEnd();
1691
1692 MOFEM_LOG_CHANNEL("WORLD");
1693 MOFEM_LOG_TAG("WORLD", "mesh_data_transfer");
1694 if (!project_internal_stress) {
1695 MOFEM_LOG("WORLD", Sev::inform)
1696 << "No internal stress source mesh specified. Skipping projection of "
1697 "internal stress";
1699 }
1700 MOFEM_LOG("WORLD", Sev::inform)
1701 << "Projecting internal stress from source mesh: " << mesh_source_file;
1702
1703 auto &moab = mField.get_moab();
1704
1705 // check if tag exists
1706 Tag old_interp_tag;
1707 auto rval_check_tag = moab.tag_get_handle(iterp_tag_name, old_interp_tag);
1708 if (rval_check_tag == MB_SUCCESS) {
1709 MOFEM_LOG("WORLD", Sev::inform)
1710 << "Deleting existing tag on target mesh: " << iterp_tag_name;
1711 CHKERR moab.tag_delete(old_interp_tag);
1712 }
1713
1714 // make a size-1 communicator for the coupler (rank 0 only)
1715 int world_rank = -1, world_size = -1;
1716 MPI_Comm_rank(PETSC_COMM_WORLD, &world_rank);
1717 MPI_Comm_size(PETSC_COMM_WORLD, &world_size);
1718
1719 Range original_meshset_ents;
1720 CHKERR moab.get_entities_by_handle(0, original_meshset_ents);
1721
1722 MPI_Comm comm_coupler;
1723 if (world_rank == 0) {
1724 MPI_Comm_split(PETSC_COMM_WORLD, 0, 0, &comm_coupler);
1725 } else {
1726 MPI_Comm_split(PETSC_COMM_WORLD, MPI_UNDEFINED, world_rank, &comm_coupler);
1727 }
1728
1729 // build a separate ParallelComm for the coupler (rank 0 only)
1730 ParallelComm *pcomm0 = nullptr;
1731 int pcomm0_id = -1;
1732 if (world_rank == 0) {
1733 pcomm0 = new ParallelComm(&moab, comm_coupler, &pcomm0_id);
1734 }
1735
1736 Coupler::Method method;
1737 switch (interp_order) {
1738 case 0:
1739 method = Coupler::CONSTANT;
1740 break;
1741 case 1:
1742 method = Coupler::LINEAR_FE;
1743 break;
1744 default:
1745 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
1746 "Unsupported interpolation order");
1747 }
1748
1749 int nprocs, rank;
1750 ierr = MPI_Comm_size(PETSC_COMM_WORLD, &nprocs);
1751 CHKERRQ(ierr);
1752 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1753 CHKERRQ(ierr);
1754
1755 // std::string read_opts, write_opts;
1756 // read_opts = "PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION;PARTITION_"
1757 // "DISTRIBUTE;PARALLEL_RESOLVE_SHARED_ENTS";
1758 // if (world_size > 1)
1759 // read_opts += ";PARALLEL_GHOSTS=3.0.1";
1760 // write_opts = (world_size > 1) ? "PARALLEL=WRITE_PART" : "";
1761
1762 // create target mesh from existing meshset
1763 EntityHandle target_root;
1764 CHKERR moab.create_meshset(MESHSET_SET, target_root);
1765 MOFEM_LOG("WORLD", Sev::inform)
1766 << "Creating target mesh from existing meshset";
1767 Range target_meshset_ents;
1768 CHKERR moab.get_entities_by_handle(0, target_meshset_ents);
1769 CHKERR moab.add_entities(target_root, target_meshset_ents);
1770
1771 // variables for tags to be broadcast later
1772 int tag_length;
1773 DataType dtype;
1774 TagType storage;
1775
1776 // load source mesh
1777 Range targ_verts, targ_elems;
1778 if (world_rank == 0) {
1779
1780 EntityHandle source_root;
1781 CHKERR moab.create_meshset(MESHSET_SET, source_root);
1782
1783 MOFEM_LOG("WORLD", Sev::inform) << "Loading source mesh on rank 0";
1784 auto rval_source_mesh = moab.load_file(mesh_source_file, &source_root, "");
1785 if (rval_source_mesh != MB_SUCCESS) {
1786 MOFEM_LOG("WORLD", Sev::warning)
1787 << "Error loading source mesh file: " << mesh_source_file;
1788 }
1789 MOFEM_LOG("WORLD", Sev::inform) << "Source mesh loaded.";
1790
1791 Range src_elems;
1792 CHKERR moab.get_entities_by_dimension(source_root, 3, src_elems);
1793
1794 EntityHandle part_set;
1795 CHKERR pcomm0->create_part(part_set);
1796 CHKERR moab.add_entities(part_set, src_elems);
1797
1798 Range src_elems_part;
1799 CHKERR pcomm0->get_part_entities(src_elems_part, 3);
1800
1801 Tag interp_tag;
1802 CHKERR moab.tag_get_handle(iterp_tag_name, interp_tag);
1803
1804 int interp_tag_len;
1805 CHKERR moab.tag_get_length(interp_tag, interp_tag_len);
1806
1807 if (interp_tag_len != 1 && interp_tag_len != 3 && interp_tag_len != 9) {
1808 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
1809 "Unsupported interpolation tag length: %d", interp_tag_len);
1810 }
1811
1812 // store tag info for later broadcast
1813 tag_length = interp_tag_len;
1814 CHKERR moab.tag_get_data_type(interp_tag, dtype);
1815 CHKERR moab.tag_get_type(interp_tag, storage);
1816
1817 // coupler is collective
1818 Coupler mbc(&moab, pcomm0, src_elems_part, 0, true);
1819
1820 std::vector<double> vpos; // the positions we are interested in
1821 int num_pts = 0;
1822
1823 Range tmp_verts;
1824
1825 // First get all vertices adj to partition entities in target mesh
1826 CHKERR moab.get_entities_by_dimension(target_root, 3, targ_elems);
1827
1828 if (interp_order == 0) {
1829 targ_verts = targ_elems;
1830 } else {
1831 CHKERR moab.get_adjacencies(targ_elems, 0, false, targ_verts,
1832 moab::Interface::UNION);
1833 }
1834
1835 // Then get non-owned verts and subtract
1836 CHKERR pcomm0->get_pstatus_entities(0, PSTATUS_NOT_OWNED, tmp_verts);
1837 targ_verts = subtract(targ_verts, tmp_verts);
1838
1839 // get position of these entities; these are the target points
1840 num_pts = (int)targ_verts.size();
1841 vpos.resize(3 * targ_verts.size());
1842 CHKERR moab.get_coords(targ_verts, &vpos[0]);
1843
1844 // Locate those points in the source mesh
1845 boost::shared_ptr<TupleList> tl_ptr;
1846 tl_ptr = boost::make_shared<TupleList>();
1847 CHKERR mbc.locate_points(&vpos[0], num_pts, 0, toler, tl_ptr.get(), false);
1848
1849 // If some points were not located, we need to process them
1850 auto find_missing_points = [&](Range &targ_verts, int &num_pts,
1851 std::vector<double> &vpos,
1852 Range &missing_verts) {
1854 int missing_pts_num = 0;
1855 int i = 0;
1856 auto vit = targ_verts.begin();
1857 for (; vit != targ_verts.end(); i++) {
1858 if (tl_ptr->vi_rd[3 * i + 1] == -1) {
1859 missing_verts.insert(*vit);
1860 vit = targ_verts.erase(vit);
1861 missing_pts_num++;
1862 } else {
1863 vit++;
1864 }
1865 }
1866
1867 int missing_pts_num_global = 0;
1868 // MPI_Allreduce(&missing_pts_num, &missing_pts_num_global, 1, MPI_INT,
1869 // MPI_SUM, pcomm0);
1870 if (missing_pts_num_global) {
1871 MOFEM_LOG("WORLD", Sev::warning)
1872 << missing_pts_num_global
1873 << " points in target mesh were not located in source mesh. ";
1874 }
1875
1876 if (missing_pts_num) {
1877 num_pts = (int)targ_verts.size();
1878 vpos.resize(3 * targ_verts.size());
1879 CHKERR moab.get_coords(targ_verts, &vpos[0]);
1880 tl_ptr->reset();
1881 CHKERR mbc.locate_points(&vpos[0], num_pts, 0, toler, tl_ptr.get(),
1882 false);
1883 }
1885 };
1886
1887 Range missing_verts;
1888 CHKERR find_missing_points(targ_verts, num_pts, vpos, missing_verts);
1889
1890 std::vector<double> source_data(interp_tag_len * src_elems.size(), 0.0);
1891 std::vector<double> target_data(interp_tag_len * num_pts, 0.0);
1892
1893 CHKERR moab.tag_get_data(interp_tag, src_elems, &source_data[0]);
1894
1895 Tag scalar_tag, adj_count_tag;
1896 double def_scl = 0;
1897 string scalar_tag_name = string(iterp_tag_name) + "_COMP";
1898 CHKERR moab.tag_get_handle(scalar_tag_name.c_str(), 1, MB_TYPE_DOUBLE,
1899 scalar_tag, MB_TAG_CREAT | MB_TAG_DENSE,
1900 &def_scl);
1901
1902 string adj_count_tag_name = "ADJ_COUNT";
1903 double def_adj = 0;
1904 CHKERR moab.tag_get_handle(adj_count_tag_name.c_str(), 1, MB_TYPE_DOUBLE,
1905 adj_count_tag, MB_TAG_CREAT | MB_TAG_DENSE,
1906 &def_adj);
1907
1908 // MBCoupler functionality supports only scalar tags. For the case of
1909 // vector or tensor tags we need to save each component as a scalar tag
1910 auto create_scalar_tags = [&](const Range &src_elems,
1911 const std::vector<double> &source_data,
1912 int itag) {
1914
1915 std::vector<double> source_data_scalar(src_elems.size());
1916 // Populate source_data_scalar
1917 for (int ielem = 0; ielem < src_elems.size(); ielem++) {
1918 source_data_scalar[ielem] = source_data[itag + ielem * interp_tag_len];
1919 }
1920
1921 // Set data on the scalar tag
1922 CHKERR moab.tag_set_data(scalar_tag, src_elems, &source_data_scalar[0]);
1923
1924 if (interp_order == 1) {
1925 // Linear interpolation: compute average value of data on vertices
1926 Range src_verts;
1927 CHKERR moab.get_connectivity(src_elems, src_verts, true);
1928
1929 CHKERR moab.tag_clear_data(scalar_tag, src_verts, &def_scl);
1930 CHKERR moab.tag_clear_data(adj_count_tag, src_verts, &def_adj);
1931
1932 for (auto &tet : src_elems) {
1933 double tet_data = 0;
1934 CHKERR moab.tag_get_data(scalar_tag, &tet, 1, &tet_data);
1935
1936 Range adj_verts;
1937 CHKERR moab.get_connectivity(&tet, 1, adj_verts, true);
1938
1939 std::vector<double> adj_vert_data(adj_verts.size(), 0.0);
1940 std::vector<double> adj_vert_count(adj_verts.size(), 0.0);
1941
1942 CHKERR moab.tag_get_data(scalar_tag, adj_verts, &adj_vert_data[0]);
1943 CHKERR moab.tag_get_data(adj_count_tag, adj_verts,
1944 &adj_vert_count[0]);
1945
1946 for (int ivert = 0; ivert < adj_verts.size(); ivert++) {
1947 adj_vert_data[ivert] += tet_data;
1948 adj_vert_count[ivert] += 1;
1949 }
1950
1951 CHKERR moab.tag_set_data(scalar_tag, adj_verts, &adj_vert_data[0]);
1952 CHKERR moab.tag_set_data(adj_count_tag, adj_verts,
1953 &adj_vert_count[0]);
1954 }
1955
1956 // Reduce tags for the parallel case
1957 std::vector<Tag> tags = {scalar_tag, adj_count_tag};
1958 pcomm0->reduce_tags(tags, tags, MPI_SUM, src_verts);
1959
1960 std::vector<double> src_vert_data(src_verts.size(), 0.0);
1961 std::vector<double> src_vert_adj_count(src_verts.size(), 0.0);
1962
1963 CHKERR moab.tag_get_data(scalar_tag, src_verts, &src_vert_data[0]);
1964 CHKERR moab.tag_get_data(adj_count_tag, src_verts,
1965 &src_vert_adj_count[0]);
1966
1967 for (int ivert = 0; ivert < src_verts.size(); ivert++) {
1968 src_vert_data[ivert] /= src_vert_adj_count[ivert];
1969 }
1970 CHKERR moab.tag_set_data(scalar_tag, src_verts, &src_vert_data[0]);
1971 }
1973 };
1974
1975 for (int itag = 0; itag < interp_tag_len; itag++) {
1976
1977 CHKERR create_scalar_tags(src_elems, source_data, itag);
1978
1979 std::vector<double> target_data_scalar(num_pts, 0.0);
1980 CHKERR mbc.interpolate(method, scalar_tag_name, &target_data_scalar[0],
1981 tl_ptr.get());
1982
1983 for (int ielem = 0; ielem < num_pts; ielem++) {
1984 target_data[itag + ielem * interp_tag_len] = target_data_scalar[ielem];
1985 }
1986 }
1987
1988 // Use original tag
1989 CHKERR moab.tag_set_data(interp_tag, targ_verts, &target_data[0]);
1990
1991 if (missing_verts.size() && (interp_order == 1) && hybrid_interp) {
1992 MOFEM_LOG("WORLD", Sev::warning) << "Using hybrid interpolation for "
1993 "missing points in the target mesh.";
1994 Range missing_adj_elems;
1995 CHKERR moab.get_adjacencies(missing_verts, 3, false, missing_adj_elems,
1996 moab::Interface::UNION);
1997
1998 int num_adj_elems = (int)missing_adj_elems.size();
1999 std::vector<double> vpos_adj_elems;
2000
2001 vpos_adj_elems.resize(3 * missing_adj_elems.size());
2002 CHKERR moab.get_coords(missing_adj_elems, &vpos_adj_elems[0]);
2003
2004 // Locate those points in the source mesh
2005 tl_ptr->reset();
2006 CHKERR mbc.locate_points(&vpos_adj_elems[0], num_adj_elems, 0, toler,
2007 tl_ptr.get(), false);
2008
2009 Range missing_tets;
2010 CHKERR find_missing_points(missing_adj_elems, num_adj_elems,
2011 vpos_adj_elems, missing_tets);
2012 if (missing_tets.size()) {
2013 MOFEM_LOG("WORLD", Sev::warning)
2014 << missing_tets.size()
2015 << "points in target mesh were not located in source mesh. ";
2016 }
2017
2018 std::vector<double> target_data_adj_elems(interp_tag_len * num_adj_elems,
2019 0.0);
2020
2021 for (int itag = 0; itag < interp_tag_len; itag++) {
2022 CHKERR create_scalar_tags(src_elems, source_data, itag);
2023
2024 std::vector<double> target_data_adj_elems_scalar(num_adj_elems, 0.0);
2025 CHKERR mbc.interpolate(method, scalar_tag_name,
2026 &target_data_adj_elems_scalar[0], tl_ptr.get());
2027
2028 for (int ielem = 0; ielem < num_adj_elems; ielem++) {
2029 target_data_adj_elems[itag + ielem * interp_tag_len] =
2030 target_data_adj_elems_scalar[ielem];
2031 }
2032 }
2033
2034 CHKERR moab.tag_set_data(interp_tag, missing_adj_elems,
2035 &target_data_adj_elems[0]);
2036
2037 // FIXME: add implementation for parallel case
2038 for (auto &vert : missing_verts) {
2039 Range adj_elems;
2040 CHKERR moab.get_adjacencies(&vert, 1, 3, false, adj_elems,
2041 moab::Interface::UNION);
2042
2043 std::vector<double> adj_elems_data(adj_elems.size() * interp_tag_len,
2044 0.0);
2045 CHKERR moab.tag_get_data(interp_tag, adj_elems, &adj_elems_data[0]);
2046
2047 std::vector<double> vert_data(interp_tag_len, 0.0);
2048 for (int itag = 0; itag < interp_tag_len; itag++) {
2049 for (int i = 0; i < adj_elems.size(); i++) {
2050 vert_data[itag] += adj_elems_data[i * interp_tag_len + itag];
2051 }
2052 vert_data[itag] /= adj_elems.size();
2053 }
2054 CHKERR moab.tag_set_data(interp_tag, &vert, 1, &vert_data[0]);
2055 }
2056 }
2057
2058 CHKERR moab.tag_delete(scalar_tag);
2059 CHKERR moab.tag_delete(adj_count_tag);
2060 // delete source mesh
2061 Range src_mesh_ents;
2062 CHKERR moab.get_entities_by_handle(source_root, src_mesh_ents);
2063 CHKERR moab.delete_entities(&source_root, 1);
2064 CHKERR moab.delete_entities(src_mesh_ents);
2065 CHKERR moab.delete_entities(&part_set, 1);
2066 }
2067
2068 // broadcast tag info to other processors
2069 MPI_Bcast(&tag_length, 1, MPI_INT, 0, PETSC_COMM_WORLD);
2070 MPI_Bcast(&dtype, 1, MPI_INT, 0, PETSC_COMM_WORLD);
2071 MPI_Bcast(&storage, 1, MPI_INT, 0, PETSC_COMM_WORLD);
2072
2073 // create tag on other processors
2074 Tag interp_tag_all;
2075 unsigned flags =
2076 MB_TAG_CREAT | storage; // e.g., MB_TAG_DENSE or MB_TAG_SPARSE
2077 std::vector<double> def_val(tag_length, 0.);
2078 CHKERR moab.tag_get_handle(iterp_tag_name, tag_length, dtype, interp_tag_all,
2079 flags, def_val.data());
2080 MPI_Barrier(PETSC_COMM_WORLD);
2081
2082 // exchange data for all entity types across all processors
2083 auto vertex_exchange = CommInterface::createEntitiesPetscVector(
2084 mField.get_comm(), mField.get_moab(), 0, tag_length, Sev::inform);
2085 auto edge_exchange = CommInterface::createEntitiesPetscVector(
2086 mField.get_comm(), mField.get_moab(), 1, tag_length, Sev::inform);
2087 auto face_exchange = CommInterface::createEntitiesPetscVector(
2088 mField.get_comm(), mField.get_moab(), 2, tag_length, Sev::inform);
2089 auto volume_exchange = CommInterface::createEntitiesPetscVector(
2090 mField.get_comm(), mField.get_moab(), 3, tag_length, Sev::inform);
2091
2093 mField.get_moab(), vertex_exchange, interp_tag_all);
2095 mField.get_moab(), edge_exchange, interp_tag_all);
2097 mField.get_moab(), face_exchange, interp_tag_all);
2099 mField.get_moab(), volume_exchange, interp_tag_all);
2100
2101 // delete target meshset but not the entities
2102 CHKERR moab.delete_entities(&target_root, 1);
2103
2104#endif // INCLUDE_MBCOUPLER
2106}
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
static MoFEMErrorCode updateEntitiesPetscVector(moab::Interface &moab, EntitiesPetscVector &vec, Tag tag, UpdateGhosts update_gosts=defaultUpdateGhosts)
Exchange data between vector and data.

◆ 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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 926 of file EshelbianPlasticity.cpp.

927 {
928 *iface = const_cast<EshelbianCore *>(this);
929 return 0;
930}

◆ saveOrgCoords()

MoFEMErrorCode EshelbianCore::saveOrgCoords ( )

Definition at line 2431 of file EshelbianFracture.cpp.

2431 {
2433 auto crack_faces =
2434 get_range_from_block(mField, "CRACK_COMPUTED", SPACE_DIM - 1);
2435 Range conn;
2436 CHKERR mField.get_moab().get_connectivity(crack_faces, conn, true);
2437 Range verts;
2438 CHKERR mField.get_moab().get_entities_by_type(0, MBVERTEX, verts);
2439 verts = subtract(verts, conn);
2440 std::vector<double> coords(3 * verts.size());
2441 CHKERR mField.get_moab().get_coords(verts, coords.data());
2442 double def_coords[] = {0., 0., 0.};
2443 Tag th_org_coords;
2444 CHKERR mField.get_moab().tag_get_handle(
2445 "ORG_COORDS", 3, MB_TYPE_DOUBLE, th_org_coords,
2446 MB_TAG_CREAT | MB_TAG_DENSE, def_coords);
2447 CHKERR mField.get_moab().tag_set_data(th_org_coords, verts, coords.data());
2449}

◆ 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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 2693 of file EshelbianPlasticity.cpp.

2696 {
2698
2699 auto bubble_cache =
2700 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0, MatrixDouble());
2701 fe->getUserPolynomialBase() =
2702 boost::make_shared<CGGUserPolynomialBase>(bubble_cache);
2703 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2704 fe->getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions, frontAdjEdges);
2705
2706 // set integration rule
2707 fe->getRuleHook = [](int, int, int) { return -1; };
2708 auto vol_rule_lin = [](int o) { return 2 * o + 1; };
2709 auto vol_rule_no_lin = [](int o) { return 2 * o + (o - 1) + 1; };
2710 auto vol_rule = (SMALL_ROT > 0) ? vol_rule_lin : vol_rule_no_lin;
2711 fe->setRuleHook = SetIntegrationAtFrontVolume(frontVertices, frontAdjEdges,
2712 vol_rule, bubble_cache);
2713 // fe->getRuleHook = VolRule();
2714
2715 if (!dataAtPts) {
2716 dataAtPts =
2717 boost::shared_ptr<DataAtIntegrationPts>(new DataAtIntegrationPts());
2718 dataAtPts->physicsPtr = physicalEquations;
2719 }
2720
2721 // calculate fields values
2722 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
2723 piolaStress, dataAtPts->getApproxPAtPts()));
2724 fe->getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
2725 bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
2726 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorDivergence<3, 3>(
2727 piolaStress, dataAtPts->getDivPAtPts()));
2728
2729 if (noStretch) {
2730 fe->getOpPtrVector().push_back(
2731 physicalEquations->returnOpCalculateStretchFromStress(
2733 } else {
2734 fe->getOpPtrVector().push_back(
2736 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
2737 }
2738
2739 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2740 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
2741 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2742 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
2743 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2744 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
2745
2746 // H1 displacements
2747 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2748 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
2749 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldGradient<3, 3>(
2750 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
2751
2752 // velocities
2753 if (calc_rates) {
2754 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValuesDot<3>(
2755 spatialL2Disp, dataAtPts->getSmallWL2DotAtPts(), MBTET));
2756 if (noStretch) {
2757 } else {
2758 fe->getOpPtrVector().push_back(
2760 stretchTensor, dataAtPts->getLogStretchDotTensorAtPts(), MBTET));
2761 fe->getOpPtrVector().push_back(
2763 stretchTensor, dataAtPts->getGradLogStretchDotTensorAtPts(),
2764 MBTET));
2765 }
2766 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValuesDot<3>(
2767 rotAxis, dataAtPts->getRotAxisDotAtPts(), MBTET));
2768 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldGradientDot<3, 3>(
2769 rotAxis, dataAtPts->getRotAxisGradDotAtPts(), MBTET));
2770
2771 // acceleration
2772 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
2773 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValuesDotDot<3>(
2774 spatialL2Disp, dataAtPts->getSmallWL2DotDotAtPts(), MBTET));
2775 }
2776 }
2777
2778 // variations
2779 if (var_vec.use_count()) {
2780 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
2781 piolaStress, dataAtPts->getVarPiolaPts(), boost::make_shared<double>(1),
2782 var_vec));
2783 fe->getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
2784 bubbleField, dataAtPts->getVarPiolaPts(), boost::make_shared<double>(1),
2785 var_vec, MBMAXTYPE));
2786 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2787 rotAxis, dataAtPts->getVarRotAxisPts(), var_vec, MBTET));
2788 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorDivergence<3, 3>(
2789 piolaStress, dataAtPts->getDivVarPiolaPts(), var_vec));
2790 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2791 spatialL2Disp, dataAtPts->getVarWL2Pts(), var_vec, MBTET));
2792
2793 if (noStretch) {
2794 fe->getOpPtrVector().push_back(
2795 physicalEquations->returnOpCalculateVarStretchFromStress(
2797 } else {
2798 fe->getOpPtrVector().push_back(
2800 stretchTensor, dataAtPts->getVarLogStreachPts(), var_vec, MBTET));
2801 }
2802 }
2803
2804 // calculate other derived quantities
2805 fe->getOpPtrVector().push_back(new OpCalculateRotationAndSpatialGradient(
2806 dataAtPts, ((do_rhs || do_lhs) && calc_rates) ? alphaOmega : 0.));
2807
2808 // evaluate integration points
2809 if (noStretch) {
2810 } else {
2811 fe->getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
2812 tag, do_rhs, do_lhs, dataAtPts, physicalEquations));
2813 }
2814
2816}
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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp, ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

Definition at line 4003 of file EshelbianPlasticity.cpp.

4003 {
4005
4006 auto set_block = [&](auto name, int dim) {
4007 std::map<int, Range> map;
4008 auto set_tag_impl = [&](auto name) {
4010 auto mesh_mng = mField.getInterface<MeshsetsManager>();
4011 auto bcs = mesh_mng->getCubitMeshsetPtr(
4012
4013 std::regex((boost::format("%s(.*)") % name).str())
4014
4015 );
4016 for (auto bc : bcs) {
4017 Range r;
4018 CHKERR bc->getMeshsetIdEntitiesByDimension(mField.get_moab(), dim, r,
4019 true);
4020 map[bc->getMeshsetId()] = r;
4021 MOFEM_LOG("EP", Sev::inform)
4022 << "Block " << name << " id " << bc->getMeshsetId() << " has "
4023 << r.size() << " entities";
4024 }
4026 };
4027
4028 CHKERR set_tag_impl(name);
4029
4030 return std::make_pair(name, map);
4031 };
4032
4033 auto set_skin = [&](auto &&map) {
4034 for (auto &m : map.second) {
4035 auto s = filter_true_skin(mField, get_skin(mField, m.second));
4036 m.second.swap(s);
4037 MOFEM_LOG("EP", Sev::inform)
4038 << "Skin for block " << map.first << " id " << m.first << " has "
4039 << m.second.size() << " entities";
4040 }
4041 return map;
4042 };
4043
4044 auto set_tag = [&](auto &&map) {
4045 Tag th;
4046 auto name = map.first;
4047 int def_val[] = {-1};
4049 mField.get_moab().tag_get_handle(name, 1, MB_TYPE_INTEGER, th,
4050 MB_TAG_SPARSE | MB_TAG_CREAT, def_val),
4051 "create tag");
4052 for (auto &m : map.second) {
4053 int id = m.first;
4054 CHK_MOAB_THROW(mField.get_moab().tag_clear_data(th, m.second, &id),
4055 "clear tag");
4056 }
4057 return th;
4058 };
4059
4060 listTagsToTransfer.push_back(set_tag(set_skin(set_block("BODY", 3))));
4061 listTagsToTransfer.push_back(set_tag(set_skin(set_block("MAT_ELASTIC", 3))));
4062 listTagsToTransfer.push_back(
4063 set_tag(set_skin(set_block("MAT_NEOHOOKEAN", 3))));
4064 listTagsToTransfer.push_back(set_tag(set_block("CONTACT", 2)));
4065
4067}
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< ForcesAndSourcesCore > &  fe_contact_tree)
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 3558 of file EshelbianPlasticity.cpp.

3562 {
3564 fe_contact_tree = createContactDetectionFiniteElement(*this);
3566}
boost::shared_ptr< ForcesAndSourcesCore > createContactDetectionFiniteElement(EshelbianCore &ep)
Create a Contact Tree finite element.

◆ setElasticElementOps()

MoFEMErrorCode EshelbianCore::setElasticElementOps ( const int  tag)
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp, ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

Definition at line 3568 of file EshelbianPlasticity.cpp.

3568 {
3570
3571 // Add contact operators. Note that only for rhs. THe lhs is assembled with
3572 // volume element, to enable schur complement evaluation.
3574
3577
3578 auto adj_cache =
3579 boost::make_shared<ForcesAndSourcesCore::UserDataOperator::AdjCache>();
3580
3581 auto get_op_contact_bc = [&]() {
3583 auto op_loop_side = new OpLoopSide<SideEle>(
3584 mField, contactElement, SPACE_DIM - 1, Sev::noisy, adj_cache);
3585 return op_loop_side;
3586 };
3587
3589}
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 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< ForcesAndSourcesCore > &fe_contact_tree)
ElementsAndOps< SPACE_DIM >::SideEle SideEle
Definition plastic.cpp:61

◆ setElasticElementToTs()

MoFEMErrorCode EshelbianCore::setElasticElementToTs ( DM  dm)
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp, ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

Definition at line 3591 of file EshelbianPlasticity.cpp.

3591 {
3593 boost::shared_ptr<FEMethod> null;
3594
3595 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
3596
3598 null);
3600 null);
3602 null);
3604 null);
3605
3606 } else {
3608 null);
3610 null);
3612 null);
3614 null);
3615 }
3616
3618}
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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 3391 of file EshelbianPlasticity.cpp.

3394 {
3396
3397 fe_rhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
3398 fe_lhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
3399
3400 // set integration rule
3401 // fe_rhs->getRuleHook = [](int, int, int p) { return 2 * (p + 1); };
3402 // fe_lhs->getRuleHook = [](int, int, int p) { return 2 * (p + 1); };
3403 fe_rhs->getRuleHook = [](int, int, int) { return -1; };
3404 fe_lhs->getRuleHook = [](int, int, int) { return -1; };
3405 fe_rhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3406 fe_lhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3407
3408 CHKERR
3409 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3410 fe_rhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
3411 CHKERR
3412 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3413 fe_lhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
3414
3415 if (add_elastic) {
3416
3417 auto get_broken_op_side = [this](auto &pip) {
3418 using EleOnSide =
3420 using SideEleOp = EleOnSide::UserDataOperator;
3421 // Iterate over domain FEs adjacent to boundary.
3422 auto broken_data_ptr =
3423 boost::make_shared<std::vector<BrokenBaseSideData>>();
3424 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
3425 auto op_loop_domain_side = new OpLoopSide<EleOnSide>(
3426 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
3427 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3428 boost::make_shared<CGGUserPolynomialBase>();
3429 CHKERR
3430 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3431 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3433 op_loop_domain_side->getOpPtrVector().push_back(
3434 new OpGetBrokenBaseSideData<SideEleOp>(piolaStress, broken_data_ptr));
3435 boost::shared_ptr<double> piola_scale_ptr(new double);
3436 op_loop_domain_side->getOpPtrVector().push_back(
3437 physicalEquations->returnOpSetScale(piola_scale_ptr,
3439 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
3440 op_loop_domain_side->getOpPtrVector().push_back(
3442 flux_mat_ptr));
3443 op_loop_domain_side->getOpPtrVector().push_back(
3444 new OpSetFlux<SideEleOp>(broken_data_ptr, flux_mat_ptr));
3445 pip.push_back(op_loop_domain_side);
3446 return std::make_tuple(broken_data_ptr, piola_scale_ptr);
3447 };
3448
3449 auto set_rhs = [&]() {
3451
3452 auto [broken_data_ptr, piola_scale_ptr] =
3453 get_broken_op_side(fe_rhs->getOpPtrVector());
3454
3455 fe_rhs->getOpPtrVector().push_back(
3456 new OpDispBc(broken_data_ptr, bcSpatialDispVecPtr, timeScaleMap));
3457 fe_rhs->getOpPtrVector().push_back(new OpAnalyticalDispBc(
3459 timeScaleMap));
3460 fe_rhs->getOpPtrVector().push_back(new OpRotationBc(
3461 broken_data_ptr, bcSpatialRotationVecPtr, timeScaleMap));
3462
3463 fe_rhs->getOpPtrVector().push_back(
3465 piola_scale_ptr, timeScaleMap));
3466 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
3467 // if you push gradient of L2 base to physical element, it will not work.
3468 fe_rhs->getOpPtrVector().push_back(
3470 hybridSpatialDisp, hybrid_grad_ptr));
3471 fe_rhs->getOpPtrVector().push_back(new OpBrokenPressureBc(
3473 hybrid_grad_ptr, timeScaleMap));
3474 fe_rhs->getOpPtrVector().push_back(new OpBrokenAnalyticalTractionBc(
3476 timeScaleMap));
3477
3478 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3479 fe_rhs->getOpPtrVector().push_back(
3481 hybrid_ptr));
3482 fe_rhs->getOpPtrVector().push_back(new OpNormalDispRhsBc(
3483 hybridSpatialDisp, hybrid_ptr, broken_data_ptr,
3485
3486 auto get_normal_disp_bc_faces = [&]() {
3487 auto faces =
3488 get_range_from_block(mField, "NORMAL_DISPLACEMENT", SPACE_DIM - 1);
3489 return boost::make_shared<Range>(faces);
3490 };
3491
3492 using BoundaryEle =
3494 using BdyEleOp = BoundaryEle::UserDataOperator;
3496 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
3497 fe_rhs->getOpPtrVector().push_back(new OpC_dBroken(
3498 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0),
3499 get_normal_disp_bc_faces()));
3500
3502 };
3503
3504 auto set_lhs = [&]() {
3506
3507 auto [broken_data_ptr, piola_scale_ptr] =
3508 get_broken_op_side(fe_lhs->getOpPtrVector());
3509
3510 fe_lhs->getOpPtrVector().push_back(new OpNormalDispLhsBc_dU(
3512 fe_lhs->getOpPtrVector().push_back(new OpNormalDispLhsBc_dP(
3514 timeScaleMap));
3515
3516 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
3517 // if you push gradient of L2 base to physical element, it will not work.
3518 fe_lhs->getOpPtrVector().push_back(
3520 hybridSpatialDisp, hybrid_grad_ptr));
3521 fe_lhs->getOpPtrVector().push_back(new OpBrokenPressureBcLhs_dU(
3523 timeScaleMap));
3524
3525 auto get_normal_disp_bc_faces = [&]() {
3526 auto faces =
3527 get_range_from_block(mField, "NORMAL_DISPLACEMENT", SPACE_DIM - 1);
3528 return boost::make_shared<Range>(faces);
3529 };
3530
3531 using BoundaryEle =
3533 using BdyEleOp = BoundaryEle::UserDataOperator;
3535 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
3536 fe_lhs->getOpPtrVector().push_back(new OpC(
3537 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0),
3538 true, true, get_normal_disp_bc_faces()));
3539
3541 };
3542
3543 CHKERR set_rhs();
3544 CHKERR set_lhs();
3545 }
3546
3548}
@ GAUSS
Gaussian quadrature integration.
constexpr AssemblyType A
Apply rotation boundary condition.
BoundaryEle::UserDataOperator BdyEleOp

◆ setFaceInterfaceOps()

MoFEMErrorCode EshelbianCore::setFaceInterfaceOps ( const bool  add_elastic,
const bool  add_material,
boost::shared_ptr< FaceElementForcesAndSourcesCore > &  fe_rhs,
boost::shared_ptr< FaceElementForcesAndSourcesCore > &  fe_lhs 
)

◆ setNewFrontCoordinates()

MoFEMErrorCode EshelbianCore::setNewFrontCoordinates ( )

Definition at line 1659 of file EshelbianFracture.cpp.

1659 {
1661
1662 if (!maxMovedFaces)
1664
1665 Tag th_front_position;
1666 auto rval =
1667 mField.get_moab().tag_get_handle("FrontPosition", th_front_position);
1668 if (rval == MB_SUCCESS && maxMovedFaces) {
1669 Range verts;
1670 CHKERR mField.get_moab().get_connectivity(*maxMovedFaces, verts, true);
1671 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(verts);
1672 std::vector<double> coords(3 * verts.size());
1673 CHKERR mField.get_moab().get_coords(verts, coords.data());
1674 std::vector<double> pos(3 * verts.size());
1675 CHKERR mField.get_moab().tag_get_data(th_front_position, verts, pos.data());
1676 for (int i = 0; i != 3 * verts.size(); ++i) {
1677 coords[i] += pos[i];
1678 }
1679 CHKERR mField.get_moab().set_coords(verts, coords.data());
1680 double zero[] = {0., 0., 0.};
1681 CHKERR mField.get_moab().tag_clear_data(th_front_position, verts, zero);
1682 }
1683
1684#ifndef NDEBUG
1685 constexpr bool debug = false;
1686 if (debug) {
1687
1689 mField.get_moab(),
1690 "set_coords_faces_" +
1691 boost::lexical_cast<std::string>(mField.get_comm_rank()) + ".vtk",
1692 *maxMovedFaces);
1693 }
1694#endif
1696}

◆ 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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 2818 of file EshelbianPlasticity.cpp.

2821 {
2823
2824 /** Contact requires that body is marked */
2825 auto get_body_range = [this](auto name, int dim) {
2826 std::map<int, Range> map;
2827
2828 for (auto m_ptr :
2829 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
2830
2831 (boost::format("%s(.*)") % name).str()
2832
2833 ))
2834
2835 ) {
2836 Range ents;
2837 CHK_MOAB_THROW(m_ptr->getMeshsetIdEntitiesByDimension(mField.get_moab(),
2838 dim, ents, true),
2839 "by dim");
2840 map[m_ptr->getMeshsetId()] = ents;
2841 }
2842
2843 return map;
2844 };
2845
2846 constexpr bool stab_tau_dot_variant = false;
2847
2848 auto local_tau_sacale = boost::make_shared<double>(1.0);
2849 using BoundaryEle =
2851 using BdyEleOp = BoundaryEle::UserDataOperator;
2852 auto set_scale_op = new BdyEleOp(NOSPACE, BdyEleOp::OPSPACE);
2853 set_scale_op->doWorkRhsHook =
2854 [this,
2855 local_tau_sacale](DataOperator *raw_op_ptr, int side, EntityType type,
2858 auto op_ptr = static_cast<BdyEleOp *>(raw_op_ptr);
2859 auto h = std::sqrt(op_ptr->getFTensor1Normal().l2());
2860 *local_tau_sacale = (alphaTau / h);
2862 };
2863
2864 auto not_interface_face = [this](FEMethod *fe_method_ptr) {
2865 auto ent = fe_method_ptr->getFEEntityHandle();
2866 if (
2867
2868 (interfaceFaces->find(ent) != interfaceFaces->end())
2869
2870 || (crackFaces->find(ent) != crackFaces->end())
2871
2872 ) {
2873 return false;
2874 };
2875 return true;
2876 };
2877
2878 // Right hand side
2879 fe_rhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
2880 CHKERR setBaseVolumeElementOps(tag, true, false, true, SmartPetscObj<Vec>(),
2881 fe_rhs);
2882
2883 // elastic
2884 if (add_elastic) {
2885
2886 fe_rhs->getOpPtrVector().push_back(
2888 fe_rhs->getOpPtrVector().push_back(
2890 if (noStretch) {
2891 // do nothing - no stretch approximation
2892 } else {
2893 if (!internalStressTagName.empty()) {
2894 switch (internalStressInterpOrder) {
2895 case 0:
2896 fe_rhs->getOpPtrVector().push_back(
2898 break;
2899 case 1:
2900 fe_rhs->getOpPtrVector().push_back(
2902 break;
2903 default:
2904 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
2905 "Unsupported internal stress interpolation order %d",
2907 }
2908 // set default time scaling for interal stresses to constant
2909 TimeScale::ScalingFun def_scaling_fun = [](double time) { return 1; };
2910 auto ts_internal_stress =
2911 boost::make_shared<DynamicRelaxationTimeScale>(
2912 "internal_stress_history.txt", false, def_scaling_fun);
2913 if (internalStressVoigt) {
2914 fe_rhs->getOpPtrVector().push_back(
2916 stretchTensor, dataAtPts, ts_internal_stress));
2917 } else {
2918 fe_rhs->getOpPtrVector().push_back(
2920 stretchTensor, dataAtPts, ts_internal_stress));
2921 }
2922 }
2923 if (auto op = physicalEquations->returnOpSpatialPhysicalExternalStrain(
2925 fe_rhs->getOpPtrVector().push_back(op);
2926 } else if (externalStrainVecPtr && !externalStrainVecPtr->empty()) {
2927 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
2928 "OpSpatialPhysicalExternalStrain not implemented for this "
2929 "material");
2930 }
2931
2932 fe_rhs->getOpPtrVector().push_back(
2933 physicalEquations->returnOpSpatialPhysical(stretchTensor, dataAtPts,
2934 alphaU));
2935 }
2936 fe_rhs->getOpPtrVector().push_back(
2938 fe_rhs->getOpPtrVector().push_back(
2940 fe_rhs->getOpPtrVector().push_back(
2942
2943 auto set_hybridisation_rhs = [&](auto &pip) {
2945
2946 using BoundaryEle =
2948 using EleOnSide =
2950 using SideEleOp = EleOnSide::UserDataOperator;
2951 using BdyEleOp = BoundaryEle::UserDataOperator;
2952
2953 // First: Iterate over skeleton FEs adjacent to Domain FEs
2954 // Note: BoundaryEle, i.e. uses skeleton interation rule
2955 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
2956 mField, skeletonElement, SPACE_DIM - 1, Sev::noisy);
2957 // op_loop_skeleton_side->getSideFEPtr()->getRuleHook = FaceRule();
2958 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
2959 return -1;
2960 };
2961 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
2962 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
2963
2964 CHKERR EshelbianPlasticity::
2965 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2966 op_loop_skeleton_side->getOpPtrVector(), {L2},
2968
2969 // Second: Iterate over domain FEs adjacent to skelton, particularly one
2970 // domain element.
2971 auto broken_data_ptr =
2972 boost::make_shared<std::vector<BrokenBaseSideData>>();
2973 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
2974 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
2975 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
2976 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2977 boost::make_shared<CGGUserPolynomialBase>();
2978 CHKERR
2979 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2980 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2982 op_loop_domain_side->getOpPtrVector().push_back(
2983 new OpGetBrokenBaseSideData<SideEleOp>(piolaStress, broken_data_ptr));
2984 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
2985 op_loop_domain_side->getOpPtrVector().push_back(
2987 flux_mat_ptr));
2988 op_loop_domain_side->getOpPtrVector().push_back(
2989 new OpSetFlux<SideEleOp>(broken_data_ptr, flux_mat_ptr));
2990
2991 // Assemble on skeleton
2992 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
2994 GAUSS>::OpBrokenSpaceConstrainDHybrid<SPACE_DIM>;
2996 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
2997 op_loop_skeleton_side->getOpPtrVector().push_back(new OpC_dHybrid(
2998 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0)));
2999 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3000 op_loop_skeleton_side->getOpPtrVector().push_back(
3002 hybrid_ptr));
3003 op_loop_skeleton_side->getOpPtrVector().push_back(new OpC_dBroken(
3004 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0)));
3005
3006 // Add skeleton to domain pipeline
3007 pip.push_back(op_loop_skeleton_side);
3008
3010 };
3011
3012 auto set_tau_stabilsation_rhs = [&](auto &pip, auto side_fe_name,
3013 auto hybrid_field) {
3015
3016 using BoundaryEle =
3018 using EleOnSide =
3020 using SideEleOp = EleOnSide::UserDataOperator;
3021 using BdyEleOp = BoundaryEle::UserDataOperator;
3022
3023 // First: Iterate over skeleton FEs adjacent to Domain FEs
3024 // Note: BoundaryEle, i.e. uses skeleton interation rule
3025 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
3026 mField, side_fe_name, SPACE_DIM - 1, Sev::noisy);
3027 // op_loop_skeleton_side->getSideFEPtr()->getRuleHook = FaceRule();
3028 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3029 return -1;
3030 };
3031 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3032 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3033 CHKERR EshelbianPlasticity::
3034 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3035 op_loop_skeleton_side->getOpPtrVector(), {L2},
3037
3038 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
3039 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
3040 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3041 boost::make_shared<CGGUserPolynomialBase>();
3042 CHKERR
3043 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3044 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3046
3047 // Add stabilization operator
3048 auto broken_disp_data_ptr =
3049 boost::make_shared<std::vector<BrokenBaseSideData>>();
3050 op_loop_domain_side->getOpPtrVector().push_back(
3052 broken_disp_data_ptr));
3053 auto disp_mat_ptr = boost::make_shared<MatrixDouble>();
3054 if (stab_tau_dot_variant) {
3055 op_loop_domain_side->getOpPtrVector().push_back(
3057 disp_mat_ptr));
3058 } else {
3059 op_loop_domain_side->getOpPtrVector().push_back(
3061 disp_mat_ptr));
3062 }
3063 // Set diag fluxes on skeleton side
3064 op_loop_domain_side->getOpPtrVector().push_back(
3065 new OpSetFlux<SideEleOp>(broken_disp_data_ptr, disp_mat_ptr));
3066
3067 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3068 op_loop_skeleton_side->getOpPtrVector().push_back(set_scale_op);
3069
3070 // Add stabilization Ugamma Ugamma skeleton
3071 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3072 if (stab_tau_dot_variant) {
3073 op_loop_skeleton_side->getOpPtrVector().push_back(
3075 hybrid_ptr));
3076 } else {
3077 op_loop_skeleton_side->getOpPtrVector().push_back(
3079 hybrid_ptr));
3080 }
3081
3082 // Diag u_gamma - u_gamma faces
3083 op_loop_skeleton_side->getOpPtrVector().push_back(
3085 hybrid_field, hybrid_ptr,
3086 [local_tau_sacale, broken_disp_data_ptr](double, double, double) {
3087 return broken_disp_data_ptr->size() * (*local_tau_sacale);
3088 }));
3089 // Diag L2 - L2 volumes
3090 op_loop_skeleton_side->getOpPtrVector().push_back(
3092 broken_disp_data_ptr, [local_tau_sacale](double, double, double) {
3093 return (*local_tau_sacale);
3094 }));
3095 // Off-diag Ugamma - L2
3096 op_loop_skeleton_side->getOpPtrVector().push_back(
3098 hybrid_field, broken_disp_data_ptr,
3099 [local_tau_sacale](double, double, double) {
3100 return -(*local_tau_sacale);
3101 }));
3102 // Off-diag L2 - Ugamma
3103 op_loop_skeleton_side->getOpPtrVector().push_back(
3105 broken_disp_data_ptr, hybrid_ptr,
3106 [local_tau_sacale](double, double, double) {
3107 return -(*local_tau_sacale);
3108 }));
3109
3110 // Add skeleton to domain pipeline
3111 pip.push_back(op_loop_skeleton_side);
3112
3114 };
3115
3116 auto set_contact_rhs = [&](auto &pip) {
3117 return pushContactOpsRhs(*this, contactTreeRhs, pip);
3118 };
3119
3120 auto set_cohesive_rhs = [&](auto &pip) {
3121 return pushCohesiveOpsRhs(
3122 *this,
3123 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges,
3124 [](int p) { return 2 * (p + 1) + 1; }),
3125 interfaceFaces, pip);
3126 };
3127
3128 CHKERR set_hybridisation_rhs(fe_rhs->getOpPtrVector());
3129 CHKERR set_contact_rhs(fe_rhs->getOpPtrVector());
3130 if (alphaTau > 0.0) {
3131 CHKERR set_tau_stabilsation_rhs(fe_rhs->getOpPtrVector(), skeletonElement,
3133 CHKERR set_tau_stabilsation_rhs(fe_rhs->getOpPtrVector(), contactElement,
3134 contactDisp);
3135 }
3136 if (intefaceCrack == PETSC_TRUE) {
3137 CHKERR set_cohesive_rhs(fe_rhs->getOpPtrVector());
3138 }
3139
3140 // Body forces
3141 using BodyNaturalBC =
3143 Assembly<PETSC>::LinearForm<GAUSS>;
3144 using OpBodyForce =
3145 BodyNaturalBC::OpFlux<NaturalMeshsetType<BLOCKSET>, 1, 3>;
3146
3147 auto body_time_scale =
3148 boost::make_shared<DynamicRelaxationTimeScale>("body_force.txt");
3149 CHKERR BodyNaturalBC::AddFluxToPipeline<OpBodyForce>::add(
3150 fe_rhs->getOpPtrVector(), mField, spatialL2Disp, {body_time_scale},
3151 "BODY_FORCE", Sev::inform);
3152 }
3153
3154 // Left hand side
3155 fe_lhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
3156 CHKERR setBaseVolumeElementOps(tag, true, true, true, SmartPetscObj<Vec>(),
3157 fe_lhs);
3158
3159 // elastic
3160 if (add_elastic) {
3161
3162 if (noStretch) {
3163 fe_lhs->getOpPtrVector().push_back(
3165 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dBubble_dP(
3167 fe_lhs->getOpPtrVector().push_back(
3169 dataAtPts));
3170 } else {
3171 fe_lhs->getOpPtrVector().push_back(
3172 physicalEquations->returnOpSpatialPhysical_du_du(
3174 fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_dP(
3176 fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_dBubble(
3178 fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_domega(
3180 symmetrySelector == SYMMETRIC ? true : false));
3181 }
3182
3183 fe_lhs->getOpPtrVector().push_back(new OpSpatialEquilibrium_dw_dP(
3185 fe_lhs->getOpPtrVector().push_back(new OpSpatialEquilibrium_dw_dw(
3187
3188 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dP_domega(
3190 symmetrySelector == SYMMETRIC ? true : false));
3191 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dBubble_domega(
3193 symmetrySelector == SYMMETRIC ? true : false));
3194
3195 if (symmetrySelector > SYMMETRIC) {
3196 if (!noStretch) {
3197 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_du(
3198 rotAxis, stretchTensor, dataAtPts, false));
3199 }
3200 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_dP(
3201 rotAxis, piolaStress, dataAtPts, false));
3202 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_dBubble(
3203 rotAxis, bubbleField, dataAtPts, false));
3204 }
3205 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_domega(
3207
3208 auto set_hybridisation_lhs = [&](auto &pip) {
3210
3211 using BoundaryEle =
3213 using EleOnSide =
3215 using SideEleOp = EleOnSide::UserDataOperator;
3216 using BdyEleOp = BoundaryEle::UserDataOperator;
3217
3218 // First: Iterate over skeleton FEs adjacent to Domain FEs
3219 // Note: BoundaryEle, i.e. uses skeleton interation rule
3220 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
3221 mField, skeletonElement, SPACE_DIM - 1, Sev::noisy);
3222 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3223 return -1;
3224 };
3225 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3226 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3227 CHKERR EshelbianPlasticity::
3228 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3229 op_loop_skeleton_side->getOpPtrVector(), {L2},
3231
3232 // Second: Iterate over domain FEs adjacent to skelton, particularly one
3233 // domain element.
3234 auto broken_data_ptr =
3235 boost::make_shared<std::vector<BrokenBaseSideData>>();
3236 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
3237 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
3238 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
3239 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3240 boost::make_shared<CGGUserPolynomialBase>();
3241 CHKERR
3242 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3243 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3245 op_loop_domain_side->getOpPtrVector().push_back(
3246 new OpGetBrokenBaseSideData<SideEleOp>(piolaStress, broken_data_ptr));
3247
3248 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3250 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
3251 op_loop_skeleton_side->getOpPtrVector().push_back(
3252 new OpC(hybridSpatialDisp, broken_data_ptr,
3253 boost::make_shared<double>(1.0), true, false));
3254
3255 pip.push_back(op_loop_skeleton_side);
3256
3258 };
3259
3260 auto set_tau_stabilsation_lhs = [&](auto &pip, auto side_fe_name,
3261 auto hybrid_field) {
3263
3264 using BoundaryEle =
3266 using EleOnSide =
3268 using SideEleOp = EleOnSide::UserDataOperator;
3269 using BdyEleOp = BoundaryEle::UserDataOperator;
3270
3271 // First: Iterate over skeleton FEs adjacent to Domain FEs
3272 // Note: BoundaryEle, i.e. uses skeleton interation rule
3273 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
3274 mField, side_fe_name, SPACE_DIM - 1, Sev::noisy);
3275 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3276 return -1;
3277 };
3278 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3279 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3280 CHKERR EshelbianPlasticity::
3281 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3282 op_loop_skeleton_side->getOpPtrVector(), {L2},
3284
3285 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
3286 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
3287 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
3288 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3289 boost::make_shared<CGGUserPolynomialBase>();
3290 CHKERR
3291 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3292 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3294
3295 auto broken_disp_data_ptr =
3296 boost::make_shared<std::vector<BrokenBaseSideData>>();
3297 op_loop_domain_side->getOpPtrVector().push_back(
3299 broken_disp_data_ptr));
3300 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3301 op_loop_skeleton_side->getOpPtrVector().push_back(set_scale_op);
3302
3303 auto time_shift = [](const FEMethod *fe_ptr) { return fe_ptr->ts_a; };
3304
3305 // Diag Ugamma-Ugamma skeleton
3306 op_loop_skeleton_side->getOpPtrVector().push_back(new OpMassVectorFace(
3307 hybrid_field, hybrid_field,
3308 [local_tau_sacale, broken_disp_data_ptr](double, double, double) {
3309 return broken_disp_data_ptr->size() * (*local_tau_sacale);
3310 }));
3311 if (stab_tau_dot_variant) {
3312 static_cast<OpMassVectorFace &>(
3313 op_loop_skeleton_side->getOpPtrVector().back())
3314 .feScalingFun = time_shift;
3315 }
3316 // Diag L2-L2 volumes
3317 op_loop_skeleton_side->getOpPtrVector().push_back(
3319 broken_disp_data_ptr, [local_tau_sacale](double, double, double) {
3320 return (*local_tau_sacale);
3321 }));
3322 if (stab_tau_dot_variant) {
3323 static_cast<OpBrokenBaseBrokenBase &>(
3324 op_loop_skeleton_side->getOpPtrVector().back())
3325 .feScalingFun = time_shift;
3326 }
3327 // Off-diag Ugamma - L2
3328 op_loop_skeleton_side->getOpPtrVector().push_back(
3330 hybrid_field, broken_disp_data_ptr,
3331 [local_tau_sacale](double, double, double) {
3332 return -(*local_tau_sacale);
3333 },
3334 false, false));
3335 if (stab_tau_dot_variant) {
3336 static_cast<OpHyrbridBaseBrokenBase &>(
3337 op_loop_skeleton_side->getOpPtrVector().back())
3338 .feScalingFun = time_shift;
3339 }
3340
3341 // Off-diag L2 - Ugamma
3342 op_loop_skeleton_side->getOpPtrVector().push_back(
3344 hybrid_field, broken_disp_data_ptr,
3345 [local_tau_sacale](double, double, double) {
3346 return -(*local_tau_sacale);
3347 },
3348 true, true));
3349 if (stab_tau_dot_variant) {
3350 static_cast<OpHyrbridBaseBrokenBase &>(
3351 op_loop_skeleton_side->getOpPtrVector().back())
3352 .feScalingFun = time_shift;
3353 }
3354
3355 pip.push_back(op_loop_skeleton_side);
3356
3358 };
3359
3360 auto set_contact_lhs = [&](auto &pip) {
3361 return pushContactOpsLhs(*this, contactTreeRhs, pip);
3362 };
3363
3364 auto set_cohesive_lhs = [&](auto &pip) {
3365 return pushCohesiveOpsLhs(
3366 *this,
3367 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges,
3368 [](int p) { return 2 * (p + 1) + 1; }),
3369 interfaceFaces, pip);
3370 };
3371
3372 CHKERR set_hybridisation_lhs(fe_lhs->getOpPtrVector());
3373 CHKERR set_contact_lhs(fe_lhs->getOpPtrVector());
3374 if (alphaTau > 0.0) {
3375 CHKERR set_tau_stabilsation_lhs(fe_lhs->getOpPtrVector(), skeletonElement,
3377 CHKERR set_tau_stabilsation_lhs(fe_lhs->getOpPtrVector(), contactElement,
3378 contactDisp);
3379 }
3380 if (intefaceCrack == PETSC_TRUE) {
3381 CHKERR set_cohesive_lhs(fe_lhs->getOpPtrVector());
3382 }
3383 }
3384
3385 if (add_material) {
3386 }
3387
3389}
FormsIntegrators< FaceElementForcesAndSourcesCore::UserDataOperator >::Assembly< A >::BiLinearForm< GAUSS >::OpMass< 1, SPACE_DIM > OpMassVectorFace
@ NOSPACE
Definition definitions.h:83
MoFEMErrorCode pushContactOpsRhs(EshelbianCore &ep, boost::shared_ptr< ForcesAndSourcesCore > contact_tree_ptr, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip)
Push contact operations to the right-hand side.
MoFEMErrorCode pushContactOpsLhs(EshelbianCore &ep, boost::shared_ptr< ForcesAndSourcesCore > contact_tree_ptr, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip)
Push contact operations to the left-hand side.
MoFEMErrorCode pushCohesiveOpsLhs(EshelbianCore &ep, ForcesAndSourcesCore::GaussHookFun set_integration_at_front_face, boost::shared_ptr< Range > interface_range_ptr, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip)
MoFEMErrorCode pushCohesiveOpsRhs(EshelbianCore &ep, ForcesAndSourcesCore::GaussHookFun set_integration_at_front_face, boost::shared_ptr< Range > interface_range_ptr, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip)
double h
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)
base operator to do operations at Gauss Pt. level
Natural boundary conditions.
Definition Natural.hpp:57
Operator for broken loop side.

◆ solveCohesiveCrackGrowth()

MoFEMErrorCode EshelbianCore::solveCohesiveCrackGrowth ( TS  ts,
Vec  x,
int  start_step,
double  start_time 
)

Solve cohesive crack growth problem.

Parameters
ts
x
Returns
* MoFEMErrorCode
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp, ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

Definition at line 5021 of file EshelbianPlasticity.cpp.

5023 {
5025
5026 auto storage = solve_elastic_setup::setup(this, ts, x, false);
5027
5028 auto cohesive_tao_ctx = createCohesiveTAOCtx(
5029 this,
5030 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges,
5031 [](int p) { return 2 * (p + 1) + 1; }),
5032 SmartPetscObj<TS>(ts, true));
5033
5034 double final_time = 1;
5035 double delta_time = 0.1;
5036 int max_it = 10;
5037 PetscBool ts_h1_update = PETSC_FALSE;
5038
5039 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Dynamic Relaxation Options", "none");
5040
5041 CHKERR PetscOptionsScalar("-dynamic_final_time",
5042 "dynamic relaxation final time", "", final_time,
5043 &final_time, PETSC_NULLPTR);
5044 CHKERR PetscOptionsScalar("-dynamic_delta_time",
5045 "dynamic relaxation final time", "", delta_time,
5046 &delta_time, PETSC_NULLPTR);
5047 CHKERR PetscOptionsInt("-dynamic_max_it", "dynamic relaxation iterations", "",
5048 max_it, &max_it, PETSC_NULLPTR);
5049 CHKERR PetscOptionsBool("-dynamic_h1_update", "update each ts step", "",
5050 ts_h1_update, &ts_h1_update, PETSC_NULLPTR);
5051
5052 PetscOptionsEnd();
5053
5054 MOFEM_LOG("EP", Sev::inform)
5055 << "Dynamic relaxation final time -dynamic_final_time = " << final_time;
5056 MOFEM_LOG("EP", Sev::inform)
5057 << "Dynamic relaxation delta time -dynamic_delta_time = " << delta_time;
5058 MOFEM_LOG("EP", Sev::inform)
5059 << "Dynamic relaxation max iterations -dynamic_max_it = " << max_it;
5060 MOFEM_LOG("EP", Sev::inform)
5061 << "Dynamic relaxation H1 update each step -dynamic_h1_update = "
5062 << (ts_h1_update ? "TRUE" : "FALSE");
5063
5066
5067 auto setup_ts_monitor = [&]() {
5068 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*this);
5069 return monitor_ptr;
5070 };
5071 auto monitor_ptr = setup_ts_monitor();
5072
5073 TetPolynomialBase::switchCacheBaseOn<HDIV>(
5074 {elasticFeLhs.get(), elasticFeRhs.get()});
5075 CHKERR TSSetUp(ts);
5076 CHKERR TSElasticPostStep::postStepInitialise(this);
5077
5078 double ts_delta_time;
5079 CHKERR TSGetTimeStep(ts, &ts_delta_time);
5080
5081 if (ts_h1_update) {
5082 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
5083 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
5084 }
5085
5086 CHKERR TSElasticPostStep::preStepFun(ts);
5087 CHKERR TSElasticPostStep::postStepFun(ts);
5088
5089 auto tao = createTao(mField.get_comm());
5090 CHKERR TaoSetType(tao, TAOLMVM);
5091 auto g = cohesive_tao_ctx->duplicateGradientVec();
5093 cohesiveEvaluateObjectiveAndGradient,
5094 (void *)cohesive_tao_ctx.get());
5095
5096 dynamicTime = start_time;
5097 dynamicStep = start_step;
5098 monitor_ptr->ts_u = PETSC_NULLPTR;
5099 monitor_ptr->ts_t = dynamicTime;
5100 monitor_ptr->ts_step = dynamicStep;
5102
5103 auto tao_sol0 = cohesive_tao_ctx->duplicateKappaVec();
5104 int tao_sol_size, tao_sol_loc_size;
5105 CHKERR VecGetSize(tao_sol0, &tao_sol_size);
5106 CHKERR VecGetLocalSize(tao_sol0, &tao_sol_loc_size);
5107 MOFEM_LOG("EP", Sev::inform)
5108 << "Cohesive crack growth initial kappa vector size " << tao_sol_size
5109 << " local size " << tao_sol_loc_size << " number of interface faces "
5110 << interfaceFaces->size();
5111
5112 CHKERR TaoSetFromOptions(tao);
5113
5114 auto xl = vectorDuplicate(tao_sol0);
5115 auto xu = vectorDuplicate(tao_sol0);
5116 CHKERR VecSet(xl, 0.0);
5117 CHKERR VecSet(xu, PETSC_INFINITY);
5118 CHKERR TaoSetVariableBounds(tao, xl, xu);
5119
5120 for (; dynamicTime < final_time; dynamicTime += delta_time) {
5121 MOFEM_LOG("EP", Sev::inform) << "Load step " << dynamicStep << " Time "
5122 << dynamicTime << " delta time " << delta_time;
5123
5124 CHKERR VecZeroEntries(tao_sol0);
5125 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5126 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5127 CHKERR TaoSetSolution(tao, tao_sol0);
5128 CHKERR TaoSolve(tao);
5129 Vec tao_sol;
5130 CHKERR TaoGetSolution(tao, &tao_sol);
5131
5132 // add solution increment to kappa vec/tags
5133 auto &kappa_vec = cohesive_tao_ctx->getKappaVec();
5134 CHKERR CommInterface::setVectorFromTag(mField.get_moab(), kappa_vec,
5136 CHKERR VecAXPY(kappa_vec.second, 1.0, tao_sol);
5137 CHKERR VecGhostUpdateBegin(kappa_vec.second, INSERT_VALUES,
5138 SCATTER_FORWARD);
5139 CHKERR VecGhostUpdateEnd(kappa_vec.second, INSERT_VALUES, SCATTER_FORWARD);
5140 CHKERR CommInterface::setTagFromVector(mField.get_moab(), kappa_vec,
5142
5143 CHKERR DMoFEMMeshToLocalVector(dmElastic, x, INSERT_VALUES,
5144 SCATTER_FORWARD);
5145 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
5146 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
5147 monitor_ptr->ts_u = x;
5148 monitor_ptr->ts_t = dynamicTime;
5149 monitor_ptr->ts_step = dynamicStep;
5151
5152 ++dynamicStep;
5153 if (dynamicStep > max_it)
5154 break;
5155 }
5156
5157 CHKERR TSElasticPostStep::postStepDestroy();
5158 TetPolynomialBase::switchCacheBaseOff<HDIV>(
5159 {elasticFeLhs.get(), elasticFeRhs.get()});
5160
5162}
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode)
set local (or ghosted) vector values on mesh for partition only
Definition DMMoFEM.cpp:514
boost::shared_ptr< CohesiveTAOCtx > createCohesiveTAOCtx(EshelbianCore *ep, ForcesAndSourcesCore::GaussHookFun set_integration_at_front_face, SmartPetscObj< TS > time_solver)
Tag get_kappa_tag(moab::Interface &moab)
MoFEMErrorCode initializeCohesiveKappaField(EshelbianCore &ep)
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
PetscErrorCode TaoSetObjectiveAndGradient(Tao tao, Vec x, PetscReal *f, Vec g, void *ctx)
Sets the objective function value and gradient for a TAO optimization solver.
Definition TaoCtx.cpp:178
auto createTao(MPI_Comm comm)
constexpr double g
static double dynamicTime
static int dynamicStep
MoFEMErrorCode addDebugModel(TS ts)
Add debug to model.

◆ 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
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp, ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

Definition at line 3897 of file EshelbianPlasticity.cpp.

3899 {
3901
3902 auto storage = solve_elastic_setup::setup(this, ts, x, false);
3903
3904 double final_time = 1;
3905 double delta_time = 0.1;
3906 int max_it = 10;
3907 PetscBool ts_h1_update = PETSC_FALSE;
3908
3909 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Dynamic Relaxation Options", "none");
3910
3911 CHKERR PetscOptionsScalar("-dynamic_final_time",
3912 "dynamic relaxation final time", "", final_time,
3913 &final_time, PETSC_NULLPTR);
3914 CHKERR PetscOptionsScalar("-dynamic_delta_time",
3915 "dynamic relaxation final time", "", delta_time,
3916 &delta_time, PETSC_NULLPTR);
3917 CHKERR PetscOptionsInt("-dynamic_max_it", "dynamic relaxation iterations", "",
3918 max_it, &max_it, PETSC_NULLPTR);
3919 CHKERR PetscOptionsBool("-dynamic_h1_update", "update each ts step", "",
3920 ts_h1_update, &ts_h1_update, PETSC_NULLPTR);
3921
3922 PetscOptionsEnd();
3923
3924 MOFEM_LOG("EP", Sev::inform)
3925 << "Dynamic relaxation final time -dynamic_final_time = " << final_time;
3926 MOFEM_LOG("EP", Sev::inform)
3927 << "Dynamic relaxation delta time -dynamic_delta_time = " << delta_time;
3928 MOFEM_LOG("EP", Sev::inform)
3929 << "Dynamic relaxation max iterations -dynamic_max_it = " << max_it;
3930 MOFEM_LOG("EP", Sev::inform)
3931 << "Dynamic relaxation H1 update each step -dynamic_h1_update = "
3932 << (ts_h1_update ? "TRUE" : "FALSE");
3933
3935
3936 auto setup_ts_monitor = [&]() {
3937 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*this);
3938 return monitor_ptr;
3939 };
3940 auto monitor_ptr = setup_ts_monitor();
3941
3942 TetPolynomialBase::switchCacheBaseOn<HDIV>(
3943 {elasticFeLhs.get(), elasticFeRhs.get()});
3944 CHKERR TSSetUp(ts);
3945 CHKERR TSElasticPostStep::postStepInitialise(this);
3946
3947 double ts_delta_time;
3948 CHKERR TSGetTimeStep(ts, &ts_delta_time);
3949
3950 if (ts_h1_update) {
3951 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
3952 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
3953 }
3954
3955 CHKERR TSElasticPostStep::preStepFun(ts);
3956 CHKERR TSElasticPostStep::postStepFun(ts);
3957
3958 dynamicTime = start_time;
3959 dynamicStep = start_step;
3960 monitor_ptr->ts_u = PETSC_NULLPTR;
3961 monitor_ptr->ts_t = dynamicTime;
3962 monitor_ptr->ts_step = dynamicStep;
3964
3965 for (; dynamicTime < final_time; dynamicTime += delta_time) {
3966 MOFEM_LOG("EP", Sev::inform) << "Load step " << dynamicStep << " Time "
3967 << dynamicTime << " delta time " << delta_time;
3968
3969 CHKERR TSSetStepNumber(ts, 0);
3970 CHKERR TSSetTime(ts, 0);
3971 CHKERR TSSetTimeStep(ts, ts_delta_time);
3972 if (!ts_h1_update) {
3973 CHKERR TSElasticPostStep::preStepFun(ts);
3974 }
3975 CHKERR TSSetSolution(ts, x);
3976 CHKERR TSSolve(ts, PETSC_NULLPTR);
3977 if (!ts_h1_update) {
3978 CHKERR TSElasticPostStep::postStepFun(ts);
3979 }
3980
3981 CHKERR DMoFEMMeshToLocalVector(dmElastic, x, INSERT_VALUES,
3982 SCATTER_FORWARD);
3983 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
3984 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
3985
3986 monitor_ptr->ts_u = x;
3987 monitor_ptr->ts_t = dynamicTime;
3988 monitor_ptr->ts_step = dynamicStep;
3990
3991 ++dynamicStep;
3992 if (dynamicStep > max_it)
3993 break;
3994 }
3995
3996 CHKERR TSElasticPostStep::postStepDestroy();
3997 TetPolynomialBase::switchCacheBaseOff<HDIV>(
3998 {elasticFeLhs.get(), elasticFeRhs.get()});
3999
4001}

◆ solveElastic()

MoFEMErrorCode EshelbianCore::solveElastic ( TS  ts,
Vec  x 
)
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp, ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

Definition at line 3792 of file EshelbianPlasticity.cpp.

3792 {
3794
3796
3797 auto storage = solve_elastic_setup::setup(this, ts, x, true);
3798
3799 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
3800 Vec xx;
3801 CHKERR VecDuplicate(x, &xx);
3802 CHKERR VecZeroEntries(xx);
3803 CHKERR TS2SetSolution(ts, x, xx);
3804 CHKERR VecDestroy(&xx);
3805 } else {
3806 CHKERR TSSetSolution(ts, x);
3807 }
3808
3809 TetPolynomialBase::switchCacheBaseOn<HDIV>(
3810 {elasticFeLhs.get(), elasticFeRhs.get()});
3811 CHKERR TSSetUp(ts);
3812 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
3813 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
3814 CHKERR TSElasticPostStep::postStepInitialise(this);
3815 CHKERR TSSolve(ts, PETSC_NULLPTR);
3816 CHKERR TSElasticPostStep::postStepDestroy();
3817 TetPolynomialBase::switchCacheBaseOff<HDIV>(
3818 {elasticFeLhs.get(), elasticFeRhs.get()});
3819
3820#ifndef NDEBUG
3821 // Make graph
3822 if (mField.get_comm_rank() == 0) {
3823 auto ts_ctx_ptr = getDMTsCtx(dmElastic);
3824 CHKERR PipelineGraph::writeTSGraphGraphviz(ts_ctx_ptr.get(),
3825 "solve_elastic_graph.dot");
3826 }
3827#endif
3828
3829 SNES snes;
3830 CHKERR TSGetSNES(ts, &snes);
3831 int lin_solver_iterations;
3832 CHKERR SNESGetLinearSolveIterations(snes, &lin_solver_iterations);
3833 MOFEM_LOG("EP", Sev::inform)
3834 << "Number of linear solver iterations " << lin_solver_iterations;
3835
3836 PetscBool test_cook_flg = PETSC_FALSE;
3837 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-test_cook", &test_cook_flg,
3838 PETSC_NULLPTR);
3839 if (test_cook_flg) {
3840 constexpr int expected_lin_solver_iterations = 11;
3841 if (lin_solver_iterations > expected_lin_solver_iterations)
3842 SETERRQ(
3843 PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
3844 "Expected number of iterations is different than expected %d > %d",
3845 lin_solver_iterations, expected_lin_solver_iterations);
3846 }
3847
3848 PetscBool test_sslv116_flag = PETSC_FALSE;
3849 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-test_sslv116",
3850 &test_sslv116_flag, PETSC_NULLPTR);
3851
3852 if (test_sslv116_flag) {
3853 double max_val = 0.0;
3854 double min_val = 0.0;
3855 auto field_min_max = [&](boost::shared_ptr<FieldEntity> ent_ptr) {
3857 auto ent_type = ent_ptr->getEntType();
3858 if (ent_type == MBVERTEX) {
3859 max_val = std::max(ent_ptr->getEntFieldData()[SPACE_DIM - 1], max_val);
3860 min_val = std::min(ent_ptr->getEntFieldData()[SPACE_DIM - 1], min_val);
3861 }
3863 };
3864 CHKERR mField.getInterface<FieldBlas>()->fieldLambdaOnEntities(
3865 field_min_max, spatialH1Disp);
3866
3867 double global_max_val = 0.0;
3868 double global_min_val = 0.0;
3869 MPI_Allreduce(&max_val, &global_max_val, 1, MPI_DOUBLE, MPI_MAX,
3870 mField.get_comm());
3871 MPI_Allreduce(&min_val, &global_min_val, 1, MPI_DOUBLE, MPI_MIN,
3872 mField.get_comm());
3873 MOFEM_LOG("EP", Sev::inform)
3874 << "Max " << spatialH1Disp << " value: " << global_max_val;
3875 MOFEM_LOG("EP", Sev::inform)
3876 << "Min " << spatialH1Disp << " value: " << global_min_val;
3877
3878 double ref_max_val = 0.00767;
3879 double ref_min_val = -0.00329;
3880 if (std::abs(global_max_val - ref_max_val) > 1e-5) {
3881 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
3882 "Incorrect max value of the displacement field: %f != %f",
3883 global_max_val, ref_max_val);
3884 }
3885 if (std::abs(global_min_val - ref_min_val) > 4e-5) {
3886 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
3887 "Incorrect min value of the displacement field: %f != %f",
3888 global_min_val, ref_min_val);
3889 }
3890 }
3891
3893
3895}
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
MoFEMErrorCode gettingNorms()
[Getting norms]

Friends And Related Symbol Documentation

◆ solve_elastic_set_up

friend struct solve_elastic_set_up
friend

Definition at line 388 of file EshelbianCore.hpp.

Member Data Documentation

◆ a00FieldList

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

Definition at line 495 of file EshelbianCore.hpp.

◆ a00RangeList

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

Definition at line 497 of file EshelbianCore.hpp.

◆ addCrackMeshsetId

int EshelbianCore::addCrackMeshsetId = 1000
inlinestatic

Definition at line 43 of file EshelbianCore.hpp.

◆ alphaOmega

double EshelbianCore::alphaOmega = 0

◆ alphaRho

double EshelbianCore::alphaRho = 0

◆ alphaTau

double EshelbianCore::alphaTau = 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 493 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()

◆ bitAdjEntMask

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

bit ref level for parent parent

Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 479 of file EshelbianCore.hpp.

◆ bitAdjParent

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

◆ bitAdjParentMask

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

bit ref level for parent parent

Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 476 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<ForcesAndSourcesCore> EshelbianCore::contactTreeRhs

◆ crackFaces

boost::shared_ptr<Range> EshelbianCore::crackFaces

◆ crackHybridIs

SmartPetscObj<IS> EshelbianCore::crackHybridIs

Definition at line 494 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

◆ dmElastic

SmartPetscObj<DM> EshelbianCore::dmElastic

◆ dmMaterial

SmartPetscObj<DM> EshelbianCore::dmMaterial

Material problem.

Definition at line 204 of file EshelbianCore.hpp.

◆ dmPrjSpatial

SmartPetscObj<DM> EshelbianCore::dmPrjSpatial

◆ 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 239 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"

◆ intefaceCrack

PetscBool EshelbianCore::intefaceCrack
inlinestatic

◆ interfaceFaces

boost::shared_ptr<Range> EshelbianCore::interfaceFaces

◆ internalStressInterpOrder

int EshelbianCore::internalStressInterpOrder
inlinestatic

◆ internalStressTagName

std::string EshelbianCore::internalStressTagName
inlinestatic

◆ internalStressVoigt

PetscBool EshelbianCore::internalStressVoigt
inlinestatic

◆ inv_d_f

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

◆ inv_dd_f

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

◆ inv_f

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

◆ l2UserBaseScale

PetscBool EshelbianCore::l2UserBaseScale = PETSC_TRUE
inlinestatic

◆ listTagsToTransfer

std::vector<Tag> EshelbianCore::listTagsToTransfer

◆ materialH1Positions

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

◆ materialModel

enum MaterialModel EshelbianCore::materialModel = MooneyRivlin
inlinestatic

◆ materialOrder

int EshelbianCore::materialOrder = 1

◆ maxMovedFaces

boost::shared_ptr<Range> EshelbianCore::maxMovedFaces

Definition at line 469 of file EshelbianCore.hpp.

◆ mField

MoFEM::Interface& EshelbianCore::mField

◆ naturalBcElement

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

◆ nbCrackFaces

int EshelbianCore::nbCrackFaces = 0

Definition at line 499 of file EshelbianCore.hpp.

◆ 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 492 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

◆ solverType

enum SolverType EshelbianCore::solverType = TimeSolver
inlinestatic

◆ 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 64 of file EshelbianCore.hpp.

◆ v_max

constexpr double EshelbianCore::v_max = 24
inlinestaticconstexpr

Definition at line 65 of file EshelbianCore.hpp.

◆ v_min

constexpr double EshelbianCore::v_min = -v_max
inlinestaticconstexpr

Definition at line 66 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: