OGS
LinearElasticOrthotropicPhaseField.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#pragma once
5
6#include <Eigen/Eigenvalues>
7
10
11namespace MaterialLib
12{
13namespace Solids
14{
15namespace Phasefield
16{
17
18template <int DisplacementDim>
20 DisplacementDim> /* eps_tensile */,
22 DisplacementDim> /* sigma_real */,
24 DisplacementDim> /* sigma_tensile */,
26 DisplacementDim> /* sigma_compressive */,
28 double /* strain_energy_tensile */, double /* elastic_energy */,
30 DisplacementDim> /* C_tensile */,
32 DisplacementDim> /* C_compressive
33 */
34 >
36 double const degradation,
39{
40 static constexpr int KelvinVectorSize =
42 using KelvinVector =
44 using KelvinMatrix =
47 // calculation of deviatoric parts
48 auto const& P_dev = Invariants::deviatoric_projection;
49
50 KelvinMatrix const C = C_ortho;
51 // calculation of square root of elasticity tensor
52 Eigen::SelfAdjointEigenSolver<KelvinMatrix> es(C);
53 KelvinMatrix const sqrt_C = es.operatorSqrt();
54 Eigen::SelfAdjointEigenSolver<KelvinMatrix> es_inverse(C.inverse());
55 KelvinMatrix const sqrt_C_inverse = es_inverse.operatorSqrt();
56
57 // strain in a transformed space
58 KelvinVector const epst = sqrt_C * eps;
59 double const epst_curr_trace = Invariants::trace(epst);
60
61 // projection tensors in transformed space
62 KelvinMatrix teps_p = KelvinMatrix::Zero();
63 KelvinMatrix teps_n = KelvinMatrix::Zero();
64 if (epst_curr_trace >= 0) /* QQQ */
65 {
66 teps_p.template topLeftCorner<3, 3>().setConstant(1. / 3);
67 }
68 else
69 {
70 teps_n.template topLeftCorner<3, 3>().setConstant(1. / 3);
71 }
72
73 teps_p.noalias() += P_dev * KelvinMatrix::Identity();
74
75 // strain tensile / compressive
76 KelvinVector const eps_tensile = sqrt_C_inverse * (teps_p * sqrt_C) * eps;
77 KelvinVector const eps_compressive =
78 sqrt_C_inverse * (teps_n * sqrt_C) * eps;
79
80 // projection tensors in original space
81 KelvinMatrix const der_eps_p = sqrt_C_inverse * (teps_p * sqrt_C);
82 KelvinMatrix const der_eps_n = sqrt_C_inverse * (teps_n * sqrt_C);
83 // C tensile / compressive
84 KelvinMatrix const C_tensile = der_eps_p.transpose() * C * der_eps_p;
85 KelvinMatrix const C_compressive = der_eps_n.transpose() * C * der_eps_n;
86
87 // stress tensile / compressive
88 KelvinVector const sigma_tensile = C_tensile * eps;
89 KelvinVector const sigma_compressive = C_compressive * eps;
90
91 // decomposition of strain energy density
92 double const strain_energy_tensile =
93 0.5 * sigma_tensile.adjoint() * eps_tensile;
94 double const strain_energy_compressive =
95 0.5 * sigma_compressive.adjoint() * eps_compressive;
96
97 double const elastic_energy =
98 degradation * strain_energy_tensile + strain_energy_compressive;
99
100 KelvinVector const sigma_real =
101 degradation * sigma_tensile + sigma_compressive;
102 KelvinMatrix const D = degradation * C_tensile + C_compressive;
103
104 return std::make_tuple(eps_tensile, sigma_real, sigma_tensile,
105 sigma_compressive, D, strain_energy_tensile,
106 elastic_energy, C_tensile, C_compressive);
107}
108
109template <int DisplacementDim>
111 DisplacementDim> /* eps_tensile */,
113 DisplacementDim> /* sigma_real */,
115 DisplacementDim> /* sigma_tensile */,
117 double /* strain_energy_tensile */, double /* elastic_energy */,
119 DisplacementDim> /* C_tensile */,
121 DisplacementDim> /* C_compressive
122 */
123 >
125 double const degradation,
128{
129 using KelvinVector =
131 using KelvinMatrix =
133
134 KelvinMatrix const C = C_ortho;
135
136 // calculation of square root of elasticity tensor
137 Eigen::SelfAdjointEigenSolver<KelvinMatrix> es(C);
138 KelvinMatrix const sqrt_C = es.operatorSqrt();
139 Eigen::SelfAdjointEigenSolver<KelvinMatrix> es_inverse(C.inverse());
140 KelvinMatrix const sqrt_C_inverse = es_inverse.operatorSqrt();
141
142 // strain in a transformed space
143 KelvinVector const epst = sqrt_C * eps;
144
145 // strain tensor in 3D
146 Eigen::Matrix3d const eps_3D =
148
149 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> const es_eps_3D(eps_3D);
150 Eigen::Vector3d const eigen_values_eps_3D = es_eps_3D.eigenvalues().real();
151 Eigen::Matrix3d const eigen_vectors_eps_3D = es_eps_3D.eigenvectors();
152 Eigen::Matrix3d const E1_eigenp =
153 eigen_vectors_eps_3D.col(0) * eigen_vectors_eps_3D.col(0).transpose();
154
155 Eigen::Matrix3d const E3_eigenp =
156 eigen_vectors_eps_3D.col(2) * eigen_vectors_eps_3D.col(2).transpose();
157
158 KelvinVector const E1_vec =
160
161 KelvinVector const E3_vec =
163
164 KelvinMatrix const E1oE1 = E1_vec * E1_vec.transpose();
165 KelvinMatrix const E3oE3 = E3_vec * E3_vec.transpose();
166
167 KelvinMatrix I_p = KelvinMatrix::Zero();
168 KelvinMatrix I_n = KelvinMatrix::Zero();
169
170 KelvinMatrix const I_S = KelvinMatrix::Identity();
171 if (DisplacementDim == 2)
172 {
173 if (std::abs(eigen_values_eps_3D(2) - eigen_values_eps_3D(0)) >
174 std::numeric_limits<double>::epsilon())
175 {
176 I_p = (macaulayTensile(eigen_values_eps_3D(0)) -
177 macaulayTensile(eigen_values_eps_3D(2))) /
178 (eigen_values_eps_3D(0) - eigen_values_eps_3D(2)) *
179 (I_S - (E1oE1 + E3oE3)) +
180 (heaviside(eigen_values_eps_3D(0)) * E1oE1 +
181 heaviside(eigen_values_eps_3D(2)) * E3oE3);
182 I_n = (macaulayCompressive(eigen_values_eps_3D(0)) -
183 macaulayCompressive(eigen_values_eps_3D(2))) /
184 (eigen_values_eps_3D(0) - eigen_values_eps_3D(2)) *
185 (I_S - (E1oE1 + E3oE3)) +
186 (heaviside(-eigen_values_eps_3D(0)) * E1oE1 +
187 heaviside(-eigen_values_eps_3D(2)) * E3oE3);
188 }
189 else
190 {
191 I_p = heaviside(eigen_values_eps_3D(0)) * I_S;
192 I_n = heaviside(-eigen_values_eps_3D(0)) * I_S;
193 }
194 }
195
196 // strain tensile / compressive
197 KelvinVector const eps_tensile = sqrt_C_inverse * (I_p * sqrt_C) * eps;
198 KelvinVector const eps_compressive = sqrt_C_inverse * (I_n * sqrt_C) * eps;
199
200 // C tensile / compressive
201 KelvinMatrix const C_tensile = sqrt_C * I_p * sqrt_C;
202 KelvinMatrix const C_compressive = sqrt_C * I_n * sqrt_C;
203
204 // stress tensile / compressive
205 KelvinVector const sigma_tensile = C * eps_tensile;
206 KelvinVector const sigma_compressive = C * eps_compressive;
207
208 // decomposition of strain energy density
209 double const strain_energy_tensile =
210 0.5 * sigma_tensile.adjoint() * eps_tensile;
211 double const strain_energy_compressive =
212 0.5 * sigma_compressive.adjoint() * eps_compressive;
213
214 double const elastic_energy =
215 degradation * strain_energy_tensile + strain_energy_compressive;
216
217 KelvinVector const sigma_real =
218 degradation * sigma_tensile + sigma_compressive;
219
220 KelvinMatrix const D = degradation * C_tensile + C_compressive;
221
222 return std::make_tuple(eps_tensile, sigma_real, sigma_tensile, D,
223 strain_energy_tensile, elastic_energy, C_tensile,
224 C_compressive);
225}
226
227} // namespace Phasefield
228} // namespace Solids
229} // namespace MaterialLib
std::tuple< MathLib::KelvinVector::KelvinVectorType< DisplacementDim >, MathLib::KelvinVector::KelvinVectorType< DisplacementDim >, MathLib::KelvinVector::KelvinVectorType< DisplacementDim >, MathLib::KelvinVector::KelvinVectorType< DisplacementDim >, MathLib::KelvinVector::KelvinMatrixType< DisplacementDim >, double, double, MathLib::KelvinVector::KelvinMatrixType< DisplacementDim >, MathLib::KelvinVector::KelvinMatrixType< DisplacementDim > > calculateOrthoVolDevDegradedStress(double const degradation, MathLib::KelvinVector::KelvinVectorType< DisplacementDim > const &eps, MathLib::KelvinVector::KelvinMatrixType< DisplacementDim > const &C_ortho)
std::tuple< MathLib::KelvinVector::KelvinVectorType< DisplacementDim >, MathLib::KelvinVector::KelvinVectorType< DisplacementDim >, MathLib::KelvinVector::KelvinVectorType< DisplacementDim >, MathLib::KelvinVector::KelvinMatrixType< DisplacementDim >, double, double, MathLib::KelvinVector::KelvinMatrixType< DisplacementDim >, MathLib::KelvinVector::KelvinMatrixType< DisplacementDim > > calculateOrthoMasonryDegradedStress(double const degradation, MathLib::KelvinVector::KelvinVectorType< DisplacementDim > const &eps, MathLib::KelvinVector::KelvinMatrixType< DisplacementDim > const &C_ortho)
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)
KelvinVectorType< DisplacementDim > tensorToKelvin(Eigen::Matrix< double, 3, 3 > const &m)
Eigen::Matrix< double, kelvin_vector_dimensions(DisplacementDim), kelvin_vector_dimensions(DisplacementDim), Eigen::RowMajor > KelvinMatrixType