OGS
LinearElasticIsotropicPhaseField.h
Go to the documentation of this file.
1
10#pragma once
11
12#include <Eigen/Eigenvalues>
13#include <boost/math/special_functions/pow.hpp>
14
16
17namespace MaterialLib
18{
19namespace Solids
20{
21namespace Phasefield
22{
32inline double heaviside(double const v)
33{
34 return (v < 0) ? 0.0 : 1.0;
35}
36
39inline double macaulayTensile(double const v)
40{
41 return v * heaviside(v);
42}
43inline double macaulayCompressive(double v)
44{
45 return v * (1 - heaviside(v));
46}
47
48template <int DisplacementDim>
50 DisplacementDim> /* sigma_real */,
52 DisplacementDim> /* sigma_tensile */,
54 double /* strain_energy_tensile */, double /* elastic_energy */,
56 DisplacementDim> /* C_tensile */,
58 DisplacementDim> /* C_compressive
59 */
60 >
62 double const degradation, double const bulk_modulus, double const mu,
64{
65 static int const KelvinVectorSize =
67 using KelvinVector =
69 using KelvinMatrix =
72 // calculation of deviatoric parts
73 auto const& P_dev = Invariants::deviatoric_projection;
74 KelvinVector const epsd_curr = P_dev * eps;
75
76 // Hydrostatic part for the stress and the tangent.
77 double const eps_curr_trace = Invariants::trace(eps);
78
79 KelvinMatrix C_tensile = KelvinMatrix::Zero();
80 KelvinMatrix C_compressive = KelvinMatrix::Zero();
81
82 auto strain_energy_computation_vol = [&](auto&& macaulay)
83 {
84 auto macaulay_squared = [&macaulay](double x)
85 { return boost::math::pow<2>(macaulay(x)); };
86 return bulk_modulus / 2 * macaulay_squared(eps_curr_trace);
87 };
88
89 auto stress_computation_vol = [&](auto&& macaulay)
90 { return bulk_modulus * macaulay(eps_curr_trace) * Invariants::identity2; };
91
92 auto hs = [&](double const v) { return heaviside(v); };
93
94 auto mt = [&](double const v) { return macaulayTensile(v); };
95
96 auto mc = [&](double const v) { return macaulayCompressive(v); };
97
98 double const strain_energy_tensile = strain_energy_computation_vol(mt) +
99 mu * epsd_curr.transpose() * epsd_curr;
100
101 KelvinVector const sigma_tensile =
102 stress_computation_vol(mt) + 2 * mu * epsd_curr;
103
104 KelvinVector const sigma_compressive = stress_computation_vol(mc);
105
106 C_tensile.template topLeftCorner<3, 3>().setConstant(bulk_modulus *
107 hs(eps_curr_trace));
108 C_tensile.noalias() += 2 * mu * P_dev * KelvinMatrix::Identity();
109
110 C_compressive.template topLeftCorner<3, 3>().setConstant(
111 bulk_modulus * (1 - hs(eps_curr_trace)));
112
113 double const elastic_energy =
114 bulk_modulus / 2 * eps_curr_trace * eps_curr_trace +
115 mu * epsd_curr.transpose() * epsd_curr;
116 KelvinVector const sigma_real =
117 degradation * sigma_tensile + sigma_compressive;
118
119 KelvinMatrix const D = degradation * C_tensile + C_compressive;
120
121 return std::make_tuple(sigma_real, sigma_tensile, D, strain_energy_tensile,
122 elastic_energy, C_tensile, C_compressive);
123}
124
125template <int DisplacementDim>
127 DisplacementDim> /* sigma_real */,
129 DisplacementDim> /* sigma_tensile */,
131 double /* strain_energy_tensile */, double /* elastic_energy */,
133 DisplacementDim> /* C_tensile */,
135 DisplacementDim> /* C_compressive
136 */
137 >
139 double const degradation,
140 double const bulk_modulus,
141 double const mu,
143{
144 static int const KelvinVectorSize =
146 using KelvinVector =
148 using KelvinMatrix =
151 // calculation of deviatoric parts
152 auto const& P_dev = Invariants::deviatoric_projection;
153 KelvinVector const epsd_curr = P_dev * eps;
154
155 // Hydrostatic part for the stress and the tangent.
156 double const eps_curr_trace = Invariants::trace(eps);
157
158 KelvinMatrix C_tensile = KelvinMatrix::Zero();
159 KelvinMatrix C_compressive = KelvinMatrix::Zero();
160
161 double const strain_energy_tensile =
162 bulk_modulus / 2 * eps_curr_trace * eps_curr_trace +
163 mu * epsd_curr.transpose() * epsd_curr;
164 double const elastic_energy = degradation * strain_energy_tensile;
165 KelvinVector const sigma_tensile =
166 bulk_modulus * eps_curr_trace * Invariants::identity2 +
167 2 * mu * epsd_curr;
168 C_tensile.template topLeftCorner<3, 3>().setConstant(bulk_modulus);
169 C_tensile.noalias() += 2 * mu * P_dev * KelvinMatrix::Identity();
170 KelvinVector const sigma_real = degradation * sigma_tensile;
171
172 KelvinMatrix const D = degradation * C_tensile + C_compressive;
173
174 return std::make_tuple(sigma_real, sigma_tensile, D, strain_energy_tensile,
175 elastic_energy, C_tensile, C_compressive);
176}
177
178template <int DisplacementDim>
180 DisplacementDim> /* sigma_real */,
182 DisplacementDim> /* sigma_tensile */,
184 double /* strain_energy_tensile */, double /* elastic_energy */,
186 DisplacementDim> /* C_tensile */,
188 DisplacementDim> /* C_compressive
189 */
190 >
192 double const degradation,
193 double const bulk_modulus,
194 double const mu,
196{
197 static int const KelvinVectorSize =
199 using KelvinVector =
201 using KelvinMatrix =
204 // calculation of deviatoric parts
205 auto const& P_dev = Invariants::deviatoric_projection;
206 KelvinVector const epsd_curr = P_dev * eps;
207
208 // Hydrostatic part for the stress and the tangent.
209 double const eps_curr_trace = Invariants::trace(eps);
210
211 KelvinMatrix C_tensile = KelvinMatrix::Zero();
212 KelvinMatrix C_compressive = KelvinMatrix::Zero();
213
214 KelvinVector const sigma_tensile =
215 bulk_modulus * eps_curr_trace * Invariants::identity2 +
216 2 * mu * epsd_curr;
217 // The maximum principal stress
218 auto sigma_tensor =
220 Eigen::SelfAdjointEigenSolver<decltype(sigma_tensor)>
221 selfAdjoint_eigen_solver(sigma_tensor);
222 double const max_principle_stress =
223 selfAdjoint_eigen_solver
224 .eigenvalues()[2]; // selfAdjoint_eigen_solver function gives an
225 // ascending sequence.
226 //
227 double const E0 = 9.0 * mu * bulk_modulus / (3.0 * bulk_modulus + mu);
228 auto hs = [&](double const v) { return heaviside(v); };
229 //
230 double const strain_energy_tensile = 0.5 * max_principle_stress *
231 max_principle_stress *
232 hs(max_principle_stress) / E0;
233 double const elastic_energy =
234 degradation * (bulk_modulus / 2 * eps_curr_trace * eps_curr_trace +
235 mu * epsd_curr.transpose() * epsd_curr);
236 //
237 C_tensile.template topLeftCorner<3, 3>().setConstant(bulk_modulus);
238 C_tensile.noalias() += 2 * mu * P_dev * KelvinMatrix::Identity();
239 KelvinVector const sigma_real = degradation * sigma_tensile;
240
241 KelvinMatrix const D = degradation * C_tensile + C_compressive;
242 return std::make_tuple(sigma_real, sigma_tensile, D, strain_energy_tensile,
243 elastic_energy, C_tensile, C_compressive);
244}
245
246} // namespace Phasefield
247} // namespace Solids
248} // namespace MaterialLib
std::tuple< MathLib::KelvinVector::KelvinVectorType< DisplacementDim >, MathLib::KelvinVector::KelvinVectorType< DisplacementDim >, MathLib::KelvinVector::KelvinMatrixType< DisplacementDim >, double, double, MathLib::KelvinVector::KelvinMatrixType< DisplacementDim >, MathLib::KelvinVector::KelvinMatrixType< DisplacementDim > > calculateIsotropicDegradedStress(double const degradation, double const bulk_modulus, double const mu, MathLib::KelvinVector::KelvinVectorType< DisplacementDim > const &eps)
std::tuple< MathLib::KelvinVector::KelvinVectorType< DisplacementDim >, MathLib::KelvinVector::KelvinVectorType< DisplacementDim >, MathLib::KelvinVector::KelvinMatrixType< DisplacementDim >, double, double, MathLib::KelvinVector::KelvinMatrixType< DisplacementDim >, MathLib::KelvinVector::KelvinMatrixType< DisplacementDim > > calculateVolDevDegradedStress(double const degradation, double const bulk_modulus, double const mu, MathLib::KelvinVector::KelvinVectorType< DisplacementDim > const &eps)
std::tuple< MathLib::KelvinVector::KelvinVectorType< DisplacementDim >, MathLib::KelvinVector::KelvinVectorType< DisplacementDim >, MathLib::KelvinVector::KelvinMatrixType< DisplacementDim >, double, double, MathLib::KelvinVector::KelvinMatrixType< DisplacementDim >, MathLib::KelvinVector::KelvinMatrixType< DisplacementDim > > calculateIsotropicDegradedStressWithRankineEnergy(double const degradation, double const bulk_modulus, double const mu, MathLib::KelvinVector::KelvinVectorType< DisplacementDim > const &eps)
constexpr int kelvin_vector_dimensions(int const displacement_dim)
Kelvin vector dimensions for given displacement dimension.
Eigen::Matrix< double, kelvin_vector_dimensions(DisplacementDim), 1, Eigen::ColMajor > KelvinVectorType
Eigen::Matrix< double, 3, 3 > kelvinVectorToTensor(Eigen::Matrix< double, 4, 1, Eigen::ColMajor, 4, 1 > const &v)
Eigen::Matrix< double, kelvin_vector_dimensions(DisplacementDim), kelvin_vector_dimensions(DisplacementDim), Eigen::RowMajor > KelvinMatrixType