Skip to content
Snippets Groups Projects
Commit 8ad3debf authored by wenqing's avatar wenqing
Browse files

[MaterialLib] Added PermeabilityMohrCoulombFailureIndexModel

parent f0d2e66a
No related branches found
No related tags found
No related merge requests found
/**
* \file
* \copyright
* Copyright (c) 2012-2020, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
* Created on June 4, 2020, 10:13 AM
*/
#include "PermeabilityMohrCoulombFailureIndexModel.h"
#include <boost/math/constants/constants.hpp>
#include <cmath>
#include <limits>
#include "BaseLib/Error.h"
#include "MaterialLib/MPL/Medium.h"
#include "MaterialLib/MPL/Utils/FormEigenTensor.h"
#include "MaterialLib/MPL/Utils/GetSymmetricTensor.h"
#include "MathLib/KelvinVector.h"
#include "MathLib/MathTools.h"
#include "ParameterLib/CoordinateSystem.h"
#include "ParameterLib/Parameter.h"
namespace MaterialPropertyLib
{
template <int DisplacementDim>
PermeabilityMohrCoulombFailureIndexModel<DisplacementDim>::
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,
ParameterLib::CoordinateSystem const* const local_coordinate_system)
: k0_(k0),
kr_(kr),
b_(b),
c_(c),
phi_(boost::math::constants::degree<double>() * phi),
k_max_(k_max),
local_coordinate_system_(local_coordinate_system)
{
name_ = std::move(name);
}
template <int DisplacementDim>
void PermeabilityMohrCoulombFailureIndexModel<DisplacementDim>::checkScale()
const
{
if (!std::holds_alternative<Medium*>(scale_))
{
OGS_FATAL(
"The property 'PermeabilityMohrCoulombFailureIndexModel' is "
"implemented on the 'medium' scale only.");
}
}
template <int DisplacementDim>
PropertyDataType
PermeabilityMohrCoulombFailureIndexModel<DisplacementDim>::value(
VariableArray const& variable_array,
ParameterLib::SpatialPosition const& pos, double const t,
double const /*dt*/) const
{
auto const& stress_vector = std::get<SymmetricTensor<DisplacementDim>>(
variable_array[static_cast<int>(Variable::stress)]);
auto const& stress_tensor =
formEigenTensor<3>(static_cast<PropertyDataType>(stress_vector));
Eigen::SelfAdjointEigenSolver<Eigen::Matrix<double, 3, 3>>
eigenvalue_solver(stress_tensor);
// Principle stress
auto const sigma = eigenvalue_solver.eigenvalues();
auto k_data = k0_(t, pos);
double const max_sigma = std::max(std::fabs(sigma[0]), std::fabs(sigma[2]));
if (max_sigma < std::numeric_limits<double>::epsilon())
{
return fromVector(k_data);
}
double const sigma_m = 0.5 * (sigma[2] + sigma[0]);
double tau_tt = c_ * std::cos(phi_) - sigma_m * std::sin(phi_);
const double apex_cut_offset = 0.001;
if (std::fabs(tau_tt) < apex_cut_offset)
{
tau_tt = apex_cut_offset * c_ * std::cos(phi_);
}
// +- tau_t = tau_tt
double const f = 0.5 * std::fabs(sigma[2] - sigma[0]) / tau_tt;
if (f >= 1.0)
{
const double exp_value = std::exp(b_ * f);
for (auto& k_i : k_data)
{
k_i = std::min(k_i + kr_ * exp_value, k_max_);
}
}
// Local coordinate transformation is only applied for the case that the
// initial intrinsic permeability is given with orthotropic assumption.
if (local_coordinate_system_ && (k_data.size() == DisplacementDim))
{
Eigen::Matrix<double, DisplacementDim, DisplacementDim> const e =
local_coordinate_system_->transformation<DisplacementDim>(pos);
Eigen::Matrix<double, DisplacementDim, DisplacementDim> k =
Eigen::Matrix<double, DisplacementDim, DisplacementDim>::Zero();
for (int i = 0; i < DisplacementDim; ++i)
{
Eigen::Matrix<double, DisplacementDim, DisplacementDim> const
ei_otimes_ei = e.col(i) * e.col(i).transpose();
k += k_data[i] * ei_otimes_ei;
}
return k;
}
return fromVector(k_data);
}
template <int DisplacementDim>
PropertyDataType
PermeabilityMohrCoulombFailureIndexModel<DisplacementDim>::dValue(
VariableArray const& /*variable_array*/, Variable const /*variable*/,
ParameterLib::SpatialPosition const& /*pos*/, double const /*t*/,
double const /*dt*/) const
{
OGS_FATAL(
"The derivative of the intrinsic permeability k(sigma, ...) with "
"respect to stress tensor (sigma) is not implemented because that "
"dk/du is normally omitted.");
}
template class PermeabilityMohrCoulombFailureIndexModel<2>;
template class PermeabilityMohrCoulombFailureIndexModel<3>;
} // namespace MaterialPropertyLib
/**
* \file
* \copyright
* Copyright (c) 2012-2020, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
* Created on June 4, 2020, 10:13 AM
*/
#pragma once
#include "MaterialLib/MPL/Property.h"
#include "MaterialLib/MPL/VariableType.h"
namespace ParameterLib
{
struct CoordinateSystem;
template <typename T>
struct Parameter;
} // namespace ParameterLib
namespace MaterialPropertyLib
{
/**
* \brief A failure index dependent permeability model \cite wangetalPerm2020
*
* \f[ \mathbf{k} =
* \mathbf{k}_0+ H(f-1) k_\text{r} \mathrm{e}^{b f}\mathbf{I}\f]
*
* where
* \f$\mathbf{k}_0\f$ is the intrinsic permeability
* of the undamaged material,
* \f$H\f$ is the Heaviside step function, \f$f\f$ is the failure index,
* \f$k_\text{r}\f$ is a reference permeability,
* \f$b\f$ is a fitting parameter.
* \f$k_\text{r}\f$ and \f$b\f$ can be calibrated by experimental data.
* The failure index \f$f\f$ is calculated from the Mohr Coulomb failure
* criterion comparing an acting shear stress. The Mohr Coulomb failure
* criterion \cite labuz2012mohr takes
* the form
* \f[\tau(\sigma)=c-\sigma \mathrm{tan} \phi\f]
* with \f$\tau\f$ the shear stress, \f$c\f$ the cohesion, \f$\sigma\f$ the
* tensile stress, and \f$\phi\f$ the internal friction angle.
*
* The failure index is calculated by
* \f[
* f=\frac{\tau_m }{\cos(\phi)\tau(\sigma_m)}
* \f]
* with
* \f$\tau_m=(\sigma_3-\sigma_1)/2\f$
* and \f$\sigma_m=(\sigma_1+\sigma_3)/2\f$,
* where \f$\sigma_1\f$ and \f$\sigma_3\f$ are the minimum and maximum shear
* stress, respectively.
*
* Note: the conventional mechanics notations are used, which mean that tensile
* stress is positive.
*
*/
template <int DisplacementDim>
class PermeabilityMohrCoulombFailureIndexModel final : public Property
{
public:
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,
ParameterLib::CoordinateSystem const* const local_coordinate_system);
void checkScale() const override;
PropertyDataType value(VariableArray const& variable_array,
ParameterLib::SpatialPosition const& pos,
double const t, double const dt) const override;
PropertyDataType dValue(VariableArray const& variable_array,
Variable const variable,
ParameterLib::SpatialPosition const& pos,
double const t, double const dt) const override;
private:
/// Intrinsic permeability for undamaged material.
ParameterLib::Parameter<double> const& k0_;
/// Reference permeability.
double const kr_;
/// Fitting parameter.
double const b_;
/// Cohesion.
double const c_;
/// Angle of internal friction.
double const phi_;
/// Maximum permeability.
double const k_max_;
ParameterLib::CoordinateSystem const* const local_coordinate_system_;
};
} // namespace MaterialPropertyLib
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment