OGS
PermeabilityMohrCoulombFailureIndexModel.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
5
6#include <Eigen/Eigenvalues>
7#include <boost/math/constants/constants.hpp>
8#include <cmath>
9#include <limits>
10
11#include "BaseLib/Error.h"
16#include "MathLib/MathTools.h"
19
20namespace MaterialPropertyLib
21{
22template <int DisplacementDim>
25 std::string name, ParameterLib::Parameter<double> const& k0,
26 double const kr, double const b, double const c, double const phi,
27 double const k_max, double const t_sigma_max,
28 ParameterLib::CoordinateSystem const* const local_coordinate_system)
29 : k0_(k0),
30 kr_(kr),
31 b_(b),
32 c_(c),
33 phi_(boost::math::constants::degree<double>() * phi),
34 k_max_(k_max),
35 t_sigma_max_(t_sigma_max),
36 local_coordinate_system_(local_coordinate_system)
37{
38 const double t_sigma_upper = c_ / std::tan(phi_);
39 if (t_sigma_max_ <= 0.0 || t_sigma_max_ > t_sigma_upper ||
40 std::fabs(t_sigma_max_ - t_sigma_upper) <
41 std::numeric_limits<double>::epsilon())
42 {
44 "Tensile strength parameter of {:e} is out of the range (0, "
45 "c/tan(phi)) = (0, {:e})",
46 t_sigma_max_, t_sigma_upper);
47 }
48
49 name_ = std::move(name);
50}
51
52template <int DisplacementDim>
54 const
55{
56 if (!std::holds_alternative<Medium*>(scale_))
57 {
59 "The property 'PermeabilityMohrCoulombFailureIndexModel' is "
60 "implemented on the 'medium' scale only.");
61 }
62}
63
64template <int DisplacementDim>
67 VariableArray const& variable_array,
68 ParameterLib::SpatialPosition const& pos, double const t,
69 double const /*dt*/) const
70{
71 auto const& stress_vector =
72 std::get<SymmetricTensor<DisplacementDim>>(variable_array.total_stress);
73
74 auto const& stress_tensor =
75 formEigenTensor<3>(static_cast<PropertyDataType>(stress_vector));
76
77 Eigen::SelfAdjointEigenSolver<Eigen::Matrix<double, 3, 3>>
78 eigenvalue_solver(stress_tensor);
79
80 // Principle stress
81 auto const sigma = eigenvalue_solver.eigenvalues();
82
83 auto k_data = k0_(t, pos);
84
85 double const max_sigma = std::max(std::fabs(sigma[0]), std::fabs(sigma[2]));
86
87 if (max_sigma < std::numeric_limits<double>::epsilon())
88 {
89 return fromVector(k_data);
90 }
91
92 double const sigma_m = 0.5 * (sigma[2] + sigma[0]);
93
94 double const tau_m = 0.5 * std::fabs(sigma[2] - sigma[0]);
95 double f = 0.0;
96 if (sigma_m > t_sigma_max_)
97 {
98 // tensile failure criterion
99 f = sigma_m / t_sigma_max_;
100
101 double const tau_tt =
102 c_ * std::cos(phi_) - t_sigma_max_ * std::sin(phi_);
103
104 f = std::max(f, tau_m / tau_tt);
105 }
106 else
107 {
108 // Mohr Coulomb failure criterion
109 f = tau_m / (c_ * std::cos(phi_) - sigma_m * std::sin(phi_));
110 }
111
112 if (f >= 1.0)
113 {
114 const double exp_value = std::exp(b_ * f);
115 std::transform(begin(k_data), end(k_data), begin(k_data),
116 [&](double const k_i)
117 { return std::min(k_i + kr_ * exp_value, k_max_); });
118 }
119
120 // Local coordinate transformation is only applied for the case that the
121 // initial intrinsic permeability is given with orthotropic assumption.
122 if (local_coordinate_system_ && (k_data.size() == DisplacementDim))
123 {
124 Eigen::Matrix<double, DisplacementDim, DisplacementDim> const e =
125 local_coordinate_system_->transformation<DisplacementDim>(pos);
126 Eigen::Matrix<double, DisplacementDim, DisplacementDim> k =
127 Eigen::Matrix<double, DisplacementDim, DisplacementDim>::Zero();
128
129 for (int i = 0; i < DisplacementDim; ++i)
130 {
131 Eigen::Matrix<double, DisplacementDim, DisplacementDim> const
132 ei_otimes_ei = e.col(i) * e.col(i).transpose();
133
134 k += k_data[i] * ei_otimes_ei;
135 }
136 return k;
137 }
138
139 return fromVector(k_data);
140}
141
142template <int DisplacementDim>
145 VariableArray const& /*variable_array*/, Variable const variable,
146 ParameterLib::SpatialPosition const& /*pos*/, double const /*t*/,
147 double const /*dt*/) const
148{
149 if (variable == Variable::mechanical_strain)
150 {
151 return 0.;
152 }
153
154 OGS_FATAL(
155 "The derivative of the intrinsic permeability k(sigma, ...) with "
156 "respect to stress tensor (sigma) is not implemented because that "
157 "dk/du is normally omitted.");
158}
161} // namespace MaterialPropertyLib
#define OGS_FATAL(...)
Definition Error.h:19
A failure index dependent permeability model wangetalperm2020.
PermeabilityMohrCoulombFailureIndexModel(std::string name, ParameterLib::Parameter< double > const &k0, double const kr, double const b, double const c, double const phi, double const k_max, double const t_sigma_max, ParameterLib::CoordinateSystem const *const local_coordinate_system)
PropertyDataType dValue(VariableArray const &variable_array, Variable const variable, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const override
virtual PropertyDataType value() const
std::variant< Medium *, Phase *, Component * > scale_
template Eigen::Matrix< double, 3, 3 > formEigenTensor< 3 >(MaterialPropertyLib::PropertyDataType const &values)
PropertyDataType fromVector(std::vector< double > const &values)
std::variant< double, Eigen::Matrix< double, 2, 1 >, Eigen::Matrix< double, 3, 1 >, Eigen::Matrix< double, 2, 2 >, Eigen::Matrix< double, 3, 3 >, Eigen::Matrix< double, 4, 1 >, Eigen::Matrix< double, 6, 1 >, Eigen::MatrixXd > PropertyDataType
A local coordinate system used for tensor transformations.