15#include <boost/math/constants/constants.hpp>
16#include <boost/math/special_functions/lambert_w.hpp>
30 OpShortenConstantRotation(
const std::string &field, Vec solution,
34 doEntities.fill(
false);
35 doEntities[MBTET] =
true;
45 if (!
data.getIndices().size())
47 if (
data.getIndices().size() < 3 ||
data.getFieldData().size() < 3)
49 "Incomplete constant rotation block");
52 const auto *indices =
data.getIndices().data().data();
53 if (indices[0] < first || indices[0] >= last)
55 if (indices[1] < first || indices[2] >= last)
57 "Constant rotation block crosses PETSc ownership ranges");
58 const double phi0 =
data.getN()(0, 0);
59 auto coefficient =
data.getFTensor1FieldData<3>();
60 const double angle = std::abs(phi0) * coefficient.l2();
61 if (!std::isfinite(angle))
63 constexpr double pi = std::numbers::pi;
67 const double turns = std::round(angle / (2 * pi));
68 const double factor = 1. - 2 * pi * turns / angle;
69 std::array<double, 3>
values;
70 auto shortened = getFTensor1FromPtr<3>(
values.data());
72 shortened(
i) = factor * coefficient(
i);
82 CHKERR TSGetSolution(ts, &solution);
83 const auto shorten_rotation = [&]() {
90 CHKERR VecGhostUpdateBegin(solution, INSERT_VALUES, SCATTER_FORWARD);
91 CHKERR VecGhostUpdateEnd(solution, INSERT_VALUES, SCATTER_FORWARD);
95 boost::make_shared<VolumeElementForcesAndSourcesCore>(ep_ptr->
mField);
96 fe->getUserPolynomialBase() =
97 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
98 fe->getRuleHook = [](
int,
int,
int) {
return 1; };
102 PetscInt local_count = 0, global_count;
103 fe->getOpPtrVector().push_back(
104 new OpShortenConstantRotation(ep_ptr->
rotAxis, solution, local_count));
107 CHKERR VecAssemblyBegin(solution);
108 CHKERR VecAssemblyEnd(solution);
109 CHKERR MPI_Allreduce(&local_count, &global_count, 1, MPIU_INT, MPI_SUM,
112 CHKERR VecGhostUpdateBegin(solution, INSERT_VALUES, SCATTER_FORWARD);
113 CHKERR VecGhostUpdateEnd(solution, INSERT_VALUES, SCATTER_FORWARD);
116 MOFEM_LOG(
"EP", Sev::inform) <<
"Shortened constant L2 rotation on "
117 << global_count <<
" elements";
122 const auto zero_fields = [&]() {
124 auto zero_field = [&](
const std::string &
field_name) {
128 CHKERR is_mng->isCreateProblemFieldAndRankLocal(
130 const int *index_ptr;
131 CHKERR ISGetIndices(is, &index_ptr);
135 CHKERR VecGetArray(solution, &array);
136 for (
int ii = 0; ii !=
size; ++ii) {
137 array[index_ptr[ii]] = 0;
139 CHKERR VecRestoreArray(solution, &array);
140 CHKERR ISRestoreIndices(is, &index_ptr);
145 <<
"Resetting incremental stretch and rotation after H1 transfer";
148 CHKERR VecGhostUpdateBegin(solution, INSERT_VALUES, SCATTER_FORWARD);
149 CHKERR VecGhostUpdateEnd(solution, INSERT_VALUES, SCATTER_FORWARD);
155 CHKERR shorten_rotation();
165 "Unsupported gradient approximator for incremental kinematics reset");
171constexpr char elasticPreStepKey[] =
"ep_elastic_pre_step";
172struct ElasticPreStepContext {
181 PetscContainer container =
nullptr;
183 reinterpret_cast<PetscObject *
>(&container));
186 "Missing elastic TS pre-step context");
187 void *pointer =
nullptr;
188 CHKERR PetscContainerGetPointer(container, &pointer);
189 auto &
context = *
static_cast<ElasticPreStepContext *
>(pointer);
195 !
context.reportedCoordinatePenalty) {
197 <<
"Constant rotation shortening disabled: alpha_r or "
198 "viscosity_alpha_r acts on raw rotation coordinates";
199 context.reportedCoordinatePenalty =
true;
211 PetscContainer container =
nullptr;
213 reinterpret_cast<PetscObject *
>(&container));
216 auto *
context =
new ElasticPreStepContext{ep_ptr, h1_update};
218 CHKERR PetscContainerSetUserDestroy(container, [](
void *pointer) {
220 delete static_cast<ElasticPreStepContext *
>(pointer);
225 CHKERR PetscContainerDestroy(&container);
227 void *pointer =
nullptr;
228 CHKERR PetscContainerGetPointer(container, &pointer);
229 auto &
context = *
static_cast<ElasticPreStepContext *
>(pointer);
233 CHKERR TSSetPreStep(ts, elasticPreStep);
238 :
comm(ep_ptr->mField.get_comm()) {
241 "Elastic projection is already active");
244 "Initialise elastic spatial projection");
253 CHKERRABORT(
comm, close());
281 auto create_post_step_ksp = [&]() {
284 auto set_up = [&]() {
291 GAUSS>::OpBaseTimesVector<1, 3, 3>;
292 auto fe_lhs = boost::make_shared<DomainEle>(ep_ptr->
mField);
293 auto fe_rhs = boost::make_shared<DomainEle>(ep_ptr->
mField);
295 fe_lhs->getUserPolynomialBase() = boost::shared_ptr<BaseFunction>(
297 fe_rhs->getUserPolynomialBase() = boost::shared_ptr<BaseFunction>(
300 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
304 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
308 fe_lhs->getOpPtrVector().push_back(
310 auto w_ptr = boost::make_shared<MatrixDouble>();
311 fe_rhs->getOpPtrVector().push_back(
313 fe_rhs->getOpPtrVector().push_back(
319 fe_rhs,
nullptr,
nullptr);
321 CHKERR KSPAppendOptionsPrefix(
ksp,
"prjspatial_");
333 prjKsp = create_post_step_ksp();
356 MOFEM_LOG(
"EP", Sev::inform) <<
"Pre step";
359 CHKERR TSGetTime(ts, &time);
363 auto debug_crack = [&]() {
366 PetscBool debug_crack_mesh = PETSC_FALSE;
368 &debug_crack_mesh, PETSC_NULLPTR);
369 if (debug_crack_mesh) {
372 const std::string &block_name,
374 std::vector<EntityHandle> &r) {
379 std::regex((boost::format(
"%s(.*)") % block_name).str())
383 for (
auto bc : bcs) {
386 bc->getMeshset(), dim, ents,
true);
388 r.push_back(bc->getMeshset());
406 *meshset_ptr, 3, tets);
409 std::vector<EntityHandle> meshsets;
410 meshsets.push_back(*meshset_ptr);
420 CHKERR TSGetStepNumber(ts, &time_step);
421 std::string file_name =
422 "crack_meshsets_" + std::to_string(time_step) +
".h5m";
424 nullptr, meshsets.data(),
425 static_cast<int>(meshsets.size()));
442 CHKERR TSGetSolution(ts, &T);
455 CHKERR TSGetTime(ts, &time);
457 MOFEM_LOG(
"EP", Sev::inform) <<
"Solve H1 post-step";
460 CHKERR VecGhostUpdateBegin(
prjD, INSERT_VALUES, SCATTER_FORWARD);
461 CHKERR VecGhostUpdateEnd(
prjD, INSERT_VALUES, SCATTER_FORWARD);
474 MOFEM_LOG(
"EP", Sev::inform) <<
"Calculate Griffith force";
479 "Energy release selector not handled");
482 std::numeric_limits<double>::epsilon()) {
483 MOFEM_LOG(
"EP", Sev::inform) <<
"Calculate faces orientation";
496 PetscBool local_stop = PETSC_FALSE;
497 PetscBool global_stop = PETSC_FALSE;
501 const double area_increase =
503 const bool crack_arrest_stops =
508 crack_arrest_stops) {
510 "Stopping crack growth. Area increase: %3.12e, "
511 "average Griffiths energy: %3.12e, critical Griffiths "
515 local_stop = PETSC_TRUE;
518 MPI_Bcast(&local_stop, 1, MPIU_BOOL, 0, PETSC_COMM_WORLD);
519 global_stop = local_stop;
522 TSSetConvergedReason(ts, TS_CONVERGED_USER);
Eshelbian plasticity interface.
boost::shared_ptr< IncrementalOptimizationContext > context
#define MOFEM_LOG_C(channel, severity, format,...)
boost::shared_ptr< DataAtIntegrationPts > data
bool reportedCoordinatePenalty
Elastic TS pre/post-step registration and H1 transfer lifecycle.
SmartPetscObj< Vec > values
#define FTENSOR_INDEX(DIM, I)
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, FIELD_DIM > OpDomainMass
#define MAX_DOFS_ON_ENTITY
Maximal number of DOFs on entity.
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
PetscErrorCode DMMoFEMSetIsPartitioned(DM dm, PetscBool is_partitioned)
PetscErrorCode DMMoFEMCreateSubDM(DM subdm, DM dm, const char problem_name[])
Must be called by user to set Sub DM MoFEM data structures.
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
PetscErrorCode DMMoFEMSetSquareProblem(DM dm, PetscBool square_problem)
set squared problem
PetscErrorCode DMMoFEMAddSubFieldRow(DM dm, const char field_name[])
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
PetscErrorCode DMMoFEMKSPSetComputeRHS(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
set KSP right hand side evaluation function
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
PetscErrorCode DMMoFEMKSPSetComputeOperators(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
Set KSP operators and push mofem finite element methods.
#define MOFEM_LOG(channel, severity)
Log.
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
FTensor::Index< 'i', SPACE_DIM > i
const FTensor::Tensor2< T, Dim, Dim > Vec
VolumeElementForcesAndSourcesCore::UserDataOperator VolUserDataOperator
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
auto createKSP(MPI_Comm comm)
PetscErrorCode DMMoFEMSetDestroyProblem(DM dm, PetscBool destroy_problem)
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
PetscErrorCode DMMoFEMClearDMCtx(DM dm)
Clear solver and Schur data owned by a MoFEM DM context.
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
PetscObject getPetscObject(T obj)
auto get_temp_meshset_ptr(moab::Interface &moab)
Create smart pointer to temporary meshset.
auto createDM(MPI_Comm comm, const std::string dm_type_name)
Creates smart DM object.
MoFEMErrorCode VecSetValues(Vec V, const EntitiesFieldData::EntData &data, const double *ptr, InsertMode iora)
Assemble PETSc vector.
constexpr auto field_name
CGG User Polynomial Base.
boost::shared_ptr< Range > frontAdjEdges
MoFEM::Interface & mField
const std::string spatialL2Disp
static enum SolverType solverType
SmartPetscObj< DM > dM
Coupled problem all fields.
const std::string materialH1Positions
static bool noCrackExtension
static PetscBool crackingOn
static double griffithEnergy
Griffith energy.
const std::string elementVolumeName
static enum RotSelector rotSelector
static enum RotSelector gradApproximator
boost::shared_ptr< Range > maxMovedFaces
const std::string spatialH1Disp
static double maxCrackExtension
static double crackingStartTime
MoFEMErrorCode calculateCrackArea(boost::shared_ptr< double > &area_ptr)
MoFEMErrorCode calculateOrientation(const int tag, bool set_orientation)
MoFEMErrorCode setNewFrontCoordinates()
MoFEMErrorCode projectGeometry(const EntityHandle meshset=0, double time=0)
MoFEMErrorCode projectMaterialTags(const EntityHandle meshset=0)
const std::string rotAxis
static int nbStepsNoCrackExtension
boost::shared_ptr< double > currentCrackAreaPtr
double avgGriffithsEnergy
MoFEMErrorCode addCrackSurfaces(const bool debug=false)
MoFEMErrorCode calculateFaceMaterialForce(const int tag, TS ts, SmartPetscObj< Vec > *adjoint_gradient_vector=nullptr)
static bool potentialCrackArrest
static int addCrackMeshsetId
static PetscBool propagateUnderCompression
static enum EnergyReleaseSelector energyReleaseSelector
SmartPetscObj< Vec > solTSStep
SmartPetscObj< DM > dmElastic
Elastic problem.
const std::string stretchTensor
ProjectionScope(EshelbianCore *ep_ptr)
static SmartPetscObj< KSP > prjKsp
static MoFEMErrorCode setPreStep(EshelbianCore *ep_ptr, TS ts, bool h1_update=false)
static MoFEMErrorCode postStepDestroy()
static SmartPetscObj< Vec > prjF
static SmartPetscObj< Vec > prjD
static MoFEMErrorCode postStepInitialise(EshelbianCore *ep_ptr)
static SmartPetscObj< DM > dmPrjSpatial
static EshelbianCore * epPtr
static MoFEMErrorCode postStepFun(TS ts)
static MoFEMErrorCode preStepFun(TS ts)
Add operators pushing bases from local to physical configuration.
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
Section manager is used to create indexes and sections.
Interface for managing meshsets containing materials and boundary conditions.
Specialization for MatrixDouble vector field values calculation.
intrusive_ptr for managing petsc objects
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Volume finite element base.