www.mooseframework.org
PorousFlowPermeabilityKozenyCarman.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
11 
14 
15 template <bool is_ad>
18 {
20  MooseEnum poroperm_function("kozeny_carman_fd2=0 kozeny_carman_phi0=1", "kozeny_carman_fd2");
21  params.addParam<MooseEnum>(
22  "poroperm_function",
23  poroperm_function,
24  "Function relating porosity and permeability. The options are: kozeny_carman_fd2 = f d^2 "
25  "phi^n/(1-phi)^m (where phi is porosity, f is a scalar constant with typical values "
26  "0.01-0.001, and d is grain size). kozeny_carman_phi0 = k0 (1-phi0)^m/phi0^n * "
27  "phi^n/(1-phi)^m (where phi is porosity, and k0 is the permeability at porosity phi0)");
28  params.addRangeCheckedParam<Real>("k0",
29  "k0 > 0",
30  "The permeability scalar value (usually in "
31  "m^2) at the reference porosity, required for "
32  "kozeny_carman_phi0");
33  params.addParam<RealTensorValue>("k_anisotropy",
34  "A tensor to multiply the calculated scalar "
35  "permeability, in order to obtain anisotropy if "
36  "required. Defaults to isotropic permeability "
37  "if not specified.");
38  params.addRangeCheckedParam<Real>(
39  "phi0", "phi0 > 0 & phi0 < 1", "The reference porosity, required for kozeny_carman_phi0");
40  params.addRangeCheckedParam<Real>(
41  "f", "f > 0", "The multiplying factor, required for kozeny_carman_fd2");
42  params.addRangeCheckedParam<Real>(
43  "d", "d > 0", "The grain diameter, required for kozeny_carman_fd2");
44  params.addRequiredRangeCheckedParam<Real>("n", "n >= 0", "Porosity exponent");
45  params.addRequiredRangeCheckedParam<Real>("m", "m >= 0", "(1-porosity) exponent");
46  params.addClassDescription(
47  "This Material calculates the permeability tensor from a form of the Kozeny-Carman equation, "
48  "k = k_ijk * A * phi^n / (1 - phi)^m, where k_ijk is a tensor providing the anisotropy, phi "
49  "is porosity, n and m are positive scalar constants and A is given in one of the following "
50  "forms: A = k0 * (1 - phi0)^m / phi0^n (where k0 and phi0 are a reference permeability and "
51  "porosity) or A = f * d^2 (where f is a scalar constant and d is grain diameter.");
52  return params;
53 }
54 
55 template <bool is_ad>
57  const InputParameters & parameters)
58  : PorousFlowPermeabilityBaseTempl<is_ad>(parameters),
59  _k0(parameters.isParamValid("k0") ? this->template getParam<Real>("k0") : -1),
60  _phi0(parameters.isParamValid("phi0") ? this->template getParam<Real>("phi0") : -1),
61  _f(parameters.isParamValid("f") ? this->template getParam<Real>("f") : -1),
62  _d(parameters.isParamValid("d") ? this->template getParam<Real>("d") : -1),
63  _m(this->template getParam<Real>("m")),
64  _n(this->template getParam<Real>("n")),
65  _k_anisotropy(parameters.isParamValid("k_anisotropy")
66  ? this->template getParam<RealTensorValue>("k_anisotropy")
67  : RealTensorValue(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0)),
68  _porosity_qp(this->template getGenericMaterialProperty<Real, is_ad>("PorousFlow_porosity_qp")),
69  _dporosity_qp_dvar(is_ad ? nullptr
70  : &this->template getMaterialProperty<std::vector<Real>>(
71  "dPorousFlow_porosity_qp_dvar")),
72  _dporosity_qp_dgradvar(is_ad ? nullptr
73  : &this->template getMaterialProperty<std::vector<RealGradient>>(
74  "dPorousFlow_porosity_qp_dgradvar")),
75  _poroperm_function(this->template getParam<MooseEnum>("poroperm_function")
76  .template getEnum<PoropermFunction>())
77 {
78  switch (_poroperm_function)
79  {
81  if (!(parameters.isParamValid("f") && parameters.isParamValid("d")))
82  mooseError("You must specify f and d in order to use kozeny_carman_fd2 in "
83  "PorousFlowPermeabilityKozenyCarman");
84  _A = _f * _d * _d;
85  break;
86 
88  if (!(parameters.isParamValid("k0") && parameters.isParamValid("phi0")))
89  mooseError("You must specify k0 and phi0 in order to use kozeny_carman_phi0 in "
90  "PorousFlowPermeabilityKozenyCarman");
91  _A = _k0 * std::pow(1.0 - _phi0, _m) / std::pow(_phi0, _n);
92  break;
93  }
94 
95  // Make sure that derivatives are included in the Jacobian calculations
96  _dictator.usePermDerivs(true);
97 }
98 
99 template <bool is_ad>
100 void
102 {
103  _permeability_qp[_qp] =
104  _k_anisotropy * _A * std::pow(_porosity_qp[_qp], _n) / std::pow(1.0 - _porosity_qp[_qp], _m);
105 
106  if constexpr (!is_ad)
107  {
108  (*_dpermeability_qp_dvar)[_qp].resize(_num_var, RealTensorValue());
109  for (unsigned int v = 0; v < _num_var; ++v)
110  (*_dpermeability_qp_dvar)[_qp][v] = (*_dporosity_qp_dvar)[_qp][v] * _permeability_qp[_qp] *
111  (_n / _porosity_qp[_qp] + _m / (1.0 - _porosity_qp[_qp]));
112 
113  (*_dpermeability_qp_dgradvar)[_qp].resize(LIBMESH_DIM);
114  for (const auto i : make_range(Moose::dim))
115  {
116  (*_dpermeability_qp_dgradvar)[_qp][i].resize(_num_var, RealTensorValue());
117  for (unsigned int v = 0; v < _num_var; ++v)
118  (*_dpermeability_qp_dgradvar)[_qp][i][v] =
119  (*_dporosity_qp_dgradvar)[_qp][v](i) * _permeability_qp[_qp] *
120  (_n / _porosity_qp[_qp] + _m / (1.0 - _porosity_qp[_qp]));
121  }
122  }
123 }
124 
PorousFlowPermeabilityKozenyCarmanTempl(const InputParameters &parameters)
Material designed to provide the permeability tensor which is calculated from porosity using a form o...
void addRequiredRangeCheckedParam(const std::string &name, const std::string &parsed_function, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void mooseError(Args &&... args)
enum PorousFlowPermeabilityKozenyCarmanTempl::PoropermFunction _poroperm_function
static constexpr std::size_t dim
Base class Material designed to provide the permeability tensor.
TensorValue< Real > RealTensorValue
const Real _f
Multiplying factor in A = f * d^2.
PoropermFunction
Name of porosity-permeability relationship.
const Real _phi0
Reference porosity in A = k0 * (1 - phi0)^m / phi0^n.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const std::string v
Definition: NS.h:82
const Real _m
Exponent in k = k_ijk * A * phi^n / (1 - phi)^m.
IntRange< T > make_range(T beg, T end)
void addClassDescription(const std::string &doc_string)
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
Real _A
Multiplying factor in k = k_ijk * A * phi^n / (1 - phi)^m.
const Real _k0
Reference scalar permeability in A = k0 * (1 - phi0)^m / phi0^n.
MooseUnits pow(const MooseUnits &, int)
const Real _d
Grain diameter in A = f * d^2.
registerMooseObject("PorousFlowApp", PorousFlowPermeabilityKozenyCarman)
const Real _n
Exponent in k = k_ijk * A * phi^n / (1 - phi)^m.
bool isParamValid(const std::string &name) const