v0.16.0
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  FieldOrders
 
struct  FieldOrders< AINSWORTH_LEGENDRE_BASE >
 
struct  FieldOrders< DEMKOWICZ_JACOBI_BASE >
 
struct  SetUpSchur
 

Public Types

enum  MaterialModel {
  StVenantKirchhoff , MooneyRivlin , Hencky , Neohookean ,
  Storakers , Meta , LastMaterial
}
 
enum  SolverType {
  TimeSolver , DynamicRelaxation , Cohesive , LoadFactor ,
  ShapeOptimization , TestTopologicalDerivative , LastSolver
}
 
enum  StretchHandling { FULL_ORDER_STREACH , NO_STREACH_LINEAR , NO_STREACH_NONLINEAR }
 

Public Member Functions

template<typename Op >
MoFEMErrorCode withFieldOrders (Op &&op) const
 
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 ()
 
std::string getStringArgumentFromJsonBlockset (const std::string &type_name, const int meshset_id, const std::string &param_name)
 
MoFEMErrorCode getStringArgumentFromJsonBlocksets (const std::string &type_name, const std::string &param_name, std::string &param_value)
 
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, const bool add_bubble=true)
 
MoFEMErrorCode projectGeometry (const EntityHandle meshset=0, double time=0)
 
MoFEMErrorCode projectMaterialTags (const EntityHandle meshset=0)
 
MoFEMErrorCode addVolumeFiniteElement (const EntityHandle meshset=0, const bool add_bubble=true)
 
MoFEMErrorCode addBoundaryFiniteElement (const EntityHandle meshset=0)
 
MoFEMErrorCode addDMs (const BitRefLevel bit=BitRefLevel().set(0), const EntityHandle meshset=0)
 
MoFEMErrorCode addMaterial_HMHNeohookean (const double c10, const double K)
 
MoFEMErrorCode addMaterial_HMHStorakers (const double eta, const double mu, const double beta)
 
MoFEMErrorCode addMaterial_Hencky (double E, double nu)
 
MoFEMErrorCode addMaterial_Core (boost::weak_ptr< MatOps::PhysicalEquations > mat_physical_equations_ptr)
 
MoFEMErrorCode setBaseVolumeElementOps (const int tag, const bool do_rhs, const bool do_lhs, const bool calc_rates, boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe, const bool add_bubble=true)
 
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 pushNoStretchVolumeA00Ops (boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe_lhs)
 
MoFEMErrorCode pushStretchVolumeA00Ops (boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe_lhs)
 
MoFEMErrorCode pushStressGramOps (boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe_lhs)
 
MoFEMErrorCode pushPiolaStressGramOps (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 solveLoadFactor (TS ts, Vec x, int start_step, double start_time)
 Solve load factor crack growth problem.
 
MoFEMErrorCode solveSchapeOptimisation (TS ts, Vec x, int start_step, double start_time)
 Solve shape optimisation problem.
 
MoFEMErrorCode solveTestTopologicalDerivative (TS ts, Vec x, int start_step, double start_time)
 
MoFEMErrorCode setBlockTagsOnSkin ()
 
MoFEMErrorCode postProcessRestartMesh (const int tag, const std::string file, std::vector< Tag > tags_to_transfer={})
 
MoFEMErrorCode postProcessResults (const int tag, const std::string file, Vec f_residual=PETSC_NULLPTR, Vec var_vec=PETSC_NULLPTR, Vec gradient=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={}, TS ts=PETSC_NULLPTR)
 
MoFEMErrorCode calculateCrackArea (boost::shared_ptr< double > &area_ptr)
 
MoFEMErrorCode gettingNorms ()
 [Getting norms]
 
MoFEMErrorCode calculateFaceMaterialForce (const int tag, TS ts, SmartPetscObj< Vec > *adjoint_gradient_vector=nullptr)
 
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 bool isNoStretch ()
 
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 inv_f_log_e_quadratic (const double stretch)
 
static double inv_d_f_log_e_quadratic (const double stretch)
 
static double inv_dd_f_log_e_quadratic (const double stretch)
 
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_linear (const double v)
 
static double d_f_linear (const double)
 
static double dd_f_linear (const double)
 
static double inv_f_linear (const double v)
 
static double inv_d_f_linear (const double)
 
static double inv_dd_f_linear (const double)
 
- 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 materialH1Order = 1
 
double alphaU = 0
 
double alphaW = 0
 
double alphaOmega = 0
 
double alphaOmega0 = 0
 
double alphaR = 0
 
double alphaR0 = 0
 
double alphaViscousOmega = 0
 
double alphaViscousOmega0 = 0
 
double alphaViscousR = 0
 
double alphaViscousR0 = 0
 
double alphaRho = 0
 
double alphaTau = 0
 
double alphaTau0 = 0
 
double alphaTauBcDisp = 0
 
double alphaTauBcDisp0 = 0
 
int contactRefinementLevels = 1
 
int frontLayers = 3
 
double loadFactor = 1.0
 
double avgGriffithsEnergy = -1
 
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< SpringBcVec > bcSpatialSpringVecPtr
 
boost::shared_ptr< AnalyticalDisplacementBcVec > bcSpatialAnalyticalDisplacementVecPtr
 
boost::shared_ptr< AnalyticalTractionBcVec > bcSpatialAnalyticalTractionVecPtr
 
boost::shared_ptr< PressureBcVec > bcSpatialPressureVecPtr
 
boost::shared_ptr< ExternalStrainVec > externalStrainVecPtr
 
double oldCrackArea = 0.
 
double oldStrainEnergy = 0.
 
double oldLoadFactor = 1.0
 
double strainEnergy = 0.
 
boost::shared_ptr< doublecurrentCrackAreaPtr
 
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
 
PetscBool loadFactorTSSolveExecuted = PETSC_FALSE
 
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 constexpr enum SymmetrySelector symmetrySelector = SYMMETRIC
 
static enum SolverType solverType = TimeSolver
 
static enum MaterialModel materialModel = MooneyRivlin
 
static enum RotSelector rotSelector = LARGE_ROT
 
static enum RotSelector gradApproximator = LARGE_ROT
 
static enum StretchSelector stretchSelector = LOG
 
static enum StretchHandling stretchHandling
 
static PetscBool setSingularity = PETSC_FALSE
 
static PetscBool physicalTimeFlg
 
static PetscBool crackingOn = PETSC_FALSE
 
static double crackingStartTime = -1
 
static double crackingAddTime = -1
 
static int nbJIntegralContours
 
static double finalPhysicalTime = 0
 
static double currentPhysicalTime
 
static double physicalDt = 0
 
static int physicalMaxSteps = 20
 
static int physicalStepNumber = 0
 
static PetscBool physicalH1Update
 
static PetscBool l2UserBaseScale = PETSC_FALSE
 
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 PetscBool internalStressVoigt
 
static PetscBool interfaceCrack
 
static int interfaceRemoveLevel
 
static std::string heterogeneousYoungModTagName
 
static bool hasNonHomogeneousMaterialBlock = false
 
static std::string meshTransferSourceMeshFileName
 
static int meshTransferInterpOrder
 
static PetscBool meshTransferSourceMeshFileSpecified
 
static PetscBool meshTransferHybridInterp
 
static std::vector< std::string > listTagsToProject
 
static FieldApproximationBase brokenHdivBase
 
static double maxCrackExtension
 
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 double v_max = 24
 

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 
Storakers 
Meta 
LastMaterial 

Definition at line 14 of file EshelbianCore.hpp.

◆ SolverType

Enumerator
TimeSolver 
DynamicRelaxation 
Cohesive 
LoadFactor 
ShapeOptimization 
TestTopologicalDerivative 
LastSolver 
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 31 of file EshelbianCore.hpp.

◆ StretchHandling

Enumerator
FULL_ORDER_STREACH 
NO_STREACH_LINEAR 
NO_STREACH_NONLINEAR 

Definition at line 41 of file EshelbianCore.hpp.

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

941 : mField(m_field) {
942 CHK_THROW_MESSAGE(getOptions(), "getOptions failed");
943}
#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 2443 of file EshelbianPlasticity.cpp.

2443 {
2445
2446 Range meshset_ents;
2447 CHKERR mField.get_moab().get_entities_by_handle(meshset, meshset_ents);
2448
2449 auto set_fe_adjacency = [&](auto fe_name) {
2452 boost::make_shared<ParentFiniteElementAdjacencyFunctionSkeleton<2>>(
2455 fe_name, MBTRI, *parentAdjSkeletonFunctionDim2);
2457 };
2458
2459 // set finite element fields
2460 auto add_field_to_fe = [this](const std::string fe,
2461 const std::string field_name) {
2470 };
2471
2473
2474 Range natural_bc_elements;
2475 if (bcSpatialDispVecPtr) {
2476 for (auto &v : *bcSpatialDispVecPtr) {
2477 natural_bc_elements.merge(v.faces);
2478 }
2479 }
2481 for (auto &v : *bcSpatialRotationVecPtr) {
2482 natural_bc_elements.merge(v.faces);
2483 }
2484 }
2486 for (auto &v : *bcSpatialNormalDisplacementVecPtr) {
2487 natural_bc_elements.merge(v.faces);
2488 }
2489 }
2491 for (auto &v : *bcSpatialSpringVecPtr) {
2492 natural_bc_elements.merge(v.faces);
2493 }
2494 }
2497 natural_bc_elements.merge(v.faces);
2498 }
2499 }
2501 for (auto &v : *bcSpatialTractionVecPtr) {
2502 natural_bc_elements.merge(v.faces);
2503 }
2504 }
2506 for (auto &v : *bcSpatialAnalyticalTractionVecPtr) {
2507 natural_bc_elements.merge(v.faces);
2508 }
2509 }
2511 for (auto &v : *bcSpatialPressureVecPtr) {
2512 natural_bc_elements.merge(v.faces);
2513 }
2514 }
2515 natural_bc_elements = intersect(natural_bc_elements, meshset_ents);
2516
2518 CHKERR mField.add_ents_to_finite_element_by_type(natural_bc_elements, MBTRI,
2520 CHKERR add_field_to_fe(naturalBcElement, piolaStress);
2521 CHKERR add_field_to_fe(naturalBcElement, hybridSpatialDisp);
2522 CHKERR set_fe_adjacency(naturalBcElement);
2524 }
2525
2526 auto get_skin = [&](auto &body_ents) {
2527 Skinner skin(&mField.get_moab());
2528 Range skin_ents;
2529 CHKERR skin.find_skin(0, body_ents, false, skin_ents);
2530 return skin_ents;
2531 };
2532
2533 auto filter_true_skin = [&](auto &&skin) {
2534 Range boundary_ents;
2535 ParallelComm *pcomm =
2536 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
2537 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
2538 PSTATUS_NOT, -1, &boundary_ents);
2539 return boundary_ents;
2540 };
2541
2543
2544 Range body_ents;
2545 CHKERR mField.get_moab().get_entities_by_dimension(meshset, SPACE_DIM,
2546 body_ents);
2547 auto skin = filter_true_skin(get_skin(body_ents));
2548
2556 contactDisp);
2559
2561 }
2562
2564 if (contactFaces) {
2565 MOFEM_LOG("EP", Sev::inform)
2566 << "Contact elements " << contactFaces->size();
2570 CHKERR add_field_to_fe(contactElement, piolaStress);
2571 CHKERR add_field_to_fe(contactElement, contactDisp);
2572 CHKERR add_field_to_fe(contactElement, spatialL2Disp);
2573 CHKERR add_field_to_fe(contactElement, spatialH1Disp);
2574 CHKERR set_fe_adjacency(contactElement);
2576 }
2577 }
2578
2580 if (!skeletonFaces)
2581 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "No skeleton faces");
2582 MOFEM_LOG("EP", Sev::inform)
2583 << "Skeleton elements " << skeletonFaces->size();
2587 CHKERR add_field_to_fe(skeletonElement, piolaStress);
2588 CHKERR add_field_to_fe(skeletonElement, hybridSpatialDisp);
2589 CHKERR add_field_to_fe(skeletonElement, spatialL2Disp);
2590 CHKERR add_field_to_fe(skeletonElement, spatialH1Disp);
2591 CHKERR set_fe_adjacency(skeletonElement);
2593 }
2594
2596}
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< SpringBcVec > bcSpatialSpringVecPtr
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 2100 of file EshelbianFracture.cpp.

2100 {
2102
2103 constexpr bool potential_crack_debug = false;
2104 if constexpr (potential_crack_debug) {
2105
2106 auto add_ents = get_range_from_block(mField, "POTENTIAL", SPACE_DIM - 1);
2107 Range crack_front_verts;
2108 CHKERR mField.get_moab().get_connectivity(*frontEdges, crack_front_verts,
2109 true);
2110 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
2111 crack_front_verts);
2112 Range crack_front_faces;
2113 CHKERR mField.get_moab().get_adjacencies(crack_front_verts, SPACE_DIM - 1,
2114 true, crack_front_faces,
2115 moab::Interface::UNION);
2116 crack_front_faces = intersect(crack_front_faces, add_ents);
2117 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
2118 crack_front_faces);
2119 CHKERR mField.getInterface<MeshsetsManager>()->addEntitiesToMeshset(
2120 BLOCKSET, addCrackMeshsetId, crack_front_faces);
2121 }
2122
2123 auto get_crack_faces = [&]() {
2124 if (maxMovedFaces) {
2125 return unite(*crackFaces, *maxMovedFaces);
2126 } else {
2127 return *crackFaces;
2128 }
2129 };
2130
2131 auto get_extended_crack_faces = [&]() {
2132 auto get_faces_of_crack_front_verts = [&](auto crack_faces_org) {
2133 ParallelComm *pcomm =
2134 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
2135
2136 Range crack_faces;
2137
2138 if (!pcomm->rank()) {
2139
2140 auto get_nodes = [&](auto &&e) {
2141 Range nodes;
2142 CHK_MOAB_THROW(mField.get_moab().get_connectivity(e, nodes, true),
2143 "get connectivity");
2144 return nodes;
2145 };
2146
2147 auto get_adj = [&](auto &&e, auto dim,
2148 auto t = moab::Interface::UNION) {
2149 Range adj;
2151 mField.get_moab().get_adjacencies(e, dim, true, adj, t),
2152 "get adj");
2153 return adj;
2154 };
2155
2156 Range body_ents;
2157 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
2158 body_ents);
2159 auto body_skin = get_skin(mField, body_ents);
2160 auto body_skin_edges = get_adj(body_skin, 1, moab::Interface::UNION);
2161 auto geometry_edges = get_range_from_block(mField, "EDGES", 1);
2162 auto front_block_edges = get_range_from_block(mField, "FRONT", 1);
2163 auto front_block_nodes = get_nodes(front_block_edges);
2164
2165 size_t s;
2166 do {
2167 s = crack_faces.size();
2168
2169 auto crack_face_nodes = get_nodes(crack_faces_org);
2170 auto crack_faces_edges =
2171 get_adj(crack_faces_org, 1, moab::Interface::UNION);
2172
2173 auto crack_skin = get_skin(mField, crack_faces_org);
2174 front_block_edges = subtract(front_block_edges, crack_skin);
2175 auto crack_skin_nodes = get_nodes(crack_skin);
2176 crack_skin_nodes.merge(front_block_nodes);
2177
2178 auto crack_skin_faces =
2179 get_adj(crack_skin, 2, moab::Interface::UNION);
2180 crack_skin_faces =
2181 subtract(subtract(crack_skin_faces, crack_faces_org), body_skin);
2182
2183 crack_faces = crack_faces_org;
2184 for (auto f : crack_skin_faces) {
2185 auto edges = intersect(
2186 get_adj(Range(f, f), 1, moab::Interface::UNION), crack_skin);
2187
2188 // if other edge is part of body skin, e.g. crack punching through
2189 // body surface
2190 if (edges.size() == 2) {
2191 edges.merge(
2192 intersect(get_adj(Range(f, f), 1, moab::Interface::UNION),
2193 body_skin_edges));
2194 }
2195
2196 if (edges.size() == 2) {
2197 auto edge_conn = get_nodes(Range(edges));
2198 auto faces = intersect(get_adj(edges, 2, moab::Interface::UNION),
2199 crack_faces_org);
2200 if (faces.size() == 2) {
2201 auto edge0_conn = get_nodes(Range(edges[0], edges[0]));
2202 auto edge1_conn = get_nodes(Range(edges[1], edges[1]));
2203 auto edges_conn = intersect(intersect(edge0_conn, edge1_conn),
2204 crack_skin_nodes); // node at apex
2205 if (edges_conn.size() == 1) {
2206
2207 auto node_edges =
2208 subtract(intersect(get_adj(edges_conn, 1,
2209 moab::Interface::INTERSECT),
2210 crack_faces_edges),
2211 crack_skin); // nodes on crack surface, but not
2212 // at the skin
2213
2214 if (node_edges.size()) {
2217 CHKERR mField.get_moab().get_coords(edges_conn, &t_v0(0));
2218
2219 auto get_t_dir = [&](auto e_conn) {
2220 auto other_node = subtract(e_conn, edges_conn);
2222 CHKERR mField.get_moab().get_coords(other_node,
2223 &t_dir(0));
2224 t_dir(i) -= t_v0(i);
2225 return t_dir;
2226 };
2227
2229 t_ave_dir(i) =
2230 get_t_dir(edge0_conn)(i) + get_t_dir(edge1_conn)(i);
2231
2232 FTensor::Tensor1<double, SPACE_DIM> t_crack_surface_ave_dir;
2233 t_crack_surface_ave_dir(i) = 0;
2234 for (auto e : node_edges) {
2235 auto e_conn = get_nodes(Range(e, e));
2236 auto t_dir = get_t_dir(e_conn);
2237 t_crack_surface_ave_dir(i) += t_dir(i);
2238 }
2239
2240 auto dot = t_ave_dir(i) * t_crack_surface_ave_dir(i);
2241 // ave edges is in opposite direction to crack surface, so
2242 // thus crack is not turning back
2243 if (dot < -std::numeric_limits<double>::epsilon()) {
2244 crack_faces.insert(f);
2245 }
2246 } else {
2247 crack_faces.insert(f);
2248 }
2249 }
2250 }
2251 } else if (edges.size() == 3) {
2252 crack_faces.insert(f);
2253 }
2254
2255 // if other edge is part of geometry edge, e.g. keyway
2256 if (edges.size() == 1) {
2257 edges.merge(
2258 intersect(get_adj(Range(f, f), 1, moab::Interface::UNION),
2259 geometry_edges));
2260 edges.merge(
2261 intersect(get_adj(Range(f, f), 1, moab::Interface::UNION),
2262 front_block_edges));
2263 if (edges.size() == 2) {
2264 crack_faces.insert(f);
2265 continue;
2266 }
2267 }
2268 }
2269
2270 crack_faces_org = crack_faces;
2271
2272 } while (s != crack_faces.size());
2273 };
2274
2275 return crack_faces; // send_type(mField, crack_faces, MBTRI);
2276 };
2277
2278 return get_faces_of_crack_front_verts(get_crack_faces());
2279 };
2280
2281 if (debug) {
2282 CHKERR save_range(mField.get_moab(), "new_crack_surface_debug.vtk",
2283 get_extended_crack_faces());
2284 }
2285
2286 auto reconstruct_crack_faces = [&](auto crack_faces) {
2287 ParallelComm *pcomm =
2288 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
2289
2290 auto impl = [&]() {
2292
2293 Range new_crack_faces;
2294 if (!pcomm->rank()) {
2295
2296 auto get_nodes = [&](auto &&e) {
2297 Range nodes;
2298 CHK_MOAB_THROW(mField.get_moab().get_connectivity(e, nodes, true),
2299 "get connectivity");
2300 return nodes;
2301 };
2302
2303 auto get_adj = [&](auto &&e, auto dim,
2304 auto t = moab::Interface::UNION) {
2305 Range adj;
2307 mField.get_moab().get_adjacencies(e, dim, true, adj, t),
2308 "get adj");
2309 return adj;
2310 };
2311
2312 auto get_test_on_crack_surface = [&]() {
2313 auto crack_faces_nodes =
2314 get_nodes(crack_faces); // nodes on crac faces
2315 auto crack_faces_tets =
2316 get_adj(crack_faces_nodes, 3,
2317 moab::Interface::UNION); // adjacent
2318 // tets to
2319 // crack
2320 // faces throug nodes
2321 auto crack_faces_tets_nodes =
2322 get_nodes(crack_faces_tets); // nodes on crack faces tets
2323 crack_faces_tets_nodes =
2324 subtract(crack_faces_tets_nodes, crack_faces_nodes);
2325 crack_faces_tets =
2326 subtract(crack_faces_tets, get_adj(crack_faces_tets_nodes, 3,
2327 moab::Interface::UNION));
2328 new_crack_faces =
2329 get_adj(crack_faces_tets, 2,
2330 moab::Interface::UNION); // adjacency faces to crack
2331 // faces through tets
2332 new_crack_faces.merge(crack_faces); // add original crack faces
2333
2334 return std::make_tuple(new_crack_faces, crack_faces_tets);
2335 };
2336
2337 auto carck_faces_test_edges = [&](auto faces, auto tets) {
2338 auto adj_tets_faces = get_adj(tets, 2, moab::Interface::UNION);
2339 auto adj_faces_edges = get_adj(subtract(faces, adj_tets_faces), 1,
2340 moab::Interface::UNION);
2341 auto adj_tets_edges = get_adj(tets, 1, moab::Interface::UNION);
2342 auto geometry_edges = get_range_from_block(mField, "EDGES", 1);
2343 auto front_block_edges = get_range_from_block(mField, "FRONT", 1);
2344 adj_faces_edges.merge(geometry_edges); // geometry edges
2345 adj_faces_edges.merge(front_block_edges); // front block edges
2346
2347 auto boundary_tets_edges = intersect(adj_tets_edges, adj_faces_edges);
2348 auto boundary_test_nodes = get_nodes(boundary_tets_edges);
2349 auto boundary_test_nodes_edges =
2350 get_adj(boundary_test_nodes, 1, moab::Interface::UNION);
2351 auto boundary_test_nodes_edges_nodes = subtract(
2352 get_nodes(boundary_test_nodes_edges), boundary_test_nodes);
2353
2354 boundary_tets_edges =
2355 subtract(boundary_test_nodes_edges,
2356 get_adj(boundary_test_nodes_edges_nodes, 1,
2357 moab::Interface::UNION));
2358
2359 Range body_ents;
2360 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
2361 body_ents);
2362 auto body_skin = get_skin(mField, body_ents);
2363
2364 auto body_skin_edges = get_adj(body_skin, 1, moab::Interface::UNION);
2365 body_skin_edges = intersect(get_adj(tets, 1, moab::Interface::UNION),
2366 body_skin_edges);
2367 body_skin = intersect(body_skin, adj_tets_faces);
2368 body_skin_edges = subtract(
2369 body_skin_edges, get_adj(body_skin, 1, moab::Interface::UNION));
2370
2371 save_range(mField.get_moab(), "body_skin_edges.vtk", body_skin_edges);
2372 for (auto e : body_skin_edges) {
2373 auto adj_tet = intersect(
2374 get_adj(Range(e, e), 3, moab::Interface::INTERSECT), tets);
2375 if (adj_tet.size() == 1) {
2376 boundary_tets_edges.insert(e);
2377 }
2378 }
2379
2380 return boundary_tets_edges;
2381 };
2382
2383 auto p = get_test_on_crack_surface();
2384 auto &[new_crack_faces, crack_faces_tets] = p;
2385
2386 if (debug) {
2387 CHKERR save_range(mField.get_moab(), "hole_crack_faces_debug.vtk",
2388 crack_faces);
2389 CHKERR save_range(mField.get_moab(), "new_crack_faces_debug.vtk",
2390 new_crack_faces);
2391 CHKERR save_range(mField.get_moab(), "new_crack_tets_debug.vtk",
2392 crack_faces_tets);
2393 }
2394
2395 auto boundary_tets_edges =
2396 carck_faces_test_edges(new_crack_faces, crack_faces_tets);
2397 CHKERR save_range(mField.get_moab(), "boundary_tets_edges.vtk",
2398 boundary_tets_edges);
2399
2400 auto resolve_surface = [&](auto boundary_tets_edges,
2401 auto crack_faces_tets) {
2402 auto boundary_tets_edges_nodes = get_nodes(boundary_tets_edges);
2403 auto crack_faces_tets_faces =
2404 get_adj(crack_faces_tets, 2, moab::Interface::UNION);
2405
2406 Range all_removed_faces;
2407 Range all_removed_tets;
2408 int counter = 0;
2409
2410 int size = 0;
2411 while (size != crack_faces_tets.size()) {
2412 auto tets_faces =
2413 get_adj(crack_faces_tets, 2, moab::Interface::UNION);
2414 auto skin_tets = get_skin(mField, crack_faces_tets);
2415 auto skin_skin =
2416 get_skin(mField, subtract(crack_faces_tets_faces, tets_faces));
2417 auto skin_skin_nodes = get_nodes(skin_skin);
2418
2419 size = crack_faces_tets.size();
2420 MOFEM_LOG("SELF", Sev::inform)
2421 << "Crack faces tets size " << crack_faces_tets.size()
2422 << " crack faces size " << crack_faces_tets_faces.size();
2423 auto skin_tets_nodes = subtract(
2424 get_nodes(skin_tets),
2425 boundary_tets_edges_nodes); // not remove tets which are
2426 // adjagasent to crack faces nodes
2427 skin_tets_nodes = subtract(skin_tets_nodes, skin_skin_nodes);
2428
2429 Range removed_nodes;
2430 Range tets_to_remove;
2431 Range faces_to_remove;
2432 for (auto n : skin_tets_nodes) {
2433 auto tets =
2434 intersect(get_adj(Range(n, n), 3, moab::Interface::INTERSECT),
2435 crack_faces_tets);
2436 if (tets.size() == 0) {
2437 continue;
2438 }
2439
2440 auto hole_detetction = [&]() {
2441 auto adj_tets =
2442 get_adj(Range(n, n), 3, moab::Interface::INTERSECT);
2443 adj_tets =
2444 subtract(adj_tets,
2445 crack_faces_tets); // tetst adjacent to the node
2446 // but not part of crack surface
2447 if (adj_tets.size() == 0) {
2448 return std::make_pair(
2449 intersect(
2450 get_adj(Range(n, n), 2, moab::Interface::INTERSECT),
2451 tets_faces),
2452 tets);
2453 }
2454
2455 std::vector<Range> tets_groups;
2456 auto test_adj_tets = adj_tets;
2457 while (test_adj_tets.size()) {
2458 auto seed_size = 0;
2459 Range seed = Range(test_adj_tets[0], test_adj_tets[0]);
2460 while (seed.size() != seed_size) {
2461 auto adj_faces =
2462 subtract(get_adj(seed, 2, moab::Interface::UNION),
2463 tets_faces); // edges which are not
2464 // part of the node
2465 seed_size = seed.size();
2466 seed.merge(
2467 intersect(get_adj(adj_faces, 3, moab::Interface::UNION),
2468 test_adj_tets));
2469 }
2470 tets_groups.push_back(seed);
2471 test_adj_tets = subtract(test_adj_tets, seed);
2472 }
2473 if (tets_groups.size() == 1) {
2474
2475 return std::make_pair(
2476 intersect(
2477 get_adj(Range(n, n), 2, moab::Interface::INTERSECT),
2478 tets_faces),
2479 tets);
2480 }
2481
2482 Range tets_to_remove;
2483 Range faces_to_remove;
2484 for (auto &r : tets_groups) {
2485 auto f = get_adj(r, 2, moab::Interface::UNION);
2486 auto t = intersect(get_adj(f, 3, moab::Interface::UNION),
2487 crack_faces_tets); // tets
2488
2489 if (f.size() > faces_to_remove.size() ||
2490 faces_to_remove.size() == 0) {
2491 faces_to_remove = f;
2492 tets_to_remove = t; // largest group of tets
2493 }
2494 }
2495 MOFEM_LOG("EPSELF", Sev::inform)
2496 << "Hole detection: faces to remove "
2497 << faces_to_remove.size() << " tets to remove "
2498 << tets_to_remove.size();
2499 return std::make_pair(faces_to_remove, tets_to_remove);
2500 };
2501
2502 if (tets.size() < tets_to_remove.size() ||
2503 tets_to_remove.size() == 0) {
2504 removed_nodes = Range(n, n);
2505 auto [h_faces_to_remove, h_tets_to_remove] =
2506 hole_detetction(); // find faces and tets to remove
2507 faces_to_remove = h_faces_to_remove;
2508 tets_to_remove = h_tets_to_remove;
2509
2510 // intersect(
2511 // get_adj(Range(n, n), 2, moab::Interface::INTERSECT),
2512 // tets_faces);
2513
2514 } // find tets which is largest adjacencty size, so that it is
2515 // removed first, and then faces are removed
2516 all_removed_faces.merge(faces_to_remove);
2517 all_removed_tets.merge(tets_to_remove);
2518 }
2519
2520 crack_faces_tets = subtract(crack_faces_tets, tets_to_remove);
2521 crack_faces_tets_faces =
2522 subtract(crack_faces_tets_faces, faces_to_remove);
2523
2524 if (debug) {
2526 "removed_nodes_" +
2527 boost::lexical_cast<std::string>(counter) + ".vtk",
2528 removed_nodes);
2530 "faces_to_remove_" +
2531 boost::lexical_cast<std::string>(counter) + ".vtk",
2532 faces_to_remove);
2534 "tets_to_remove_" +
2535 boost::lexical_cast<std::string>(counter) + ".vtk",
2536 tets_to_remove);
2538 "crack_faces_tets_faces_" +
2539 boost::lexical_cast<std::string>(counter) + ".vtk",
2540 crack_faces_tets_faces);
2542 "crack_faces_tets_" +
2543 boost::lexical_cast<std::string>(counter) + ".vtk",
2544 crack_faces_tets);
2545 }
2546 counter++;
2547 }
2548
2549 auto cese_internal_faces = [&]() {
2551 auto skin_tets = get_skin(mField, crack_faces_tets);
2552 auto adj_faces = get_adj(skin_tets, 2, moab::Interface::UNION);
2553 adj_faces =
2554 subtract(adj_faces, skin_tets); // remove skin tets faces
2555 auto adj_tets = get_adj(adj_faces, 3,
2556 moab::Interface::UNION); // tets which are
2557 // adjacent to skin
2558 crack_faces_tets =
2559 subtract(crack_faces_tets,
2560 adj_tets); // remove tets which are adjacent to
2561 // skin, so that they are not removed
2562 crack_faces_tets_faces =
2563 subtract(crack_faces_tets_faces, adj_faces);
2564
2565 all_removed_faces.merge(adj_faces);
2566 all_removed_tets.merge(adj_tets);
2567
2568 MOFEM_LOG("EPSELF", Sev::inform)
2569 << "Remove internal faces size " << adj_faces.size()
2570 << " tets size " << adj_tets.size();
2572 };
2573
2574 auto case_only_one_free_edge = [&]() {
2576
2577 for (auto t : Range(crack_faces_tets)) {
2578
2579 auto adj_faces = get_adj(
2580 Range(t, t), 2,
2581 moab::Interface::UNION); // faces of tet which can be removed
2582 auto crack_surface_edges =
2583 get_adj(subtract(unite(crack_faces_tets_faces, crack_faces),
2584 adj_faces),
2585 1,
2586 moab::Interface::UNION); // edges not on the tet but
2587 // on crack surface
2588 auto adj_edges =
2589 subtract(get_adj(Range(t, t), 1, moab::Interface::INTERSECT),
2590 crack_surface_edges); // free edges
2591 adj_edges = subtract(
2592 adj_edges,
2593 boundary_tets_edges); // edges which are not part of gemetry
2594
2595 if (adj_edges.size() == 1) {
2596 crack_faces_tets =
2597 subtract(crack_faces_tets,
2598 Range(t, t)); // remove tets which are adjacent to
2599 // skin, so that they are not removed
2600
2601 auto faces_to_remove =
2602 get_adj(adj_edges, 2, moab::Interface::UNION); // faces
2603 // which can
2604 // be removed
2605 crack_faces_tets_faces =
2606 subtract(crack_faces_tets_faces, faces_to_remove);
2607
2608 all_removed_faces.merge(faces_to_remove);
2609 all_removed_tets.merge(Range(t, t));
2610
2611 MOFEM_LOG("EPSELF", Sev::inform) << "Remove free one edges ";
2612 }
2613 }
2614
2615 crack_faces_tets = subtract(crack_faces_tets, all_removed_tets);
2616 crack_faces_tets_faces =
2617 subtract(crack_faces_tets_faces, all_removed_faces);
2618
2620 };
2621
2622 auto cese_flat_tet = [&](auto max_adj_edges) {
2624
2625 Range body_ents;
2626 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
2627 body_ents);
2628 auto body_skin = get_skin(mField, body_ents);
2629 auto body_skin_edges =
2630 get_adj(body_skin, 1, moab::Interface::UNION);
2631
2632 for (auto t : Range(crack_faces_tets)) {
2633
2634 auto adj_faces = get_adj(
2635 Range(t, t), 2,
2636 moab::Interface::UNION); // faces of tet which can be removed
2637 auto crack_surface_edges =
2638 get_adj(subtract(unite(crack_faces_tets_faces, crack_faces),
2639 adj_faces),
2640 1,
2641 moab::Interface::UNION); // edges not on the tet but
2642 // on crack surface
2643 auto adj_edges =
2644 subtract(get_adj(Range(t, t), 1, moab::Interface::INTERSECT),
2645 crack_surface_edges); // free edges
2646 adj_edges = subtract(adj_edges, body_skin_edges);
2647
2648 auto tet_edges = get_adj(Range(t, t), 1,
2649 moab::Interface::UNION); // edges of
2650 // tet
2651 tet_edges = subtract(tet_edges, adj_edges);
2652
2653 for (auto e : tet_edges) {
2654 constexpr int opposite_edge[] = {5, 3, 4, 1, 2, 0};
2655 auto get_side = [&](auto e) {
2656 int side, sense, offset;
2658 mField.get_moab().side_number(t, e, side, sense, offset),
2659 "get side number failed");
2660 return side;
2661 };
2662 auto get_side_ent = [&](auto side) {
2663 EntityHandle side_edge;
2665 mField.get_moab().side_element(t, 1, side, side_edge),
2666 "get side failed");
2667 return side_edge;
2668 };
2669 adj_edges.erase(get_side_ent(opposite_edge[get_side(e)]));
2670 }
2671
2672 if (adj_edges.size() <= max_adj_edges) {
2673
2674 double dot = 1;
2675 Range faces_to_remove;
2676 for (auto e : adj_edges) {
2677 auto edge_adj_faces =
2678 get_adj(Range(e, e), 2, moab::Interface::UNION);
2679 edge_adj_faces = intersect(edge_adj_faces, adj_faces);
2680 if (edge_adj_faces.size() != 2) {
2682 "Adj faces size is not 2 for edge " +
2683 boost::lexical_cast<std::string>(e));
2684 }
2685
2686 auto get_normal = [&](auto f) {
2689 mField.getInterface<Tools>()->getTriNormal(f, &t_n(0)),
2690 "get tri normal failed");
2691 return t_n;
2692 };
2693 auto t_n0 = get_normal(edge_adj_faces[0]);
2694 auto t_n1 = get_normal(edge_adj_faces[1]);
2695 auto get_sense = [&](auto f) {
2696 int side, sense, offset;
2697 CHK_MOAB_THROW(mField.get_moab().side_number(t, f, side,
2698 sense, offset),
2699 "get side number failed");
2700 return sense;
2701 };
2702 auto sense0 = get_sense(edge_adj_faces[0]);
2703 auto sense1 = get_sense(edge_adj_faces[1]);
2704 t_n0.normalize();
2705 t_n1.normalize();
2706
2708 auto dot_e = (sense0 * sense1) * t_n0(i) * t_n1(i);
2709 if (dot_e < dot || e == adj_edges[0]) {
2710 dot = dot_e;
2711 faces_to_remove = edge_adj_faces;
2712 }
2713 }
2714
2715 all_removed_faces.merge(faces_to_remove);
2716 all_removed_tets.merge(Range(t, t));
2717
2718 MOFEM_LOG("EPSELF", Sev::inform)
2719 << "Remove free edges on flat tet, with considered nb. of "
2720 "edges "
2721 << adj_edges.size();
2722 }
2723 }
2724
2725 crack_faces_tets = subtract(crack_faces_tets, all_removed_tets);
2726 crack_faces_tets_faces =
2727 subtract(crack_faces_tets_faces, all_removed_faces);
2728
2730 };
2731
2732 CHK_THROW_MESSAGE(case_only_one_free_edge(),
2733 "Case only one free edge failed");
2734 for (auto max_adj_edges : {0, 1, 2, 3}) {
2735 CHK_THROW_MESSAGE(cese_flat_tet(max_adj_edges),
2736 "Case only one free edge failed");
2737 }
2738 CHK_THROW_MESSAGE(cese_internal_faces(),
2739 "Case internal faces failed");
2740
2741 if (debug) {
2743 "crack_faces_tets_faces_" +
2744 boost::lexical_cast<std::string>(counter) + ".vtk",
2745 crack_faces_tets_faces);
2747 "crack_faces_tets_" +
2748 boost::lexical_cast<std::string>(counter) + ".vtk",
2749 crack_faces_tets);
2750 }
2751
2752 return std::make_tuple(crack_faces_tets_faces, crack_faces_tets,
2753 all_removed_faces, all_removed_tets);
2754 };
2755
2756 auto [resolved_faces, resolved_tets, all_removed_faces,
2757 all_removed_tets] =
2758 resolve_surface(boundary_tets_edges, crack_faces_tets);
2759 resolved_faces.merge(subtract(crack_faces, all_removed_faces));
2760 if (debug) {
2761 CHKERR save_range(mField.get_moab(), "resolved_faces.vtk",
2762 resolved_faces);
2763 CHKERR save_range(mField.get_moab(), "resolved_tets.vtk",
2764 resolved_tets);
2765 }
2766
2767 crack_faces = resolved_faces;
2768 }
2769
2771 };
2772
2773 CHK_THROW_MESSAGE(impl(), "resolve new crack surfaces");
2774
2775 return crack_faces; // send_type(mField, crack_faces, MBTRI);
2776 };
2777
2778 auto resolve_consisten_crack_extension = [&]() {
2780 auto crack_meshset =
2781 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
2783 auto meshset = crack_meshset->getMeshset();
2784
2785 if (!mField.get_comm_rank()) {
2786 Range old_crack_faces;
2787 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTRI,
2788 old_crack_faces);
2789 auto extendeded_crack_faces = get_extended_crack_faces();
2790 auto reconstructed_crack_faces =
2791 subtract(reconstruct_crack_faces(extendeded_crack_faces),
2792 subtract(*crackFaces, old_crack_faces));
2793 if (nbCrackFaces >= reconstructed_crack_faces.size()) {
2794 MOFEM_LOG("EPSELF", Sev::warning)
2795 << "No new crack faces to add, skipping adding to meshset";
2796 extendeded_crack_faces = subtract(
2797 extendeded_crack_faces, subtract(*crackFaces, old_crack_faces));
2798 MOFEM_LOG("EPSELF", Sev::inform)
2799 << "Number crack faces size (extended) "
2800 << extendeded_crack_faces.size();
2801 CHKERR mField.get_moab().clear_meshset(&meshset, 1);
2802 CHKERR mField.get_moab().add_entities(meshset, extendeded_crack_faces);
2803 } else {
2804 CHKERR mField.get_moab().clear_meshset(&meshset, 1);
2805 CHKERR mField.get_moab().add_entities(meshset,
2806 reconstructed_crack_faces);
2807 MOFEM_LOG("EPSELF", Sev::inform)
2808 << "Number crack faces size (reconstructed) "
2809 << reconstructed_crack_faces.size();
2810 nbCrackFaces = reconstructed_crack_faces.size();
2811 }
2812 }
2813
2814 Range crack_faces;
2815 if (!mField.get_comm_rank()) {
2816 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTRI,
2817 crack_faces);
2818 }
2819 crack_faces = send_type(mField, crack_faces, MBTRI);
2820 if (mField.get_comm_rank()) {
2821 CHKERR mField.get_moab().clear_meshset(&meshset, 1);
2822 CHKERR mField.get_moab().add_entities(meshset, crack_faces);
2823 }
2824
2826 };
2827
2828 CHKERR resolve_consisten_crack_extension();
2829
2831};
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:2254
#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 4368 of file EshelbianPlasticity.cpp.

4368 {
4370
4371 PetscBool debug_model = PETSC_FALSE;
4372 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-debug_model", &debug_model,
4373 PETSC_NULLPTR);
4374 MOFEM_LOG("EP", Sev::inform)
4375 << "Debug model flag is " << (debug_model ? "ON" : "OFF");
4376
4377 if (debug_model == PETSC_TRUE) {
4378 auto ts_ctx_ptr = getDMTsCtx(dmElastic);
4379 auto post_proc = [&](TS ts, PetscReal t, Vec u, Vec u_t, Vec u_tt, Vec F,
4380 void *ctx) {
4382
4383 SNES snes;
4384 CHKERR TSGetSNES(ts, &snes);
4385 int it;
4386 CHKERR SNESGetIterationNumber(snes, &it);
4387 std::string file_name = "snes_iteration_" + std::to_string(it) + ".h5m";
4388 CHKERR postProcessResults(1, file_name, F, u_t, PETSC_NULLPTR, {}, ts);
4389 std::string file_skel_name =
4390 "snes_iteration_skel_" + std::to_string(it) + ".h5m";
4391
4392 auto get_material_force_tag = [&]() {
4393 auto &moab = mField.get_moab();
4394 Tag tag;
4395 CHK_MOAB_THROW(moab.tag_get_handle("MaterialForce", tag),
4396 "can't get tag");
4397 return tag;
4398 };
4399
4401 CHKERR postProcessSkeletonResults(1, file_skel_name, F,
4402 {get_material_force_tag()}, ts);
4403
4405 };
4406 ts_ctx_ptr->tsDebugHook = post_proc;
4407 }
4408
4410}
@ 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 postProcessSkeletonResults(const int tag, const std::string file, Vec f_residual=PETSC_NULLPTR, std::vector< Tag > tags_to_transfer={}, TS ts=PETSC_NULLPTR)
MoFEMErrorCode postProcessResults(const int tag, const std::string file, Vec f_residual=PETSC_NULLPTR, Vec var_vec=PETSC_NULLPTR, Vec gradient=PETSC_NULLPTR, std::vector< Tag > tags_to_transfer={}, TS ts=PETSC_NULLPTR)
MoFEMErrorCode calculateFaceMaterialForce(const int tag, TS ts, SmartPetscObj< Vec > *adjoint_gradient_vector=nullptr)
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 2598 of file EshelbianPlasticity.cpp.

2599 {
2601
2602 // find adjacencies between finite elements and dofs
2604
2605 // Create coupled problem
2606 dM = createDM(mField.get_comm(), "DMMOFEM");
2607 CHKERR DMMoFEMCreateMoFEM(dM, &mField, "ESHELBY_PLASTICITY", bit,
2608 BitRefLevel().set());
2609 CHKERR DMMoFEMSetDestroyProblem(dM, PETSC_TRUE);
2610 CHKERR DMMoFEMSetIsPartitioned(dM, PETSC_TRUE);
2616
2617 mField.getInterface<ProblemsManager>()->buildProblemFromFields = PETSC_TRUE;
2618 CHKERR DMSetUp(dM);
2619 mField.getInterface<ProblemsManager>()->buildProblemFromFields = PETSC_FALSE;
2620
2621 auto remove_dofs_on_broken_skin = [&](const std::string prb_name) {
2623 for (int d : {0, 1, 2}) {
2624 std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_to_remove;
2626 ->getSideDofsOnBrokenSpaceEntities(
2627 dofs_to_remove, prb_name, ROW, piolaStress,
2629 // remove piola dofs, i.e. traction free boundary
2630 CHKERR mField.getInterface<ProblemsManager>()->removeDofs(prb_name, ROW,
2631 dofs_to_remove);
2632 CHKERR mField.getInterface<ProblemsManager>()->removeDofs(prb_name, COL,
2633 dofs_to_remove);
2634 }
2636 };
2637 CHKERR remove_dofs_on_broken_skin("ESHELBY_PLASTICITY");
2638
2639 // Create elastic sub-problem
2640 dmElastic = createDM(mField.get_comm(), "DMMOFEM");
2641 CHKERR DMMoFEMCreateSubDM(dmElastic, dM, "ELASTIC_PROBLEM");
2647 if (!isNoStretch()) {
2649 }
2659 CHKERR DMSetUp(dmElastic);
2660
2661 dmMaterial = createDM(mField.get_comm(), "DMMOFEM");
2662 CHKERR DMMoFEMCreateSubDM(dmMaterial, dM, "MATERIAL_PROBLEM");
2671 if (!isNoStretch()) {
2673 }
2679 CHKERR DMSetUp(dmMaterial);
2680
2681 auto set_zero_block = [&]() {
2683 if (!isNoStretch()) {
2684 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2685 "ELASTIC_PROBLEM", spatialL2Disp, stretchTensor);
2686 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2687 "ELASTIC_PROBLEM", stretchTensor, spatialL2Disp);
2688 }
2689 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2690 "ELASTIC_PROBLEM", spatialL2Disp, rotAxis);
2691 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2692 "ELASTIC_PROBLEM", rotAxis, spatialL2Disp);
2693 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2694 "ELASTIC_PROBLEM", spatialL2Disp, bubbleField);
2695 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2696 "ELASTIC_PROBLEM", bubbleField, spatialL2Disp);
2697 if (!isNoStretch()) {
2698 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2699 "ELASTIC_PROBLEM", bubbleField, bubbleField);
2700 CHKERR
2701 mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2702 "ELASTIC_PROBLEM", piolaStress, piolaStress);
2703 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2704 "ELASTIC_PROBLEM", bubbleField, piolaStress);
2705 CHKERR mField.getInterface<ProblemsManager>()->addFieldToEmptyFieldBlocks(
2706 "ELASTIC_PROBLEM", piolaStress, bubbleField);
2707 }
2708
2709 auto zero_kinetic_constraints_block = [&]() {
2711 // we shoudl have sparet bloc names for this. TOPO_FIX_X, TOPO_FIX_Y,
2712 // TOPO_FIX_Z, TOPO_FIX_ALL
2713 auto bc_mng = mField.getInterface<BcManager>();
2714 CHKERR bc_mng->removeBlockDOFsOnEntities("MATERIAL_PROBLEM", "REMOVE_X",
2715 materialH1Positions, 0, 0);
2716 CHKERR bc_mng->removeBlockDOFsOnEntities("MATERIAL_PROBLEM", "REMOVE_Y",
2717 materialH1Positions, 1, 1);
2718 CHKERR bc_mng->removeBlockDOFsOnEntities("MATERIAL_PROBLEM", "REMOVE_Z",
2719 materialH1Positions, 2, 2);
2720 CHKERR bc_mng->removeBlockDOFsOnEntities("MATERIAL_PROBLEM", "REMOVE_ALL",
2721 materialH1Positions, 0, 3);
2722 CHKERR bc_mng->removeBlockDOFsOnEntities("MATERIAL_PROBLEM", "FIX_X",
2723 materialH1Positions, 0, 0);
2724 CHKERR bc_mng->removeBlockDOFsOnEntities("MATERIAL_PROBLEM", "FIX_Y",
2725 materialH1Positions, 1, 1);
2726 CHKERR bc_mng->removeBlockDOFsOnEntities("MATERIAL_PROBLEM", "FIX_Z",
2727 materialH1Positions, 2, 2);
2728 CHKERR bc_mng->removeBlockDOFsOnEntities("MATERIAL_PROBLEM", "FIX_ALL",
2729 materialH1Positions, 0, 3);
2731 };
2732
2733 // CHKERR zero_kinetic_constraints_block();
2734
2737 };
2738
2739 auto set_section = [&]() {
2741 PetscSection section;
2742 CHKERR mField.getInterface<ISManager>()->sectionCreate("ELASTIC_PROBLEM",
2743 &section);
2744 CHKERR DMSetSection(dmElastic, section);
2745 CHKERR DMSetGlobalSection(dmElastic, section);
2746 CHKERR PetscSectionDestroy(&section);
2748 };
2749
2750 CHKERR set_zero_block();
2751 CHKERR set_section();
2752
2753 dmPrjSpatial = createDM(mField.get_comm(), "DMMOFEM");
2754 CHKERR DMMoFEMCreateSubDM(dmPrjSpatial, dM, "PROJECT_SPATIAL");
2760 CHKERR DMSetUp(dmPrjSpatial);
2761
2762 // CHKERR mField.getInterface<BcManager>()
2763 // ->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
2764 // "PROJECT_SPATIAL", spatialH1Disp, true, false);
2765
2767}
@ 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
MoFEMErrorCode removeBlockDOFsOnEntities(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, bool is_distributed_mesh=true)
Remove DOFs from problem based on block entities.
Definition BcManager.cpp:72
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.
const std::string rotAxis
SmartPetscObj< DM > dmPrjSpatial
Projection spatial displacement.
static bool isNoStretch()
SmartPetscObj< Vec > solTSStep
const std::string stretchTensor
Boundary condition manager for finite element problem setup.
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,
const bool  add_bubble = true 
)
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 1416 of file EshelbianPlasticity.cpp.

1417 {
1419
1420 auto get_tets = [&]() {
1421 Range tets;
1422 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
1423 return tets;
1424 };
1425
1426 auto get_tets_skin = [&]() {
1427 Range tets_skin_part;
1428 Skinner skin(&mField.get_moab());
1429 CHKERR skin.find_skin(0, get_tets(), false, tets_skin_part);
1430 ParallelComm *pcomm =
1431 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
1432 Range tets_skin;
1433 CHKERR pcomm->filter_pstatus(tets_skin_part,
1434 PSTATUS_SHARED | PSTATUS_MULTISHARED,
1435 PSTATUS_NOT, -1, &tets_skin);
1436 return tets_skin;
1437 };
1438
1439 auto subtract_boundary_conditions = [&](auto &&tets_skin) {
1440 // That mean, that hybrid field on all faces on which traction is applied,
1441 // on other faces, or enforcing displacements as
1442 // natural boundary condition.
1444 for (auto &v : *bcSpatialTractionVecPtr) {
1445 tets_skin = subtract(tets_skin, v.faces);
1446 }
1447
1449 for (auto &v : *bcSpatialSpringVecPtr) {
1450 tets_skin = subtract(tets_skin, v.faces);
1451 }
1452
1454 for (auto &v : *bcSpatialAnalyticalTractionVecPtr) {
1455 tets_skin = subtract(tets_skin, v.faces);
1456 }
1457
1459 for (auto &v : *bcSpatialPressureVecPtr) {
1460 tets_skin = subtract(tets_skin, v.faces);
1461 }
1462
1463 return tets_skin;
1464 };
1465
1466 auto add_blockset = [&](auto block_name, auto &&tets_skin) {
1467 auto crack_faces =
1468 get_range_from_block(mField, "block_name", SPACE_DIM - 1);
1469 tets_skin.merge(crack_faces);
1470 return tets_skin;
1471 };
1472
1473 auto subtract_blockset = [&](auto block_name, auto &&tets_skin) {
1474 auto contact_range =
1475 get_range_from_block(mField, block_name, SPACE_DIM - 1);
1476 tets_skin = subtract(tets_skin, contact_range);
1477 return tets_skin;
1478 };
1479
1480 auto get_stress_trace_faces = [&](auto &&tets_skin) {
1481 Range faces;
1482 CHKERR mField.get_moab().get_adjacencies(get_tets(), SPACE_DIM - 1, true,
1483 faces, moab::Interface::UNION);
1484 Range trace_faces = subtract(faces, tets_skin);
1485 return trace_faces;
1486 };
1487
1488 auto tets = get_tets();
1489
1490 // remove also contact faces, i.e. that is also kind of hybrid field but
1491 // named but used to enforce contact conditions
1492 auto trace_faces = get_stress_trace_faces(
1493
1494 subtract_blockset("CONTACT",
1495 subtract_boundary_conditions(get_tets_skin()))
1496
1497 );
1498
1499 contactFaces = boost::make_shared<Range>(intersect(
1500 trace_faces, get_range_from_block(mField, "CONTACT", SPACE_DIM - 1)));
1502 boost::make_shared<Range>(subtract(trace_faces, *contactFaces));
1503
1504#ifndef NDEBUG
1505 if (contactFaces->size())
1507 "contact_faces_" +
1508 std::to_string(mField.get_comm_rank()) + ".vtk",
1509 *contactFaces);
1510 if (skeletonFaces->size())
1512 "skeleton_faces_" +
1513 std::to_string(mField.get_comm_rank()) + ".vtk",
1514 *skeletonFaces);
1515#endif
1516
1517 const FieldApproximationBase broken_hdiv_base =
1519
1520 auto add_broken_hdiv_field = [this, meshset, broken_hdiv_base](
1521 const std::string field_name,
1522 const int order) {
1524
1525 const FieldApproximationBase base = broken_hdiv_base;
1526
1527 auto get_side_map_hdiv = [&]() {
1528 return std::vector<
1529
1530 std::pair<EntityType,
1532
1533 >>{
1534
1535 {MBTET,
1536 [&](BaseFunction::DofsSideMap &dofs_side_map) -> MoFEMErrorCode {
1537 return TetPolynomialBase::setDofsSideMap(HDIV, DISCONTINUOUS, base,
1538 dofs_side_map);
1539 }}
1540
1541 };
1542 };
1543
1545 get_side_map_hdiv(), MB_TAG_DENSE, MF_ZERO);
1547 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1549 };
1550
1551 auto add_l2_field = [this, meshset](const std::string field_name,
1552 const int order, const int dim) {
1555 MB_TAG_DENSE, MF_ZERO);
1557 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1559 };
1560
1561 auto add_h1_field = [this, meshset](const std::string field_name,
1562 const int order, const int dim) {
1565 MB_TAG_DENSE, MF_ZERO);
1567 CHKERR mField.set_field_order(meshset, MBVERTEX, field_name, 1);
1568 CHKERR mField.set_field_order(meshset, MBEDGE, field_name, order);
1569 CHKERR mField.set_field_order(meshset, MBTRI, field_name, order);
1570 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1572 };
1573
1574 auto add_l2_field_by_range = [this](const std::string field_name,
1575 const int order, const int dim,
1576 const int field_dim, Range &&r) {
1579 MB_TAG_DENSE, MF_ZERO);
1580 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(r);
1584 };
1585
1586 auto add_bubble_field = [this, meshset](const std::string field_name,
1587 const int order, const int dim) {
1589 CHKERR mField.add_field(field_name, HDIV, USER_BASE, dim, MB_TAG_DENSE,
1590 MF_ZERO);
1591 // Modify field
1592 auto field_ptr = mField.get_field_structure(field_name);
1593 auto field_order_table =
1594 const_cast<Field *>(field_ptr)->getFieldOrderTable();
1595 auto get_cgg_bubble_order_zero = [](int p) { return 0; };
1596 auto get_cgg_bubble_order_tet = [](int p) {
1597 return NBVOLUMETET_CCG_BUBBLE(p);
1598 };
1599 field_order_table[MBVERTEX] = get_cgg_bubble_order_zero;
1600 field_order_table[MBEDGE] = get_cgg_bubble_order_zero;
1601 field_order_table[MBTRI] = get_cgg_bubble_order_zero;
1602 field_order_table[MBTET] = get_cgg_bubble_order_tet;
1604 CHKERR mField.set_field_order(meshset, MBTRI, field_name, order);
1605 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1607 };
1608
1609 auto add_user_l2_field = [this, meshset](const std::string field_name,
1610 const int order, const int dim) {
1612 CHKERR mField.add_field(field_name, L2, USER_BASE, dim, MB_TAG_DENSE,
1613 MF_ZERO);
1614 // Modify field
1615 auto field_ptr = mField.get_field_structure(field_name);
1616 auto field_order_table =
1617 const_cast<Field *>(field_ptr)->getFieldOrderTable();
1618 auto zero_dofs = [](int p) { return 0; };
1619 auto dof_l2_tet = [](int p) { return NBVOLUMETET_L2(p); };
1620 field_order_table[MBVERTEX] = zero_dofs;
1621 field_order_table[MBEDGE] = zero_dofs;
1622 field_order_table[MBTRI] = zero_dofs;
1623 field_order_table[MBTET] = dof_l2_tet;
1625 CHKERR mField.set_field_order(meshset, MBTET, field_name, order);
1627 };
1628
1629 if (!skeletonFaces)
1630 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "No skeleton faces");
1631 if (!contactFaces)
1632 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "No contact faces");
1633
1634 auto get_hybridised_disp = [&]() {
1635 auto faces = *skeletonFaces;
1636 auto skin = subtract_boundary_conditions(get_tets_skin());
1637 for (auto &bc : *bcSpatialNormalDisplacementVecPtr) {
1638 faces.merge(intersect(bc.faces, skin));
1639 }
1641 for (auto &bc : *bcSpatialSpringVecPtr) {
1642 faces.merge(intersect(bc.faces, skin));
1643 }
1644 return faces;
1645 };
1646
1647 auto add_spatial_fields = [&]<FieldApproximationBase Base>() {
1649 using Orders = EshelbianCore::FieldOrders<Base>;
1650 CHKERR add_broken_hdiv_field(piolaStress, Orders::stress(spaceOrder));
1651 if (add_bubble) {
1652 CHKERR add_bubble_field(bubbleField, Orders::bubble(spaceOrder), 1);
1653 }
1654 CHKERR add_l2_field(spatialL2Disp, Orders::disp(spaceOrder), 3);
1655 CHKERR add_user_l2_field(rotAxis, Orders::rot(spaceOrder), 3);
1656 CHKERR add_user_l2_field(stretchTensor,
1657 !isNoStretch()
1658 ? Orders::stretch(spaceOrder)
1659 : -1,
1660 6);
1661 CHKERR add_l2_field_by_range(hybridSpatialDisp,
1662 Orders::hybrid(spaceOrder), 2, 3,
1663 get_hybridised_disp());
1664 CHKERR add_l2_field_by_range(contactDisp, Orders::hybrid(spaceOrder), 2, 3,
1667 };
1668
1669 CHKERR withFieldOrders(add_spatial_fields);
1670
1671 // spatial displacement
1672 CHKERR add_h1_field(spatialH1Disp, spaceH1Order, 3);
1673 // material positions
1674 CHKERR add_h1_field(materialH1Positions, materialH1Order, 3);
1675
1677
1679}
#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
@ 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
static FieldApproximationBase brokenHdivBase
MoFEMErrorCode withFieldOrders(Op &&op) const
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_Core()

MoFEMErrorCode EshelbianCore::addMaterial_Core ( boost::weak_ptr< MatOps::PhysicalEquations mat_physical_equations_ptr)
Examples
ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

Definition at line 123 of file EshelbianMat.cpp.

124 {
126 physicalEquations = boost::make_shared<MatPhysicalEquations>(
127 mat_physical_equations_ptr.lock());
129}
boost::shared_ptr< PhysicalEquations > physicalEquations

◆ addMaterial_Hencky()

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

Definition at line 117 of file EshelbianMat.cpp.

117 {
119 physicalEquations = boost::make_shared<HMHHencky>(mField, E, nu);
121}

◆ addMaterial_HMHNeohookean()

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

Definition at line 102 of file EshelbianMat.cpp.

103 {
105 physicalEquations = boost::make_shared<HMHNeohookean>(mField, c10, K);
107}

◆ addMaterial_HMHStorakers()

MoFEMErrorCode EshelbianCore::addMaterial_HMHStorakers ( const double  eta,
const double  mu,
const double  beta 
)
Examples
ep.cpp, and mofem/users_modules/eshelbian_plasticity/ep.cpp.

Definition at line 109 of file EshelbianMat.cpp.

111 {
113 physicalEquations = boost::make_shared<HMHStorakers>(mField, eta, mu, beta);
115}
double eta

◆ addVolumeFiniteElement()

MoFEMErrorCode EshelbianCore::addVolumeFiniteElement ( const EntityHandle  meshset = 0,
const bool  add_bubble = true 
)
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 2404 of file EshelbianPlasticity.cpp.

2405 {
2407
2408 // set finite element fields
2409 auto add_field_to_fe = [this](const std::string fe,
2410 const std::string field_name) {
2416 };
2417
2422
2423 CHKERR add_field_to_fe(elementVolumeName, piolaStress);
2424 if (add_bubble) {
2425 CHKERR add_field_to_fe(elementVolumeName, bubbleField);
2426 }
2427 if (!isNoStretch())
2428 CHKERR add_field_to_fe(elementVolumeName, stretchTensor);
2429 CHKERR add_field_to_fe(elementVolumeName, rotAxis);
2430 CHKERR add_field_to_fe(elementVolumeName, spatialL2Disp);
2431 CHKERR add_field_to_fe(elementVolumeName, spatialH1Disp);
2432 CHKERR add_field_to_fe(elementVolumeName, contactDisp);
2434
2435 // build finite elements data structures
2437 }
2438
2440}

◆ calculateCrackArea()

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

Definition at line 2865 of file EshelbianFracture.cpp.

2865 {
2867
2868 if (!area_ptr) {
2869 // initialize area
2870 area_ptr = boost::shared_ptr<double>(new double(0.0));
2871 }
2872
2873 int success;
2874 *area_ptr = 0;
2875 if (mField.get_comm_rank() == 0) {
2876 MOFEM_LOG("EP", Sev::inform) << "Calculate crack area";
2877 auto crack_faces = get_range_from_block(mField, "CRACK", SPACE_DIM - 1);
2878 for (auto f : crack_faces) {
2879 *area_ptr += mField.getInterface<Tools>()->getTriArea(f);
2880 }
2881 success = MPI_Bcast(area_ptr.get(), 1, MPI_DOUBLE, 0, mField.get_comm());
2882 } else {
2883 success = MPI_Bcast(area_ptr.get(), 1, MPI_DOUBLE, 0, mField.get_comm());
2884 }
2885 if (success != MPI_SUCCESS) {
2887 }
2889}
@ MOFEM_OPERATION_UNSUCCESSFUL
Definition definitions.h:34

◆ calculateFaceMaterialForce()

MoFEMErrorCode EshelbianCore::calculateFaceMaterialForce ( const int  tag,
TS  ts,
SmartPetscObj< Vec > *  adjoint_gradient_vector = nullptr 
)

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.

15 {
17
18 constexpr bool debug = false;
19
20 auto get_tags_vec = [&](std::vector<std::pair<std::string, int>> names) {
21 std::vector<Tag> tags;
22 tags.reserve(names.size());
23 auto create_and_clean = [&]() {
25 for (auto n : names) {
26 tags.push_back(Tag());
27 auto &tag = tags.back();
28 auto &moab = mField.get_moab();
29 auto rval = moab.tag_get_handle(n.first.c_str(), tag);
30 if (rval == MB_SUCCESS) {
31 moab.tag_delete(tag);
32 }
33 double def_val[] = {0., 0., 0.};
34 CHKERR moab.tag_get_handle(n.first.c_str(), n.second, MB_TYPE_DOUBLE,
35 tag, MB_TAG_CREAT | MB_TAG_SPARSE, def_val);
36 }
38 };
39 CHK_THROW_MESSAGE(create_and_clean(), "create_and_clean");
40 return tags;
41 };
42
43 enum ExhangeTags {
44 MATERIALFORCE,
45 ADJOINT_MATERIALFORCE,
46 AREAGROWTH,
47 GRIFFITHFORCE,
48 ADJOINT_GRIFFITHFORCE,
49 FACEPRESSURE
50 };
51
52 auto tags = get_tags_vec({{"MaterialForce", 3},
53 {"AdjointMaterialForce", 3},
54 {"AreaGrowth", 3},
55 {"GriffithForce", 1},
56 {"AdjointGriffithForce", 1},
57 {"FacePressure", 1}});
58
59 auto calculate_material_forces = [&]() {
61
62 /**
63 * @brief Create element to integration faces energies
64 */
65 auto get_face_material_force_fe = [&]() {
67 auto fe_ptr = boost::make_shared<FaceEle>(mField);
68 fe_ptr->getRuleHook = [](int, int, int) { return -1; };
69 fe_ptr->setRuleHook =
70 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
71 if (ts != PETSC_NULLPTR) {
72 fe_ptr->data_ctx |= PetscData::CTX_SET_TIME;
73 CHKERR TSGetTime(ts, &(fe_ptr->ts_t));
74 CHKERR TSGetTimeStep(ts, &(fe_ptr->ts_dt));
75 }
76 // hybrid disp, evaluated on face first
77 EshelbianPlasticity::AddHOOps<2, 2, 3>::add(
78 fe_ptr->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
79 fe_ptr->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
80 hybridSpatialDisp, dataAtPts->getHybridDispAtPts()));
81 fe_ptr->getOpPtrVector().push_back(
82 new OpCalculateVectorFieldGradient<SPACE_DIM, SPACE_DIM>(
83 hybridSpatialDisp, dataAtPts->getGradHybridDispAtPts()));
84 auto op_loop_domain_side =
85 new OpLoopSide<VolumeElementForcesAndSourcesCoreOnSide>(
86 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
87 fe_ptr->getOpPtrVector().push_back(op_loop_domain_side);
88 fe_ptr->getOpPtrVector().push_back(new OpFaceMaterialForce(dataAtPts));
89
90 // evaluated in side domain, that is op_loop_domain_side
91 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
92 boost::make_shared<CGGUserPolynomialBase>(nullptr, true);
93
94 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
95 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
96 materialH1Positions, frontAdjEdges, nullptr, nullptr, nullptr);
97 op_loop_domain_side->getOpPtrVector().push_back(
98 new OpCalculateHVecTensorField<SPACE_DIM, SPACE_DIM>(
99 piolaStress, dataAtPts->getApproxPAtPts()));
100
101 op_loop_domain_side->getOpPtrVector().push_back(
102 new OpCalculateVectorFieldValues<SPACE_DIM>(
103 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
104 if (isNoStretch() ||
106 // We have to use actual strains to evaluate J integral and energy,
107 // in this case. Note actual stresses, and actual energy can only drive
108 // crack growth
109
111 op_loop_domain_side->getOpPtrVector(), physicalEquations,
113 } else {
114 // That will not work for problem with internal stress or strain, since
115 // we approximate mechanical stretch, not actual stretch. At some point
116 // in time we can change formulation so that actual stretch is
117 // approximated. However, the way how to do it is not clear.
118
119 op_loop_domain_side->getOpPtrVector().push_back(
120 new OpCalculateTensor2SymmetricFieldValues<SPACE_DIM>(
121 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
122 }
123
124 op_loop_domain_side->getOpPtrVector().push_back(
126
127 return fe_ptr;
128 };
129
130 auto integrate_face_material_force_fe = [&](auto &&face_energy_fe) {
133 dM, skeletonElement, face_energy_fe, 0, mField.get_comm_size());
134
135 auto face_exchange = CommInterface::createEntitiesPetscVector(
136 mField.get_comm(), mField.get_moab(), 2, 3, Sev::inform);
137
138 auto print_loc_size = [this](auto v, auto str, auto sev) {
140 int size;
141 CHKERR VecGetLocalSize(v.second, &size);
142 int low, high;
143 CHKERR VecGetOwnershipRange(v.second, &low, &high);
144 MOFEM_LOG("EPSYNC", sev) << str << " local size " << size << " ( "
145 << low << " " << high << " ) ";
148 };
149 CHKERR print_loc_size(face_exchange, "material face_exchange",
150 Sev::verbose);
151
152 CHKERR CommInterface::updateEntitiesPetscVector(
153 mField.get_moab(), face_exchange, tags[ExhangeTags::MATERIALFORCE]);
154 CHKERR CommInterface::updateEntitiesPetscVector(
155 mField.get_moab(), faceExchange, tags[ExhangeTags::FACEPRESSURE]);
156
157 #ifndef NDEBUG
158 if (debug) {
160 "front_skin_faces_material_force_" +
161 std::to_string(mField.get_comm_rank()) + ".vtk",
163 }
164 #endif
165
167 };
168
169 CHKERR integrate_face_material_force_fe(get_face_material_force_fe());
170
172 };
173
174 auto get_conn = [&](auto e) {
175 Range conn;
176 CHK_MOAB_THROW(mField.get_moab().get_connectivity(&e, 1, conn, true),
177 "get connectivity");
178 return conn;
179 };
180
181 auto get_conn_range = [&](auto e) {
182 Range conn;
183 CHK_MOAB_THROW(mField.get_moab().get_connectivity(e, conn, true),
184 "get connectivity");
185 return conn;
186 };
187
188 auto get_adj = [&](auto e, auto dim) {
189 Range adj;
190 CHK_MOAB_THROW(mField.get_moab().get_adjacencies(&e, 1, dim, true, adj),
191 "get adj");
192 return adj;
193 };
194
195 auto get_adj_range = [&](auto e, auto dim) {
196 Range adj;
197 CHK_MOAB_THROW(mField.get_moab().get_adjacencies(e, dim, true, adj,
198 moab::Interface::UNION),
199 "get adj");
200 return adj;
201 };
202
203 auto get_vector_tag_data = [&](auto r, auto th) {
204 MatrixDouble tag_data(r.size(), 3, false);
206 mField.get_moab().tag_get_data(th, r, tag_data.data().data()),
207 "get vector tag data");
208 return tag_data;
209 };
210
211 auto calculate_edge_direction = [&](auto e) {
212 const EntityHandle *conn;
213 int num_nodes;
215 mField.get_moab().get_connectivity(e, conn, num_nodes, true),
216 "get connectivity");
217 std::array<double, 6> coords;
218 CHK_MOAB_THROW(mField.get_moab().get_coords(conn, num_nodes, coords.data()),
219 "get coords");
221 &coords[0], &coords[1], &coords[2]};
223 &coords[3], &coords[4], &coords[5]};
226 t_dir(i) = t_p1(i) - t_p0(i);
227 return t_dir;
228 };
229
230 auto average_vector_tag_at_edge = [&](auto th) {
232
234
235 for (auto e : *frontEdges) {
236 auto conn = get_conn(e);
237 auto data = get_vector_tag_data(conn, th);
238 auto t_node = getFTensor1FromPtr<SPACE_DIM>(data.data().data());
239 FTensor::Tensor1<double, SPACE_DIM> t_edge_material_force{0., 0., 0.};
240 for (auto n : conn) {
241 NOT_USED(n);
242 t_edge_material_force(I) += t_node(I);
243 ++t_node;
244 }
245 t_edge_material_force(I) /= conn.size();
246
247 FTensor::Tensor1<double, SPACE_DIM> t_edge_direction =
248 calculate_edge_direction(e);
249 t_edge_direction.normalize();
250
251 // Project the averaged vector to the plane normal to the front edge.
253 t_cross(K) = FTensor::levi_civita(I, J, K) * t_edge_direction(I) *
254 t_edge_material_force(J);
255 t_edge_material_force(K) =
256 FTensor::levi_civita(I, J, K) * t_edge_direction(J) * t_cross(I);
257
258 CHKERR mField.get_moab().tag_set_data(th, &e, 1,
259 &t_edge_material_force(0));
260 }
261
263 };
264
265 auto average_material_force_at_edge = [&](auto th) {
267
268 if (mField.get_comm_rank() == 0) {
269 CHKERR average_vector_tag_at_edge(th);
270
271// #ifndef NDEBUG
272// if (debug) {
273 int ts_step;
274 CHKERR TSGetStepNumber(ts, &ts_step);
276 "front_edges_material_force_" +
277 std::to_string(ts_step) + ".vtk",
278 *frontEdges);
279// }
280// #endif
281 }
282
284 };
285
286 auto calculate_force_through_node = [&](auto nb_J_integral_contours) {
288
290
291 if (mField.get_comm_rank() == 0) {
292 auto front_nodes = get_conn_range(*frontEdges);
293 Range all_skin_faces;
294
295 for (auto n : front_nodes) {
296 auto adj_tets = get_adj(n, SPACE_DIM);
297 for (int ll = 0; ll < nb_J_integral_contours; ++ll) {
298 auto conn = get_conn_range(adj_tets);
299 adj_tets = get_adj_range(conn, SPACE_DIM);
300 }
301
302 auto skin_faces = get_skin(mField, adj_tets);
303 auto material_forces =
304 get_vector_tag_data(skin_faces, tags[ExhangeTags::MATERIALFORCE]);
305
306#ifndef NDEBUG
307 if (debug) {
308 all_skin_faces.merge(skin_faces);
309 }
310#endif
311
312 auto t_face_T =
313 getFTensor1FromPtr<SPACE_DIM>(material_forces.data().data());
314 FTensor::Tensor1<double, SPACE_DIM> t_node_force{0., 0., 0.};
315 for (auto face : skin_faces) {
316
317 FTensor::Tensor1<double, SPACE_DIM> t_face_force_tmp{0., 0., 0.};
318 t_face_force_tmp(I) = t_face_T(I);
319 ++t_face_T;
320
321 auto face_tets = intersect(get_adj(face, SPACE_DIM), adj_tets);
322
323 if (face_tets.empty()) {
324 continue;
325 }
326
327 if (face_tets.size() != 1) {
329 "face_tets.size() != 1");
330 }
331
332 int side_number, sense, offset;
333 CHK_MOAB_THROW(mField.get_moab().side_number(face_tets[0], face,
334 side_number, sense,
335 offset),
336 "moab side number");
337 t_face_force_tmp(I) *= sense;
338 t_node_force(I) += t_face_force_tmp(I);
339 }
340
341 t_node_force(I) /= griffithEnergy; // scale all by griffith energy
343 mField.get_moab().tag_set_data(tags[ExhangeTags::MATERIALFORCE],
344 &n, 1, &t_node_force(0)),
345 "set data");
346 }
347
348#ifndef NDEBUG
349 if (debug) {
350 int ts_step;
351 CHKERR TSGetStepNumber(ts, &ts_step);
353 "front_skin_faces_material_force_" +
354 std::to_string(ts_step) + ".vtk",
355 all_skin_faces);
356 }
357#endif
358 }
359
361 };
362
363 auto get_adj_tets_for_contour = [&](auto n, auto nb_J_integral_contours) {
364 auto adj_tets = get_adj(n, SPACE_DIM);
365 for (int ll = 0; ll < nb_J_integral_contours; ++ll) {
366 auto conn = get_conn_range(adj_tets);
367 adj_tets = get_adj_range(conn, SPACE_DIM);
368 }
369 return adj_tets;
370 };
371
372 auto get_front_node_adj_crack_faces = [&](auto n) {
373 return intersect(get_adj(n, SPACE_DIM - 1), *crackFaces);
374 };
375
376 auto calculate_crack_area_growth_face = [&](auto nb_J_integral_contours) {
378
379 FTENSOR_INDEXES(SPACE_DIM, I, J, K, L);
380
381 if (mField.get_comm_rank() == 0) {
382 auto front_nodes = get_conn_range(*frontEdges);
383 auto body_edges = get_range_from_block(mField, "EDGES", 1);
384 Range body_ents;
385 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
386 body_ents);
387 auto body_skin = get_skin(mField, body_ents);
388 auto body_skin_conn = get_conn_range(body_skin);
389
390 auto calculate_seed_area_growth = [&](auto n, auto &adj_faces) {
391 // if skin is on body surface, project the direction on it
392 FTensor::Tensor1<double, SPACE_DIM> t_project{0., 0., 0.};
393 auto boundary_node = intersect(Range(n, n), body_skin_conn);
394 if (boundary_node.size()) {
395 auto faces = intersect(get_adj(n, SPACE_DIM - 1), body_skin);
396 for (auto f : faces) {
397 FTensor::Tensor1<double, 3> t_normal_face;
398 CHKERR mField.getInterface<Tools>()->getTriNormal(
399 f, &t_normal_face(0));
400 t_project(I) += t_normal_face(I);
401 }
402 t_project.normalize();
403 }
404
405 // calculate surface projection matrix
408 t_Q(I, J) = t_kd(I, J);
409 if (boundary_node.size()) {
410 t_Q(I, J) -= t_project(I) * t_project(J);
411 }
412
413 FTensor::Tensor1<double, 3> t_area_dir{0., 0., 0.};
414 for (auto f : adj_faces) {
415 int num_nodes;
416 const EntityHandle *conn;
417 CHKERR mField.get_moab().get_connectivity(f, conn, num_nodes, true);
418 std::array<double, 9> coords;
419 CHKERR mField.get_moab().get_coords(conn, num_nodes, coords.data());
420 FTensor::Tensor1<double, 3> t_face_normal;
422 CHKERR mField.getInterface<Tools>()->getTriNormal(
423 coords.data(), &t_face_normal(0), &t_d_normal(0, 0, 0));
424 auto n_it = std::find(conn, conn + num_nodes, n);
425 auto n_index = std::distance(conn, n_it);
426
427 FTensor::Tensor2<double, 3, 3> t_face_hessian{
428 t_d_normal(0, n_index, 0), t_d_normal(0, n_index, 1),
429 t_d_normal(0, n_index, 2),
430
431 t_d_normal(1, n_index, 0), t_d_normal(1, n_index, 1),
432 t_d_normal(1, n_index, 2),
433
434 t_d_normal(2, n_index, 0), t_d_normal(2, n_index, 1),
435 t_d_normal(2, n_index, 2)};
436
437 FTensor::Tensor2<double, 3, 3> t_projected_hessian;
438 t_projected_hessian(I, J) =
439 t_Q(I, K) * (t_face_hessian(K, L) * t_Q(L, J));
440 t_face_normal.normalize();
441 t_area_dir(K) += t_face_normal(I) * t_projected_hessian(I, K) / 2.;
442 }
443
444 return t_area_dir;
445 };
446
447 auto get_crack_area_growth_seed_nodes = [&](auto &adj_tets) {
448 // This gets all 1D edges adjacent to the current tetrahedral patch
449 // adj_tets, then keeps only edges that are either crack-front edges or
450 // special body edges from the "EDGES" block. So adj_edges is the local
451 // edge stencil relevant to crack growth near the current front node.
452 auto adj_edges = intersect(get_adj_range(adj_tets, 1),
453 unite(*frontEdges, body_edges));
454
455 // This collects all vertices/nodes connected to those edges. These are
456 // candidate seed nodes whose local crack-area growth contribution will
457 // be accumulated.
458 auto seed_n = get_conn_range(adj_edges);
459 auto skin_adj_edges = get_skin(mField, adj_edges);
460 skin_adj_edges = subtract(skin_adj_edges, body_skin_conn);
461 seed_n = subtract(seed_n, skin_adj_edges);
462
463 return std::make_pair(seed_n, skin_adj_edges);
464 };
465
466 auto calculate_front_node_area_growth = [&](auto &adj_tets) {
467 auto [seed_n, skin_adj_edges] =
468 get_crack_area_growth_seed_nodes(adj_tets);
469
470 FTensor::Tensor1<double, SPACE_DIM> t_area_dir{0., 0., 0.};
471 auto add_area_growth_direction = [&](auto sn, double weight) {
472 auto adj_faces = intersect(get_adj(sn, SPACE_DIM - 1), *crackFaces);
473 if (adj_faces.empty()) {
474 return;
475 }
476
477 auto t_area_dir_sn = calculate_seed_area_growth(sn, adj_faces);
478 t_area_dir(I) += weight * t_area_dir_sn(I);
479 };
480
481 for (auto sn : seed_n) {
482 add_area_growth_direction(sn, 1.);
483 }
484 for (auto sn : skin_adj_edges) {
485 add_area_growth_direction(sn, 0.5);
486 }
487
488 return t_area_dir;
489 };
490
491 for (auto n : front_nodes) {
492 auto front_node_adj_faces = get_front_node_adj_crack_faces(n);
493 if (front_node_adj_faces.empty()) {
494 continue;
495 }
496
497 auto adj_tets = get_adj_tets_for_contour(n, nb_J_integral_contours);
498 auto t_area_dir = calculate_front_node_area_growth(adj_tets);
499
501 mField.get_moab().tag_set_data(tags[ExhangeTags::AREAGROWTH], &n, 1,
502 &t_area_dir(0)),
503 "set data");
504 }
505 }
506
508 };
509
510 auto calculate_crack_area_growth_no_face = [&](auto nb_J_integral_contours,
511 auto material_force_tag) {
513
515
516 if (mField.get_comm_rank() == 0) {
517 auto front_nodes = get_conn_range(*frontEdges);
518 auto body_edges = get_range_from_block(mField, "EDGES", 1);
519 Range body_ents;
520 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM,
521 body_ents);
522 auto body_skin = get_skin(mField, body_ents);
523 auto body_skin_conn = get_conn_range(body_skin);
524
525 auto calculate_seed_area_growth = [&](auto n, auto &t_node_force) {
526 auto adj_edges =
527 intersect(get_adj(n, 1), unite(*frontEdges, body_edges));
528 double l = 0;
529 for (auto e : adj_edges) {
530 auto t_dir = calculate_edge_direction(e);
531 l += t_dir.l2();
532 }
533 l /= 2;
534
535 FTensor::Tensor1<double, SPACE_DIM> t_area_dir{0., 0., 0.};
537 t_node_force_tmp(I) = t_node_force(I);
538 t_node_force_tmp.normalize();
539 t_area_dir(I) = -t_node_force_tmp(I);
540 t_area_dir(I) *= l / 2;
541 return t_area_dir;
542 };
543
544 auto get_crack_area_growth_seed_nodes = [&](auto &adj_tets) {
545 auto adj_edges = intersect(get_adj_range(adj_tets, 1),
546 unite(*frontEdges, body_edges));
547 auto seed_n = get_conn_range(adj_edges);
548 auto skin_adj_edges = get_skin(mField, adj_edges);
549 skin_adj_edges = subtract(skin_adj_edges, body_skin_conn);
550 seed_n = subtract(seed_n, skin_adj_edges);
551
552 return std::make_pair(seed_n, skin_adj_edges);
553 };
554
555 auto calculate_front_node_area_growth = [&](auto &adj_tets,
556 auto &t_node_force) {
557 auto [seed_n, skin_adj_edges] =
558 get_crack_area_growth_seed_nodes(adj_tets);
559
560 FTensor::Tensor1<double, SPACE_DIM> t_area_dir{0., 0., 0.};
561 auto add_area_growth_direction = [&](auto sn, double weight) {
562 auto t_area_dir_sn = calculate_seed_area_growth(sn, t_node_force);
563 t_area_dir(I) += weight * t_area_dir_sn(I);
564 };
565
566 for (auto sn : seed_n) {
567 add_area_growth_direction(sn, 1.);
568 }
569 for (auto sn : skin_adj_edges) {
570 add_area_growth_direction(sn, 0.5);
571 }
572
573 return t_area_dir;
574 };
575
576 for (auto n : front_nodes) {
577 auto front_node_adj_faces = get_front_node_adj_crack_faces(n);
578 if (front_node_adj_faces.empty()) {
580 CHKERR mField.get_moab().tag_get_data(tags[material_force_tag], &n, 1,
581 &t_node_force(0));
582
583 auto adj_tets = get_adj_tets_for_contour(n, nb_J_integral_contours);
584 auto t_area_dir =
585 calculate_front_node_area_growth(adj_tets, t_node_force);
586
588 mField.get_moab().tag_set_data(tags[ExhangeTags::AREAGROWTH], &n,
589 1, &t_area_dir(0)),
590 "set data");
591 }
592 }
593 }
594
596 };
597
598 auto update_crack_area_growth_edges = [&]() {
600
601 if (mField.get_comm_rank() == 0) {
602 CHKERR average_vector_tag_at_edge(tags[ExhangeTags::AREAGROWTH]);
603 }
604
605 auto area_growth_edge_exchange = CommInterface::createEntitiesPetscVector(
606 mField.get_comm(), mField.get_moab(), 1, 3, Sev::inform);
607 CHKERR CommInterface::updateEntitiesPetscVector(
608 mField.get_moab(), area_growth_edge_exchange,
609 tags[ExhangeTags::AREAGROWTH]);
610
612 };
613
614 auto calculate_griffith_force = [&](ExhangeTags material_force_tag,
615 ExhangeTags griffith_force_tag) {
617
619
620 if (mField.get_comm_rank() == 0) {
621 auto front_nodes = get_conn_range(*frontEdges);
622 Range all_front_faces;
623
624 for (auto n : front_nodes) {
626 CHKERR mField.get_moab().tag_get_data(tags[material_force_tag], &n, 1,
627 &t_node_force(0));
629 CHKERR mField.get_moab().tag_get_data(tags[ExhangeTags::AREAGROWTH], &n,
630 1, &t_area_dir(0));
631
632 auto griffith =
633 -t_node_force(I) * t_area_dir(I) / (t_area_dir(K) * t_area_dir(K));
634 CHK_MOAB_THROW(mField.get_moab().tag_set_data(
635 tags[griffith_force_tag], &n, 1, &griffith),
636 "set data");
637 }
638
639 for (auto e : *frontEdges) {
641 CHKERR mField.get_moab().tag_get_data(tags[material_force_tag], &e, 1,
642 &t_edge_force(0));
644 CHKERR mField.get_moab().tag_get_data(tags[ExhangeTags::AREAGROWTH], &e,
645 1, &t_edge_area_dir(0));
646 double griffith_energy =
647 -t_edge_force(I) * t_edge_area_dir(I) /
648 (t_edge_area_dir(K) * t_edge_area_dir(K));
649 CHKERR mField.get_moab().tag_set_data(tags[griffith_force_tag], &e, 1,
650 &griffith_energy);
651 }
652
653 for (auto e : *frontEdges) {
654 auto adj_faces = get_adj(e, SPACE_DIM - 1);
655
656 if (debug) {
657 all_front_faces.merge(adj_faces);
658 }
659
661 CHKERR mField.get_moab().tag_get_data(tags[material_force_tag], &e, 1,
662 &t_edge_force(0));
663 FTensor::Tensor1<double, SPACE_DIM> t_edge_direction =
664 calculate_edge_direction(e);
665 t_edge_direction.normalize();
666
668 t_cross(K) = FTensor::levi_civita(I, J, K) * t_edge_direction(I) *
669 t_edge_force(J);
670
671 for (auto f : adj_faces) {
673 CHKERR mField.getInterface<Tools>()->getTriNormal(f, &t_normal(0));
674 t_normal.normalize();
675 int side_number, sense, offset;
676 CHKERR mField.get_moab().side_number(f, e, side_number, sense, offset);
677 auto dot = -sense * t_cross(I) * t_normal(I);
678 CHK_MOAB_THROW(mField.get_moab().tag_set_data(
679 tags[griffith_force_tag], &f, 1, &dot),
680 "set data");
681 }
682 }
683
684#ifndef NDEBUG
685 if (debug) {
686 int ts_step;
687 CHKERR TSGetStepNumber(ts, &ts_step);
689 "front_faces_material_force_" +
690 std::to_string(ts_step) + ".vtk",
691 all_front_faces);
692 }
693#endif
694 }
695
696 auto vector_edge_exchange = CommInterface::createEntitiesPetscVector(
697 mField.get_comm(), mField.get_moab(), 1, 3, Sev::inform);
698 CHKERR CommInterface::updateEntitiesPetscVector(
699 mField.get_moab(), vector_edge_exchange, tags[material_force_tag]);
700 auto &scalar_edge_exchange = edgeExchange;
701 CHKERR CommInterface::updateEntitiesPetscVector(
702 mField.get_moab(), scalar_edge_exchange, tags[griffith_force_tag]);
703
705 };
706
707 auto calculate_griffith_force_simplified = [&](auto material_force_tag,
708 auto griffith_force_tag) {
710
711 if (mField.get_comm_rank() == 0) {
712 auto front_nodes = get_conn_range(*frontEdges);
713
714 for (auto n : front_nodes) {
716 CHKERR mField.get_moab().tag_get_data(tags[material_force_tag], &n, 1,
717 &t_node_force(0));
718
719 auto adj_edges = intersect(get_adj(n, 1), *frontEdges);
720 double adj_edges_length = 0.;
721 for (auto e : adj_edges) {
722 auto t_edge_dir = calculate_edge_direction(e);
723 adj_edges_length += t_edge_dir.l2();
724 }
725
726 const double nodal_front_length = adj_edges_length / 2.;
727 if (nodal_front_length <= 0.) {
729 "Front node has zero adjacent front edge length");
730 }
731
732 double griffith_energy = t_node_force.l2() / nodal_front_length;
733 CHK_MOAB_THROW(mField.get_moab().tag_set_data(tags[griffith_force_tag],
734 &n, 1, &griffith_energy),
735 "set data");
736 }
737 }
738
740 };
741
742 auto calculate_adjoint_material_force = [&]() {
744
745 if (ts == PETSC_NULLPTR) {
747 "TS is required to calculate adjoint material force");
748 }
749
750 auto topological_tao_ctx = createTopologicalTAOCtx(
751 this, SetIntegrationAtFrontVolume(frontVertices, frontAdjEdges),
752 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges),
753 SmartPetscObj<TS>(ts, true));
754
756 double obj_value = 0;
757 CHKERR evaluateGradient(topological_tao_ctx.get(), &obj_value, g,
758 ObjectiveModelType::HENCKY_MODEL);
759
760 auto set_vertex_exchange_from_gradient = [&]() {
762
763 CHKERR VecZeroEntries(vertexExchange.second);
764 CHKERR VecGhostUpdateBegin(vertexExchange.second, INSERT_VALUES,
765 SCATTER_FORWARD);
766 CHKERR VecGhostUpdateEnd(vertexExchange.second, INSERT_VALUES,
767 SCATTER_FORWARD);
768
769 auto *problem_ptr = getProblemPtr(dmMaterial);
770 auto &dofs =
771 problem_ptr->getNumeredRowDofsPtr()->get<Unique_mi_tag>();
772 const auto field_bit = mField.get_field_bit_number(materialH1Positions);
773
774 double *g_array;
775 double *exchange_array;
776 CHKERR VecGetArray(g, &g_array);
777 CHKERR VecGetArray(vertexExchange.second, &exchange_array);
778
779 auto ptr = exchange_array; // vector values are arranged as entries, That
780 // is key idea behind vertexExchange vector.
781 for (auto v : vertexExchange.first.first) {
782 std::array<double, SPACE_DIM> values = {0., 0., 0.};
783 auto lo =
784 dofs.lower_bound(DofEntity::getLoFieldEntityUId(field_bit, v));
785 auto hi =
786 dofs.upper_bound(DofEntity::getHiFieldEntityUId(field_bit, v));
787 for (; lo != hi; ++lo) {
788 if (!(*lo)->getHasLocalIndex())
789 continue;
790 const auto coeff = (*lo)->getDofCoeffIdx();
791 if (coeff < SPACE_DIM)
792 values[coeff] = g_array[(*lo)->getPetscLocalDofIdx()];
793 }
794 for (int d = 0; d != SPACE_DIM; ++d, ++ptr) {
795 *ptr = values[d];
796 }
797 }
798
799 CHKERR VecRestoreArray(vertexExchange.second, &exchange_array);
800 CHKERR VecRestoreArray(g, &g_array);
801
802 if (adjoint_gradient_vector != nullptr) {
803 (*adjoint_gradient_vector) = g;
804 }
805
807 };
808
809 CHKERR set_vertex_exchange_from_gradient();
810
811 CHKERR CommInterface::setTagFromVector(
813 tags[ExhangeTags::ADJOINT_MATERIALFORCE]);
814 CHKERR CommInterface::updateEntitiesPetscVector(
816 tags[ExhangeTags::ADJOINT_MATERIALFORCE]);
817
819 };
820
821 auto print_results = [&](auto nb_J_integral_conturs, bool print_material,
822 bool print_adjoint) {
824
825 if (!print_material && !print_adjoint) {
827 }
828
829 auto get_conn_range = [&](auto e) {
830 Range conn;
831 CHK_MOAB_THROW(mField.get_moab().get_connectivity(e, conn, true),
832 "get connectivity");
833 return conn;
834 };
835
836 auto get_tag_data = [&](auto &ents, auto tag, auto dim) {
837 std::vector<double> data(ents.size() * dim);
838 CHK_MOAB_THROW(mField.get_moab().tag_get_data(tag, ents, data.data()),
839 "get data");
840 return data;
841 };
842
843 if (mField.get_comm_rank() == 0) {
844 auto at_nodes = [&]() {
846 auto conn = get_conn_range(*frontEdges);
847 std::vector<double> material_force;
848 std::vector<double> adjoint_material_force;
849 auto area_growth = get_tag_data(conn, tags[ExhangeTags::AREAGROWTH], 3);
850 std::vector<double> griffith_force;
851 std::vector<double> adjoint_griffith_force;
852 if (print_material) {
853 material_force =
854 get_tag_data(conn, tags[ExhangeTags::MATERIALFORCE], 3);
855 griffith_force =
856 get_tag_data(conn, tags[ExhangeTags::GRIFFITHFORCE], 1);
857 }
858 if (print_adjoint) {
859 adjoint_material_force =
860 get_tag_data(conn, tags[ExhangeTags::ADJOINT_MATERIALFORCE], 3);
861 adjoint_griffith_force =
862 get_tag_data(conn, tags[ExhangeTags::ADJOINT_GRIFFITHFORCE], 1);
863 }
864 std::vector<double> coords(conn.size() * 3);
865 CHK_MOAB_THROW(mField.get_moab().get_coords(conn, coords.data()),
866 "get coords");
867 MOFEM_LOG("EPSELF", Sev::inform) << "Force results at nodes";
868 MOFEM_LOG("EPSELF", Sev::inform)
869 << std::left << std::setw(10) << "kind" << std::right
870 << std::setw(9) << "node" << std::setw(18) << "coord_x"
871 << std::setw(18) << "coord_y" << std::setw(18) << "coord_z"
872 << std::setw(18) << "force_x" << std::setw(18) << "force_y"
873 << std::setw(18) << "force_z" << std::setw(18) << "area_x"
874 << std::setw(18) << "area_y" << std::setw(18) << "area_z"
875 << std::setw(18) << "griffith" << std::setw(10) << "contour";
876
877 auto print_row = [&](const char *kind, const auto &force,
878 const auto &griffith, const size_t i) {
879 MOFEM_LOG("EPSELF", Sev::inform)
880 << std::left << std::setw(10) << kind << std::right
881 << std::setw(9) << conn[i] << std::scientific
882 << std::setprecision(10) << std::setw(18) << coords[i * 3 + 0]
883 << std::setw(18) << coords[i * 3 + 1] << std::setw(18)
884 << coords[i * 3 + 2] << std::setw(18) << force[i * 3 + 0]
885 << std::setw(18) << force[i * 3 + 1] << std::setw(18)
886 << force[i * 3 + 2] << std::setw(18) << area_growth[i * 3 + 0]
887 << std::setw(18) << area_growth[i * 3 + 1] << std::setw(18)
888 << area_growth[i * 3 + 2] << std::setw(18) << griffith[i]
889 << std::defaultfloat << std::setprecision(6) << std::setw(10)
890 << nb_J_integral_conturs;
891 };
892
893 for (size_t i = 0; i < conn.size(); ++i) {
894 if (print_material) {
895 print_row("material", material_force, griffith_force, i);
896 }
897 if (print_adjoint) {
898 print_row("adjoint", adjoint_material_force, adjoint_griffith_force,
899 i);
900 }
901 }
902
904 };
905
906 at_nodes();
907 }
909 };
910
911 CHKERR calculate_material_forces();
912
913 PetscBool all_contours = PETSC_FALSE;
914 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "",
915 "-calculate_J_integral_all_levels", &all_contours,
916 PETSC_NULLPTR); // for backward compatibility
918 PETSC_NULLPTR, "", "-calculate_J_integral_all_contours", &all_contours,
919 PETSC_NULLPTR); // new name
920
921 if (all_contours == PETSC_TRUE) {
922 for (int l = 0; l < nbJIntegralContours; ++l) {
923 CHKERR calculate_force_through_node(l);
924 CHKERR average_material_force_at_edge(tags[ExhangeTags::MATERIALFORCE]);
925 CHKERR calculate_crack_area_growth_face(l);
926 CHKERR calculate_crack_area_growth_no_face(l, ExhangeTags::MATERIALFORCE);
927 CHKERR update_crack_area_growth_edges();
928 CHKERR calculate_griffith_force(ExhangeTags::MATERIALFORCE,
929 ExhangeTags::GRIFFITHFORCE);
930 CHKERR print_results(l, true, false);
931 }
932 }
933
934 PetscBool has_nonzero_ts_solution = PETSC_FALSE;
935
936 if (ts != PETSC_NULLPTR) {
937 Vec ts_solution = PETSC_NULLPTR;
938 CHKERR TSGetSolution(ts, &ts_solution);
939 if (ts_solution != PETSC_NULLPTR) {
940 PetscReal ts_solution_norm = 0.0;
941 CHKERR VecNorm(ts_solution, NORM_2, &ts_solution_norm);
942 has_nonzero_ts_solution =
943 (ts_solution_norm > PETSC_MACHINE_EPSILON) ? PETSC_TRUE : PETSC_FALSE;
944 }
945
946 if (has_nonzero_ts_solution == PETSC_TRUE) {
947 CHKERR calculate_adjoint_material_force();
948 }
949 }
950
951 CHKERR calculate_force_through_node(nbJIntegralContours);
952 CHKERR average_material_force_at_edge(tags[ExhangeTags::MATERIALFORCE]);
953 CHKERR calculate_crack_area_growth_face(nbJIntegralContours);
954 CHKERR calculate_crack_area_growth_no_face(nbJIntegralContours,
955 ExhangeTags::MATERIALFORCE);
956 CHKERR update_crack_area_growth_edges();
957 CHKERR calculate_griffith_force(ExhangeTags::MATERIALFORCE,
958 ExhangeTags::GRIFFITHFORCE);
959 if (has_nonzero_ts_solution == PETSC_TRUE) {
960 CHKERR calculate_griffith_force(ExhangeTags::ADJOINT_MATERIALFORCE,
961 ExhangeTags::ADJOINT_GRIFFITHFORCE);
962 CHKERR calculate_griffith_force_simplified(
963 ExhangeTags::ADJOINT_MATERIALFORCE, ExhangeTags::ADJOINT_GRIFFITHFORCE);
964 }
965 CHKERR print_results(nbJIntegralContours, true, true);
966
968}
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
#define FTENSOR_INDEXES(DIM,...)
Kronecker Delta class.
Tensor1< T, Tensor_Dim > normalize()
#define NOT_USED(x)
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
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
boost::shared_ptr< TopologicalTAOCtx > createTopologicalTAOCtx(EshelbianCore *ep, ForcesAndSourcesCore::GaussHookFun set_integration_at_interior, ForcesAndSourcesCore::GaussHookFun set_integration_at_face, SmartPetscObj< TS > time_solver)
MoFEMErrorCode evaluateGradient(TopologicalTAOCtx *ctx_ptr, double *f, Vec g, ObjectiveModelType eval_energy_model)
void pushOpCalculateStretchFromStress(OpVector &op_vector, boost::shared_ptr< PhysicalEquations > physics_ptr, boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< ExternalStrainVec > external_strain_vec_ptr, const std::map< std::string, boost::shared_ptr< ScalingMethod > > &smv, boost::shared_ptr< MatrixDouble > strain_ptr=nullptr)
Push pointwise external-pressure evaluation before stress recovery.
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
auto getProblemPtr(DM dm)
get problem pointer from DM
Definition DMMoFEM.hpp:1182
constexpr IntegrationType I
constexpr double g
boost::shared_ptr< ExternalStrainVec > externalStrainVecPtr
boost::shared_ptr< Range > frontAdjEdges
std::map< std::string, boost::shared_ptr< ScalingMethod > > timeScaleMap
static int nbJIntegralContours
static double griffithEnergy
Griffith energy.
CommInterface::EntitiesPetscVector vertexExchange
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
virtual FieldBitNumber get_field_bit_number(const std::string name) const =0
get field bit number

◆ 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 970 of file EshelbianFracture.cpp.

971 {
973
974 constexpr bool debug = false;
975 (void)debug;
976 constexpr auto sev = Sev::verbose;
977
978 Range body_ents;
979 CHKERR mField.get_moab().get_entities_by_dimension(0, 3, body_ents);
980 auto body_skin = get_skin(mField, body_ents);
981 Range body_skin_edges;
982 CHKERR mField.get_moab().get_adjacencies(body_skin, 1, false, body_skin_edges,
983 moab::Interface::UNION);
984 Range boundary_skin_verts;
985 CHKERR mField.get_moab().get_connectivity(body_skin_edges,
986 boundary_skin_verts, true);
987
988 auto geometry_edges = get_range_from_block(mField, "EDGES", 1);
989 Range geometry_edges_verts;
990 CHKERR mField.get_moab().get_connectivity(geometry_edges,
991 geometry_edges_verts, true);
992 Range crack_faces_verts;
993 CHKERR mField.get_moab().get_connectivity(*crackFaces, crack_faces_verts,
994 true);
995 Range crack_faces_edges;
996 CHKERR mField.get_moab().get_adjacencies(
997 *crackFaces, 1, true, crack_faces_edges, moab::Interface::UNION);
998 Range crack_faces_tets;
999 CHKERR mField.get_moab().get_adjacencies(
1000 *crackFaces, 3, true, crack_faces_tets, moab::Interface::UNION);
1001
1002 Range front_verts;
1003 CHKERR mField.get_moab().get_connectivity(*frontEdges, front_verts, true);
1004 Range front_faces;
1005 CHKERR mField.get_moab().get_adjacencies(*frontEdges, 2, true, front_faces,
1006 moab::Interface::UNION);
1007 Range front_verts_edges;
1008 CHKERR mField.get_moab().get_adjacencies(
1009 front_verts, 1, true, front_verts_edges, moab::Interface::UNION);
1010
1011 auto get_tags_vec = [&](auto tag_name, int dim) {
1012 std::vector<Tag> tags(1);
1013
1014 if (dim > 3)
1016
1017 auto create_and_clean = [&]() {
1019 auto &moab = mField.get_moab();
1020 auto rval = moab.tag_get_handle(tag_name, tags[0]);
1021 if (rval == MB_SUCCESS) {
1022 moab.tag_delete(tags[0]);
1023 }
1024 double def_val[] = {0., 0., 0.};
1025 CHKERR moab.tag_get_handle(tag_name, dim, MB_TYPE_DOUBLE, tags[0],
1026 MB_TAG_CREAT | MB_TAG_SPARSE, def_val);
1028 };
1029
1030 CHK_THROW_MESSAGE(create_and_clean(), "create_and_clean");
1031
1032 return tags;
1033 };
1034
1035 auto get_adj_front = [&](bool subtract_crack) {
1036 Range adj_front;
1037 CHKERR mField.get_moab().get_adjacencies(*frontEdges, SPACE_DIM - 1, true,
1038 adj_front, moab::Interface::UNION);
1039 if (subtract_crack)
1040 adj_front = subtract(adj_front, *crackFaces);
1041 return adj_front;
1042 };
1043
1044 MOFEM_LOG_CHANNEL("SELF");
1045
1046 auto th_front_position = get_tags_vec("FrontPosition", 3);
1047 auto th_max_face_energy = get_tags_vec("MaxFaceEnergy", 1);
1048
1049 if (mField.get_comm_rank() == 0) {
1050
1051 auto get_crack_adj_tets = [&](auto r) {
1052 Range crack_faces_conn;
1053 CHKERR mField.get_moab().get_connectivity(r, crack_faces_conn);
1054 Range crack_faces_conn_tets;
1055 CHKERR mField.get_moab().get_adjacencies(crack_faces_conn, SPACE_DIM,
1056 true, crack_faces_conn_tets,
1057 moab::Interface::UNION);
1058 return crack_faces_conn_tets;
1059 };
1060
1061 auto get_layers_for_sides = [&](auto &side) {
1062 std::vector<Range> layers;
1063 auto get = [&]() {
1065
1066 auto get_adj = [&](auto &r, int dim) {
1067 Range adj;
1068 CHKERR mField.get_moab().get_adjacencies(r, dim, true, adj,
1069 moab::Interface::UNION);
1070 return adj;
1071 };
1072
1073 auto get_tets = [&](auto r) { return get_adj(r, SPACE_DIM); };
1074
1075 Range front_nodes;
1076 CHKERR mField.get_moab().get_connectivity(*frontEdges, front_nodes,
1077 true);
1078 Range front_faces = get_adj(front_nodes, 2);
1079 front_faces = subtract(front_faces, *crackFaces);
1080 auto front_tets = get_tets(front_nodes);
1081 auto front_side = intersect(side, front_tets);
1082 layers.push_back(front_side);
1083 for (;;) {
1084 auto adj_faces = get_skin(mField, layers.back());
1085 adj_faces = intersect(adj_faces, front_faces);
1086 auto adj_faces_tets = get_tets(adj_faces);
1087 adj_faces_tets = intersect(adj_faces_tets, front_tets);
1088 layers.push_back(unite(layers.back(), adj_faces_tets));
1089 if (layers.back().size() == layers[layers.size() - 2].size()) {
1090 break;
1091 }
1092 }
1094 };
1095 CHK_THROW_MESSAGE(get(), "get_layers_for_sides");
1096 return layers;
1097 };
1098
1100 auto layers_top = get_layers_for_sides(sides_pair.first);
1101 auto layers_bottom = get_layers_for_sides(sides_pair.second);
1102
1103#ifndef NDEBUG
1104 if (debug) {
1106 mField.get_moab(),
1107 "crack_tets_" +
1108 boost::lexical_cast<std::string>(mField.get_comm_rank()) + ".vtk",
1109 get_crack_adj_tets(*crackFaces));
1110 CHKERR save_range(mField.get_moab(), "sides_first.vtk", sides_pair.first);
1111 CHKERR save_range(mField.get_moab(), "sides_second.vtk",
1112 sides_pair.second);
1113 MOFEM_LOG("EP", sev) << "Nb. layers " << layers_top.size();
1114 int l = 0;
1115 for (auto &r : layers_top) {
1116 MOFEM_LOG("EP", sev) << "Layer " << l << " size " << r.size();
1118 mField.get_moab(),
1119 "layers_top_" + boost::lexical_cast<std::string>(l) + ".vtk", r);
1120 ++l;
1121 }
1122
1123 l = 0;
1124 for (auto &r : layers_bottom) {
1125 MOFEM_LOG("EP", sev) << "Layer " << l << " size " << r.size();
1127 mField.get_moab(),
1128 "layers_bottom_" + boost::lexical_cast<std::string>(l) + ".vtk", r);
1129 ++l;
1130 }
1131 }
1132#endif
1133
1134 auto get_cross = [&](auto t_dir, auto f) {
1136 CHKERR mField.getInterface<Tools>()->getTriNormal(f, &t_normal(0));
1137 t_normal.normalize();
1142 t_cross(i) = FTensor::levi_civita(i, j, k) * t_normal(j) * t_dir(k);
1143 return t_cross;
1144 };
1145
1146 auto get_sense = [&](auto f, auto e) {
1147 int side, sense, offset;
1148 CHK_MOAB_THROW(mField.get_moab().side_number(f, e, side, sense, offset),
1149 "get sense");
1150 return std::make_tuple(side, sense, offset);
1151 };
1152
1153 auto calculate_edge_direction = [&](auto e, auto normalize = true) {
1154 const EntityHandle *conn;
1155 int num_nodes;
1156 CHKERR mField.get_moab().get_connectivity(e, conn, num_nodes, true);
1157 std::array<double, 6> coords;
1158 CHKERR mField.get_moab().get_coords(conn, num_nodes, coords.data());
1160 &coords[0], &coords[1], &coords[2]};
1162 &coords[3], &coords[4], &coords[5]};
1165 t_dir(i) = t_p1(i) - t_p0(i);
1166 if (normalize)
1167 t_dir.normalize();
1168 return t_dir;
1169 };
1170
1171 auto evaluate_face_energy_and_set_orientation = [&](auto front_edges,
1172 auto front_faces,
1173 auto &sides_pair,
1174 auto th_position) {
1176
1177 Tag th_face_energy;
1178 Tag th_material_force;
1179 switch (energyReleaseSelector) {
1180 case GRIFFITH_FORCE:
1181 case GRIFFITH_SKELETON:
1182 CHKERR mField.get_moab().tag_get_handle("GriffithForce",
1183 th_face_energy);
1184 // CHKERR mField.get_moab().tag_get_handle("MaterialForce",
1185 // th_material_force);
1186 CHKERR mField.get_moab().tag_get_handle("MaterialForce",
1187 th_material_force);
1188
1189 break;
1190 default:
1191 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
1192 "Unknown energy release selector");
1193 };
1194
1195 /**
1196 * Iterate over front edges, get adjacent faces, find maximal face energy.
1197 * Maximal face energy is stored in the edge. Maximal face energy is
1198 * magnitude of edge Griffith force.
1199 */
1200 auto find_maximal_face_energy = [&](auto front_edges, auto front_faces,
1201 auto &edge_face_max_energy_map) {
1203
1204 Range body_ents;
1205 CHKERR mField.get_moab().get_entities_by_dimension(0, 3, body_ents);
1206 auto body_skin = get_skin(mField, body_ents);
1207
1208 Range max_faces;
1209
1210 for (auto e : front_edges) {
1211
1212 double griffith_force;
1213 CHKERR mField.get_moab().tag_get_data(th_face_energy, &e, 1,
1214 &griffith_force);
1215
1216 Range faces;
1217 CHKERR mField.get_moab().get_adjacencies(&e, 1, 2, false, faces);
1218 faces = subtract(intersect(faces, front_faces), body_skin);
1219 std::vector<double> face_energy(faces.size());
1220 CHKERR mField.get_moab().tag_get_data(th_face_energy, faces,
1221 face_energy.data());
1222 auto max_energy_it =
1223 std::max_element(face_energy.begin(), face_energy.end());
1224 double max_energy =
1225 max_energy_it != face_energy.end() ? *max_energy_it : 0;
1226
1227 edge_face_max_energy_map[e] =
1228 std::make_tuple(faces[max_energy_it - face_energy.begin()],
1229 griffith_force, static_cast<double>(0));
1230 MOFEM_LOG("EP", Sev::inform)
1231 << "Edge " << e << " griffith force " << griffith_force
1232 << " max face energy " << max_energy << " factor "
1233 << max_energy / griffith_force;
1234
1235 max_faces.insert(faces[max_energy_it - face_energy.begin()]);
1236 }
1237
1238#ifndef NDEBUG
1239 if (debug) {
1241 mField.get_moab(),
1242 "max_faces_" +
1243 boost::lexical_cast<std::string>(mField.get_comm_rank()) +
1244 ".vtk",
1245 max_faces);
1246 }
1247#endif
1248
1250 };
1251
1252 /**
1253 * For each front edge, find maximal face energy and orientation. This is
1254 * by finding angle between edge material force and maximal face normal
1255 *
1256 */
1257 auto calculate_face_orientation = [&](auto &edge_face_max_energy_map) {
1259
1260 auto up_down_face = [&](
1261
1262 auto &face_angle_map_up,
1263 auto &face_angle_map_down
1264
1265 ) {
1267
1268 for (auto &m : edge_face_max_energy_map) {
1269 auto e = m.first;
1270 auto [max_face, energy, opt_angle] = m.second;
1271
1272 Range faces;
1273 CHKERR mField.get_moab().get_adjacencies(&e, 1, 2, false, faces);
1274 faces = intersect(faces, front_faces);
1275 Range adj_tets; // tetrahedrons adjacent to the face
1276 CHKERR mField.get_moab().get_adjacencies(&max_face, 1, SPACE_DIM,
1277 false, adj_tets,
1278 moab::Interface::UNION);
1279 if (adj_tets.size()) {
1280
1281 Range adj_tets; // tetrahedrons adjacent to the face
1282 CHKERR mField.get_moab().get_adjacencies(&max_face, 1, SPACE_DIM,
1283 false, adj_tets,
1284 moab::Interface::UNION);
1285 if (adj_tets.size()) {
1286
1287 Range adj_tets_faces;
1288 // get faces
1289 CHKERR mField.get_moab().get_adjacencies(
1290 adj_tets, SPACE_DIM - 1, false, adj_tets_faces,
1291 moab::Interface::UNION);
1292 adj_tets_faces = intersect(adj_tets_faces, faces);
1294
1295 // cross product of face normal and edge direction
1296 auto t_cross_max =
1297 get_cross(calculate_edge_direction(e, true), max_face);
1298 auto [side_max, sense_max, offset_max] = get_sense(max_face, e);
1299 t_cross_max(i) *= sense_max;
1300
1301 for (auto t : adj_tets) {
1302 Range adj_tets_faces;
1303 CHKERR mField.get_moab().get_adjacencies(
1304 &t, 1, SPACE_DIM - 1, false, adj_tets_faces);
1305 adj_tets_faces = intersect(adj_tets_faces, faces);
1306 adj_tets_faces =
1307 subtract(adj_tets_faces, Range(max_face, max_face));
1308
1309 if (adj_tets_faces.size() == 1) {
1310
1311 // cross product of adjacent face normal and edge
1312 // direction
1313 auto t_cross = get_cross(calculate_edge_direction(e, true),
1314 adj_tets_faces[0]);
1315 auto [side, sense, offset] =
1316 get_sense(adj_tets_faces[0], e);
1317 t_cross(i) *= sense;
1318 double dot = t_cross(i) * t_cross_max(i);
1319 auto angle = std::acos(dot);
1320
1321 double face_energy;
1322 CHKERR mField.get_moab().tag_get_data(
1323 th_face_energy, adj_tets_faces, &face_energy);
1324
1325 auto [side_face, sense_face, offset_face] =
1326 get_sense(t, max_face);
1327
1328 if (sense_face > 0) {
1329 face_angle_map_up[e] = std::make_tuple(face_energy, angle,
1330 adj_tets_faces[0]);
1331
1332 } else {
1333 face_angle_map_down[e] = std::make_tuple(
1334 face_energy, -angle, adj_tets_faces[0]);
1335 }
1336 }
1337 }
1338 }
1339 }
1340 }
1341
1343 };
1344
1345 auto calc_optimal_angle = [&](
1346
1347 auto &face_angle_map_up,
1348 auto &face_angle_map_down
1349
1350 ) {
1352
1353 for (auto &m : edge_face_max_energy_map) {
1354 auto e = m.first;
1355 auto &[max_face, e0, a0] = m.second;
1356
1357 if (std::abs(e0) > std::numeric_limits<double>::epsilon()) {
1358
1359 if (face_angle_map_up.find(e) == face_angle_map_up.end() ||
1360 face_angle_map_down.find(e) == face_angle_map_down.end()) {
1361 // Do nothing
1362 } else {
1363
1364 switch (energyReleaseSelector) {
1365 case GRIFFITH_FORCE:
1366 case GRIFFITH_SKELETON: {
1367
1368 Tag th_material_force;
1369 CHKERR mField.get_moab().tag_get_handle("MaterialForce",
1370 th_material_force);
1371 FTensor::Tensor1<double, SPACE_DIM> t_material_force;
1372 CHKERR mField.get_moab().tag_get_data(
1373 th_material_force, &e, 1, &t_material_force(0));
1374 auto material_force_magnitude = t_material_force.l2();
1375 if (material_force_magnitude <
1376 std::numeric_limits<double>::epsilon()) {
1377 a0 = 0;
1378
1379 } else {
1380
1381 auto t_edge_dir = calculate_edge_direction(e, true);
1382 auto t_cross_max = get_cross(t_edge_dir, max_face);
1383 auto [side, sense, offset] = get_sense(max_face, e);
1384 t_cross_max(sense) *= sense;
1385
1389
1390 t_material_force.normalize();
1391 t_cross_max.normalize();
1393 t_cross(I) = FTensor::levi_civita(I, J, K) *
1394 t_material_force(J) * t_cross_max(K);
1395 a0 = -std::asin(t_cross(I) * t_edge_dir(I));
1396
1397 MOFEM_LOG("EP", sev)
1398 << "Optimal angle " << a0 << " energy " << e0;
1399 }
1400 break;
1401 }
1402 default: {
1403
1404 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
1405 "Unknown energy release selector");
1406 }
1407 }
1408 }
1409 }
1410 }
1411
1413 };
1414
1415 std::map<EntityHandle, std::tuple<double, double, EntityHandle>>
1416 face_angle_map_up;
1417 std::map<EntityHandle, std::tuple<double, double, EntityHandle>>
1418 face_angle_map_down;
1419 CHKERR up_down_face(face_angle_map_up, face_angle_map_down);
1420 CHKERR calc_optimal_angle(face_angle_map_up, face_angle_map_down);
1421
1422#ifndef NDEBUG
1423 if (debug) {
1424 auto th_angle = get_tags_vec("Angle", 1);
1425 Range up;
1426 for (auto &m : face_angle_map_up) {
1427 auto [e, a, face] = m.second;
1428 up.insert(face);
1429 CHKERR mField.get_moab().tag_set_data(th_angle[0], &face, 1, &a);
1430 }
1431 Range down;
1432 for (auto &m : face_angle_map_down) {
1433 auto [e, a, face] = m.second;
1434 down.insert(face);
1435 CHKERR mField.get_moab().tag_set_data(th_angle[0], &face, 1, &a);
1436 }
1437
1438 Range max_energy_faces;
1439 for (auto &m : edge_face_max_energy_map) {
1440 auto [face, e, angle] = m.second;
1441 max_energy_faces.insert(face);
1442 CHKERR mField.get_moab().tag_set_data(th_angle[0], &face, 1,
1443 &angle);
1444 }
1445 if (mField.get_comm_rank() == 0) {
1446 CHKERR save_range(mField.get_moab(), "up_faces.vtk", up);
1447 CHKERR save_range(mField.get_moab(), "down_faces.vtk", down);
1448 CHKERR save_range(mField.get_moab(), "max_energy_faces.vtk",
1449 max_energy_faces);
1450 }
1451 }
1452#endif // NDEBUG
1453
1455 };
1456
1457 auto get_conn = [&](auto e) {
1458 Range conn;
1459 CHK_MOAB_THROW(mField.get_moab().get_connectivity(e, conn, true),
1460 "get conn");
1461 return conn;
1462 };
1463
1464 auto get_adj = [&](auto e, auto dim) {
1465 Range adj;
1466 CHK_MOAB_THROW(mField.get_moab().get_adjacencies(
1467 e, dim, false, adj, moab::Interface::UNION),
1468 "get adj");
1469 return adj;
1470 };
1471
1472 auto get_coords = [&](auto v) {
1474 CHK_MOAB_THROW(mField.get_moab().get_coords(v, &t_coords(0)),
1475 "get coords");
1476 return t_coords;
1477 };
1478
1479 // calculate normal of the max energy face
1480 auto get_rotated_normal = [&](auto e, auto f, auto angle) {
1483 auto t_edge_dir = calculate_edge_direction(e, true);
1484 auto [side, sense, offset] = get_sense(f, e);
1485 t_edge_dir(i) *= sense;
1486 t_edge_dir.normalize();
1487 t_edge_dir(i) *= angle;
1488 auto t_R = LieGroups::SO3::exp(t_edge_dir, angle);
1490 mField.getInterface<Tools>()->getTriNormal(f, &t_normal(0));
1491 FTensor::Tensor1<double, SPACE_DIM> t_rotated_normal;
1492 t_rotated_normal(i) = t_R(i, j) * t_normal(j);
1493 return std::make_tuple(t_normal, t_rotated_normal);
1494 };
1495
1496 auto set_coord = [&](auto v, auto &adj_vertex_tets_verts, auto &coords,
1497 auto &t_move, auto gamma) {
1498 auto index = adj_vertex_tets_verts.index(v);
1499 if (index >= 0) {
1500 for (auto ii : {0, 1, 2}) {
1501 coords[3 * index + ii] += gamma * t_move(ii);
1502 }
1503 return true;
1504 }
1505 return false;
1506 };
1507
1508 auto tets_quality = [&](auto quality, auto &adj_vertex_tets_verts,
1509 auto &adj_vertex_tets, auto &coords) {
1510 for (auto t : adj_vertex_tets) {
1511 const EntityHandle *conn;
1512 int num_nodes;
1513 CHKERR mField.get_moab().get_connectivity(t, conn, num_nodes, true);
1514 std::array<double, 12> tet_coords;
1515 for (auto n = 0; n != 4; ++n) {
1516 auto index = adj_vertex_tets_verts.index(conn[n]);
1517 if (index < 0) {
1519 }
1520 for (auto ii = 0; ii != 3; ++ii) {
1521 tet_coords[3 * n + ii] = coords[3 * index + ii];
1522 }
1523 }
1524 double q = Tools::volumeLengthQuality(tet_coords.data());
1525 if (!std::isnormal(q))
1526 q = -2;
1527 quality = std::min(quality, q);
1528 };
1529
1530 return quality;
1531 };
1532
1533 auto calculate_free_face_node_displacement =
1534 [&](auto &edge_face_max_energy_map) {
1535 // get edges adjacent to vertex along which nodes are moving
1536 auto get_vertex_edges = [&](auto vertex) {
1537 Range vertex_edges; // edges adjacent to vertex
1538
1539 auto impl = [&]() {
1541 CHKERR mField.get_moab().get_adjacencies(vertex, 1, false,
1542 vertex_edges);
1543 vertex_edges = subtract(vertex_edges, front_verts_edges);
1544
1545 if (boundary_skin_verts.size() &&
1546 boundary_skin_verts.find(vertex[0]) !=
1547 boundary_skin_verts.end()) {
1548 MOFEM_LOG("EP", sev) << "Boundary vertex";
1549 vertex_edges = intersect(vertex_edges, body_skin_edges);
1550 }
1551 if (geometry_edges_verts.size() &&
1552 geometry_edges_verts.find(vertex[0]) !=
1553 geometry_edges_verts.end()) {
1554 MOFEM_LOG("EP", sev) << "Geometry edge vertex";
1555 vertex_edges = intersect(vertex_edges, geometry_edges);
1556 }
1557 if (crack_faces_verts.size() &&
1558 crack_faces_verts.find(vertex[0]) !=
1559 crack_faces_verts.end()) {
1560 MOFEM_LOG("EP", sev) << "Crack face vertex";
1561 vertex_edges = intersect(vertex_edges, crack_faces_edges);
1562 }
1564 };
1565
1566 CHK_THROW_MESSAGE(impl(), "get_vertex_edges");
1567
1568 return vertex_edges;
1569 };
1570
1571 // vector of rotated faces, edge along node is moved, moved edge,
1572 // moved displacement, quality, cardinality, gamma
1573 using Bundle = std::vector<
1574
1575 std::tuple<EntityHandle, EntityHandle, EntityHandle,
1577
1578 >;
1579 std::map<EntityHandle, Bundle> edge_bundle_map;
1580
1581 for (auto &m : edge_face_max_energy_map) {
1582
1583 auto edge = m.first;
1584 auto &[max_face, energy, opt_angle] = m.second;
1585
1586 // calculate rotation of max energy face
1587 auto [t_normal, t_rotated_normal] =
1588 get_rotated_normal(edge, max_face, opt_angle);
1589
1590 auto front_vertex = get_conn(Range(m.first, m.first));
1591 auto adj_tets = get_adj(Range(max_face, max_face), 3);
1592 auto adj_tets_faces = get_adj(adj_tets, 2);
1593 auto adj_front_faces = subtract(
1594 intersect(get_adj(Range(edge, edge), 2), adj_tets_faces),
1595 *crackFaces);
1596 if (adj_front_faces.size() > 3)
1598 "adj_front_faces.size()>3");
1599
1600 FTensor::Tensor1<double, SPACE_DIM> t_material_force;
1601 CHKERR mField.get_moab().tag_get_data(th_material_force, &edge, 1,
1602 &t_material_force(0));
1603 std::vector<double> griffith_energy(adj_front_faces.size());
1604 CHKERR mField.get_moab().tag_get_data(
1605 th_face_energy, adj_front_faces, griffith_energy.data());
1606
1607 auto set_edge_bundle = [&](auto min_gamma) {
1608 for (auto rotated_f : adj_front_faces) {
1609
1610 double rotated_face_energy =
1611 griffith_energy[adj_front_faces.index(rotated_f)];
1612
1613 auto vertex = subtract(get_conn(Range(rotated_f, rotated_f)),
1614 front_vertex);
1615 if (vertex.size() != 1) {
1617 "Wrong number of vertex to move");
1618 }
1619 auto front_vertex_edges_vertex = get_conn(
1620 intersect(get_adj(front_vertex, 1), crack_faces_edges));
1621 vertex = subtract(
1622 vertex, front_vertex_edges_vertex); // vertex free to move
1623 if (vertex.empty()) {
1624 continue;
1625 }
1626
1627 auto face_cardinality = [&](auto f, auto &seen_front_edges) {
1628 auto whole_front =
1629 unite(*frontEdges,
1630 subtract(body_skin_edges, crack_faces_edges));
1631 auto faces = Range(f, f);
1632 int c = 0;
1633 for (; c < 10; ++c) {
1634 auto front_edges =
1635 subtract(get_adj(faces, 1), seen_front_edges);
1636 if (front_edges.size() == 0) {
1637 return 0;
1638 }
1639 auto front_connected_edges =
1640 intersect(front_edges, whole_front);
1641 if (front_connected_edges.size()) {
1642 seen_front_edges.merge(front_connected_edges);
1643 return c;
1644 }
1645 faces.merge(get_adj(front_edges, 2));
1646 ++c;
1647 }
1648 return c;
1649 };
1650
1651 Range seen_edges = Range(edge, edge);
1652 double rotated_face_cardinality = face_cardinality(
1653 rotated_f,
1654 seen_edges); // add cardinality of max energy
1655 // face to rotated face cardinality
1656 // rotated_face_cardinality +=
1657 // face_cardinality(max_face, seen_edges);
1658 rotated_face_cardinality = std::max(rotated_face_cardinality,
1659 1.); // at least one edge
1660
1661 auto t_vertex_coords = get_coords(vertex);
1662 auto vertex_edges = get_vertex_edges(vertex);
1663
1664 EntityHandle f0 = front_vertex[0];
1665 EntityHandle f1 = front_vertex[1];
1666 FTensor::Tensor1<double, 3> t_v_e0, t_v_e1;
1667 CHKERR mField.get_moab().get_coords(&f0, 1, &t_v_e0(0));
1668 CHKERR mField.get_moab().get_coords(&f1, 1, &t_v_e1(0));
1669
1671 for (auto e_used_to_move_detection : vertex_edges) {
1672 auto edge_conn = get_conn(Range(e_used_to_move_detection,
1673 e_used_to_move_detection));
1674 edge_conn = subtract(edge_conn, vertex);
1675 // Find displacement of the edge such that dot porduct with
1676 // normal is zero.
1677 //
1678 // { (t_v0 - t_vertex_coords) + gamma * (t_v3 -
1679 // t_vertex_coords) } * n = 0
1680 // where t_v0 is the edge vertex, t_v3 is the edge end
1681 // point, n is the rotated normal of the face gamma is the
1682 // factor by which the edge is moved
1684 t_v0(i) = (t_v_e0(i) + t_v_e1(i)) / 2;
1686 CHKERR mField.get_moab().get_coords(edge_conn, &t_v3(0));
1687 auto a =
1688 (t_v0(i) - t_vertex_coords(i)) * t_rotated_normal(i);
1689 auto b =
1690 (t_v3(i) - t_vertex_coords(i)) * t_rotated_normal(i);
1691 auto gamma = a / b;
1692
1693 constexpr double eps =
1694 std::numeric_limits<double>::epsilon();
1695 if (std::isnormal(gamma) && gamma < 1.0 - eps &&
1696 gamma > -0.1) {
1698 t_move(i) = gamma * (t_v3(i) - t_vertex_coords(i));
1699
1700 auto check_rotated_face_directoon = [&]() {
1702 t_delta(i) = t_vertex_coords(i) + t_move(i) - t_v0(i);
1703 t_delta.normalize();
1704 auto dot =
1705 (t_material_force(i) / t_material_force.l2()) *
1706 t_delta(i);
1707 return -dot > 0 ? true : false;
1708 };
1709
1710 if (check_rotated_face_directoon()) {
1711
1712 MOFEM_LOG("EP", Sev::verbose)
1713 << "Crack edge " << edge << " moved face "
1714 << rotated_f
1715 << " edge: " << e_used_to_move_detection
1716 << " face direction/energy " << rotated_face_energy
1717 << " face cardinality " << rotated_face_cardinality
1718 << " gamma: " << gamma;
1719
1720 auto &bundle = edge_bundle_map[edge];
1721 bundle.emplace_back(rotated_f, e_used_to_move_detection,
1722 vertex[0], t_move, 1,
1723 rotated_face_cardinality, gamma);
1724 }
1725 }
1726 }
1727 }
1728 };
1729
1730 set_edge_bundle(std::numeric_limits<double>::epsilon());
1731 if (edge_bundle_map[edge].empty()) {
1732 set_edge_bundle(-1.);
1733 }
1734 }
1735
1736 return edge_bundle_map;
1737 };
1738
1739 auto get_sort_by_energy = [&](auto &edge_face_max_energy_map) {
1740 std::map<double, std::tuple<EntityHandle, EntityHandle, double>>
1741 sort_by_energy;
1742
1743 for (auto &m : edge_face_max_energy_map) {
1744 auto e = m.first;
1745 auto &[max_face, energy, opt_angle] = m.second;
1746 auto abs_energy = std::abs(energy);
1747 sort_by_energy[abs_energy] = std::make_tuple(e, max_face, opt_angle);
1748 }
1749
1750 return sort_by_energy;
1751 };
1752
1753 auto set_tag = [&](auto &&adj_edges_map, auto &&sort_by_energy) {
1755
1756 Tag th_face_pressure;
1758 mField.get_moab().tag_get_handle("FacePressure", th_face_pressure),
1759 "get tag");
1760 auto get_face_pressure = [&](auto face) {
1761 double pressure;
1762 CHK_MOAB_THROW(mField.get_moab().tag_get_data(th_face_pressure, &face,
1763 1, &pressure),
1764 "get rag data");
1765 return pressure;
1766 };
1767
1768 MOFEM_LOG("EPSELF", Sev::inform)
1769 << "Number of edges to check " << sort_by_energy.size();
1770
1771 enum face_energy { POSITIVE, NEGATIVE };
1772 constexpr bool skip_negative = true;
1773
1774 for (auto fe : {face_energy::POSITIVE, face_energy::NEGATIVE}) {
1775
1776 std::vector<double> energies;
1777 double max_pressure = -1;
1778 // check max energies and average all energies along the crack front
1779 // extract max pressure along the crack front
1780 for (auto it = sort_by_energy.rbegin(); it != sort_by_energy.rend();
1781 ++it) {
1782 auto energy = it->first;
1783 auto [max_edge, max_face, opt_angle] = it->second;
1784
1785 auto face_pressure = get_face_pressure(max_face);
1786 energies.push_back(energy);
1787
1788 max_pressure = std::max(max_pressure, face_pressure);
1789 }
1790
1791 double average_energy = 0;
1792 if (!energies.empty()) {
1793 average_energy =
1794 std::accumulate(energies.begin(), energies.end(), 0.) /
1795 energies.size();
1796 }
1797
1798 MOFEM_LOG("EPSELF", Sev::inform)
1799 << "Average energy Griffiths energy of crack front "
1800 << average_energy;
1801
1802 // iterate edges wih maximal energy, and make them seed. Such edges,
1803 // will most likely will have also smallest node displacement
1804 for (auto it = sort_by_energy.rbegin(); it != sort_by_energy.rend();
1805 ++it) {
1806
1807 auto energy = it->first;
1808 auto [max_edge, max_face, opt_angle] = it->second;
1809
1810 auto face_pressure = get_face_pressure(max_face);
1811 if (skip_negative) {
1812 if (fe == face_energy::POSITIVE) {
1813 if (face_pressure <
1814 -(crackingAtol + crackingRtol * std::abs(max_pressure))) {
1815 MOFEM_LOG("EPSELF", Sev::inform)
1816 << "Skip negative face " << max_face << " with energy "
1817 << energy << " and pressure " << face_pressure;
1818 continue;
1819 }
1820 }
1821 }
1822
1823 MOFEM_LOG("EPSELF", Sev::inform)
1824 << "Check face " << max_face << " edge " << max_edge
1825 << " energy " << energy << " optimal angle " << opt_angle
1826 << " face pressure " << face_pressure;
1827
1828 // store energy of max face
1829 if (!average_energy) {
1830 MOFEM_LOG("EPSELF", Sev::warning)
1831 << "Average energy is zero, setting max Griffiths energy to "
1832 "current energy "
1833 << energy;
1834 average_energy = energy;
1835 }
1836 avgGriffithsEnergy = average_energy;
1837 auto jt = adj_edges_map.find(max_edge);
1838 if (jt == adj_edges_map.end()) {
1839 MOFEM_LOG("EPSELF", Sev::warning)
1840 << "Edge " << max_edge << " not found in adj_edges_map";
1841 continue;
1842 }
1843 auto &bundle = jt->second;
1844
1845 auto find_max_in_bundle_impl = [&](auto edge, auto &bundle,
1846 auto gamma) {
1848
1849 EntityHandle vertex_max = 0;
1850 EntityHandle face_max = 0;
1851 EntityHandle move_edge_max = 0;
1852 double max_quality = -2;
1853 double max_quality_evaluated = -2;
1854 double min_cardinality = std::numeric_limits<double>::max();
1855
1856 FTensor::Tensor1<double, SPACE_DIM> t_move_last{0., 0., 0.};
1857
1858 for (auto &b : bundle) {
1859 auto &[face, move_edge, vertex, t_move, quality, cardinality,
1860 edge_gamma] = b;
1861
1862 auto adj_vertex_tets = get_adj(Range(vertex, vertex), 3);
1863 auto adj_vertex_tets_verts = get_conn(adj_vertex_tets);
1864 std::vector<double> coords(3 * adj_vertex_tets_verts.size());
1865 CHK_MOAB_THROW(mField.get_moab().get_coords(
1866 adj_vertex_tets_verts, coords.data()),
1867 "get coords");
1868
1869 set_coord(vertex, adj_vertex_tets_verts, coords, t_move, gamma);
1870 quality = tets_quality(quality, adj_vertex_tets_verts,
1871 adj_vertex_tets, coords);
1872
1873 auto eval_quality = [](auto q, auto c, auto edge_gamma) {
1874 if (q < 0) {
1875 return q;
1876 } else {
1877 return ((edge_gamma < 0) ? (q / 2) : q) / pow(c, 2);
1878 }
1879 };
1880
1881 if (eval_quality(quality, cardinality, edge_gamma) >=
1882 max_quality_evaluated) {
1883 max_quality = quality;
1884 min_cardinality = cardinality;
1885 vertex_max = vertex;
1886 face_max = face;
1887 move_edge_max = move_edge;
1888 t_move_last(i) = t_move(i);
1889 max_quality_evaluated =
1890 eval_quality(max_quality, min_cardinality, edge_gamma);
1891 }
1892 }
1893
1894 return std::make_tuple(vertex_max, face_max, t_move_last,
1895 max_quality, min_cardinality);
1896 };
1897
1898 auto find_max_in_bundle = [&](auto edge, auto &bundle) {
1899 auto b_org_bundle = bundle;
1900 auto r = find_max_in_bundle_impl(edge, bundle, 1.);
1901 auto &[vertex_max, face_max, t_move_last, max_quality,
1902 cardinality] = r;
1903 if (max_quality < 0) {
1904 for (double gamma = 0.95; gamma >= 0.45; gamma -= 0.05) {
1905 bundle = b_org_bundle;
1906 r = find_max_in_bundle_impl(edge, bundle, gamma);
1907 auto &[vertex_max, face_max, t_move_last, max_quality,
1908 cardinality] = r;
1909 MOFEM_LOG("EPSELF", Sev::warning)
1910 << "Back tracking: gamma " << gamma << " edge " << edge
1911 << " quality " << max_quality << " cardinality "
1912 << cardinality;
1913 if (max_quality > 0.01) {
1915 t_move_last(I) *= gamma;
1916 return r;
1917 }
1918 }
1920 t_move_last(I) = 0;
1921 }
1922 return r;
1923 };
1924
1925 // set tags with displacement of node and face energy
1926 auto set_tag_to_vertex_and_face = [&](auto &&r, auto &quality) {
1928 auto &[v, f, t_move, q, cardinality] = r;
1929
1930 if ((q > 0 && std::isnormal(q)) && energy > 0) {
1931
1932 MOFEM_LOG("EPSELF", Sev::inform)
1933 << "Set tag: vertex " << v << " face " << f << " "
1934 << max_edge << " move " << t_move << " energy " << energy
1935 << " quality " << q << " cardinality " << cardinality;
1936 CHKERR mField.get_moab().tag_set_data(th_position[0], &v, 1,
1937 &t_move(0));
1938 CHKERR mField.get_moab().tag_set_data(th_max_face_energy[0], &f,
1939 1, &energy);
1940 }
1941
1942 quality = q;
1944 };
1945
1946 double quality = -2;
1947 CHKERR set_tag_to_vertex_and_face(
1948
1949 find_max_in_bundle(max_edge, bundle),
1950
1951 quality
1952
1953 );
1954
1955 if (quality > 0 && std::isnormal(quality) && energy > 0) {
1956 MOFEM_LOG("EPSELF", Sev::inform)
1957 << "Crack face set with quality: " << quality;
1959 }
1960 }
1961
1962 if (!skip_negative)
1963 break;
1964 }
1965
1967 };
1968
1969 // map: {edge, {face, energy, optimal_angle}}
1970 MOFEM_LOG("EP", sev) << "Calculate orientation";
1971 std::map<EntityHandle, std::tuple<EntityHandle, double, double>>
1972 edge_face_max_energy_map;
1973 CHKERR find_maximal_face_energy(front_edges, front_faces,
1974 edge_face_max_energy_map);
1975 CHKERR calculate_face_orientation(edge_face_max_energy_map);
1976
1977 MOFEM_LOG("EP", sev) << "Calculate node positions";
1978 CHKERR set_tag(
1979
1980 calculate_free_face_node_displacement(edge_face_max_energy_map),
1981 get_sort_by_energy(edge_face_max_energy_map)
1982
1983 );
1984
1986 };
1987
1988 auto get_max_griffith_force = [&](auto r) {
1989 auto &moab = mField.get_moab();
1990 std::vector<double> gc(r.size());
1991 Tag th_gc;
1992 CHKERR moab.tag_get_handle("GriffithForce", th_gc);
1993 CHKERR moab.tag_get_data(th_gc, r, gc.data());
1994 double max_griffith_force = 0;
1995 for (size_t i = 0; i < r.size(); ++i) {
1996 max_griffith_force = std::max(max_griffith_force, std::abs(gc[i]));
1997 }
1998 return max_griffith_force;
1999 };
2000
2001 MOFEM_LOG("EP", sev) << "Front edges " << frontEdges->size();
2002 if (std::abs(get_max_griffith_force(get_adj_front(true))) >
2003 std::numeric_limits<double>::epsilon()) {
2004 CHKERR evaluate_face_energy_and_set_orientation(
2005 *frontEdges, get_adj_front(true), sides_pair, th_front_position);
2006 } else {
2007 auto adj_front = get_adj_front(true);
2008 double zero[] = {0., 0., 0.};
2009 CHKERR mField.get_moab().tag_clear_data(th_front_position[0], adj_front,
2010 zero);
2011 }
2012 }
2013
2014 // exchange positions and energies from processor zero to all other
2015 CHKERR VecZeroEntries(vertexExchange.second);
2016 CHKERR VecGhostUpdateBegin(vertexExchange.second, INSERT_VALUES,
2017 SCATTER_FORWARD);
2018 CHKERR VecGhostUpdateEnd(vertexExchange.second, INSERT_VALUES,
2019 SCATTER_FORWARD);
2020 CHKERR mField.getInterface<CommInterface>()->updateEntitiesPetscVector(
2021 mField.get_moab(), vertexExchange, th_front_position[0]);
2022 CHKERR VecZeroEntries(faceExchange.second);
2023 CHKERR VecGhostUpdateBegin(faceExchange.second, INSERT_VALUES,
2024 SCATTER_FORWARD);
2025 CHKERR VecGhostUpdateEnd(faceExchange.second, INSERT_VALUES, SCATTER_FORWARD);
2026 CHKERR mField.getInterface<CommInterface>()->updateEntitiesPetscVector(
2027 mField.get_moab(), faceExchange, th_max_face_energy[0]);
2028
2029 auto get_max_moved_faces = [&]() {
2030 Range max_moved_faces;
2031 auto adj_front = get_adj_front(false);
2032 std::vector<double> face_energy(adj_front.size());
2033 CHKERR mField.get_moab().tag_get_data(th_max_face_energy[0], adj_front,
2034 face_energy.data());
2035 for (int i = 0; i != adj_front.size(); ++i) {
2036 if (face_energy[i] > std::numeric_limits<double>::epsilon()) {
2037 max_moved_faces.insert(adj_front[i]);
2038 }
2039 }
2040
2041 return boost::make_shared<Range>(max_moved_faces);
2042 };
2043
2044 // move all faces with energy larger than 0
2045 maxMovedFaces = get_max_moved_faces();
2046 MOFEM_LOG("EP", sev) << "Number of of moved faces: " << maxMovedFaces->size();
2047
2048#ifndef NDEBUG
2049 if (debug) {
2051 mField.get_moab(),
2052 "max_moved_faces_" +
2053 boost::lexical_cast<std::string>(mField.get_comm_rank()) + ".vtk",
2054 *maxMovedFaces);
2055 }
2056#endif
2057
2059}
static auto get_two_sides_of_crack_surface(MoFEM::Interface &m_field, Range crack_faces)
constexpr double a
static const double eps
@ MOFEM_ATOM_TEST_INVALID
Definition definitions.h:40
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
constexpr double a0
const double c
speed of light (cm/ns)
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
FTensor::Index< 'm', 3 > m
static double crackingAtol
Cracking absolute tolerance.
static double crackingRtol
Cracking relative tolerance.
double avgGriffithsEnergy
static enum EnergyReleaseSelector energyReleaseSelector
static auto exp(A &&t_w_vee, B &&theta)
Definition Lie.hpp:69

◆ createCrackSurfaceMeshset()

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

Definition at line 2853 of file EshelbianFracture.cpp.

2853 {
2855 auto meshset_mng = mField.getInterface<MeshsetsManager>();
2856 while (meshset_mng->checkMeshset(addCrackMeshsetId, BLOCKSET))
2858 MOFEM_LOG("EP", Sev::inform)
2859 << "Crack added surface meshset " << addCrackMeshsetId;
2860 CHKERR meshset_mng->addMeshset(BLOCKSET, addCrackMeshsetId, "CRACK_COMPUTED");
2862};

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

5852 {
5854
5855 auto print_loc_size = [this](auto v, auto str, auto sev) {
5857 int size;
5858 CHKERR VecGetLocalSize(v.second, &size);
5859 int low, high;
5860 CHKERR VecGetOwnershipRange(v.second, &low, &high);
5861 MOFEM_LOG("EPSYNC", sev) << str << " local size " << size << " ( " << low
5862 << " " << high << " ) ";
5865 };
5866
5868 mField.get_comm(), mField.get_moab(), 3, 1, sev);
5869 CHKERR print_loc_size(volumeExchange, "volumeExchange", sev);
5871 mField.get_comm(), mField.get_moab(), 2, 1, Sev::inform);
5872 CHKERR print_loc_size(faceExchange, "faceExchange", sev);
5874 mField.get_comm(), mField.get_moab(), 1, 1, Sev::inform);
5875 CHKERR print_loc_size(edgeExchange, "edgeExchange", sev);
5877 mField.get_comm(), mField.get_moab(), 0, 3, Sev::inform);
5878 CHKERR print_loc_size(vertexExchange, "vertexExchange", sev);
5879
5881}
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  )
inlinestatic

◆ d_f_log_e()

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

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

150 {
151 if (v > v_max) {
152 double e = static_cast<double>(std::exp(v_max));
153 double dv = v - v_max;
154 return e * dv + e;
155 } else {
156 return static_cast<double>(std::exp(v));
157 }
158 }
static constexpr double v_max

◆ dd_f_linear()

static double EshelbianCore::dd_f_linear ( const double  )
inlinestatic

◆ dd_f_log_e()

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

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

160 {
161 if (v > v_max) {
162 return static_cast<double>(std::exp(v_max));
163 } else {
164 return static_cast<double>(std::exp(v));
165 }
166 }

◆ f_linear()

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

◆ f_log_e()

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

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

140 {
141 if (v > v_max) {
142 double e = static_cast<double>(std::exp(v_max));
143 double dv = v - v_max;
144 return 0.5 * e * dv * dv + e * dv + e;
145 } else {
146 return static_cast<double>(std::exp(v));
147 }
148 }

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

350 {
352 for (auto it :
353 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
354
355 (boost::format("%s(.*)") % block_name).str()
356
357 ))
358
359 ) {
360 std::vector<double> block_attributes;
361 CHKERR it->getAttributes(block_attributes);
362 if (block_attributes.size() < static_cast<size_t>(nb_attributes)) {
363 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
364 "In block %s expected %d attributes, but given %ld",
365 it->getName().c_str(), nb_attributes, block_attributes.size());
366 }
367 Range faces;
368 CHKERR it->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2, faces,
369 true);
370 bc_vec_ptr->emplace_back(
371 it->getName(), block_attributes, faces,
372 getStringArgumentFromJsonBlockset(block_name, it->getMeshsetId(),
373 "load_history"));
374 }
376 }
std::string getStringArgumentFromJsonBlockset(const std::string &type_name, const int meshset_id, const std::string &param_name)
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 5782 of file EshelbianPlasticity.cpp.

5782 {
5784
5785 auto getExternalStrain = [&](boost::shared_ptr<ExternalStrainVec>
5786 &ext_strain_vec_ptr,
5787 const std::string block_name,
5788 const int nb_attributes) {
5790 for (auto it : mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
5791 std::regex((boost::format("(.*)%s(.*)") % block_name).str()))) {
5792 std::vector<double> block_attributes;
5793 const bool analytical_external_strain = std::regex_match(
5794 it->getName(), std::regex("(.*)ANALYTICAL_EXTERNALSTRAIN(.*)"));
5795 const std::string json_block_name =
5796 analytical_external_strain ? "ANALYTICAL_EXTERNALSTRAIN" : block_name;
5797
5798 CHKERR it->getAttributes(block_attributes);
5799
5800 if (block_attributes.size() < nb_attributes) {
5801 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
5802 "In block %s expected %d attributes, but given %ld",
5803 it->getName().c_str(), nb_attributes, block_attributes.size());
5804 }
5805
5806 auto get_block_ents = [&]() {
5807 Range ents;
5808 CHKERR mField.get_moab().get_entities_by_handle(it->meshset, ents,
5809 true);
5810 return ents;
5811 };
5812
5813 std::string load_history;
5814 if (!analytical_external_strain) {
5815 load_history = getStringArgumentFromJsonBlockset(
5816 json_block_name, it->getMeshsetId(), "load_history");
5817 }
5818 ext_strain_vec_ptr->emplace_back(it->getName(), block_attributes,
5819 get_block_ents(), load_history);
5820 }
5822 };
5823
5824 externalStrainVecPtr = boost::make_shared<ExternalStrainVec>();
5825
5826 CHKERR getExternalStrain(externalStrainVecPtr, "EXTERNALSTRAIN", 2);
5827
5828 auto ts_pre_stretch = boost::make_shared<DynamicRelaxationTimeScale>(
5829 "externalstrain_history.txt");
5830 for (auto &ext_strain_block : *externalStrainVecPtr) {
5831 MOFEM_LOG("EP", Sev::noisy)
5832 << "Add time scaling external strain: " << ext_strain_block.blockName;
5833 if (!ext_strain_block.loadHistoryFile.empty()) {
5834 MOFEM_LOG("EP", Sev::inform)
5835 << "External strain load history from JSON for "
5836 << ext_strain_block.blockName << ": "
5837 << ext_strain_block.loadHistoryFile;
5838 timeScaleMap[ext_strain_block.blockName] =
5839 boost::make_shared<DynamicRelaxationTimeScale>(
5840 ext_strain_block.loadHistoryFile);
5841 } else {
5842 timeScaleMap[ext_strain_block.blockName] =
5844 ts_pre_stretch, "externalstrain_history", ".txt",
5845 ext_strain_block.blockName);
5846 }
5847 }
5848
5850}
analytical_external_strain(delta_t, t, x, y, z, block_name)
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 947 of file EshelbianPlasticity.cpp.

947 {
949 const char *list_rots[] = {"small", "moderate", "large", "no_h1"};
950 const char *list_release[] = {"griffith_force", "griffith_skeleton"};
951 const char *list_stretches[] = {"linear", "log", "log_quadratic"};
952 const char *list_broken_hdiv_bases[] = {"demkowicz", "ainsworth"};
953 PetscInt choice_rot = EshelbianCore::rotSelector;
954 PetscInt choice_grad = EshelbianCore::gradApproximator;
955 PetscInt choice_release = EshelbianCore::energyReleaseSelector;
956 PetscInt choice_stretch = StretchSelector::LOG;
957 PetscInt choice_solver = SolverType::TimeSolver;
958 PetscInt choice_broken_hdiv_base = 0;
959 PetscBool l2_user_base_scale_set = PETSC_FALSE;
962 choice_broken_hdiv_base = 0;
963 break;
965 choice_broken_hdiv_base = 1;
966 break;
967 default:
968 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
969 "Unsupported broken HDIV base %s",
971 }
972 char analytical_expr_file_name[255] = "analytical_expr.py";
973 PetscBool no_stretch = isNoStretch() ? PETSC_TRUE : PETSC_FALSE;
974
975 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Eshelbian plasticity", "none");
976 CHKERR PetscOptionsInt("-space_order", "approximation oder for space", "",
977 spaceOrder, &spaceOrder, PETSC_NULLPTR);
978 CHKERR PetscOptionsInt("-space_h1_order", "approximation oder for space", "",
979 spaceH1Order, &spaceH1Order, PETSC_NULLPTR);
980 CHKERR PetscOptionsInt("-material_order", "approximation oder for material",
981 "", materialH1Order, &materialH1Order, PETSC_NULLPTR);
982 CHKERR PetscOptionsScalar("-viscosity_alpha_u", "viscosity", "", alphaU,
983 &alphaU, PETSC_NULLPTR);
984 CHKERR PetscOptionsScalar("-viscosity_alpha_w", "viscosity", "", alphaW,
985 &alphaW, PETSC_NULLPTR);
986 CHKERR PetscOptionsScalar("-alpha_omega", "rot H1 penalty", "", alphaOmega,
987 &alphaOmega, PETSC_NULLPTR);
988 CHKERR PetscOptionsScalar("-alpha_omega0", "rot H1 penalty scaled by |M0|",
989 "", alphaOmega0, &alphaOmega0, PETSC_NULLPTR);
990 CHKERR PetscOptionsScalar("-alpha_r", "rot L2 penalty", "", alphaR, &alphaR,
991 PETSC_NULLPTR);
992 CHKERR PetscOptionsScalar("-alpha_r0", "rot L2 penalty scaled by |M0|", "",
993 alphaR0, &alphaR0, PETSC_NULLPTR);
994 CHKERR PetscOptionsScalar("-viscosity_alpha_omega", "rot viscosity", "",
996 PETSC_NULLPTR);
997 CHKERR PetscOptionsScalar("-viscosity_alpha_omega0",
998 "rot viscosity scaled by |M0|", "",
1000 PETSC_NULLPTR);
1001 CHKERR PetscOptionsScalar("-viscosity_alpha_r", "rot L2 viscosity", "",
1002 alphaViscousR, &alphaViscousR, PETSC_NULLPTR);
1003 CHKERR PetscOptionsScalar("-viscosity_alpha_r0",
1004 "rot L2 viscosity scaled by |M0|", "",
1005 alphaViscousR0, &alphaViscousR0, PETSC_NULLPTR);
1006 CHKERR PetscOptionsScalar("-density_alpha_rho", "density", "", alphaRho,
1007 &alphaRho, PETSC_NULLPTR);
1008 CHKERR PetscOptionsScalar("-alpha_tau", "tau", "", alphaTau, &alphaTau,
1009 PETSC_NULLPTR);
1010 CHKERR PetscOptionsScalar("-alpha_tau0", "tau0", "", alphaTau0, &alphaTau0,
1011 PETSC_NULLPTR);
1012 CHKERR PetscOptionsScalar("-alpha_tau_bc_disp", "tau for displacement BC", "",
1013 alphaTauBcDisp, &alphaTauBcDisp, PETSC_NULLPTR);
1014 CHKERR PetscOptionsScalar("-alpha_tau0_bc_disp",
1015 "tau0 for displacement BC", "", alphaTauBcDisp0,
1016 &alphaTauBcDisp0, PETSC_NULLPTR);
1017 CHKERR PetscOptionsEList("-rotations", "rotations", "", list_rots,
1018 LARGE_ROT + 1, list_rots[choice_rot], &choice_rot,
1019 PETSC_NULLPTR);
1020 CHKERR PetscOptionsEList("-grad", "gradient of defamation approximate", "",
1021 list_rots, NO_H1_CONFIGURATION + 1,
1022 list_rots[choice_grad], &choice_grad, PETSC_NULLPTR);
1023
1024 CHKERR PetscOptionsEList("-stretches", "stretches", "", list_stretches,
1025 StretchSelector::STRETCH_SELECTOR_LAST,
1026 list_stretches[choice_stretch], &choice_stretch,
1027 PETSC_NULLPTR);
1028
1029 CHKERR PetscOptionsBool("-no_stretch", "do not solve for stretch", "",
1030 no_stretch, &no_stretch, PETSC_NULLPTR);
1031 CHKERR PetscOptionsBool("-set_singularity", "set singularity", "",
1032 setSingularity, &setSingularity, PETSC_NULLPTR);
1033 CHKERR PetscOptionsBool("-l2_user_base_scale", "streach scale", "",
1035 &l2_user_base_scale_set);
1036 CHKERR PetscOptionsEList(
1037 "-broken_hdiv_base", "broken HDIV stress approximation base", "",
1038 list_broken_hdiv_bases, 2,
1039 list_broken_hdiv_bases[choice_broken_hdiv_base],
1040 &choice_broken_hdiv_base, PETSC_NULLPTR);
1041
1042 // dynamic relaxation
1043
1044 // @deprecate this option
1045 CHKERR PetscOptionsBool("-dynamic_relaxation", "dynamic time relaxation", "",
1046 physicalTimeFlg, &physicalTimeFlg, PETSC_NULLPTR);
1047 CHKERR PetscOptionsEList(
1048 "-solver_type", "solver type", "", EshelbianCore::listSolvers,
1050 EshelbianCore::listSolvers[choice_solver], &choice_solver, PETSC_NULLPTR);
1051
1052 if (choice_solver != SolverType::TimeSolver) {
1053 CHKERR PetscOptionsScalar("-physical_final_time", "physical final time", "",
1055 &EshelbianCore::finalPhysicalTime, PETSC_NULLPTR);
1056 CHKERR PetscOptionsScalar("-physical_delta_time", "physical delta time", "",
1058 PETSC_NULLPTR);
1059 CHKERR PetscOptionsInt("-physical_max_steps", "physical max iterations", "",
1061 PETSC_NULLPTR);
1062 CHKERR PetscOptionsBool(
1063 "-physical_h1_update", "update each physicalsolver step", "",
1065 }
1066
1067 // contact parameters
1068 CHKERR PetscOptionsInt("-contact_max_post_proc_ref_level", "refinement level",
1070 PETSC_NULLPTR);
1071 // cohesive interface
1072 CHKERR PetscOptionsBool("-cohesive_interface_on", "cohesive interface ON", "",
1073 interfaceCrack, &interfaceCrack, PETSC_NULLPTR);
1074 CHKERR PetscOptionsInt(
1075 "-cohesive_interface_remove_level", "cohesive interface remove level", "",
1077
1078 // cracking parameters
1079 CHKERR PetscOptionsBool("-cracking_on", "cracking ON", "", crackingOn,
1080 &crackingOn, PETSC_NULLPTR);
1081 CHKERR PetscOptionsScalar("-cracking_add_time", "cracking add time", "",
1082 crackingAddTime, &crackingAddTime, PETSC_NULLPTR);
1083 CHKERR PetscOptionsScalar("-cracking_start_time", "cracking start time", "",
1085 PETSC_NULLPTR);
1086 CHKERR PetscOptionsScalar("-griffith_energy", "Griffith energy", "",
1087 griffithEnergy, &griffithEnergy, PETSC_NULLPTR);
1088
1089 CHKERR PetscOptionsScalar("-cracking_rtol", "Cracking relative tolerance", "",
1090 crackingRtol, &crackingRtol, PETSC_NULLPTR);
1091 CHKERR PetscOptionsScalar("-cracking_atol", "Cracking absolute tolerance", "",
1092 crackingAtol, &crackingAtol, PETSC_NULLPTR);
1093 CHKERR PetscOptionsEList("-energy_release_variant", "energy release variant",
1094 "", list_release, 2, list_release[choice_release],
1095 &choice_release, PETSC_NULLPTR);
1096 CHKERR PetscOptionsInt("-nb_J_integral_levels", "Number of J integarl levels",
1098 PETSC_NULLPTR); // backward compatibility
1099 CHKERR PetscOptionsInt(
1100 "-nb_J_integral_contours", "Number of J integral contours", "",
1101 nbJIntegralContours, &nbJIntegralContours, PETSC_NULLPTR);
1102
1103 // internal stress
1104 char tag_name[255] = "";
1105 CHKERR PetscOptionsString("-internal_stress_tag_name",
1106 "internal stress tag name", "", "", tag_name, 255,
1107 PETSC_NULLPTR);
1108 internalStressTagName = string(tag_name);
1109 CHKERR PetscOptionsBool("-internal_stress_voigt", "Voigt index notation", "",
1111 PETSC_NULLPTR);
1112
1113 // Heterogenous Young's modulus
1114 char tag_heterogeneous_youngs_modulus_name[255] = "";
1115 CHKERR PetscOptionsString(
1116 "-heterogeneous_youngs_modulus", "heterogeneous Young's modulus tag name",
1117 "", "", tag_heterogeneous_youngs_modulus_name, 255, PETSC_NULLPTR);
1118 heterogeneousYoungModTagName = string(tag_heterogeneous_youngs_modulus_name);
1119
1120 PetscBool has_analytical_expr_file_option = PETSC_FALSE;
1122 PETSC_NULLPTR, PETSC_NULLPTR, "-analytical_expr_file",
1123 analytical_expr_file_name, 255, &has_analytical_expr_file_option);
1124 if (!has_analytical_expr_file_option) {
1125 const auto analytical_expr_script =
1126 mField.getInterface<JsonConfigManager>()->getPythonScriptByKey(
1127 "analytical_expr");
1128 if (!analytical_expr_script.empty()) {
1129 CHKERR PetscStrncpy(analytical_expr_file_name,
1130 analytical_expr_script.c_str(),
1131 sizeof(analytical_expr_file_name));
1132 MOFEM_LOG("EP", Sev::inform)
1133 << "Using Python script 'analytical_expr' from JSON config: "
1134 << analytical_expr_file_name;
1135 }
1136 }
1137
1138 PetscOptionsEnd();
1139
1142
1143 PetscOptionsBegin(PETSC_COMM_WORLD, "mesh_transfer_", "mesh data transfer",
1144 "none");
1145 char tag_mesh_transfer_source_file_name[255] = "";
1146 CHKERR PetscOptionsString("-source_file", "source mesh file name", "",
1147 "source.h5m", tag_mesh_transfer_source_file_name,
1149 meshTransferSourceMeshFileName = string(tag_mesh_transfer_source_file_name);
1150 CHKERR PetscOptionsInt("-interp_order", "interpolation order", "", 0,
1151 &meshTransferInterpOrder, PETSC_NULLPTR);
1152 CHKERR PetscOptionsBool("-hybrid_interp", "use hybrid interpolation", "",
1154 PETSC_NULLPTR);
1155 PetscOptionsEnd();
1156
1158 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
1159 "Unsupported mesh transfer interpolation order %d",
1161 }
1162 if (!internalStressTagName.empty())
1164 if (!heterogeneousYoungModTagName.empty())
1166
1167 const PetscBool l2_user_base_scale_option = l2UserBaseScale;
1168 if (setSingularity && !l2_user_base_scale_set) {
1169 l2UserBaseScale = PETSC_TRUE;
1170 }
1171
1174 EshelbianCore::rotSelector = static_cast<RotSelector>(choice_rot);
1175 EshelbianCore::gradApproximator = static_cast<RotSelector>(choice_grad);
1176 EshelbianCore::stretchSelector = static_cast<StretchSelector>(choice_stretch);
1178 static_cast<EnergyReleaseSelector>(choice_release);
1179 switch (choice_broken_hdiv_base) {
1180 case 0:
1182 break;
1183 case 1:
1185 break;
1186 default:
1187 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
1188 "Unknown broken HDIV base option");
1189 }
1190
1192 case StretchSelector::LINEAR:
1199 break;
1200 case StretchSelector::LOG:
1207 break;
1208 case StretchSelector::LOG_QUADRATIC:
1215 break;
1216 default:
1217 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "Unknown stretch");
1218 break;
1219 };
1220
1221 const PetscBool dynamic_relaxation_option = physicalTimeFlg;
1222 if (physicalTimeFlg) {
1223 MOFEM_LOG("EP", Sev::warning)
1224 << "-dynamic_relaxation option is deprecated, use -solver_type "
1225 "dynamic_relaxation instead.";
1226 choice_solver = SolverType::DynamicRelaxation;
1227 }
1228
1229 switch (choice_solver) {
1232 break;
1236 physicalTimeFlg = PETSC_TRUE;
1237 break;
1240 break;
1243 physicalTimeFlg = PETSC_TRUE;
1244 break;
1248 break;
1252 physicalTimeFlg = PETSC_TRUE;
1253 break;
1254 default:
1255 SETERRQ(mField.get_comm(), MOFEM_DATA_INCONSISTENCY, "Unknown solver");
1256 break;
1257 };
1258
1259 // start cracking after adding crack elements
1261
1262 const auto yes_no = [](auto flag) { return flag ? "yes" : "no"; };
1263
1264 MOFEM_LOG("EP", Sev::inform) << "spaceOrder: -space_order " << spaceOrder;
1265 MOFEM_LOG("EP", Sev::inform)
1266 << "spaceH1Order: -space_h1_order " << spaceH1Order;
1267 MOFEM_LOG("EP", Sev::inform)
1268 << "materialH1Order: -material_order " << materialH1Order;
1269 MOFEM_LOG("EP", Sev::inform) << "alphaU: -viscosity_alpha_u " << alphaU;
1270 MOFEM_LOG("EP", Sev::inform) << "alphaW: -viscosity_alpha_w " << alphaW;
1271 MOFEM_LOG("EP", Sev::inform) << "alphaOmega: -alpha_omega " << alphaOmega;
1272 MOFEM_LOG("EP", Sev::inform)
1273 << "alphaOmega0: -alpha_omega0 " << alphaOmega0;
1274 MOFEM_LOG("EP", Sev::inform) << "alphaR: -alpha_r " << alphaR;
1275 MOFEM_LOG("EP", Sev::inform) << "alphaR0: -alpha_r0 " << alphaR0;
1276 MOFEM_LOG("EP", Sev::inform)
1277 << "alphaViscousOmega: -viscosity_alpha_omega "
1279 MOFEM_LOG("EP", Sev::inform)
1280 << "alphaViscousOmega0: -viscosity_alpha_omega0 "
1282 MOFEM_LOG("EP", Sev::inform)
1283 << "alphaViscousR: -viscosity_alpha_r " << alphaViscousR;
1284 MOFEM_LOG("EP", Sev::inform)
1285 << "alphaViscousR0: -viscosity_alpha_r0 " << alphaViscousR0;
1286 MOFEM_LOG("EP", Sev::inform) << "alphaRho: -density_alpha_rho " << alphaRho;
1287 MOFEM_LOG("EP", Sev::inform) << "alphaTau: -alpha_tau " << alphaTau;
1288 MOFEM_LOG("EP", Sev::inform) << "alphaTau0: -alpha_tau0 " << alphaTau0;
1289 MOFEM_LOG("EP", Sev::inform)
1290 << "alphaTauBcDisp: -alpha_tau_bc_disp " << alphaTauBcDisp;
1291 MOFEM_LOG("EP", Sev::inform)
1292 << "alphaTauBcDisp0: -alpha_tau0_bc_disp " << alphaTauBcDisp0;
1293 MOFEM_LOG("EP", Sev::inform)
1294 << "Rotations: -rotations " << list_rots[EshelbianCore::rotSelector];
1295 MOFEM_LOG("EP", Sev::inform) << "Gradient of deformation: -grad "
1296 << list_rots[EshelbianCore::gradApproximator];
1297 MOFEM_LOG("EP", Sev::inform)
1298 << "Stretch: -stretches " << list_stretches[choice_stretch];
1299 MOFEM_LOG("EP", Sev::inform)
1300 << "No stretch: -no_stretch "
1301 << (isNoStretch() ? "yes" : "no");
1302
1303 MOFEM_LOG("EP", Sev::inform)
1304 << "Dynamic relaxation: -dynamic_relaxation "
1305 << yes_no(dynamic_relaxation_option);
1306 MOFEM_LOG("EP", Sev::inform) << "Solver type: -solver_type "
1307 << EshelbianCore::listSolvers[choice_solver];
1308 if (choice_solver != SolverType::TimeSolver) {
1309 MOFEM_LOG("EP", Sev::inform)
1310 << "Physical final time: -physical_final_time " << finalPhysicalTime;
1311 MOFEM_LOG("EP", Sev::inform)
1312 << "Physical delta time: -physical_delta_time " << physicalDt;
1313 MOFEM_LOG("EP", Sev::inform)
1314 << "Physical max steps: -physical_max_steps " << physicalMaxSteps;
1315 MOFEM_LOG("EP", Sev::inform)
1316 << "Physical H1 update: -physical_h1_update "
1317 << yes_no(physicalH1Update);
1318 }
1319 MOFEM_LOG("EP", Sev::inform)
1320 << "Singularity: -set_singularity " << yes_no(setSingularity);
1321 MOFEM_LOG("EP", Sev::inform)
1322 << "L2 user base scale: -l2_user_base_scale "
1323 << yes_no(l2_user_base_scale_option);
1324 if (l2UserBaseScale != l2_user_base_scale_option) {
1325 MOFEM_LOG("EP", Sev::inform)
1326 << "Effective L2 user base scale after option processing "
1327 << yes_no(l2UserBaseScale) << " (auto-enabled by -set_singularity)";
1328 }
1329 MOFEM_LOG("EP", Sev::inform)
1330 << "Broken HDIV base: -broken_hdiv_base "
1331 << list_broken_hdiv_bases[choice_broken_hdiv_base];
1332 MOFEM_LOG("EP", Sev::inform)
1333 << "Contact max post-proc ref level: -contact_max_post_proc_ref_level "
1335
1336 MOFEM_LOG("EP", Sev::inform)
1337 << "Cracking on: -cracking_on " << yes_no(crackingOn);
1338 MOFEM_LOG("EP", Sev::inform)
1339 << "Cracking add time: -cracking_add_time " << crackingAddTime;
1340 MOFEM_LOG("EP", Sev::inform)
1341 << "Cracking start time: -cracking_start_time " << crackingStartTime;
1342 MOFEM_LOG("EP", Sev::inform)
1343 << "Griffith energy: -griffith_energy " << griffithEnergy;
1344 MOFEM_LOG("EP", Sev::inform)
1345 << "Cracking relative tolerance: -cracking_rtol " << crackingRtol;
1346 MOFEM_LOG("EP", Sev::inform)
1347 << "Cracking absolute tolerance: -cracking_atol " << crackingAtol;
1348 MOFEM_LOG("EP", Sev::inform)
1349 << "Energy release variant: -energy_release_variant "
1350 << list_release[EshelbianCore::energyReleaseSelector];
1351 MOFEM_LOG("EP", Sev::inform)
1352 << "Number of J integral contours: -nb_J_integral_contours / "
1353 "-nb_J_integral_levels "
1355 MOFEM_LOG("EP", Sev::inform)
1356 << "Cohesive interface on: -cohesive_interface_on "
1357 << ((interfaceCrack == PETSC_TRUE) ? "yes" : "no");
1358 MOFEM_LOG("EP", Sev::inform)
1359 << "Cohesive interface remove level: -cohesive_interface_remove_level "
1361 MOFEM_LOG("EP", Sev::inform)
1362 << "Internal stress tag name: -internal_stress_tag_name "
1364 MOFEM_LOG("EP", Sev::inform)
1365 << "Internal stress Voigt notation: -internal_stress_voigt "
1366 << yes_no(internalStressVoigt);
1367 MOFEM_LOG("EP", Sev::inform)
1368 << "Heterogeneous Young's modulus: -heterogeneous_youngs_modulus "
1370 MOFEM_LOG("EP", Sev::inform)
1371 << "Analytical expression file: -analytical_expr_file "
1372 << analytical_expr_file_name;
1374 MOFEM_LOG("EP", Sev::inform)
1375 << "Mesh transfer source file: -mesh_transfer_source_file "
1377 } else {
1378 MOFEM_LOG("EP", Sev::inform)
1379 << "Mesh transfer source file: -mesh_transfer_source_file <not set>";
1380 }
1381 MOFEM_LOG("EP", Sev::inform)
1382 << "Mesh transfer interpolation order: -mesh_transfer_interp_order "
1384 MOFEM_LOG("EP", Sev::inform)
1385 << "Mesh transfer hybrid interpolation: -mesh_transfer_hybrid_interp "
1386 << yes_no(meshTransferHybridInterp);
1387
1388#ifdef ENABLE_PYTHON_BINDING
1389 auto file_exists = [](std::string myfile) {
1390 std::ifstream file(myfile.c_str());
1391 if (file) {
1392 return true;
1393 }
1394 return false;
1395 };
1396
1397 if (file_exists(analytical_expr_file_name)) {
1398 MOFEM_LOG("EP", Sev::inform) << analytical_expr_file_name << " file found";
1399
1400 AnalyticalExprPythonPtr = boost::make_shared<AnalyticalExprPython>();
1401 CHKERR AnalyticalExprPythonPtr->analyticalExprInit(
1402 analytical_expr_file_name);
1403 AnalyticalExprPythonWeakPtr = AnalyticalExprPythonPtr;
1404 } else {
1405 MOFEM_LOG("EP", Sev::warning)
1406 << analytical_expr_file_name << " file NOT found";
1407 }
1408#endif
1409
1410 if (spaceH1Order == -1)
1412
1414}
@ DEMKOWICZ_JACOBI_BASE
Definition definitions.h:66
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
static const char *const ApproximationBaseNames[]
Definition definitions.h:72
PetscErrorCode PetscOptionsGetString(PetscOptions *, const char pre[], const char name[], char str[], size_t size, PetscBool *set)
static PetscBool physicalH1Update
static enum StretchSelector stretchSelector
static int interfaceRemoveLevel
static double inv_dd_f_linear(const double)
static double inv_f_linear(const double v)
static double dd_f_log_e_quadratic(const double v)
static double inv_d_f_linear(const double)
static double dd_f_linear(const double)
static boost::function< double(const double)> inv_dd_f
static enum SolverType solverType
static PetscBool l2UserBaseScale
static enum StretchHandling stretchHandling
static const char * listSolvers[]
static PetscBool crackingOn
static double dd_f_log_e(const double v)
static double d_f_linear(const double)
static enum RotSelector rotSelector
static enum RotSelector gradApproximator
static double inv_dd_f_log_e_quadratic(const double stretch)
static double physicalDt
static std::vector< std::string > listTagsToProject
static std::string heterogeneousYoungModTagName
static int physicalMaxSteps
static double crackingStartTime
static double inv_d_f_log_e(const double v)
static PetscBool physicalTimeFlg
static double crackingAddTime
double alphaViscousOmega0
boost::shared_ptr< AnalyticalExprPython > AnalyticalExprPythonPtr
static PetscBool meshTransferHybridInterp
static std::string internalStressTagName
static double finalPhysicalTime
static PetscBool internalStressVoigt
static double inv_dd_f_log_e(const double v)
static PetscBool setSingularity
static double d_f_log_e(const double v)
static PetscBool meshTransferSourceMeshFileSpecified
static double f_log_e_quadratic(const double v)
static double inv_f_log_e_quadratic(const double stretch)
static PetscBool interfaceCrack
static double d_f_log_e_quadratic(const double v)
static boost::function< double(const double)> dd_f
static double f_log_e(const double v)
static double inv_f_log_e(const double v)
static boost::function< double(const double)> d_f
static boost::function< double(const double)> inv_d_f
static int meshTransferInterpOrder
static double inv_d_f_log_e_quadratic(const double stretch)
static std::string meshTransferSourceMeshFileName
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 5578 of file EshelbianPlasticity.cpp.

5578 {
5580
5581 auto bc_mng = mField.getInterface<BcManager>();
5583 "", piolaStress, false, false);
5584 CHKERR bc_mng->pushMarkDOFsOnEntities<BcDisplacementMeshsetType<BLOCKSET>>(
5585 "", piolaStress, false, false);
5586
5587 bcSpatialDispVecPtr = boost::make_shared<BcDispVec>();
5588 auto get_fix_load_history = [&](const std::string &block_name) {
5589 for (const auto type_name : {"FIX_X", "FIX_Y", "FIX_Z", "FIX_ALL"}) {
5590 for (auto it : mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
5591 std::regex(
5592
5593 (boost::format("%s(.*)") % type_name).str()
5594
5595 ))
5596
5597 ) {
5598 if (it->getName() == block_name) {
5600 type_name, it->getMeshsetId(), "load_history");
5601 }
5602 }
5603 }
5604 return std::string();
5605 };
5606
5607 for (auto bc : bc_mng->getBcMapByBlockName()) {
5608 if (auto disp_bc = bc.second->dispBcPtr) {
5609
5610 auto [field_name, block_name] =
5612 MOFEM_LOG("EP", Sev::inform)
5613 << "Field name: " << field_name << " Block name: " << block_name;
5614 MOFEM_LOG("EP", Sev::noisy) << "Displacement BC: " << *disp_bc;
5615
5616 std::vector<double> block_attributes(6, 0.);
5617 if (disp_bc->data.flag1 == 1) {
5618 block_attributes[0] = disp_bc->data.value1;
5619 block_attributes[3] = 1;
5620 }
5621 if (disp_bc->data.flag2 == 1) {
5622 block_attributes[1] = disp_bc->data.value2;
5623 block_attributes[4] = 1;
5624 }
5625 if (disp_bc->data.flag3 == 1) {
5626 block_attributes[2] = disp_bc->data.value3;
5627 block_attributes[5] = 1;
5628 }
5629 auto faces = bc.second->bcEnts.subset_by_dimension(2);
5630 bcSpatialDispVecPtr->emplace_back(block_name, block_attributes, faces,
5631 get_fix_load_history(block_name));
5632 }
5633 }
5634 // old way of naming blocksets for displacement BCs
5635 CHKERR getBc(bcSpatialDispVecPtr, "SPATIAL_DISP_BC", 6);
5636
5638 boost::make_shared<NormalDisplacementBcVec>();
5639 CHKERR getBc(bcSpatialNormalDisplacementVecPtr, "NORMAL_DISPLACEMENT", 1);
5640
5641 bcSpatialSpringVecPtr = boost::make_shared<SpringBcVec>();
5642 auto mesh_mng = mField.getInterface<MeshsetsManager>();
5643 for (auto it : mesh_mng->getCubitMeshsetPtr(
5644 std::regex((boost::format("(.*)%s(.*)") % "SPRING_BC").str()))) {
5645 std::vector<double> block_attributes;
5646 CHKERR it->getAttributes(block_attributes);
5647 if (block_attributes.size() < 2) {
5648 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
5649 "In block %s expected 2 attributes, but given %ld",
5650 it->getName().c_str(), block_attributes.size());
5651 }
5652 Range faces;
5653 CHKERR it->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2, faces,
5654 true);
5655 MOFEM_LOG("EP", Sev::inform)
5656 << "Found spring BC on block " << it->getName();
5657 MOFEM_LOG("EP", Sev::inform)
5658 << " kn = " << block_attributes[0] << ", kt = " << block_attributes[1];
5659 MOFEM_LOG("EP", Sev::inform) << " nb. of faces " << faces.size();
5660 bcSpatialSpringVecPtr->emplace_back(it->getName(), block_attributes, faces);
5661 }
5662
5664 boost::make_shared<AnalyticalDisplacementBcVec>();
5665 CHKERR getBc(bcSpatialAnalyticalDisplacementVecPtr, "ANALYTICAL_DISPLACEMENT",
5666 3);
5667
5668 auto ts_displacement =
5669 boost::make_shared<DynamicRelaxationTimeScale>("disp_history.txt");
5670 for (auto &bc : *bcSpatialDispVecPtr) {
5671 MOFEM_LOG("EP", Sev::noisy)
5672 << "Add time scaling displacement BC: " << bc.blockName;
5673 if (!bc.loadHistoryFile.empty()) {
5674 MOFEM_LOG("EP", Sev::inform)
5675 << "Displacement load history from JSON for " << bc.blockName << ": "
5676 << bc.loadHistoryFile;
5677 timeScaleMap[bc.blockName] =
5678 boost::make_shared<DynamicRelaxationTimeScale>(bc.loadHistoryFile);
5679 } else {
5680 timeScaleMap[bc.blockName] =
5682 ts_displacement, "disp_history", ".txt", bc.blockName);
5683 }
5684 }
5685
5686 auto ts_normal_displacement =
5687 boost::make_shared<DynamicRelaxationTimeScale>("normal_disp_history.txt");
5688 for (auto &bc : *bcSpatialNormalDisplacementVecPtr) {
5689 MOFEM_LOG("EP", Sev::noisy)
5690 << "Add time scaling normal displacement BC: " << bc.blockName;
5691 if (!bc.loadHistoryFile.empty()) {
5692 MOFEM_LOG("EP", Sev::inform)
5693 << "Normal displacement load history from JSON for " << bc.blockName
5694 << ": " << bc.loadHistoryFile;
5695 timeScaleMap[bc.blockName] =
5696 boost::make_shared<DynamicRelaxationTimeScale>(bc.loadHistoryFile);
5697 } else {
5698 timeScaleMap[bc.blockName] =
5700 ts_normal_displacement, "normal_disp_history", ".txt",
5701 bc.blockName);
5702 }
5703 }
5704
5706}
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)
Template specialization for displacement boundary conditions.
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.
Template specialization system for type-safe boundary condition handling.

◆ getSpatialRotationBc()

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

Definition at line 380 of file EshelbianCore.hpp.

380 {
382 bcSpatialRotationVecPtr = boost::make_shared<BcRotVec>();
383 CHKERR getBc(bcSpatialRotationVecPtr, "SPATIAL_ROTATION_BC", 4);
384 CHKERR getBc(bcSpatialRotationVecPtr, "SPATIAL_ROTATION_AXIS_BC", 7);
385
386 for (auto &bc : *bcSpatialRotationVecPtr) {
387 MOFEM_LOG("EP", Sev::inform)
388 << "Found spatial rotation BC on block " << bc.blockName;
389 MOFEM_LOG("EP", Sev::inform) << " with attributes: " << bc.vals;
390 MOFEM_LOG("EP", Sev::inform) << " and rotation angle: " << bc.theta;
391 MOFEM_LOG("EP", Sev::inform) << " and nb of faces: " << bc.faces.size();
392 }
393
394 auto ts_rotation =
395 boost::make_shared<DynamicRelaxationTimeScale>("rotation_history.txt");
396 for (auto &bc : *bcSpatialRotationVecPtr) {
397 if (!bc.loadHistoryFile.empty()) {
398 MOFEM_LOG("EP", Sev::inform)
399 << "Rotation load history from JSON for " << bc.blockName << ": "
400 << bc.loadHistoryFile;
401 timeScaleMap[bc.blockName] =
402 boost::make_shared<DynamicRelaxationTimeScale>(
403 bc.loadHistoryFile);
404 } else {
405 timeScaleMap[bc.blockName] =
406 GetBlockScalingMethod<DynamicRelaxationTimeScale>::get(
407 ts_rotation, "rotation_history", ".txt", bc.blockName);
408 }
409 }
410
412 }

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

5708 {
5710
5711 auto bc_mng = mField.getInterface<BcManager>();
5713 false, false);
5714
5715 bcSpatialTractionVecPtr = boost::make_shared<TractionBcVec>();
5716
5717 for (auto bc : bc_mng->getBcMapByBlockName()) {
5718 if (auto force_bc = bc.second->forceBcPtr) {
5719
5720 auto [field_name, block_name] =
5722 MOFEM_LOG("EP", Sev::inform)
5723 << "Field name: " << field_name << " Block name: " << block_name;
5724 MOFEM_LOG("EP", Sev::noisy) << "Force BC: " << *force_bc;
5725
5726 std::vector<double> block_attributes(6, 0.);
5727 block_attributes[0] = -force_bc->data.value3 * force_bc->data.value1;
5728 block_attributes[3] = 1;
5729 block_attributes[1] = -force_bc->data.value4 * force_bc->data.value1;
5730 block_attributes[4] = 1;
5731 block_attributes[2] = -force_bc->data.value5 * force_bc->data.value1;
5732 block_attributes[5] = 1;
5733 auto faces = bc.second->bcEnts.subset_by_dimension(2);
5734 bcSpatialTractionVecPtr->emplace_back(block_name, block_attributes,
5735 faces);
5736 }
5737 }
5738 CHKERR getBc(bcSpatialTractionVecPtr, "SPATIAL_TRACTION_BC", 6);
5739
5740 bcSpatialPressureVecPtr = boost::make_shared<PressureBcVec>();
5741 CHKERR getBc(bcSpatialPressureVecPtr, "PRESSURE", 1);
5742
5744 boost::make_shared<AnalyticalTractionBcVec>();
5745 CHKERR getBc(bcSpatialAnalyticalTractionVecPtr, "ANALYTICAL_TRACTION", 3);
5746
5747 auto ts_traction =
5748 boost::make_shared<DynamicRelaxationTimeScale>("traction_history.txt");
5749 for (auto &bc : *bcSpatialTractionVecPtr) {
5750 if (!bc.loadHistoryFile.empty()) {
5751 MOFEM_LOG("EP", Sev::inform)
5752 << "Traction load history from JSON for " << bc.blockName << ": "
5753 << bc.loadHistoryFile;
5754 timeScaleMap[bc.blockName] =
5755 boost::make_shared<DynamicRelaxationTimeScale>(bc.loadHistoryFile);
5756 } else {
5757 timeScaleMap[bc.blockName] =
5759 ts_traction, "traction_history", ".txt", bc.blockName);
5760 }
5761 }
5762
5763 auto ts_pressure =
5764 boost::make_shared<DynamicRelaxationTimeScale>("pressure_history.txt");
5765 for (auto &bc : *bcSpatialPressureVecPtr) {
5766 if (!bc.loadHistoryFile.empty()) {
5767 MOFEM_LOG("EP", Sev::inform)
5768 << "Pressure load history from JSON for " << bc.blockName << ": "
5769 << bc.loadHistoryFile;
5770 timeScaleMap[bc.blockName] =
5771 boost::make_shared<DynamicRelaxationTimeScale>(bc.loadHistoryFile);
5772 } else {
5773 timeScaleMap[bc.blockName] =
5775 ts_pressure, "pressure_history", ".txt", bc.blockName);
5776 }
5777 }
5778
5780}
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 431 of file EshelbianCore.hpp.

431 {
433 boost::shared_ptr<TractionFreeBc>(new TractionFreeBc());
434 return getTractionFreeBc(meshset, bcSpatialFreeTractionVecPtr, "CONTACT");
435 }
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.

◆ getStringArgumentFromJsonBlockset()

std::string EshelbianCore::getStringArgumentFromJsonBlockset ( const std::string &  type_name,
const int  meshset_id,
const std::string &  param_name 
)
inline
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 313 of file EshelbianCore.hpp.

315 {
316 const auto string_params =
317 mField.getInterface<JsonConfigManager>()->getStringParamsFromBlockset(
318 type_name, meshset_id);
319 if (const auto it = string_params.find(param_name);
320 it != string_params.end()) {
321 return it->second;
322 }
323 return "";
324 }

◆ getStringArgumentFromJsonBlocksets()

MoFEMErrorCode EshelbianCore::getStringArgumentFromJsonBlocksets ( const std::string &  type_name,
const std::string &  param_name,
std::string &  param_value 
)
inline
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 326 of file EshelbianCore.hpp.

328 {
330 param_value.clear();
331 for (auto it : mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
332 std::regex((boost::format("%s(.*)") % type_name).str()))) {
333 const auto block_param = getStringArgumentFromJsonBlockset(
334 type_name, it->getMeshsetId(), param_name);
335 if (block_param.empty()) {
336 continue;
337 }
338 if (!param_value.empty() && param_value != block_param) {
339 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
340 "JSON %s blocksets specify different '%s' values",
341 type_name.c_str(), param_name.c_str());
342 }
343 param_value = block_param;
344 }
346 }

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

5511 {
5513
5514 auto post_proc_norm_fe =
5515 boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
5516
5517 auto bubble_cache =
5518 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0, MatrixDouble());
5519 post_proc_norm_fe->getUserPolynomialBase() =
5520 boost::shared_ptr<BaseFunction>(new CGGUserPolynomialBase(bubble_cache));
5521 post_proc_norm_fe->getRuleHook = [](int, int, int) { return -1; };
5522 post_proc_norm_fe->setRuleHook = SetIntegrationAtFrontVolume(
5523 frontVertices, frontAdjEdges, vol_rule, bubble_cache);
5524 CHKERR EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
5525 post_proc_norm_fe->getOpPtrVector(), {L2, H1, HDIV}, materialH1Positions,
5527
5528 enum NORMS { U_NORM_L2 = 0, U_NORM_H1, PIOLA_NORM, U_ERROR_L2, LAST_NORM };
5529 auto norms_vec =
5530 createVectorMPI(mField.get_comm(), LAST_NORM, PETSC_DETERMINE);
5531 CHKERR VecZeroEntries(norms_vec);
5532
5533 auto u_l2_ptr = boost::make_shared<MatrixDouble>();
5534 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
5535 post_proc_norm_fe->getOpPtrVector().push_back(
5537 post_proc_norm_fe->getOpPtrVector().push_back(
5539 post_proc_norm_fe->getOpPtrVector().push_back(
5540 new OpCalcNormL2Tensor1<SPACE_DIM>(u_l2_ptr, norms_vec, U_NORM_L2));
5541 post_proc_norm_fe->getOpPtrVector().push_back(
5542 new OpCalcNormL2Tensor1<SPACE_DIM>(u_h1_ptr, norms_vec, U_NORM_H1));
5543 post_proc_norm_fe->getOpPtrVector().push_back(
5544 new OpCalcNormL2Tensor1<SPACE_DIM>(u_l2_ptr, norms_vec, U_ERROR_L2,
5545 u_h1_ptr));
5546
5547 auto piola_ptr = boost::make_shared<MatrixDouble>();
5548 post_proc_norm_fe->getOpPtrVector().push_back(
5550 post_proc_norm_fe->getOpPtrVector().push_back(
5552 MBMAXTYPE));
5553
5554 post_proc_norm_fe->getOpPtrVector().push_back(
5555 new OpCalcNormL2Tensor2<3, 3>(piola_ptr, norms_vec, PIOLA_NORM));
5556
5557 TetPolynomialBase::switchCacheBaseOn<HDIV>({post_proc_norm_fe.get()});
5559 *post_proc_norm_fe);
5560 TetPolynomialBase::switchCacheBaseOff<HDIV>({post_proc_norm_fe.get()});
5561
5562 CHKERR VecAssemblyBegin(norms_vec);
5563 CHKERR VecAssemblyEnd(norms_vec);
5564 const double *norms;
5565 CHKERR VecGetArrayRead(norms_vec, &norms);
5566 MOFEM_LOG("EP", Sev::inform) << "norm_u: " << std::sqrt(norms[U_NORM_L2]);
5567 MOFEM_LOG("EP", Sev::inform) << "norm_u_h1: " << std::sqrt(norms[U_NORM_H1]);
5568 MOFEM_LOG("EP", Sev::inform)
5569 << "norm_error_u_l2: " << std::sqrt(norms[U_ERROR_L2]);
5570 MOFEM_LOG("EP", Sev::inform)
5571 << "norm_piola: " << std::sqrt(norms[PIOLA_NORM]);
5572 CHKERR VecRestoreArrayRead(norms_vec, &norms);
5573
5575}
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 MatrixDouble 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 2936 of file EshelbianPlasticity.cpp.

2938 {
2940
2941 // get skin from all tets
2942 Range tets;
2943 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
2944 Range tets_skin_part;
2945 Skinner skin(&mField.get_moab());
2946 CHKERR skin.find_skin(0, tets, false, tets_skin_part);
2947 ParallelComm *pcomm =
2948 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
2949 Range tets_skin;
2950 CHKERR pcomm->filter_pstatus(tets_skin_part,
2951 PSTATUS_SHARED | PSTATUS_MULTISHARED,
2952 PSTATUS_NOT, -1, &tets_skin);
2953
2954 bc_ptr->resize(3);
2955 for (int dd = 0; dd != 3; ++dd)
2956 (*bc_ptr)[dd] = tets_skin;
2957
2958 // Do not remove dofs on which traction is applied
2960 for (auto &v : *bcSpatialDispVecPtr) {
2961 if (v.flags[0])
2962 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2963 if (v.flags[1])
2964 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2965 if (v.flags[2])
2966 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2967 }
2968
2969 // Do not remove dofs on which rotation is applied
2971 for (auto &v : *bcSpatialRotationVecPtr) {
2972 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2973 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2974 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2975 }
2976
2978 for (auto &v : *bcSpatialNormalDisplacementVecPtr) {
2979 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2980 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2981 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2982 }
2983
2986 if (v.flags[0])
2987 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2988 if (v.flags[1])
2989 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2990 if (v.flags[2])
2991 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2992 }
2993
2995 for (auto &v : *bcSpatialTractionVecPtr) {
2996 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
2997 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
2998 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
2999 }
3000
3002 for (auto &v : *bcSpatialSpringVecPtr) {
3003 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
3004 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
3005 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
3006 }
3007
3009 for (auto &v : *bcSpatialAnalyticalTractionVecPtr) {
3010 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
3011 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
3012 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
3013 }
3014
3016 for (auto &v : *bcSpatialPressureVecPtr) {
3017 (*bc_ptr)[0] = subtract((*bc_ptr)[0], v.faces);
3018 (*bc_ptr)[1] = subtract((*bc_ptr)[1], v.faces);
3019 (*bc_ptr)[2] = subtract((*bc_ptr)[2], v.faces);
3020 }
3021
3022 // remove contact
3023 for (auto m : mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
3024 std::regex((boost::format("%s(.*)") % contact_set_name).str()))) {
3025 Range faces;
3026 CHKERR m->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2, faces,
3027 true);
3028 (*bc_ptr)[0] = subtract((*bc_ptr)[0], faces);
3029 (*bc_ptr)[1] = subtract((*bc_ptr)[1], faces);
3030 (*bc_ptr)[2] = subtract((*bc_ptr)[2], faces);
3031 }
3032
3034}
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  )
inlinestatic

◆ inv_d_f_log_e()

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

◆ inv_d_f_log_e_quadratic()

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

Definition at line 177 of file EshelbianCore.hpp.

177 {
178 const double transition_stretch = std::exp(v_max);
179 if (stretch <= transition_stretch) {
180 return 1. / stretch;
181 }
182 const double root =
183 std::sqrt(2. * stretch / transition_stretch - 1.);
184 return 1. / (transition_stretch * root);
185 }

◆ inv_dd_f_linear()

static double EshelbianCore::inv_dd_f_linear ( const double  )
inlinestatic

◆ inv_dd_f_log_e()

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

◆ inv_dd_f_log_e_quadratic()

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

Definition at line 187 of file EshelbianCore.hpp.

187 {
188 const double transition_stretch = std::exp(v_max);
189 if (stretch <= transition_stretch) {
190 return -1. / (stretch * stretch);
191 }
192 const double root =
193 std::sqrt(2. * stretch / transition_stretch - 1.);
194 return -1. /
195 (transition_stretch * transition_stretch * root * root * root);
196 }

◆ inv_f_linear()

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

◆ inv_f_log_e()

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

◆ inv_f_log_e_quadratic()

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

Definition at line 168 of file EshelbianCore.hpp.

168 {
169 const double transition_stretch = std::exp(v_max);
170 if (stretch <= transition_stretch) {
171 return std::log(stretch);
172 }
173 return v_max - 1. +
174 std::sqrt(2. * stretch / transition_stretch - 1.);
175 }

◆ isNoStretch()

static bool EshelbianCore::isNoStretch ( )
inlinestatic

◆ postProcessRestartMesh()

MoFEMErrorCode EshelbianCore::postProcessRestartMesh ( const int  tag,
const std::string  file,
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 4713 of file EshelbianPlasticity.cpp.

4714 {
4716 ParallelComm *pcomm =
4717 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
4718 // write file with only crack surfaces and full mesh
4719 if (crackingOn && !pcomm->rank()) {
4720 auto meshsets_mng = mField.getInterface<MeshsetsManager>();
4721
4722 std::vector<boost::shared_ptr<TempMeshset>> meshsets_tmp_list;
4723 auto &list = meshsets_mng->getMeshsetsMultindex();
4724 std::vector<Tag> tags_list;
4725
4726 auto meshset_ptr = get_temp_meshset_ptr(mField.get_moab());
4727
4728 for (auto &m : list) {
4729 meshsets_tmp_list.push_back(get_temp_meshset_ptr(mField.get_moab()));
4730 EntityHandle new_meshset = *meshsets_tmp_list.back();
4731 auto meshset = m.getMeshset();
4732 std::vector<Tag> tmp_tags_list;
4733 CHKERR mField.get_moab().tag_get_tags_on_entity(meshset, tmp_tags_list);
4734 Range ents;
4735 CHKERR mField.get_moab().get_entities_by_handle(meshset, ents, true);
4736 CHKERR mField.get_moab().add_entities(new_meshset, ents);
4737 for (auto t : tmp_tags_list) {
4738 void *tag_vals[1];
4739 int tag_size[1];
4740 CHKERR mField.get_moab().tag_get_by_ptr(
4741 t, &meshset, 1, (const void **)tag_vals, tag_size);
4742 CHKERR mField.get_moab().tag_set_by_ptr(t, &new_meshset, 1, tag_vals,
4743 tag_size);
4744 }
4745 std::vector<std::string> remove_tags;
4746 remove_tags.push_back("AKDTree_coord_norm");
4747 remove_tags.push_back("__PARALLEL_");
4748 remove_tags.push_back("_RefBitLevel");
4749
4750 for (auto t : tmp_tags_list) {
4751 std::string tag_name;
4752 CHKERR mField.get_moab().tag_get_name(t, tag_name);
4753 bool add = true;
4754
4755 for (auto &p : remove_tags) {
4756 if (tag_name.compare(0, p.size(), p) == 0) {
4757 add = false;
4758 break;
4759 }
4760 }
4761
4762 if (add)
4763 tags_list.push_back(t);
4764 }
4765 }
4766
4767 for (auto &m_ptr : meshsets_tmp_list) {
4768 EntityHandle m = *m_ptr;
4769 CHKERR mField.get_moab().add_entities(*meshset_ptr, &m, 1);
4770 }
4771
4772 // meshsets_tmp_list has all meshsets to write
4773 std::sort(tags_list.begin(), tags_list.end());
4774 auto new_end = std::unique(tags_list.begin(), tags_list.end());
4775 tags_list.resize(std::distance(tags_list.begin(), new_end));
4776
4777 EntityHandle save_meshset = *meshset_ptr;
4778 CHKERR mField.get_moab().write_file(file.c_str(), "MOAB", "", &save_meshset,
4779 1, &tags_list[0], tags_list.size());
4780 }
4782}
auto get_temp_meshset_ptr(moab::Interface &moab)
Create smart pointer to temporary meshset.
CubitMeshSet_multiIndex & getMeshsetsMultindex()

◆ postProcessResults()

MoFEMErrorCode EshelbianCore::postProcessResults ( const int  tag,
const std::string  file,
Vec  f_residual = PETSC_NULLPTR,
Vec  var_vec = PETSC_NULLPTR,
Vec  gradient = 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 4785 of file EshelbianPlasticity.cpp.

4787 {
4789
4790 SmartPetscObj<Vec> f_r, v_v;
4791 if (f_residual != PETSC_NULLPTR || var_vector != PETSC_NULLPTR) {
4793 SmartPetscObj<Vec> xout;
4794 xout = createDMVector(dM);
4795 auto xin = f_residual != PETSC_NULLPTR ? f_residual : var_vector;
4796 CHKERR mField.getInterface<VecManager>()->vecScatterCreate(
4797 xin, "ELASTIC_PROBLEM", RowColData::ROW, xout, "ESHELBY_PLASTICITY",
4798 RowColData::ROW, scatter);
4799 if (f_residual) {
4800 f_r = vectorDuplicate(xout);
4801 CHKERR VecScatterBegin(scatter, f_residual, f_r, INSERT_VALUES,
4802 SCATTER_FORWARD);
4803 CHKERR VecScatterEnd(scatter, f_residual, f_r, INSERT_VALUES,
4804 SCATTER_FORWARD);
4805 CHKERR VecGhostUpdateBegin(f_r, INSERT_VALUES, SCATTER_FORWARD);
4806 CHKERR VecGhostUpdateEnd(f_r, INSERT_VALUES, SCATTER_FORWARD);
4807 }
4808 if (var_vector) {
4809 v_v = createDMVector(dM);
4810 CHKERR VecScatterBegin(scatter, var_vector, v_v, INSERT_VALUES,
4811 SCATTER_FORWARD);
4812 CHKERR VecScatterEnd(scatter, var_vector, v_v, INSERT_VALUES,
4813 SCATTER_FORWARD);
4814 CHKERR VecGhostUpdateBegin(v_v, INSERT_VALUES, SCATTER_FORWARD);
4815 CHKERR VecGhostUpdateEnd(v_v, INSERT_VALUES, SCATTER_FORWARD);
4816 }
4817 }
4818
4820 if (gradient) {
4822 g = createDMVector(dM);
4823 CHKERR mField.getInterface<VecManager>()->vecScatterCreate(
4824 gradient, "MATERIAL_PROBLEM", RowColData::ROW, g, "ESHELBY_PLASTICITY",
4825 RowColData::ROW, scatter);
4826 CHKERR VecScatterBegin(scatter, gradient, g, INSERT_VALUES,
4827 SCATTER_FORWARD);
4828 CHKERR VecScatterEnd(scatter, gradient, g, INSERT_VALUES, SCATTER_FORWARD);
4829 CHKERR VecGhostUpdateBegin(g, INSERT_VALUES, SCATTER_FORWARD);
4830 CHKERR VecGhostUpdateEnd(g, INSERT_VALUES, SCATTER_FORWARD);
4831 }
4832
4833 // mark crack surface
4834 if (crackingOn) {
4835 auto get_tag = [&](auto name, auto dim) {
4836 auto &mob = mField.get_moab();
4837 Tag tag;
4838 double def_val[] = {0., 0., 0.};
4839 CHK_MOAB_THROW(mob.tag_get_handle(name, dim, MB_TYPE_DOUBLE, tag,
4840 MB_TAG_CREAT | MB_TAG_SPARSE, def_val),
4841 "create tag");
4842 return tag;
4843 };
4844 tags_to_transfer.push_back(get_tag("MaterialForce", 3));
4845 }
4846
4847 {
4848 auto get_crack_tag = [&]() {
4849 Tag th;
4850 rval = mField.get_moab().tag_get_handle("CRACK", th);
4851 if (rval == MB_SUCCESS) {
4852 MOAB_THROW(mField.get_moab().tag_delete(th));
4853 }
4854 int def_val[] = {0};
4855 MOAB_THROW(mField.get_moab().tag_get_handle(
4856 "CRACK", 1, MB_TYPE_INTEGER, th, MB_TAG_SPARSE | MB_TAG_CREAT,
4857 def_val));
4858 return th;
4859 };
4860
4861 Tag th = get_crack_tag();
4862 tags_to_transfer.push_back(th);
4863 int mark[] = {1};
4864 Range mark_faces;
4865 if (crackFaces)
4866 mark_faces.merge(*crackFaces);
4867 if (interfaceFaces)
4868 mark_faces.merge(*interfaceFaces);
4869 CHKERR mField.get_moab().tag_clear_data(th, mark_faces, mark);
4870 }
4871
4872 // add tags to transfer
4873 for (auto t : listTagsToTransfer) {
4874 std::string name;
4875 CHKERR mField.get_moab().tag_get_name(t, name);
4876 MOFEM_LOG("EP", Sev::verbose)
4877 << "Adding tag " << name << " to transfer list for post-processing";
4878 tags_to_transfer.push_back(t);
4879 }
4880
4881 if (!dataAtPts) {
4882 dataAtPts =
4883 boost::shared_ptr<DataAtIntegrationPts>(new DataAtIntegrationPts());
4884 }
4885
4887
4888 auto get_post_proc = [&](auto &post_proc_mesh, auto sense) {
4890 auto post_proc_ptr =
4891 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
4892 mField, post_proc_mesh);
4893 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
4894 post_proc_ptr->getOpPtrVector(), {L2}, materialH1Positions,
4896
4897 if (ts != PETSC_NULLPTR) {
4898 post_proc_ptr->data_ctx |= PetscData::CTX_SET_TIME;
4899 CHKERR TSGetTime(ts, &(post_proc_ptr->ts_t));
4900 CHKERR TSGetTimeStep(ts, &(post_proc_ptr->ts_dt));
4901 }
4902
4903 auto domain_ops = [&](auto &fe, int sense) {
4905
4906 auto bubble_cache = boost::make_shared<CGGUserPolynomialBase::CachePhi>(
4907 0, 0, MatrixDouble());
4908 fe.getUserPolynomialBase() = boost::shared_ptr<BaseFunction>(
4909 new CGGUserPolynomialBase(bubble_cache));
4910 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4911 fe.getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions,
4913 auto piola_scale_ptr = boost::make_shared<double>(1.0);
4914 fe.getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
4915 piolaStress, dataAtPts->getApproxPAtPts(), piola_scale_ptr));
4916 constexpr bool add_bubble = true;
4917 if (add_bubble) {
4918 fe.getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
4919 bubbleField, dataAtPts->getApproxPAtPts(), piola_scale_ptr,
4920 SmartPetscObj<Vec>(), MBMAXTYPE));
4921 }
4922 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4923 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
4924 if (isNoStretch()) {
4926 fe.getOpPtrVector(), physicalEquations, dataAtPts,
4928 } else {
4929 fe.getOpPtrVector().push_back(
4931 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
4932 }
4933 CHKERR VecSetDM(solTSStep, PETSC_NULLPTR);
4934 fe.getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
4935 piolaStress, dataAtPts->getApproxP0AtPts(), nullptr, solTSStep));
4936 if (add_bubble) {
4937 fe.getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
4938 bubbleField, dataAtPts->getApproxP0AtPts(), nullptr, solTSStep,
4939 MBMAXTYPE));
4940 }
4941 if (!isNoStretch()) {
4942 fe.getOpPtrVector().push_back(
4944 stretchTensor, dataAtPts->getLogStretchTensor0AtPts(),
4945 solTSStep, MBTET));
4946 }
4947 if (var_vector) {
4948 fe.getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
4949 piolaStress, dataAtPts->getVarPiolaPts(),
4950 boost::make_shared<double>(1), v_v));
4951 fe.getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
4952 bubbleField, dataAtPts->getVarPiolaPts(),
4953 boost::make_shared<double>(1), v_v, MBMAXTYPE));
4954 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4955 rotAxis, dataAtPts->getVarRotAxisPts(), v_v, MBTET));
4956 if (isNoStretch()) {
4957 fe.getOpPtrVector().push_back(
4958 physicalEquations->returnOpCalculateVarStretchFromStress(
4960 } else {
4961 fe.getOpPtrVector().push_back(
4963 stretchTensor, dataAtPts->getVarLogStreachPts(), v_v, MBTET));
4964 }
4965 }
4966 if (gradient) {
4967 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4968 materialH1Positions, dataAtPts->getGradientAtPts(), g));
4969 }
4970
4971 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4972 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
4973
4974 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4975 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
4976 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
4977 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
4978 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldGradient<3, 3>(
4979 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
4980 // evaluate derived quantities
4981 fe.getOpPtrVector().push_back(
4983
4984 // evaluate integration points
4985 fe.getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
4986 true, false, dataAtPts, physicalEquations));
4987 if (auto op =
4988 physicalEquations->returnOpCalculateEnergy(dataAtPts, nullptr)) {
4989 fe.getOpPtrVector().push_back(op);
4990 fe.getOpPtrVector().push_back(new OpCalculateEshelbyStress(dataAtPts));
4991 }
4992
4993 // // post-proc
4996 VolumeElementForcesAndSourcesCoreOnSide::UserDataOperator>;
4997
4998 struct OpSidePPMap : public OpPPMap {
4999 OpSidePPMap(moab::Interface &post_proc_mesh,
5000 std::vector<EntityHandle> &map_gauss_pts,
5001 DataMapVec data_map_scalar, DataMapMat data_map_vec,
5002 DataMapMat data_map_mat, DataMapMat data_symm_map_mat,
5003 int sense)
5004 : OpPPMap(post_proc_mesh, map_gauss_pts, data_map_scalar,
5005 data_map_vec, data_map_mat, data_symm_map_mat),
5006 tagSense(sense) {}
5007
5008 MoFEMErrorCode doWork(int side, EntityType type,
5011
5012 if (tagSense != 0) {
5013 if (tagSense != OpPPMap::getSkeletonSense())
5015 }
5016
5017 CHKERR OpPPMap::doWork(side, type, data);
5019 }
5020
5021 private:
5022 int tagSense;
5023 };
5024
5025 OpPPMap::DataMapMat vec_fields;
5026 vec_fields["SpatialDisplacementL2"] = dataAtPts->getSmallWL2AtPts();
5027 vec_fields["SpatialDisplacementH1"] = dataAtPts->getSmallWH1AtPts();
5028 vec_fields["Omega"] = dataAtPts->getRotAxisAtPts();
5029 vec_fields["AngularMomentum"] = dataAtPts->getLeviKirchhoffAtPts();
5030 vec_fields["X"] = dataAtPts->getLargeXH1AtPts();
5031 if (!isNoStretch()) {
5032 vec_fields["EiegnLogStreach"] = dataAtPts->getEigenVals();
5033 }
5034 if (var_vector) {
5035 vec_fields["VarOmega"] = dataAtPts->getVarRotAxisPts();
5036 vec_fields["VarSpatialDisplacementL2"] =
5037 boost::make_shared<MatrixDouble>();
5038 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
5039 spatialL2Disp, vec_fields["VarSpatialDisplacementL2"], v_v, MBTET));
5040 }
5041 if (f_residual) {
5042 vec_fields["ResSpatialDisplacementL2"] =
5043 boost::make_shared<MatrixDouble>();
5044 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
5045 spatialL2Disp, vec_fields["ResSpatialDisplacementL2"], f_r, MBTET));
5046 vec_fields["ResOmega"] = boost::make_shared<MatrixDouble>();
5047 fe.getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
5048 rotAxis, vec_fields["ResOmega"], f_r, MBTET));
5049 }
5050 if (gradient) {
5051 vec_fields["Gradient"] = dataAtPts->getGradientAtPts();
5052 }
5053
5054 OpPPMap::DataMapMat mat_fields;
5055 mat_fields["PiolaStress"] = dataAtPts->getApproxPAtPts();
5056 if (var_vector) {
5057 mat_fields["VarPiolaStress"] = dataAtPts->getVarPiolaPts();
5058 }
5059 if (f_residual) {
5060 mat_fields["ResPiolaStress"] = boost::make_shared<MatrixDouble>();
5061 fe.getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
5062 piolaStress, mat_fields["ResPiolaStress"],
5063 boost::make_shared<double>(1), f_r));
5064 fe.getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
5065 bubbleField, mat_fields["ResPiolaStress"],
5066 boost::make_shared<double>(1), f_r, MBMAXTYPE));
5067 }
5068 if (!internalStressTagName.empty()) {
5069 mat_fields[internalStressTagName] = dataAtPts->getInternalStressAtPts();
5070 switch (meshTransferInterpOrder) {
5071 case 0:
5072 fe.getOpPtrVector().push_back(
5074 break;
5075 case 1:
5076 fe.getOpPtrVector().push_back(
5078 break;
5079 default:
5080 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
5081 "Unsupported mesh transfer interpolation order %d, for "
5082 "internal stress",
5084 }
5085 }
5086
5087 OpPPMap::DataMapMat mat_fields_symm;
5088 mat_fields_symm["LogSpatialStretch"] =
5089 dataAtPts->getLogStretchTensorAtPts();
5090 mat_fields_symm["SpatialStretch"] = dataAtPts->getStretchTensorAtPts();
5091 if (var_vector) {
5092 mat_fields_symm["VarLogSpatialStretch"] =
5093 dataAtPts->getVarLogStreachPts();
5094 }
5095 if (f_residual) {
5096 if (!isNoStretch()) {
5097 mat_fields_symm["ResLogSpatialStretch"] =
5098 boost::make_shared<MatrixDouble>();
5099 fe.getOpPtrVector().push_back(
5101 stretchTensor, mat_fields_symm["ResLogSpatialStretch"], f_r,
5102 MBTET));
5103 }
5104 }
5105
5106 fe.getOpPtrVector().push_back(
5107
5108 new OpSidePPMap(
5109
5110 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
5111
5112 {},
5113
5114 vec_fields,
5115
5116 mat_fields,
5117
5118 mat_fields_symm,
5119
5120 sense
5121
5122 )
5123
5124 );
5125
5126 fe.getOpPtrVector().push_back(new OpPostProcDataStructure(
5127 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
5128 dataAtPts, sense));
5129
5131 };
5132
5133 auto X_h1_ptr = boost::make_shared<MatrixDouble>();
5134 // H1 material positions
5135 post_proc_ptr->getOpPtrVector().push_back(
5137 dataAtPts->getLargeXH1AtPts()));
5138
5139 // domain
5142 domain_ops(*(op_loop_side->getSideFEPtr()), sense);
5143 post_proc_ptr->getOpPtrVector().push_back(op_loop_side);
5144
5145 return post_proc_ptr;
5146 };
5147
5148 // contact
5149 auto calcs_side_traction_and_displacements = [&](auto &post_proc_ptr,
5150 auto &pip) {
5152 // evaluate traction
5153 using EleOnSide =
5155 using SideEleOp = EleOnSide::UserDataOperator;
5156 auto op_loop_domain_side = new OpLoopSide<EleOnSide>(
5157 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
5158 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
5159 boost::shared_ptr<BaseFunction>(
5160 new CGGUserPolynomialBase(nullptr, true));
5161 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
5162 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
5164 auto traction_ptr = boost::make_shared<MatrixDouble>();
5165 op_loop_domain_side->getOpPtrVector().push_back(
5167 piolaStress, traction_ptr, boost::make_shared<double>(1.0)));
5168
5169 pip.push_back(new OpCalculateVectorFieldValues<3>(
5170 contactDisp, dataAtPts->getContactL2AtPts()));
5171 pip.push_back(op_loop_domain_side);
5172 // evaluate contact displacement and contact conditions
5173 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
5174 pip.push_back(new OpCalculateVectorFieldValues<3>(spatialH1Disp, u_h1_ptr));
5175 pip.push_back(getOpContactDetection(
5176 *this, contactTreeRhs, u_h1_ptr, traction_ptr,
5177 get_range_from_block(mField, "CONTACT", SPACE_DIM - 1),
5178 &post_proc_ptr->getPostProcMesh(), &post_proc_ptr->getMapGaussPts()));
5179
5181 using BoundaryEle =
5183 auto op_this = new OpLoopThis<BoundaryEle>(mField, contactElement);
5184 pip.push_back(op_this);
5185
5186 op_this->getOpPtrVector().push_back(
5187
5188 new OpPPMap(
5189
5190 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
5191
5192 {},
5193
5194 {{"ContactDisplacement", dataAtPts->getContactL2AtPts()}},
5195
5196 {},
5197
5198 {}
5199
5200 )
5201
5202 );
5203
5204 if (f_residual) {
5205
5206 auto contact_residual = boost::make_shared<MatrixDouble>();
5207 op_this->getOpPtrVector().push_back(
5209 contactDisp, contact_residual, f_r, MBTET));
5210 op_this->getOpPtrVector().push_back(
5211
5212 new OpPPMap(
5213
5214 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
5215
5216 {},
5217
5218 {{"res_contact", contact_residual}},
5219
5220 {},
5221
5222 {}
5223
5224 )
5225
5226 );
5227 }
5228
5230 };
5231
5232 auto post_proc_mesh = boost::make_shared<moab::Core>();
5233 auto post_proc_ptr = get_post_proc(post_proc_mesh, /*positive sense*/ 1);
5234 auto post_proc_negative_sense_ptr =
5235 get_post_proc(post_proc_mesh, /*negative sense*/ -1);
5236 auto skin_post_proc_ptr = get_post_proc(post_proc_mesh, /*positive sense*/ 1);
5237 CHKERR calcs_side_traction_and_displacements(
5238 skin_post_proc_ptr, skin_post_proc_ptr->getOpPtrVector());
5239
5240 auto own_tets =
5242 .subset_by_dimension(SPACE_DIM);
5243 Range own_faces;
5244 CHKERR mField.get_moab().get_adjacencies(own_tets, SPACE_DIM - 1, true,
5245 own_faces, moab::Interface::UNION);
5246
5247 auto get_crack_faces = [&](auto crack_faces) {
5248 auto get_adj = [&](auto e, auto dim) {
5249 Range adj;
5250 CHKERR mField.get_moab().get_adjacencies(e, dim, true, adj,
5251 moab::Interface::UNION);
5252 return adj;
5253 };
5254 // this removes faces
5255 auto tets = get_adj(crack_faces, 3);
5256 // faces adjacent to tets not in crack_faces
5257 auto faces = subtract(get_adj(tets, 2), crack_faces);
5258 // what is left from below, are tets fully inside crack_faces
5259 tets = subtract(tets, get_adj(faces, 3));
5260 return subtract(crack_faces, get_adj(tets, 2));
5261 };
5262
5263 auto side_one_faces = [&](auto &faces) {
5264 std::pair<Range, Range> sides;
5265 for (auto f : faces) {
5266 Range adj;
5267 MOAB_THROW(mField.get_moab().get_adjacencies(&f, 1, 3, false, adj));
5268 adj = intersect(own_tets, adj);
5269 for (auto t : adj) {
5270 int side, sense, offset;
5271 MOAB_THROW(mField.get_moab().side_number(t, f, side, sense, offset));
5272 if (sense == 1) {
5273 sides.first.insert(f);
5274 } else {
5275 sides.second.insert(f);
5276 }
5277 }
5278 }
5279 return sides;
5280 };
5281
5282 auto get_interface_from_block = [&](auto block_name) {
5283 auto vol_eles = get_range_from_block(mField, block_name, SPACE_DIM);
5284 auto skin = filter_true_skin(mField, get_skin(mField, vol_eles));
5285 Range faces;
5286 CHKERR mField.get_moab().get_adjacencies(vol_eles, SPACE_DIM - 1, true,
5287 faces, moab::Interface::UNION);
5288 faces = subtract(faces, skin);
5289 return faces;
5290 };
5291
5292 auto crack_faces = unite(get_crack_faces(*crackFaces), *interfaceFaces);
5293 // VOLUME_INTERFACE faces were already merged into interfaceFaces in
5294 // projectGeometry(), after applying REMOVE_INTERFACE exclusions.
5295 auto crack_side_faces = side_one_faces(crack_faces);
5296 auto side_one_crack_faces = [crack_side_faces](FEMethod *fe_method_ptr) {
5297 auto ent = fe_method_ptr->getFEEntityHandle();
5298 if (crack_side_faces.first.find(ent) == crack_side_faces.first.end()) {
5299 return false;
5300 }
5301 return true;
5302 };
5303 auto side_minus_crack_faces = [crack_side_faces](FEMethod *fe_method_ptr) {
5304 auto ent = fe_method_ptr->getFEEntityHandle();
5305 if (crack_side_faces.second.find(ent) == crack_side_faces.second.end()) {
5306 return false;
5307 }
5308 return true;
5309 };
5310
5311 skin_post_proc_ptr->setTagsToTransfer(tags_to_transfer);
5312 post_proc_ptr->setTagsToTransfer(tags_to_transfer);
5313 post_proc_negative_sense_ptr->setTagsToTransfer(tags_to_transfer);
5314
5315 auto post_proc_begin =
5317 CHKERR DMoFEMPreProcessFiniteElements(dM, post_proc_begin.getFEMethod());
5318 CHKERR DMoFEMLoopFiniteElements(dM, skinElement, skin_post_proc_ptr);
5319 post_proc_ptr->exeTestHook = side_one_crack_faces;
5321 dM, skeletonElement, post_proc_ptr, 0, mField.get_comm_size());
5322 post_proc_negative_sense_ptr->exeTestHook = side_minus_crack_faces;
5324 post_proc_negative_sense_ptr, 0,
5326
5327 constexpr bool debug = false;
5328 if (debug) {
5329
5330 auto get_adj_front = [&]() {
5331 auto skeleton_faces = *skeletonFaces;
5332 Range adj_front;
5333 CHKERR mField.get_moab().get_adjacencies(*frontEdges, 2, true, adj_front,
5334 moab::Interface::UNION);
5335
5336 adj_front = intersect(adj_front, skeleton_faces);
5337 adj_front = subtract(adj_front, *crackFaces);
5338 adj_front = intersect(own_faces, adj_front);
5339 return adj_front;
5340 };
5341
5342 auto adj_front = filter_owners(mField, get_adj_front());
5343 auto only_front_faces = [adj_front](FEMethod *fe_method_ptr) {
5344 auto ent = fe_method_ptr->getFEEntityHandle();
5345 if (adj_front.find(ent) == adj_front.end()) {
5346 return false;
5347 }
5348 return true;
5349 };
5350
5351 post_proc_ptr->exeTestHook = only_front_faces;
5353 dM, skeletonElement, post_proc_ptr, 0, mField.get_comm_size());
5354 post_proc_negative_sense_ptr->exeTestHook = only_front_faces;
5356 post_proc_negative_sense_ptr, 0,
5358 }
5359 auto post_proc_end = PostProcBrokenMeshInMoabBaseEnd(mField, post_proc_mesh);
5360 CHKERR DMoFEMPostProcessFiniteElements(dM, post_proc_end.getFEMethod());
5361
5362 CHKERR post_proc_end.writeFile(file.c_str());
5364}
static auto filter_owners(MoFEM::Interface &m_field, Range skin)
std::string type
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
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
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
Vector manager is used to create vectors \mofem_vectors.

◆ postProcessSkeletonResults()

MoFEMErrorCode EshelbianCore::postProcessSkeletonResults ( const int  tag,
const std::string  file,
Vec  f_residual = 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 5367 of file EshelbianPlasticity.cpp.

5370 {
5372
5374 if (f_residual != PETSC_NULLPTR) {
5376 f_r = createDMVector(dM);
5377 CHKERR mField.getInterface<VecManager>()->vecScatterCreate(
5378 f_residual, "ELASTIC_PROBLEM", RowColData::ROW, f_r,
5379 "ESHELBY_PLASTICITY", RowColData::ROW, scatter);
5380 CHKERR VecScatterBegin(scatter, f_residual, f_r, INSERT_VALUES,
5381 SCATTER_FORWARD);
5382 CHKERR VecScatterEnd(scatter, f_residual, f_r, INSERT_VALUES,
5383 SCATTER_FORWARD);
5384 }
5385
5387
5388 auto post_proc_mesh = boost::make_shared<moab::Core>();
5389 auto post_proc_ptr =
5390 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
5391 mField, post_proc_mesh);
5392 if (ts != PETSC_NULLPTR) {
5393 post_proc_ptr->data_ctx |= PetscData::CtxSetTime;
5394 CHKERR TSGetTime(ts, &post_proc_ptr->ts_t);
5395 CHKERR TSGetTimeStep(ts, &post_proc_ptr->ts_dt);
5396 }
5397 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM - 1, SPACE_DIM>::add(
5398 post_proc_ptr->getOpPtrVector(), {L2}, materialH1Positions,
5400
5401 auto hybrid_disp = boost::make_shared<MatrixDouble>();
5402 post_proc_ptr->getOpPtrVector().push_back(
5404 post_proc_ptr->getOpPtrVector().push_back(
5406 hybridSpatialDisp, dataAtPts->getGradHybridDispAtPts()));
5407
5408 auto op_loop_domain_side =
5410 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
5411 post_proc_ptr->getOpPtrVector().push_back(op_loop_domain_side);
5412
5413 // evaluated in side domain, that is op_loop_domain_side
5414 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
5415 boost::make_shared<CGGUserPolynomialBase>(nullptr, true);
5416 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
5417 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
5419 op_loop_domain_side->getOpPtrVector().push_back(
5421 piolaStress, dataAtPts->getApproxPAtPts()));
5422 op_loop_domain_side->getOpPtrVector().push_back(
5424 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
5425 op_loop_domain_side->getOpPtrVector().push_back(
5427 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
5428
5429 if (isNoStretch()) {
5431 op_loop_domain_side->getOpPtrVector(), physicalEquations, dataAtPts,
5433 } else {
5434 op_loop_domain_side->getOpPtrVector().push_back(
5436 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
5437 }
5438
5440
5441 OpPPMap::DataMapMat vec_fields;
5442 vec_fields["HybridDisplacement"] = hybrid_disp;
5443 // note that grad and omega have not trace, so this is only other side value
5444 vec_fields["spatialL2Disp"] = dataAtPts->getSmallWL2AtPts();
5445 vec_fields["Omega"] = dataAtPts->getRotAxisAtPts();
5446 OpPPMap::DataMapMat mat_fields;
5447 mat_fields["PiolaStress"] = dataAtPts->getApproxPAtPts();
5448 mat_fields["HybridDisplacementGradient"] =
5449 dataAtPts->getGradHybridDispAtPts();
5450 OpPPMap::DataMapMat mat_fields_symm;
5451 mat_fields_symm["LogSpatialStretch"] = dataAtPts->getLogStretchTensorAtPts();
5452
5453 post_proc_ptr->getOpPtrVector().push_back(
5454
5455 new OpPPMap(
5456
5457 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
5458
5459 {},
5460
5461 vec_fields,
5462
5463 mat_fields,
5464
5465 mat_fields_symm
5466
5467 )
5468
5469 );
5470
5471 if (f_residual) {
5472 auto hybrid_res = boost::make_shared<MatrixDouble>();
5473 post_proc_ptr->getOpPtrVector().push_back(
5475 f_r));
5477 post_proc_ptr->getOpPtrVector().push_back(
5478
5479 new OpPPMap(
5480
5481 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
5482
5483 {},
5484
5485 {{"res_hybrid", hybrid_res}},
5486
5487 {},
5488
5489 {}
5490
5491 )
5492
5493 );
5494 }
5495
5496 post_proc_ptr->setTagsToTransfer(tags_to_transfer);
5497
5498 auto post_proc_begin =
5500 CHKERR DMoFEMPreProcessFiniteElements(dM, post_proc_begin.getFEMethod());
5502 auto post_proc_end = PostProcBrokenMeshInMoabBaseEnd(mField, post_proc_mesh);
5503 CHKERR DMoFEMPostProcessFiniteElements(dM, post_proc_end.getFEMethod());
5504
5505 CHKERR post_proc_end.writeFile(file.c_str());
5506
5508}
static constexpr Switches CtxSetTime
Time value switch.

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

1682 {
1684
1685 Range meshset_ents;
1686 CHKERR mField.get_moab().get_entities_by_handle(meshset, meshset_ents);
1687
1688 auto project_ho_geometry = [&](auto field) {
1690 return mField.loop_dofs(field, ent_method);
1691 };
1692 CHKERR project_ho_geometry(materialH1Positions);
1693
1694 auto get_adj_front_edges = [&](auto &front_edges) {
1695 Range front_crack_nodes;
1696 Range crack_front_edges_with_both_nodes_not_at_front;
1697
1698 if (mField.get_comm_rank() == 0) {
1699 auto &moab = mField.get_moab();
1701 moab.get_connectivity(front_edges, front_crack_nodes, true),
1702 "get_connectivity failed");
1703 Range crack_front_edges;
1704 CHK_MOAB_THROW(moab.get_adjacencies(front_crack_nodes, SPACE_DIM - 2,
1705 false, crack_front_edges,
1706 moab::Interface::UNION),
1707 "get_adjacencies failed");
1708 Range crack_front_edges_nodes;
1709 CHK_MOAB_THROW(moab.get_connectivity(crack_front_edges,
1710 crack_front_edges_nodes, true),
1711 "get_connectivity failed");
1712 // those nodes are hannging nodes
1713 crack_front_edges_nodes =
1714 subtract(crack_front_edges_nodes, front_crack_nodes);
1715 Range crack_front_edges_with_both_nodes_not_at_front;
1717 moab.get_adjacencies(crack_front_edges_nodes, 1, false,
1718 crack_front_edges_with_both_nodes_not_at_front,
1719 moab::Interface::UNION),
1720 "get_adjacencies failed");
1721 // those edges are have one node not at the crack front
1722 crack_front_edges_with_both_nodes_not_at_front = intersect(
1723 crack_front_edges, crack_front_edges_with_both_nodes_not_at_front);
1724 }
1725
1726 front_crack_nodes = send_type(mField, front_crack_nodes, MBVERTEX);
1727 crack_front_edges_with_both_nodes_not_at_front = send_type(
1728 mField, crack_front_edges_with_both_nodes_not_at_front, MBEDGE);
1729
1730 return std::make_pair(boost::make_shared<Range>(front_crack_nodes),
1731 boost::make_shared<Range>(
1732 crack_front_edges_with_both_nodes_not_at_front));
1733 };
1734
1735 if ((time - crackingAddTime) > std::numeric_limits<double>::epsilon()) {
1736 crackFaces = boost::make_shared<Range>(
1737 get_range_from_block(mField, "CRACK", SPACE_DIM - 1));
1738 } else {
1739 crackFaces = boost::make_shared<Range>();
1740 }
1741 frontEdges =
1742 boost::make_shared<Range>(get_crack_front_edges(mField, *crackFaces));
1743 auto [front_vertices, front_adj_edges] = get_adj_front_edges(*frontEdges);
1744 frontVertices = front_vertices;
1745 frontAdjEdges = front_adj_edges;
1746
1747 MOFEM_LOG("EP", Sev::inform)
1748 << "Number of crack faces: " << crackFaces->size();
1749 MOFEM_LOG("EP", Sev::inform)
1750 << "Number of front edges: " << frontEdges->size();
1751 MOFEM_LOG("EP", Sev::inform)
1752 << "Number of front vertices: " << frontVertices->size();
1753 MOFEM_LOG("EP", Sev::inform)
1754 << "Number of front adjacent edges: " << frontAdjEdges->size();
1755
1756#ifndef NDEBUG
1757 if (crackingOn) {
1758 auto rank = mField.get_comm_rank();
1759 // CHKERR save_range(mField.get_moab(),
1760 // (boost::format("meshset_ents_%d.vtk") % rank).str(),
1761 // meshset_ents);
1763 (boost::format("crack_faces_%d.vtk") % rank).str(),
1764 *crackFaces);
1766 (boost::format("front_edges_%d.vtk") % rank).str(),
1767 *frontEdges);
1768 // CHKERR save_range(mField.get_moab(),
1769 // (boost::format("front_vertices_%d.vtk") % rank).str(),
1770 // *frontVertices);
1771 // CHKERR save_range(mField.get_moab(),
1772 // (boost::format("front_adj_edges_%d.vtk") % rank).str(),
1773 // *frontAdjEdges);
1774 }
1775#endif // NDEBUG
1776
1777 auto set_singular_dofs = [&](auto &front_adj_edges, auto &front_vertices) {
1779 auto &moab = mField.get_moab();
1780
1781 double eps = 1;
1782 double beta = 0;
1783 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "-singularity_eps", &beta,
1784 PETSC_NULLPTR);
1785 MOFEM_LOG("EP", Sev::inform) << "Singularity eps " << beta;
1786 eps -= beta;
1787
1788 auto field_blas = mField.getInterface<FieldBlas>();
1789 auto lambda =
1790 [&](boost::shared_ptr<FieldEntity> field_entity_ptr) -> MoFEMErrorCode {
1792 FTENSOR_INDEX(3, i);
1793 FTENSOR_INDEX(3, j);
1794
1795 auto nb_dofs = field_entity_ptr->getEntFieldData().size();
1796 if (nb_dofs == 0) {
1798 }
1799
1800#ifndef NDEBUG
1801 if (field_entity_ptr->getNbOfCoeffs() != 3)
1803 "Expected 3 coefficients per edge");
1804 if (nb_dofs % 3 != 0)
1806 "Expected multiple of 3 coefficients per edge");
1807#endif // NDEBUG
1808
1809 auto get_conn = [&]() {
1810 int num_nodes;
1811 const EntityHandle *conn;
1812 CHKERR moab.get_connectivity(field_entity_ptr->getEnt(), conn,
1813 num_nodes, false);
1814 return std::make_pair(conn, num_nodes);
1815 };
1816
1817 auto get_dir = [&](auto &&conn_p) {
1818 auto [conn, num_nodes] = conn_p;
1819 double coords[6];
1820 CHKERR moab.get_coords(conn, num_nodes, coords);
1821 FTensor::Tensor1<double, 3> t_edge_dir{coords[3] - coords[0],
1822 coords[4] - coords[1],
1823 coords[5] - coords[2]};
1824 return t_edge_dir;
1825 };
1826
1827 auto get_singularity_dof = [&](auto &&conn_p, auto &&t_edge_dir) {
1828 auto [conn, num_nodes] = conn_p;
1829 FTensor::Tensor1<double, 3> t_singularity_dof{0., 0., 0.};
1830 if (front_vertices.find(conn[0]) != front_vertices.end()) {
1831 t_singularity_dof(i) = t_edge_dir(i) * (-eps);
1832 } else if (front_vertices.find(conn[1]) != front_vertices.end()) {
1833 t_singularity_dof(i) = t_edge_dir(i) * eps;
1834 }
1835 return t_singularity_dof;
1836 };
1837
1838 auto t_singularity_dof =
1839 get_singularity_dof(get_conn(), get_dir(get_conn()));
1840
1841 auto field_data = field_entity_ptr->getEntFieldData();
1843 &field_data[0], &field_data[1], &field_data[2]};
1844
1845 t_dof(i) = t_singularity_dof(i);
1846 ++t_dof;
1847 for (auto n = 1; n < field_data.size() / 3; ++n) {
1848 t_dof(i) = 0;
1849 ++t_dof;
1850 }
1851
1853 };
1854
1855 CHKERR field_blas->fieldLambdaOnEntities(lambda, materialH1Positions,
1856 &front_adj_edges);
1857
1859 };
1860
1861 if (setSingularity)
1862 CHKERR set_singular_dofs(*frontAdjEdges, *frontVertices);
1863
1864 interfaceFaces = boost::make_shared<Range>(
1865 get_range_from_block(mField, "INTERFACE", SPACE_DIM - 1));
1866 MOFEM_LOG("EP", Sev::inform)
1867 << "Number of interface elements: " << interfaceFaces->size();
1868
1869 auto get_interface_from_block = [&](auto block_name) {
1870 auto vol_eles = get_range_from_block(mField, block_name, SPACE_DIM);
1871 auto skin = filter_true_skin(mField, get_skin(mField, vol_eles));
1872 Range faces;
1873 CHKERR mField.get_moab().get_adjacencies(vol_eles, SPACE_DIM - 1, true,
1874 faces, moab::Interface::UNION);
1875 faces = subtract(faces, skin);
1876 MOFEM_LOG("EP", Sev::inform)
1877 << "Number of vol interface elements: " << vol_eles.size()
1878 << " and faces: " << faces.size();
1879 return faces;
1880 };
1881
1882 interfaceFaces->merge(get_interface_from_block("VOLUME_INTERFACE"));
1883
1884 auto remove_interface_from_block = [&](auto block_name, auto level) {
1886 Range intreface_faces;
1887 if (mField.get_comm_rank() == 0) {
1888 auto ents = get_entities_by_handle(mField, block_name);
1889 for (auto l = 0; l < level; ++l) {
1890 Range adj_tets;
1891 CHKERR mField.get_moab().get_adjacencies(
1892 ents, SPACE_DIM, true, adj_tets, moab::Interface::UNION);
1893 Range adj_tets_faces;
1894 CHKERR mField.get_moab().get_adjacencies(adj_tets, SPACE_DIM - 1, true,
1895 adj_tets_faces,
1896 moab::Interface::UNION);
1897 ents.merge(adj_tets_faces);
1898 }
1899 auto faces = ents.subset_by_dimension(SPACE_DIM - 1);
1900 if (faces.size()) {
1901 MOFEM_LOG("EP", Sev::inform)
1902 << "Removed ents " << faces.size()
1903 << " interface faces: " << interfaceFaces->size();
1904 }
1905 intreface_faces = subtract(*interfaceFaces, faces);
1906 MOFEM_LOG("EP", Sev::noisy)
1907 << "Interface faces after remove " << intreface_faces;
1908 }
1909 auto intreface_faces_global = send_type(mField, intreface_faces, MBTRI);
1910 interfaceFaces->swap(intreface_faces_global);
1912 };
1913 CHKERR remove_interface_from_block("REMOVE_INTERFACE", interfaceRemoveLevel);
1914
1916}
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.
static double lambda
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.

◆ projectMaterialTags()

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

1918 {
1920#ifdef INCLUDE_MBCOUPLER
1921
1922 double toler = 5.e-10;
1923 MOFEM_LOG_CHANNEL("WORLD");
1924 MOFEM_LOG_TAG("WORLD", "mesh_data_transfer");
1926 MOFEM_LOG("WORLD", Sev::verbose)
1927 << "No source mesh specified. Skipping projection";
1929 }
1930 MOFEM_LOG("WORLD", Sev::inform)
1931 << "Projecting from source mesh: " << meshTransferSourceMeshFileName;
1932 MOFEM_LOG("WORLD", Sev::verbose)
1933 << "Interpolation Stress tag name: " << internalStressTagName;
1934 MOFEM_LOG("WORLD", Sev::verbose) << "Interpolation Young's modulus tag name: "
1936 MOFEM_LOG("WORLD", Sev::verbose)
1937 << "Interpolation order: " << meshTransferInterpOrder;
1938 MOFEM_LOG("WORLD", Sev::verbose) << "Using hybrid interpolation: "
1939 << (meshTransferHybridInterp ? "yes" : "no");
1940
1941 auto &moab = mField.get_moab();
1942
1943 // check if tag exists
1944 for (const auto &tag_name : listTagsToProject) {
1945 Tag old_interp_tag;
1946 auto rval_check_tag = moab.tag_get_handle(tag_name.c_str(), old_interp_tag);
1947 if (rval_check_tag == MB_SUCCESS) {
1948 MOFEM_LOG("WORLD", Sev::inform)
1949 << "Deleting existing tag on target mesh: " << tag_name;
1950 CHKERR moab.tag_delete(old_interp_tag);
1951 }
1952 }
1953 // make a size-1 communicator for the coupler (rank 0 only)
1954 int world_rank = -1, world_size = -1;
1955 MPI_Comm_rank(PETSC_COMM_WORLD, &world_rank);
1956 MPI_Comm_size(PETSC_COMM_WORLD, &world_size);
1957
1958 Range original_meshset_ents;
1959 CHKERR moab.get_entities_by_handle(0, original_meshset_ents);
1960
1961 MPI_Comm comm_coupler;
1962 if (world_rank == 0) {
1963 MPI_Comm_split(PETSC_COMM_WORLD, 0, 0, &comm_coupler);
1964 } else {
1965 MPI_Comm_split(PETSC_COMM_WORLD, MPI_UNDEFINED, world_rank, &comm_coupler);
1966 }
1967
1968 // build a separate ParallelComm for the coupler (rank 0 only)
1969 ParallelComm *pcomm0 = nullptr;
1970 int pcomm0_id = -1;
1971 if (world_rank == 0) {
1972 pcomm0 = new ParallelComm(&moab, comm_coupler, &pcomm0_id);
1973 }
1974
1975 Coupler::Method method;
1976 switch (meshTransferInterpOrder) {
1977 case 0:
1978 method = Coupler::CONSTANT;
1979 break;
1980 case 1:
1981 method = Coupler::LINEAR_FE;
1982 break;
1983 default:
1984 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
1985 "Unsupported interpolation order");
1986 }
1987
1988 int nprocs, rank;
1989 ierr = MPI_Comm_size(PETSC_COMM_WORLD, &nprocs);
1990 CHKERRQ(ierr);
1991 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1992 CHKERRQ(ierr);
1993
1994 // std::string read_opts, write_opts;
1995 // read_opts = "PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION;PARTITION_"
1996 // "DISTRIBUTE;PARALLEL_RESOLVE_SHARED_ENTS";
1997 // if (world_size > 1)
1998 // read_opts += ";PARALLEL_GHOSTS=3.0.1";
1999 // write_opts = (world_size > 1) ? "PARALLEL=WRITE_PART" : "";
2000
2001 // create target mesh from existing meshset
2002 EntityHandle target_root;
2003 CHKERR moab.create_meshset(MESHSET_SET, target_root);
2004 MOFEM_LOG("WORLD", Sev::inform)
2005 << "Creating target mesh from existing meshset";
2006 Range target_meshset_ents;
2007 CHKERR moab.get_entities_by_handle(0, target_meshset_ents);
2008 CHKERR moab.add_entities(target_root, target_meshset_ents);
2009
2010 // variables for tags to be broadcast later
2011 std::vector<Tag> interp_tags;
2012 std::vector<int> tag_length;
2013 std::vector<DataType> dtype;
2014 std::vector<TagType> storage;
2015
2016 // load source mesh
2017 Range targ_verts, targ_elems;
2018 if (world_rank == 0) {
2019 EntityHandle source_root;
2020 CHKERR moab.create_meshset(MESHSET_SET, source_root);
2021
2022 MOFEM_LOG("WORLD", Sev::inform) << "Loading source mesh on rank 0";
2023 auto rval_source_mesh = moab.load_file(
2024 meshTransferSourceMeshFileName.c_str(), &source_root, "");
2025 if (rval_source_mesh != MB_SUCCESS) {
2026 MOFEM_LOG("WORLD", Sev::warning) << "Error loading source mesh file: "
2028 }
2029 MOFEM_LOG("WORLD", Sev::inform) << "Source mesh loaded.";
2030
2031 Range src_elems;
2032 CHKERR moab.get_entities_by_dimension(source_root, 3, src_elems);
2033
2034 EntityHandle part_set;
2035 CHKERR pcomm0->create_part(part_set);
2036 CHKERR moab.add_entities(part_set, src_elems);
2037
2038 Range src_elems_part;
2039 CHKERR pcomm0->get_part_entities(src_elems_part, 3);
2040
2041 for (const auto &iterp_tag_name : listTagsToProject) {
2042 std::string tag_to_use = iterp_tag_name;
2043
2044 Tag interp_tag;
2045 CHKERR moab.tag_get_handle(tag_to_use.c_str(), interp_tag);
2046
2047 int interp_tag_len;
2048 CHKERR moab.tag_get_length(interp_tag, interp_tag_len);
2049
2050 if (interp_tag_len != 1 && interp_tag_len != 3 && interp_tag_len != 9) {
2051 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
2052 "Unsupported interpolation tag length: %d", interp_tag_len);
2053 }
2054
2055 // store tag info for later broadcast
2056 tag_length.push_back(interp_tag_len);
2057 dtype.push_back(DataType());
2058 storage.push_back(TagType());
2059 interp_tags.push_back(interp_tag);
2060 CHKERR moab.tag_get_data_type(interp_tag, dtype.back());
2061 CHKERR moab.tag_get_type(interp_tag, storage.back());
2062
2063 // coupler is collective
2064 Coupler mbc(&moab, pcomm0, src_elems_part, 0, true);
2065
2066 std::vector<double> vpos; // the positions we are interested in
2067 int num_pts = 0;
2068
2069 Range tmp_verts;
2070
2071 // First get all vertices adj to partition entities in target mesh
2072 CHKERR moab.get_entities_by_dimension(target_root, 3, targ_elems);
2073
2074 if (meshTransferInterpOrder == 0) {
2075 targ_verts = targ_elems;
2076 } else {
2077 CHKERR moab.get_adjacencies(targ_elems, 0, false, targ_verts,
2078 moab::Interface::UNION);
2079 }
2080
2081 // Then get non-owned verts and subtract
2082 CHKERR pcomm0->get_pstatus_entities(0, PSTATUS_NOT_OWNED, tmp_verts);
2083 targ_verts = subtract(targ_verts, tmp_verts);
2084
2085 // get position of these entities; these are the target points
2086 num_pts = (int)targ_verts.size();
2087 vpos.resize(3 * targ_verts.size());
2088 CHKERR moab.get_coords(targ_verts, &vpos[0]);
2089
2090 // Locate those points in the source mesh
2091 boost::shared_ptr<TupleList> tl_ptr;
2092 tl_ptr = boost::make_shared<TupleList>();
2093 CHKERR mbc.locate_points(&vpos[0], num_pts, 0, toler, tl_ptr.get(),
2094 false);
2095
2096 // If some points were not located, we need to process them
2097 auto find_missing_points = [&](Range &targ_verts, int &num_pts,
2098 std::vector<double> &vpos,
2099 Range &missing_verts) {
2101 int missing_pts_num = 0;
2102 int i = 0;
2103 auto vit = targ_verts.begin();
2104 for (; vit != targ_verts.end(); i++) {
2105 if (tl_ptr->vi_rd[3 * i + 1] == -1) {
2106 missing_verts.insert(*vit);
2107 vit = targ_verts.erase(vit);
2108 missing_pts_num++;
2109 } else {
2110 vit++;
2111 }
2112 }
2113
2114 int missing_pts_num_global = 0;
2115 // MPI_Allreduce(&missing_pts_num, &missing_pts_num_global, 1, MPI_INT,
2116 // MPI_SUM, pcomm0);
2117 if (missing_pts_num_global) {
2118 MOFEM_LOG("WORLD", Sev::warning)
2119 << missing_pts_num_global
2120 << " points in target mesh were not located in source mesh. ";
2121 }
2122
2123 if (missing_pts_num) {
2124 num_pts = (int)targ_verts.size();
2125 vpos.resize(3 * targ_verts.size());
2126 CHKERR moab.get_coords(targ_verts, &vpos[0]);
2127 tl_ptr->reset();
2128 CHKERR mbc.locate_points(&vpos[0], num_pts, 0, toler, tl_ptr.get(),
2129 false);
2130 }
2132 };
2133
2134 Range missing_verts;
2135 CHKERR find_missing_points(targ_verts, num_pts, vpos, missing_verts);
2136
2137 std::vector<double> source_data(interp_tag_len * src_elems.size(), 0.0);
2138 std::vector<double> target_data(interp_tag_len * num_pts, 0.0);
2139
2140 CHKERR moab.tag_get_data(interp_tag, src_elems, &source_data[0]);
2141
2142 Tag scalar_tag, adj_count_tag;
2143 double def_scl = 0;
2144 string scalar_tag_name = string(tag_to_use) + "_COMP";
2145 CHKERR moab.tag_get_handle(scalar_tag_name.c_str(), 1, MB_TYPE_DOUBLE,
2146 scalar_tag, MB_TAG_CREAT | MB_TAG_DENSE,
2147 &def_scl);
2148
2149 string adj_count_tag_name = "ADJ_COUNT";
2150 double def_adj = 0;
2151 CHKERR moab.tag_get_handle(adj_count_tag_name.c_str(), 1, MB_TYPE_DOUBLE,
2152 adj_count_tag, MB_TAG_CREAT | MB_TAG_DENSE,
2153 &def_adj);
2154
2155 // MBCoupler functionality supports only scalar tags. For the case of
2156 // vector or tensor tags we need to save each component as a scalar tag
2157 auto create_scalar_tags = [&](const Range &src_elems,
2158 const std::vector<double> &source_data,
2159 int itag) {
2161
2162 std::vector<double> source_data_scalar(src_elems.size());
2163 // Populate source_data_scalar
2164 for (int ielem = 0; ielem < src_elems.size(); ielem++) {
2165 source_data_scalar[ielem] =
2166 source_data[itag + ielem * interp_tag_len];
2167 }
2168
2169 // Set data on the scalar tag
2170 CHKERR moab.tag_set_data(scalar_tag, src_elems, &source_data_scalar[0]);
2171
2172 if (meshTransferInterpOrder == 1) {
2173 // Linear interpolation: compute average value of data on vertices
2174 Range src_verts;
2175 CHKERR moab.get_connectivity(src_elems, src_verts, true);
2176
2177 CHKERR moab.tag_clear_data(scalar_tag, src_verts, &def_scl);
2178 CHKERR moab.tag_clear_data(adj_count_tag, src_verts, &def_adj);
2179
2180 for (auto &tet : src_elems) {
2181 double tet_data = 0;
2182 CHKERR moab.tag_get_data(scalar_tag, &tet, 1, &tet_data);
2183
2184 Range adj_verts;
2185 CHKERR moab.get_connectivity(&tet, 1, adj_verts, true);
2186
2187 std::vector<double> adj_vert_data(adj_verts.size(), 0.0);
2188 std::vector<double> adj_vert_count(adj_verts.size(), 0.0);
2189
2190 CHKERR moab.tag_get_data(scalar_tag, adj_verts, &adj_vert_data[0]);
2191 CHKERR moab.tag_get_data(adj_count_tag, adj_verts,
2192 &adj_vert_count[0]);
2193
2194 for (int ivert = 0; ivert < adj_verts.size(); ivert++) {
2195 adj_vert_data[ivert] += tet_data;
2196 adj_vert_count[ivert] += 1;
2197 }
2198
2199 CHKERR moab.tag_set_data(scalar_tag, adj_verts, &adj_vert_data[0]);
2200 CHKERR moab.tag_set_data(adj_count_tag, adj_verts,
2201 &adj_vert_count[0]);
2202 }
2203
2204 // Reduce tags for the parallel case
2205 std::vector<Tag> tags = {scalar_tag, adj_count_tag};
2206 pcomm0->reduce_tags(tags, tags, MPI_SUM, src_verts);
2207
2208 std::vector<double> src_vert_data(src_verts.size(), 0.0);
2209 std::vector<double> src_vert_adj_count(src_verts.size(), 0.0);
2210
2211 CHKERR moab.tag_get_data(scalar_tag, src_verts, &src_vert_data[0]);
2212 CHKERR moab.tag_get_data(adj_count_tag, src_verts,
2213 &src_vert_adj_count[0]);
2214
2215 for (int ivert = 0; ivert < src_verts.size(); ivert++) {
2216 src_vert_data[ivert] /= src_vert_adj_count[ivert];
2217 }
2218 CHKERR moab.tag_set_data(scalar_tag, src_verts, &src_vert_data[0]);
2219 }
2221 };
2222
2223 MOFEM_LOG("WORLD", Sev::inform)
2224 << "Performing interpolation for tag: " << tag_to_use;
2225 MOFEM_LOG("WORLD", Sev::inform)
2226 << "Number of target points to interpolate: " << num_pts;
2227 MOFEM_LOG("WORLD", Sev::inform)
2228 << "Interpolation method: "
2229 << (method == Coupler::CONSTANT ? "constant" : "linear FE");
2230 MOFEM_LOG("WORLD", Sev::inform)
2231 << "Number of components in tag: " << interp_tag_len;
2232
2233 MOFEM_LOG("WORLD", Sev::inform)
2234 << "Source tag data range: ["
2235 << *std::min_element(source_data.begin(), source_data.end()) << ", "
2236 << *std::max_element(source_data.begin(), source_data.end()) << "]";
2237
2238 for (int itag = 0; itag < interp_tag_len; itag++) {
2239
2240 CHKERR create_scalar_tags(src_elems, source_data, itag);
2241
2242 std::vector<double> target_data_scalar(num_pts, 0.0);
2243 CHKERR mbc.interpolate(method, scalar_tag_name, &target_data_scalar[0],
2244 tl_ptr.get());
2245
2246 for (int ielem = 0; ielem < num_pts; ielem++) {
2247 target_data[itag + ielem * interp_tag_len] =
2248 target_data_scalar[ielem];
2249 }
2250 }
2251
2252 // Use original tag
2253 CHKERR moab.tag_set_data(interp_tag, targ_verts, &target_data[0]);
2254
2255 if (missing_verts.size() && (meshTransferInterpOrder == 1) &&
2257 MOFEM_LOG("WORLD", Sev::warning)
2258 << "Using hybrid interpolation for "
2259 "missing points in the target mesh.";
2260 Range missing_adj_elems;
2261 CHKERR moab.get_adjacencies(missing_verts, 3, false, missing_adj_elems,
2262 moab::Interface::UNION);
2263
2264 int num_adj_elems = (int)missing_adj_elems.size();
2265 std::vector<double> vpos_adj_elems;
2266
2267 vpos_adj_elems.resize(3 * missing_adj_elems.size());
2268 CHKERR moab.get_coords(missing_adj_elems, &vpos_adj_elems[0]);
2269
2270 // Locate those points in the source mesh
2271 tl_ptr->reset();
2272 CHKERR mbc.locate_points(&vpos_adj_elems[0], num_adj_elems, 0, toler,
2273 tl_ptr.get(), false);
2274
2275 Range missing_tets;
2276 CHKERR find_missing_points(missing_adj_elems, num_adj_elems,
2277 vpos_adj_elems, missing_tets);
2278 if (missing_tets.size()) {
2279 MOFEM_LOG("WORLD", Sev::warning)
2280 << missing_tets.size()
2281 << " points in target mesh were not located in source mesh. ";
2282 }
2283
2284 std::vector<double> target_data_adj_elems(
2285 interp_tag_len * num_adj_elems, 0.0);
2286
2287 for (int itag = 0; itag < interp_tag_len; itag++) {
2288 CHKERR create_scalar_tags(src_elems, source_data, itag);
2289
2290 std::vector<double> target_data_adj_elems_scalar(num_adj_elems, 0.0);
2291 CHKERR mbc.interpolate(method, scalar_tag_name,
2292 &target_data_adj_elems_scalar[0],
2293 tl_ptr.get());
2294
2295 for (int ielem = 0; ielem < num_adj_elems; ielem++) {
2296 target_data_adj_elems[itag + ielem * interp_tag_len] =
2297 target_data_adj_elems_scalar[ielem];
2298 }
2299 }
2300
2301 CHKERR moab.tag_set_data(interp_tag, missing_adj_elems,
2302 &target_data_adj_elems[0]);
2303
2304 // FIXME: add implementation for parallel case
2305 for (auto &vert : missing_verts) {
2306 Range adj_elems;
2307 CHKERR moab.get_adjacencies(&vert, 1, 3, false, adj_elems,
2308 moab::Interface::UNION);
2309
2310 std::vector<double> adj_elems_data(adj_elems.size() * interp_tag_len,
2311 0.0);
2312 CHKERR moab.tag_get_data(interp_tag, adj_elems, &adj_elems_data[0]);
2313
2314 std::vector<double> vert_data(interp_tag_len, 0.0);
2315 for (int itag = 0; itag < interp_tag_len; itag++) {
2316 for (int i = 0; i < adj_elems.size(); i++) {
2317 vert_data[itag] += adj_elems_data[i * interp_tag_len + itag];
2318 }
2319 vert_data[itag] /= adj_elems.size();
2320 }
2321 CHKERR moab.tag_set_data(interp_tag, &vert, 1, &vert_data[0]);
2322 }
2323 }
2324
2325 CHKERR moab.tag_delete(scalar_tag);
2326 CHKERR moab.tag_delete(adj_count_tag);
2327 }
2328
2329 // delete source mesh after projection but keep the tags info for broadcast
2330 Range src_mesh_ents;
2331 CHKERR moab.get_entities_by_handle(source_root, src_mesh_ents);
2332 CHKERR moab.delete_entities(&source_root, 1);
2333 CHKERR moab.delete_entities(src_mesh_ents);
2334 CHKERR moab.delete_entities(&part_set, 1);
2335 }
2336
2337 // broadcast tag info to other processors
2338 int tag_size = tag_length.size();
2339 MPI_Bcast(&tag_size, 1, MPI_INT, 0, PETSC_COMM_WORLD);
2340 if (rank != 0) {
2341 interp_tags.resize(tag_size);
2342 tag_length.resize(tag_size);
2343 dtype.resize(tag_size);
2344 storage.resize(tag_size);
2345 }
2346 MPI_Bcast(interp_tags.data(), tag_size, MPI_INT, 0, PETSC_COMM_WORLD);
2347 MPI_Bcast(tag_length.data(), tag_size, MPI_INT, 0, PETSC_COMM_WORLD);
2348 MPI_Bcast(dtype.data(), tag_size, MPI_INT, 0, PETSC_COMM_WORLD);
2349 MPI_Bcast(storage.data(), tag_size, MPI_INT, 0, PETSC_COMM_WORLD);
2350
2351 // create new tag on other processors
2352 // loop over tag index to support multiple tags projection in one run
2353
2354 for (size_t index = 0; index < interp_tags.size(); index++) {
2355 // check if tag exists first
2356 if (world_rank) {
2357 Tag old_interp_tag;
2358 auto rval_check_tag =
2359 moab.tag_get_handle(listTagsToProject[index].c_str(), old_interp_tag);
2360 if (rval_check_tag == MB_SUCCESS) {
2361 MOFEM_LOG("WORLD", Sev::verbose)
2362 << "Deleting existing tag on target mesh (post-projection): "
2363 << listTagsToProject[index];
2364 CHKERR moab.tag_delete(old_interp_tag);
2365 }
2366 }
2367 Tag interp_tag_all;
2368 unsigned flags =
2369 MB_TAG_CREAT | storage[index]; // e.g., MB_TAG_DENSE or MB_TAG_SPARSE
2370 std::vector<double> def_val(tag_length[index], 0.);
2371 auto rval = moab.tag_get_handle(listTagsToProject[index].c_str(),
2372 tag_length[index], dtype[index],
2373 interp_tag_all, flags, def_val.data());
2374 if (rval != MB_SUCCESS && world_rank) {
2375 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2376 "Unable to create projection tag %s",
2377 listTagsToProject[index].c_str());
2378 }
2379
2380 MPI_Barrier(PETSC_COMM_WORLD);
2381
2382 // exchange data for all entity types across all processors
2383 auto vertex_exchange = CommInterface::createEntitiesPetscVector(
2384 mField.get_comm(), mField.get_moab(), 0, tag_length[index],
2385 Sev::inform);
2386 auto volume_exchange = CommInterface::createEntitiesPetscVector(
2387 mField.get_comm(), mField.get_moab(), 3, tag_length[index],
2388 Sev::inform);
2389
2391 mField.get_moab(), vertex_exchange, interp_tag_all);
2393 mField.get_moab(), volume_exchange, interp_tag_all);
2394 }
2395
2396 // delete target meshset but not the entities
2397 CHKERR moab.delete_entities(&target_root, 1);
2398
2399#endif // INCLUDE_MBCOUPLER
2401}
#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.

◆ pushNoStretchVolumeA00Ops()

MoFEMErrorCode EshelbianCore::pushNoStretchVolumeA00Ops ( boost::shared_ptr< VolumeElementForcesAndSourcesCore fe_lhs)
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 3167 of file EshelbianPlasticity.cpp.

3168 {
3170
3171 bool has_nonhomogeneous_mat_block =
3173 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dP_dP(
3174 piolaStress, piolaStress, dataAtPts, has_nonhomogeneous_mat_block));
3175 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dBubble_dP(
3176 bubbleField, piolaStress, dataAtPts, has_nonhomogeneous_mat_block));
3177 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dBubble_dBubble(
3178 bubbleField, bubbleField, dataAtPts, has_nonhomogeneous_mat_block));
3179
3180 fe_lhs->getOpPtrVector().push_back(new OpSpatialEquilibrium_dw_dP(
3182 fe_lhs->getOpPtrVector().push_back(new OpSpatialEquilibrium_dw_dw(
3184
3185 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dP_domega(
3187 symmetrySelector == SYMMETRIC ? true : false));
3188 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dBubble_domega(
3190 symmetrySelector == SYMMETRIC ? true : false));
3191
3192 if (symmetrySelector > SYMMETRIC) {
3193 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_dP(
3194 rotAxis, piolaStress, dataAtPts, false));
3195 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_dBubble(
3196 rotAxis, bubbleField, dataAtPts, false));
3197 }
3198 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_domega(
3202
3204}
static constexpr enum SymmetrySelector symmetrySelector
static bool hasNonHomogeneousMaterialBlock

◆ pushPiolaStressGramOps()

MoFEMErrorCode EshelbianCore::pushPiolaStressGramOps ( boost::shared_ptr< VolumeElementForcesAndSourcesCore fe_lhs)
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 3260 of file EshelbianPlasticity.cpp.

3261 {
3263 fe_lhs->getOpPtrVector().push_back(
3266}
FormsIntegrators< VolUserDataOperator >::Assembly< A >::BiLinearForm< GAUSS >::OpMass< 3, 9 > OpStressGram_dP_dP

◆ pushStressGramOps()

MoFEMErrorCode EshelbianCore::pushStressGramOps ( boost::shared_ptr< VolumeElementForcesAndSourcesCore fe_lhs)
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 3249 of file EshelbianPlasticity.cpp.

3250 {
3253 fe_lhs->getOpPtrVector().push_back(
3255 fe_lhs->getOpPtrVector().push_back(new OpStressGram_dBubble_dBubble(
3258}
FormsIntegrators< VolUserDataOperator >::Assembly< A >::BiLinearForm< GAUSS >::OpMass< 9, 9 > OpStressGram_dBubble_dBubble
MoFEMErrorCode pushPiolaStressGramOps(boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe_lhs)

◆ pushStretchVolumeA00Ops()

MoFEMErrorCode EshelbianCore::pushStretchVolumeA00Ops ( boost::shared_ptr< VolumeElementForcesAndSourcesCore fe_lhs)
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 3206 of file EshelbianPlasticity.cpp.

3207 {
3209
3210 fe_lhs->getOpPtrVector().push_back(
3211 physicalEquations->returnOpSpatialPhysical_du_du(
3213 fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_dP(
3215 fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_dBubble(
3217 fe_lhs->getOpPtrVector().push_back(new OpSpatialPhysical_du_domega(
3219 symmetrySelector == SYMMETRIC ? true : false));
3220
3221 fe_lhs->getOpPtrVector().push_back(new OpSpatialEquilibrium_dw_dP(
3223 fe_lhs->getOpPtrVector().push_back(new OpSpatialEquilibrium_dw_dw(
3225
3226 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dP_domega(
3228 symmetrySelector == SYMMETRIC ? true : false));
3229 fe_lhs->getOpPtrVector().push_back(new OpSpatialConsistency_dBubble_domega(
3231 symmetrySelector == SYMMETRIC ? true : false));
3232
3233 if (symmetrySelector > SYMMETRIC) {
3234 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_du(
3235 rotAxis, stretchTensor, dataAtPts, false));
3236 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_dP(
3237 rotAxis, piolaStress, dataAtPts, false));
3238 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_dBubble(
3239 rotAxis, bubbleField, dataAtPts, false));
3240 }
3241 fe_lhs->getOpPtrVector().push_back(new OpSpatialRotation_domega_domega(
3245
3247}

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

924 {
925 *iface = const_cast<EshelbianCore *>(this);
926 return 0;
927}

◆ saveOrgCoords()

MoFEMErrorCode EshelbianCore::saveOrgCoords ( )

Definition at line 2833 of file EshelbianFracture.cpp.

2833 {
2835 auto crack_faces =
2836 get_range_from_block(mField, "CRACK_COMPUTED", SPACE_DIM - 1);
2837 Range conn;
2838 CHKERR mField.get_moab().get_connectivity(crack_faces, conn, true);
2839 Range verts;
2840 CHKERR mField.get_moab().get_entities_by_type(0, MBVERTEX, verts);
2841 verts = subtract(verts, conn);
2842 std::vector<double> coords(3 * verts.size());
2843 CHKERR mField.get_moab().get_coords(verts, coords.data());
2844 double def_coords[] = {0., 0., 0.};
2845 Tag th_org_coords;
2846 CHKERR mField.get_moab().tag_get_handle(
2847 "ORG_COORDS", 3, MB_TYPE_DOUBLE, th_org_coords,
2848 MB_TAG_CREAT | MB_TAG_DENSE, def_coords);
2849 CHKERR mField.get_moab().tag_set_data(th_org_coords, verts, coords.data());
2851}

◆ setBaseVolumeElementOps()

MoFEMErrorCode EshelbianCore::setBaseVolumeElementOps ( const int  tag,
const bool  do_rhs,
const bool  do_lhs,
const bool  calc_rates,
boost::shared_ptr< VolumeElementForcesAndSourcesCore fe,
const bool  add_bubble = true 
)
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 3057 of file EshelbianPlasticity.cpp.

3060 {
3062
3063 auto bubble_cache =
3064 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0, MatrixDouble());
3065 fe->getUserPolynomialBase() =
3066 boost::make_shared<CGGUserPolynomialBase>(bubble_cache);
3067 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3068 fe->getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions, frontAdjEdges);
3069
3070 // set integration rule
3071 fe->getRuleHook = [](int, int, int) { return -1; };
3072 // auto vol_rule = (SMALL_ROT > 0) ? vol_rule_lin : vol_rule_no_lin;
3073 fe->setRuleHook = SetIntegrationAtFrontVolume(frontVertices, frontAdjEdges,
3074 vol_rule, bubble_cache);
3075 // fe->getRuleHook = VolRule();
3076
3077 if (!dataAtPts) {
3078 dataAtPts =
3079 boost::shared_ptr<DataAtIntegrationPts>(new DataAtIntegrationPts());
3080 dataAtPts->physicsPtr = physicalEquations;
3081 }
3082
3083 // calculate fields values
3084 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
3085 piolaStress, dataAtPts->getApproxPAtPts()));
3086 if (add_bubble) {
3087 fe->getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
3088 bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
3089 }
3090 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorDivergence<3, 3>(
3091 piolaStress, dataAtPts->getDivPAtPts()));
3092 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
3093 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
3094
3095 if (isNoStretch()) {
3097 fe->getOpPtrVector(), physicalEquations, dataAtPts,
3099 } else {
3100 fe->getOpPtrVector().push_back(
3102 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
3103 }
3104
3105 CHKERR VecSetDM(solTSStep, PETSC_NULLPTR);
3106 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
3107 piolaStress, dataAtPts->getApproxP0AtPts(), nullptr, solTSStep));
3108 if (!isNoStretch()) {
3109 fe->getOpPtrVector().push_back(new OpCalculateTensor2SymmetricFieldValues<3>(
3110 stretchTensor, dataAtPts->getLogStretchTensor0AtPts(), solTSStep,
3111 MBTET));
3112 }
3113
3114 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
3115 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
3116 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldGradient<3, 3>(
3117 rotAxis, dataAtPts->getRotAxisGradAtPts(), MBTET));
3118 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
3119 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
3120
3121 // H1 displacements
3122 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
3123 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
3124 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldGradient<3, 3>(
3125 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
3126
3127 // velocities
3128 if (calc_rates) {
3129 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValuesDot<3>(
3130 spatialL2Disp, dataAtPts->getSmallWL2DotAtPts(), MBTET));
3131 if (isNoStretch()) {
3132 } else {
3133 fe->getOpPtrVector().push_back(
3135 stretchTensor, dataAtPts->getLogStretchDotTensorAtPts(), MBTET));
3136 fe->getOpPtrVector().push_back(
3138 stretchTensor, dataAtPts->getGradLogStretchDotTensorAtPts(),
3139 MBTET));
3140 }
3141 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValuesDot<3>(
3142 rotAxis, dataAtPts->getRotAxisDotAtPts(), MBTET));
3143 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldGradientDot<3, 3>(
3144 rotAxis, dataAtPts->getRotAxisGradDotAtPts(), MBTET));
3145
3146 // acceleration
3147 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
3148 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValuesDotDot<3>(
3149 spatialL2Disp, dataAtPts->getSmallWL2DotDotAtPts(), MBTET));
3150 }
3151 }
3152
3153 // calculate other derived quantities
3154 fe->getOpPtrVector().push_back(
3156
3157 // evaluate integration points
3158 if (isNoStretch()) {
3159 } else {
3160 fe->getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
3161 do_rhs, do_lhs, dataAtPts, physicalEquations));
3162 }
3163
3165}
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 4646 of file EshelbianPlasticity.cpp.

4646 {
4648
4649 auto set_block = [&](auto name, int dim) {
4650 std::map<int, Range> map;
4651 auto set_tag_impl = [&](auto name) {
4653 auto mesh_mng = mField.getInterface<MeshsetsManager>();
4654 auto bcs = mesh_mng->getCubitMeshsetPtr(
4655
4656 std::regex((boost::format("%s(.*)") % name).str())
4657
4658 );
4659 for (auto bc : bcs) {
4660 Range r;
4661 CHKERR bc->getMeshsetIdEntitiesByDimension(mField.get_moab(), dim, r,
4662 true);
4663 map[bc->getMeshsetId()] = r;
4664 MOFEM_LOG("EP", Sev::inform)
4665 << "Block " << name << " id " << bc->getMeshsetId() << " has "
4666 << r.size() << " entities";
4667 }
4669 };
4670
4671 CHKERR set_tag_impl(name);
4672
4673 return std::make_pair(name, map);
4674 };
4675
4676 auto set_skin = [&](auto &&map) {
4677 for (auto &m : map.second) {
4678 auto s = filter_true_skin(mField, get_skin(mField, m.second));
4679 m.second.swap(s);
4680 MOFEM_LOG("EP", Sev::inform)
4681 << "Skin for block " << map.first << " id " << m.first << " has "
4682 << m.second.size() << " entities";
4683 }
4684 return map;
4685 };
4686
4687 auto set_tag = [&](auto &&map) {
4688 Tag th;
4689 auto name = map.first;
4690 int def_val[] = {-1};
4692 mField.get_moab().tag_get_handle(name, 1, MB_TYPE_INTEGER, th,
4693 MB_TAG_SPARSE | MB_TAG_CREAT, def_val),
4694 "create tag");
4695 for (auto &m : map.second) {
4696 int id = m.first;
4697 CHK_MOAB_THROW(mField.get_moab().tag_clear_data(th, m.second, &id),
4698 "clear tag");
4699 }
4700 return th;
4701 };
4702
4703 listTagsToTransfer.push_back(set_tag(set_skin(set_block("BODY", 3))));
4704 listTagsToTransfer.push_back(set_tag(set_skin(set_block("MAT_ELASTIC", 3))));
4705 listTagsToTransfer.push_back(
4706 set_tag(set_skin(set_block("MAT_NEOHOOKEAN", 3))));
4707 listTagsToTransfer.push_back(set_tag(set_block("CONTACT", 2)));
4708
4710}
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 4161 of file EshelbianPlasticity.cpp.

4165 {
4167 fe_contact_tree = createContactDetectionFiniteElement(*this);
4169}
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 4171 of file EshelbianPlasticity.cpp.

4171 {
4173
4174 // Add contact operators. Note that only for rhs. THe lhs is assembled with
4175 // volume element, to enable schur complement evaluation.
4177
4180
4181 auto adj_cache =
4182 boost::make_shared<ForcesAndSourcesCore::UserDataOperator::AdjCache>();
4183
4184 auto get_op_contact_bc = [&]() {
4186 auto op_loop_side = new OpLoopSide<SideEle>(
4187 mField, contactElement, SPACE_DIM - 1, Sev::noisy, adj_cache);
4188 return op_loop_side;
4189 };
4190
4192}
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:62

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

4194 {
4196 boost::shared_ptr<FEMethod> null;
4197
4198 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
4199
4201 null);
4203 null);
4205 null);
4207 null);
4208
4209 } else {
4211 null);
4213 null);
4215 null);
4217 null);
4218 }
4219
4221}
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 3976 of file EshelbianPlasticity.cpp.

3979 {
3981
3982 fe_rhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
3983 fe_lhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
3984
3985 // set integration rule
3986 // fe_rhs->getRuleHook = [](int, int, int p) { return 2 * (p + 1); };
3987 // fe_lhs->getRuleHook = [](int, int, int p) { return 2 * (p + 1); };
3988 fe_rhs->getRuleHook = [](int, int, int) { return -1; };
3989 fe_lhs->getRuleHook = [](int, int, int) { return -1; };
3990 fe_rhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3991 fe_lhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3992
3993 CHKERR
3994 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3995 fe_rhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
3996 CHKERR
3997 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3998 fe_lhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
3999
4000 if (add_elastic) {
4001
4002 auto get_broken_op_side = [this](auto &pip) {
4003 using EleOnSide =
4005 using SideEleOp = EleOnSide::UserDataOperator;
4006 // Iterate over domain FEs adjacent to boundary.
4007 auto broken_data_ptr =
4008 boost::make_shared<std::vector<BrokenBaseSideData>>();
4009 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
4010 auto op_loop_domain_side = new OpLoopSide<EleOnSide>(
4011 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
4012 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
4013 boost::make_shared<CGGUserPolynomialBase>(nullptr, true);
4014 CHKERR
4015 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4016 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
4018 op_loop_domain_side->getOpPtrVector().push_back(
4019 new OpGetBrokenBaseSideData<SideEleOp>(piolaStress, broken_data_ptr));
4020 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
4021 op_loop_domain_side->getOpPtrVector().push_back(
4023 flux_mat_ptr));
4024 op_loop_domain_side->getOpPtrVector().push_back(
4025 new OpSetFlux<SideEleOp>(broken_data_ptr, flux_mat_ptr));
4026 pip.push_back(op_loop_domain_side);
4027 return broken_data_ptr;
4028 };
4029
4030 auto set_rhs = [&]() {
4032
4033 auto broken_data_ptr = get_broken_op_side(fe_rhs->getOpPtrVector());
4034
4035 fe_rhs->getOpPtrVector().push_back(
4036 new OpDispBc(broken_data_ptr, bcSpatialDispVecPtr, timeScaleMap));
4037 fe_rhs->getOpPtrVector().push_back(new OpAnalyticalDispBc(
4039 timeScaleMap));
4040 fe_rhs->getOpPtrVector().push_back(new OpRotationBc(
4041 broken_data_ptr, bcSpatialRotationVecPtr, timeScaleMap));
4042
4043 auto piola_scale_ptr = boost::make_shared<double>(1.0);
4044 fe_rhs->getOpPtrVector().push_back(
4046 piola_scale_ptr, timeScaleMap));
4047 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
4048 // if you push gradient of L2 base to physical element, it will not work.
4049 fe_rhs->getOpPtrVector().push_back(
4051 hybridSpatialDisp, hybrid_grad_ptr));
4052 fe_rhs->getOpPtrVector().push_back(new OpBrokenPressureBc(
4054 hybrid_grad_ptr, timeScaleMap));
4055 fe_rhs->getOpPtrVector().push_back(new OpBrokenAnalyticalTractionBc(
4057 timeScaleMap));
4058
4059 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
4060 fe_rhs->getOpPtrVector().push_back(
4062 hybrid_ptr));
4063 fe_rhs->getOpPtrVector().push_back(new OpNormalDispRhsBc(
4064 hybridSpatialDisp, hybrid_ptr, broken_data_ptr,
4066 fe_rhs->getOpPtrVector().push_back(
4067 new OpSpringRhsBc(hybridSpatialDisp, hybrid_ptr, broken_data_ptr,
4069
4070 auto get_normal_disp_bc_faces = [&]() {
4071 auto faces =
4072 get_range_from_block(mField, "NORMAL_DISPLACEMENT", SPACE_DIM - 1);
4073 return boost::make_shared<Range>(faces);
4074 };
4075
4076 auto get_spring_bc_faces = [&]() {
4077 auto faces = get_range_from_block(mField, "SPRING_BC", SPACE_DIM - 1);
4078 return boost::make_shared<Range>(faces);
4079 };
4080
4081 using BoundaryEle =
4083 using BdyEleOp = BoundaryEle::UserDataOperator;
4085 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
4086 fe_rhs->getOpPtrVector().push_back(new OpC_dBroken(
4087 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0),
4088 get_normal_disp_bc_faces()));
4089 fe_rhs->getOpPtrVector().push_back(new OpC_dBroken(
4090 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0),
4091 get_spring_bc_faces()));
4092
4094 };
4095
4096 auto set_lhs = [&]() {
4098
4099 auto broken_data_ptr = get_broken_op_side(fe_lhs->getOpPtrVector());
4100
4101 fe_lhs->getOpPtrVector().push_back(new OpNormalDispLhsBc_dU(
4103 fe_lhs->getOpPtrVector().push_back(new OpNormalDispLhsBc_dP(
4105 timeScaleMap));
4106 fe_lhs->getOpPtrVector().push_back(
4108 fe_lhs->getOpPtrVector().push_back(new OpSpringLhsBc_dP(
4109 hybridSpatialDisp, broken_data_ptr, bcSpatialSpringVecPtr));
4110
4111 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
4112 // if you push gradient of L2 base to physical element, it will not work.
4113 fe_lhs->getOpPtrVector().push_back(
4115 hybridSpatialDisp, hybrid_grad_ptr));
4116 fe_lhs->getOpPtrVector().push_back(new OpBrokenPressureBcLhs_dU(
4118 timeScaleMap));
4119
4120 auto get_normal_disp_bc_faces = [&]() {
4121 auto faces =
4122 get_range_from_block(mField, "NORMAL_DISPLACEMENT", SPACE_DIM - 1);
4123 return boost::make_shared<Range>(faces);
4124 };
4125
4126 auto get_spring_bc_faces = [&]() {
4127 auto faces = get_range_from_block(mField, "SPRING_BC", SPACE_DIM - 1);
4128 return boost::make_shared<Range>(faces);
4129 };
4130
4131 using BoundaryEle =
4133 using BdyEleOp = BoundaryEle::UserDataOperator;
4135 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
4136 fe_lhs->getOpPtrVector().push_back(new OpC(
4137 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0),
4138 true, true, get_normal_disp_bc_faces()));
4139 fe_lhs->getOpPtrVector().push_back(new OpC(
4140 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0),
4141 true, true, get_spring_bc_faces()));
4142
4144 };
4145
4146 CHKERR set_rhs();
4147 CHKERR set_lhs();
4148 }
4149
4151}
@ 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 2061 of file EshelbianFracture.cpp.

2061 {
2063
2064 if (!maxMovedFaces)
2066
2067 Tag th_front_position;
2068 auto rval =
2069 mField.get_moab().tag_get_handle("FrontPosition", th_front_position);
2070 if (rval == MB_SUCCESS && maxMovedFaces) {
2071 Range verts;
2072 CHKERR mField.get_moab().get_connectivity(*maxMovedFaces, verts, true);
2073 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(verts);
2074 std::vector<double> coords(3 * verts.size());
2075 CHKERR mField.get_moab().get_coords(verts, coords.data());
2076 std::vector<double> pos(3 * verts.size());
2077 CHKERR mField.get_moab().tag_get_data(th_front_position, verts, pos.data());
2078 for (int i = 0; i != 3 * verts.size(); ++i) {
2079 coords[i] += pos[i];
2080 }
2081 CHKERR mField.get_moab().set_coords(verts, coords.data());
2082 double zero[] = {0., 0., 0.};
2083 CHKERR mField.get_moab().tag_clear_data(th_front_position, verts, zero);
2084 }
2085
2086#ifndef NDEBUG
2087 constexpr bool debug = false;
2088 if (debug) {
2089
2091 mField.get_moab(),
2092 "set_coords_faces_" +
2093 boost::lexical_cast<std::string>(mField.get_comm_rank()) + ".vtk",
2094 *maxMovedFaces);
2095 }
2096#endif
2098}

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

3271 {
3273
3274 /** Contact requires that body is marked */
3275 auto get_body_range = [this](auto name, int dim) {
3276 std::map<int, Range> map;
3277
3278 for (auto m_ptr :
3279 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
3280
3281 (boost::format("%s(.*)") % name).str()
3282
3283 ))
3284
3285 ) {
3286 Range ents;
3287 CHK_MOAB_THROW(m_ptr->getMeshsetIdEntitiesByDimension(mField.get_moab(),
3288 dim, ents, true),
3289 "by dim");
3290 map[m_ptr->getMeshsetId()] = ents;
3291 }
3292
3293 return map;
3294 };
3295
3296 auto local_tau_sacale = boost::make_shared<double>(1.0);
3297 using BoundaryEle =
3299 using BdyEleOp = BoundaryEle::UserDataOperator;
3300 struct OpSetTauScale : public BdyEleOp {
3301 OpSetTauScale(boost::shared_ptr<double> local_tau_sacale, double alphaTau,
3302 double alphaTau0,
3303 boost::shared_ptr<MatrixDouble> flux_mat_ptr)
3304 : BdyEleOp(NOSPACE, BdyEleOp::OPSPACE),
3305 localTauSacale(local_tau_sacale), alphaTau(alphaTau),
3306 alphaTau0(alphaTau0), fluxMatPtr(flux_mat_ptr) {}
3307 MoFEMErrorCode doWork(int side, EntityType type,
3308 EntitiesFieldData::EntData &data) override {
3310 auto &coords = BdyEleOp::getCoords();
3311 auto [centre, barycenter, h] =
3312 Tools::getTricircumcenter3d(coords.data().data());
3313
3314 FTENSOR_INDEXES(3, i, J);
3315 auto t_P = getFTensor2FromMat<3, 3>(fluxMatPtr);
3316 auto t_normal = getFTensor1NormalsAtGaussPts();
3317 auto t_w = getFTensor0IntegrationWeight();
3318 auto nb_gauss_pts = getGaussPts().size2();
3319 double norm = 0;
3320 for (auto gg = 0; gg != nb_gauss_pts; ++gg) {
3322 t_t(i) = t_P(i, J) * t_normal(J);
3323 norm += t_w * sqrt(t_t(i) * t_t(i));
3324 ++t_w;
3325 ++t_normal;
3326 ++t_P;
3327 }
3328
3329 *localTauSacale = (alphaTau / h) + alphaTau0 * norm;
3330
3332 }
3333
3334 private:
3335 boost::shared_ptr<double> localTauSacale;
3336 boost::shared_ptr<MatrixDouble> fluxMatPtr;
3337 double alphaTau;
3338 double alphaTau0;
3339 };
3340
3341 auto not_interface_face = [this](FEMethod *fe_method_ptr) {
3342 auto ent = fe_method_ptr->getFEEntityHandle();
3343 if (
3344
3345 (interfaceFaces->find(ent) != interfaceFaces->end())
3346
3347 || (crackFaces->find(ent) != crackFaces->end())
3348
3349 ) {
3350 return false;
3351 };
3352 return true;
3353 };
3354
3355 // Right hand side
3356 fe_rhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
3357 CHKERR setBaseVolumeElementOps(tag, true, false, true, fe_rhs);
3358
3359 // elastic
3360 if (add_elastic) {
3361
3362 fe_rhs->getOpPtrVector().push_back(
3364 fe_rhs->getOpPtrVector().push_back(
3368 if (isNoStretch()) {
3369 // do nothing - no stretch approximation
3370 } else {
3371 if (!internalStressTagName.empty()) {
3372 switch (meshTransferInterpOrder) {
3373 case 0:
3374 fe_rhs->getOpPtrVector().push_back(
3376 break;
3377 case 1:
3378 fe_rhs->getOpPtrVector().push_back(
3380 break;
3381 default:
3382 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
3383 "Unsupported mesh transfer interpolation order %d, for "
3384 "internal stress",
3386 }
3387 // set default time scaling for interal stresses to constant
3388 TimeScale::ScalingFun def_scaling_fun = [](double time) { return 1; };
3389 auto ts_internal_stress =
3390 boost::make_shared<DynamicRelaxationTimeScale>(
3391 "internal_stress_history.txt", false, def_scaling_fun);
3392 if (internalStressVoigt) {
3393 fe_rhs->getOpPtrVector().push_back(
3395 stretchTensor, dataAtPts, ts_internal_stress));
3396 } else {
3397 fe_rhs->getOpPtrVector().push_back(
3399 stretchTensor, dataAtPts, ts_internal_stress));
3400 }
3401 }
3402 if (auto op = physicalEquations->returnOpSpatialPhysicalExternalStrain(
3404 fe_rhs->getOpPtrVector().push_back(op);
3405 } else if (externalStrainVecPtr && !externalStrainVecPtr->empty()) {
3406 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
3407 "OpSpatialPhysicalExternalStrain not implemented for this "
3408 "material");
3409 }
3410
3411 fe_rhs->getOpPtrVector().push_back(
3412 physicalEquations->returnOpSpatialPhysical(stretchTensor, dataAtPts,
3413 alphaU));
3414 }
3415 fe_rhs->getOpPtrVector().push_back(
3417 fe_rhs->getOpPtrVector().push_back(
3419 fe_rhs->getOpPtrVector().push_back(
3421
3422 auto set_hybridisation_rhs = [&](auto &pip) {
3424
3425 using BoundaryEle =
3427 using EleOnSide =
3429 using SideEleOp = EleOnSide::UserDataOperator;
3430 using BdyEleOp = BoundaryEle::UserDataOperator;
3431
3432 // First: Iterate over skeleton FEs adjacent to Domain FEs
3433 // Note: BoundaryEle, i.e. uses skeleton interation rule
3434 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
3435 mField, skeletonElement, SPACE_DIM - 1, Sev::noisy);
3436 // op_loop_skeleton_side->getSideFEPtr()->getRuleHook = FaceRule();
3437 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3438 return -1;
3439 };
3440 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3441 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3442
3443 CHKERR EshelbianPlasticity::
3444 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3445 op_loop_skeleton_side->getOpPtrVector(), {L2},
3447
3448 // Second: Iterate over domain FEs adjacent to skelton, particularly one
3449 // domain element.
3450 auto broken_data_ptr =
3451 boost::make_shared<std::vector<BrokenBaseSideData>>();
3452 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
3453 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
3454 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
3455 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3456 boost::make_shared<CGGUserPolynomialBase>(nullptr, true);
3457 CHKERR
3458 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3459 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3461 op_loop_domain_side->getOpPtrVector().push_back(
3462 new OpGetBrokenBaseSideData<SideEleOp>(piolaStress, broken_data_ptr));
3463 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
3464 op_loop_domain_side->getOpPtrVector().push_back(
3466 flux_mat_ptr));
3467 op_loop_domain_side->getOpPtrVector().push_back(
3468 new OpSetFlux<SideEleOp>(broken_data_ptr, flux_mat_ptr));
3469
3470 // Assemble on skeleton
3471 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3473 GAUSS>::OpBrokenSpaceConstrainDHybrid<SPACE_DIM>;
3475 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
3476 op_loop_skeleton_side->getOpPtrVector().push_back(new OpC_dHybrid(
3477 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0)));
3478 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3479 op_loop_skeleton_side->getOpPtrVector().push_back(
3481 hybrid_ptr));
3482 op_loop_skeleton_side->getOpPtrVector().push_back(new OpC_dBroken(
3483 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0)));
3484
3485 // Add skeleton to domain pipeline
3486 pip.push_back(op_loop_skeleton_side);
3487
3489 };
3490
3491 auto set_tau_stabilsation_rhs = [&](auto &pip, auto side_fe_name,
3492 auto hybrid_field) {
3494
3495 using BoundaryEle =
3497 using EleOnSide =
3499 using SideEleOp = EleOnSide::UserDataOperator;
3500 using BdyEleOp = BoundaryEle::UserDataOperator;
3501
3502 // First: Iterate over skeleton FEs adjacent to Domain FEs
3503 // Note: BoundaryEle, i.e. uses skeleton interation rule
3504 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
3505 mField, side_fe_name, SPACE_DIM - 1, Sev::noisy);
3506 // op_loop_skeleton_side->getSideFEPtr()->getRuleHook = FaceRule();
3507 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3508 return -1;
3509 };
3510 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3511 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3512 op_loop_skeleton_side->getSideFEPtr()->exeTestHook = not_interface_face;
3513 CHKERR EshelbianPlasticity::
3514 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3515 op_loop_skeleton_side->getOpPtrVector(), {L2},
3517
3518 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
3519 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
3520 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3521 boost::make_shared<CGGUserPolynomialBase>(nullptr, true);
3522 CHKERR
3523 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3524 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3526
3527 // Add stabilization operator
3528 auto broken_disp_data_ptr =
3529 boost::make_shared<std::vector<BrokenBaseSideData>>();
3530 op_loop_domain_side->getOpPtrVector().push_back(
3532 broken_disp_data_ptr));
3533 auto disp_mat_ptr = boost::make_shared<MatrixDouble>();
3534 op_loop_domain_side->getOpPtrVector().push_back(
3536 disp_mat_ptr));
3537 // Set diag fluxes on skeleton side
3538 op_loop_domain_side->getOpPtrVector().push_back(
3539 new OpSetFlux<SideEleOp>(broken_disp_data_ptr, disp_mat_ptr));
3540 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
3541 op_loop_domain_side->getOpPtrVector().push_back(
3543 piolaStress, flux_mat_ptr, boost::make_shared<double>(1.0),
3544 solTSStep));
3545 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3546 op_loop_skeleton_side->getOpPtrVector().push_back(
3547 new OpSetTauScale(local_tau_sacale, alphaTau, alphaTau0,
3548 flux_mat_ptr));
3549
3550 // Add stabilization Ugamma Ugamma skeleton
3551 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3552 op_loop_skeleton_side->getOpPtrVector().push_back(
3554 hybrid_ptr));
3555
3556 // Diag u_gamma - u_gamma faces
3557 op_loop_skeleton_side->getOpPtrVector().push_back(
3559 hybrid_field, hybrid_ptr,
3560 [local_tau_sacale, broken_disp_data_ptr](double, double, double) {
3561 return broken_disp_data_ptr->size() * (*local_tau_sacale);
3562 }));
3563 // Diag L2 - L2 volumes
3564 op_loop_skeleton_side->getOpPtrVector().push_back(
3566 broken_disp_data_ptr, [local_tau_sacale](double, double, double) {
3567 return (*local_tau_sacale);
3568 }));
3569 // Off-diag Ugamma - L2
3570 op_loop_skeleton_side->getOpPtrVector().push_back(
3572 hybrid_field, broken_disp_data_ptr,
3573 [local_tau_sacale](double, double, double) {
3574 return -(*local_tau_sacale);
3575 }));
3576 // Off-diag L2 - Ugamma
3577 op_loop_skeleton_side->getOpPtrVector().push_back(
3579 broken_disp_data_ptr, hybrid_ptr,
3580 [local_tau_sacale](double, double, double) {
3581 return -(*local_tau_sacale);
3582 }));
3583
3584 // Add skeleton to domain pipeline
3585 pip.push_back(op_loop_skeleton_side);
3586
3588 };
3589
3590 auto set_tau_stabilsation_disp_bc_rhs = [&](auto &pip, auto side_fe_name) {
3592
3593 using BoundaryEle =
3595 using EleOnSide =
3597 using SideEleOp = EleOnSide::UserDataOperator;
3598 using BdyEleOp = BoundaryEle::UserDataOperator;
3599
3600 // First: Iterate over skeleton FEs adjacent to Domain FEs
3601 // Note: BoundaryEle, i.e. uses skeleton interation rule
3602 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
3603 mField, side_fe_name, SPACE_DIM - 1, Sev::noisy);
3604 // op_loop_skeleton_side->getSideFEPtr()->getRuleHook = FaceRule();
3605 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3606 return -1;
3607 };
3608 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3609 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3610 op_loop_skeleton_side->getSideFEPtr()->exeTestHook = not_interface_face;
3611 CHKERR EshelbianPlasticity::
3612 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3613 op_loop_skeleton_side->getOpPtrVector(), {L2},
3615
3616 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
3617 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
3618 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3619 boost::make_shared<CGGUserPolynomialBase>(nullptr, true);
3620 CHKERR
3621 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3622 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3624
3625 // Add stabilization operator
3626 auto broken_disp_data_ptr =
3627 boost::make_shared<std::vector<BrokenBaseSideData>>();
3628 op_loop_domain_side->getOpPtrVector().push_back(
3630 broken_disp_data_ptr));
3631 auto disp_mat_ptr = boost::make_shared<MatrixDouble>();
3632 op_loop_domain_side->getOpPtrVector().push_back(
3634 disp_mat_ptr));
3635 // Set diag fluxes on skeleton side
3636 op_loop_domain_side->getOpPtrVector().push_back(
3637 new OpSetFlux<SideEleOp>(broken_disp_data_ptr, disp_mat_ptr));
3638
3639 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3640 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
3641 op_loop_domain_side->getOpPtrVector().push_back(
3643 piolaStress, flux_mat_ptr, boost::make_shared<double>(1.0),
3644 solTSStep));
3645 op_loop_skeleton_side->getOpPtrVector().push_back(new OpSetTauScale(
3646 local_tau_sacale, alphaTauBcDisp, alphaTauBcDisp0, flux_mat_ptr));
3647
3648 // Diag L2 - L2 volumes
3649 op_loop_skeleton_side->getOpPtrVector().push_back(
3651 broken_disp_data_ptr, bcSpatialDispVecPtr, timeScaleMap,
3652 [local_tau_sacale](double, double, double) {
3653 return (*local_tau_sacale);
3654 }));
3655 op_loop_skeleton_side->getOpPtrVector().push_back(
3657 broken_disp_data_ptr, bcSpatialAnalyticalDisplacementVecPtr,
3658 timeScaleMap, [local_tau_sacale](double, double, double) {
3659 return (*local_tau_sacale);
3660 }));
3661 op_loop_skeleton_side->getOpPtrVector().push_back(
3663 broken_disp_data_ptr, bcSpatialRotationVecPtr, timeScaleMap,
3664 [local_tau_sacale](double, double, double) {
3665 return (*local_tau_sacale);
3666 }));
3667
3668 // Add skeleton to domain pipeline
3669 pip.push_back(op_loop_skeleton_side);
3670
3672 };
3673
3674 auto set_contact_rhs = [&](auto &pip) {
3675 return pushContactOpsRhs(*this, contactTreeRhs, pip);
3676 };
3677
3678 auto set_cohesive_rhs = [&](auto &pip) {
3679 return pushCohesiveOpsRhs(
3680 *this, SetIntegrationAtFrontFace(frontVertices, frontAdjEdges),
3681 interfaceFaces, pip);
3682 };
3683
3684 CHKERR set_hybridisation_rhs(fe_rhs->getOpPtrVector());
3685 CHKERR set_contact_rhs(fe_rhs->getOpPtrVector());
3686 if (alphaTau > 0.0 || alphaTau0 > 0.0) {
3687 CHKERR set_tau_stabilsation_rhs(fe_rhs->getOpPtrVector(), skeletonElement,
3689 }
3690 if (alphaTauBcDisp > 0.0 || alphaTauBcDisp0 > 0.0) {
3691 CHKERR set_tau_stabilsation_disp_bc_rhs(fe_rhs->getOpPtrVector(),
3693 }
3694 if (interfaceCrack == PETSC_TRUE) {
3695 CHKERR set_cohesive_rhs(fe_rhs->getOpPtrVector());
3696 }
3697
3698 // Body forces
3699 using BodyNaturalBC =
3701 Assembly<PETSC>::LinearForm<GAUSS>;
3702 using OpBodyForce =
3703 BodyNaturalBC::OpFlux<NaturalMeshsetType<BLOCKSET>, 1, 3>;
3704
3705 std::string body_force_history;
3706 CHKERR getStringArgumentFromJsonBlocksets("BODY_FORCE", "load_history",
3707 body_force_history);
3708 if (body_force_history.empty()) {
3709 body_force_history = "body_force.txt";
3710 } else {
3711 MOFEM_LOG("EP", Sev::inform)
3712 << "Body force load history from JSON: " << body_force_history;
3713 }
3714 auto body_time_scale =
3715 boost::make_shared<DynamicRelaxationTimeScale>(body_force_history);
3716 CHKERR BodyNaturalBC::AddFluxToPipeline<OpBodyForce>::add(
3717 fe_rhs->getOpPtrVector(), mField, spatialL2Disp, {body_time_scale},
3718 "BODY_FORCE", Sev::inform);
3719 }
3720
3721 // Left hand side
3722 fe_lhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
3723 CHKERR setBaseVolumeElementOps(tag, true, true, true, fe_lhs);
3724
3725 // elastic
3726 if (add_elastic) {
3727
3728 if (isNoStretch()) {
3730 } else {
3732 }
3733
3734 auto set_hybridisation_lhs = [&](auto &pip) {
3736
3737 using BoundaryEle =
3739 using EleOnSide =
3741 using SideEleOp = EleOnSide::UserDataOperator;
3742 using BdyEleOp = BoundaryEle::UserDataOperator;
3743
3744 // First: Iterate over skeleton FEs adjacent to Domain FEs
3745 // Note: BoundaryEle, i.e. uses skeleton interation rule
3746 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
3747 mField, skeletonElement, SPACE_DIM - 1, Sev::noisy);
3748 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3749 return -1;
3750 };
3751 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3752 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3753 CHKERR EshelbianPlasticity::
3754 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3755 op_loop_skeleton_side->getOpPtrVector(), {L2},
3757
3758 // Second: Iterate over domain FEs adjacent to skelton, particularly one
3759 // domain element.
3760 auto broken_data_ptr =
3761 boost::make_shared<std::vector<BrokenBaseSideData>>();
3762 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
3763 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
3764 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
3765 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3766 boost::make_shared<CGGUserPolynomialBase>(nullptr, true);
3767 CHKERR
3768 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3769 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3771 op_loop_domain_side->getOpPtrVector().push_back(
3772 new OpGetBrokenBaseSideData<SideEleOp>(piolaStress, broken_data_ptr));
3773
3774 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3776 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
3777 op_loop_skeleton_side->getOpPtrVector().push_back(
3778 new OpC(hybridSpatialDisp, broken_data_ptr,
3779 boost::make_shared<double>(1.0), true, false));
3780
3781 pip.push_back(op_loop_skeleton_side);
3782
3784 };
3785
3786 auto set_tau_stabilsation_lhs = [&](auto &pip, auto side_fe_name,
3787 auto hybrid_field) {
3789
3790 using BoundaryEle =
3792 using EleOnSide =
3794 using SideEleOp = EleOnSide::UserDataOperator;
3795 using BdyEleOp = BoundaryEle::UserDataOperator;
3796
3797 // First: Iterate over skeleton FEs adjacent to Domain FEs
3798 // Note: BoundaryEle, i.e. uses skeleton interation rule
3799 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
3800 mField, side_fe_name, SPACE_DIM - 1, Sev::noisy);
3801 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3802 return -1;
3803 };
3804 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3805 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3806 op_loop_skeleton_side->getSideFEPtr()->exeTestHook = not_interface_face;
3807 CHKERR EshelbianPlasticity::
3808 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3809 op_loop_skeleton_side->getOpPtrVector(), {L2},
3811
3812 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
3813 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
3814 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
3815 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3816 boost::make_shared<CGGUserPolynomialBase>(nullptr, true);
3817 CHKERR
3818 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3819 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3821
3822 auto broken_disp_data_ptr =
3823 boost::make_shared<std::vector<BrokenBaseSideData>>();
3824 op_loop_domain_side->getOpPtrVector().push_back(
3826 broken_disp_data_ptr));
3827 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
3828 op_loop_domain_side->getOpPtrVector().push_back(
3830 piolaStress, flux_mat_ptr, boost::make_shared<double>(1.0),
3831 solTSStep));
3832 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3833 op_loop_skeleton_side->getOpPtrVector().push_back(
3834 new OpSetTauScale(local_tau_sacale, alphaTau, alphaTau0,
3835 flux_mat_ptr));
3836
3837 // Diag Ugamma-Ugamma skeleton
3838 op_loop_skeleton_side->getOpPtrVector().push_back(new OpMassVectorFace(
3839 hybrid_field, hybrid_field,
3840 [local_tau_sacale, broken_disp_data_ptr](double, double, double) {
3841 return broken_disp_data_ptr->size() * (*local_tau_sacale);
3842 }));
3843 // Diag L2-L2 volumes
3844 op_loop_skeleton_side->getOpPtrVector().push_back(
3846 broken_disp_data_ptr, [local_tau_sacale](double, double, double) {
3847 return (*local_tau_sacale);
3848 }));
3849 // Off-diag Ugamma - L2
3850 op_loop_skeleton_side->getOpPtrVector().push_back(
3852 hybrid_field, broken_disp_data_ptr,
3853 [local_tau_sacale](double, double, double) {
3854 return -(*local_tau_sacale);
3855 },
3856 false, false));
3857 // Off-diag L2 - Ugamma
3858 op_loop_skeleton_side->getOpPtrVector().push_back(
3860 hybrid_field, broken_disp_data_ptr,
3861 [local_tau_sacale](double, double, double) {
3862 return -(*local_tau_sacale);
3863 },
3864 true, true));
3865
3866 pip.push_back(op_loop_skeleton_side);
3867
3869 };
3870
3871 auto set_tau_stabilsation_disp_bc_lhs = [&](auto &pip, auto side_fe_name) {
3873
3874 using BoundaryEle =
3876 using EleOnSide =
3878 using SideEleOp = EleOnSide::UserDataOperator;
3879 using BdyEleOp = BoundaryEle::UserDataOperator;
3880
3881 // First: Iterate over skeleton FEs adjacent to Domain FEs
3882 // Note: BoundaryEle, i.e. uses skeleton interation rule
3883 auto op_loop_skeleton_side = new OpLoopSide<BoundaryEle>(
3884 mField, side_fe_name, SPACE_DIM - 1, Sev::noisy);
3885 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3886 return -1;
3887 };
3888 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3889 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3890 op_loop_skeleton_side->getSideFEPtr()->exeTestHook = not_interface_face;
3891 CHKERR EshelbianPlasticity::
3892 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3893 op_loop_skeleton_side->getOpPtrVector(), {L2},
3895
3896 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
3897 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
3898 mField, elementVolumeName, SPACE_DIM, Sev::noisy);
3899 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3900 boost::make_shared<CGGUserPolynomialBase>(nullptr, true);
3901 CHKERR
3902 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3903 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3905
3906 auto broken_disp_data_ptr =
3907 boost::make_shared<std::vector<BrokenBaseSideData>>();
3908 op_loop_domain_side->getOpPtrVector().push_back(
3910 broken_disp_data_ptr));
3911 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
3912 op_loop_domain_side->getOpPtrVector().push_back(
3914 piolaStress, flux_mat_ptr, boost::make_shared<double>(1.0),
3915 solTSStep));
3916 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3917 op_loop_skeleton_side->getOpPtrVector().push_back(new OpSetTauScale(
3918 local_tau_sacale, alphaTauBcDisp, alphaTauBcDisp0, flux_mat_ptr));
3919
3920 // Diag L2-L2 volumes
3921 op_loop_skeleton_side->getOpPtrVector().push_back(
3923 broken_disp_data_ptr, bcSpatialDispVecPtr,
3924 [local_tau_sacale](double, double, double) {
3925 return (*local_tau_sacale);
3926 }));
3927 op_loop_skeleton_side->getOpPtrVector().push_back(
3929 broken_disp_data_ptr, bcSpatialAnalyticalDisplacementVecPtr,
3930 [local_tau_sacale](double, double, double) {
3931 return (*local_tau_sacale);
3932 }));
3933 op_loop_skeleton_side->getOpPtrVector().push_back(
3935 broken_disp_data_ptr, bcSpatialRotationVecPtr,
3936 [local_tau_sacale](double, double, double) {
3937 return (*local_tau_sacale);
3938 }));
3939
3940 pip.push_back(op_loop_skeleton_side);
3941
3943 };
3944
3945 auto set_contact_lhs = [&](auto &pip) {
3946 return pushContactOpsLhs(*this, contactTreeRhs, pip);
3947 };
3948
3949 auto set_cohesive_lhs = [&](auto &pip) {
3950 return pushCohesiveOpsLhs(
3951 *this, SetIntegrationAtFrontFace(frontVertices, frontAdjEdges),
3952 interfaceFaces, pip);
3953 };
3954
3955 CHKERR set_hybridisation_lhs(fe_lhs->getOpPtrVector());
3956 CHKERR set_contact_lhs(fe_lhs->getOpPtrVector());
3957 if (alphaTau > 0.0 || alphaTau0 > 0.0) {
3958 CHKERR set_tau_stabilsation_lhs(fe_lhs->getOpPtrVector(), skeletonElement,
3960 }
3961 if (alphaTauBcDisp > 0.0 || alphaTauBcDisp0 > 0.0) {
3962 CHKERR set_tau_stabilsation_disp_bc_lhs(fe_lhs->getOpPtrVector(),
3964 }
3965 if (interfaceCrack == PETSC_TRUE) {
3966 CHKERR set_cohesive_lhs(fe_lhs->getOpPtrVector());
3967 }
3968 }
3969
3970 if (add_material) {
3971 }
3972
3974}
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 pushNoStretchVolumeA00Ops(boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe_lhs)
MoFEMErrorCode setBaseVolumeElementOps(const int tag, const bool do_rhs, const bool do_lhs, const bool calc_rates, boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe, const bool add_bubble=true)
MoFEMErrorCode getStringArgumentFromJsonBlocksets(const std::string &type_name, const std::string &param_name, std::string &param_value)
MoFEMErrorCode pushStretchVolumeA00Ops(boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe_lhs)
Natural boundary conditions.
Definition Natural.hpp:57
Operator for broken loop side.
static std::tuple< std::array< double, 3 >, std::array< double, 2 >, double > getTricircumcenter3d(double *coords_ptr)
Calculate triangle circumcenter in 3d.
Definition Tools.cpp:878

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

5885 {
5887
5888 auto storage = solve_elastic_setup::setup(this, ts, x, false);
5889
5890 auto cohesive_tao_ctx = createCohesiveTAOCtx(
5891 this, SetIntegrationAtFrontFace(frontVertices, frontAdjEdges),
5892 SmartPetscObj<TS>(ts, true));
5893
5894 // Deprecated options
5895 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Dynamic Relaxation Options", "none");
5896
5897 CHKERR PetscOptionsScalar(
5898 "-dynamic_final_time", "dynamic relaxation final time", "",
5899 finalPhysicalTime, &finalPhysicalTime, PETSC_NULLPTR);
5900 CHKERR PetscOptionsScalar("-dynamic_delta_time",
5901 "dynamic relaxation final time", "", physicalDt,
5902 &physicalDt, PETSC_NULLPTR);
5903 CHKERR PetscOptionsInt("-dynamic_max_it", "dynamic relaxation iterations", "",
5904 physicalMaxSteps, &physicalMaxSteps, PETSC_NULLPTR);
5905 CHKERR PetscOptionsBool("-dynamic_h1_update", "update each ts step", "",
5906 physicalH1Update, &physicalH1Update, PETSC_NULLPTR);
5907
5908 PetscOptionsEnd();
5909
5910 EshelbianCore::physicalTimeFlg = PETSC_TRUE;
5911 MOFEM_LOG("EP", Sev::inform)
5912 << "Dynamic relaxation final time -dynamic_final_time = "
5914 MOFEM_LOG("EP", Sev::inform)
5915 << "Dynamic relaxation delta time -dynamic_delta_time = " << physicalDt;
5916 MOFEM_LOG("EP", Sev::inform)
5917 << "Dynamic relaxation max iterations -dynamic_max_it = "
5919 MOFEM_LOG("EP", Sev::inform)
5920 << "Dynamic relaxation H1 update each step -dynamic_h1_update = "
5921 << (physicalH1Update ? "TRUE" : "FALSE");
5922
5925
5926 auto setup_ts_monitor = [&]() {
5927 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*this);
5928 return monitor_ptr;
5929 };
5930 auto monitor_ptr = setup_ts_monitor();
5931
5932 TetPolynomialBase::switchCacheBaseOn<HDIV>(
5933 {elasticFeLhs.get(), elasticFeRhs.get()});
5934 CHKERR TSSetUp(ts);
5935 CHKERR TSElasticPostStep::postStepInitialise(this);
5936
5937 double ts_delta_time;
5938 CHKERR TSGetTimeStep(ts, &ts_delta_time);
5939
5940 if (physicalH1Update) {
5941 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
5942 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
5943 }
5944
5945 auto tao = createTao(mField.get_comm());
5946 CHKERR TaoSetType(tao, TAOLMVM);
5947 auto g = cohesive_tao_ctx->duplicateGradientVec();
5949 cohesiveEvaluateObjectiveAndGradient,
5950 (void *)cohesive_tao_ctx.get());
5951
5952 currentPhysicalTime = start_time;
5953 physicalStepNumber = start_step;
5954 monitor_ptr->ts = PETSC_NULLPTR;
5955 monitor_ptr->ts_u = PETSC_NULLPTR;
5956 monitor_ptr->ts_t = currentPhysicalTime;
5957 monitor_ptr->ts_step = physicalStepNumber;
5959
5960 auto tao_sol0 = cohesive_tao_ctx->duplicateKappaVec();
5961 int tao_sol_size, tao_sol_loc_size;
5962 CHKERR VecGetSize(tao_sol0, &tao_sol_size);
5963 CHKERR VecGetLocalSize(tao_sol0, &tao_sol_loc_size);
5964 MOFEM_LOG("EP", Sev::inform)
5965 << "Cohesive crack growth initial kappa vector size " << tao_sol_size
5966 << " local size " << tao_sol_loc_size << " number of interface faces "
5967 << interfaceFaces->size();
5968
5969 CHKERR TaoSetFromOptions(tao);
5970
5971 auto xl = vectorDuplicate(tao_sol0);
5972 auto xu = vectorDuplicate(tao_sol0);
5973 CHKERR VecSet(xl, 0.0);
5974 CHKERR VecSet(xu, PETSC_INFINITY);
5975 CHKERR TaoSetVariableBounds(tao, xl, xu);
5976
5977 if (physicalDt <= 0.) {
5979 "physicalDt must be positive, got %g", physicalDt);
5980 }
5982 MOFEM_LOG("EP", Sev::inform)
5983 << "Load step " << physicalStepNumber << " Time " << currentPhysicalTime
5984 << " delta time " << physicalDt;
5985
5986 CHKERR VecZeroEntries(tao_sol0);
5987 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5988 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5989 CHKERR TaoSetSolution(tao, tao_sol0);
5990
5991 if (!physicalH1Update && physicalStepNumber > start_step) {
5992 CHKERR TSElasticPostStep::preStepFun(ts);
5993 }
5994 CHKERR TaoSolve(tao);
5995
5996 Vec tao_sol;
5997 CHKERR TaoGetSolution(tao, &tao_sol);
5998
5999 // add solution increment to kappa vec/tags
6000 auto &kappa_vec = cohesive_tao_ctx->getKappaVec();
6003 CHKERR VecAXPY(kappa_vec.second, 1.0, tao_sol);
6004 CHKERR VecGhostUpdateBegin(kappa_vec.second, INSERT_VALUES,
6005 SCATTER_FORWARD);
6006 CHKERR VecGhostUpdateEnd(kappa_vec.second, INSERT_VALUES, SCATTER_FORWARD);
6009
6010 CHKERR DMoFEMMeshToLocalVector(dmElastic, x, INSERT_VALUES,
6011 SCATTER_FORWARD);
6012 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
6013 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
6014 monitor_ptr->ts = PETSC_NULLPTR;
6015 monitor_ptr->ts_u = x;
6016 monitor_ptr->ts_t = currentPhysicalTime;
6017 monitor_ptr->ts_step = physicalStepNumber;
6019
6020 if (!physicalH1Update) {
6021 CHKERR TSElasticPostStep::postStepFun(ts);
6022 }
6023
6026 break;
6027
6028 const double remainingPhysicalTime =
6030 if (physicalDt >= remainingPhysicalTime) {
6032 } else {
6034 }
6035 }
6036
6037 CHKERR TSElasticPostStep::postStepDestroy();
6038 TetPolynomialBase::switchCacheBaseOff<HDIV>(
6039 {elasticFeLhs.get(), elasticFeRhs.get()});
6040
6042}
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)
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)
MoFEMErrorCode addDebugModel(TS ts)
Add debug to model.
static int physicalStepNumber
static double currentPhysicalTime
static MoFEMErrorCode setVectorFromTag(moab::Interface &moab, EntitiesPetscVector &vec, Tag tag)
Set the Vector From Tag object.
static MoFEMErrorCode setTagFromVector(moab::Interface &moab, EntitiesPetscVector &vec, Tag tag)
Set the Tag From Vector object.

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

4522 {
4524
4525 auto storage = solve_elastic_setup::setup(this, ts, x, false);
4526
4527 // Deprecated options
4528 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Dynamic Relaxation Options", "none");
4529
4530 CHKERR PetscOptionsScalar(
4531 "-dynamic_final_time", "dynamic relaxation final time", "",
4532 finalPhysicalTime, &finalPhysicalTime, PETSC_NULLPTR);
4533 CHKERR PetscOptionsScalar("-dynamic_delta_time",
4534 "dynamic relaxation final time", "", physicalDt,
4535 &physicalDt, PETSC_NULLPTR);
4536 CHKERR PetscOptionsInt("-dynamic_max_it", "dynamic relaxation iterations", "",
4537 physicalMaxSteps, &physicalMaxSteps, PETSC_NULLPTR);
4538 CHKERR PetscOptionsBool("-dynamic_h1_update", "update each ts step", "",
4539 physicalH1Update, &physicalH1Update, PETSC_NULLPTR);
4540
4541 PetscOptionsEnd();
4542
4543 MOFEM_LOG("EP", Sev::warning)
4544 << "Following options are deprecated, use -physical prefix options "
4545 "instead";
4546 MOFEM_LOG("EP", Sev::inform)
4547 << "Dynamic relaxation final time -dynamic_final_time = "
4549 MOFEM_LOG("EP", Sev::inform)
4550 << "Dynamic relaxation delta time -dynamic_delta_time = " << physicalDt;
4551 MOFEM_LOG("EP", Sev::inform)
4552 << "Dynamic relaxation max iterations -dynamic_max_it = "
4554 MOFEM_LOG("EP", Sev::inform)
4555 << "Dynamic relaxation H1 update each step -dynamic_h1_update = "
4556 << (physicalH1Update ? "TRUE" : "FALSE");
4557
4559
4560 auto setup_ts_monitor = [&]() {
4561 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*this);
4562 return monitor_ptr;
4563 };
4564 auto monitor_ptr = setup_ts_monitor();
4565
4566 TetPolynomialBase::switchCacheBaseOn<HDIV>(
4567 {elasticFeLhs.get(), elasticFeRhs.get()});
4568 CHKERR TSSetUp(ts);
4569 CHKERR TSElasticPostStep::postStepInitialise(this);
4570
4571 double ts_delta_time;
4572 CHKERR TSGetTimeStep(ts, &ts_delta_time);
4573 CHKERR TSSetSolution(ts, x);
4574
4575 if (physicalH1Update) {
4576 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
4577 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
4578 } else {
4579 CHKERR TSSetPreStep(ts, PETSC_NULLPTR);
4580 CHKERR TSSetPostStep(ts, PETSC_NULLPTR);
4581 }
4582
4583 CHKERR TSElasticPostStep::preStepFun(ts);
4584 CHKERR TSElasticPostStep::postStepFun(ts);
4585
4586 currentPhysicalTime = start_time;
4587 physicalStepNumber = start_step;
4588 monitor_ptr->ts = PETSC_NULLPTR;
4589 monitor_ptr->ts_u = PETSC_NULLPTR;
4590 monitor_ptr->ts_t = currentPhysicalTime;
4591 monitor_ptr->ts_step = physicalStepNumber;
4593
4594 if (physicalDt <= 0.) {
4596 "physicalDt must be positive, got %g", physicalDt);
4597 }
4599 MOFEM_LOG("EP", Sev::inform)
4600 << "Load step " << physicalStepNumber << " Time " << currentPhysicalTime
4601 << " delta time " << physicalDt;
4602
4603 CHKERR TSSetStepNumber(ts, 0);
4604 CHKERR TSSetTime(ts, 0);
4605 CHKERR TSSetTimeStep(ts, ts_delta_time);
4606 CHKERR TSSetSolution(ts, x);
4607 if (!physicalH1Update) {
4608 CHKERR TSElasticPostStep::preStepFun(ts);
4609 }
4610 CHKERR TSSolve(ts, PETSC_NULLPTR);
4611 if (!physicalH1Update) {
4612 CHKERR TSElasticPostStep::postStepFun(ts);
4613 }
4614
4615 CHKERR DMoFEMMeshToLocalVector(dmElastic, x, INSERT_VALUES,
4616 SCATTER_FORWARD);
4617 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
4618 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
4619
4620 monitor_ptr->ts = PETSC_NULLPTR;
4621 monitor_ptr->ts_u = x;
4622 monitor_ptr->ts_t = currentPhysicalTime;
4623 monitor_ptr->ts_step = physicalStepNumber;
4625
4628 break;
4629
4630 const double remainingPhysicalTime =
4632 if (physicalDt >= remainingPhysicalTime) {
4634 } else {
4636 }
4637 }
4638
4639 CHKERR TSElasticPostStep::postStepDestroy();
4640 TetPolynomialBase::switchCacheBaseOff<HDIV>(
4641 {elasticFeLhs.get(), elasticFeRhs.get()});
4642
4644}

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

4412 {
4414
4416
4417 auto storage = solve_elastic_setup::setup(this, ts, x, true);
4418
4419 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
4420 Vec xx;
4421 CHKERR VecDuplicate(x, &xx);
4422 CHKERR VecZeroEntries(xx);
4423 CHKERR TS2SetSolution(ts, x, xx);
4424 CHKERR VecDestroy(&xx);
4425 } else {
4426 CHKERR TSSetSolution(ts, x);
4427 }
4428
4429 TetPolynomialBase::switchCacheBaseOn<HDIV>(
4430 {elasticFeLhs.get(), elasticFeRhs.get()});
4431 CHKERR TSSetUp(ts);
4432 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
4433 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
4434 CHKERR TSElasticPostStep::postStepInitialise(this);
4435 CHKERR TSSolve(ts, PETSC_NULLPTR);
4436 CHKERR TSElasticPostStep::postStepDestroy();
4437 TetPolynomialBase::switchCacheBaseOff<HDIV>(
4438 {elasticFeLhs.get(), elasticFeRhs.get()});
4439
4440#ifndef NDEBUG
4441 // Make graph
4442 if (mField.get_comm_rank() == 0) {
4443 auto ts_ctx_ptr = getDMTsCtx(dmElastic);
4445 "solve_elastic_graph.dot");
4446 }
4447#endif
4448
4449 SNES snes;
4450 CHKERR TSGetSNES(ts, &snes);
4451 int lin_solver_iterations;
4452 CHKERR SNESGetLinearSolveIterations(snes, &lin_solver_iterations);
4453 MOFEM_LOG("EP", Sev::inform)
4454 << "Number of linear solver iterations " << lin_solver_iterations;
4455
4456 PetscBool test_cook_flg = PETSC_FALSE;
4457 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-test_cook", &test_cook_flg,
4458 PETSC_NULLPTR);
4459 if (test_cook_flg) {
4460 PetscInt expected_lin_solver_iterations = 11;
4461 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "",
4462 "-test_cook_max_linear_iterations",
4463 &expected_lin_solver_iterations, PETSC_NULLPTR);
4464 if (lin_solver_iterations > expected_lin_solver_iterations)
4465 SETERRQ(
4466 PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
4467 "Expected number of iterations is different than expected %d > %d",
4468 lin_solver_iterations, expected_lin_solver_iterations);
4469 }
4470
4471 PetscBool test_sslv116_flag = PETSC_FALSE;
4472 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-test_sslv116",
4473 &test_sslv116_flag, PETSC_NULLPTR);
4474
4475 if (test_sslv116_flag) {
4476 double max_val = 0.0;
4477 double min_val = 0.0;
4478 auto field_min_max = [&](boost::shared_ptr<FieldEntity> ent_ptr) {
4480 auto ent_type = ent_ptr->getEntType();
4481 if (ent_type == MBVERTEX) {
4482 max_val = std::max(ent_ptr->getEntFieldData()[SPACE_DIM - 1], max_val);
4483 min_val = std::min(ent_ptr->getEntFieldData()[SPACE_DIM - 1], min_val);
4484 }
4486 };
4487 CHKERR mField.getInterface<FieldBlas>()->fieldLambdaOnEntities(
4488 field_min_max, spatialH1Disp);
4489
4490 double global_max_val = 0.0;
4491 double global_min_val = 0.0;
4492 MPI_Allreduce(&max_val, &global_max_val, 1, MPI_DOUBLE, MPI_MAX,
4493 mField.get_comm());
4494 MPI_Allreduce(&min_val, &global_min_val, 1, MPI_DOUBLE, MPI_MIN,
4495 mField.get_comm());
4496 MOFEM_LOG("EP", Sev::inform)
4497 << "Max " << spatialH1Disp << " value: " << global_max_val;
4498 MOFEM_LOG("EP", Sev::inform)
4499 << "Min " << spatialH1Disp << " value: " << global_min_val;
4500
4501 double ref_max_val = 0.00767;
4502 double ref_min_val = -0.00329;
4503 if (std::abs(global_max_val - ref_max_val) > 1e-5) {
4504 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
4505 "Incorrect max value of the displacement field: %f != %f",
4506 global_max_val, ref_max_val);
4507 }
4508 if (std::abs(global_min_val - ref_min_val) > 4e-5) {
4509 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
4510 "Incorrect min value of the displacement field: %f != %f",
4511 global_min_val, ref_min_val);
4512 }
4513 }
4514
4516
4518}
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
MoFEMErrorCode gettingNorms()
[Getting norms]
static MoFEMErrorCode writeTSGraphGraphviz(TsCtx *ts_ctx, std::string file_name)
TS graph to Graphviz file.

◆ solveLoadFactor()

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

Solve load factor 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 6044 of file EshelbianPlasticity.cpp.

6045 {
6047
6048 loadFactorTSSolveExecuted = PETSC_FALSE;
6049
6050 auto storage = solve_elastic_setup::setup(this, ts, x, false);
6051
6053
6054 auto setup_ts_monitor = [&]() {
6055 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*this);
6056 return monitor_ptr;
6057 };
6058 auto monitor_ptr = setup_ts_monitor();
6059
6060 auto test_monitor_ptr =
6061 boost::make_shared<EshelbianTestingMonitor>(*this, monitor_ptr);
6062
6063 TetPolynomialBase::switchCacheBaseOn<HDIV>(
6064 {elasticFeLhs.get(), elasticFeRhs.get()});
6065 CHKERR TSSetUp(ts);
6066 CHKERR TSElasticPostStep::postStepInitialise(this);
6067
6068 double ts_delta_time;
6069 CHKERR TSGetTimeStep(ts, &ts_delta_time);
6070
6071 if (physicalH1Update) {
6072 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
6073 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
6074 }
6075
6076 CHKERR TSElasticPostStep::preStepFun(ts);
6077 CHKERR TSElasticPostStep::postStepFun(ts);
6078
6079 double load_factor_change_clip = 0.1;
6080
6081 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Load Factor Options", "none");
6082
6083 CHKERR PetscOptionsScalar("-initial_load_factor", "Initial load factor", "",
6084 loadFactor, &loadFactor, PETSC_NULLPTR);
6085 CHKERR PetscOptionsScalar(
6086 "-max_crack_ext_area", "Maximum crack extension area", "",
6087 maxCrackExtension, &maxCrackExtension, PETSC_NULLPTR);
6088 CHKERR PetscOptionsScalar(
6089 "-clip_load_factor_percent", "Upper bound for load factor change", "",
6090 load_factor_change_clip, &load_factor_change_clip, PETSC_NULLPTR);
6091 PetscOptionsEnd();
6092
6093 currentPhysicalTime = start_time;
6094 physicalStepNumber = start_step;
6095 monitor_ptr->ts = ts;
6096 monitor_ptr->ts_u = PETSC_NULLPTR;
6097 monitor_ptr->ts_t = currentPhysicalTime;
6098 monitor_ptr->ts_step = physicalStepNumber;
6100
6101 PetscBool test_cook_flg = PETSC_FALSE;
6102 PetscInt atom_test = 0;
6103 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-test_cook", &test_cook_flg,
6104 PETSC_NULLPTR);
6105 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-atom_test", &atom_test,
6106 PETSC_NULLPTR);
6107 if (atom_test || test_cook_flg) {
6108 test_monitor_ptr->ts = ts;
6109 test_monitor_ptr->ts_u = PETSC_NULLPTR;
6110 test_monitor_ptr->ts_t = currentPhysicalTime;
6111 test_monitor_ptr->ts_step = physicalStepNumber;
6112
6114 test_monitor_ptr);
6115 }
6116
6117 MOFEM_LOG("EP", Sev::inform)
6118 << "Initial crack area: " << *currentCrackAreaPtr;
6119 MOFEM_LOG("EP", Sev::inform) << "Initial load factor: " << loadFactor;
6120 MOFEM_LOG("EP", Sev::inform)
6121 << "Initial crack front energy: " << avgGriffithsEnergy;
6122
6124 MOFEM_LOG("EP", Sev::inform)
6125 << "Load step " << physicalStepNumber << " Load Factor "
6126 << currentPhysicalTime << " delta load factor " << physicalDt;
6127
6131
6132 CHKERR TSSetStepNumber(ts, 0);
6133 CHKERR TSSetTime(ts, 0);
6134 CHKERR TSSetTimeStep(ts, ts_delta_time);
6135 if (!physicalH1Update) {
6136 CHKERR TSElasticPostStep::preStepFun(ts);
6137 }
6138 CHKERR TSSetSolution(ts, x);
6139 CHKERR TSSolve(ts, PETSC_NULLPTR);
6140 loadFactorTSSolveExecuted = PETSC_TRUE;
6141 if (!physicalH1Update) {
6142 CHKERR TSElasticPostStep::postStepFun(ts);
6143 }
6144
6145 CHKERR DMoFEMMeshToLocalVector(dmElastic, x, INSERT_VALUES,
6146 SCATTER_FORWARD);
6147 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
6148 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
6149
6150 monitor_ptr->ts = ts;
6151 monitor_ptr->ts_u = x;
6152 monitor_ptr->ts_t = currentPhysicalTime;
6153 monitor_ptr->ts_step = physicalStepNumber;
6155
6156 if (atom_test || test_cook_flg) {
6157 test_monitor_ptr->ts = ts;
6158 test_monitor_ptr->ts_u = x;
6159 test_monitor_ptr->ts_t = currentPhysicalTime;
6160 test_monitor_ptr->ts_step = physicalStepNumber;
6162 test_monitor_ptr);
6163 }
6164
6165 if (mField.get_comm_rank() == 0) {
6166 const double delta_area = *currentCrackAreaPtr - oldCrackArea;
6167 const bool has_crack_extension = delta_area > 0.0;
6168
6169 if (has_crack_extension) {
6170 const double denom = 0.5 * std::abs(avgGriffithsEnergy);
6171 if (denom > 0.0) {
6172 const double updated_load_factor =
6173 oldLoadFactor * std::sqrt(griffithEnergy / denom);
6174 loadFactor = std::max(updated_load_factor, 1.0e-6);
6175 }
6176 }
6177
6178 const bool is_first_step = physicalStepNumber == start_step;
6179 const double initial_step_range = 5;
6180 const double min_load_factor = 1.0e-6;
6181 const double max_load_factor =
6182 oldLoadFactor * (1.0 + load_factor_change_clip);
6183
6184 if (physicalStepNumber >= start_step + initial_step_range) {
6185 loadFactor = std::clamp(loadFactor, min_load_factor, max_load_factor);
6186 MOFEM_LOG("EP", Sev::inform)
6187 << "Allowable range for load factor [" << min_load_factor << ", "
6188 << max_load_factor << "]";
6189 }
6190
6191 const double previous_load_factor = is_first_step ? 0. : oldLoadFactor;
6192 physicalDt = loadFactor - previous_load_factor;
6193
6194 MOFEM_LOG("EP", Sev::inform)
6195 << "Setting new load factor to: " << loadFactor;
6196 }
6197 double load_control_data[] = {physicalDt, loadFactor};
6198 CHKERR MPI_Bcast(load_control_data, 2, MPI_DOUBLE, 0, MPI_COMM_WORLD);
6199 physicalDt = load_control_data[0];
6200 loadFactor = load_control_data[1];
6201
6204 break;
6205
6206 const double remainingPhysicalTime =
6208 if (physicalDt >= remainingPhysicalTime) {
6210 } else {
6212 }
6213 }
6214
6215 CHKERR TSElasticPostStep::postStepDestroy();
6216 TetPolynomialBase::switchCacheBaseOff<HDIV>(
6217 {elasticFeLhs.get(), elasticFeRhs.get()});
6218 MOFEM_LOG("EP", Sev::inform) << "Final load factor: " << loadFactor;
6219
6221}
PetscBool loadFactorTSSolveExecuted
static double maxCrackExtension
boost::shared_ptr< double > currentCrackAreaPtr
int atom_test
Atom test.
Definition plastic.cpp:122

◆ solveSchapeOptimisation()

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

Solve shape optimisation 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 6223 of file EshelbianPlasticity.cpp.

6225 {
6227
6228 auto storage = solve_elastic_setup::setup(this, ts, x, false);
6229
6230 auto topological_tao_ctx = createTopologicalTAOCtx(
6231 this, SetIntegrationAtFrontVolume(frontVertices, frontAdjEdges),
6232 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges),
6233 SmartPetscObj<TS>(ts, true));
6234
6235 double final_time = 1;
6236 double delta_time = 0.1;
6237 int max_it = 10;
6238 PetscBool ts_h1_update = PETSC_FALSE;
6239
6240 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Dynamic Relaxation Options", "none");
6241
6242 CHKERR PetscOptionsScalar("-dynamic_final_time",
6243 "dynamic relaxation final time", "", final_time,
6244 &final_time, PETSC_NULLPTR);
6245 CHKERR PetscOptionsScalar("-dynamic_delta_time",
6246 "dynamic relaxation final time", "", delta_time,
6247 &delta_time, PETSC_NULLPTR);
6248 CHKERR PetscOptionsInt("-dynamic_max_it", "dynamic relaxation iterations", "",
6249 max_it, &max_it, PETSC_NULLPTR);
6250 CHKERR PetscOptionsBool("-dynamic_h1_update", "update each ts step", "",
6251 ts_h1_update, &ts_h1_update, PETSC_NULLPTR);
6252
6253 PetscOptionsEnd();
6254
6255 EshelbianCore::physicalTimeFlg = PETSC_TRUE;
6256 MOFEM_LOG("EP", Sev::inform)
6257 << "Dynamic relaxation final time -dynamic_final_time = " << final_time;
6258 MOFEM_LOG("EP", Sev::inform)
6259 << "Dynamic relaxation delta time -dynamic_delta_time = " << delta_time;
6260 MOFEM_LOG("EP", Sev::inform)
6261 << "Dynamic relaxation max iterations -dynamic_max_it = " << max_it;
6262 MOFEM_LOG("EP", Sev::inform)
6263 << "Dynamic relaxation H1 update each step -dynamic_h1_update = "
6264 << (ts_h1_update ? "TRUE" : "FALSE");
6265
6267
6268 auto setup_ts_monitor = [&]() {
6269 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*this);
6270 return monitor_ptr;
6271 };
6272 auto monitor_ptr = setup_ts_monitor();
6273
6274 TetPolynomialBase::switchCacheBaseOn<HDIV>(
6275 {elasticFeLhs.get(), elasticFeRhs.get()});
6276 CHKERR TSSetUp(ts);
6277 CHKERR TSElasticPostStep::postStepInitialise(this);
6278
6279 double ts_delta_time;
6280 CHKERR TSGetTimeStep(ts, &ts_delta_time);
6281
6282 if (ts_h1_update) {
6283 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
6284 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
6285 }
6286
6287 CHKERR TSElasticPostStep::preStepFun(ts);
6288 CHKERR TSElasticPostStep::postStepFun(ts);
6289
6290 auto tao = createTao(mField.get_comm());
6291 CHKERR TaoSetType(tao, TAOLMVM);
6294 topologicalEvaluateObjectiveAndGradient,
6295 (void *)topological_tao_ctx.get());
6296
6297 currentPhysicalTime = start_time;
6298 physicalStepNumber = start_step;
6299 monitor_ptr->ts = PETSC_NULLPTR;
6300 monitor_ptr->ts_u = PETSC_NULLPTR;
6301 monitor_ptr->ts_t = currentPhysicalTime;
6302 monitor_ptr->ts_step = physicalStepNumber;
6304
6305 auto tao_sol0 = createDMVector(dmMaterial, RowColData::ROW);
6306 CHKERR DMoFEMMeshToLocalVector(dmMaterial, tao_sol0, INSERT_VALUES,
6307 SCATTER_FORWARD, RowColData::ROW);
6308 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6309 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6310
6311 int tao_sol_size, tao_sol_loc_size;
6312 CHKERR VecGetSize(tao_sol0, &tao_sol_size);
6313 CHKERR VecGetLocalSize(tao_sol0, &tao_sol_loc_size);
6314 MOFEM_LOG("EP", Sev::inform)
6315 << "Toplogical data vector size " << tao_sol_size << " local size "
6316 << tao_sol_loc_size << " number of interface faces "
6317 << interfaceFaces->size();
6318
6319 CHKERR TaoSetFromOptions(tao);
6320
6321 if (delta_time <= 0.) {
6323 "delta_time must be positive, got %g", delta_time);
6324 }
6325 for (; currentPhysicalTime < final_time;) {
6326 MOFEM_LOG("EP", Sev::inform)
6327 << "Load step " << physicalStepNumber << " Time " << currentPhysicalTime
6328 << " delta time " << delta_time;
6329
6330 CHKERR VecZeroEntries(tao_sol0);
6331 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6332 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6333 CHKERR TaoSetSolution(tao, tao_sol0);
6334 CHKERR TaoSolve(tao);
6335 Vec tao_sol;
6336 CHKERR TaoGetSolution(tao, &tao_sol);
6337
6338 // // add solution increment to kappa vec/tags
6339 // auto &kappa_vec = topological_tao_ctx->getKappaVec();
6340 // CHKERR CommInterface::setVectorFromTag(mField.get_moab(), kappa_vec,
6341 // get_kappa_tag(mField.get_moab()));
6342 // CHKERR VecAXPY(kappa_vec.second, 1.0, tao_sol);
6343 // CHKERR VecGhostUpdateBegin(kappa_vec.second, INSERT_VALUES,
6344 // SCATTER_FORWARD);
6345 // CHKERR VecGhostUpdateEnd(kappa_vec.second, INSERT_VALUES,
6346 // SCATTER_FORWARD); CHKERR
6347 // CommInterface::setTagFromVector(mField.get_moab(), kappa_vec,
6348 // get_kappa_tag(mField.get_moab()));
6349
6350 CHKERR DMoFEMMeshToLocalVector(dmElastic, x, INSERT_VALUES,
6351 SCATTER_FORWARD);
6352 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
6353 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
6354 monitor_ptr->ts = PETSC_NULLPTR;
6355 monitor_ptr->ts_u = x;
6356 monitor_ptr->ts_t = currentPhysicalTime;
6357 monitor_ptr->ts_step = physicalStepNumber;
6359
6361 if (physicalStepNumber > max_it)
6362 break;
6363
6364 const double remainingPhysicalTime = final_time - currentPhysicalTime;
6365 if (delta_time >= remainingPhysicalTime) {
6366 currentPhysicalTime = final_time;
6367 } else {
6368 currentPhysicalTime += delta_time;
6369 }
6370 }
6371
6372 CHKERR TSElasticPostStep::postStepDestroy();
6373 TetPolynomialBase::switchCacheBaseOff<HDIV>(
6374 {elasticFeLhs.get(), elasticFeRhs.get()});
6375
6377}

◆ solveTestTopologicalDerivative()

MoFEMErrorCode EshelbianCore::solveTestTopologicalDerivative ( TS  ts,
Vec  x,
int  start_step,
double  start_time 
)
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 6379 of file EshelbianPlasticity.cpp.

6381 {
6383
6384 auto storage = solve_elastic_setup::setup(this, ts, x, false);
6385
6386 auto topological_tao_ctx = createTopologicalTAOCtx(
6387 this, SetIntegrationAtFrontVolume(frontVertices, frontAdjEdges),
6388 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges),
6389 SmartPetscObj<TS>(ts, true));
6390
6391 EshelbianCore::physicalTimeFlg = PETSC_TRUE;
6393
6394 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*this);
6395
6396 TetPolynomialBase::switchCacheBaseOn<HDIV>(
6397 {elasticFeLhs.get(), elasticFeRhs.get()});
6398 CHKERR TSSetUp(ts);
6399 CHKERR TSElasticPostStep::postStepInitialise(this);
6400
6401 double ts_delta_time;
6402 CHKERR TSGetTimeStep(ts, &ts_delta_time);
6403
6404 if (physicalH1Update) {
6405 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
6406 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
6407 }
6408
6409 CHKERR TSElasticPostStep::preStepFun(ts);
6410 CHKERR TSElasticPostStep::postStepFun(ts);
6411
6412 const bool restart_run =
6413 start_step != 0 ||
6414 std::abs(start_time) > std::numeric_limits<double>::epsilon();
6415 const double test_time = restart_run ? start_time : finalPhysicalTime;
6416 if (!restart_run &&
6417 std::abs(test_time) < std::numeric_limits<double>::epsilon()) {
6419 "Set non-zero -physical_final_time for test_topological_derivative");
6420 }
6421
6422 currentPhysicalTime = test_time;
6423 physicalStepNumber = start_step;
6424 monitor_ptr->ts = PETSC_NULLPTR;
6425 monitor_ptr->ts_u = PETSC_NULLPTR;
6426 monitor_ptr->ts_t = currentPhysicalTime;
6427 monitor_ptr->ts_step = physicalStepNumber;
6429
6430 MOFEM_LOG("EP", Sev::inform)
6431 << "Solving load step before topological derivative test: "
6432 << physicalStepNumber << " Time " << currentPhysicalTime
6433 << " TS delta time " << ts_delta_time;
6434
6435 CHKERR TSSetStepNumber(ts, 0);
6436 CHKERR TSSetTime(ts, 0);
6437 CHKERR TSSetTimeStep(ts, ts_delta_time);
6438 if (!physicalH1Update) {
6439 CHKERR TSElasticPostStep::preStepFun(ts);
6440 }
6441 CHKERR TSSetSolution(ts, x);
6442 CHKERR TSSolve(ts, PETSC_NULLPTR);
6443 if (!physicalH1Update) {
6444 CHKERR TSElasticPostStep::postStepFun(ts);
6445 }
6446
6447 CHKERR DMoFEMMeshToLocalVector(dmElastic, x, INSERT_VALUES,
6448 SCATTER_FORWARD);
6449 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
6450 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
6451
6452 monitor_ptr->ts = PETSC_NULLPTR;
6453 monitor_ptr->ts_u = x;
6454 monitor_ptr->ts_t = currentPhysicalTime;
6455 monitor_ptr->ts_step = physicalStepNumber;
6457
6458 auto tao_sol0 = createDMVector(dmMaterial, RowColData::ROW);
6459 CHKERR DMoFEMMeshToLocalVector(dmMaterial, tao_sol0, INSERT_VALUES,
6460 SCATTER_FORWARD, RowColData::ROW);
6461 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6462 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6463
6464 int tao_sol_size, tao_sol_loc_size;
6465 CHKERR VecGetSize(tao_sol0, &tao_sol_size);
6466 CHKERR VecGetLocalSize(tao_sol0, &tao_sol_loc_size);
6467 MOFEM_LOG("EP", Sev::inform)
6468 << "Topological data vector size " << tao_sol_size << " local size "
6469 << tao_sol_loc_size << " number of interface faces "
6470 << interfaceFaces->size();
6471
6472 const char *list_objective_models[ObjectiveModelType::LAST_MODEL] = {
6473 "python_model", "hencky_model"};
6474#ifdef ENABLE_PYTHON_BINDING
6475 PetscInt choice_objective_model = ObjectiveModelType::PYTHON_MODEL;
6476#else
6477 PetscInt choice_objective_model = ObjectiveModelType::HENCKY_MODEL;
6478#endif
6480 PETSC_NULLPTR, PETSC_NULLPTR, "-objective_model_type",
6481 list_objective_models, ObjectiveModelType::LAST_MODEL,
6482 &choice_objective_model, PETSC_NULLPTR);
6483 const auto objective_model_type =
6484 static_cast<ObjectiveModelType>(choice_objective_model);
6485 MOFEM_LOG("EP", Sev::inform)
6486 << "Objective model type: -objective_model_type "
6487 << list_objective_models[objective_model_type];
6488
6490 PetscReal obj_value;
6491 CHKERR testTopologicalDerivative(topological_tao_ctx.get(), tao_sol0,
6492 &obj_value, g, objective_model_type);
6493
6494 CHKERR TSElasticPostStep::postStepDestroy();
6495 TetPolynomialBase::switchCacheBaseOff<HDIV>(
6496 {elasticFeLhs.get(), elasticFeRhs.get()});
6497
6499}
MoFEMErrorCode testTopologicalDerivative(TopologicalTAOCtx *ctx_ptr, Vec sol, PetscReal *f, Vec g, ObjectiveModelType eval_energy_model)
PetscErrorCode PetscOptionsGetEList(PetscOptions *, const char pre[], const char name[], const char *const *list, PetscInt next, PetscInt *value, PetscBool *set)

◆ withFieldOrders()

template<typename Op >
MoFEMErrorCode EshelbianCore::withFieldOrders ( Op &&  op) const
inline
Examples
/home/lk58p/mofem_install/vanilla_dev_release/mofem-cephas/mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 112 of file EshelbianCore.hpp.

112 {
116 CHKERR op.template operator()<DEMKOWICZ_JACOBI_BASE>();
117 break;
119 CHKERR op.template operator()<AINSWORTH_LEGENDRE_BASE>();
120 break;
121 default:
123 "Broken HDIV base not implemented");
124 }
126 }

Friends And Related Symbol Documentation

◆ solve_elastic_set_up

friend struct solve_elastic_set_up
friend

Definition at line 512 of file EshelbianCore.hpp.

Member Data Documentation

◆ a00FieldList

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

Definition at line 648 of file EshelbianCore.hpp.

◆ a00RangeList

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

Definition at line 650 of file EshelbianCore.hpp.

◆ addCrackMeshsetId

int EshelbianCore::addCrackMeshsetId = 1000
inlinestatic

Definition at line 77 of file EshelbianCore.hpp.

◆ alphaOmega

double EshelbianCore::alphaOmega = 0

◆ alphaOmega0

double EshelbianCore::alphaOmega0 = 0

◆ alphaR

double EshelbianCore::alphaR = 0

◆ alphaR0

double EshelbianCore::alphaR0 = 0

◆ alphaRho

double EshelbianCore::alphaRho = 0

◆ alphaTau

double EshelbianCore::alphaTau = 0

◆ alphaTau0

double EshelbianCore::alphaTau0 = 0

◆ alphaTauBcDisp

double EshelbianCore::alphaTauBcDisp = 0

◆ alphaTauBcDisp0

double EshelbianCore::alphaTauBcDisp0 = 0

◆ alphaU

double EshelbianCore::alphaU = 0

◆ alphaViscousOmega

double EshelbianCore::alphaViscousOmega = 0

◆ alphaViscousOmega0

double EshelbianCore::alphaViscousOmega0 = 0

◆ alphaViscousR

double EshelbianCore::alphaViscousR = 0

◆ alphaViscousR0

double EshelbianCore::alphaViscousR0 = 0

◆ alphaW

double EshelbianCore::alphaW = 0

◆ AnalyticalExprPythonPtr

boost::shared_ptr<AnalyticalExprPython> EshelbianCore::AnalyticalExprPythonPtr

◆ aoS

AO EshelbianCore::aoS = PETSC_NULLPTR

Definition at line 646 of file EshelbianCore.hpp.

◆ avgGriffithsEnergy

double EshelbianCore::avgGriffithsEnergy = -1

◆ 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

◆ bcSpatialSpringVecPtr

boost::shared_ptr<SpringBcVec> EshelbianCore::bcSpatialSpringVecPtr

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

◆ brokenHdivBase

FieldApproximationBase EshelbianCore::brokenHdivBase
inlinestatic

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

◆ crackingAddTime

double EshelbianCore::crackingAddTime = -1
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 = -1
inlinestatic

◆ currentCrackAreaPtr

boost::shared_ptr<double> EshelbianCore::currentCrackAreaPtr

◆ currentPhysicalTime

double EshelbianCore::currentPhysicalTime
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

◆ 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

◆ 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

◆ finalPhysicalTime

double EshelbianCore::finalPhysicalTime = 0
inlinestatic

◆ frontAdjEdges

boost::shared_ptr<Range> EshelbianCore::frontAdjEdges

◆ frontEdges

boost::shared_ptr<Range> EshelbianCore::frontEdges

◆ frontLayers

int EshelbianCore::frontLayers = 3

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

◆ hasNonHomogeneousMaterialBlock

bool EshelbianCore::hasNonHomogeneousMaterialBlock = false
inlinestatic

◆ heterogeneousYoungModTagName

std::string EshelbianCore::heterogeneousYoungModTagName
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

◆ 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_FALSE
inlinestatic

◆ listSolvers

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

Definition at line 24 of file EshelbianCore.hpp.

24 {"time_solver",
25 "dynamic_relaxation",
26 "cohesive",
27 "load_factor",
28 "shape_optimization",
29 "test_topological_derivative"};

◆ listTagsToProject

std::vector<std::string> EshelbianCore::listTagsToProject
inlinestatic

◆ listTagsToTransfer

std::vector<Tag> EshelbianCore::listTagsToTransfer

◆ loadFactor

double EshelbianCore::loadFactor = 1.0

◆ loadFactorTSSolveExecuted

PetscBool EshelbianCore::loadFactorTSSolveExecuted = PETSC_FALSE

◆ materialH1Order

int EshelbianCore::materialH1Order = 1

◆ materialH1Positions

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

◆ materialModel

enum MaterialModel EshelbianCore::materialModel = MooneyRivlin
inlinestatic

◆ maxCrackExtension

double EshelbianCore::maxCrackExtension
inlinestatic

◆ maxMovedFaces

boost::shared_ptr<Range> EshelbianCore::maxMovedFaces

Definition at line 621 of file EshelbianCore.hpp.

◆ meshTransferHybridInterp

PetscBool EshelbianCore::meshTransferHybridInterp
inlinestatic

◆ meshTransferInterpOrder

int EshelbianCore::meshTransferInterpOrder
inlinestatic

◆ meshTransferSourceMeshFileName

std::string EshelbianCore::meshTransferSourceMeshFileName
inlinestatic

◆ meshTransferSourceMeshFileSpecified

PetscBool EshelbianCore::meshTransferSourceMeshFileSpecified
inlinestatic

◆ mField

MoFEM::Interface& EshelbianCore::mField

◆ naturalBcElement

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

◆ nbCrackFaces

int EshelbianCore::nbCrackFaces = 0

Definition at line 652 of file EshelbianCore.hpp.

◆ nbJIntegralContours

int EshelbianCore::nbJIntegralContours
inlinestatic

◆ oldCrackArea

double EshelbianCore::oldCrackArea = 0.

◆ oldLoadFactor

double EshelbianCore::oldLoadFactor = 1.0

◆ oldStrainEnergy

double EshelbianCore::oldStrainEnergy = 0.

◆ parentAdjSkeletonFunctionDim2

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

◆ physicalDt

double EshelbianCore::physicalDt = 0
inlinestatic

◆ physicalEquations

boost::shared_ptr<PhysicalEquations> EshelbianCore::physicalEquations

◆ physicalH1Update

PetscBool EshelbianCore::physicalH1Update
inlinestatic

◆ physicalMaxSteps

int EshelbianCore::physicalMaxSteps = 20
inlinestatic

◆ physicalStepNumber

int EshelbianCore::physicalStepNumber = 0
inlinestatic

◆ physicalTimeFlg

PetscBool EshelbianCore::physicalTimeFlg
inlinestatic

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

◆ strainEnergy

double EshelbianCore::strainEnergy = 0.

◆ stretchHandling

enum StretchHandling EshelbianCore::stretchHandling
inlinestatic

◆ stretchSelector

enum StretchSelector EshelbianCore::stretchSelector = LOG
inlinestatic

◆ stretchTensor

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

◆ symmetrySelector

constexpr enum SymmetrySelector EshelbianCore::symmetrySelector = SYMMETRIC
inlinestaticconstexpr

◆ timeScaleMap

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

◆ v_max

constexpr double EshelbianCore::v_max = 24
inlinestaticconstexpr

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