v0.15.5
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, 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 > 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 double crackingRtol = 1e-10
 Cracking relative tolerance.
 
static double crackingAtol = 1e-12
 Cracking absolute tolerance.
 
static enum EnergyReleaseSelector energyReleaseSelector
 
static std::string internalStressTagName
 
static int internalStressInterpOrder
 
static PetscBool internalStressVoigt
 
static PetscBool interfaceCrack
 
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 937 of file EshelbianPlasticity.cpp.

937 : mField(m_field) {
938 CHK_THROW_MESSAGE(getOptions(), "getOptions failed");
939}
#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 2163 of file EshelbianPlasticity.cpp.

2163 {
2165
2166 Range meshset_ents;
2167 CHKERR mField.get_moab().get_entities_by_handle(meshset, meshset_ents);
2168
2169 auto set_fe_adjacency = [&](auto fe_name) {
2172 boost::make_shared<ParentFiniteElementAdjacencyFunctionSkeleton<2>>(
2175 fe_name, MBTRI, *parentAdjSkeletonFunctionDim2);
2177 };
2178
2179 // set finite element fields
2180 auto add_field_to_fe = [this](const std::string fe,
2181 const std::string field_name) {
2188 };
2189
2191
2192 Range natural_bc_elements;
2193 if (bcSpatialDispVecPtr) {
2194 for (auto &v : *bcSpatialDispVecPtr) {
2195 natural_bc_elements.merge(v.faces);
2196 }
2197 }
2199 for (auto &v : *bcSpatialRotationVecPtr) {
2200 natural_bc_elements.merge(v.faces);
2201 }
2202 }
2204 for (auto &v : *bcSpatialNormalDisplacementVecPtr) {
2205 natural_bc_elements.merge(v.faces);
2206 }
2207 }
2210 natural_bc_elements.merge(v.faces);
2211 }
2212 }
2214 for (auto &v : *bcSpatialTractionVecPtr) {
2215 natural_bc_elements.merge(v.faces);
2216 }
2217 }
2219 for (auto &v : *bcSpatialAnalyticalTractionVecPtr) {
2220 natural_bc_elements.merge(v.faces);
2221 }
2222 }
2224 for (auto &v : *bcSpatialPressureVecPtr) {
2225 natural_bc_elements.merge(v.faces);
2226 }
2227 }
2228 natural_bc_elements = intersect(natural_bc_elements, meshset_ents);
2229
2231 CHKERR mField.add_ents_to_finite_element_by_type(natural_bc_elements, MBTRI,
2233 CHKERR add_field_to_fe(naturalBcElement, piolaStress);
2234 CHKERR add_field_to_fe(naturalBcElement, hybridSpatialDisp);
2235 CHKERR set_fe_adjacency(naturalBcElement);
2237 }
2238
2239 auto get_skin = [&](auto &body_ents) {
2240 Skinner skin(&mField.get_moab());
2241 Range skin_ents;
2242 CHKERR skin.find_skin(0, body_ents, false, skin_ents);
2243 return skin_ents;
2244 };
2245
2246 auto filter_true_skin = [&](auto &&skin) {
2247 Range boundary_ents;
2248 ParallelComm *pcomm =
2249 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
2250 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
2251 PSTATUS_NOT, -1, &boundary_ents);
2252 return boundary_ents;
2253 };
2254
2256
2257 Range body_ents;
2258 CHKERR mField.get_moab().get_entities_by_dimension(meshset, SPACE_DIM,
2259 body_ents);
2260 auto skin = filter_true_skin(get_skin(body_ents));
2261
2269 contactDisp);
2272
2274 }
2275
2277 if (contactFaces) {
2278 MOFEM_LOG("EP", Sev::inform)
2279 << "Contact elements " << contactFaces->size();
2283 CHKERR add_field_to_fe(contactElement, piolaStress);
2284 CHKERR add_field_to_fe(contactElement, contactDisp);
2285 CHKERR add_field_to_fe(contactElement, spatialL2Disp);
2286 CHKERR add_field_to_fe(contactElement, spatialH1Disp);
2287 CHKERR set_fe_adjacency(contactElement);
2289 }
2290 }
2291
2293 if (!skeletonFaces)
2294 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "No skeleton faces");
2295 MOFEM_LOG("EP", Sev::inform)
2296 << "Skeleton elements " << skeletonFaces->size();
2300 CHKERR add_field_to_fe(skeletonElement, piolaStress);
2301 CHKERR add_field_to_fe(skeletonElement, hybridSpatialDisp);
2302 CHKERR add_field_to_fe(skeletonElement, spatialL2Disp);
2303 CHKERR add_field_to_fe(skeletonElement, spatialH1Disp);
2304 CHKERR set_fe_adjacency(skeletonElement);
2306 }
2307
2309}
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 1699 of file EshelbianFracture.cpp.

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

3736 {
3738
3739 PetscBool debug_model = PETSC_FALSE;
3740 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-debug_model", &debug_model,
3741 PETSC_NULLPTR);
3742 MOFEM_LOG("EP", Sev::inform)
3743 << "Debug model flag is " << (debug_model ? "ON" : "OFF");
3744
3745 if (debug_model == PETSC_TRUE) {
3746 auto ts_ctx_ptr = getDMTsCtx(dmElastic);
3747 auto post_proc = [&](TS ts, PetscReal t, Vec u, Vec u_t, Vec u_tt, Vec F,
3748 void *ctx) {
3750
3751 SNES snes;
3752 CHKERR TSGetSNES(ts, &snes);
3753 int it;
3754 CHKERR SNESGetIterationNumber(snes, &it);
3755 std::string file_name = "snes_iteration_" + std::to_string(it) + ".h5m";
3756 CHKERR postProcessResults(1, file_name, F, u_t);
3757 std::string file_skel_name =
3758 "snes_iteration_skel_" + std::to_string(it) + ".h5m";
3759
3760 auto get_material_force_tag = [&]() {
3761 auto &moab = mField.get_moab();
3762 Tag tag;
3763 CHK_MOAB_THROW(moab.tag_get_handle("MaterialForce", tag),
3764 "can't get tag");
3765 return tag;
3766 };
3767
3769 CHKERR postProcessSkeletonResults(1, file_skel_name, F,
3770 {get_material_force_tag()});
3771
3773 };
3774 ts_ctx_ptr->tsDebugHook = post_proc;
3775 }
3776
3778}
@ 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 2311 of file EshelbianPlasticity.cpp.

2312 {
2314
2315 // find adjacencies between finite elements and dofs
2317
2318 // Create coupled problem
2319 dM = createDM(mField.get_comm(), "DMMOFEM");
2320 CHKERR DMMoFEMCreateMoFEM(dM, &mField, "ESHELBY_PLASTICITY", bit,
2321 BitRefLevel().set());
2322 CHKERR DMMoFEMSetDestroyProblem(dM, PETSC_TRUE);
2323 CHKERR DMMoFEMSetIsPartitioned(dM, PETSC_TRUE);
2329
2330 mField.getInterface<ProblemsManager>()->buildProblemFromFields = PETSC_TRUE;
2331 CHKERR DMSetUp(dM);
2332 mField.getInterface<ProblemsManager>()->buildProblemFromFields = PETSC_FALSE;
2333
2334 auto remove_dofs_on_broken_skin = [&](const std::string prb_name) {
2336 for (int d : {0, 1, 2}) {
2337 std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_to_remove;
2339 ->getSideDofsOnBrokenSpaceEntities(
2340 dofs_to_remove, prb_name, ROW, piolaStress,
2342 // remove piola dofs, i.e. traction free boundary
2343 CHKERR mField.getInterface<ProblemsManager>()->removeDofs(prb_name, ROW,
2344 dofs_to_remove);
2345 CHKERR mField.getInterface<ProblemsManager>()->removeDofs(prb_name, COL,
2346 dofs_to_remove);
2347 }
2349 };
2350 CHKERR remove_dofs_on_broken_skin("ESHELBY_PLASTICITY");
2351
2352 // Create elastic sub-problem
2353 dmElastic = createDM(mField.get_comm(), "DMMOFEM");
2354 CHKERR DMMoFEMCreateSubDM(dmElastic, dM, "ELASTIC_PROBLEM");
2360 if (!noStretch) {
2362 }
2372 CHKERR DMSetUp(dmElastic);
2373
2374 // dmMaterial = createDM(mField.get_comm(), "DMMOFEM");
2375 // CHKERR DMMoFEMCreateSubDM(dmMaterial, dM, "MATERIAL_PROBLEM");
2376 // CHKERR DMMoFEMSetDestroyProblem(dmMaterial, PETSC_TRUE);
2377 // CHKERR DMMoFEMAddSubFieldRow(dmMaterial, eshelbyStress);
2378 // CHKERR DMMoFEMAddSubFieldRow(dmMaterial, materialL2Disp);
2379 // CHKERR DMMoFEMAddElement(dmMaterh elementVolumeName);
2380 // CHKERR DMMoFEMAddElement(dmMaterial, naturalBcElement);
2381 // CHKERR DMMoFEMAddElement(dmMaterial, skinElement);
2382 // CHKERR DMMoFEMSetSquareProblem(dmMaterial, PETSC_TRUE);
2383 // CHKERR DMMoFEMSetIsPartitioned(dmMaterial, PETSC_TRUE);
2384 // CHKERR DMSetUp(dmMaterial);
2385
2386 auto set_zero_block = [&]() {
2388 if (!noStretch) {
2389 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2390 "ELASTIC_PROBLEM", spatialL2Disp, stretchTensor);
2391 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2392 "ELASTIC_PROBLEM", stretchTensor, spatialL2Disp);
2393 }
2394 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2395 "ELASTIC_PROBLEM", spatialL2Disp, rotAxis);
2396 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2397 "ELASTIC_PROBLEM", rotAxis, spatialL2Disp);
2398 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2399 "ELASTIC_PROBLEM", spatialL2Disp, bubbleField);
2400 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2401 "ELASTIC_PROBLEM", bubbleField, spatialL2Disp);
2402 if (!noStretch) {
2403 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2404 "ELASTIC_PROBLEM", bubbleField, bubbleField);
2405 CHKERR
2406 mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2407 "ELASTIC_PROBLEM", piolaStress, piolaStress);
2408 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2409 "ELASTIC_PROBLEM", bubbleField, piolaStress);
2410 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2411 "ELASTIC_PROBLEM", piolaStress, bubbleField);
2412 }
2413
2416 };
2417
2418 auto set_section = [&]() {
2420 PetscSection section;
2421 CHKERR mField.getInterface<ISManager>()->sectionCreate("ELASTIC_PROBLEM",
2422 &section);
2423 CHKERR DMSetSection(dmElastic, section);
2424 CHKERR DMSetGlobalSection(dmElastic, section);
2425 CHKERR PetscSectionDestroy(&section);
2427 };
2428
2429 CHKERR set_zero_block();
2430 CHKERR set_section();
2431
2432 dmPrjSpatial = createDM(mField.get_comm(), "DMMOFEM");
2433 CHKERR DMMoFEMCreateSubDM(dmPrjSpatial, dM, "PROJECT_SPATIAL");
2439 CHKERR DMSetUp(dmPrjSpatial);
2440
2441 // CHKERR mField.getInterface<BcManager>()
2442 // ->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
2443 // "PROJECT_SPATIAL", spatialH1Disp, true, false);
2444
2446}
@ 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 1237 of file EshelbianPlasticity.cpp.

1237 {
1239
1240 auto get_tets = [&]() {
1241 Range tets;
1242 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
1243 return tets;
1244 };
1245
1246 auto get_tets_skin = [&]() {
1247 Range tets_skin_part;
1248 Skinner skin(&mField.get_moab());
1249 CHKERR skin.find_skin(0, get_tets(), false, tets_skin_part);
1250 ParallelComm *pcomm =
1251 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
1252 Range tets_skin;
1253 CHKERR pcomm->filter_pstatus(tets_skin_part,
1254 PSTATUS_SHARED | PSTATUS_MULTISHARED,
1255 PSTATUS_NOT, -1, &tets_skin);
1256 return tets_skin;
1257 };
1258
1259 auto subtract_boundary_conditions = [&](auto &&tets_skin) {
1260 // That mean, that hybrid field on all faces on which traction is applied,
1261 // on other faces, or enforcing displacements as
1262 // natural boundary condition.
1264 for (auto &v : *bcSpatialTractionVecPtr) {
1265 tets_skin = subtract(tets_skin, v.faces);
1266 }
1268 for (auto &v : *bcSpatialAnalyticalTractionVecPtr) {
1269 tets_skin = subtract(tets_skin, v.faces);
1270 }
1271
1273 for (auto &v : *bcSpatialPressureVecPtr) {
1274 tets_skin = subtract(tets_skin, v.faces);
1275 }
1276
1277 return tets_skin;
1278 };
1279
1280 auto add_blockset = [&](auto block_name, auto &&tets_skin) {
1281 auto crack_faces =
1282 get_range_from_block(mField, "block_name", SPACE_DIM - 1);
1283 tets_skin.merge(crack_faces);
1284 return tets_skin;
1285 };
1286
1287 auto subtract_blockset = [&](auto block_name, auto &&tets_skin) {
1288 auto contact_range =
1289 get_range_from_block(mField, block_name, SPACE_DIM - 1);
1290 tets_skin = subtract(tets_skin, contact_range);
1291 return tets_skin;
1292 };
1293
1294 auto get_stress_trace_faces = [&](auto &&tets_skin) {
1295 Range faces;
1296 CHKERR mField.get_moab().get_adjacencies(get_tets(), SPACE_DIM - 1, true,
1297 faces, moab::Interface::UNION);
1298 Range trace_faces = subtract(faces, tets_skin);
1299 return trace_faces;
1300 };
1301
1302 auto tets = get_tets();
1303
1304 // remove also contact faces, i.e. that is also kind of hybrid field but
1305 // named but used to enforce contact conditions
1306 auto trace_faces = get_stress_trace_faces(
1307
1308 subtract_blockset("CONTACT",
1309 subtract_boundary_conditions(get_tets_skin()))
1310
1311 );
1312
1313 contactFaces = boost::make_shared<Range>(intersect(
1314 trace_faces, get_range_from_block(mField, "CONTACT", SPACE_DIM - 1)));
1316 boost::make_shared<Range>(subtract(trace_faces, *contactFaces));
1317
1318#ifndef NDEBUG
1319 if (contactFaces->size())
1321 "contact_faces_" +
1322 std::to_string(mField.get_comm_rank()) + ".vtk",
1323 *contactFaces);
1324 if (skeletonFaces->size())
1326 "skeleton_faces_" +
1327 std::to_string(mField.get_comm_rank()) + ".vtk",
1328 *skeletonFaces);
1329#endif
1330
1331 auto add_broken_hdiv_field = [this, meshset](const std::string field_name,
1332 const int order) {
1334
1336
1337 auto get_side_map_hdiv = [&]() {
1338 return std::vector<
1339
1340 std::pair<EntityType,
1342
1343 >>{
1344
1345 {MBTET,
1346 [&](BaseFunction::DofsSideMap &dofs_side_map) -> MoFEMErrorCode {
1347 return TetPolynomialBase::setDofsSideMap(HDIV, DISCONTINUOUS, base,
1348 dofs_side_map);
1349 }}
1350
1351 };
1352 };
1353
1355 get_side_map_hdiv(), MB_TAG_DENSE, MF_ZERO);
1357 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1359 };
1360
1361 auto add_l2_field = [this, meshset](const std::string field_name,
1362 const int order, const int dim) {
1365 MB_TAG_DENSE, MF_ZERO);
1367 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1369 };
1370
1371 auto add_h1_field = [this, meshset](const std::string field_name,
1372 const int order, const int dim) {
1375 MB_TAG_DENSE, MF_ZERO);
1377 CHKERR mField.set_field_order(meshset, MBVERTEX, field_name, 1);
1378 CHKERR mField.set_field_order(meshset, MBEDGE, field_name, order);
1379 CHKERR mField.set_field_order(meshset, MBTRI, field_name, order);
1380 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1382 };
1383
1384 auto add_l2_field_by_range = [this](const std::string field_name,
1385 const int order, const int dim,
1386 const int field_dim, Range &&r) {
1389 MB_TAG_DENSE, MF_ZERO);
1390 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(r);
1394 };
1395
1396 auto add_bubble_field = [this, meshset](const std::string field_name,
1397 const int order, const int dim) {
1399 CHKERR mField.add_field(field_name, HDIV, USER_BASE, dim, MB_TAG_DENSE,
1400 MF_ZERO);
1401 // Modify field
1402 auto field_ptr = mField.get_field_structure(field_name);
1403 auto field_order_table =
1404 const_cast<Field *>(field_ptr)->getFieldOrderTable();
1405 auto get_cgg_bubble_order_zero = [](int p) { return 0; };
1406 auto get_cgg_bubble_order_tet = [](int p) {
1407 return NBVOLUMETET_CCG_BUBBLE(p);
1408 };
1409 field_order_table[MBVERTEX] = get_cgg_bubble_order_zero;
1410 field_order_table[MBEDGE] = get_cgg_bubble_order_zero;
1411 field_order_table[MBTRI] = get_cgg_bubble_order_zero;
1412 field_order_table[MBTET] = get_cgg_bubble_order_tet;
1414 CHKERR mField.set_field_order(meshset, MBTRI, field_name, order);
1415 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1417 };
1418
1419 auto add_user_l2_field = [this, meshset](const std::string field_name,
1420 const int order, const int dim) {
1422 CHKERR mField.add_field(field_name, L2, USER_BASE, dim, MB_TAG_DENSE,
1423 MF_ZERO);
1424 // Modify field
1425 auto field_ptr = mField.get_field_structure(field_name);
1426 auto field_order_table =
1427 const_cast<Field *>(field_ptr)->getFieldOrderTable();
1428 auto zero_dofs = [](int p) { return 0; };
1429 auto dof_l2_tet = [](int p) { return NBVOLUMETET_L2(p); };
1430 field_order_table[MBVERTEX] = zero_dofs;
1431 field_order_table[MBEDGE] = zero_dofs;
1432 field_order_table[MBTRI] = zero_dofs;
1433 field_order_table[MBTET] = dof_l2_tet;
1435 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1437 };
1438
1439 // spatial fields
1440 CHKERR add_broken_hdiv_field(piolaStress, spaceOrder);
1441 CHKERR add_bubble_field(bubbleField, spaceOrder, 1);
1442 CHKERR add_l2_field(spatialL2Disp, spaceOrder - 1, 3);
1443 CHKERR add_user_l2_field(rotAxis, spaceOrder - 1, 3);
1444 CHKERR add_user_l2_field(stretchTensor, noStretch ? -1 : spaceOrder, 6);
1445
1446 if (!skeletonFaces)
1447 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "No skeleton faces");
1448 if (!contactFaces)
1449 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "No contact faces");
1450
1451 auto get_hybridised_disp = [&]() {
1452 auto faces = *skeletonFaces;
1453 auto skin = subtract_boundary_conditions(get_tets_skin());
1454 for (auto &bc : *bcSpatialNormalDisplacementVecPtr) {
1455 faces.merge(intersect(bc.faces, skin));
1456 }
1457 return faces;
1458 };
1459
1460 CHKERR add_l2_field_by_range(hybridSpatialDisp, spaceOrder - 1, 2, 3,
1461 get_hybridised_disp());
1462 CHKERR add_l2_field_by_range(contactDisp, spaceOrder - 1, 2, 3,
1464
1465 // spatial displacement
1466 CHKERR add_h1_field(spatialH1Disp, spaceH1Order, 3);
1467 // material positions
1468 CHKERR add_h1_field(materialH1Positions, 2, 3);
1469
1470 // Eshelby stress
1471 // CHKERR add_broken_hdiv_field(eshelbyStress, spaceOrder);
1472 // CHKERR add_l2_field(materialL2Disp, spaceOrder - 1, 3);
1473 // CHKERR add_l2_field_by_range(hybridMaterialDisp, spaceOrder - 1, 2, 3,
1474 // Range(*materialSkeletonFaces));
1475
1477
1479}
#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 542 of file EshelbianADOL-C.cpp.

542 {
544 physicalEquations = boost::make_shared<HMHHencky>(mField, E, nu);
546}
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 515 of file EshelbianADOL-C.cpp.

517 {
519 physicalEquations = boost::make_shared<HMHStVenantKirchhoff>(lambda, mu);
520 CHKERR physicalEquations->recordTape(tape, nullptr);
522}
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 524 of file EshelbianADOL-C.cpp.

526 {
529 boost::make_shared<HMHPMooneyRivlinWriggersEq63>(alpha, beta, lambda);
530 CHKERR physicalEquations->recordTape(tape, nullptr);
532}

◆ 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 533 of file EshelbianADOL-C.cpp.

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

◆ 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 2126 of file EshelbianPlasticity.cpp.

2126 {
2128
2129 // set finite element fields
2130 auto add_field_to_fe = [this](const std::string fe,
2131 const std::string field_name) {
2137 };
2138
2143
2144 CHKERR add_field_to_fe(elementVolumeName, piolaStress);
2145 CHKERR add_field_to_fe(elementVolumeName, bubbleField);
2146 if (!noStretch)
2147 CHKERR add_field_to_fe(elementVolumeName, stretchTensor);
2148 CHKERR add_field_to_fe(elementVolumeName, rotAxis);
2149 CHKERR add_field_to_fe(elementVolumeName, spatialL2Disp);
2150 CHKERR add_field_to_fe(elementVolumeName, spatialH1Disp);
2151 CHKERR add_field_to_fe(elementVolumeName, contactDisp);
2154
2155 // build finite elements data structures
2157 }
2158
2160}

◆ calculateCrackArea()

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

Definition at line 2464 of file EshelbianFracture.cpp.

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

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

◆ 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, std::function< Range(Range)> get_entities_fun, const int nb_coeffs, Sev sev=Sev::verbose, int root_rank=0, bool get_vertices=true)
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 111 of file EshelbianCore.hpp.

111 {
112 if constexpr (use_quadratic_exp) {
113 return d_f_log_e_quadratic(v);
114 } else {
115 if (v > v_max)
116 return std::exp(v_max);
117 else
118 return std::exp(v);
119 }
120 }
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 80 of file EshelbianCore.hpp.

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

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

121 {
122 if constexpr (use_quadratic_exp) {
123 return dd_f_log_e_quadratic(v);
124 } else {
125 if (v > v_max)
126 return 0.;
127 else
128 return std::exp(v);
129 }
130 }
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 90 of file EshelbianCore.hpp.

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

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

98 {
99 if constexpr(use_quadratic_exp) {
100 return f_log_e_quadratic(v);
101 } else {
102 if (v > v_max)
103 // y = exp(v_max) * v + exp(v_max) * (1 - v_max);
104 // y/exp(v_max) = v + (1 - v_max);
105 // y/exp(v_max) - (1 - v_max) = v;
106 return std::exp(v_max) * v + std::exp(v_max) * (1 - v_max);
107 else
108 return std::exp(v);
109 }
110 }
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 70 of file EshelbianCore.hpp.

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

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

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

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

◆ getSpatialDispBc()

MoFEMErrorCode EshelbianCore::getSpatialDispBc ( )

[Getting norms]

Examples
/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 287 of file EshelbianCore.hpp.

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

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

321 {
323 boost::shared_ptr<TractionFreeBc>(new TractionFreeBc());
324 return getTractionFreeBc(meshset, bcSpatialFreeTractionVecPtr, "CONTACT");
325 }
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 2596 of file EshelbianPlasticity.cpp.

2598 {
2600
2601 // get skin from all tets
2602 Range tets;
2603 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
2604 Range tets_skin_part;
2605 Skinner skin(&mField.get_moab());
2606 CHKERR skin.find_skin(0, tets, false, tets_skin_part);
2607 ParallelComm *pcomm =
2608 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
2609 Range tets_skin;
2610 CHKERR pcomm->filter_pstatus(tets_skin_part,
2611 PSTATUS_SHARED | PSTATUS_MULTISHARED,
2612 PSTATUS_NOT, -1, &tets_skin);
2613
2614 bc_ptr->resize(3);
2615 for (int dd = 0; dd != 3; ++dd)
2616 (*bc_ptr)[dd] = tets_skin;
2617
2618 // Do not remove dofs on which traction is applied
2620 for (auto &v : *bcSpatialDispVecPtr) {
2621 if (v.flags[0])
2622 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2623 if (v.flags[1])
2624 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2625 if (v.flags[2])
2626 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2627 }
2628
2629 // Do not remove dofs on which rotation is applied
2631 for (auto &v : *bcSpatialRotationVecPtr) {
2632 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2633 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2634 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2635 }
2636
2638 for (auto &v : *bcSpatialNormalDisplacementVecPtr) {
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
2646 if (v.flags[0])
2647 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2648 if (v.flags[1])
2649 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2650 if (v.flags[2])
2651 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2652 }
2653
2655 for (auto &v : *bcSpatialTractionVecPtr) {
2656 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2657 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2658 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2659 }
2660
2662 for (auto &v : *bcSpatialAnalyticalTractionVecPtr) {
2663 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2664 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2665 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2666 }
2667
2669 for (auto &v : *bcSpatialPressureVecPtr) {
2670 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2671 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2672 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2673 }
2674
2675 // remove contact
2676 for (auto m : mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
2677 std::regex((boost::format("%s(.*)") % contact_set_name).str()))) {
2678 Range faces;
2679 CHKERR m->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2, faces,
2680 true);
2681 (*bc_ptr)[0] = subtract((*bc_ptr)[0], faces);
2682 (*bc_ptr)[1] = subtract((*bc_ptr)[1], faces);
2683 (*bc_ptr)[2] = subtract((*bc_ptr)[2], faces);
2684 }
2685
2687}
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 140 of file EshelbianCore.hpp.

140 {
141 if (v > std::exp(v_min))
142 return 1. / v;
143 else
144 return 1. / exp(v_min);
145 }
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 146 of file EshelbianCore.hpp.

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

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

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

◆ 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 4058 of file EshelbianPlasticity.cpp.

4060 {
4062
4063 // mark crack surface
4064 if (crackingOn) {
4065 auto get_tag = [&](auto name, auto dim) {
4066 auto &mob = mField.get_moab();
4067 Tag tag;
4068 double def_val[] = {0., 0., 0.};
4069 CHK_MOAB_THROW(mob.tag_get_handle(name, dim, MB_TYPE_DOUBLE, tag,
4070 MB_TAG_CREAT | MB_TAG_SPARSE, def_val),
4071 "create tag");
4072 return tag;
4073 };
4074 tags_to_transfer.push_back(get_tag("MaterialForce", 3));
4075 }
4076
4077 {
4078 auto get_crack_tag = [&]() {
4079 Tag th;
4080 rval = mField.get_moab().tag_get_handle("CRACK", th);
4081 if (rval == MB_SUCCESS) {
4082 MOAB_THROW(mField.get_moab().tag_delete(th));
4083 }
4084 int def_val[] = {0};
4085 MOAB_THROW(mField.get_moab().tag_get_handle(
4086 "CRACK", 1, MB_TYPE_INTEGER, th, MB_TAG_SPARSE | MB_TAG_CREAT,
4087 def_val));
4088 return th;
4089 };
4090
4091 Tag th = get_crack_tag();
4092 tags_to_transfer.push_back(th);
4093 int mark[] = {1};
4094 Range mark_faces;
4095 if (crackFaces)
4096 mark_faces.merge(*crackFaces);
4097 if (interfaceFaces)
4098 mark_faces.merge(*interfaceFaces);
4099 CHKERR mField.get_moab().tag_clear_data(th, mark_faces, mark);
4100 }
4101
4102 // add tags to transfer
4103 for (auto t : listTagsToTransfer) {
4104 tags_to_transfer.push_back(t);
4105 }
4106
4107 if (!dataAtPts) {
4108 dataAtPts =
4109 boost::shared_ptr<DataAtIntegrationPts>(new DataAtIntegrationPts());
4110 }
4111
4113
4114 auto get_post_proc = [&](auto &post_proc_mesh, auto sense) {
4116 auto post_proc_ptr =
4117 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
4118 mField, post_proc_mesh);
4119 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
4120 post_proc_ptr->getOpPtrVector(), {L2}, materialH1Positions,
4122
4123 auto domain_ops = [&](auto &fe, int sense) {
4125 fe.getUserPolynomialBase() =
4126 boost::shared_ptr<BaseFunction>(new CGGUserPolynomialBase());
4127 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4128 fe.getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions,
4130 auto piola_scale_ptr = boost::make_shared<double>(1.0);
4131 fe.getOpPtrVector().push_back(physicalEquations->returnOpSetScale(
4132 piola_scale_ptr, physicalEquations));
4133 fe.getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
4134 piolaStress, dataAtPts->getApproxPAtPts(), piola_scale_ptr));
4135 fe.getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
4136 bubbleField, dataAtPts->getApproxPAtPts(), piola_scale_ptr,
4137 SmartPetscObj<Vec>(), MBMAXTYPE));
4138 if (noStretch) {
4139 fe.getOpPtrVector().push_back(
4140 physicalEquations->returnOpCalculateStretchFromStress(
4142 } else {
4143 fe.getOpPtrVector().push_back(
4145 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
4146 }
4147 if (var_vector) {
4148 auto vec = SmartPetscObj<Vec>(var_vector, true);
4149 fe.getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
4150 piolaStress, dataAtPts->getVarPiolaPts(),
4151 boost::make_shared<double>(1), vec));
4152 fe.getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
4153 bubbleField, dataAtPts->getVarPiolaPts(),
4154 boost::make_shared<double>(1), vec, MBMAXTYPE));
4155 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4156 rotAxis, dataAtPts->getVarRotAxisPts(), vec, MBTET));
4157 if (noStretch) {
4158 fe.getOpPtrVector().push_back(
4159 physicalEquations->returnOpCalculateVarStretchFromStress(
4161 } else {
4162 fe.getOpPtrVector().push_back(
4164 stretchTensor, dataAtPts->getVarLogStreachPts(), vec, MBTET));
4165 }
4166 }
4167
4168 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4169 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
4170 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4171 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
4172
4173 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4174 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
4175 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4176 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
4177 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldGradient<3, 3>(
4178 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
4179 // evaluate derived quantities
4180 fe.getOpPtrVector().push_back(
4182
4183 // evaluate integration points
4184 fe.getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
4185 tag, true, false, dataAtPts, physicalEquations));
4186 if (auto op =
4187 physicalEquations->returnOpCalculateEnergy(dataAtPts, nullptr)) {
4188 fe.getOpPtrVector().push_back(op);
4189 fe.getOpPtrVector().push_back(new OpCalculateEshelbyStress(dataAtPts));
4190 }
4191
4192 // // post-proc
4195 VolumeElementForcesAndSourcesCoreOnSide::UserDataOperator>;
4196
4197 struct OpSidePPMap : public OpPPMap {
4198 OpSidePPMap(moab::Interface &post_proc_mesh,
4199 std::vector<EntityHandle> &map_gauss_pts,
4200 DataMapVec data_map_scalar, DataMapMat data_map_vec,
4201 DataMapMat data_map_mat, DataMapMat data_symm_map_mat,
4202 int sense)
4203 : OpPPMap(post_proc_mesh, map_gauss_pts, data_map_scalar,
4204 data_map_vec, data_map_mat, data_symm_map_mat),
4205 tagSense(sense) {}
4206
4207 MoFEMErrorCode doWork(int side, EntityType type,
4210
4211 if (tagSense != 0) {
4212 if (tagSense != OpPPMap::getSkeletonSense())
4214 }
4215
4216 CHKERR OpPPMap::doWork(side, type, data);
4218 }
4219
4220 private:
4221 int tagSense;
4222 };
4223
4224 OpPPMap::DataMapMat vec_fields;
4225 vec_fields["SpatialDisplacementL2"] = dataAtPts->getSmallWL2AtPts();
4226 vec_fields["SpatialDisplacementH1"] = dataAtPts->getSmallWH1AtPts();
4227 vec_fields["Omega"] = dataAtPts->getRotAxisAtPts();
4228 vec_fields["AngularMomentum"] = dataAtPts->getLeviKirchhoffAtPts();
4229 vec_fields["X"] = dataAtPts->getLargeXH1AtPts();
4230 if (!noStretch) {
4231 vec_fields["EiegnLogStreach"] = dataAtPts->getEigenValsAtPts();
4232 }
4233 if (var_vector) {
4234 auto vec = SmartPetscObj<Vec>(var_vector, true);
4235 vec_fields["VarOmega"] = dataAtPts->getVarRotAxisPts();
4236 vec_fields["VarSpatialDisplacementL2"] =
4237 boost::make_shared<MatrixDouble>();
4238 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4239 spatialL2Disp, vec_fields["VarSpatialDisplacementL2"], vec, MBTET));
4240 }
4241 if (f_residual) {
4242 auto vec = SmartPetscObj<Vec>(f_residual, true);
4243 vec_fields["ResSpatialDisplacementL2"] =
4244 boost::make_shared<MatrixDouble>();
4245 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4246 spatialL2Disp, vec_fields["ResSpatialDisplacementL2"], vec, MBTET));
4247 vec_fields["ResOmega"] = boost::make_shared<MatrixDouble>();
4248 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4249 rotAxis, vec_fields["ResOmega"], vec, MBTET));
4250 }
4251
4252 OpPPMap::DataMapMat mat_fields;
4253 mat_fields["PiolaStress"] = dataAtPts->getApproxPAtPts();
4254 if (var_vector) {
4255 mat_fields["VarPiolaStress"] = dataAtPts->getVarPiolaPts();
4256 }
4257 if (f_residual) {
4258 auto vec = SmartPetscObj<Vec>(f_residual, true);
4259 mat_fields["ResPiolaStress"] = boost::make_shared<MatrixDouble>();
4260 fe.getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
4261 piolaStress, mat_fields["ResPiolaStress"],
4262 boost::make_shared<double>(1), vec));
4263 fe.getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
4264 bubbleField, mat_fields["ResPiolaStress"],
4265 boost::make_shared<double>(1), vec, MBMAXTYPE));
4266 }
4267 if (!internalStressTagName.empty()) {
4268 mat_fields[internalStressTagName] = dataAtPts->getInternalStressAtPts();
4269 switch (internalStressInterpOrder) {
4270 case 0:
4271 fe.getOpPtrVector().push_back(
4273 break;
4274 case 1:
4275 fe.getOpPtrVector().push_back(
4277 break;
4278 default:
4279 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
4280 "Unsupported internal stress interpolation order %d",
4282 }
4283 }
4284
4285 OpPPMap::DataMapMat mat_fields_symm;
4286 mat_fields_symm["LogSpatialStretch"] =
4287 dataAtPts->getLogStretchTensorAtPts();
4288 mat_fields_symm["SpatialStretch"] = dataAtPts->getStretchTensorAtPts();
4289 if (var_vector) {
4290 mat_fields_symm["VarLogSpatialStretch"] =
4291 dataAtPts->getVarLogStreachPts();
4292 }
4293 if (f_residual) {
4294 auto vec = SmartPetscObj<Vec>(f_residual, true);
4295 if (!noStretch) {
4296 mat_fields_symm["ResLogSpatialStretch"] =
4297 boost::make_shared<MatrixDouble>();
4298 fe.getOpPtrVector().push_back(
4300 stretchTensor, mat_fields_symm["ResLogSpatialStretch"], vec,
4301 MBTET));
4302 }
4303 }
4304
4305 fe.getOpPtrVector().push_back(
4306
4307 new OpSidePPMap(
4308
4309 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4310
4311 {},
4312
4313 vec_fields,
4314
4315 mat_fields,
4316
4317 mat_fields_symm,
4318
4319 sense
4320
4321 )
4322
4323 );
4324
4325 fe.getOpPtrVector().push_back(new OpPostProcDataStructure(
4326 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4327 dataAtPts, sense));
4328
4330 };
4331
4332 auto X_h1_ptr = boost::make_shared<MatrixDouble>();
4333 // H1 material positions
4334 post_proc_ptr->getOpPtrVector().push_back(
4336 dataAtPts->getLargeXH1AtPts()));
4337
4338 // domain
4341 domain_ops(*(op_loop_side->getSideFEPtr()), sense);
4342 post_proc_ptr->getOpPtrVector().push_back(op_loop_side);
4343
4344 return post_proc_ptr;
4345 };
4346
4347 // contact
4348 auto calcs_side_traction_and_displacements = [&](auto &post_proc_ptr,
4349 auto &pip) {
4351 // evaluate traction
4352 using EleOnSide =
4354 using SideEleOp = EleOnSide::UserDataOperator;
4355 auto op_loop_domain_side = new OpLoopSide<EleOnSide>(
4356 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
4357 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
4358 boost::shared_ptr<BaseFunction>(new CGGUserPolynomialBase());
4359 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4360 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
4362 auto traction_ptr = boost::make_shared<MatrixDouble>();
4363 op_loop_domain_side->getOpPtrVector().push_back(
4365 piolaStress, traction_ptr, boost::make_shared<double>(1.0)));
4366
4367 pip.push_back(new OpCalculateVectorFieldValues<3>(
4368 contactDisp, dataAtPts->getContactL2AtPts()));
4369 pip.push_back(op_loop_domain_side);
4370 // evaluate contact displacement and contact conditions
4371 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
4372 pip.push_back(new OpCalculateVectorFieldValues<3>(spatialH1Disp, u_h1_ptr));
4373 pip.push_back(getOpContactDetection(
4374 *this, contactTreeRhs, u_h1_ptr, traction_ptr,
4375 get_range_from_block(mField, "CONTACT", SPACE_DIM - 1),
4376 &post_proc_ptr->getPostProcMesh(), &post_proc_ptr->getMapGaussPts()));
4377
4379 using BoundaryEle =
4381 auto op_this = new OpLoopThis<BoundaryEle>(mField, contactElement);
4382 pip.push_back(op_this);
4383
4384 op_this->getOpPtrVector().push_back(
4385
4386 new OpPPMap(
4387
4388 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4389
4390 {},
4391
4392 {{"ContactDisplacement", dataAtPts->getContactL2AtPts()}},
4393
4394 {},
4395
4396 {}
4397
4398 )
4399
4400 );
4401
4402
4403 if (f_residual) {
4404
4405 auto contact_residual = boost::make_shared<MatrixDouble>();
4406 op_this->getOpPtrVector().push_back(
4408 contactDisp, contact_residual,
4409 SmartPetscObj<Vec>(f_residual, true)));
4410 op_this->getOpPtrVector().push_back(
4411
4412 new OpPPMap(
4413
4414 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4415
4416 {},
4417
4418 {{"res_contact", contact_residual}},
4419
4420 {},
4421
4422 {}
4423
4424 )
4425
4426 );
4427 }
4428
4430 };
4431
4432 auto post_proc_mesh = boost::make_shared<moab::Core>();
4433 auto post_proc_ptr = get_post_proc(post_proc_mesh, /*positive sense*/ 1);
4434 auto post_proc_negative_sense_ptr =
4435 get_post_proc(post_proc_mesh, /*negative sense*/ -1);
4436 auto skin_post_proc_ptr = get_post_proc(post_proc_mesh, /*positive sense*/ 1);
4437 CHKERR calcs_side_traction_and_displacements(
4438 skin_post_proc_ptr, skin_post_proc_ptr->getOpPtrVector());
4439
4440 auto own_tets =
4442 .subset_by_dimension(SPACE_DIM);
4443 Range own_faces;
4444 CHKERR mField.get_moab().get_adjacencies(own_tets, SPACE_DIM - 1, true,
4445 own_faces, moab::Interface::UNION);
4446
4447 auto get_crack_faces = [&](auto crack_faces) {
4448 auto get_adj = [&](auto e, auto dim) {
4449 Range adj;
4450 CHKERR mField.get_moab().get_adjacencies(e, dim, true, adj,
4451 moab::Interface::UNION);
4452 return adj;
4453 };
4454 // this removes faces
4455 auto tets = get_adj(crack_faces, 3);
4456 // faces adjacent to tets not in crack_faces
4457 auto faces = subtract(get_adj(tets, 2), crack_faces);
4458 // what is left from below, are tets fully inside crack_faces
4459 tets = subtract(tets, get_adj(faces, 3));
4460 return subtract(crack_faces, get_adj(tets, 2));
4461 };
4462
4463 auto side_one_faces = [&](auto &faces) {
4464 std::pair<Range, Range> sides;
4465 for (auto f : faces) {
4466 Range adj;
4467 MOAB_THROW(mField.get_moab().get_adjacencies(&f, 1, 3, false, adj));
4468 adj = intersect(own_tets, adj);
4469 for (auto t : adj) {
4470 int side, sense, offset;
4471 MOAB_THROW(mField.get_moab().side_number(t, f, side, sense, offset));
4472 if (sense == 1) {
4473 sides.first.insert(f);
4474 } else {
4475 sides.second.insert(f);
4476 }
4477 }
4478 }
4479 return sides;
4480 };
4481
4482 auto get_interface_from_block = [&](auto block_name) {
4483 auto vol_eles = get_range_from_block(mField, block_name, SPACE_DIM);
4484 auto skin = filter_true_skin(mField, get_skin(mField, vol_eles));
4485 Range faces;
4486 CHKERR mField.get_moab().get_adjacencies(vol_eles, SPACE_DIM - 1, true,
4487 faces, moab::Interface::UNION);
4488 faces = subtract(faces, skin);
4489 return faces;
4490 };
4491
4492 auto crack_faces = unite(get_crack_faces(*crackFaces), *interfaceFaces);
4493 crack_faces.merge(get_interface_from_block("VOLUME_INTERFACE"));
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 1481 of file EshelbianPlasticity.cpp.

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

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

920 {
921 *iface = const_cast<EshelbianCore *>(this);
922 return 0;
923}

◆ saveOrgCoords()

MoFEMErrorCode EshelbianCore::saveOrgCoords ( )

Definition at line 2432 of file EshelbianFracture.cpp.

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

◆ setBaseVolumeElementOps()

MoFEMErrorCode EshelbianCore::setBaseVolumeElementOps ( const int  tag,
const bool  do_rhs,
const bool  do_lhs,
const bool  calc_rates,
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 2710 of file EshelbianPlasticity.cpp.

2712 {
2714
2715 auto bubble_cache =
2716 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0, MatrixDouble());
2717 fe->getUserPolynomialBase() =
2718 boost::make_shared<CGGUserPolynomialBase>(bubble_cache);
2719 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2720 fe->getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions, frontAdjEdges);
2721
2722 // set integration rule
2723 fe->getRuleHook = [](int, int, int) { return -1; };
2724 auto vol_rule_lin = [](int o) { return 2 * o + 1; };
2725 auto vol_rule_no_lin = [](int o) { return 2 * o + (o - 1) + 1; };
2726 auto vol_rule = (SMALL_ROT > 0) ? vol_rule_lin : vol_rule_no_lin;
2727 fe->setRuleHook = SetIntegrationAtFrontVolume(frontVertices, frontAdjEdges,
2728 vol_rule, bubble_cache);
2729 // fe->getRuleHook = VolRule();
2730
2731 if (!dataAtPts) {
2732 dataAtPts =
2733 boost::shared_ptr<DataAtIntegrationPts>(new DataAtIntegrationPts());
2734 dataAtPts->physicsPtr = physicalEquations;
2735 }
2736
2737 // calculate fields values
2738 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
2739 piolaStress, dataAtPts->getApproxPAtPts()));
2740 fe->getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
2741 bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
2742 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorDivergence<3, 3>(
2743 piolaStress, dataAtPts->getDivPAtPts()));
2744
2745 if (noStretch) {
2746 fe->getOpPtrVector().push_back(
2747 physicalEquations->returnOpCalculateStretchFromStress(
2749 } else {
2750 fe->getOpPtrVector().push_back(
2752 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
2753 }
2754
2755 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2756 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
2757 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2758 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
2759 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2760 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
2761
2762 // H1 displacements
2763 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2764 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
2765 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldGradient<3, 3>(
2766 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
2767
2768 // velocities
2769 if (calc_rates) {
2770 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValuesDot<3>(
2771 spatialL2Disp, dataAtPts->getSmallWL2DotAtPts(), MBTET));
2772 if (noStretch) {
2773 } else {
2774 fe->getOpPtrVector().push_back(
2776 stretchTensor, dataAtPts->getLogStretchDotTensorAtPts(), MBTET));
2777 fe->getOpPtrVector().push_back(
2779 stretchTensor, dataAtPts->getGradLogStretchDotTensorAtPts(),
2780 MBTET));
2781 }
2782 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValuesDot<3>(
2783 rotAxis, dataAtPts->getRotAxisDotAtPts(), MBTET));
2784 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldGradientDot<3, 3>(
2785 rotAxis, dataAtPts->getRotAxisGradDotAtPts(), MBTET));
2786
2787 // acceleration
2788 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
2789 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValuesDotDot<3>(
2790 spatialL2Disp, dataAtPts->getSmallWL2DotDotAtPts(), MBTET));
2791 }
2792 }
2793
2794 // calculate other derived quantities
2795 fe->getOpPtrVector().push_back(new OpCalculateRotationAndSpatialGradient(
2796 dataAtPts, ((do_rhs || do_lhs) && calc_rates) ? alphaOmega : 0.));
2797
2798 // evaluate integration points
2799 if (noStretch) {
2800 } else {
2801 fe->getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
2802 tag, do_rhs, do_lhs, dataAtPts, physicalEquations));
2803 }
2804
2806}
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 3991 of file EshelbianPlasticity.cpp.

3991 {
3993
3994 auto set_block = [&](auto name, int dim) {
3995 std::map<int, Range> map;
3996 auto set_tag_impl = [&](auto name) {
3998 auto mesh_mng = mField.getInterface<MeshsetsManager>();
3999 auto bcs = mesh_mng->getCubitMeshsetPtr(
4000
4001 std::regex((boost::format("%s(.*)") % name).str())
4002
4003 );
4004 for (auto bc : bcs) {
4005 Range r;
4006 CHKERR bc->getMeshsetIdEntitiesByDimension(mField.get_moab(), dim, r,
4007 true);
4008 map[bc->getMeshsetId()] = r;
4009 MOFEM_LOG("EP", Sev::inform)
4010 << "Block " << name << " id " << bc->getMeshsetId() << " has "
4011 << r.size() << " entities";
4012 }
4014 };
4015
4016 CHKERR set_tag_impl(name);
4017
4018 return std::make_pair(name, map);
4019 };
4020
4021 auto set_skin = [&](auto &&map) {
4022 for (auto &m : map.second) {
4023 auto s = filter_true_skin(mField, get_skin(mField, m.second));
4024 m.second.swap(s);
4025 MOFEM_LOG("EP", Sev::inform)
4026 << "Skin for block " << map.first << " id " << m.first << " has "
4027 << m.second.size() << " entities";
4028 }
4029 return map;
4030 };
4031
4032 auto set_tag = [&](auto &&map) {
4033 Tag th;
4034 auto name = map.first;
4035 int def_val[] = {-1};
4037 mField.get_moab().tag_get_handle(name, 1, MB_TYPE_INTEGER, th,
4038 MB_TAG_SPARSE | MB_TAG_CREAT, def_val),
4039 "create tag");
4040 for (auto &m : map.second) {
4041 int id = m.first;
4042 CHK_MOAB_THROW(mField.get_moab().tag_clear_data(th, m.second, &id),
4043 "clear tag");
4044 }
4045 return th;
4046 };
4047
4048 listTagsToTransfer.push_back(set_tag(set_skin(set_block("BODY", 3))));
4049 listTagsToTransfer.push_back(set_tag(set_skin(set_block("MAT_ELASTIC", 3))));
4050 listTagsToTransfer.push_back(
4051 set_tag(set_skin(set_block("MAT_NEOHOOKEAN", 3))));
4052 listTagsToTransfer.push_back(set_tag(set_block("CONTACT", 2)));
4053
4055}
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 3546 of file EshelbianPlasticity.cpp.

3550 {
3552 fe_contact_tree = createContactDetectionFiniteElement(*this);
3554}
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 3556 of file EshelbianPlasticity.cpp.

3556 {
3558
3559 // Add contact operators. Note that only for rhs. THe lhs is assembled with
3560 // volume element, to enable schur complement evaluation.
3562
3565
3566 auto adj_cache =
3567 boost::make_shared<ForcesAndSourcesCore::UserDataOperator::AdjCache>();
3568
3569 auto get_op_contact_bc = [&]() {
3571 auto op_loop_side = new OpLoopSide<SideEle>(
3572 mField, contactElement, SPACE_DIM - 1, Sev::noisy, adj_cache);
3573 return op_loop_side;
3574 };
3575
3577}
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 3579 of file EshelbianPlasticity.cpp.

3579 {
3581 boost::shared_ptr<FEMethod> null;
3582
3583 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
3584
3586 null);
3588 null);
3590 null);
3592 null);
3593
3594 } else {
3596 null);
3598 null);
3600 null);
3602 null);
3603 }
3604
3606}
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 3379 of file EshelbianPlasticity.cpp.

3382 {
3384
3385 fe_rhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
3386 fe_lhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
3387
3388 // set integration rule
3389 // fe_rhs->getRuleHook = [](int, int, int p) { return 2 * (p + 1); };
3390 // fe_lhs->getRuleHook = [](int, int, int p) { return 2 * (p + 1); };
3391 fe_rhs->getRuleHook = [](int, int, int) { return -1; };
3392 fe_lhs->getRuleHook = [](int, int, int) { return -1; };
3393 fe_rhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3394 fe_lhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3395
3396 CHKERR
3397 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3398 fe_rhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
3399 CHKERR
3400 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3401 fe_lhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
3402
3403 if (add_elastic) {
3404
3405 auto get_broken_op_side = [this](auto &pip) {
3406 using EleOnSide =
3408 using SideEleOp = EleOnSide::UserDataOperator;
3409 // Iterate over domain FEs adjacent to boundary.
3410 auto broken_data_ptr =
3411 boost::make_shared<std::vector<BrokenBaseSideData>>();
3412 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
3413 auto op_loop_domain_side = new OpLoopSide<EleOnSide>(
3414 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
3415 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3416 boost::make_shared<CGGUserPolynomialBase>();
3417 CHKERR
3418 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3419 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3421 op_loop_domain_side->getOpPtrVector().push_back(
3422 new OpGetBrokenBaseSideData<SideEleOp>(piolaStress, broken_data_ptr));
3423 boost::shared_ptr<double> piola_scale_ptr(new double);
3424 op_loop_domain_side->getOpPtrVector().push_back(
3425 physicalEquations->returnOpSetScale(piola_scale_ptr,
3427 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
3428 op_loop_domain_side->getOpPtrVector().push_back(
3430 flux_mat_ptr));
3431 op_loop_domain_side->getOpPtrVector().push_back(
3432 new OpSetFlux<SideEleOp>(broken_data_ptr, flux_mat_ptr));
3433 pip.push_back(op_loop_domain_side);
3434 return std::make_tuple(broken_data_ptr, piola_scale_ptr);
3435 };
3436
3437 auto set_rhs = [&]() {
3439
3440 auto [broken_data_ptr, piola_scale_ptr] =
3441 get_broken_op_side(fe_rhs->getOpPtrVector());
3442
3443 fe_rhs->getOpPtrVector().push_back(
3444 new OpDispBc(broken_data_ptr, bcSpatialDispVecPtr, timeScaleMap));
3445 fe_rhs->getOpPtrVector().push_back(new OpAnalyticalDispBc(
3447 timeScaleMap));
3448 fe_rhs->getOpPtrVector().push_back(new OpRotationBc(
3449 broken_data_ptr, bcSpatialRotationVecPtr, timeScaleMap));
3450
3451 fe_rhs->getOpPtrVector().push_back(
3453 piola_scale_ptr, timeScaleMap));
3454 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
3455 // if you push gradient of L2 base to physical element, it will not work.
3456 fe_rhs->getOpPtrVector().push_back(
3458 hybridSpatialDisp, hybrid_grad_ptr));
3459 fe_rhs->getOpPtrVector().push_back(new OpBrokenPressureBc(
3461 hybrid_grad_ptr, timeScaleMap));
3462 fe_rhs->getOpPtrVector().push_back(new OpBrokenAnalyticalTractionBc(
3464 timeScaleMap));
3465
3466 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3467 fe_rhs->getOpPtrVector().push_back(
3469 hybrid_ptr));
3470 fe_rhs->getOpPtrVector().push_back(new OpNormalDispRhsBc(
3471 hybridSpatialDisp, hybrid_ptr, broken_data_ptr,
3473
3474 auto get_normal_disp_bc_faces = [&]() {
3475 auto faces =
3476 get_range_from_block(mField, "NORMAL_DISPLACEMENT", SPACE_DIM - 1);
3477 return boost::make_shared<Range>(faces);
3478 };
3479
3480 using BoundaryEle =
3482 using BdyEleOp = BoundaryEle::UserDataOperator;
3484 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
3485 fe_rhs->getOpPtrVector().push_back(new OpC_dBroken(
3486 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0),
3487 get_normal_disp_bc_faces()));
3488
3490 };
3491
3492 auto set_lhs = [&]() {
3494
3495 auto [broken_data_ptr, piola_scale_ptr] =
3496 get_broken_op_side(fe_lhs->getOpPtrVector());
3497
3498 fe_lhs->getOpPtrVector().push_back(new OpNormalDispLhsBc_dU(
3500 fe_lhs->getOpPtrVector().push_back(new OpNormalDispLhsBc_dP(
3502 timeScaleMap));
3503
3504 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
3505 // if you push gradient of L2 base to physical element, it will not work.
3506 fe_lhs->getOpPtrVector().push_back(
3508 hybridSpatialDisp, hybrid_grad_ptr));
3509 fe_lhs->getOpPtrVector().push_back(new OpBrokenPressureBcLhs_dU(
3511 timeScaleMap));
3512
3513 auto get_normal_disp_bc_faces = [&]() {
3514 auto faces =
3515 get_range_from_block(mField, "NORMAL_DISPLACEMENT", SPACE_DIM - 1);
3516 return boost::make_shared<Range>(faces);
3517 };
3518
3519 using BoundaryEle =
3521 using BdyEleOp = BoundaryEle::UserDataOperator;
3523 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
3524 fe_lhs->getOpPtrVector().push_back(new OpC(
3525 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0),
3526 true, true, get_normal_disp_bc_faces()));
3527
3529 };
3530
3531 CHKERR set_rhs();
3532 CHKERR set_lhs();
3533 }
3534
3536}
MoFEM::OpBrokenTopoBase 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 1660 of file EshelbianFracture.cpp.

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

◆ 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 2808 of file EshelbianPlasticity.cpp.

2811 {
2813
2814 /** Contact requires that body is marked */
2815 auto get_body_range = [this](auto name, int dim) {
2816 std::map<int, Range> map;
2817
2818 for (auto m_ptr :
2819 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
2820
2821 (boost::format("%s(.*)") % name).str()
2822
2823 ))
2824
2825 ) {
2826 Range ents;
2827 CHK_MOAB_THROW(m_ptr->getMeshsetIdEntitiesByDimension(mField.get_moab(),
2828 dim, ents, true),
2829 "by dim");
2830 map[m_ptr->getMeshsetId()] = ents;
2831 }
2832
2833 return map;
2834 };
2835
2836 constexpr bool stab_tau_dot_variant = false;
2837
2838 auto local_tau_sacale = boost::make_shared<double>(1.0);
2839 using BoundaryEle =
2841 using BdyEleOp = BoundaryEle::UserDataOperator;
2842 auto set_scale_op = new BdyEleOp(NOSPACE, BdyEleOp::OPSPACE);
2843 set_scale_op->doWorkRhsHook =
2844 [this,
2845 local_tau_sacale](DataOperator *raw_op_ptr, int side, EntityType type,
2848 auto op_ptr = static_cast<BdyEleOp *>(raw_op_ptr);
2849 auto h = std::sqrt(op_ptr->getFTensor1Normal().l2());
2850 *local_tau_sacale = (alphaTau / h);
2852 };
2853
2854 auto not_interface_face = [this](FEMethod *fe_method_ptr) {
2855 auto ent = fe_method_ptr->getFEEntityHandle();
2856 if (
2857
2858 (interfaceFaces->find(ent) != interfaceFaces->end())
2859
2860 || (crackFaces->find(ent) != crackFaces->end())
2861
2862 ) {
2863 return false;
2864 };
2865 return true;
2866 };
2867
2868 // Right hand side
2869 fe_rhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
2870 CHKERR setBaseVolumeElementOps(tag, true, false, true, fe_rhs);
2871
2872 // elastic
2873 if (add_elastic) {
2874
2875 fe_rhs->getOpPtrVector().push_back(
2877 fe_rhs->getOpPtrVector().push_back(
2879 if (noStretch) {
2880 // do nothing - no stretch approximation
2881 } else {
2882 if (!internalStressTagName.empty()) {
2883 switch (internalStressInterpOrder) {
2884 case 0:
2885 fe_rhs->getOpPtrVector().push_back(
2887 break;
2888 case 1:
2889 fe_rhs->getOpPtrVector().push_back(
2891 break;
2892 default:
2893 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
2894 "Unsupported internal stress interpolation order %d",
2896 }
2897 // set default time scaling for interal stresses to constant
2898 TimeScale::ScalingFun def_scaling_fun = [](double time) { return 1; };
2899 auto ts_internal_stress =
2900 boost::make_shared<DynamicRelaxationTimeScale>(
2901 "internal_stress_history.txt", false, def_scaling_fun);
2902 if (internalStressVoigt) {
2903 fe_rhs->getOpPtrVector().push_back(
2905 stretchTensor, dataAtPts, ts_internal_stress));
2906 } else {
2907 fe_rhs->getOpPtrVector().push_back(
2909 stretchTensor, dataAtPts, ts_internal_stress));
2910 }
2911 }
2912 if (auto op = physicalEquations->returnOpSpatialPhysicalExternalStrain(
2914 fe_rhs->getOpPtrVector().push_back(op);
2915 } else if (externalStrainVecPtr && !externalStrainVecPtr->empty()) {
2916 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
2917 "OpSpatialPhysicalExternalStrain not implemented for this "
2918 "material");
2919 }
2920
2921 fe_rhs->getOpPtrVector().push_back(
2922 physicalEquations->returnOpSpatialPhysical(stretchTensor, dataAtPts,
2923 alphaU));
2924 }
2925 fe_rhs->getOpPtrVector().push_back(
2927 fe_rhs->getOpPtrVector().push_back(
2929 fe_rhs->getOpPtrVector().push_back(
2931
2932 auto set_hybridisation_rhs = [&](auto &pip) {
2934
2935 using BoundaryEle =
2937 using EleOnSide =
2939 using SideEleOp = EleOnSide::UserDataOperator;
2940 using BdyEleOp = BoundaryEle::UserDataOperator;
2941
2942 // First: Iterate over skeleton FEs adjacent to Domain FEs
2943 // Note: BoundaryEle, i.e. uses skeleton interation rule
2944 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
2945 mField, skeletonElement, SPACE_DIM - 1, Sev::noisy);
2946 // op_loop_skeleton_side->getSideFEPtr()->getRuleHook = FaceRule();
2947 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
2948 return -1;
2949 };
2950 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
2951 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
2952
2953 CHKERR EshelbianPlasticity::
2954 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2955 op_loop_skeleton_side->getOpPtrVector(), {L2},
2957
2958 // Second: Iterate over domain FEs adjacent to skelton, particularly one
2959 // domain element.
2960 auto broken_data_ptr =
2961 boost::make_shared<std::vector<BrokenBaseSideData>>();
2962 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
2963 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
2964 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
2965 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2966 boost::make_shared<CGGUserPolynomialBase>();
2967 CHKERR
2968 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2969 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2971 op_loop_domain_side->getOpPtrVector().push_back(
2972 new OpGetBrokenBaseSideData<SideEleOp>(piolaStress, broken_data_ptr));
2973 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
2974 op_loop_domain_side->getOpPtrVector().push_back(
2976 flux_mat_ptr));
2977 op_loop_domain_side->getOpPtrVector().push_back(
2978 new OpSetFlux<SideEleOp>(broken_data_ptr, flux_mat_ptr));
2979
2980 // Assemble on skeleton
2981 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
2983 GAUSS>::OpBrokenSpaceConstrainDHybrid<SPACE_DIM>;
2985 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
2986 op_loop_skeleton_side->getOpPtrVector().push_back(new OpC_dHybrid(
2987 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0)));
2988 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
2989 op_loop_skeleton_side->getOpPtrVector().push_back(
2991 hybrid_ptr));
2992 op_loop_skeleton_side->getOpPtrVector().push_back(new OpC_dBroken(
2993 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0)));
2994
2995 // Add skeleton to domain pipeline
2996 pip.push_back(op_loop_skeleton_side);
2997
2999 };
3000
3001 auto set_tau_stabilsation_rhs = [&](auto &pip, auto side_fe_name,
3002 auto hybrid_field) {
3004
3005 using BoundaryEle =
3007 using EleOnSide =
3009 using SideEleOp = EleOnSide::UserDataOperator;
3010 using BdyEleOp = BoundaryEle::UserDataOperator;
3011
3012 // First: Iterate over skeleton FEs adjacent to Domain FEs
3013 // Note: BoundaryEle, i.e. uses skeleton interation rule
3014 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
3015 mField, side_fe_name, SPACE_DIM - 1, Sev::noisy);
3016 // op_loop_skeleton_side->getSideFEPtr()->getRuleHook = FaceRule();
3017 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3018 return -1;
3019 };
3020 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3021 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3022 CHKERR EshelbianPlasticity::
3023 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3024 op_loop_skeleton_side->getOpPtrVector(), {L2},
3026
3027 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
3028 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
3029 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3030 boost::make_shared<CGGUserPolynomialBase>();
3031 CHKERR
3032 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3033 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3035
3036 // Add stabilization operator
3037 auto broken_disp_data_ptr =
3038 boost::make_shared<std::vector<BrokenBaseSideData>>();
3039 op_loop_domain_side->getOpPtrVector().push_back(
3041 broken_disp_data_ptr));
3042 auto disp_mat_ptr = boost::make_shared<MatrixDouble>();
3043 if (stab_tau_dot_variant) {
3044 op_loop_domain_side->getOpPtrVector().push_back(
3046 disp_mat_ptr));
3047 } else {
3048 op_loop_domain_side->getOpPtrVector().push_back(
3050 disp_mat_ptr));
3051 }
3052 // Set diag fluxes on skeleton side
3053 op_loop_domain_side->getOpPtrVector().push_back(
3054 new OpSetFlux<SideEleOp>(broken_disp_data_ptr, disp_mat_ptr));
3055
3056 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3057 op_loop_skeleton_side->getOpPtrVector().push_back(set_scale_op);
3058
3059 // Add stabilization Ugamma Ugamma skeleton
3060 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3061 if (stab_tau_dot_variant) {
3062 op_loop_skeleton_side->getOpPtrVector().push_back(
3064 hybrid_ptr));
3065 } else {
3066 op_loop_skeleton_side->getOpPtrVector().push_back(
3068 hybrid_ptr));
3069 }
3070
3071 // Diag u_gamma - u_gamma faces
3072 op_loop_skeleton_side->getOpPtrVector().push_back(
3074 hybrid_field, hybrid_ptr,
3075 [local_tau_sacale, broken_disp_data_ptr](double, double, double) {
3076 return broken_disp_data_ptr->size() * (*local_tau_sacale);
3077 }));
3078 // Diag L2 - L2 volumes
3079 op_loop_skeleton_side->getOpPtrVector().push_back(
3081 broken_disp_data_ptr, [local_tau_sacale](double, double, double) {
3082 return (*local_tau_sacale);
3083 }));
3084 // Off-diag Ugamma - L2
3085 op_loop_skeleton_side->getOpPtrVector().push_back(
3087 hybrid_field, broken_disp_data_ptr,
3088 [local_tau_sacale](double, double, double) {
3089 return -(*local_tau_sacale);
3090 }));
3091 // Off-diag L2 - Ugamma
3092 op_loop_skeleton_side->getOpPtrVector().push_back(
3094 broken_disp_data_ptr, hybrid_ptr,
3095 [local_tau_sacale](double, double, double) {
3096 return -(*local_tau_sacale);
3097 }));
3098
3099 // Add skeleton to domain pipeline
3100 pip.push_back(op_loop_skeleton_side);
3101
3103 };
3104
3105 auto set_contact_rhs = [&](auto &pip) {
3106 return pushContactOpsRhs(*this, contactTreeRhs, pip);
3107 };
3108
3109 auto set_cohesive_rhs = [&](auto &pip) {
3110 return pushCohesiveOpsRhs(
3111 *this,
3112 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges,
3113 [](int p) { return 2 * (p + 1) + 1; }),
3114 interfaceFaces, pip);
3115 };
3116
3117 CHKERR set_hybridisation_rhs(fe_rhs->getOpPtrVector());
3118 CHKERR set_contact_rhs(fe_rhs->getOpPtrVector());
3119 if (alphaTau > 0.0) {
3120 CHKERR set_tau_stabilsation_rhs(fe_rhs->getOpPtrVector(), skeletonElement,
3122 CHKERR set_tau_stabilsation_rhs(fe_rhs->getOpPtrVector(), contactElement,
3123 contactDisp);
3124 }
3125 if (interfaceCrack == PETSC_TRUE) {
3126 CHKERR set_cohesive_rhs(fe_rhs->getOpPtrVector());
3127 }
3128
3129 // Body forces
3130 using BodyNaturalBC =
3132 Assembly<PETSC>::LinearForm<GAUSS>;
3133 using OpBodyForce =
3134 BodyNaturalBC::OpFlux<NaturalMeshsetType<BLOCKSET>, 1, 3>;
3135
3136 auto body_time_scale =
3137 boost::make_shared<DynamicRelaxationTimeScale>("body_force.txt");
3138 CHKERR BodyNaturalBC::AddFluxToPipeline<OpBodyForce>::add(
3139 fe_rhs->getOpPtrVector(), mField, spatialL2Disp, {body_time_scale},
3140 "BODY_FORCE", Sev::inform);
3141 }
3142
3143 // Left hand side
3144 fe_lhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
3145 CHKERR setBaseVolumeElementOps(tag, true, true, true, fe_lhs);
3146
3147 // elastic
3148 if (add_elastic) {
3149
3150 if (noStretch) {
3151 fe_lhs->getOpPtrVector().push_back(
3153 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dBubble_dP(
3155 fe_lhs->getOpPtrVector().push_back(
3157 dataAtPts));
3158 } else {
3159 fe_lhs->getOpPtrVector().push_back(
3160 physicalEquations->returnOpSpatialPhysical_du_du(
3162 fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_dP(
3164 fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_dBubble(
3166 fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_domega(
3168 symmetrySelector == SYMMETRIC ? true : false));
3169 }
3170
3171 fe_lhs->getOpPtrVector().push_back(new OpSpatialEquilibrium_dw_dP(
3173 fe_lhs->getOpPtrVector().push_back(new OpSpatialEquilibrium_dw_dw(
3175
3176 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dP_domega(
3178 symmetrySelector == SYMMETRIC ? true : false));
3179 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dBubble_domega(
3181 symmetrySelector == SYMMETRIC ? true : false));
3182
3183 if (symmetrySelector > SYMMETRIC) {
3184 if (!noStretch) {
3185 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_du(
3186 rotAxis, stretchTensor, dataAtPts, false));
3187 }
3188 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_dP(
3189 rotAxis, piolaStress, dataAtPts, false));
3190 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_dBubble(
3191 rotAxis, bubbleField, dataAtPts, false));
3192 }
3193 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_domega(
3195
3196 auto set_hybridisation_lhs = [&](auto &pip) {
3198
3199 using BoundaryEle =
3201 using EleOnSide =
3203 using SideEleOp = EleOnSide::UserDataOperator;
3204 using BdyEleOp = BoundaryEle::UserDataOperator;
3205
3206 // First: Iterate over skeleton FEs adjacent to Domain FEs
3207 // Note: BoundaryEle, i.e. uses skeleton interation rule
3208 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
3209 mField, skeletonElement, SPACE_DIM - 1, Sev::noisy);
3210 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3211 return -1;
3212 };
3213 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3214 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3215 CHKERR EshelbianPlasticity::
3216 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3217 op_loop_skeleton_side->getOpPtrVector(), {L2},
3219
3220 // Second: Iterate over domain FEs adjacent to skelton, particularly one
3221 // domain element.
3222 auto broken_data_ptr =
3223 boost::make_shared<std::vector<BrokenBaseSideData>>();
3224 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
3225 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
3226 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
3227 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3228 boost::make_shared<CGGUserPolynomialBase>();
3229 CHKERR
3230 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3231 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3233 op_loop_domain_side->getOpPtrVector().push_back(
3234 new OpGetBrokenBaseSideData<SideEleOp>(piolaStress, broken_data_ptr));
3235
3236 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3238 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
3239 op_loop_skeleton_side->getOpPtrVector().push_back(
3240 new OpC(hybridSpatialDisp, broken_data_ptr,
3241 boost::make_shared<double>(1.0), true, false));
3242
3243 pip.push_back(op_loop_skeleton_side);
3244
3246 };
3247
3248 auto set_tau_stabilsation_lhs = [&](auto &pip, auto side_fe_name,
3249 auto hybrid_field) {
3251
3252 using BoundaryEle =
3254 using EleOnSide =
3256 using SideEleOp = EleOnSide::UserDataOperator;
3257 using BdyEleOp = BoundaryEle::UserDataOperator;
3258
3259 // First: Iterate over skeleton FEs adjacent to Domain FEs
3260 // Note: BoundaryEle, i.e. uses skeleton interation rule
3261 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
3262 mField, side_fe_name, SPACE_DIM - 1, Sev::noisy);
3263 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3264 return -1;
3265 };
3266 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3267 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3268 CHKERR EshelbianPlasticity::
3269 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3270 op_loop_skeleton_side->getOpPtrVector(), {L2},
3272
3273 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
3274 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
3275 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
3276 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3277 boost::make_shared<CGGUserPolynomialBase>();
3278 CHKERR
3279 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3280 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3282
3283 auto broken_disp_data_ptr =
3284 boost::make_shared<std::vector<BrokenBaseSideData>>();
3285 op_loop_domain_side->getOpPtrVector().push_back(
3287 broken_disp_data_ptr));
3288 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3289 op_loop_skeleton_side->getOpPtrVector().push_back(set_scale_op);
3290
3291 auto time_shift = [](const FEMethod *fe_ptr) { return fe_ptr->ts_a; };
3292
3293 // Diag Ugamma-Ugamma skeleton
3294 op_loop_skeleton_side->getOpPtrVector().push_back(new OpMassVectorFace(
3295 hybrid_field, hybrid_field,
3296 [local_tau_sacale, broken_disp_data_ptr](double, double, double) {
3297 return broken_disp_data_ptr->size() * (*local_tau_sacale);
3298 }));
3299 if (stab_tau_dot_variant) {
3300 static_cast<OpMassVectorFace &>(
3301 op_loop_skeleton_side->getOpPtrVector().back())
3302 .feScalingFun = time_shift;
3303 }
3304 // Diag L2-L2 volumes
3305 op_loop_skeleton_side->getOpPtrVector().push_back(
3307 broken_disp_data_ptr, [local_tau_sacale](double, double, double) {
3308 return (*local_tau_sacale);
3309 }));
3310 if (stab_tau_dot_variant) {
3311 static_cast<OpBrokenBaseBrokenBase &>(
3312 op_loop_skeleton_side->getOpPtrVector().back())
3313 .feScalingFun = time_shift;
3314 }
3315 // Off-diag Ugamma - L2
3316 op_loop_skeleton_side->getOpPtrVector().push_back(
3318 hybrid_field, broken_disp_data_ptr,
3319 [local_tau_sacale](double, double, double) {
3320 return -(*local_tau_sacale);
3321 },
3322 false, false));
3323 if (stab_tau_dot_variant) {
3324 static_cast<OpHyrbridBaseBrokenBase &>(
3325 op_loop_skeleton_side->getOpPtrVector().back())
3326 .feScalingFun = time_shift;
3327 }
3328
3329 // Off-diag L2 - Ugamma
3330 op_loop_skeleton_side->getOpPtrVector().push_back(
3332 hybrid_field, broken_disp_data_ptr,
3333 [local_tau_sacale](double, double, double) {
3334 return -(*local_tau_sacale);
3335 },
3336 true, true));
3337 if (stab_tau_dot_variant) {
3338 static_cast<OpHyrbridBaseBrokenBase &>(
3339 op_loop_skeleton_side->getOpPtrVector().back())
3340 .feScalingFun = time_shift;
3341 }
3342
3343 pip.push_back(op_loop_skeleton_side);
3344
3346 };
3347
3348 auto set_contact_lhs = [&](auto &pip) {
3349 return pushContactOpsLhs(*this, contactTreeRhs, pip);
3350 };
3351
3352 auto set_cohesive_lhs = [&](auto &pip) {
3353 return pushCohesiveOpsLhs(
3354 *this,
3355 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges,
3356 [](int p) { return 2 * (p + 1) + 1; }),
3357 interfaceFaces, pip);
3358 };
3359
3360 CHKERR set_hybridisation_lhs(fe_lhs->getOpPtrVector());
3361 CHKERR set_contact_lhs(fe_lhs->getOpPtrVector());
3362 if (alphaTau > 0.0) {
3363 CHKERR set_tau_stabilsation_lhs(fe_lhs->getOpPtrVector(), skeletonElement,
3365 CHKERR set_tau_stabilsation_lhs(fe_lhs->getOpPtrVector(), contactElement,
3366 contactDisp);
3367 }
3368 if (interfaceCrack == PETSC_TRUE) {
3369 CHKERR set_cohesive_lhs(fe_lhs->getOpPtrVector());
3370 }
3371 }
3372
3373 if (add_material) {
3374 }
3375
3377}
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, 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();
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);
5142
5143
5144 CHKERR DMoFEMMeshToLocalVector(dmElastic, x, INSERT_VALUES,
5145 SCATTER_FORWARD);
5146 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
5147 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
5148 monitor_ptr->ts_u = x;
5149 monitor_ptr->ts_t = dynamicTime;
5150 monitor_ptr->ts_step = dynamicStep;
5152
5153 ++dynamicStep;
5154 if (dynamicStep > max_it)
5155 break;
5156 }
5157
5158 CHKERR TSElasticPostStep::postStepDestroy();
5159 TetPolynomialBase::switchCacheBaseOff<HDIV>(
5160 {elasticFeLhs.get(), elasticFeRhs.get()});
5161
5163}
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.
static MoFEMErrorCode setVectorFromTag(moab::Interface &moab, EntitiesPetscVector &vec, Tag tag)
static MoFEMErrorCode setTagFromVector(moab::Interface &moab, EntitiesPetscVector &vec, Tag tag)

◆ 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 3885 of file EshelbianPlasticity.cpp.

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

◆ 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 3780 of file EshelbianPlasticity.cpp.

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

Friends And Related Symbol Documentation

◆ solve_elastic_set_up

friend struct solve_elastic_set_up
friend

Definition at line 390 of file EshelbianCore.hpp.

Member Data Documentation

◆ a00FieldList

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

Definition at line 497 of file EshelbianCore.hpp.

◆ a00RangeList

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

Definition at line 499 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 495 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 481 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 478 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 496 of file EshelbianCore.hpp.

◆ crackingAtol

double EshelbianCore::crackingAtol = 1e-12
inlinestatic

◆ crackingOn

PetscBool EshelbianCore::crackingOn = PETSC_FALSE
inlinestatic

◆ crackingRtol

double EshelbianCore::crackingRtol = 1e-10
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

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

◆ interfaceCrack

PetscBool EshelbianCore::interfaceCrack
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 471 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 501 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 494 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 66 of file EshelbianCore.hpp.

◆ v_max

constexpr double EshelbianCore::v_max = 24
inlinestaticconstexpr

Definition at line 67 of file EshelbianCore.hpp.

◆ v_min

constexpr double EshelbianCore::v_min = -v_max
inlinestaticconstexpr

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