From dfaf9b9fc8fd30df2bd16fb3f73c1a7ba015045e Mon Sep 17 00:00:00 2001 From: Francesco Parisio <francesco.parisio@protonmail.com> Date: Fri, 10 Feb 2017 12:11:53 +0100 Subject: [PATCH] [MatL] Ehlers: Add damage state and updateDamage. --- MaterialLib/SolidModels/Ehlers-impl.h | 64 ++++++++++++++++++++++++++- MaterialLib/SolidModels/Ehlers.h | 23 +++++++++- 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/MaterialLib/SolidModels/Ehlers-impl.h b/MaterialLib/SolidModels/Ehlers-impl.h index d5415da9d24..92c401d855c 100644 --- a/MaterialLib/SolidModels/Ehlers-impl.h +++ b/MaterialLib/SolidModels/Ehlers-impl.h @@ -464,6 +464,50 @@ void calculatePlasticJacobian( // G_52, G_53, G_55 are zero } +template <int DisplacementDim> +void SolidEhlers<DisplacementDim>::updateDamage( + double const t, ProcessLib::SpatialPosition const& x, + typename MechanicsBase<DisplacementDim>::MaterialStateVariables& + material_state_variables) +{ + assert(dynamic_cast<MaterialStateVariables*>(&material_state_variables) != + nullptr); + MaterialStateVariables& state = + static_cast<MaterialStateVariables&>(material_state_variables); + + // Default case of the rate problem. Updated below if volumetric plastic + // strain rate is positive (dilatancy). + state.kappa_d = state.kappa_d_prev; + + // Compute damage current step + double const eps_p_V_dot = state.eps_p_V - state.eps_p_V_prev; + if (eps_p_V_dot > 0) + { + double const h_d = _damage_properties->h_d(t, x)[0]; + double const eps_p_eff_dot = state.eps_p_eff - state.eps_p_eff_prev; + double const r_s = eps_p_eff_dot / eps_p_V_dot; + + // Brittleness decrease with confinement for the nonlinear flow rule. + // ATTENTION: For linear flow rule -> constant brittleness. + double x_s = 0; + if (r_s < 1) + { + x_s = 1 + h_d * r_s * r_s; + } + else + { + x_s = 1 - 3 * h_d + 4 * h_d * std::sqrt(r_s); + } + state.kappa_d += eps_p_eff_dot / x_s; + } + + double const alpha_d = _damage_properties->alpha_d(t, x)[0]; + double const beta_d = _damage_properties->beta_d(t, x)[0]; + + // Update internal damage variable. + state.damage = (1 - beta_d) * (1 - std::exp(-state.kappa_d / alpha_d)); +} + /// Calculates the derivative of the residuals with respect to total /// strain. Implementation fully implicit only. template <int DisplacementDim> @@ -551,8 +595,17 @@ bool SolidEhlers<DisplacementDim>::computeConstitutiveRelation( double const G = _mp.G(t, x)[0]; double const K = _mp.K(t, x)[0]; + KelvinVector sigma_eff_prev = sigma_prev; // In case without damage the + // effective value is same as the + // previous one. + if (_damage_properties) + { + // Compute sigma_eff from damage total stress sigma, which is given by + // sigma_eff=sigma_prev / (1-damage) + sigma_eff_prev = sigma_prev / (1 - _state.damage_prev); + } KelvinVector sigma = - predict_sigma<DisplacementDim>(G, K, sigma_prev, eps, eps_prev, eps_V); + predict_sigma<DisplacementDim>(G, K, sigma_eff_prev, eps, eps_prev, eps_V); // update parameter _mp.calculateIsotropicHardening(t, x, _state.eps_p_eff); @@ -644,6 +697,9 @@ bool SolidEhlers<DisplacementDim>::computeConstitutiveRelation( dresidual_deps.template block<KelvinVectorSize, KelvinVectorSize>(0, 0) .noalias() = calculateDResidualDEps<DisplacementDim>(K, G); + if (_damage_properties) + updateDamage(t, x, _state); + // Extract consistent tangent. C.noalias() = _mp.G(t, x)[0] * @@ -652,7 +708,11 @@ bool SolidEhlers<DisplacementDim>::computeConstitutiveRelation( } // Update sigma. - sigma_final.noalias() = G * sigma; + if (_damage_properties) + sigma_final = G * sigma * (1 - _state.damage); + else + sigma_final.noalias() = G * sigma; + return true; } diff --git a/MaterialLib/SolidModels/Ehlers.h b/MaterialLib/SolidModels/Ehlers.h index b7e0ec00479..7b60c649c91 100644 --- a/MaterialLib/SolidModels/Ehlers.h +++ b/MaterialLib/SolidModels/Ehlers.h @@ -143,6 +143,8 @@ public: eps_p_D = eps_p_D_prev; eps_p_V = eps_p_V_prev; eps_p_eff = eps_p_eff_prev; + kappa_d = kappa_d_prev; + damage = damage_prev; lambda = 0; } @@ -151,6 +153,8 @@ public: eps_p_D_prev = eps_p_D; eps_p_V_prev = eps_p_V; eps_p_eff_prev = eps_p_eff; // effective part of trace(eps_p) + kappa_d_prev = kappa_d; + damage_prev = damage; lambda = 0; } @@ -159,13 +163,16 @@ public: KelvinVector eps_p_D; ///< deviatoric plastic strain double eps_p_V = 0; ///< volumetric strain double eps_p_eff = 0; ///< effective plastic strain + double kappa_d = 0; ///< damage driving variable + double damage = 0; ///< isotropic damage variable // Initial values from previous timestep KelvinVector eps_p_D_prev; ///< \copydoc eps_p_D double eps_p_V_prev = 0; ///< \copydoc eps_p_V double eps_p_eff_prev = 0; ///< \copydoc eps_p_eff - - double lambda = 0; ///< plastic multiplier + double kappa_d_prev = 0; ///< \copydoc kappa_d + double damage_prev = 0; ///< \copydoc damage + double lambda = 0; ///< plastic multiplier #ifndef NDEBUG friend std::ostream& operator<<(std::ostream& os, @@ -174,8 +181,12 @@ public: os << "State:\n" << "eps_p_D: " << m.eps_p_D << "\n" << "eps_p_eff: " << m.eps_p_eff << "\n" + << "kappa_d: " << m.kappa_d << "\n" + << "damage: " << m.damage << "\n" << "eps_p_D_prev: " << m.eps_p_D_prev << "\n" << "eps_p_eff_prev: " << m.eps_p_eff_prev << "\n" + << "kappa_d_prev: " << m.kappa_d_prev << "\n" + << "damage_prev: " << m.damage_prev << "\n" << "lambda: " << m.lambda << "\n"; return os; } @@ -216,6 +227,14 @@ public: typename MechanicsBase<DisplacementDim>::MaterialStateVariables& material_state_variables) override; +private: + /// Computes the damage internal material variable explicitly based on the + /// results obtained from the local stress return algorithm. + void updateDamage( + double const t, ProcessLib::SpatialPosition const& x, + typename MechanicsBase<DisplacementDim>::MaterialStateVariables& + material_state_variables); + private: MaterialProperties _mp; std::unique_ptr<EhlersDamageProperties> _damage_properties; -- GitLab