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 , ShapeOptimization ,
  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, double time=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 solveSchapeOptimisation (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={}, TS ts=PETSC_NULLPTR)
 
MoFEMErrorCode postProcessSkeletonResults (const int tag, const std::string file, Vec f_residual=PETSC_NULLPTR, std::vector< Tag > tags_to_transfer={})
 
MoFEMErrorCode calculateCrackArea (boost::shared_ptr< double > area_ptr)
 
MoFEMErrorCode gettingNorms ()
 [Getting norms]
 
MoFEMErrorCode calculateFaceMaterialForce (const int tag, TS ts)
 
MoFEMErrorCode calculateOrientation (const int tag, bool set_orientation)
 
MoFEMErrorCode setNewFrontCoordinates ()
 
MoFEMErrorCode addCrackSurfaces (const bool debug=false)
 
MoFEMErrorCode saveOrgCoords ()
 
MoFEMErrorCode createCrackSurfaceMeshset ()
 
- Public Member Functions inherited from MoFEM::UnknownInterface
virtual MoFEMErrorCode query_interface (boost::typeindex::type_index type_index, UnknownInterface **iface) const =0
 
template<class IFACE >
MoFEMErrorCode registerInterface (bool error_if_registration_failed=true)
 Register interface.
 
template<class IFACE >
MoFEMErrorCode getInterface (IFACE *&iface) const
 Get interface reference to pointer of interface.
 
template<class IFACE >
MoFEMErrorCode getInterface (IFACE **const iface) const
 Get interface pointer to pointer of interface.
 
template<class IFACE , typename boost::enable_if< boost::is_pointer< IFACE >, int >::type = 0>
IFACE getInterface () const
 Get interface pointer to pointer of interface.
 
template<class IFACE , typename boost::enable_if< boost::is_reference< IFACE >, int >::type = 0>
IFACE getInterface () const
 Get reference to interface.
 
template<class IFACE >
IFACE * getInterface () const
 Function returning pointer to interface.
 
virtual ~UnknownInterface ()=default
 

Static Public Member Functions

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

Public Attributes

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

Static Public Attributes

static const char * listSolvers []
 
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 double crackingAddTime = 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 int interfaceRemoveLevel
 
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 958 of file EshelbianPlasticity.cpp.

958 : mField(m_field) {
959 CHK_THROW_MESSAGE(getOptions(), "getOptions failed");
960}
#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 2235 of file EshelbianPlasticity.cpp.

2235 {
2237
2238 Range meshset_ents;
2239 CHKERR mField.get_moab().get_entities_by_handle(meshset, meshset_ents);
2240
2241 auto set_fe_adjacency = [&](auto fe_name) {
2244 boost::make_shared<ParentFiniteElementAdjacencyFunctionSkeleton<2>>(
2247 fe_name, MBTRI, *parentAdjSkeletonFunctionDim2);
2249 };
2250
2251 // set finite element fields
2252 auto add_field_to_fe = [this](const std::string fe,
2253 const std::string field_name) {
2262 };
2263
2265
2266 Range natural_bc_elements;
2267 if (bcSpatialDispVecPtr) {
2268 for (auto &v : *bcSpatialDispVecPtr) {
2269 natural_bc_elements.merge(v.faces);
2270 }
2271 }
2273 for (auto &v : *bcSpatialRotationVecPtr) {
2274 natural_bc_elements.merge(v.faces);
2275 }
2276 }
2278 for (auto &v : *bcSpatialNormalDisplacementVecPtr) {
2279 natural_bc_elements.merge(v.faces);
2280 }
2281 }
2284 natural_bc_elements.merge(v.faces);
2285 }
2286 }
2288 for (auto &v : *bcSpatialTractionVecPtr) {
2289 natural_bc_elements.merge(v.faces);
2290 }
2291 }
2293 for (auto &v : *bcSpatialAnalyticalTractionVecPtr) {
2294 natural_bc_elements.merge(v.faces);
2295 }
2296 }
2298 for (auto &v : *bcSpatialPressureVecPtr) {
2299 natural_bc_elements.merge(v.faces);
2300 }
2301 }
2302 natural_bc_elements = intersect(natural_bc_elements, meshset_ents);
2303
2305 CHKERR mField.add_ents_to_finite_element_by_type(natural_bc_elements, MBTRI,
2307 CHKERR add_field_to_fe(naturalBcElement, piolaStress);
2308 CHKERR add_field_to_fe(naturalBcElement, hybridSpatialDisp);
2309 CHKERR set_fe_adjacency(naturalBcElement);
2311 }
2312
2313 auto get_skin = [&](auto &body_ents) {
2314 Skinner skin(&mField.get_moab());
2315 Range skin_ents;
2316 CHKERR skin.find_skin(0, body_ents, false, skin_ents);
2317 return skin_ents;
2318 };
2319
2320 auto filter_true_skin = [&](auto &&skin) {
2321 Range boundary_ents;
2322 ParallelComm *pcomm =
2323 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
2324 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
2325 PSTATUS_NOT, -1, &boundary_ents);
2326 return boundary_ents;
2327 };
2328
2330
2331 Range body_ents;
2332 CHKERR mField.get_moab().get_entities_by_dimension(meshset, SPACE_DIM,
2333 body_ents);
2334 auto skin = filter_true_skin(get_skin(body_ents));
2335
2343 contactDisp);
2346
2348 }
2349
2351 if (contactFaces) {
2352 MOFEM_LOG("EP", Sev::inform)
2353 << "Contact elements " << contactFaces->size();
2357 CHKERR add_field_to_fe(contactElement, piolaStress);
2358 CHKERR add_field_to_fe(contactElement, contactDisp);
2359 CHKERR add_field_to_fe(contactElement, spatialL2Disp);
2360 CHKERR add_field_to_fe(contactElement, spatialH1Disp);
2361 CHKERR set_fe_adjacency(contactElement);
2363 }
2364 }
2365
2367 if (!skeletonFaces)
2368 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "No skeleton faces");
2369 MOFEM_LOG("EP", Sev::inform)
2370 << "Skeleton elements " << skeletonFaces->size();
2374 CHKERR add_field_to_fe(skeletonElement, piolaStress);
2375 CHKERR add_field_to_fe(skeletonElement, hybridSpatialDisp);
2376 CHKERR add_field_to_fe(skeletonElement, spatialL2Disp);
2377 CHKERR add_field_to_fe(skeletonElement, spatialH1Disp);
2378 CHKERR set_fe_adjacency(skeletonElement);
2380 }
2381
2383}
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 1696 of file EshelbianFracture.cpp.

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

3827 {
3829
3830 PetscBool debug_model = PETSC_FALSE;
3831 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-debug_model", &debug_model,
3832 PETSC_NULLPTR);
3833 MOFEM_LOG("EP", Sev::inform)
3834 << "Debug model flag is " << (debug_model ? "ON" : "OFF");
3835
3836 if (debug_model == PETSC_TRUE) {
3837 auto ts_ctx_ptr = getDMTsCtx(dmElastic);
3838 auto post_proc = [&](TS ts, PetscReal t, Vec u, Vec u_t, Vec u_tt, Vec F,
3839 void *ctx) {
3841
3842 SNES snes;
3843 CHKERR TSGetSNES(ts, &snes);
3844 int it;
3845 CHKERR SNESGetIterationNumber(snes, &it);
3846 std::string file_name = "snes_iteration_" + std::to_string(it) + ".h5m";
3847 CHKERR postProcessResults(1, file_name, F, u_t);
3848 std::string file_skel_name =
3849 "snes_iteration_skel_" + std::to_string(it) + ".h5m";
3850
3851 auto get_material_force_tag = [&]() {
3852 auto &moab = mField.get_moab();
3853 Tag tag;
3854 CHK_MOAB_THROW(moab.tag_get_handle("MaterialForce", tag),
3855 "can't get tag");
3856 return tag;
3857 };
3858
3860 CHKERR postProcessSkeletonResults(1, file_skel_name, F,
3861 {get_material_force_tag()});
3862
3864 };
3865 ts_ctx_ptr->tsDebugHook = post_proc;
3866 }
3867
3869}
@ F
const FTensor::Tensor2< T, Dim, Dim > Vec
auto getDMTsCtx(DM dm)
Get TS context data structure used by DM.
Definition DMMoFEM.hpp:1279
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
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={}, TS ts=PETSC_NULLPTR)
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={})
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 2385 of file EshelbianPlasticity.cpp.

2386 {
2388
2389 // find adjacencies between finite elements and dofs
2391
2392 // Create coupled problem
2393 dM = createDM(mField.get_comm(), "DMMOFEM");
2394 CHKERR DMMoFEMCreateMoFEM(dM, &mField, "ESHELBY_PLASTICITY", bit,
2395 BitRefLevel().set());
2396 CHKERR DMMoFEMSetDestroyProblem(dM, PETSC_TRUE);
2397 CHKERR DMMoFEMSetIsPartitioned(dM, PETSC_TRUE);
2403
2404 mField.getInterface<ProblemsManager>()->buildProblemFromFields = PETSC_TRUE;
2405 CHKERR DMSetUp(dM);
2406 mField.getInterface<ProblemsManager>()->buildProblemFromFields = PETSC_FALSE;
2407
2408 auto remove_dofs_on_broken_skin = [&](const std::string prb_name) {
2410 for (int d : {0, 1, 2}) {
2411 std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_to_remove;
2413 ->getSideDofsOnBrokenSpaceEntities(
2414 dofs_to_remove, prb_name, ROW, piolaStress,
2416 // remove piola dofs, i.e. traction free boundary
2417 CHKERR mField.getInterface<ProblemsManager>()->removeDofs(prb_name, ROW,
2418 dofs_to_remove);
2419 CHKERR mField.getInterface<ProblemsManager>()->removeDofs(prb_name, COL,
2420 dofs_to_remove);
2421 }
2423 };
2424 CHKERR remove_dofs_on_broken_skin("ESHELBY_PLASTICITY");
2425
2426 // Create elastic sub-problem
2427 dmElastic = createDM(mField.get_comm(), "DMMOFEM");
2428 CHKERR DMMoFEMCreateSubDM(dmElastic, dM, "ELASTIC_PROBLEM");
2434 if (!noStretch) {
2436 }
2446 CHKERR DMSetUp(dmElastic);
2447
2448 dmMaterial = createDM(mField.get_comm(), "DMMOFEM");
2449 CHKERR DMMoFEMCreateSubDM(dmMaterial, dM, "MATERIAL_PROBLEM");
2458 if (!noStretch) {
2460 }
2465 CHKERR DMSetUp(dmMaterial);
2466
2467 auto set_zero_block = [&]() {
2469 if (!noStretch) {
2470 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2471 "ELASTIC_PROBLEM", spatialL2Disp, stretchTensor);
2472 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2473 "ELASTIC_PROBLEM", stretchTensor, spatialL2Disp);
2474 }
2475 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2476 "ELASTIC_PROBLEM", spatialL2Disp, rotAxis);
2477 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2478 "ELASTIC_PROBLEM", rotAxis, spatialL2Disp);
2479 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2480 "ELASTIC_PROBLEM", spatialL2Disp, bubbleField);
2481 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2482 "ELASTIC_PROBLEM", bubbleField, spatialL2Disp);
2483 if (!noStretch) {
2484 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2485 "ELASTIC_PROBLEM", bubbleField, bubbleField);
2486 CHKERR
2487 mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2488 "ELASTIC_PROBLEM", piolaStress, piolaStress);
2489 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2490 "ELASTIC_PROBLEM", bubbleField, piolaStress);
2491 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2492 "ELASTIC_PROBLEM", piolaStress, bubbleField);
2493 }
2494
2497 };
2498
2499 auto set_section = [&]() {
2501 PetscSection section;
2502 CHKERR mField.getInterface<ISManager>()->sectionCreate("ELASTIC_PROBLEM",
2503 &section);
2504 CHKERR DMSetSection(dmElastic, section);
2505 CHKERR DMSetGlobalSection(dmElastic, section);
2506 CHKERR PetscSectionDestroy(&section);
2508 };
2509
2510 CHKERR set_zero_block();
2511 CHKERR set_section();
2512
2513 dmPrjSpatial = createDM(mField.get_comm(), "DMMOFEM");
2514 CHKERR DMMoFEMCreateSubDM(dmPrjSpatial, dM, "PROJECT_SPATIAL");
2520 CHKERR DMSetUp(dmPrjSpatial);
2521
2522 // CHKERR mField.getInterface<BcManager>()
2523 // ->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
2524 // "PROJECT_SPATIAL", spatialH1Disp, true, false);
2525
2527}
@ 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, RowColData rc=RowColData::COL)
Get smart vector from DM.
Definition DMMoFEM.hpp:1237
PetscErrorCode DMMoFEMAddSubFieldCol(DM dm, const char field_name[])
Definition DMMoFEM.cpp:280
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
SmartPetscObj< DM > dmMaterial
Material problem.
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 1274 of file EshelbianPlasticity.cpp.

1274 {
1276
1277 auto get_tets = [&]() {
1278 Range tets;
1279 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
1280 return tets;
1281 };
1282
1283 auto get_tets_skin = [&]() {
1284 Range tets_skin_part;
1285 Skinner skin(&mField.get_moab());
1286 CHKERR skin.find_skin(0, get_tets(), false, tets_skin_part);
1287 ParallelComm *pcomm =
1288 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
1289 Range tets_skin;
1290 CHKERR pcomm->filter_pstatus(tets_skin_part,
1291 PSTATUS_SHARED | PSTATUS_MULTISHARED,
1292 PSTATUS_NOT, -1, &tets_skin);
1293 return tets_skin;
1294 };
1295
1296 auto subtract_boundary_conditions = [&](auto &&tets_skin) {
1297 // That mean, that hybrid field on all faces on which traction is applied,
1298 // on other faces, or enforcing displacements as
1299 // natural boundary condition.
1301 for (auto &v : *bcSpatialTractionVecPtr) {
1302 tets_skin = subtract(tets_skin, v.faces);
1303 }
1305 for (auto &v : *bcSpatialAnalyticalTractionVecPtr) {
1306 tets_skin = subtract(tets_skin, v.faces);
1307 }
1308
1310 for (auto &v : *bcSpatialPressureVecPtr) {
1311 tets_skin = subtract(tets_skin, v.faces);
1312 }
1313
1314 return tets_skin;
1315 };
1316
1317 auto add_blockset = [&](auto block_name, auto &&tets_skin) {
1318 auto crack_faces =
1319 get_range_from_block(mField, "block_name", SPACE_DIM - 1);
1320 tets_skin.merge(crack_faces);
1321 return tets_skin;
1322 };
1323
1324 auto subtract_blockset = [&](auto block_name, auto &&tets_skin) {
1325 auto contact_range =
1326 get_range_from_block(mField, block_name, SPACE_DIM - 1);
1327 tets_skin = subtract(tets_skin, contact_range);
1328 return tets_skin;
1329 };
1330
1331 auto get_stress_trace_faces = [&](auto &&tets_skin) {
1332 Range faces;
1333 CHKERR mField.get_moab().get_adjacencies(get_tets(), SPACE_DIM - 1, true,
1334 faces, moab::Interface::UNION);
1335 Range trace_faces = subtract(faces, tets_skin);
1336 return trace_faces;
1337 };
1338
1339 auto tets = get_tets();
1340
1341 // remove also contact faces, i.e. that is also kind of hybrid field but
1342 // named but used to enforce contact conditions
1343 auto trace_faces = get_stress_trace_faces(
1344
1345 subtract_blockset("CONTACT",
1346 subtract_boundary_conditions(get_tets_skin()))
1347
1348 );
1349
1350 contactFaces = boost::make_shared<Range>(intersect(
1351 trace_faces, get_range_from_block(mField, "CONTACT", SPACE_DIM - 1)));
1353 boost::make_shared<Range>(subtract(trace_faces, *contactFaces));
1354
1355#ifndef NDEBUG
1356 if (contactFaces->size())
1358 "contact_faces_" +
1359 std::to_string(mField.get_comm_rank()) + ".vtk",
1360 *contactFaces);
1361 if (skeletonFaces->size())
1363 "skeleton_faces_" +
1364 std::to_string(mField.get_comm_rank()) + ".vtk",
1365 *skeletonFaces);
1366#endif
1367
1368 auto add_broken_hdiv_field = [this, meshset](const std::string field_name,
1369 const int order) {
1371
1373
1374 auto get_side_map_hdiv = [&]() {
1375 return std::vector<
1376
1377 std::pair<EntityType,
1379
1380 >>{
1381
1382 {MBTET,
1383 [&](BaseFunction::DofsSideMap &dofs_side_map) -> MoFEMErrorCode {
1384 return TetPolynomialBase::setDofsSideMap(HDIV, DISCONTINUOUS, base,
1385 dofs_side_map);
1386 }}
1387
1388 };
1389 };
1390
1392 get_side_map_hdiv(), MB_TAG_DENSE, MF_ZERO);
1394 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1396 };
1397
1398 auto add_l2_field = [this, meshset](const std::string field_name,
1399 const int order, const int dim) {
1402 MB_TAG_DENSE, MF_ZERO);
1404 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1406 };
1407
1408 auto add_h1_field = [this, meshset](const std::string field_name,
1409 const int order, const int dim) {
1412 MB_TAG_DENSE, MF_ZERO);
1414 CHKERR mField.set_field_order(meshset, MBVERTEX, field_name, 1);
1415 CHKERR mField.set_field_order(meshset, MBEDGE, field_name, order);
1416 CHKERR mField.set_field_order(meshset, MBTRI, field_name, order);
1417 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1419 };
1420
1421 auto add_l2_field_by_range = [this](const std::string field_name,
1422 const int order, const int dim,
1423 const int field_dim, Range &&r) {
1426 MB_TAG_DENSE, MF_ZERO);
1427 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(r);
1431 };
1432
1433 auto add_bubble_field = [this, meshset](const std::string field_name,
1434 const int order, const int dim) {
1436 CHKERR mField.add_field(field_name, HDIV, USER_BASE, dim, MB_TAG_DENSE,
1437 MF_ZERO);
1438 // Modify field
1439 auto field_ptr = mField.get_field_structure(field_name);
1440 auto field_order_table =
1441 const_cast<Field *>(field_ptr)->getFieldOrderTable();
1442 auto get_cgg_bubble_order_zero = [](int p) { return 0; };
1443 auto get_cgg_bubble_order_tet = [](int p) {
1444 return NBVOLUMETET_CCG_BUBBLE(p);
1445 };
1446 field_order_table[MBVERTEX] = get_cgg_bubble_order_zero;
1447 field_order_table[MBEDGE] = get_cgg_bubble_order_zero;
1448 field_order_table[MBTRI] = get_cgg_bubble_order_zero;
1449 field_order_table[MBTET] = get_cgg_bubble_order_tet;
1451 CHKERR mField.set_field_order(meshset, MBTRI, field_name, order);
1452 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1454 };
1455
1456 auto add_user_l2_field = [this, meshset](const std::string field_name,
1457 const int order, const int dim) {
1459 CHKERR mField.add_field(field_name, L2, USER_BASE, dim, MB_TAG_DENSE,
1460 MF_ZERO);
1461 // Modify field
1462 auto field_ptr = mField.get_field_structure(field_name);
1463 auto field_order_table =
1464 const_cast<Field *>(field_ptr)->getFieldOrderTable();
1465 auto zero_dofs = [](int p) { return 0; };
1466 auto dof_l2_tet = [](int p) { return NBVOLUMETET_L2(p); };
1467 field_order_table[MBVERTEX] = zero_dofs;
1468 field_order_table[MBEDGE] = zero_dofs;
1469 field_order_table[MBTRI] = zero_dofs;
1470 field_order_table[MBTET] = dof_l2_tet;
1472 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1474 };
1475
1476 // spatial fields
1477 CHKERR add_broken_hdiv_field(piolaStress, spaceOrder);
1478 CHKERR add_bubble_field(bubbleField, spaceOrder, 1);
1479 CHKERR add_l2_field(spatialL2Disp, spaceOrder - 1, 3);
1480 CHKERR add_user_l2_field(rotAxis, spaceOrder - 1, 3);
1481 CHKERR add_user_l2_field(stretchTensor, noStretch ? -1 : spaceOrder, 6);
1482
1483 if (!skeletonFaces)
1484 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "No skeleton faces");
1485 if (!contactFaces)
1486 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "No contact faces");
1487
1488 auto get_hybridised_disp = [&]() {
1489 auto faces = *skeletonFaces;
1490 auto skin = subtract_boundary_conditions(get_tets_skin());
1491 for (auto &bc : *bcSpatialNormalDisplacementVecPtr) {
1492 faces.merge(intersect(bc.faces, skin));
1493 }
1494 return faces;
1495 };
1496
1497 CHKERR add_l2_field_by_range(hybridSpatialDisp, spaceOrder - 1, 2, 3,
1498 get_hybridised_disp());
1499 CHKERR add_l2_field_by_range(contactDisp, spaceOrder - 1, 2, 3,
1501
1502 // spatial displacement
1503 CHKERR add_h1_field(spatialH1Disp, spaceH1Order, 3);
1504 // material positions
1505 CHKERR add_h1_field(materialH1Positions, 2, 3);
1506
1507 // Eshelby stress
1508 // CHKERR add_broken_hdiv_field(eshelbyStress, spaceOrder);
1509 // CHKERR add_l2_field(materialL2Disp, spaceOrder - 1, 3);
1510 // CHKERR add_l2_field_by_range(hybridMaterialDisp, spaceOrder - 1, 2, 3,
1511 // Range(*materialSkeletonFaces));
1512
1514
1516}
#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 544 of file EshelbianADOL-C.cpp.

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

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

528 {
531 boost::make_shared<HMHPMooneyRivlinWriggersEq63>(alpha, beta, lambda);
532 CHKERR physicalEquations->recordTape(tape, nullptr);
534}

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

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

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

2199 {
2201
2202 // set finite element fields
2203 auto add_field_to_fe = [this](const std::string fe,
2204 const std::string field_name) {
2210 };
2211
2216
2217 CHKERR add_field_to_fe(elementVolumeName, piolaStress);
2218 CHKERR add_field_to_fe(elementVolumeName, bubbleField);
2219 if (!noStretch)
2220 CHKERR add_field_to_fe(elementVolumeName, stretchTensor);
2221 CHKERR add_field_to_fe(elementVolumeName, rotAxis);
2222 CHKERR add_field_to_fe(elementVolumeName, spatialL2Disp);
2223 CHKERR add_field_to_fe(elementVolumeName, spatialH1Disp);
2224 CHKERR add_field_to_fe(elementVolumeName, contactDisp);
2226
2227 // build finite elements data structures
2229 }
2230
2232}

◆ calculateCrackArea()

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

Definition at line 2461 of file EshelbianFracture.cpp.

2461 {
2463
2464 if (!area_ptr) {
2465 CHK_THROW_MESSAGE(MOFEM_INVALID_DATA, "area_ptr is null");
2466 }
2467
2468 int success;
2469 *area_ptr = 0;
2470 if (mField.get_comm_rank() == 0) {
2471 MOFEM_LOG("EP", Sev::inform) << "Calculate crack area";
2472 auto crack_faces = get_range_from_block(mField, "CRACK", SPACE_DIM - 1);
2473 for (auto f : crack_faces) {
2474 *area_ptr += mField.getInterface<Tools>()->getTriArea(f);
2475 }
2476 success = MPI_Bcast(area_ptr.get(), 1, MPI_DOUBLE, 0, mField.get_comm());
2477 } else {
2478 success = MPI_Bcast(area_ptr.get(), 1, MPI_DOUBLE, 0, mField.get_comm());
2479 }
2480 if (success != MPI_SUCCESS) {
2482 }
2484}
@ 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>(nullptr, true);
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
87 op_loop_domain_side->getOpPtrVector().push_back(
88 new OpCalculateVectorFieldValues<SPACE_DIM>(
89 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
91 // We have to use actual strains to evaluate J integral and energy,
92 // in this case. Note actual stresses, and actual energy can only drive
93 // crack growth
94
95 op_loop_domain_side->getOpPtrVector().push_back(
96 physicalEquations->returnOpCalculateStretchFromStress(
98 } else {
99 // That will not work for problem with internal stress or strain, since
100 // we approximate mechanical stretch, not actual stretch. At some point
101 // in time we can change formulation so that actual stretch is
102 // approximated. However, the way how to do it is not clear.
103
104 op_loop_domain_side->getOpPtrVector().push_back(
105 new OpCalculateTensor2SymmetricFieldValues<SPACE_DIM>(
106 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
107 }
108
109 op_loop_domain_side->getOpPtrVector().push_back(
111
112 return fe_ptr;
113 };
114
115 auto integrate_face_material_force_fe = [&](auto &&face_energy_fe) {
118 dM, skeletonElement, face_energy_fe, 0, mField.get_comm_size());
119
120 auto face_exchange = CommInterface::createEntitiesPetscVector(
121 mField.get_comm(), mField.get_moab(), 2, 3, Sev::inform);
122
123 auto print_loc_size = [this](auto v, auto str, auto sev) {
125 int size;
126 CHKERR VecGetLocalSize(v.second, &size);
127 int low, high;
128 CHKERR VecGetOwnershipRange(v.second, &low, &high);
129 MOFEM_LOG("EPSYNC", sev) << str << " local size " << size << " ( "
130 << low << " " << high << " ) ";
133 };
134 CHKERR print_loc_size(face_exchange, "material face_exchange",
135 Sev::verbose);
136
137 CHKERR CommInterface::updateEntitiesPetscVector(
138 mField.get_moab(), face_exchange, tags[ExhangeTags::MATERIALFORCE]);
139 CHKERR CommInterface::updateEntitiesPetscVector(
140 mField.get_moab(), faceExchange, tags[ExhangeTags::FACEPRESSURE]);
141
142 // #ifndef NDEBUG
143 if (debug) {
145 "front_skin_faces_material_force_" +
146 std::to_string(mField.get_comm_rank()) + ".vtk",
148 }
149 // #endif
150
152 };
153
154 CHKERR integrate_face_material_force_fe(get_face_material_force_fe());
155
157 };
158
159 auto calculate_front_material_force = [&](auto nb_J_integral_contours) {
162
163 auto get_conn = [&](auto e) {
164 Range conn;
165 CHK_MOAB_THROW(mField.get_moab().get_connectivity(&e, 1, conn, true),
166 "get connectivity");
167 return conn;
168 };
169
170 auto get_conn_range = [&](auto e) {
171 Range conn;
172 CHK_MOAB_THROW(mField.get_moab().get_connectivity(e, conn, true),
173 "get connectivity");
174 return conn;
175 };
176
177 auto get_adj = [&](auto e, auto dim) {
178 Range adj;
179 CHK_MOAB_THROW(mField.get_moab().get_adjacencies(&e, 1, dim, true, adj),
180 "get adj");
181 return adj;
182 };
183
184 auto get_adj_range = [&](auto e, auto dim) {
185 Range adj;
186 CHK_MOAB_THROW(mField.get_moab().get_adjacencies(e, dim, true, adj,
187 moab::Interface::UNION),
188 "get adj");
189 return adj;
190 };
191
192 auto get_material_force = [&](auto r, auto th) {
193 MatrixDouble material_forces(r.size(), 3, false);
195 mField.get_moab().tag_get_data(th, r, material_forces.data().data()),
196 "get data");
197 return material_forces;
198 };
199
200 if (mField.get_comm_rank() == 0) {
201
202 auto crack_edges = get_adj_range(*crackFaces, 1);
203 auto front_nodes = get_conn_range(*frontEdges);
204 auto body_edges = get_range_from_block(mField, "EDGES", 1);
205 // auto front_block_edges = get_range_from_block(mField, "FRONT", 1);
206 // front_block_edges = subtract(front_block_edges, crack_edges);
207 // auto front_block_edges_conn = get_conn_range(front_block_edges);
208
209 // #ifndef NDEBUG
210 Range all_skin_faces;
211 Range all_front_faces;
212 // #endif
213
214 auto calculate_edge_direction = [&](auto e) {
215 const EntityHandle *conn;
216 int num_nodes;
218 mField.get_moab().get_connectivity(e, conn, num_nodes, true),
219 "get connectivity");
220 std::array<double, 6> coords;
222 mField.get_moab().get_coords(conn, num_nodes, coords.data()),
223 "get coords");
225 &coords[0], &coords[1], &coords[2]};
227 &coords[3], &coords[4], &coords[5]};
230 t_dir(i) = t_p1(i) - t_p0(i);
231 return t_dir;
232 };
233
234 // take bubble tets at node, and then avarage over the edges
235 auto calculate_force_through_node = [&]() {
237
242
243 Range body_ents;
244 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
245 body_ents);
246 auto body_skin = get_skin(mField, body_ents);
247 auto body_skin_conn = get_conn_range(body_skin);
248
249 // calculate nodal material force
250 for (auto n : front_nodes) {
251 auto adj_tets = get_adj(n, 3);
252 for (int ll = 0; ll < nb_J_integral_contours; ++ll) {
253 auto conn = get_conn_range(adj_tets);
254 adj_tets = get_adj_range(conn, 3);
255 }
256 auto skin_faces = get_skin(mField, adj_tets);
257 auto material_forces = get_material_force(skin_faces, tags[0]);
258
259#ifndef NDEBUG
260 if (debug) {
261 all_skin_faces.merge(skin_faces);
262 }
263#endif
264
265 auto calculate_node_material_force = [&]() {
266 auto t_face_T =
267 getFTensor1FromPtr<SPACE_DIM>(material_forces.data().data());
268 FTensor::Tensor1<double, SPACE_DIM> t_node_force{0., 0., 0.};
269 for (auto face : skin_faces) {
270
271 FTensor::Tensor1<double, SPACE_DIM> t_face_force_tmp{0., 0., 0.};
272 t_face_force_tmp(I) = t_face_T(I);
273 ++t_face_T;
274
275 auto face_tets = intersect(get_adj(face, 3), adj_tets);
276
277 if (face_tets.empty()) {
278 continue;
279 }
280
281 if (face_tets.size() != 1) {
283 "face_tets.size() != 1");
284 }
285
286 int side_number, sense, offset;
287 CHK_MOAB_THROW(mField.get_moab().side_number(face_tets[0], face,
288 side_number, sense,
289 offset),
290 "moab side number");
291 t_face_force_tmp(I) *= sense;
292 t_node_force(I) += t_face_force_tmp(I);
293 }
294
295 return t_node_force;
296 };
297
298 auto calculate_crack_area_growth_direction = [&](auto n,
299 auto &t_node_force) {
300 // if skin is on body surface, project the direction on it
301 FTensor::Tensor1<double, SPACE_DIM> t_project{0., 0., 0.};
302 auto boundary_node = intersect(Range(n, n), body_skin_conn);
303 if (boundary_node.size()) {
304 auto faces = intersect(get_adj(n, 2), body_skin);
305 for (auto f : faces) {
306 FTensor::Tensor1<double, 3> t_normal_face;
307 CHKERR mField.getInterface<Tools>()->getTriNormal(
308 f, &t_normal_face(0));
309 t_project(I) += t_normal_face(I);
310 }
311 t_project.normalize();
312 }
313
314 // calculate surface projection matrix
317 t_Q(I, J) = t_kd(I, J);
318 if (boundary_node.size()) {
319 t_Q(I, J) -= t_project(I) * t_project(J);
320 }
321
322 auto adj_faces = intersect(get_adj(n, 2), *crackFaces);
323 if (adj_faces.empty()) {
324 auto adj_edges =
325 intersect(get_adj(n, 1), unite(*frontEdges, body_edges));
326 double l = 0;
327 for (auto e : adj_edges) {
328 auto t_dir = calculate_edge_direction(e);
329 l += t_dir.l2();
330 }
331 l /= 2;
332 FTensor::Tensor1<double, SPACE_DIM> t_area_dir{0., 0., 0.};
334 t_node_force_tmp(I) = t_node_force(I);
335 t_node_force_tmp.normalize();
336 t_area_dir(I) = -t_node_force_tmp(I);
337 t_area_dir(I) *= l / 2;
338 return t_area_dir;
339 }
340
341 // calculate direction
342 auto front_edges = get_adj(n, 1);
343 FTensor::Tensor1<double, 3> t_area_dir{0., 0., 0.};
344 for (auto f : adj_faces) {
345 int num_nodes;
346 const EntityHandle *conn;
347 CHKERR mField.get_moab().get_connectivity(f, conn, num_nodes,
348 true);
349 std::array<double, 9> coords;
350 CHKERR mField.get_moab().get_coords(conn, num_nodes,
351 coords.data());
352 FTensor::Tensor1<double, 3> t_face_normal;
354 CHKERR mField.getInterface<Tools>()->getTriNormal(
355 coords.data(), &t_face_normal(0), &t_d_normal(0, 0, 0));
356 auto n_it = std::find(conn, conn + num_nodes, n);
357 auto n_index = std::distance(conn, n_it);
358
359 FTensor::Tensor2<double, 3, 3> t_face_hessian{
360 t_d_normal(0, n_index, 0), t_d_normal(0, n_index, 1),
361 t_d_normal(0, n_index, 2),
362
363 t_d_normal(1, n_index, 0), t_d_normal(1, n_index, 1),
364 t_d_normal(1, n_index, 2),
365
366 t_d_normal(2, n_index, 0), t_d_normal(2, n_index, 1),
367 t_d_normal(2, n_index, 2)};
368
369 FTensor::Tensor2<double, 3, 3> t_projected_hessian;
370 t_projected_hessian(I, J) =
371 t_Q(I, K) * (t_face_hessian(K, L) * t_Q(L, J));
372 t_face_normal.normalize();
373 t_area_dir(K) +=
374 t_face_normal(I) * t_projected_hessian(I, K) / 2.;
375 }
376
377 return t_area_dir;
378 };
379
380 auto t_node_force = calculate_node_material_force();
381 t_node_force(I) /= griffithEnergy; // scale all by griffith energy
383 mField.get_moab().tag_set_data(tags[ExhangeTags::MATERIALFORCE],
384 &n, 1, &t_node_force(0)),
385 "set data");
386
387 auto get_area_dir = [&]() {
388 FTensor::Tensor1<double, SPACE_DIM> t_area_dir{0., 0., 0.};
389 auto adj_edges = intersect(get_adj_range(adj_tets, 1),
390 unite(*frontEdges, body_edges));
391 auto seed_n = get_conn_range(adj_edges);
392 auto skin_adj_edges = get_skin(mField, adj_edges);
393 skin_adj_edges = subtract(skin_adj_edges, body_skin_conn);
394 seed_n = subtract(seed_n, skin_adj_edges);
395 t_area_dir(I) = 0;
396 for (auto sn : seed_n) {
397 auto t_area_dir_sn =
398 calculate_crack_area_growth_direction(sn, t_node_force);
399 t_area_dir(I) += t_area_dir_sn(I);
400 }
401 for (auto sn : skin_adj_edges) {
402 auto t_area_dir_sn =
403 calculate_crack_area_growth_direction(sn, t_node_force);
404 t_area_dir(I) += t_area_dir_sn(I) / 2;
405 }
406 return t_area_dir;
407 };
408
409 auto t_area_dir = get_area_dir();
410
412 mField.get_moab().tag_set_data(tags[ExhangeTags::AREAGROWTH], &n,
413 1, &t_area_dir(0)),
414 "set data");
415 auto griffith = -t_node_force(I) * t_area_dir(I) /
416 (t_area_dir(K) * t_area_dir(K));
418 mField.get_moab().tag_set_data(tags[ExhangeTags::GRIFFITHFORCE],
419 &n, 1, &griffith),
420 "set data");
421 }
422
423 // iterate over edges, and calculate average edge material force
424 auto ave_node_force = [&](auto th) {
426
427 for (auto e : *frontEdges) {
428
429 auto conn = get_conn(e);
430 auto data = get_material_force(conn, th);
431 auto t_node = getFTensor1FromPtr<SPACE_DIM>(data.data().data());
432 FTensor::Tensor1<double, SPACE_DIM> t_edge{0., 0., 0.};
433 for (auto n : conn) {
434 NOT_USED(n);
435 t_edge(I) += t_node(I);
436 ++t_node;
437 }
438 t_edge(I) /= conn.size();
439
440 FTensor::Tensor1<double, SPACE_DIM> t_edge_direction =
441 calculate_edge_direction(e);
442 t_edge_direction.normalize();
443
448 t_cross(K) =
449 FTensor::levi_civita(I, J, K) * t_edge_direction(I) * t_edge(J);
450 t_edge(K) = FTensor::levi_civita(I, J, K) * t_edge_direction(J) *
451 t_cross(I);
452
453 CHKERR mField.get_moab().tag_set_data(th, &e, 1, &t_edge(0));
454 }
456 };
457
458 // iterate over edges, and calculate average edge griffith energy
459 auto ave_node_griffith_energy = [&](auto th) {
461 for (auto e : *frontEdges) {
463 CHKERR mField.get_moab().tag_get_data(
464 tags[ExhangeTags::MATERIALFORCE], &e, 1, &t_edge_force(0));
466 CHKERR mField.get_moab().tag_get_data(tags[ExhangeTags::AREAGROWTH],
467 &e, 1, &t_edge_area_dir(0));
468 double griffith_energy = -t_edge_force(I) * t_edge_area_dir(I) /
469 (t_edge_area_dir(K) * t_edge_area_dir(K));
470 CHKERR mField.get_moab().tag_set_data(th, &e, 1, &griffith_energy);
471 }
473 };
474
475 CHKERR ave_node_force(tags[ExhangeTags::MATERIALFORCE]);
476 CHKERR ave_node_force(tags[ExhangeTags::AREAGROWTH]);
477 CHKERR ave_node_griffith_energy(tags[ExhangeTags::GRIFFITHFORCE]);
478
480 };
481
482 CHKERR calculate_force_through_node();
483
484 // calculate face cross
485 for (auto e : *frontEdges) {
486 auto adj_faces = get_adj(e, 2);
487 auto crack_face = intersect(get_adj(e, 2), *crackFaces);
488
489 // #ifndef NDEBUG
490 if (debug) {
491 all_front_faces.merge(adj_faces);
492 }
493 // #endif
494
496 CHKERR mField.get_moab().tag_get_data(tags[ExhangeTags::MATERIALFORCE],
497 &e, 1, &t_edge_force(0));
498 FTensor::Tensor1<double, SPACE_DIM> t_edge_direction =
499 calculate_edge_direction(e);
500 t_edge_direction.normalize();
505 t_cross(K) = FTensor::levi_civita(I, J, K) * t_edge_direction(I) *
506 t_edge_force(J);
507
508 for (auto f : adj_faces) {
510 CHKERR mField.getInterface<Tools>()->getTriNormal(f, &t_normal(0));
511 t_normal.normalize();
512 int side_number, sense, offset;
513 CHKERR mField.get_moab().side_number(f, e, side_number, sense,
514 offset);
515 auto dot = -sense * t_cross(I) * t_normal(I);
516 CHK_MOAB_THROW(mField.get_moab().tag_set_data(
517 tags[ExhangeTags::GRIFFITHFORCE], &f, 1, &dot),
518 "set data");
519 }
520 }
521
522#ifndef NDEBUG
523 if (debug) {
524 int ts_step;
525 CHKERR TSGetStepNumber(ts, &ts_step);
527 "front_edges_material_force_" +
528 std::to_string(ts_step) + ".vtk",
529 *frontEdges);
531 "front_skin_faces_material_force_" +
532 std::to_string(ts_step) + ".vtk",
533 all_skin_faces);
535 "front_faces_material_force_" +
536 std::to_string(ts_step) + ".vtk",
537 all_front_faces);
538 }
539#endif
540 }
541
542 auto edge_exchange = CommInterface::createEntitiesPetscVector(
543 mField.get_comm(), mField.get_moab(), 1, 3, Sev::inform);
544 CHKERR CommInterface::updateEntitiesPetscVector(
545 mField.get_moab(), edge_exchange, tags[ExhangeTags::MATERIALFORCE]);
546 CHKERR CommInterface::updateEntitiesPetscVector(
547 mField.get_moab(), edge_exchange, tags[ExhangeTags::AREAGROWTH]);
548 CHKERR CommInterface::updateEntitiesPetscVector(
549 mField.get_moab(), edgeExchange, tags[ExhangeTags::GRIFFITHFORCE]);
550
552 };
553
554 auto print_results = [&](auto nb_J_integral_conturs) {
556
557 auto get_conn_range = [&](auto e) {
558 Range conn;
559 CHK_MOAB_THROW(mField.get_moab().get_connectivity(e, conn, true),
560 "get connectivity");
561 return conn;
562 };
563
564 auto get_tag_data = [&](auto &ents, auto tag, auto dim) {
565 std::vector<double> data(ents.size() * dim);
566 CHK_MOAB_THROW(mField.get_moab().tag_get_data(tag, ents, data.data()),
567 "get data");
568 return data;
569 };
570
571 if (mField.get_comm_rank() == 0) {
572 auto at_nodes = [&]() {
574 auto conn = get_conn_range(*frontEdges);
575 auto material_force =
576 get_tag_data(conn, tags[ExhangeTags::MATERIALFORCE], 3);
577 auto area_growth = get_tag_data(conn, tags[ExhangeTags::AREAGROWTH], 3);
578 auto griffith_force =
579 get_tag_data(conn, tags[ExhangeTags::GRIFFITHFORCE], 1);
580 std::vector<double> coords(conn.size() * 3);
581 CHK_MOAB_THROW(mField.get_moab().get_coords(conn, coords.data()),
582 "get coords");
583 if (conn.size())
584 MOFEM_LOG("EPSELF", Sev::inform) << "Material force at nodes";
585 for (size_t i = 0; i < conn.size(); ++i) {
586 MOFEM_LOG("EPSELF", Sev::inform)
587 << "Node " << conn[i] << " coords " << coords[i * 3 + 0] << " "
588 << coords[i * 3 + 1] << " " << coords[i * 3 + 2]
589 << " material force " << material_force[i * 3 + 0] << " "
590 << material_force[i * 3 + 1] << " " << material_force[i * 3 + 2]
591 << " area growth " << area_growth[i * 3 + 0] << " "
592 << area_growth[i * 3 + 1] << " " << area_growth[i * 3 + 2]
593 << " griffith force " << std::setprecision(12)
594 << griffith_force[i] << " contour " << nb_J_integral_conturs;
595 }
597 };
598
599 at_nodes();
600 }
602 };
603
604 CHKERR calculate_material_forces();
605
606 PetscBool all_contours = PETSC_FALSE;
607 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "",
608 "-calculate_J_integral_all_levels", &all_contours,
609 PETSC_NULLPTR); // for backward compatibility
611 PETSC_NULLPTR, "", "-calculate_J_integral_all_contours", &all_contours,
612 PETSC_NULLPTR); // new name
613
614 if (all_contours == PETSC_TRUE) {
615 for (int l = 0; l < nbJIntegralContours; ++l) {
616 CHKERR calculate_front_material_force(l);
617 CHKERR print_results(l);
618 }
619 }
620
621 CHKERR calculate_front_material_force(nbJIntegralContours);
622 CHKERR print_results(nbJIntegralContours);
623
625}
#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 627 of file EshelbianFracture.cpp.

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

◆ createCrackSurfaceMeshset()

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

Definition at line 2449 of file EshelbianFracture.cpp.

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

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

5095 {
5097
5098 auto print_loc_size = [this](auto v, auto str, auto sev) {
5100 int size;
5101 CHKERR VecGetLocalSize(v.second, &size);
5102 int low, high;
5103 CHKERR VecGetOwnershipRange(v.second, &low, &high);
5104 MOFEM_LOG("EPSYNC", sev) << str << " local size " << size << " ( " << low
5105 << " " << high << " ) ";
5108 };
5109
5111 mField.get_comm(), mField.get_moab(), 3, 1, sev);
5112 CHKERR print_loc_size(volumeExchange, "volumeExchange", sev);
5114 mField.get_comm(), mField.get_moab(), 2, 1, Sev::inform);
5115 CHKERR print_loc_size(faceExchange, "faceExchange", sev);
5117 mField.get_comm(), mField.get_moab(), 1, 1, Sev::inform);
5118 CHKERR print_loc_size(edgeExchange, "edgeExchange", sev);
5120 mField.get_comm(), mField.get_moab(), 0, 3, Sev::inform);
5121 CHKERR print_loc_size(vertexExchange, "vertexExchange", sev);
5122
5124}
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 123 of file EshelbianCore.hpp.

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

92 {
93 if (v > v_max) {
94 double e = static_cast<double>(std::exp(v_max));
95 double dv = v - v_max;
96 return e * dv + e;
97 } else {
98 return static_cast<double>(std::exp(v));
99 }
100 }

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

133 {
134 if constexpr (use_quadratic_exp) {
135 return dd_f_log_e_quadratic(v);
136 } else {
137 if (v > v_max)
138 return 0.;
139 else
140 return std::exp(v);
141 }
142 }
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 102 of file EshelbianCore.hpp.

102 {
103 if (v > v_max) {
104 return static_cast<double>(std::exp(v_max));
105 } else {
106 return static_cast<double>(std::exp(v));
107 }
108 }

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

110 {
111 if constexpr(use_quadratic_exp) {
112 return f_log_e_quadratic(v);
113 } else {
114 if (v > v_max)
115 // y = exp(v_max) * v + exp(v_max) * (1 - v_max);
116 // y/exp(v_max) = v + (1 - v_max);
117 // y/exp(v_max) - (1 - v_max) = v;
118 return std::exp(v_max) * v + std::exp(v_max) * (1 - v_max);
119 else
120 return std::exp(v);
121 }
122 }
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 82 of file EshelbianCore.hpp.

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

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

272 {
274 for (auto it :
275 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
276
277 (boost::format("%s(.*)") % block_name).str()
278
279 ))
280
281 ) {
282 std::vector<double> block_attributes;
283 CHKERR it->getAttributes(block_attributes);
284 if (block_attributes.size() < nb_attributes) {
285 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
286 "In block %s expected %d attributes, but given %ld",
287 it->getName().c_str(), nb_attributes, block_attributes.size());
288 }
289 Range faces;
290 CHKERR it->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2, faces,
291 true);
292 bc_vec_ptr->emplace_back(it->getName(), block_attributes, faces);
293 }
295 }
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 5046 of file EshelbianPlasticity.cpp.

5046 {
5048
5049 auto getExternalStrain = [&](boost::shared_ptr<ExternalStrainVec>
5050 &ext_strain_vec_ptr,
5051 const std::string block_name,
5052 const int nb_attributes) {
5054 for (auto it : mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
5055 std::regex((boost::format("(.*)%s(.*)") % block_name).str()))) {
5056 std::vector<double> block_attributes;
5057 CHKERR it->getAttributes(block_attributes);
5058 if (block_attributes.size() < nb_attributes) {
5059 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
5060 "In block %s expected %d attributes, but given %ld",
5061 it->getName().c_str(), nb_attributes, block_attributes.size());
5062 }
5063
5064 auto get_block_ents = [&]() {
5065 Range ents;
5066 CHKERR mField.get_moab().get_entities_by_handle(it->meshset, ents,
5067 true);
5068 return ents;
5069 };
5070 auto Ents = get_block_ents();
5071 ext_strain_vec_ptr->emplace_back(it->getName(), block_attributes,
5072 get_block_ents());
5073 }
5075 };
5076
5077 externalStrainVecPtr = boost::make_shared<ExternalStrainVec>();
5078
5079 CHKERR getExternalStrain(externalStrainVecPtr, "EXTERNALSTRAIN", 2);
5080
5081 auto ts_pre_stretch = boost::make_shared<DynamicRelaxationTimeScale>(
5082 "externalstrain_history.txt");
5083 for (auto &ext_strain_block : *externalStrainVecPtr) {
5084 MOFEM_LOG("EP", Sev::noisy)
5085 << "Add time scaling external strain: " << ext_strain_block.blockName;
5086 timeScaleMap[ext_strain_block.blockName] =
5088 ts_pre_stretch, "externalstrain_history", ".txt",
5089 ext_strain_block.blockName);
5090 }
5091
5093}
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 964 of file EshelbianPlasticity.cpp.

964 {
966 const char *list_rots[] = {"small", "moderate", "large", "no_h1"};
967 const char *list_symm[] = {"symm", "not_symm"};
968 const char *list_release[] = {"griffith_force", "griffith_skeleton"};
969 const char *list_stretches[] = {"linear", "log", "log_quadratic"};
970 PetscInt choice_rot = EshelbianCore::rotSelector;
971 PetscInt choice_grad = EshelbianCore::gradApproximator;
972 PetscInt choice_symm = EshelbianCore::symmetrySelector;
973 PetscInt choice_release = EshelbianCore::energyReleaseSelector;
974 PetscInt choice_stretch = StretchSelector::LOG;
975 PetscInt choice_solver = SolverType::TimeSolver;
976 char analytical_expr_file_name[255] = "analytical_expr.py";
977
978 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Eshelbian plasticity", "none");
979 CHKERR PetscOptionsInt("-space_order", "approximation oder for space", "",
980 spaceOrder, &spaceOrder, PETSC_NULLPTR);
981 CHKERR PetscOptionsInt("-space_h1_order", "approximation oder for space", "",
982 spaceH1Order, &spaceH1Order, PETSC_NULLPTR);
983 CHKERR PetscOptionsInt("-material_order", "approximation oder for material",
984 "", materialOrder, &materialOrder, PETSC_NULLPTR);
985 CHKERR PetscOptionsScalar("-viscosity_alpha_u", "viscosity", "", alphaU,
986 &alphaU, PETSC_NULLPTR);
987 CHKERR PetscOptionsScalar("-viscosity_alpha_w", "viscosity", "", alphaW,
988 &alphaW, PETSC_NULLPTR);
989 CHKERR PetscOptionsScalar("-viscosity_alpha_omega", "rot viscosity", "",
990 alphaOmega, &alphaOmega, PETSC_NULLPTR);
991 CHKERR PetscOptionsScalar("-density_alpha_rho", "density", "", alphaRho,
992 &alphaRho, PETSC_NULLPTR);
993 CHKERR PetscOptionsScalar("-alpha_tau", "tau", "", alphaTau, &alphaTau,
994 PETSC_NULLPTR);
995 CHKERR PetscOptionsEList("-rotations", "rotations", "", list_rots,
996 LARGE_ROT + 1, list_rots[choice_rot], &choice_rot,
997 PETSC_NULLPTR);
998 CHKERR PetscOptionsEList("-grad", "gradient of defamation approximate", "",
999 list_rots, NO_H1_CONFIGURATION + 1,
1000 list_rots[choice_grad], &choice_grad, PETSC_NULLPTR);
1001 CHKERR PetscOptionsEList("-symm", "symmetric variant", "", list_symm, 2,
1002 list_symm[choice_symm], &choice_symm, PETSC_NULLPTR);
1003
1004 CHKERR PetscOptionsScalar("-exponent_base", "exponent_base", "", exponentBase,
1005 &EshelbianCore::exponentBase, PETSC_NULLPTR);
1006 CHKERR PetscOptionsEList("-stretches", "stretches", "", list_stretches,
1007 StretchSelector::STRETCH_SELECTOR_LAST,
1008 list_stretches[choice_stretch], &choice_stretch,
1009 PETSC_NULLPTR);
1010
1011 CHKERR PetscOptionsBool("-no_stretch", "do not solve for stretch", "",
1012 noStretch, &noStretch, PETSC_NULLPTR);
1013 CHKERR PetscOptionsBool("-set_singularity", "set singularity", "",
1014 setSingularity, &setSingularity, PETSC_NULLPTR);
1015 CHKERR PetscOptionsBool("-l2_user_base_scale", "streach scale", "",
1016 l2UserBaseScale, &l2UserBaseScale, PETSC_NULLPTR);
1017
1018 // dynamic relaxation
1019
1020 // @deprecate this option
1021 CHKERR PetscOptionsBool("-dynamic_relaxation", "dynamic time relaxation", "",
1022 dynamicRelaxation, &dynamicRelaxation, PETSC_NULLPTR);
1023 CHKERR PetscOptionsEList(
1024 "-solver_type", "solver type", "", EshelbianCore::listSolvers,
1026 EshelbianCore::listSolvers[choice_solver], &choice_solver, PETSC_NULLPTR);
1027
1028 // contact parameters
1029 CHKERR PetscOptionsInt("-contact_max_post_proc_ref_level", "refinement level",
1031 PETSC_NULLPTR);
1032 // cohesive interfae
1033 CHKERR PetscOptionsBool("-cohesive_interface_on", "cohesive interface ON", "",
1034 interfaceCrack, &interfaceCrack, PETSC_NULLPTR);
1035 CHKERR PetscOptionsInt(
1036 "-cohesive_interface_remove_level", "cohesive interface remove level", "",
1038
1039 // cracking parameters
1040 CHKERR PetscOptionsBool("-cracking_on", "cracking ON", "", crackingOn,
1041 &crackingOn, PETSC_NULLPTR);
1042 CHKERR PetscOptionsScalar("-cracking_add_time", "cracking add time", "",
1043 crackingAddTime, &crackingAddTime, PETSC_NULLPTR);
1044 CHKERR PetscOptionsScalar("-cracking_start_time", "cracking start time", "",
1046 PETSC_NULLPTR);
1047 CHKERR PetscOptionsScalar("-griffith_energy", "Griffith energy", "",
1048 griffithEnergy, &griffithEnergy, PETSC_NULLPTR);
1049
1050 CHKERR PetscOptionsScalar("-cracking_rtol", "Cracking relative tolerance", "",
1051 crackingRtol, &crackingRtol, PETSC_NULLPTR);
1052 CHKERR PetscOptionsScalar("-cracking_atol", "Cracking absolute tolerance", "",
1053 crackingAtol, &crackingAtol, PETSC_NULLPTR);
1054 CHKERR PetscOptionsEList("-energy_release_variant", "energy release variant",
1055 "", list_release, 2, list_release[choice_release],
1056 &choice_release, PETSC_NULLPTR);
1057 CHKERR PetscOptionsInt("-nb_J_integral_levels", "Number of J integarl levels",
1059 PETSC_NULLPTR); // backward compatibility
1060 CHKERR PetscOptionsInt(
1061 "-nb_J_integral_contours", "Number of J integral contours", "",
1062 nbJIntegralContours, &nbJIntegralContours, PETSC_NULLPTR);
1063
1064 // internal stress
1065 char tag_name[255] = "";
1066 CHKERR PetscOptionsString("-internal_stress_tag_name",
1067 "internal stress tag name", "", "", tag_name, 255,
1068 PETSC_NULLPTR);
1069 internalStressTagName = string(tag_name);
1070 CHKERR PetscOptionsInt(
1071 "-internal_stress_interp_order", "internal stress interpolation order",
1073 CHKERR PetscOptionsBool("-internal_stress_voigt", "Voigt index notation", "",
1075 PETSC_NULLPTR);
1076
1077 CHKERR PetscOptionsGetString(PETSC_NULLPTR, PETSC_NULLPTR,
1078 "-analytical_expr_file",
1079 analytical_expr_file_name, 255, PETSC_NULLPTR);
1080
1081 PetscOptionsEnd();
1082
1084 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
1085 "Unsupported internal stress interpolation order %d",
1087 }
1088
1089 if (setSingularity) {
1090 l2UserBaseScale = PETSC_TRUE;
1091 }
1092
1093 EshelbianCore::rotSelector = static_cast<RotSelector>(choice_rot);
1094 EshelbianCore::gradApproximator = static_cast<RotSelector>(choice_grad);
1095 EshelbianCore::stretchSelector = static_cast<StretchSelector>(choice_stretch);
1096 EshelbianCore::symmetrySelector = static_cast<SymmetrySelector>(choice_symm);
1098 static_cast<EnergyReleaseSelector>(choice_release);
1099
1101 case StretchSelector::LINEAR:
1108 break;
1109 case StretchSelector::LOG:
1110 if (std::fabs(EshelbianCore::exponentBase - exp(1)) >
1111 std::numeric_limits<float>::epsilon()) {
1118 } else {
1125 }
1126 break;
1127 case StretchSelector::LOG_QUADRATIC:
1131 EshelbianCore::inv_f = [](const double x) {
1133 "No logarithmic quadratic stretch for this case");
1134 return 0;
1135 };
1138 break; // no stretch, do not use stretch functions
1139 default:
1140 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "Unknown stretch");
1141 break;
1142 };
1143
1144 if (dynamicRelaxation) {
1145 MOFEM_LOG("EP", Sev::warning)
1146 << "-dynamic_relaxation option is deprecated, use -solver_type "
1147 "dynamic_relaxation instead.";
1148 choice_solver = SolverType::DynamicRelaxation;
1149 }
1150
1151 switch (choice_solver) {
1154 break;
1158 dynamicRelaxation = PETSC_TRUE;
1159 break;
1162 break;
1166 break;
1167 default:
1168 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "Unknown solver");
1169 break;
1170 };
1171
1172 // start cracking after adding crack elements
1174
1175 MOFEM_LOG("EP", Sev::inform) << "spaceOrder: -space_order " << spaceOrder;
1176 MOFEM_LOG("EP", Sev::inform)
1177 << "spaceH1Order: -space_h1_order " << spaceH1Order;
1178 MOFEM_LOG("EP", Sev::inform)
1179 << "materialOrder: -material_order " << materialOrder;
1180 MOFEM_LOG("EP", Sev::inform) << "alphaU: -viscosity_alpha_u " << alphaU;
1181 MOFEM_LOG("EP", Sev::inform) << "alphaW: -viscosity_alpha_w " << alphaW;
1182 MOFEM_LOG("EP", Sev::inform)
1183 << "alphaOmega: -viscosity_alpha_omega " << alphaOmega;
1184 MOFEM_LOG("EP", Sev::inform) << "alphaRho: -density_alpha_rho " << alphaRho;
1185 MOFEM_LOG("EP", Sev::inform) << "alphaTau: -alpha_tau " << alphaTau;
1186 MOFEM_LOG("EP", Sev::inform)
1187 << "Rotations: -rotations " << list_rots[EshelbianCore::rotSelector];
1188 MOFEM_LOG("EP", Sev::inform) << "Gradient of deformation "
1189 << list_rots[EshelbianCore::gradApproximator];
1190 MOFEM_LOG("EP", Sev::inform)
1191 << "Symmetry: -symm " << list_symm[EshelbianCore::symmetrySelector];
1192 if (exponentBase != exp(1))
1193 MOFEM_LOG("EP", Sev::inform)
1194 << "Base exponent: -exponent_base " << EshelbianCore::exponentBase;
1195 else
1196 MOFEM_LOG("EP", Sev::inform) << "Base exponent e";
1197 MOFEM_LOG("EP", Sev::inform)
1198 << "Stretch: -stretches " << list_stretches[choice_stretch];
1199 MOFEM_LOG("EP", Sev::inform) << "No stretch: -no_stretch " << (noStretch)
1200 ? "yes"
1201 : "no";
1202
1203 MOFEM_LOG("EP", Sev::inform)
1204 << "Dynamic relaxation: -dynamic_relaxation " << (dynamicRelaxation)
1205 ? "yes"
1206 : "no";
1207 MOFEM_LOG("EP", Sev::inform) << "Solver type: -solver_type "
1208 << EshelbianCore::listSolvers[choice_solver];
1209 MOFEM_LOG("EP", Sev::inform)
1210 << "Singularity: -set_singularity " << (setSingularity)
1211 ? "yes"
1212 : "no";
1213 MOFEM_LOG("EP", Sev::inform)
1214 << "L2 user base scale: -l2_user_base_scale " << (l2UserBaseScale)
1215 ? "yes"
1216 : "no";
1217
1218 MOFEM_LOG("EP", Sev::inform) << "Cracking on: -cracking_on " << (crackingOn)
1219 ? "yes"
1220 : "no";
1221 MOFEM_LOG("EP", Sev::inform)
1222 << "Cracking add time: -cracking_add_time " << crackingAddTime;
1223 MOFEM_LOG("EP", Sev::inform)
1224 << "Cracking start time: -cracking_start_time " << crackingStartTime;
1225 MOFEM_LOG("EP", Sev::inform)
1226 << "Griffith energy: -griffith_energy " << griffithEnergy;
1227 MOFEM_LOG("EP", Sev::inform)
1228 << "Cracking relative tolerance: -cracking_rtol " << crackingRtol;
1229 MOFEM_LOG("EP", Sev::inform)
1230 << "Cracking absolute tolerance: -cracking_atol " << crackingAtol;
1231 MOFEM_LOG("EP", Sev::inform)
1232 << "Energy release variant: -energy_release_variant "
1233 << list_release[EshelbianCore::energyReleaseSelector];
1234 MOFEM_LOG("EP", Sev::inform)
1235 << "Number of J integral contours: -nb_J_integral_contours "
1237 MOFEM_LOG("EP", Sev::inform)
1238 << "Cohesive interface on: -cohesive_interface_on "
1239 << (interfaceCrack == PETSC_TRUE)
1240 ? "yes"
1241 : "no";
1242 MOFEM_LOG("EP", Sev::inform)
1243 << "Cohesive interface remove level: -cohesive_interface_remove_level "
1245
1246#ifdef ENABLE_PYTHON_BINDING
1247 auto file_exists = [](std::string myfile) {
1248 std::ifstream file(myfile.c_str());
1249 if (file) {
1250 return true;
1251 }
1252 return false;
1253 };
1254
1255 if (file_exists(analytical_expr_file_name)) {
1256 MOFEM_LOG("EP", Sev::inform) << analytical_expr_file_name << " file found";
1257
1258 AnalyticalExprPythonPtr = boost::make_shared<AnalyticalExprPython>();
1259 CHKERR AnalyticalExprPythonPtr->analyticalExprInit(
1260 analytical_expr_file_name);
1261 AnalyticalExprPythonWeakPtr = AnalyticalExprPythonPtr;
1262 } else {
1263 MOFEM_LOG("EP", Sev::warning)
1264 << analytical_expr_file_name << " file NOT found";
1265 }
1266#endif
1267
1268 if (spaceH1Order == -1)
1270
1272}
@ 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 int interfaceRemoveLevel
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 const char * listSolvers[]
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 crackingAddTime
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 4868 of file EshelbianPlasticity.cpp.

4868 {
4870
4871 auto bc_mng = mField.getInterface<BcManager>();
4873 "", piolaStress, false, false);
4874
4875 bcSpatialDispVecPtr = boost::make_shared<BcDispVec>();
4876 for (auto bc : bc_mng->getBcMapByBlockName()) {
4877 if (auto disp_bc = bc.second->dispBcPtr) {
4878
4879 auto [field_name, block_name] =
4881 MOFEM_LOG("EP", Sev::inform)
4882 << "Field name: " << field_name << " Block name: " << block_name;
4883 MOFEM_LOG("EP", Sev::noisy) << "Displacement BC: " << *disp_bc;
4884
4885 std::vector<double> block_attributes(6, 0.);
4886 if (disp_bc->data.flag1 == 1) {
4887 block_attributes[0] = disp_bc->data.value1;
4888 block_attributes[3] = 1;
4889 }
4890 if (disp_bc->data.flag2 == 1) {
4891 block_attributes[1] = disp_bc->data.value2;
4892 block_attributes[4] = 1;
4893 }
4894 if (disp_bc->data.flag3 == 1) {
4895 block_attributes[2] = disp_bc->data.value3;
4896 block_attributes[5] = 1;
4897 }
4898 auto faces = bc.second->bcEnts.subset_by_dimension(2);
4899 bcSpatialDispVecPtr->emplace_back(block_name, block_attributes, faces);
4900 }
4901 }
4902 // old way of naming blocksets for displacement BCs
4903 CHKERR getBc(bcSpatialDispVecPtr, "SPATIAL_DISP_BC", 6);
4904
4906 boost::make_shared<NormalDisplacementBcVec>();
4907 for (auto bc : bc_mng->getBcMapByBlockName()) {
4908 auto block_name = "(.*)NORMAL_DISPLACEMENT(.*)";
4909 std::regex reg_name(block_name);
4910 if (std::regex_match(bc.first, reg_name)) {
4911 auto [field_name, block_name] =
4913 MOFEM_LOG("EP", Sev::inform)
4914 << "Field name: " << field_name << " Block name: " << block_name;
4916 block_name, bc.second->bcAttributes,
4917 bc.second->bcEnts.subset_by_dimension(2));
4918 }
4919 }
4920
4922 boost::make_shared<AnalyticalDisplacementBcVec>();
4923
4924 for (auto bc : bc_mng->getBcMapByBlockName()) {
4925 auto block_name = "(.*)ANALYTICAL_DISPLACEMENT(.*)";
4926 std::regex reg_name(block_name);
4927 if (std::regex_match(bc.first, reg_name)) {
4928 auto [field_name, block_name] =
4930 MOFEM_LOG("EP", Sev::inform)
4931 << "Field name: " << field_name << " Block name: " << block_name;
4933 block_name, bc.second->bcAttributes,
4934 bc.second->bcEnts.subset_by_dimension(2));
4935 }
4936 }
4937
4938 auto ts_displacement =
4939 boost::make_shared<DynamicRelaxationTimeScale>("disp_history.txt");
4940 for (auto &bc : *bcSpatialDispVecPtr) {
4941 MOFEM_LOG("EP", Sev::noisy)
4942 << "Add time scaling displacement BC: " << bc.blockName;
4943 timeScaleMap[bc.blockName] =
4945 ts_displacement, "disp_history", ".txt", bc.blockName);
4946 }
4947
4948 auto ts_normal_displacement =
4949 boost::make_shared<DynamicRelaxationTimeScale>("normal_disp_history.txt");
4950 for (auto &bc : *bcSpatialNormalDisplacementVecPtr) {
4951 MOFEM_LOG("EP", Sev::noisy)
4952 << "Add time scaling normal displacement BC: " << bc.blockName;
4953 timeScaleMap[bc.blockName] =
4955 ts_normal_displacement, "normal_disp_history", ".txt",
4956 bc.blockName);
4957 }
4958
4960}
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 299 of file EshelbianCore.hpp.

299 {
301 bcSpatialRotationVecPtr = boost::make_shared<BcRotVec>();
302 CHKERR getBc(bcSpatialRotationVecPtr, "SPATIAL_ROTATION_BC", 4);
303 CHKERR getBc(bcSpatialRotationVecPtr, "SPATIAL_ROTATION_AXIS_BC", 7);
304
305 auto ts_rotation =
306 boost::make_shared<DynamicRelaxationTimeScale>("rotation_history.txt");
307 for (auto &bc : *bcSpatialRotationVecPtr) {
308 timeScaleMap[bc.blockName] =
309 GetBlockScalingMethod<DynamicRelaxationTimeScale>::get(
310 ts_rotation, "rotation_history", ".txt", bc.blockName);
311 }
312
314 }

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

4962 {
4964
4965 auto bc_mng = mField.getInterface<BcManager>();
4967 false, false);
4968
4969 bcSpatialTractionVecPtr = boost::make_shared<TractionBcVec>();
4970
4971 for (auto bc : bc_mng->getBcMapByBlockName()) {
4972 if (auto force_bc = bc.second->forceBcPtr) {
4973
4974 auto [field_name, block_name] =
4976 MOFEM_LOG("EP", Sev::inform)
4977 << "Field name: " << field_name << " Block name: " << block_name;
4978 MOFEM_LOG("EP", Sev::noisy) << "Force BC: " << *force_bc;
4979
4980 std::vector<double> block_attributes(6, 0.);
4981 block_attributes[0] = -force_bc->data.value3 * force_bc->data.value1;
4982 block_attributes[3] = 1;
4983 block_attributes[1] = -force_bc->data.value4 * force_bc->data.value1;
4984 block_attributes[4] = 1;
4985 block_attributes[2] = -force_bc->data.value5 * force_bc->data.value1;
4986 block_attributes[5] = 1;
4987 auto faces = bc.second->bcEnts.subset_by_dimension(2);
4988 bcSpatialTractionVecPtr->emplace_back(block_name, block_attributes,
4989 faces);
4990 }
4991 }
4992 CHKERR getBc(bcSpatialTractionVecPtr, "SPATIAL_TRACTION_BC", 6);
4993
4994 bcSpatialPressureVecPtr = boost::make_shared<PressureBcVec>();
4995 for (auto bc : bc_mng->getBcMapByBlockName()) {
4996 auto block_name = "(.*)PRESSURE(.*)";
4997 std::regex reg_name(block_name);
4998 if (std::regex_match(bc.first, reg_name)) {
4999
5000 auto [field_name, block_name] =
5002 MOFEM_LOG("EP", Sev::inform)
5003 << "Field name: " << field_name << " Block name: " << block_name;
5004 bcSpatialPressureVecPtr->emplace_back(
5005 block_name, bc.second->bcAttributes,
5006 bc.second->bcEnts.subset_by_dimension(2));
5007 }
5008 }
5009
5011 boost::make_shared<AnalyticalTractionBcVec>();
5012
5013 for (auto bc : bc_mng->getBcMapByBlockName()) {
5014 auto block_name = "(.*)ANALYTICAL_TRACTION(.*)";
5015 std::regex reg_name(block_name);
5016 if (std::regex_match(bc.first, reg_name)) {
5017 auto [field_name, block_name] =
5019 MOFEM_LOG("EP", Sev::inform)
5020 << "Field name: " << field_name << " Block name: " << block_name;
5022 block_name, bc.second->bcAttributes,
5023 bc.second->bcEnts.subset_by_dimension(2));
5024 }
5025 }
5026
5027 auto ts_traction =
5028 boost::make_shared<DynamicRelaxationTimeScale>("traction_history.txt");
5029 for (auto &bc : *bcSpatialTractionVecPtr) {
5030 timeScaleMap[bc.blockName] =
5032 ts_traction, "traction_history", ".txt", bc.blockName);
5033 }
5034
5035 auto ts_pressure =
5036 boost::make_shared<DynamicRelaxationTimeScale>("pressure_history.txt");
5037 for (auto &bc : *bcSpatialPressureVecPtr) {
5038 timeScaleMap[bc.blockName] =
5040 ts_pressure, "pressure_history", ".txt", bc.blockName);
5041 }
5042
5044}
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 333 of file EshelbianCore.hpp.

333 {
335 boost::shared_ptr<TractionFreeBc>(new TractionFreeBc());
336 return getTractionFreeBc(meshset, bcSpatialFreeTractionVecPtr, "CONTACT");
337 }
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 4798 of file EshelbianPlasticity.cpp.

4798 {
4800
4801 auto post_proc_norm_fe =
4802 boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
4803
4804 auto bubble_cache =
4805 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0, MatrixDouble());
4806 post_proc_norm_fe->getUserPolynomialBase() =
4807 boost::shared_ptr<BaseFunction>(new CGGUserPolynomialBase(bubble_cache));
4808 post_proc_norm_fe->getRuleHook = [](int, int, int) { return -1; };
4809 auto vol_rule_lin = [](int o) { return 2 * o + 1; };
4810 auto vol_rule_no_lin = [](int o) { return 2 * o + (o - 1) + 1; };
4811 auto vol_rule = (SMALL_ROT > 0) ? vol_rule_lin : vol_rule_no_lin;
4812 post_proc_norm_fe->setRuleHook = SetIntegrationAtFrontVolume(
4813 frontVertices, frontAdjEdges, vol_rule, bubble_cache);
4814 CHKERR EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4815 post_proc_norm_fe->getOpPtrVector(), {L2, H1, HDIV}, materialH1Positions,
4817
4818 enum NORMS { U_NORM_L2 = 0, U_NORM_H1, PIOLA_NORM, U_ERROR_L2, LAST_NORM };
4819 auto norms_vec =
4820 createVectorMPI(mField.get_comm(), LAST_NORM, PETSC_DETERMINE);
4821 CHKERR VecZeroEntries(norms_vec);
4822
4823 auto u_l2_ptr = boost::make_shared<MatrixDouble>();
4824 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
4825 post_proc_norm_fe->getOpPtrVector().push_back(
4827 post_proc_norm_fe->getOpPtrVector().push_back(
4829 post_proc_norm_fe->getOpPtrVector().push_back(
4830 new OpCalcNormL2Tensor1<SPACE_DIM>(u_l2_ptr, norms_vec, U_NORM_L2));
4831 post_proc_norm_fe->getOpPtrVector().push_back(
4832 new OpCalcNormL2Tensor1<SPACE_DIM>(u_h1_ptr, norms_vec, U_NORM_H1));
4833 post_proc_norm_fe->getOpPtrVector().push_back(
4834 new OpCalcNormL2Tensor1<SPACE_DIM>(u_l2_ptr, norms_vec, U_ERROR_L2,
4835 u_h1_ptr));
4836
4837 auto piola_ptr = boost::make_shared<MatrixDouble>();
4838 post_proc_norm_fe->getOpPtrVector().push_back(
4840 post_proc_norm_fe->getOpPtrVector().push_back(
4842 MBMAXTYPE));
4843
4844 post_proc_norm_fe->getOpPtrVector().push_back(
4845 new OpCalcNormL2Tensor2<3, 3>(piola_ptr, norms_vec, PIOLA_NORM));
4846
4847 TetPolynomialBase::switchCacheBaseOn<HDIV>({post_proc_norm_fe.get()});
4849 *post_proc_norm_fe);
4850 TetPolynomialBase::switchCacheBaseOff<HDIV>({post_proc_norm_fe.get()});
4851
4852 CHKERR VecAssemblyBegin(norms_vec);
4853 CHKERR VecAssemblyEnd(norms_vec);
4854 const double *norms;
4855 CHKERR VecGetArrayRead(norms_vec, &norms);
4856 MOFEM_LOG("EP", Sev::inform) << "norm_u: " << std::sqrt(norms[U_NORM_L2]);
4857 MOFEM_LOG("EP", Sev::inform) << "norm_u_h1: " << std::sqrt(norms[U_NORM_H1]);
4858 MOFEM_LOG("EP", Sev::inform)
4859 << "norm_error_u_l2: " << std::sqrt(norms[U_ERROR_L2]);
4860 MOFEM_LOG("EP", Sev::inform)
4861 << "norm_piola: " << std::sqrt(norms[PIOLA_NORM]);
4862 CHKERR VecRestoreArrayRead(norms_vec, &norms);
4863
4865}
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 2679 of file EshelbianPlasticity.cpp.

2681 {
2683
2684 // get skin from all tets
2685 Range tets;
2686 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
2687 Range tets_skin_part;
2688 Skinner skin(&mField.get_moab());
2689 CHKERR skin.find_skin(0, tets, false, tets_skin_part);
2690 ParallelComm *pcomm =
2691 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
2692 Range tets_skin;
2693 CHKERR pcomm->filter_pstatus(tets_skin_part,
2694 PSTATUS_SHARED | PSTATUS_MULTISHARED,
2695 PSTATUS_NOT, -1, &tets_skin);
2696
2697 bc_ptr->resize(3);
2698 for (int dd = 0; dd != 3; ++dd)
2699 (*bc_ptr)[dd] = tets_skin;
2700
2701 // Do not remove dofs on which traction is applied
2703 for (auto &v : *bcSpatialDispVecPtr) {
2704 if (v.flags[0])
2705 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2706 if (v.flags[1])
2707 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2708 if (v.flags[2])
2709 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2710 }
2711
2712 // Do not remove dofs on which rotation is applied
2714 for (auto &v : *bcSpatialRotationVecPtr) {
2715 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2716 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2717 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2718 }
2719
2721 for (auto &v : *bcSpatialNormalDisplacementVecPtr) {
2722 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2723 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2724 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2725 }
2726
2729 if (v.flags[0])
2730 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2731 if (v.flags[1])
2732 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2733 if (v.flags[2])
2734 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2735 }
2736
2738 for (auto &v : *bcSpatialTractionVecPtr) {
2739 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2740 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2741 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2742 }
2743
2745 for (auto &v : *bcSpatialAnalyticalTractionVecPtr) {
2746 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2747 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2748 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2749 }
2750
2752 for (auto &v : *bcSpatialPressureVecPtr) {
2753 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2754 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2755 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2756 }
2757
2758 // remove contact
2759 for (auto m : mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
2760 std::regex((boost::format("%s(.*)") % contact_set_name).str()))) {
2761 Range faces;
2762 CHKERR m->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2, faces,
2763 true);
2764 (*bc_ptr)[0] = subtract((*bc_ptr)[0], faces);
2765 (*bc_ptr)[1] = subtract((*bc_ptr)[1], faces);
2766 (*bc_ptr)[2] = subtract((*bc_ptr)[2], faces);
2767 }
2768
2770}
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 152 of file EshelbianCore.hpp.

152 {
153 if (v > std::exp(v_min))
154 return 1. / v;
155 else
156 return 1. / exp(v_min);
157 }
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 158 of file EshelbianCore.hpp.

158 {
159 if (v > std::exp(v_min))
160 return -1. / (v * v);
161 else
162 return 0.;
163 }

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

143 {
144 if (v > std::exp(v_min))
145 return std::log(v);
146 else
147 // y = exp(v_min) * v + exp(v_min) * (1 - v_min);
148 // y/exp(v_min) = v + (1 - v_min);
149 // y/exp(v_min) - (1 - v_min) = v;
150 return v / exp(v_min) - (1 - v_min);
151 }

◆ 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 = {},
TS  ts = PETSC_NULLPTR 
)
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 4151 of file EshelbianPlasticity.cpp.

4153 {
4155
4156 // mark crack surface
4157 if (crackingOn) {
4158 auto get_tag = [&](auto name, auto dim) {
4159 auto &mob = mField.get_moab();
4160 Tag tag;
4161 double def_val[] = {0., 0., 0.};
4162 CHK_MOAB_THROW(mob.tag_get_handle(name, dim, MB_TYPE_DOUBLE, tag,
4163 MB_TAG_CREAT | MB_TAG_SPARSE, def_val),
4164 "create tag");
4165 return tag;
4166 };
4167 tags_to_transfer.push_back(get_tag("MaterialForce", 3));
4168 }
4169
4170 {
4171 auto get_crack_tag = [&]() {
4172 Tag th;
4173 rval = mField.get_moab().tag_get_handle("CRACK", th);
4174 if (rval == MB_SUCCESS) {
4175 MOAB_THROW(mField.get_moab().tag_delete(th));
4176 }
4177 int def_val[] = {0};
4178 MOAB_THROW(mField.get_moab().tag_get_handle(
4179 "CRACK", 1, MB_TYPE_INTEGER, th, MB_TAG_SPARSE | MB_TAG_CREAT,
4180 def_val));
4181 return th;
4182 };
4183
4184 Tag th = get_crack_tag();
4185 tags_to_transfer.push_back(th);
4186 int mark[] = {1};
4187 Range mark_faces;
4188 if (crackFaces)
4189 mark_faces.merge(*crackFaces);
4190 if (interfaceFaces)
4191 mark_faces.merge(*interfaceFaces);
4192 CHKERR mField.get_moab().tag_clear_data(th, mark_faces, mark);
4193 }
4194
4195 // add tags to transfer
4196 for (auto t : listTagsToTransfer) {
4197 std::string name;
4198 CHKERR mField.get_moab().tag_get_name(t, name);
4199 MOFEM_LOG("EP", Sev::verbose) << "Adding tag " << name
4200 << " to transfer list for post-processing";
4201 tags_to_transfer.push_back(t);
4202 }
4203
4204 if (!dataAtPts) {
4205 dataAtPts =
4206 boost::shared_ptr<DataAtIntegrationPts>(new DataAtIntegrationPts());
4207 }
4208
4210
4211 auto get_post_proc = [&](auto &post_proc_mesh, auto sense) {
4213 auto post_proc_ptr =
4214 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
4215 mField, post_proc_mesh);
4216 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
4217 post_proc_ptr->getOpPtrVector(), {L2}, materialH1Positions,
4219
4220 if (ts != PETSC_NULLPTR) {
4221 post_proc_ptr->data_ctx |= PetscData::CTX_SET_TIME;
4222 CHKERR TSGetTime(ts, &(post_proc_ptr->ts_t));
4223 }
4224
4225 auto domain_ops = [&](auto &fe, int sense) {
4227
4228 auto bubble_cache = boost::make_shared<CGGUserPolynomialBase::CachePhi>(
4229 0, 0, MatrixDouble());
4230 fe.getUserPolynomialBase() = boost::shared_ptr<BaseFunction>(
4231 new CGGUserPolynomialBase(bubble_cache));
4232 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4233 fe.getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions,
4235 auto piola_scale_ptr = boost::make_shared<double>(1.0);
4236 fe.getOpPtrVector().push_back(physicalEquations->returnOpSetScale(
4237 piola_scale_ptr, physicalEquations));
4238 fe.getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
4239 piolaStress, dataAtPts->getApproxPAtPts(), piola_scale_ptr));
4240 fe.getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
4241 bubbleField, dataAtPts->getApproxPAtPts(), piola_scale_ptr,
4242 SmartPetscObj<Vec>(), MBMAXTYPE));
4243 if (noStretch) {
4244 fe.getOpPtrVector().push_back(
4245 physicalEquations->returnOpCalculateStretchFromStress(
4247 } else {
4248 fe.getOpPtrVector().push_back(
4250 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
4251 }
4252 if (var_vector) {
4253 auto vec = SmartPetscObj<Vec>(var_vector, true);
4254 fe.getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
4255 piolaStress, dataAtPts->getVarPiolaPts(),
4256 boost::make_shared<double>(1), vec));
4257 fe.getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
4258 bubbleField, dataAtPts->getVarPiolaPts(),
4259 boost::make_shared<double>(1), vec, MBMAXTYPE));
4260 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4261 rotAxis, dataAtPts->getVarRotAxisPts(), vec, MBTET));
4262 if (noStretch) {
4263 fe.getOpPtrVector().push_back(
4264 physicalEquations->returnOpCalculateVarStretchFromStress(
4266 } else {
4267 fe.getOpPtrVector().push_back(
4269 stretchTensor, dataAtPts->getVarLogStreachPts(), vec, MBTET));
4270 }
4271 }
4272
4273 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4274 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
4275 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4276 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
4277
4278 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4279 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
4280 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4281 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
4282 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldGradient<3, 3>(
4283 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
4284 // evaluate derived quantities
4285 fe.getOpPtrVector().push_back(
4287
4288 // evaluate integration points
4289 fe.getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
4290 tag, true, false, dataAtPts, physicalEquations));
4291 if (auto op =
4292 physicalEquations->returnOpCalculateEnergy(dataAtPts, nullptr)) {
4293 fe.getOpPtrVector().push_back(op);
4294 fe.getOpPtrVector().push_back(new OpCalculateEshelbyStress(dataAtPts));
4295 }
4296
4297 // // post-proc
4300 VolumeElementForcesAndSourcesCoreOnSide::UserDataOperator>;
4301
4302 struct OpSidePPMap : public OpPPMap {
4303 OpSidePPMap(moab::Interface &post_proc_mesh,
4304 std::vector<EntityHandle> &map_gauss_pts,
4305 DataMapVec data_map_scalar, DataMapMat data_map_vec,
4306 DataMapMat data_map_mat, DataMapMat data_symm_map_mat,
4307 int sense)
4308 : OpPPMap(post_proc_mesh, map_gauss_pts, data_map_scalar,
4309 data_map_vec, data_map_mat, data_symm_map_mat),
4310 tagSense(sense) {}
4311
4312 MoFEMErrorCode doWork(int side, EntityType type,
4315
4316 if (tagSense != 0) {
4317 if (tagSense != OpPPMap::getSkeletonSense())
4319 }
4320
4321 CHKERR OpPPMap::doWork(side, type, data);
4323 }
4324
4325 private:
4326 int tagSense;
4327 };
4328
4329 OpPPMap::DataMapMat vec_fields;
4330 vec_fields["SpatialDisplacementL2"] = dataAtPts->getSmallWL2AtPts();
4331 vec_fields["SpatialDisplacementH1"] = dataAtPts->getSmallWH1AtPts();
4332 vec_fields["Omega"] = dataAtPts->getRotAxisAtPts();
4333 vec_fields["AngularMomentum"] = dataAtPts->getLeviKirchhoffAtPts();
4334 vec_fields["X"] = dataAtPts->getLargeXH1AtPts();
4335 if (!noStretch) {
4336 vec_fields["EiegnLogStreach"] = dataAtPts->getEigenValsAtPts();
4337 }
4338 if (var_vector) {
4339 auto vec = SmartPetscObj<Vec>(var_vector, true);
4340 vec_fields["VarOmega"] = dataAtPts->getVarRotAxisPts();
4341 vec_fields["VarSpatialDisplacementL2"] =
4342 boost::make_shared<MatrixDouble>();
4343 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4344 spatialL2Disp, vec_fields["VarSpatialDisplacementL2"], vec, MBTET));
4345 }
4346 if (f_residual) {
4347 auto vec = SmartPetscObj<Vec>(f_residual, true);
4348 vec_fields["ResSpatialDisplacementL2"] =
4349 boost::make_shared<MatrixDouble>();
4350 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4351 spatialL2Disp, vec_fields["ResSpatialDisplacementL2"], vec, MBTET));
4352 vec_fields["ResOmega"] = boost::make_shared<MatrixDouble>();
4353 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4354 rotAxis, vec_fields["ResOmega"], vec, MBTET));
4355 }
4356
4357 OpPPMap::DataMapMat mat_fields;
4358 mat_fields["PiolaStress"] = dataAtPts->getApproxPAtPts();
4359 if (var_vector) {
4360 mat_fields["VarPiolaStress"] = dataAtPts->getVarPiolaPts();
4361 }
4362 if (f_residual) {
4363 auto vec = SmartPetscObj<Vec>(f_residual, true);
4364 mat_fields["ResPiolaStress"] = boost::make_shared<MatrixDouble>();
4365 fe.getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
4366 piolaStress, mat_fields["ResPiolaStress"],
4367 boost::make_shared<double>(1), vec));
4368 fe.getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
4369 bubbleField, mat_fields["ResPiolaStress"],
4370 boost::make_shared<double>(1), vec, MBMAXTYPE));
4371 }
4372 if (!internalStressTagName.empty()) {
4373 mat_fields[internalStressTagName] = dataAtPts->getInternalStressAtPts();
4374 switch (internalStressInterpOrder) {
4375 case 0:
4376 fe.getOpPtrVector().push_back(
4378 break;
4379 case 1:
4380 fe.getOpPtrVector().push_back(
4382 break;
4383 default:
4384 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
4385 "Unsupported internal stress interpolation order %d",
4387 }
4388 }
4389
4390 OpPPMap::DataMapMat mat_fields_symm;
4391 mat_fields_symm["LogSpatialStretch"] =
4392 dataAtPts->getLogStretchTensorAtPts();
4393 mat_fields_symm["SpatialStretch"] = dataAtPts->getStretchTensorAtPts();
4394 if (var_vector) {
4395 mat_fields_symm["VarLogSpatialStretch"] =
4396 dataAtPts->getVarLogStreachPts();
4397 }
4398 if (f_residual) {
4399 auto vec = SmartPetscObj<Vec>(f_residual, true);
4400 if (!noStretch) {
4401 mat_fields_symm["ResLogSpatialStretch"] =
4402 boost::make_shared<MatrixDouble>();
4403 fe.getOpPtrVector().push_back(
4405 stretchTensor, mat_fields_symm["ResLogSpatialStretch"], vec,
4406 MBTET));
4407 }
4408 }
4409
4410 fe.getOpPtrVector().push_back(
4411
4412 new OpSidePPMap(
4413
4414 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4415
4416 {},
4417
4418 vec_fields,
4419
4420 mat_fields,
4421
4422 mat_fields_symm,
4423
4424 sense
4425
4426 )
4427
4428 );
4429
4430 fe.getOpPtrVector().push_back(new OpPostProcDataStructure(
4431 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4432 dataAtPts, sense));
4433
4435 };
4436
4437 auto X_h1_ptr = boost::make_shared<MatrixDouble>();
4438 // H1 material positions
4439 post_proc_ptr->getOpPtrVector().push_back(
4441 dataAtPts->getLargeXH1AtPts()));
4442
4443 // domain
4446 domain_ops(*(op_loop_side->getSideFEPtr()), sense);
4447 post_proc_ptr->getOpPtrVector().push_back(op_loop_side);
4448
4449 return post_proc_ptr;
4450 };
4451
4452 // contact
4453 auto calcs_side_traction_and_displacements = [&](auto &post_proc_ptr,
4454 auto &pip) {
4456 // evaluate traction
4457 using EleOnSide =
4459 using SideEleOp = EleOnSide::UserDataOperator;
4460 auto op_loop_domain_side = new OpLoopSide<EleOnSide>(
4461 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
4462 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
4463 boost::shared_ptr<BaseFunction>(
4464 new CGGUserPolynomialBase(nullptr, true));
4465 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4466 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
4468 auto traction_ptr = boost::make_shared<MatrixDouble>();
4469 op_loop_domain_side->getOpPtrVector().push_back(
4471 piolaStress, traction_ptr, boost::make_shared<double>(1.0)));
4472
4473 pip.push_back(new OpCalculateVectorFieldValues<3>(
4474 contactDisp, dataAtPts->getContactL2AtPts()));
4475 pip.push_back(op_loop_domain_side);
4476 // evaluate contact displacement and contact conditions
4477 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
4478 pip.push_back(new OpCalculateVectorFieldValues<3>(spatialH1Disp, u_h1_ptr));
4479 pip.push_back(getOpContactDetection(
4480 *this, contactTreeRhs, u_h1_ptr, traction_ptr,
4481 get_range_from_block(mField, "CONTACT", SPACE_DIM - 1),
4482 &post_proc_ptr->getPostProcMesh(), &post_proc_ptr->getMapGaussPts()));
4483
4485 using BoundaryEle =
4487 auto op_this = new OpLoopThis<BoundaryEle>(mField, contactElement);
4488 pip.push_back(op_this);
4489
4490 op_this->getOpPtrVector().push_back(
4491
4492 new OpPPMap(
4493
4494 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4495
4496 {},
4497
4498 {{"ContactDisplacement", dataAtPts->getContactL2AtPts()}},
4499
4500 {},
4501
4502 {}
4503
4504 )
4505
4506 );
4507
4508
4509 if (f_residual) {
4510
4511 auto contact_residual = boost::make_shared<MatrixDouble>();
4512 op_this->getOpPtrVector().push_back(
4514 contactDisp, contact_residual,
4515 SmartPetscObj<Vec>(f_residual, true)));
4516 op_this->getOpPtrVector().push_back(
4517
4518 new OpPPMap(
4519
4520 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4521
4522 {},
4523
4524 {{"res_contact", contact_residual}},
4525
4526 {},
4527
4528 {}
4529
4530 )
4531
4532 );
4533 }
4534
4536 };
4537
4538 auto post_proc_mesh = boost::make_shared<moab::Core>();
4539 auto post_proc_ptr = get_post_proc(post_proc_mesh, /*positive sense*/ 1);
4540 auto post_proc_negative_sense_ptr =
4541 get_post_proc(post_proc_mesh, /*negative sense*/ -1);
4542 auto skin_post_proc_ptr = get_post_proc(post_proc_mesh, /*positive sense*/ 1);
4543 CHKERR calcs_side_traction_and_displacements(
4544 skin_post_proc_ptr, skin_post_proc_ptr->getOpPtrVector());
4545
4546 auto own_tets =
4548 .subset_by_dimension(SPACE_DIM);
4549 Range own_faces;
4550 CHKERR mField.get_moab().get_adjacencies(own_tets, SPACE_DIM - 1, true,
4551 own_faces, moab::Interface::UNION);
4552
4553 auto get_crack_faces = [&](auto crack_faces) {
4554 auto get_adj = [&](auto e, auto dim) {
4555 Range adj;
4556 CHKERR mField.get_moab().get_adjacencies(e, dim, true, adj,
4557 moab::Interface::UNION);
4558 return adj;
4559 };
4560 // this removes faces
4561 auto tets = get_adj(crack_faces, 3);
4562 // faces adjacent to tets not in crack_faces
4563 auto faces = subtract(get_adj(tets, 2), crack_faces);
4564 // what is left from below, are tets fully inside crack_faces
4565 tets = subtract(tets, get_adj(faces, 3));
4566 return subtract(crack_faces, get_adj(tets, 2));
4567 };
4568
4569 auto side_one_faces = [&](auto &faces) {
4570 std::pair<Range, Range> sides;
4571 for (auto f : faces) {
4572 Range adj;
4573 MOAB_THROW(mField.get_moab().get_adjacencies(&f, 1, 3, false, adj));
4574 adj = intersect(own_tets, adj);
4575 for (auto t : adj) {
4576 int side, sense, offset;
4577 MOAB_THROW(mField.get_moab().side_number(t, f, side, sense, offset));
4578 if (sense == 1) {
4579 sides.first.insert(f);
4580 } else {
4581 sides.second.insert(f);
4582 }
4583 }
4584 }
4585 return sides;
4586 };
4587
4588 auto get_interface_from_block = [&](auto block_name) {
4589 auto vol_eles = get_range_from_block(mField, block_name, SPACE_DIM);
4590 auto skin = filter_true_skin(mField, get_skin(mField, vol_eles));
4591 Range faces;
4592 CHKERR mField.get_moab().get_adjacencies(vol_eles, SPACE_DIM - 1, true,
4593 faces, moab::Interface::UNION);
4594 faces = subtract(faces, skin);
4595 return faces;
4596 };
4597
4598 auto crack_faces = unite(get_crack_faces(*crackFaces), *interfaceFaces);
4599 // crack_faces.merge(get_interface_from_block("VOLUME_INTERFACE"));
4600 auto crack_side_faces = side_one_faces(crack_faces);
4601 auto side_one_crack_faces = [crack_side_faces](FEMethod *fe_method_ptr) {
4602 auto ent = fe_method_ptr->getFEEntityHandle();
4603 if (crack_side_faces.first.find(ent) == crack_side_faces.first.end()) {
4604 return false;
4605 }
4606 return true;
4607 };
4608 auto side_minus_crack_faces = [crack_side_faces](FEMethod *fe_method_ptr) {
4609 auto ent = fe_method_ptr->getFEEntityHandle();
4610 if (crack_side_faces.second.find(ent) == crack_side_faces.second.end()) {
4611 return false;
4612 }
4613 return true;
4614 };
4615
4616 skin_post_proc_ptr->setTagsToTransfer(tags_to_transfer);
4617 post_proc_ptr->setTagsToTransfer(tags_to_transfer);
4618 post_proc_negative_sense_ptr->setTagsToTransfer(tags_to_transfer);
4619
4620 auto post_proc_begin =
4622 CHKERR DMoFEMPreProcessFiniteElements(dM, post_proc_begin.getFEMethod());
4623 CHKERR DMoFEMLoopFiniteElements(dM, skinElement, skin_post_proc_ptr);
4624 post_proc_ptr->exeTestHook = side_one_crack_faces;
4626 dM, skeletonElement, post_proc_ptr, 0, mField.get_comm_size());
4627 post_proc_negative_sense_ptr->exeTestHook = side_minus_crack_faces;
4629 post_proc_negative_sense_ptr, 0,
4631
4632 constexpr bool debug = false;
4633 if (debug) {
4634
4635 auto get_adj_front = [&]() {
4636 auto skeleton_faces = *skeletonFaces;
4637 Range adj_front;
4638 CHKERR mField.get_moab().get_adjacencies(*frontEdges, 2, true, adj_front,
4639 moab::Interface::UNION);
4640
4641 adj_front = intersect(adj_front, skeleton_faces);
4642 adj_front = subtract(adj_front, *crackFaces);
4643 adj_front = intersect(own_faces, adj_front);
4644 return adj_front;
4645 };
4646
4647 auto adj_front = filter_owners(mField, get_adj_front());
4648 auto only_front_faces = [adj_front](FEMethod *fe_method_ptr) {
4649 auto ent = fe_method_ptr->getFEEntityHandle();
4650 if (adj_front.find(ent) == adj_front.end()) {
4651 return false;
4652 }
4653 return true;
4654 };
4655
4656 post_proc_ptr->exeTestHook = only_front_faces;
4658 dM, skeletonElement, post_proc_ptr, 0, mField.get_comm_size());
4659 post_proc_negative_sense_ptr->exeTestHook = only_front_faces;
4661 post_proc_negative_sense_ptr, 0,
4663 }
4664 auto post_proc_end = PostProcBrokenMeshInMoabBaseEnd(mField, post_proc_mesh);
4665 CHKERR DMoFEMPostProcessFiniteElements(dM, post_proc_end.getFEMethod());
4666
4667 CHKERR post_proc_end.writeFile(file.c_str());
4669}
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
@ CTX_SET_TIME
Time value is set.
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 4672 of file EshelbianPlasticity.cpp.

4674 {
4676
4678
4679 auto post_proc_mesh = boost::make_shared<moab::Core>();
4680 auto post_proc_ptr =
4681 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
4682 mField, post_proc_mesh);
4683 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM - 1, SPACE_DIM>::add(
4684 post_proc_ptr->getOpPtrVector(), {L2}, materialH1Positions,
4686
4687 auto hybrid_disp = boost::make_shared<MatrixDouble>();
4688 post_proc_ptr->getOpPtrVector().push_back(
4690 post_proc_ptr->getOpPtrVector().push_back(
4692 hybridSpatialDisp, dataAtPts->getGradHybridDispAtPts()));
4693
4694 auto op_loop_domain_side =
4696 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
4697 post_proc_ptr->getOpPtrVector().push_back(op_loop_domain_side);
4698
4699 // evaluated in side domain, that is op_loop_domain_side
4700 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
4701 boost::make_shared<CGGUserPolynomialBase>(nullptr, true);
4702 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4703 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
4705 op_loop_domain_side->getOpPtrVector().push_back(
4707 piolaStress, dataAtPts->getApproxPAtPts()));
4708 op_loop_domain_side->getOpPtrVector().push_back(
4710 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
4711 op_loop_domain_side->getOpPtrVector().push_back(
4713 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
4714
4715 if (noStretch) {
4716 op_loop_domain_side->getOpPtrVector().push_back(
4717 physicalEquations->returnOpCalculateStretchFromStress(
4719 } else {
4720 op_loop_domain_side->getOpPtrVector().push_back(
4722 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
4723 }
4724
4726
4727 OpPPMap::DataMapMat vec_fields;
4728 vec_fields["HybridDisplacement"] = hybrid_disp;
4729 // note that grad and omega have not trace, so this is only other side value
4730 vec_fields["spatialL2Disp"] = dataAtPts->getSmallWL2AtPts();
4731 vec_fields["Omega"] = dataAtPts->getRotAxisAtPts();
4732 OpPPMap::DataMapMat mat_fields;
4733 mat_fields["PiolaStress"] = dataAtPts->getApproxPAtPts();
4734 mat_fields["HybridDisplacementGradient"] =
4735 dataAtPts->getGradHybridDispAtPts();
4736 OpPPMap::DataMapMat mat_fields_symm;
4737 mat_fields_symm["LogSpatialStretch"] = dataAtPts->getLogStretchTensorAtPts();
4738
4739 post_proc_ptr->getOpPtrVector().push_back(
4740
4741 new OpPPMap(
4742
4743 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4744
4745 {},
4746
4747 vec_fields,
4748
4749 mat_fields,
4750
4751 mat_fields_symm
4752
4753 )
4754
4755 );
4756
4757 if (f_residual) {
4758 auto hybrid_res = boost::make_shared<MatrixDouble>();
4759 post_proc_ptr->getOpPtrVector().push_back(
4761 hybridSpatialDisp, hybrid_res,
4762 SmartPetscObj<Vec>(f_residual, true)));
4764 post_proc_ptr->getOpPtrVector().push_back(
4765
4766 new OpPPMap(
4767
4768 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4769
4770 {},
4771
4772 {{"res_hybrid", hybrid_res}},
4773
4774 {},
4775
4776 {}
4777
4778 )
4779
4780 );
4781 }
4782
4783 post_proc_ptr->setTagsToTransfer(tags_to_transfer);
4784
4785 auto post_proc_begin =
4787 CHKERR DMoFEMPreProcessFiniteElements(dM, post_proc_begin.getFEMethod());
4789 auto post_proc_end = PostProcBrokenMeshInMoabBaseEnd(mField, post_proc_mesh);
4790 CHKERR DMoFEMPostProcessFiniteElements(dM, post_proc_end.getFEMethod());
4791
4792 CHKERR post_proc_end.writeFile(file.c_str());
4793
4795}

◆ projectGeometry()

MoFEMErrorCode EshelbianCore::projectGeometry ( const EntityHandle  meshset = 0,
double  time = 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 1518 of file EshelbianPlasticity.cpp.

1519 {
1521
1522 Range meshset_ents;
1523 CHKERR mField.get_moab().get_entities_by_handle(meshset, meshset_ents);
1524
1525 auto project_ho_geometry = [&](auto field) {
1527 return mField.loop_dofs(field, ent_method);
1528 };
1529 CHKERR project_ho_geometry(materialH1Positions);
1530
1531 auto get_adj_front_edges = [&](auto &front_edges) {
1532 Range front_crack_nodes;
1533 Range crack_front_edges_with_both_nodes_not_at_front;
1534
1535 if (mField.get_comm_rank() == 0) {
1536 auto &moab = mField.get_moab();
1538 moab.get_connectivity(front_edges, front_crack_nodes, true),
1539 "get_connectivity failed");
1540 Range crack_front_edges;
1541 CHK_MOAB_THROW(moab.get_adjacencies(front_crack_nodes, SPACE_DIM - 2,
1542 false, crack_front_edges,
1543 moab::Interface::UNION),
1544 "get_adjacencies failed");
1545 Range crack_front_edges_nodes;
1546 CHK_MOAB_THROW(moab.get_connectivity(crack_front_edges,
1547 crack_front_edges_nodes, true),
1548 "get_connectivity failed");
1549 // those nodes are hannging nodes
1550 crack_front_edges_nodes =
1551 subtract(crack_front_edges_nodes, front_crack_nodes);
1552 Range crack_front_edges_with_both_nodes_not_at_front;
1554 moab.get_adjacencies(crack_front_edges_nodes, 1, false,
1555 crack_front_edges_with_both_nodes_not_at_front,
1556 moab::Interface::UNION),
1557 "get_adjacencies failed");
1558 // those edges are have one node not at the crack front
1559 crack_front_edges_with_both_nodes_not_at_front = intersect(
1560 crack_front_edges, crack_front_edges_with_both_nodes_not_at_front);
1561 }
1562
1563 front_crack_nodes = send_type(mField, front_crack_nodes, MBVERTEX);
1564 crack_front_edges_with_both_nodes_not_at_front = send_type(
1565 mField, crack_front_edges_with_both_nodes_not_at_front, MBEDGE);
1566
1567 return std::make_pair(boost::make_shared<Range>(front_crack_nodes),
1568 boost::make_shared<Range>(
1569 crack_front_edges_with_both_nodes_not_at_front));
1570 };
1571
1572 if ((time - crackingAddTime) > std::numeric_limits<double>::epsilon()) {
1573 crackFaces = boost::make_shared<Range>(
1574 get_range_from_block(mField, "CRACK", SPACE_DIM - 1));
1575 } else {
1576 crackFaces = boost::make_shared<Range>();
1577 }
1578 frontEdges =
1579 boost::make_shared<Range>(get_crack_front_edges(mField, *crackFaces));
1580 auto [front_vertices, front_adj_edges] = get_adj_front_edges(*frontEdges);
1581 frontVertices = front_vertices;
1582 frontAdjEdges = front_adj_edges;
1583
1584 MOFEM_LOG("EP", Sev::inform)
1585 << "Number of crack faces: " << crackFaces->size();
1586 MOFEM_LOG("EP", Sev::inform)
1587 << "Number of front edges: " << frontEdges->size();
1588 MOFEM_LOG("EP", Sev::inform)
1589 << "Number of front vertices: " << frontVertices->size();
1590 MOFEM_LOG("EP", Sev::inform)
1591 << "Number of front adjacent edges: " << frontAdjEdges->size();
1592
1593#ifndef NDEBUG
1594 if (crackingOn) {
1595 auto rank = mField.get_comm_rank();
1596 // CHKERR save_range(mField.get_moab(),
1597 // (boost::format("meshset_ents_%d.vtk") % rank).str(),
1598 // meshset_ents);
1600 (boost::format("crack_faces_%d.vtk") % rank).str(),
1601 *crackFaces);
1603 (boost::format("front_edges_%d.vtk") % rank).str(),
1604 *frontEdges);
1605 // CHKERR save_range(mField.get_moab(),
1606 // (boost::format("front_vertices_%d.vtk") % rank).str(),
1607 // *frontVertices);
1608 // CHKERR save_range(mField.get_moab(),
1609 // (boost::format("front_adj_edges_%d.vtk") % rank).str(),
1610 // *frontAdjEdges);
1611 }
1612#endif // NDEBUG
1613
1614 auto set_singular_dofs = [&](auto &front_adj_edges, auto &front_vertices) {
1616 auto &moab = mField.get_moab();
1617
1618 double eps = 1;
1619 double beta = 0;
1620 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "-singularity_eps", &beta,
1621 PETSC_NULLPTR);
1622 MOFEM_LOG("EP", Sev::inform) << "Singularity eps " << beta;
1623 eps -= beta;
1624
1625 auto field_blas = mField.getInterface<FieldBlas>();
1626 auto lambda =
1627 [&](boost::shared_ptr<FieldEntity> field_entity_ptr) -> MoFEMErrorCode {
1629 FTENSOR_INDEX(3, i);
1630 FTENSOR_INDEX(3, j);
1631
1632 auto nb_dofs = field_entity_ptr->getEntFieldData().size();
1633 if (nb_dofs == 0) {
1635 }
1636
1637#ifndef NDEBUG
1638 if (field_entity_ptr->getNbOfCoeffs() != 3)
1640 "Expected 3 coefficients per edge");
1641 if (nb_dofs % 3 != 0)
1643 "Expected multiple of 3 coefficients per edge");
1644#endif // NDEBUG
1645
1646 auto get_conn = [&]() {
1647 int num_nodes;
1648 const EntityHandle *conn;
1649 CHKERR moab.get_connectivity(field_entity_ptr->getEnt(), conn,
1650 num_nodes, false);
1651 return std::make_pair(conn, num_nodes);
1652 };
1653
1654 auto get_dir = [&](auto &&conn_p) {
1655 auto [conn, num_nodes] = conn_p;
1656 double coords[6];
1657 CHKERR moab.get_coords(conn, num_nodes, coords);
1658 FTensor::Tensor1<double, 3> t_edge_dir{coords[3] - coords[0],
1659 coords[4] - coords[1],
1660 coords[5] - coords[2]};
1661 return t_edge_dir;
1662 };
1663
1664 auto get_singularity_dof = [&](auto &&conn_p, auto &&t_edge_dir) {
1665 auto [conn, num_nodes] = conn_p;
1666 FTensor::Tensor1<double, 3> t_singularity_dof{0., 0., 0.};
1667 if (front_vertices.find(conn[0]) != front_vertices.end()) {
1668 t_singularity_dof(i) = t_edge_dir(i) * (-eps);
1669 } else if (front_vertices.find(conn[1]) != front_vertices.end()) {
1670 t_singularity_dof(i) = t_edge_dir(i) * eps;
1671 }
1672 return t_singularity_dof;
1673 };
1674
1675 auto t_singularity_dof =
1676 get_singularity_dof(get_conn(), get_dir(get_conn()));
1677
1678 auto field_data = field_entity_ptr->getEntFieldData();
1680 &field_data[0], &field_data[1], &field_data[2]};
1681
1682 t_dof(i) = t_singularity_dof(i);
1683 ++t_dof;
1684 for (auto n = 1; n < field_data.size() / 3; ++n) {
1685 t_dof(i) = 0;
1686 ++t_dof;
1687 }
1688
1690 };
1691
1692 CHKERR field_blas->fieldLambdaOnEntities(lambda, materialH1Positions,
1693 &front_adj_edges);
1694
1696 };
1697
1698 if (setSingularity)
1699 CHKERR set_singular_dofs(*frontAdjEdges, *frontVertices);
1700
1701 interfaceFaces = boost::make_shared<Range>(
1702 get_range_from_block(mField, "INTERFACE", SPACE_DIM - 1));
1703 MOFEM_LOG("EP", Sev::inform)
1704 << "Number of interface elements: " << interfaceFaces->size();
1705
1706 auto get_interface_from_block = [&](auto block_name) {
1707 auto vol_eles = get_range_from_block(mField, block_name, SPACE_DIM);
1708 auto skin = filter_true_skin(mField, get_skin(mField, vol_eles));
1709 Range faces;
1710 CHKERR mField.get_moab().get_adjacencies(vol_eles, SPACE_DIM - 1, true,
1711 faces, moab::Interface::UNION);
1712 faces = subtract(faces, skin);
1713 MOFEM_LOG("EP", Sev::inform)
1714 << "Number of vol interface elements: " << vol_eles.size()
1715 << " and faces: " << faces.size();
1716 return faces;
1717 };
1718
1719 interfaceFaces->merge(get_interface_from_block("VOLUME_INTERFACE"));
1720
1721 auto remove_interface_from_block = [&](auto block_name, auto level) {
1723 Range intreface_faces;
1724 if (mField.get_comm_rank() == 0) {
1725 auto ents = get_entities_by_handle(mField, block_name);
1726 for (auto l = 0; l < level; ++l) {
1727 Range adj_tets;
1728 CHKERR mField.get_moab().get_adjacencies(
1729 ents, SPACE_DIM, true, adj_tets, moab::Interface::UNION);
1730 Range adj_tets_faces;
1731 CHKERR mField.get_moab().get_adjacencies(adj_tets, SPACE_DIM - 1, true,
1732 adj_tets_faces,
1733 moab::Interface::UNION);
1734 ents.merge(adj_tets_faces);
1735 }
1736 auto faces = ents.subset_by_dimension(SPACE_DIM - 1);
1737 if (faces.size()) {
1738 MOFEM_LOG("EP", Sev::inform)
1739 << "Removed ents " << faces.size()
1740 << " interface faces: " << interfaceFaces->size();
1741 }
1742 intreface_faces = subtract(*interfaceFaces, faces);
1743 MOFEM_LOG("EP", Sev::inform)
1744 << "Interface faces after remove " << intreface_faces;
1745 }
1746 auto intreface_faces_global = send_type(mField, intreface_faces, MBTRI);
1747 interfaceFaces->swap(intreface_faces_global);
1749 };
1750 CHKERR remove_interface_from_block("REMOVE_INTERFACE", interfaceRemoveLevel);
1751
1753}
static auto get_entities_by_handle(MoFEM::Interface &m_field, const std::string block_name)
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 1756 of file EshelbianPlasticity.cpp.

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

941 {
942 *iface = const_cast<EshelbianCore *>(this);
943 return 0;
944}

◆ saveOrgCoords()

MoFEMErrorCode EshelbianCore::saveOrgCoords ( )

Definition at line 2429 of file EshelbianFracture.cpp.

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

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

2795 {
2797
2798 auto bubble_cache =
2799 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0, MatrixDouble());
2800 fe->getUserPolynomialBase() =
2801 boost::make_shared<CGGUserPolynomialBase>(bubble_cache);
2802 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2803 fe->getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions, frontAdjEdges);
2804
2805 // set integration rule
2806 fe->getRuleHook = [](int, int, int) { return -1; };
2807 auto vol_rule_lin = [](int o) { return 2 * o + 1; };
2808 auto vol_rule_no_lin = [](int o) { return 2 * o + (o - 1) + 1; };
2809 auto vol_rule = (SMALL_ROT > 0) ? vol_rule_lin : vol_rule_no_lin;
2810 fe->setRuleHook = SetIntegrationAtFrontVolume(frontVertices, frontAdjEdges,
2811 vol_rule, bubble_cache);
2812 // fe->getRuleHook = VolRule();
2813
2814 if (!dataAtPts) {
2815 dataAtPts =
2816 boost::shared_ptr<DataAtIntegrationPts>(new DataAtIntegrationPts());
2817 dataAtPts->physicsPtr = physicalEquations;
2818 }
2819
2820 // calculate fields values
2821 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
2822 piolaStress, dataAtPts->getApproxPAtPts()));
2823 fe->getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
2824 bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
2825 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorDivergence<3, 3>(
2826 piolaStress, dataAtPts->getDivPAtPts()));
2827
2828 if (noStretch) {
2829 fe->getOpPtrVector().push_back(
2830 physicalEquations->returnOpCalculateStretchFromStress(
2832 } else {
2833 fe->getOpPtrVector().push_back(
2835 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
2836 }
2837
2838 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2839 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
2840 CHKERR VecSetDM(solTSStep, PETSC_NULLPTR);
2841 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2842 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
2843 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2844 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
2845
2846 // H1 displacements
2847 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
2848 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
2849 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldGradient<3, 3>(
2850 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
2851
2852 // velocities
2853 if (calc_rates) {
2854 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValuesDot<3>(
2855 spatialL2Disp, dataAtPts->getSmallWL2DotAtPts(), MBTET));
2856 if (noStretch) {
2857 } else {
2858 fe->getOpPtrVector().push_back(
2860 stretchTensor, dataAtPts->getLogStretchDotTensorAtPts(), MBTET));
2861 fe->getOpPtrVector().push_back(
2863 stretchTensor, dataAtPts->getGradLogStretchDotTensorAtPts(),
2864 MBTET));
2865 }
2866 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValuesDot<3>(
2867 rotAxis, dataAtPts->getRotAxisDotAtPts(), MBTET));
2868 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldGradientDot<3, 3>(
2869 rotAxis, dataAtPts->getRotAxisGradDotAtPts(), MBTET));
2870
2871 // acceleration
2872 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
2873 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValuesDotDot<3>(
2874 spatialL2Disp, dataAtPts->getSmallWL2DotDotAtPts(), MBTET));
2875 }
2876 }
2877
2878 // calculate other derived quantities
2879 fe->getOpPtrVector().push_back(new OpCalculateRotationAndSpatialGradient(
2880 dataAtPts, ((do_rhs || do_lhs) && calc_rates) ? alphaOmega : 0.));
2881
2882 // evaluate integration points
2883 if (noStretch) {
2884 } else {
2885 fe->getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
2886 tag, do_rhs, do_lhs, dataAtPts, physicalEquations));
2887 }
2888
2890}
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 4084 of file EshelbianPlasticity.cpp.

4084 {
4086
4087 auto set_block = [&](auto name, int dim) {
4088 std::map<int, Range> map;
4089 auto set_tag_impl = [&](auto name) {
4091 auto mesh_mng = mField.getInterface<MeshsetsManager>();
4092 auto bcs = mesh_mng->getCubitMeshsetPtr(
4093
4094 std::regex((boost::format("%s(.*)") % name).str())
4095
4096 );
4097 for (auto bc : bcs) {
4098 Range r;
4099 CHKERR bc->getMeshsetIdEntitiesByDimension(mField.get_moab(), dim, r,
4100 true);
4101 map[bc->getMeshsetId()] = r;
4102 MOFEM_LOG("EP", Sev::inform)
4103 << "Block " << name << " id " << bc->getMeshsetId() << " has "
4104 << r.size() << " entities";
4105 }
4107 };
4108
4109 CHKERR set_tag_impl(name);
4110
4111 return std::make_pair(name, map);
4112 };
4113
4114 auto set_skin = [&](auto &&map) {
4115 for (auto &m : map.second) {
4116 auto s = filter_true_skin(mField, get_skin(mField, m.second));
4117 m.second.swap(s);
4118 MOFEM_LOG("EP", Sev::inform)
4119 << "Skin for block " << map.first << " id " << m.first << " has "
4120 << m.second.size() << " entities";
4121 }
4122 return map;
4123 };
4124
4125 auto set_tag = [&](auto &&map) {
4126 Tag th;
4127 auto name = map.first;
4128 int def_val[] = {-1};
4130 mField.get_moab().tag_get_handle(name, 1, MB_TYPE_INTEGER, th,
4131 MB_TAG_SPARSE | MB_TAG_CREAT, def_val),
4132 "create tag");
4133 for (auto &m : map.second) {
4134 int id = m.first;
4135 CHK_MOAB_THROW(mField.get_moab().tag_clear_data(th, m.second, &id),
4136 "clear tag");
4137 }
4138 return th;
4139 };
4140
4141 listTagsToTransfer.push_back(set_tag(set_skin(set_block("BODY", 3))));
4142 listTagsToTransfer.push_back(set_tag(set_skin(set_block("MAT_ELASTIC", 3))));
4143 listTagsToTransfer.push_back(
4144 set_tag(set_skin(set_block("MAT_NEOHOOKEAN", 3))));
4145 listTagsToTransfer.push_back(set_tag(set_block("CONTACT", 2)));
4146
4148}
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 3637 of file EshelbianPlasticity.cpp.

3641 {
3643 fe_contact_tree = createContactDetectionFiniteElement(*this);
3645}
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 3647 of file EshelbianPlasticity.cpp.

3647 {
3649
3650 // Add contact operators. Note that only for rhs. THe lhs is assembled with
3651 // volume element, to enable schur complement evaluation.
3653
3656
3657 auto adj_cache =
3658 boost::make_shared<ForcesAndSourcesCore::UserDataOperator::AdjCache>();
3659
3660 auto get_op_contact_bc = [&]() {
3662 auto op_loop_side = new OpLoopSide<SideEle>(
3663 mField, contactElement, SPACE_DIM - 1, Sev::noisy, adj_cache);
3664 return op_loop_side;
3665 };
3666
3668}
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 3670 of file EshelbianPlasticity.cpp.

3670 {
3672 boost::shared_ptr<FEMethod> null;
3673
3674 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
3675
3677 null);
3679 null);
3681 null);
3683 null);
3684
3685 } else {
3687 null);
3689 null);
3691 null);
3693 null);
3694 }
3695
3697}
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 3470 of file EshelbianPlasticity.cpp.

3473 {
3475
3476 fe_rhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
3477 fe_lhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
3478
3479 // set integration rule
3480 // fe_rhs->getRuleHook = [](int, int, int p) { return 2 * (p + 1); };
3481 // fe_lhs->getRuleHook = [](int, int, int p) { return 2 * (p + 1); };
3482 fe_rhs->getRuleHook = [](int, int, int) { return -1; };
3483 fe_lhs->getRuleHook = [](int, int, int) { return -1; };
3484 fe_rhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3485 fe_lhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3486
3487 CHKERR
3488 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3489 fe_rhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
3490 CHKERR
3491 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3492 fe_lhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
3493
3494 if (add_elastic) {
3495
3496 auto get_broken_op_side = [this](auto &pip) {
3497 using EleOnSide =
3499 using SideEleOp = EleOnSide::UserDataOperator;
3500 // Iterate over domain FEs adjacent to boundary.
3501 auto broken_data_ptr =
3502 boost::make_shared<std::vector<BrokenBaseSideData>>();
3503 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
3504 auto op_loop_domain_side = new OpLoopSide<EleOnSide>(
3505 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
3506 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3507 boost::make_shared<CGGUserPolynomialBase>(nullptr, true);
3508 CHKERR
3509 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3510 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3512 op_loop_domain_side->getOpPtrVector().push_back(
3513 new OpGetBrokenBaseSideData<SideEleOp>(piolaStress, broken_data_ptr));
3514 boost::shared_ptr<double> piola_scale_ptr(new double);
3515 op_loop_domain_side->getOpPtrVector().push_back(
3516 physicalEquations->returnOpSetScale(piola_scale_ptr,
3518 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
3519 op_loop_domain_side->getOpPtrVector().push_back(
3521 flux_mat_ptr));
3522 op_loop_domain_side->getOpPtrVector().push_back(
3523 new OpSetFlux<SideEleOp>(broken_data_ptr, flux_mat_ptr));
3524 pip.push_back(op_loop_domain_side);
3525 return std::make_tuple(broken_data_ptr, piola_scale_ptr);
3526 };
3527
3528 auto set_rhs = [&]() {
3530
3531 auto [broken_data_ptr, piola_scale_ptr] =
3532 get_broken_op_side(fe_rhs->getOpPtrVector());
3533
3534 fe_rhs->getOpPtrVector().push_back(
3535 new OpDispBc(broken_data_ptr, bcSpatialDispVecPtr, timeScaleMap));
3536 fe_rhs->getOpPtrVector().push_back(new OpAnalyticalDispBc(
3538 timeScaleMap));
3539 fe_rhs->getOpPtrVector().push_back(new OpRotationBc(
3540 broken_data_ptr, bcSpatialRotationVecPtr, timeScaleMap));
3541
3542 fe_rhs->getOpPtrVector().push_back(
3544 piola_scale_ptr, timeScaleMap));
3545 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
3546 // if you push gradient of L2 base to physical element, it will not work.
3547 fe_rhs->getOpPtrVector().push_back(
3549 hybridSpatialDisp, hybrid_grad_ptr));
3550 fe_rhs->getOpPtrVector().push_back(new OpBrokenPressureBc(
3552 hybrid_grad_ptr, timeScaleMap));
3553 fe_rhs->getOpPtrVector().push_back(new OpBrokenAnalyticalTractionBc(
3555 timeScaleMap));
3556
3557 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3558 fe_rhs->getOpPtrVector().push_back(
3560 hybrid_ptr));
3561 fe_rhs->getOpPtrVector().push_back(new OpNormalDispRhsBc(
3562 hybridSpatialDisp, hybrid_ptr, broken_data_ptr,
3564
3565 auto get_normal_disp_bc_faces = [&]() {
3566 auto faces =
3567 get_range_from_block(mField, "NORMAL_DISPLACEMENT", SPACE_DIM - 1);
3568 return boost::make_shared<Range>(faces);
3569 };
3570
3571 using BoundaryEle =
3573 using BdyEleOp = BoundaryEle::UserDataOperator;
3575 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
3576 fe_rhs->getOpPtrVector().push_back(new OpC_dBroken(
3577 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0),
3578 get_normal_disp_bc_faces()));
3579
3581 };
3582
3583 auto set_lhs = [&]() {
3585
3586 auto [broken_data_ptr, piola_scale_ptr] =
3587 get_broken_op_side(fe_lhs->getOpPtrVector());
3588
3589 fe_lhs->getOpPtrVector().push_back(new OpNormalDispLhsBc_dU(
3591 fe_lhs->getOpPtrVector().push_back(new OpNormalDispLhsBc_dP(
3593 timeScaleMap));
3594
3595 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
3596 // if you push gradient of L2 base to physical element, it will not work.
3597 fe_lhs->getOpPtrVector().push_back(
3599 hybridSpatialDisp, hybrid_grad_ptr));
3600 fe_lhs->getOpPtrVector().push_back(new OpBrokenPressureBcLhs_dU(
3602 timeScaleMap));
3603
3604 auto get_normal_disp_bc_faces = [&]() {
3605 auto faces =
3606 get_range_from_block(mField, "NORMAL_DISPLACEMENT", SPACE_DIM - 1);
3607 return boost::make_shared<Range>(faces);
3608 };
3609
3610 using BoundaryEle =
3612 using BdyEleOp = BoundaryEle::UserDataOperator;
3614 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
3615 fe_lhs->getOpPtrVector().push_back(new OpC(
3616 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0),
3617 true, true, get_normal_disp_bc_faces()));
3618
3620 };
3621
3622 CHKERR set_rhs();
3623 CHKERR set_lhs();
3624 }
3625
3627}
@ 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 1657 of file EshelbianFracture.cpp.

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

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

2895 {
2897
2898 /** Contact requires that body is marked */
2899 auto get_body_range = [this](auto name, int dim) {
2900 std::map<int, Range> map;
2901
2902 for (auto m_ptr :
2903 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
2904
2905 (boost::format("%s(.*)") % name).str()
2906
2907 ))
2908
2909 ) {
2910 Range ents;
2911 CHK_MOAB_THROW(m_ptr->getMeshsetIdEntitiesByDimension(mField.get_moab(),
2912 dim, ents, true),
2913 "by dim");
2914 map[m_ptr->getMeshsetId()] = ents;
2915 }
2916
2917 return map;
2918 };
2919
2920 constexpr bool stab_tau_dot_variant = false;
2921
2922 auto local_tau_sacale = boost::make_shared<double>(1.0);
2923 using BoundaryEle =
2925 using BdyEleOp = BoundaryEle::UserDataOperator;
2926 struct OpSetTauScale : public BdyEleOp {
2927 OpSetTauScale(boost::shared_ptr<double> local_tau_sacale, double alphaTau)
2928 : BdyEleOp(NOSPACE, BdyEleOp::OPSPACE),
2929 localTauSacale(local_tau_sacale), alphaTau(alphaTau) {}
2930 MoFEMErrorCode doWork(int side, EntityType type,
2931 EntitiesFieldData::EntData &data) override {
2933 auto h = std::sqrt(getFTensor1Normal().l2());
2934 *localTauSacale = (alphaTau / h);
2936 }
2937
2938 private:
2939 boost::shared_ptr<double> localTauSacale;
2940 double alphaTau;
2941 };
2942
2943 auto not_interface_face = [this](FEMethod *fe_method_ptr) {
2944 auto ent = fe_method_ptr->getFEEntityHandle();
2945 if (
2946
2947 (interfaceFaces->find(ent) != interfaceFaces->end())
2948
2949 || (crackFaces->find(ent) != crackFaces->end())
2950
2951 ) {
2952 return false;
2953 };
2954 return true;
2955 };
2956
2957 // Right hand side
2958 fe_rhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
2959 CHKERR setBaseVolumeElementOps(tag, true, false, true, fe_rhs);
2960
2961 // elastic
2962 if (add_elastic) {
2963
2964 fe_rhs->getOpPtrVector().push_back(
2966 fe_rhs->getOpPtrVector().push_back(
2968 if (noStretch) {
2969 // do nothing - no stretch approximation
2970 } else {
2971 if (!internalStressTagName.empty()) {
2972 switch (internalStressInterpOrder) {
2973 case 0:
2974 fe_rhs->getOpPtrVector().push_back(
2976 break;
2977 case 1:
2978 fe_rhs->getOpPtrVector().push_back(
2980 break;
2981 default:
2982 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
2983 "Unsupported internal stress interpolation order %d",
2985 }
2986 // set default time scaling for interal stresses to constant
2987 TimeScale::ScalingFun def_scaling_fun = [](double time) { return 1; };
2988 auto ts_internal_stress =
2989 boost::make_shared<DynamicRelaxationTimeScale>(
2990 "internal_stress_history.txt", false, def_scaling_fun);
2991 if (internalStressVoigt) {
2992 fe_rhs->getOpPtrVector().push_back(
2994 stretchTensor, dataAtPts, ts_internal_stress));
2995 } else {
2996 fe_rhs->getOpPtrVector().push_back(
2998 stretchTensor, dataAtPts, ts_internal_stress));
2999 }
3000 }
3001 if (auto op = physicalEquations->returnOpSpatialPhysicalExternalStrain(
3003 fe_rhs->getOpPtrVector().push_back(op);
3004 } else if (externalStrainVecPtr && !externalStrainVecPtr->empty()) {
3005 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
3006 "OpSpatialPhysicalExternalStrain not implemented for this "
3007 "material");
3008 }
3009
3010 fe_rhs->getOpPtrVector().push_back(
3011 physicalEquations->returnOpSpatialPhysical(stretchTensor, dataAtPts,
3012 alphaU));
3013 }
3014 fe_rhs->getOpPtrVector().push_back(
3016 fe_rhs->getOpPtrVector().push_back(
3018 fe_rhs->getOpPtrVector().push_back(
3020
3021 auto set_hybridisation_rhs = [&](auto &pip) {
3023
3024 using BoundaryEle =
3026 using EleOnSide =
3028 using SideEleOp = EleOnSide::UserDataOperator;
3029 using BdyEleOp = BoundaryEle::UserDataOperator;
3030
3031 // First: Iterate over skeleton FEs adjacent to Domain FEs
3032 // Note: BoundaryEle, i.e. uses skeleton interation rule
3033 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
3034 mField, skeletonElement, SPACE_DIM - 1, Sev::noisy);
3035 // op_loop_skeleton_side->getSideFEPtr()->getRuleHook = FaceRule();
3036 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3037 return -1;
3038 };
3039 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3040 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3041
3042 CHKERR EshelbianPlasticity::
3043 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3044 op_loop_skeleton_side->getOpPtrVector(), {L2},
3046
3047 // Second: Iterate over domain FEs adjacent to skelton, particularly one
3048 // domain element.
3049 auto broken_data_ptr =
3050 boost::make_shared<std::vector<BrokenBaseSideData>>();
3051 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
3052 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
3053 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
3054 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3055 boost::make_shared<CGGUserPolynomialBase>(nullptr, true);
3056 CHKERR
3057 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3058 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3060 op_loop_domain_side->getOpPtrVector().push_back(
3061 new OpGetBrokenBaseSideData<SideEleOp>(piolaStress, broken_data_ptr));
3062 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
3063 op_loop_domain_side->getOpPtrVector().push_back(
3065 flux_mat_ptr));
3066 op_loop_domain_side->getOpPtrVector().push_back(
3067 new OpSetFlux<SideEleOp>(broken_data_ptr, flux_mat_ptr));
3068
3069 // Assemble on skeleton
3070 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3072 GAUSS>::OpBrokenSpaceConstrainDHybrid<SPACE_DIM>;
3074 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
3075 op_loop_skeleton_side->getOpPtrVector().push_back(new OpC_dHybrid(
3076 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0)));
3077 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3078 op_loop_skeleton_side->getOpPtrVector().push_back(
3080 hybrid_ptr));
3081 op_loop_skeleton_side->getOpPtrVector().push_back(new OpC_dBroken(
3082 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0)));
3083
3084 // Add skeleton to domain pipeline
3085 pip.push_back(op_loop_skeleton_side);
3086
3088 };
3089
3090 auto set_tau_stabilsation_rhs = [&](auto &pip, auto side_fe_name,
3091 auto hybrid_field) {
3093
3094 using BoundaryEle =
3096 using EleOnSide =
3098 using SideEleOp = EleOnSide::UserDataOperator;
3099 using BdyEleOp = BoundaryEle::UserDataOperator;
3100
3101 // First: Iterate over skeleton FEs adjacent to Domain FEs
3102 // Note: BoundaryEle, i.e. uses skeleton interation rule
3103 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
3104 mField, side_fe_name, SPACE_DIM - 1, Sev::noisy);
3105 // op_loop_skeleton_side->getSideFEPtr()->getRuleHook = FaceRule();
3106 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3107 return -1;
3108 };
3109 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3110 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3111 CHKERR EshelbianPlasticity::
3112 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3113 op_loop_skeleton_side->getOpPtrVector(), {L2},
3115
3116 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
3117 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
3118 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3119 boost::make_shared<CGGUserPolynomialBase>(nullptr, true);
3120 CHKERR
3121 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3122 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3124
3125 // Add stabilization operator
3126 auto broken_disp_data_ptr =
3127 boost::make_shared<std::vector<BrokenBaseSideData>>();
3128 op_loop_domain_side->getOpPtrVector().push_back(
3130 broken_disp_data_ptr));
3131 auto disp_mat_ptr = boost::make_shared<MatrixDouble>();
3132 if (stab_tau_dot_variant) {
3133 op_loop_domain_side->getOpPtrVector().push_back(
3135 disp_mat_ptr));
3136 } else {
3137 op_loop_domain_side->getOpPtrVector().push_back(
3139 disp_mat_ptr));
3140 }
3141 // Set diag fluxes on skeleton side
3142 op_loop_domain_side->getOpPtrVector().push_back(
3143 new OpSetFlux<SideEleOp>(broken_disp_data_ptr, disp_mat_ptr));
3144
3145 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3146 op_loop_skeleton_side->getOpPtrVector().push_back(
3147 new OpSetTauScale(local_tau_sacale, alphaTau));
3148
3149 // Add stabilization Ugamma Ugamma skeleton
3150 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3151 if (stab_tau_dot_variant) {
3152 op_loop_skeleton_side->getOpPtrVector().push_back(
3154 hybrid_ptr));
3155 } else {
3156 op_loop_skeleton_side->getOpPtrVector().push_back(
3158 hybrid_ptr));
3159 }
3160
3161 // Diag u_gamma - u_gamma faces
3162 op_loop_skeleton_side->getOpPtrVector().push_back(
3164 hybrid_field, hybrid_ptr,
3165 [local_tau_sacale, broken_disp_data_ptr](double, double, double) {
3166 return broken_disp_data_ptr->size() * (*local_tau_sacale);
3167 }));
3168 // Diag L2 - L2 volumes
3169 op_loop_skeleton_side->getOpPtrVector().push_back(
3171 broken_disp_data_ptr, [local_tau_sacale](double, double, double) {
3172 return (*local_tau_sacale);
3173 }));
3174 // Off-diag Ugamma - L2
3175 op_loop_skeleton_side->getOpPtrVector().push_back(
3177 hybrid_field, broken_disp_data_ptr,
3178 [local_tau_sacale](double, double, double) {
3179 return -(*local_tau_sacale);
3180 }));
3181 // Off-diag L2 - Ugamma
3182 op_loop_skeleton_side->getOpPtrVector().push_back(
3184 broken_disp_data_ptr, hybrid_ptr,
3185 [local_tau_sacale](double, double, double) {
3186 return -(*local_tau_sacale);
3187 }));
3188
3189 // Add skeleton to domain pipeline
3190 pip.push_back(op_loop_skeleton_side);
3191
3193 };
3194
3195 auto set_contact_rhs = [&](auto &pip) {
3196 return pushContactOpsRhs(*this, contactTreeRhs, pip);
3197 };
3198
3199 auto set_cohesive_rhs = [&](auto &pip) {
3200 return pushCohesiveOpsRhs(
3201 *this,
3202 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges,
3203 [](int p) { return 2 * (p + 1) + 1; }),
3204 interfaceFaces, pip);
3205 };
3206
3207 CHKERR set_hybridisation_rhs(fe_rhs->getOpPtrVector());
3208 CHKERR set_contact_rhs(fe_rhs->getOpPtrVector());
3209 if (alphaTau > 0.0) {
3210 CHKERR set_tau_stabilsation_rhs(fe_rhs->getOpPtrVector(), skeletonElement,
3212 CHKERR set_tau_stabilsation_rhs(fe_rhs->getOpPtrVector(), contactElement,
3213 contactDisp);
3214 }
3215 if (interfaceCrack == PETSC_TRUE) {
3216 CHKERR set_cohesive_rhs(fe_rhs->getOpPtrVector());
3217 }
3218
3219 // Body forces
3220 using BodyNaturalBC =
3222 Assembly<PETSC>::LinearForm<GAUSS>;
3223 using OpBodyForce =
3224 BodyNaturalBC::OpFlux<NaturalMeshsetType<BLOCKSET>, 1, 3>;
3225
3226 auto body_time_scale =
3227 boost::make_shared<DynamicRelaxationTimeScale>("body_force.txt");
3228 CHKERR BodyNaturalBC::AddFluxToPipeline<OpBodyForce>::add(
3229 fe_rhs->getOpPtrVector(), mField, spatialL2Disp, {body_time_scale},
3230 "BODY_FORCE", Sev::inform);
3231 }
3232
3233 // Left hand side
3234 fe_lhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
3235 CHKERR setBaseVolumeElementOps(tag, true, true, true, fe_lhs);
3236
3237 // elastic
3238 if (add_elastic) {
3239
3240 if (noStretch) {
3241 fe_lhs->getOpPtrVector().push_back(
3243 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dBubble_dP(
3245 fe_lhs->getOpPtrVector().push_back(
3247 dataAtPts));
3248 } else {
3249 fe_lhs->getOpPtrVector().push_back(
3250 physicalEquations->returnOpSpatialPhysical_du_du(
3252 fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_dP(
3254 fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_dBubble(
3256 fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_domega(
3258 symmetrySelector == SYMMETRIC ? true : false));
3259 }
3260
3261 fe_lhs->getOpPtrVector().push_back(new OpSpatialEquilibrium_dw_dP(
3263 fe_lhs->getOpPtrVector().push_back(new OpSpatialEquilibrium_dw_dw(
3265
3266 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dP_domega(
3268 symmetrySelector == SYMMETRIC ? true : false));
3269 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dBubble_domega(
3271 symmetrySelector == SYMMETRIC ? true : false));
3272
3273 if (symmetrySelector > SYMMETRIC) {
3274 if (!noStretch) {
3275 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_du(
3276 rotAxis, stretchTensor, dataAtPts, false));
3277 }
3278 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_dP(
3279 rotAxis, piolaStress, dataAtPts, false));
3280 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_dBubble(
3281 rotAxis, bubbleField, dataAtPts, false));
3282 }
3283 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_domega(
3285
3286 auto set_hybridisation_lhs = [&](auto &pip) {
3288
3289 using BoundaryEle =
3291 using EleOnSide =
3293 using SideEleOp = EleOnSide::UserDataOperator;
3294 using BdyEleOp = BoundaryEle::UserDataOperator;
3295
3296 // First: Iterate over skeleton FEs adjacent to Domain FEs
3297 // Note: BoundaryEle, i.e. uses skeleton interation rule
3298 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
3299 mField, skeletonElement, SPACE_DIM - 1, Sev::noisy);
3300 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3301 return -1;
3302 };
3303 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3304 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3305 CHKERR EshelbianPlasticity::
3306 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3307 op_loop_skeleton_side->getOpPtrVector(), {L2},
3309
3310 // Second: Iterate over domain FEs adjacent to skelton, particularly one
3311 // domain element.
3312 auto broken_data_ptr =
3313 boost::make_shared<std::vector<BrokenBaseSideData>>();
3314 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
3315 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
3316 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
3317 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3318 boost::make_shared<CGGUserPolynomialBase>(nullptr, true);
3319 CHKERR
3320 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3321 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3323 op_loop_domain_side->getOpPtrVector().push_back(
3324 new OpGetBrokenBaseSideData<SideEleOp>(piolaStress, broken_data_ptr));
3325
3326 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3328 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
3329 op_loop_skeleton_side->getOpPtrVector().push_back(
3330 new OpC(hybridSpatialDisp, broken_data_ptr,
3331 boost::make_shared<double>(1.0), true, false));
3332
3333 pip.push_back(op_loop_skeleton_side);
3334
3336 };
3337
3338 auto set_tau_stabilsation_lhs = [&](auto &pip, auto side_fe_name,
3339 auto hybrid_field) {
3341
3342 using BoundaryEle =
3344 using EleOnSide =
3346 using SideEleOp = EleOnSide::UserDataOperator;
3347 using BdyEleOp = BoundaryEle::UserDataOperator;
3348
3349 // First: Iterate over skeleton FEs adjacent to Domain FEs
3350 // Note: BoundaryEle, i.e. uses skeleton interation rule
3351 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
3352 mField, side_fe_name, SPACE_DIM - 1, Sev::noisy);
3353 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3354 return -1;
3355 };
3356 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3357 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3358 CHKERR EshelbianPlasticity::
3359 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3360 op_loop_skeleton_side->getOpPtrVector(), {L2},
3362
3363 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
3364 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
3365 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
3366 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3367 boost::make_shared<CGGUserPolynomialBase>(nullptr, true);
3368 CHKERR
3369 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3370 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3372
3373 auto broken_disp_data_ptr =
3374 boost::make_shared<std::vector<BrokenBaseSideData>>();
3375 op_loop_domain_side->getOpPtrVector().push_back(
3377 broken_disp_data_ptr));
3378 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3379 op_loop_skeleton_side->getOpPtrVector().push_back(
3380 new OpSetTauScale(local_tau_sacale, alphaTau));
3381
3382 auto time_shift = [](const FEMethod *fe_ptr) { return fe_ptr->ts_a; };
3383
3384 // Diag Ugamma-Ugamma skeleton
3385 op_loop_skeleton_side->getOpPtrVector().push_back(new OpMassVectorFace(
3386 hybrid_field, hybrid_field,
3387 [local_tau_sacale, broken_disp_data_ptr](double, double, double) {
3388 return broken_disp_data_ptr->size() * (*local_tau_sacale);
3389 }));
3390 if (stab_tau_dot_variant) {
3391 static_cast<OpMassVectorFace &>(
3392 op_loop_skeleton_side->getOpPtrVector().back())
3393 .feScalingFun = time_shift;
3394 }
3395 // Diag L2-L2 volumes
3396 op_loop_skeleton_side->getOpPtrVector().push_back(
3398 broken_disp_data_ptr, [local_tau_sacale](double, double, double) {
3399 return (*local_tau_sacale);
3400 }));
3401 if (stab_tau_dot_variant) {
3402 static_cast<OpBrokenBaseBrokenBase &>(
3403 op_loop_skeleton_side->getOpPtrVector().back())
3404 .feScalingFun = time_shift;
3405 }
3406 // Off-diag Ugamma - L2
3407 op_loop_skeleton_side->getOpPtrVector().push_back(
3409 hybrid_field, broken_disp_data_ptr,
3410 [local_tau_sacale](double, double, double) {
3411 return -(*local_tau_sacale);
3412 },
3413 false, false));
3414 if (stab_tau_dot_variant) {
3415 static_cast<OpHyrbridBaseBrokenBase &>(
3416 op_loop_skeleton_side->getOpPtrVector().back())
3417 .feScalingFun = time_shift;
3418 }
3419
3420 // Off-diag L2 - Ugamma
3421 op_loop_skeleton_side->getOpPtrVector().push_back(
3423 hybrid_field, broken_disp_data_ptr,
3424 [local_tau_sacale](double, double, double) {
3425 return -(*local_tau_sacale);
3426 },
3427 true, true));
3428 if (stab_tau_dot_variant) {
3429 static_cast<OpHyrbridBaseBrokenBase &>(
3430 op_loop_skeleton_side->getOpPtrVector().back())
3431 .feScalingFun = time_shift;
3432 }
3433
3434 pip.push_back(op_loop_skeleton_side);
3435
3437 };
3438
3439 auto set_contact_lhs = [&](auto &pip) {
3440 return pushContactOpsLhs(*this, contactTreeRhs, pip);
3441 };
3442
3443 auto set_cohesive_lhs = [&](auto &pip) {
3444 return pushCohesiveOpsLhs(
3445 *this,
3446 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges,
3447 [](int p) { return 2 * (p + 1) + 1; }),
3448 interfaceFaces, pip);
3449 };
3450
3451 CHKERR set_hybridisation_lhs(fe_lhs->getOpPtrVector());
3452 CHKERR set_contact_lhs(fe_lhs->getOpPtrVector());
3453 if (alphaTau > 0.0) {
3454 CHKERR set_tau_stabilsation_lhs(fe_lhs->getOpPtrVector(), skeletonElement,
3456 CHKERR set_tau_stabilsation_lhs(fe_lhs->getOpPtrVector(), contactElement,
3457 contactDisp);
3458 }
3459 if (interfaceCrack == PETSC_TRUE) {
3460 CHKERR set_cohesive_lhs(fe_lhs->getOpPtrVector());
3461 }
3462 }
3463
3464 if (add_material) {
3465 }
3466
3468}
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)
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 5126 of file EshelbianPlasticity.cpp.

5128 {
5130
5131 auto storage = solve_elastic_setup::setup(this, ts, x, false);
5132
5133 auto cohesive_tao_ctx = createCohesiveTAOCtx(
5134 this,
5135 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges,
5136 [](int p) { return 2 * (p + 1) + 1; }),
5137 SmartPetscObj<TS>(ts, true));
5138
5139 double final_time = 1;
5140 double delta_time = 0.1;
5141 int max_it = 10;
5142 PetscBool ts_h1_update = PETSC_FALSE;
5143
5144 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Dynamic Relaxation Options", "none");
5145
5146 CHKERR PetscOptionsScalar("-dynamic_final_time",
5147 "dynamic relaxation final time", "", final_time,
5148 &final_time, PETSC_NULLPTR);
5149 CHKERR PetscOptionsScalar("-dynamic_delta_time",
5150 "dynamic relaxation final time", "", delta_time,
5151 &delta_time, PETSC_NULLPTR);
5152 CHKERR PetscOptionsInt("-dynamic_max_it", "dynamic relaxation iterations", "",
5153 max_it, &max_it, PETSC_NULLPTR);
5154 CHKERR PetscOptionsBool("-dynamic_h1_update", "update each ts step", "",
5155 ts_h1_update, &ts_h1_update, PETSC_NULLPTR);
5156
5157 PetscOptionsEnd();
5158
5160 MOFEM_LOG("EP", Sev::inform)
5161 << "Dynamic relaxation final time -dynamic_final_time = " << final_time;
5162 MOFEM_LOG("EP", Sev::inform)
5163 << "Dynamic relaxation delta time -dynamic_delta_time = " << delta_time;
5164 MOFEM_LOG("EP", Sev::inform)
5165 << "Dynamic relaxation max iterations -dynamic_max_it = " << max_it;
5166 MOFEM_LOG("EP", Sev::inform)
5167 << "Dynamic relaxation H1 update each step -dynamic_h1_update = "
5168 << (ts_h1_update ? "TRUE" : "FALSE");
5169
5172
5173 auto setup_ts_monitor = [&]() {
5174 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*this);
5175 return monitor_ptr;
5176 };
5177 auto monitor_ptr = setup_ts_monitor();
5178
5179 TetPolynomialBase::switchCacheBaseOn<HDIV>(
5180 {elasticFeLhs.get(), elasticFeRhs.get()});
5181 CHKERR TSSetUp(ts);
5182 CHKERR TSElasticPostStep::postStepInitialise(this);
5183
5184 double ts_delta_time;
5185 CHKERR TSGetTimeStep(ts, &ts_delta_time);
5186
5187 if (ts_h1_update) {
5188 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
5189 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
5190 }
5191
5192 auto tao = createTao(mField.get_comm());
5193 CHKERR TaoSetType(tao, TAOLMVM);
5194 auto g = cohesive_tao_ctx->duplicateGradientVec();
5196 cohesiveEvaluateObjectiveAndGradient,
5197 (void *)cohesive_tao_ctx.get());
5198
5199 dynamicTime = start_time;
5200 dynamicStep = start_step;
5201 monitor_ptr->ts = PETSC_NULLPTR;
5202 monitor_ptr->ts_u = PETSC_NULLPTR;
5203 monitor_ptr->ts_t = dynamicTime;
5204 monitor_ptr->ts_step = dynamicStep;
5206
5207 auto tao_sol0 = cohesive_tao_ctx->duplicateKappaVec();
5208 int tao_sol_size, tao_sol_loc_size;
5209 CHKERR VecGetSize(tao_sol0, &tao_sol_size);
5210 CHKERR VecGetLocalSize(tao_sol0, &tao_sol_loc_size);
5211 MOFEM_LOG("EP", Sev::inform)
5212 << "Cohesive crack growth initial kappa vector size " << tao_sol_size
5213 << " local size " << tao_sol_loc_size << " number of interface faces "
5214 << interfaceFaces->size();
5215
5216 CHKERR TaoSetFromOptions(tao);
5217
5218 auto xl = vectorDuplicate(tao_sol0);
5219 auto xu = vectorDuplicate(tao_sol0);
5220 CHKERR VecSet(xl, 0.0);
5221 CHKERR VecSet(xu, PETSC_INFINITY);
5222 CHKERR TaoSetVariableBounds(tao, xl, xu);
5223
5224 for (; dynamicTime < final_time; dynamicTime += delta_time) {
5225 MOFEM_LOG("EP", Sev::inform) << "Load step " << dynamicStep << " Time "
5226 << dynamicTime << " delta time " << delta_time;
5227
5228 CHKERR VecZeroEntries(tao_sol0);
5229 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5230 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5231 CHKERR TaoSetSolution(tao, tao_sol0);
5232 CHKERR TaoSolve(tao);
5233 Vec tao_sol;
5234 CHKERR TaoGetSolution(tao, &tao_sol);
5235
5236 // add solution increment to kappa vec/tags
5237 auto &kappa_vec = cohesive_tao_ctx->getKappaVec();
5240 CHKERR VecAXPY(kappa_vec.second, 1.0, tao_sol);
5241 CHKERR VecGhostUpdateBegin(kappa_vec.second, INSERT_VALUES,
5242 SCATTER_FORWARD);
5243 CHKERR VecGhostUpdateEnd(kappa_vec.second, INSERT_VALUES, SCATTER_FORWARD);
5246
5247
5248 CHKERR DMoFEMMeshToLocalVector(dmElastic, x, INSERT_VALUES,
5249 SCATTER_FORWARD);
5250 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
5251 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
5252 monitor_ptr->ts = PETSC_NULLPTR;
5253 monitor_ptr->ts_u = x;
5254 monitor_ptr->ts_t = dynamicTime;
5255 monitor_ptr->ts_step = dynamicStep;
5257
5258 ++dynamicStep;
5259 if (dynamicStep > max_it)
5260 break;
5261 }
5262
5263 CHKERR TSElasticPostStep::postStepDestroy();
5264 TetPolynomialBase::switchCacheBaseOff<HDIV>(
5265 {elasticFeLhs.get(), elasticFeRhs.get()});
5266
5268}
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode, RowColData rc=RowColData::COL)
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 3976 of file EshelbianPlasticity.cpp.

3978 {
3980
3981 auto storage = solve_elastic_setup::setup(this, ts, x, false);
3982
3983 double final_time = 1;
3984 double delta_time = 0.1;
3985 int max_it = 10;
3986 PetscBool ts_h1_update = PETSC_FALSE;
3987
3988 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Dynamic Relaxation Options", "none");
3989
3990 CHKERR PetscOptionsScalar("-dynamic_final_time",
3991 "dynamic relaxation final time", "", final_time,
3992 &final_time, PETSC_NULLPTR);
3993 CHKERR PetscOptionsScalar("-dynamic_delta_time",
3994 "dynamic relaxation final time", "", delta_time,
3995 &delta_time, PETSC_NULLPTR);
3996 CHKERR PetscOptionsInt("-dynamic_max_it", "dynamic relaxation iterations", "",
3997 max_it, &max_it, PETSC_NULLPTR);
3998 CHKERR PetscOptionsBool("-dynamic_h1_update", "update each ts step", "",
3999 ts_h1_update, &ts_h1_update, PETSC_NULLPTR);
4000
4001 PetscOptionsEnd();
4002
4003 MOFEM_LOG("EP", Sev::inform)
4004 << "Dynamic relaxation final time -dynamic_final_time = " << final_time;
4005 MOFEM_LOG("EP", Sev::inform)
4006 << "Dynamic relaxation delta time -dynamic_delta_time = " << delta_time;
4007 MOFEM_LOG("EP", Sev::inform)
4008 << "Dynamic relaxation max iterations -dynamic_max_it = " << max_it;
4009 MOFEM_LOG("EP", Sev::inform)
4010 << "Dynamic relaxation H1 update each step -dynamic_h1_update = "
4011 << (ts_h1_update ? "TRUE" : "FALSE");
4012
4014
4015 auto setup_ts_monitor = [&]() {
4016 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*this);
4017 return monitor_ptr;
4018 };
4019 auto monitor_ptr = setup_ts_monitor();
4020
4021 TetPolynomialBase::switchCacheBaseOn<HDIV>(
4022 {elasticFeLhs.get(), elasticFeRhs.get()});
4023 CHKERR TSSetUp(ts);
4024 CHKERR TSElasticPostStep::postStepInitialise(this);
4025
4026 double ts_delta_time;
4027 CHKERR TSGetTimeStep(ts, &ts_delta_time);
4028
4029 if (ts_h1_update) {
4030 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
4031 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
4032 }
4033
4034 CHKERR TSElasticPostStep::preStepFun(ts);
4035 CHKERR TSElasticPostStep::postStepFun(ts);
4036
4037 dynamicTime = start_time;
4038 dynamicStep = start_step;
4039 monitor_ptr->ts = PETSC_NULLPTR;
4040 monitor_ptr->ts_u = PETSC_NULLPTR;
4041 monitor_ptr->ts_t = dynamicTime;
4042 monitor_ptr->ts_step = dynamicStep;
4044
4045 for (; dynamicTime < final_time; dynamicTime += delta_time) {
4046 MOFEM_LOG("EP", Sev::inform) << "Load step " << dynamicStep << " Time "
4047 << dynamicTime << " delta time " << delta_time;
4048
4049 CHKERR TSSetStepNumber(ts, 0);
4050 CHKERR TSSetTime(ts, 0);
4051 CHKERR TSSetTimeStep(ts, ts_delta_time);
4052 if (!ts_h1_update) {
4053 CHKERR TSElasticPostStep::preStepFun(ts);
4054 }
4055 CHKERR TSSetSolution(ts, x);
4056 CHKERR TSSolve(ts, PETSC_NULLPTR);
4057 if (!ts_h1_update) {
4058 CHKERR TSElasticPostStep::postStepFun(ts);
4059 }
4060
4061 CHKERR DMoFEMMeshToLocalVector(dmElastic, x, INSERT_VALUES,
4062 SCATTER_FORWARD);
4063 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
4064 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
4065
4066 monitor_ptr->ts = PETSC_NULLPTR;
4067 monitor_ptr->ts_u = x;
4068 monitor_ptr->ts_t = dynamicTime;
4069 monitor_ptr->ts_step = dynamicStep;
4071
4072 ++dynamicStep;
4073 if (dynamicStep > max_it)
4074 break;
4075 }
4076
4077 CHKERR TSElasticPostStep::postStepDestroy();
4078 TetPolynomialBase::switchCacheBaseOff<HDIV>(
4079 {elasticFeLhs.get(), elasticFeRhs.get()});
4080
4082}

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

3871 {
3873
3875
3876 auto storage = solve_elastic_setup::setup(this, ts, x, true);
3877
3878 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
3879 Vec xx;
3880 CHKERR VecDuplicate(x, &xx);
3881 CHKERR VecZeroEntries(xx);
3882 CHKERR TS2SetSolution(ts, x, xx);
3883 CHKERR VecDestroy(&xx);
3884 } else {
3885 CHKERR TSSetSolution(ts, x);
3886 }
3887
3888 TetPolynomialBase::switchCacheBaseOn<HDIV>(
3889 {elasticFeLhs.get(), elasticFeRhs.get()});
3890 CHKERR TSSetUp(ts);
3891 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
3892 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
3893 CHKERR TSElasticPostStep::postStepInitialise(this);
3894 CHKERR TSSolve(ts, PETSC_NULLPTR);
3895 CHKERR TSElasticPostStep::postStepDestroy();
3896 TetPolynomialBase::switchCacheBaseOff<HDIV>(
3897 {elasticFeLhs.get(), elasticFeRhs.get()});
3898
3899#ifndef NDEBUG
3900 // Make graph
3901 if (mField.get_comm_rank() == 0) {
3902 auto ts_ctx_ptr = getDMTsCtx(dmElastic);
3904 "solve_elastic_graph.dot");
3905 }
3906#endif
3907
3908 SNES snes;
3909 CHKERR TSGetSNES(ts, &snes);
3910 int lin_solver_iterations;
3911 CHKERR SNESGetLinearSolveIterations(snes, &lin_solver_iterations);
3912 MOFEM_LOG("EP", Sev::inform)
3913 << "Number of linear solver iterations " << lin_solver_iterations;
3914
3915 PetscBool test_cook_flg = PETSC_FALSE;
3916 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-test_cook", &test_cook_flg,
3917 PETSC_NULLPTR);
3918 if (test_cook_flg) {
3919 constexpr int expected_lin_solver_iterations = 11;
3920 if (lin_solver_iterations > expected_lin_solver_iterations)
3921 SETERRQ(
3922 PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
3923 "Expected number of iterations is different than expected %d > %d",
3924 lin_solver_iterations, expected_lin_solver_iterations);
3925 }
3926
3927 PetscBool test_sslv116_flag = PETSC_FALSE;
3928 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-test_sslv116",
3929 &test_sslv116_flag, PETSC_NULLPTR);
3930
3931 if (test_sslv116_flag) {
3932 double max_val = 0.0;
3933 double min_val = 0.0;
3934 auto field_min_max = [&](boost::shared_ptr<FieldEntity> ent_ptr) {
3936 auto ent_type = ent_ptr->getEntType();
3937 if (ent_type == MBVERTEX) {
3938 max_val = std::max(ent_ptr->getEntFieldData()[SPACE_DIM - 1], max_val);
3939 min_val = std::min(ent_ptr->getEntFieldData()[SPACE_DIM - 1], min_val);
3940 }
3942 };
3943 CHKERR mField.getInterface<FieldBlas>()->fieldLambdaOnEntities(
3944 field_min_max, spatialH1Disp);
3945
3946 double global_max_val = 0.0;
3947 double global_min_val = 0.0;
3948 MPI_Allreduce(&max_val, &global_max_val, 1, MPI_DOUBLE, MPI_MAX,
3949 mField.get_comm());
3950 MPI_Allreduce(&min_val, &global_min_val, 1, MPI_DOUBLE, MPI_MIN,
3951 mField.get_comm());
3952 MOFEM_LOG("EP", Sev::inform)
3953 << "Max " << spatialH1Disp << " value: " << global_max_val;
3954 MOFEM_LOG("EP", Sev::inform)
3955 << "Min " << spatialH1Disp << " value: " << global_min_val;
3956
3957 double ref_max_val = 0.00767;
3958 double ref_min_val = -0.00329;
3959 if (std::abs(global_max_val - ref_max_val) > 1e-5) {
3960 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
3961 "Incorrect max value of the displacement field: %f != %f",
3962 global_max_val, ref_max_val);
3963 }
3964 if (std::abs(global_min_val - ref_min_val) > 4e-5) {
3965 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
3966 "Incorrect min value of the displacement field: %f != %f",
3967 global_min_val, ref_min_val);
3968 }
3969 }
3970
3972
3974}
#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.

◆ solveSchapeOptimisation()

MoFEMErrorCode EshelbianCore::solveSchapeOptimisation ( 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 5270 of file EshelbianPlasticity.cpp.

5272 {
5274
5275 constexpr bool debug = true;
5276 (void)debug;
5277
5278 auto storage = solve_elastic_setup::setup(this, ts, x, false);
5279
5280 auto topological_tao_ctx = createTopologicalTAOCtx(
5281 this,
5282 SetIntegrationAtFrontVolume(frontVertices, frontAdjEdges,
5283 [](int p) { return 2 * (p + 1) + 1; }),
5284 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges,
5285 [](int p) { return 2 * (p + 1) + 1; }),
5286 SmartPetscObj<TS>(ts, true));
5287
5288 double final_time = 1;
5289 double delta_time = 0.1;
5290 int max_it = 10;
5291 PetscBool ts_h1_update = PETSC_FALSE;
5292
5293 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Dynamic Relaxation Options", "none");
5294
5295 CHKERR PetscOptionsScalar("-dynamic_final_time",
5296 "dynamic relaxation final time", "", final_time,
5297 &final_time, PETSC_NULLPTR);
5298 CHKERR PetscOptionsScalar("-dynamic_delta_time",
5299 "dynamic relaxation final time", "", delta_time,
5300 &delta_time, PETSC_NULLPTR);
5301 CHKERR PetscOptionsInt("-dynamic_max_it", "dynamic relaxation iterations", "",
5302 max_it, &max_it, PETSC_NULLPTR);
5303 CHKERR PetscOptionsBool("-dynamic_h1_update", "update each ts step", "",
5304 ts_h1_update, &ts_h1_update, PETSC_NULLPTR);
5305
5306 PetscOptionsEnd();
5307
5309 MOFEM_LOG("EP", Sev::inform)
5310 << "Dynamic relaxation final time -dynamic_final_time = " << final_time;
5311 MOFEM_LOG("EP", Sev::inform)
5312 << "Dynamic relaxation delta time -dynamic_delta_time = " << delta_time;
5313 MOFEM_LOG("EP", Sev::inform)
5314 << "Dynamic relaxation max iterations -dynamic_max_it = " << max_it;
5315 MOFEM_LOG("EP", Sev::inform)
5316 << "Dynamic relaxation H1 update each step -dynamic_h1_update = "
5317 << (ts_h1_update ? "TRUE" : "FALSE");
5318
5320
5321 auto setup_ts_monitor = [&]() {
5322 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*this);
5323 return monitor_ptr;
5324 };
5325 auto monitor_ptr = setup_ts_monitor();
5326
5327 TetPolynomialBase::switchCacheBaseOn<HDIV>(
5328 {elasticFeLhs.get(), elasticFeRhs.get()});
5329 CHKERR TSSetUp(ts);
5330 CHKERR TSElasticPostStep::postStepInitialise(this);
5331
5332 double ts_delta_time;
5333 CHKERR TSGetTimeStep(ts, &ts_delta_time);
5334
5335 if (ts_h1_update) {
5336 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
5337 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
5338 }
5339
5340 CHKERR TSElasticPostStep::preStepFun(ts);
5341 CHKERR TSElasticPostStep::postStepFun(ts);
5342
5343 auto tao = createTao(mField.get_comm());
5344 CHKERR TaoSetType(tao, TAOLMVM);
5347 topologicalEvaluateObjectiveAndGradient,
5348 (void *)topological_tao_ctx.get());
5349
5350 dynamicTime = start_time;
5351 dynamicStep = start_step;
5352 monitor_ptr->ts = PETSC_NULLPTR;
5353 monitor_ptr->ts_u = PETSC_NULLPTR;
5354 monitor_ptr->ts_t = dynamicTime;
5355 monitor_ptr->ts_step = dynamicStep;
5357
5358 auto tao_sol0 = createDMVector(dmMaterial, RowColData::ROW);
5359 CHKERR DMoFEMMeshToLocalVector(dmMaterial, tao_sol0, INSERT_VALUES,
5360 SCATTER_FORWARD, RowColData::ROW);
5361 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5362 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5363
5364 int tao_sol_size, tao_sol_loc_size;
5365 CHKERR VecGetSize(tao_sol0, &tao_sol_size);
5366 CHKERR VecGetLocalSize(tao_sol0, &tao_sol_loc_size);
5367 MOFEM_LOG("EP", Sev::inform)
5368 << "Cohesive crack growth initial kappa vector size " << tao_sol_size
5369 << " local size " << tao_sol_loc_size << " number of interface faces "
5370 << interfaceFaces->size();
5371
5372 CHKERR TaoSetFromOptions(tao);
5373
5374 for (; dynamicTime < final_time; dynamicTime += delta_time) {
5375 MOFEM_LOG("EP", Sev::inform) << "Load step " << dynamicStep << " Time "
5376 << dynamicTime << " delta time " << delta_time;
5377
5378 if (debug) {
5379 double obj_value;
5380 CHKERR testTopologicalDerivative(topological_tao_ctx.get(), tao_sol0,
5381 &obj_value, g);
5382 } else {
5383
5384 CHKERR VecZeroEntries(tao_sol0);
5385 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5386 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5387 CHKERR TaoSetSolution(tao, tao_sol0);
5388 CHKERR TaoSolve(tao);
5389 Vec tao_sol;
5390 CHKERR TaoGetSolution(tao, &tao_sol);
5391 }
5392
5393 // // add solution increment to kappa vec/tags
5394 // auto &kappa_vec = topological_tao_ctx->getKappaVec();
5395 // CHKERR CommInterface::setVectorFromTag(mField.get_moab(), kappa_vec,
5396 // get_kappa_tag(mField.get_moab()));
5397 // CHKERR VecAXPY(kappa_vec.second, 1.0, tao_sol);
5398 // CHKERR VecGhostUpdateBegin(kappa_vec.second, INSERT_VALUES,
5399 // SCATTER_FORWARD);
5400 // CHKERR VecGhostUpdateEnd(kappa_vec.second, INSERT_VALUES, SCATTER_FORWARD);
5401 // CHKERR CommInterface::setTagFromVector(mField.get_moab(), kappa_vec,
5402 // get_kappa_tag(mField.get_moab()));
5403
5404
5405 CHKERR DMoFEMMeshToLocalVector(dmElastic, x, INSERT_VALUES,
5406 SCATTER_FORWARD);
5407 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
5408 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
5409 monitor_ptr->ts = PETSC_NULLPTR;
5410 monitor_ptr->ts_u = x;
5411 monitor_ptr->ts_t = dynamicTime;
5412 monitor_ptr->ts_step = dynamicStep;
5414
5415 ++dynamicStep;
5416 if (dynamicStep > max_it)
5417 break;
5418 }
5419
5420 CHKERR TSElasticPostStep::postStepDestroy();
5421 TetPolynomialBase::switchCacheBaseOff<HDIV>(
5422 {elasticFeLhs.get(), elasticFeRhs.get()});
5423
5425}
boost::shared_ptr< TopologicalTAOCtx > createTopologicalTAOCtx(EshelbianCore *ep, ForcesAndSourcesCore::GaussHookFun set_integration_at_interior, ForcesAndSourcesCore::GaussHookFun set_integration_at_face, SmartPetscObj< TS > time_solver)
MoFEMErrorCode testTopologicalDerivative(TopologicalTAOCtx *ctx_ptr, Vec sol, PetscReal *f, Vec g)

Friends And Related Symbol Documentation

◆ solve_elastic_set_up

friend struct solve_elastic_set_up
friend

Definition at line 403 of file EshelbianCore.hpp.

Member Data Documentation

◆ a00FieldList

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

Definition at line 518 of file EshelbianCore.hpp.

◆ a00RangeList

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

Definition at line 520 of file EshelbianCore.hpp.

◆ addCrackMeshsetId

int EshelbianCore::addCrackMeshsetId = 1000
inlinestatic

Definition at line 53 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 516 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 502 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 499 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 517 of file EshelbianCore.hpp.

◆ crackingAddTime

double EshelbianCore::crackingAddTime = 0
inlinestatic

◆ 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

◆ dmMaterial

SmartPetscObj<DM> EshelbianCore::dmMaterial

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

◆ interfaceRemoveLevel

int EshelbianCore::interfaceRemoveLevel
inlinestatic

◆ 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

◆ listSolvers

const char* EshelbianCore::listSolvers[]
inlinestatic
Initial value:
= {
"time_solver", "dynamic_relaxation", "cohesive", "shape_optimization"}
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 22 of file EshelbianCore.hpp.

22 {
23 "time_solver", "dynamic_relaxation", "cohesive", "shape_optimization"};

◆ 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 492 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 522 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 515 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 78 of file EshelbianCore.hpp.

◆ v_max

constexpr double EshelbianCore::v_max = 24
inlinestaticconstexpr

Definition at line 79 of file EshelbianCore.hpp.

◆ v_min

constexpr double EshelbianCore::v_min = -v_max
inlinestaticconstexpr

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