diff --git a/include/FrictionQPotFEM/UniformSingleLayer2d.h b/include/FrictionQPotFEM/UniformSingleLayer2d.h index 7e27fbc17..d013f787a 100644 --- a/include/FrictionQPotFEM/UniformSingleLayer2d.h +++ b/include/FrictionQPotFEM/UniformSingleLayer2d.h @@ -125,21 +125,24 @@ class System { // Minimise energy: run "timeStep" until a mechanical equilibrium has been reached. // Returns the number of iterations. - size_t minimise(double tol = 1e-5, size_t niter_tol = 20, size_t max_iter = 100000); + size_t minimise(double tol = 1e-5, size_t niter_tol = 20, size_t max_iter = 1000000); // Add event driven simple shear step. - // - "deps": size of the local stain kick to apply - // - "kick = false": increment displacements to the verge of yielding again - // "kick = true": increment displacements such that "deps" is applied locally - // - "direction = +1": apply shear to the right, - // "direction = -1": apply shear to the left - void addSimpleShearEventDriven(double deps, bool kick, double direction = +1.0); + // Return deformation gradient that is applied to the system. + double addSimpleShearEventDriven( + double deps, // size of the local stain kick to apply + bool kick, // "kick = false": increment displacements to "deps / 2" of yielding again + double direction = +1.0, // "direction = +1": apply shear to the right + bool dry_run = false); // "dry_run = true": do not apply displacement, do not check // Add simple shear until a target equivalent macroscopic stress has been reached. // Depending of the target stress compared to the current equivalent macroscopic stress, // the shear can be either to the left or to the right. // Throws if yielding is triggered before the stress was reached. - void addSimpleShearToFixedStress(double target_equivalent_macroscopic_stress); + // Return deformation gradient that is applied to the system. + double addSimpleShearToFixedStress( + double target_equivalent_macroscopic_stress, + bool dry_run = false); // "dry_run = true": do not apply displacement, do not check // Apply local strain to the right to a specific plastic element. // This 'triggers' one element while keeping the boundary conditions unchanged. diff --git a/include/FrictionQPotFEM/UniformSingleLayer2d.hpp b/include/FrictionQPotFEM/UniformSingleLayer2d.hpp index e3bd572bd..d2bee08d0 100644 --- a/include/FrictionQPotFEM/UniformSingleLayer2d.hpp +++ b/include/FrictionQPotFEM/UniformSingleLayer2d.hpp @@ -454,7 +454,8 @@ inline auto System::plastic_signOfSimpleShearPerturbation(double perturbation) return sign; } -inline void System::addSimpleShearEventDriven(double deps_kick, bool kick, double direction) +inline double System::addSimpleShearEventDriven( + double deps_kick, bool kick, double direction, bool dry_run) { FRICTIONQPOTFEM_ASSERT(this->isHomogeneousElastic()); FRICTIONQPOTFEM_REQUIRE(direction == +1.0 || direction == -1.0); @@ -476,7 +477,7 @@ inline void System::addSimpleShearEventDriven(double deps_kick, bool kick, doubl // no kick & current strain sufficiently close the next yield strain: don't move if (!kick && xt::amin(deps)() < deps_kick / 2.0) { - return; + return 0.0; } // set yield strain close to next yield strain @@ -501,6 +502,10 @@ inline void System::addSimpleShearEventDriven(double deps_kick, bool kick, doubl // - select minimal double dux = xt::amin(dgamma)(); + if (dry_run) { + return direction * dux; + } + // add as affine deformation gradient to the system for (size_t n = 0; n < m_nnode; ++n) { u_new(n, 0) += direction * dux * (m_coor(n, 1) - m_coor(0, 1)); @@ -521,9 +526,11 @@ inline void System::addSimpleShearEventDriven(double deps_kick, bool kick, doubl if (!kick) { FRICTIONQPOTFEM_REQUIRE(xt::all(xt::equal(idx, idx_new))); } + + return direction * dux; } -inline void System::addSimpleShearToFixedStress(double target_stress) +inline double System::addSimpleShearToFixedStress(double target_stress, bool dry_run) { FRICTIONQPOTFEM_ASSERT(this->isHomogeneousElastic()); @@ -549,6 +556,10 @@ inline void System::addSimpleShearToFixedStress(double target_stress) double dgamma = 2.0 * (-1.0 * direction * epsxy + std::sqrt(std::pow(eps_new, 2.0) - std::pow(epsxx, 2.0))); + if (dry_run) { + return direction * dgamma; + } + for (size_t n = 0; n < m_nnode; ++n) { u_new(n, 0) += direction * dgamma * (m_coor(n, 1) - m_coor(0, 1)); } @@ -564,6 +575,8 @@ inline void System::addSimpleShearToFixedStress(double target_stress) FRICTIONQPOTFEM_REQUIRE(xt::all(xt::equal(idx, idx_new))); FRICTIONQPOTFEM_REQUIRE(std::abs(target_stress - sig) / sig < 1e-4); + + return direction * dgamma; } inline auto System::triggerElementWithLocalSimpleShear(double deps_kick, size_t plastic_element) diff --git a/include/FrictionQPotFEM/config.h b/include/FrictionQPotFEM/config.h index a303a78fa..93a38318b 100644 --- a/include/FrictionQPotFEM/config.h +++ b/include/FrictionQPotFEM/config.h @@ -37,7 +37,7 @@ #define FRICTIONQPOTFEM_VERSION_MAJOR 0 #define FRICTIONQPOTFEM_VERSION_MINOR 5 -#define FRICTIONQPOTFEM_VERSION_PATCH 1 +#define FRICTIONQPOTFEM_VERSION_PATCH 2 #define FRICTIONQPOTFEM_VERSION_AT_LEAST(x, y, z) \ (FRICTIONQPOTFEM_VERSION_MAJOR > x || (FRICTIONQPOTFEM_VERSION_MAJOR >= x && \