OGS
SaturationDependentSwelling.cpp
Go to the documentation of this file.
1 
11 
12 #include <cmath>
13 
14 #include "MaterialLib/MPL/Medium.h"
15 #include "MathLib/KelvinVector.h"
17 
18 namespace MaterialPropertyLib
19 {
21  std::string name,
22  std::array<double, 3>
23  swelling_pressures,
24  std::array<double, 3>
25  exponents,
26  double const lower_saturation_limit,
27  double const upper_saturation_limit,
28  ParameterLib::CoordinateSystem const* const local_coordinate_system)
29  : p_(std::move(swelling_pressures)),
30  lambda_(std::move(exponents)),
31  S_min_(lower_saturation_limit),
32  S_max_(upper_saturation_limit),
33  local_coordinate_system_(local_coordinate_system)
34 {
35  name_ = std::move(name);
36 }
37 
39 {
40  if (!std::holds_alternative<Phase*>(scale_))
41  {
42  OGS_FATAL(
43  "The property 'SaturationDependentSwelling' is implemented on the "
44  "'phase' scales only.");
45  }
46  auto const phase = std::get<Phase*>(scale_);
47  if (phase->name != "Solid")
48  {
49  OGS_FATAL(
50  "The property 'SaturationDependentSwelling' must be given in the "
51  "'Solid' phase, not in '{:s}' phase.",
52  phase->name);
53  }
54 }
55 
57  VariableArray const& variable_array,
58  VariableArray const& variable_array_prev,
59  ParameterLib::SpatialPosition const& pos, double const /*t*/,
60  double const dt) const
61 {
62  auto const S_L = std::get<double>(
63  variable_array[static_cast<int>(Variable::liquid_saturation)]);
64  auto const S_L_prev = std::get<double>(
65  variable_array_prev[static_cast<int>(Variable::liquid_saturation)]);
66 
67  Eigen::Matrix<double, 3, 3> const e =
68  local_coordinate_system_ == nullptr
69  ? Eigen::Matrix<double, 3, 3>::Identity()
71 
72  Eigen::Matrix<double, 3, 3> delta_sigma_sw =
73  Eigen::Matrix<double, 3, 3>::Zero();
74 
75  if (S_L < S_min_)
76  {
77  return delta_sigma_sw; // still being zero.
78  }
79 
80  double const S_eff = std::clamp((S_L - S_min_) / (S_max_ - S_min_), 0., 1.);
81  double const S_eff_prev =
82  std::clamp((S_L_prev - S_min_) / (S_max_ - S_min_), 0., 1.);
83 
84  double const delta_S_eff = S_eff - S_eff_prev;
85 
86  // \Delta\sigma_{sw} = - \sum_i k_i (\lambda p S_{eff}^{(\lambda_i - 1)}
87  // e_i \otimes e_i \Delta S_L / (S_{max} - S_{min}), where
88  // e_i \otimes e_i is a square matrix with e_i,0^2 e_i,0*e_i,1 etc.
89  for (int i = 0; i < 3; ++i)
90  {
91  Eigen::Matrix<double, 3, 3> const ei_otimes_ei =
92  e.col(i) * e.col(i).transpose();
93 
94  delta_sigma_sw -=
95  lambda_[i] * p_[i] * std::pow(S_eff, lambda_[i] - 1) * ei_otimes_ei;
96  }
97 
98  return (delta_sigma_sw * delta_S_eff / dt).eval();
99 }
100 
102  VariableArray const& variable_array,
103  VariableArray const& variable_array_prev, Variable const primary_variable,
104  ParameterLib::SpatialPosition const& pos, double const /*t*/,
105  double const /*dt*/) const
106 {
107  if (primary_variable != Variable::liquid_saturation)
108  {
109  OGS_FATAL(
110  "SaturationDependentSwelling::dValue is implemented for "
111  "derivatives with respect to liquid saturation only.");
112  }
113 
114  auto const S_L = std::get<double>(
115  variable_array[static_cast<int>(Variable::liquid_saturation)]);
116  auto const S_L_prev = std::get<double>(
117  variable_array_prev[static_cast<int>(Variable::liquid_saturation)]);
118 
119  Eigen::Matrix<double, 3, 3> const e =
120  local_coordinate_system_ == nullptr
121  ? Eigen::Matrix<double, 3, 3>::Identity()
123 
124  Eigen::Matrix<double, 3, 3> delta_sigma_sw =
125  Eigen::Matrix<double, 3, 3>::Zero();
126 
127  if (S_L < S_min_)
128  {
129  return delta_sigma_sw; // still being zero.
130  }
131 
132  double const S_eff = std::clamp((S_L - S_min_) / (S_max_ - S_min_), 0., 1.);
133  double const S_eff_prev =
134  std::clamp((S_L_prev - S_min_) / (S_max_ - S_min_), 0., 1.);
135 
136  double const delta_S_eff = S_eff - S_eff_prev;
137 
138  // Heaviside(delta S_eff,sw)
139  if (std::abs(delta_S_eff) <= 0)
140  {
141  return delta_sigma_sw; // still being zero.
142  }
143 
144  for (int i = 0; i < 3; ++i)
145  {
146  Eigen::Matrix<double, 3, 3> const ei_otimes_ei =
147  e.col(i) * e.col(i).transpose();
148 
149  delta_sigma_sw +=
150  lambda_[i] * p_[i] * std::pow(S_eff, lambda_[i] - 1) * ei_otimes_ei;
151  }
152  return (delta_sigma_sw / (S_max_ - S_min_)).eval();
153 }
154 } // namespace MaterialPropertyLib
#define OGS_FATAL(...)
Definition: Error.h:26
virtual PropertyDataType value() const
Definition: Property.cpp:72
std::variant< Medium *, Phase *, Component * > scale_
Definition: Property.h:287
std::array< double, 3 > const p_
Maximum swelling pressures, one for each spatial dimension.
PropertyDataType dValue(VariableArray const &variable_array, VariableArray const &variable_array_prev, Variable const variable, ParameterLib::SpatialPosition const &pos, double const t, double const dt) const override
ParameterLib::CoordinateSystem const *const local_coordinate_system_
SaturationDependentSwelling(std::string name, std::array< double, 3 > swelling_pressures, std::array< double, 3 > exponents, double const lower_saturation_limit, double const upper_saturation_limit, ParameterLib::CoordinateSystem const *const local_coordinate_system)
std::array< double, 3 > const lambda_
Exponents, one for each spatial dimension.
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 > > PropertyDataType
Definition: Property.h:35
std::array< VariableType, static_cast< int >(Variable::number_of_variables)> VariableArray
Definition: VariableType.h:108
Eigen::Matrix< double, 3, 3 > transformation_3d(SpatialPosition const &pos) const