www.mooseframework.org
PorousFlowPorosity.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 
10 #include "PorousFlowPorosity.h"
11 
12 registerMooseObject("PorousFlowApp", PorousFlowPorosity);
13 
14 template <>
15 InputParameters
17 {
18  InputParameters params = validParams<PorousFlowPorosityExponentialBase>();
19  params.addParam<bool>(
20  "mechanical", false, "If true, porosity will be a function of total volumetric strain");
21  params.addParam<bool>(
22  "fluid", false, "If true, porosity will be a function of effective porepressure");
23  params.addParam<bool>("thermal", false, "If true, porosity will be a function of temperature");
24  params.addParam<bool>("chemical", false, "If true, porosity will be a function of precipitate");
25  params.addRequiredCoupledVar("porosity_zero",
26  "The porosity at zero volumetric strain and "
27  "reference temperature and reference effective "
28  "porepressure and reference chemistry. This must be a real number "
29  "or a constant monomial variable (not a linear lagrange or other "
30  "type of variable)");
31  params.addParam<Real>("thermal_expansion_coeff",
32  "Volumetric thermal expansion coefficient of the drained porous solid "
33  "skeleton (only used if thermal=true)");
34  params.addRangeCheckedParam<Real>(
35  "biot_coefficient", 1, "biot_coefficient>=0 & biot_coefficient<=1", "Biot coefficient");
36  params.addRangeCheckedParam<Real>(
37  "solid_bulk",
38  "solid_bulk>0",
39  "Bulk modulus of the drained porous solid skeleton (only used if fluid=true)");
40  params.addCoupledVar(
41  "reference_temperature", 0.0, "Reference temperature (only used if thermal=true)");
42  params.addCoupledVar(
43  "reference_porepressure", 0.0, "Reference porepressure (only used if fluid=true)");
44  params.addCoupledVar("reference_chemistry",
45  "Reference values of the solid mineral concentrations "
46  "(m^3(precipitate)/m^3(porous material)), entered as "
47  "a vector (one value per mineral). (Only used if chemical=true)");
48  params.addCoupledVar(
49  "initial_mineral_concentrations",
50  "Initial mineral concentrations (m^3(precipitate)/m^3(porous material)), entered as "
51  "a vector (one value per mineral). (Only used if chemical=true)");
52  params.addParam<std::vector<Real>>("chemical_weights",
53  "When chemical=true, porosity is a linear combination of the "
54  "solid mineral concentrations multiplied by these weights. "
55  "Default=1 for all minerals.");
56  params.addClassDescription("This Material calculates the porosity PorousFlow simulations");
57  return params;
58 }
59 
60 PorousFlowPorosity::PorousFlowPorosity(const InputParameters & parameters)
62 
63  _mechanical(getParam<bool>("mechanical")),
64  _fluid(getParam<bool>("fluid")),
65  _thermal(getParam<bool>("thermal")),
66  _chemical(getParam<bool>("chemical")),
67  _phi0(coupledValue("porosity_zero")),
68  _biot(getParam<Real>("biot_coefficient")),
69  _exp_coeff(isParamValid("thermal_expansion_coeff") ? getParam<Real>("thermal_expansion_coeff")
70  : 0.0),
71  _solid_bulk(isParamValid("solid_bulk") ? getParam<Real>("solid_bulk")
72  : std::numeric_limits<Real>::max()),
73  _coeff((_biot - 1.0) / _solid_bulk),
74 
75  _t_reference(_nodal_material ? coupledDofValues("reference_temperature")
76  : coupledValue("reference_temperature")),
77  _p_reference(_nodal_material ? coupledDofValues("reference_porepressure")
78  : coupledValue("reference_porepressure")),
79  _num_c_ref(coupledComponents("reference_chemistry")),
80  _c_reference(_num_c_ref),
81  _num_initial_c(coupledComponents("initial_mineral_concentrations")),
82  _initial_c(_num_initial_c),
83  _c_weights(isParamValid("chemical_weights") ? getParam<std::vector<Real>>("chemical_weights")
84  : std::vector<Real>(_num_c_ref, 1.0)),
85 
86  _porosity_old(_chemical ? (_nodal_material
87  ? &getMaterialPropertyOld<Real>("PorousFlow_porosity_nodal")
88  : &getMaterialPropertyOld<Real>("PorousFlow_porosity_qp"))
89  : nullptr),
90  _vol_strain_qp(_mechanical ? &getMaterialProperty<Real>("PorousFlow_total_volumetric_strain_qp")
91  : nullptr),
92  _dvol_strain_qp_dvar(_mechanical ? &getMaterialProperty<std::vector<RealGradient>>(
93  "dPorousFlow_total_volumetric_strain_qp_dvar")
94  : nullptr),
95 
96  _pf(_fluid ? (_nodal_material
97  ? &getMaterialProperty<Real>("PorousFlow_effective_fluid_pressure_nodal")
98  : &getMaterialProperty<Real>("PorousFlow_effective_fluid_pressure_qp"))
99  : nullptr),
100  _dpf_dvar(_fluid ? (_nodal_material ? &getMaterialProperty<std::vector<Real>>(
101  "dPorousFlow_effective_fluid_pressure_nodal_dvar")
102  : &getMaterialProperty<std::vector<Real>>(
103  "dPorousFlow_effective_fluid_pressure_qp_dvar"))
104  : nullptr),
105 
106  _temperature(_thermal
107  ? (_nodal_material ? &getMaterialProperty<Real>("PorousFlow_temperature_nodal")
108  : &getMaterialProperty<Real>("PorousFlow_temperature_qp"))
109  : nullptr),
110  _dtemperature_dvar(
111  _thermal
112  ? (_nodal_material
113  ? &getMaterialProperty<std::vector<Real>>("dPorousFlow_temperature_nodal_dvar")
114  : &getMaterialProperty<std::vector<Real>>("dPorousFlow_temperature_qp_dvar"))
115  : nullptr),
116 
117  _mineral_conc_old(_chemical ? (_nodal_material ? &getMaterialPropertyOld<std::vector<Real>>(
118  "PorousFlow_mineral_concentration_nodal")
119  : &getMaterialPropertyOld<std::vector<Real>>(
120  "PorousFlow_mineral_concentration_qp"))
121  : nullptr),
122  _reaction_rate(_chemical ? (_nodal_material ? &getMaterialProperty<std::vector<Real>>(
123  "PorousFlow_mineral_reaction_rate_nodal")
124  : &getMaterialProperty<std::vector<Real>>(
125  "PorousFlow_mineral_reaction_rate_qp"))
126  : nullptr),
127  _dreaction_rate_dvar(_chemical ? (_nodal_material
128  ? &getMaterialProperty<std::vector<std::vector<Real>>>(
129  "dPorousFlow_mineral_reaction_rate_nodal_dvar")
130  : &getMaterialProperty<std::vector<std::vector<Real>>>(
131  "dPorousFlow_mineral_reaction_rate_qp_dvar"))
132  : nullptr),
133  _aq_ph(_dictator.aqueousPhaseNumber()),
134  _saturation(_chemical
135  ? (_nodal_material
136  ? &getMaterialProperty<std::vector<Real>>("PorousFlow_saturation_nodal")
137  : &getMaterialProperty<std::vector<Real>>("PorousFlow_saturation_qp"))
138  : nullptr),
139  _dsaturation_dvar(_chemical
140  ? (_nodal_material ? &getMaterialProperty<std::vector<std::vector<Real>>>(
141  "dPorousFlow_saturation_nodal_dvar")
142  : &getMaterialProperty<std::vector<std::vector<Real>>>(
143  "dPorousFlow_saturation_qp_dvar"))
144  : nullptr)
145 {
146  if (_thermal && !isParamValid("thermal_expansion_coeff"))
147  mooseError("PorousFlowPorosity: When thermal=true you must provide a thermal_expansion_coeff");
148  if (_fluid && !isParamValid("solid_bulk"))
149  mooseError("PorousFlowPorosity: When fluid=true you must provide a solid_bulk");
150  if (_chemical && _num_c_ref != _dictator.numAqueousKinetic())
151  mooseError("PorousFlowPorosity: When chemical=true you must provide the reference_chemistry "
152  "values. The Dictator proclaims there should be ",
153  _dictator.numAqueousKinetic(),
154  " of these");
155  if (_chemical && _num_initial_c != _dictator.numAqueousKinetic())
156  mooseError("PorousFlowPorosity: When chemical=true you must provide the "
157  "initial_mineral_concentrations. "
158  "The Dictator proclaims there should be ",
159  _dictator.numAqueousKinetic(),
160  " of these");
161  if (_chemical && _c_weights.size() != _dictator.numAqueousKinetic())
162  mooseError(
163  "PorousFlowPorosity: When chemical=true you must provde the correct number of "
164  "chemical_weights (which the Dictator knows is ",
165  _dictator.numAqueousKinetic(),
166  ") or do not provide any chemical_weights and use the default value of 1 for each mineral");
167 
168  for (unsigned i = 0; i < _num_c_ref; ++i)
169  {
170  _c_reference[i] = (_nodal_material ? &coupledDofValues("reference_chemistry", i)
171  : &coupledValue("reference_chemistry", i));
172  _initial_c[i] = (_nodal_material ? &coupledDofValues("initial_mineral_concentrations", i)
173  : &coupledValue("initial_mineral_concentrations", i));
174  }
175 }
176 
177 Real
179 {
180  /*
181  *
182  * Note the use of the OLD value of porosity here.
183  * This strategy, which breaks the cyclic dependency between porosity
184  * and mineral concentration, is used in
185  * Kernel: PorousFlowPreDis
186  * Material: PorousFlowPorosity
187  * Material: PorousFlowAqueousPreDisChemistry
188  * Material: PorousFlowAqueousPreDisMineral
189  *
190  */
191  Real result = _biot;
192  if (_chemical)
193  {
194  if (_t_step == 0 && !_app.isRestarting())
195  for (unsigned i = 0; i < _num_c_ref; ++i)
196  result -= _c_weights[i] * (*_initial_c[i])[_qp];
197  else
198  for (unsigned i = 0; i < _num_c_ref; ++i)
199  result -= _c_weights[i] * ((*_mineral_conc_old)[_qp][i] + _dt * (*_porosity_old)[_qp] *
200  (*_saturation)[_qp][_aq_ph] *
201  (*_reaction_rate)[_qp][i]);
202  }
203  return result;
204 }
205 
206 Real
208 {
209  Real result = 0.0;
210  if (_chemical && (_t_step >= 1 || _app.isRestarting()))
211  for (unsigned i = 0; i < _num_c_ref; ++i)
212  result -= _c_weights[i] * _dt * (*_porosity_old)[_qp] *
213  ((*_saturation)[_qp][_aq_ph] * (*_dreaction_rate_dvar)[_qp][i][pvar] +
214  (*_dsaturation_dvar)[_qp][_aq_ph][pvar] * (*_reaction_rate)[_qp][i]);
215  return result;
216 }
217 
218 Real
220 {
221  // note the [0] below: _phi0 is a constant monomial and we use [0] regardless of _nodal_material
222  Real result = _phi0[0];
223  if (_chemical)
224  {
225  if (_t_step == 0 && !_app.isRestarting())
226  for (unsigned i = 0; i < _num_c_ref; ++i)
227  result -= _c_weights[i] * ((*_initial_c[i])[_qp] - (*_c_reference[i])[_qp]);
228  else
229  for (unsigned i = 0; i < _num_c_ref; ++i)
230  result -= _c_weights[i] * ((*_mineral_conc_old)[_qp][i] +
231  _dt * (*_porosity_old)[_qp] * (*_saturation)[_qp][_aq_ph] *
232  (*_reaction_rate)[_qp][i] -
233  (*_c_reference[i])[_qp]);
234  }
235  return result;
236 }
237 
238 Real
239 PorousFlowPorosity::datZeroQp(unsigned pvar) const
240 {
241  Real result = 0.0;
242  if (_chemical && (_t_step >= 1 || _app.isRestarting()))
243  for (unsigned i = 0; i < _num_c_ref; ++i)
244  result -= _c_weights[i] * _dt * (*_porosity_old)[_qp] *
245  ((*_saturation)[_qp][_aq_ph] * (*_dreaction_rate_dvar)[_qp][i][pvar] +
246  (*_dsaturation_dvar)[_qp][_aq_ph][pvar] * (*_reaction_rate)[_qp][i]);
247  return result;
248 }
249 
250 Real
252 {
253  Real result = 0.0;
254 
255  if (_thermal)
256  result += _exp_coeff * ((*_temperature)[_qp] - _t_reference[_qp]);
257 
258  if (_fluid)
259  result += _coeff * ((*_pf)[_qp] - _p_reference[_qp]);
260 
261  if (_mechanical)
262  {
263  // Note that in the following _strain[_qp] is evaluated at q quadpoint
264  // So _porosity_nodal[_qp], which should be the nodal value of porosity
265  // actually uses the strain at a quadpoint. This
266  // is OK for LINEAR elements, as strain is constant over the element anyway.
267  const unsigned qp_to_use =
268  (_nodal_material && (_bnd || _strain_at_nearest_qp) ? nearestQP(_qp) : _qp);
269  result += -(*_vol_strain_qp)[qp_to_use];
270  }
271 
272  return result;
273 }
274 
275 Real
277 {
278  Real result = 0.0;
279 
280  if (_thermal)
281  result += _exp_coeff * (*_dtemperature_dvar)[_qp][pvar];
282 
283  if (_fluid)
284  result += _coeff * (*_dpf_dvar)[_qp][pvar];
285 
286  return result;
287 }
288 
291 {
292  RealGradient result(0.0, 0.0, 0.0);
293  if (_mechanical)
294  {
295  const unsigned qp_to_use =
296  (_nodal_material && (_bnd || _strain_at_nearest_qp) ? nearestQP(_qp) : _qp);
297  result += -(*_dvol_strain_qp_dvar)[qp_to_use][pvar];
298  }
299  return result;
300 }
PorousFlowPorosity::_c_weights
std::vector< Real > _c_weights
Weights for the mineral concentrations.
Definition: PorousFlowPorosity.h:85
registerMooseObject
registerMooseObject("PorousFlowApp", PorousFlowPorosity)
validParams< PorousFlowPorosityExponentialBase >
InputParameters validParams< PorousFlowPorosityExponentialBase >()
Definition: PorousFlowPorosityExponentialBase.C:14
PorousFlowPorosity
Material designed to provide the porosity in PorousFlow simulations chemistry + biot + (phi0 - refere...
Definition: PorousFlowPorosity.h:25
PorousFlowPorosity::_chemical
const bool _chemical
Porosity is a function of chemistry.
Definition: PorousFlowPorosity.h:49
PorousFlowPorosity::ddecayQp_dvar
virtual Real ddecayQp_dvar(unsigned pvar) const override
d(decay)/d(PorousFlow variable pvar)
Definition: PorousFlowPorosity.C:276
PorousFlowPorosity::decayQp
virtual Real decayQp() const override
Returns "decay" at the quadpoint (porosity = a + (b - a) * exp(decay))
Definition: PorousFlowPorosity.C:251
PorousFlowPorosity::_mineral_conc_old
const MaterialProperty< std::vector< Real > > *const _mineral_conc_old
Old value of mineral concentration at the quadpoints or nodes.
Definition: PorousFlowPorosity.h:109
libMesh::RealGradient
VectorValue< Real > RealGradient
Definition: GrainForceAndTorqueInterface.h:17
PorousFlowPorosity::datZeroQp
virtual Real datZeroQp(unsigned pvar) const override
d(a)/d(PorousFlow variable pvar)
Definition: PorousFlowPorosity.C:239
PorousFlowPorosity::_coeff
const Real _coeff
Short-hand number (biot-1)/solid_bulk.
Definition: PorousFlowPorosity.h:64
PorousFlowPorosity::_fluid
const bool _fluid
Porosity is a function of effective porepressure.
Definition: PorousFlowPorosity.h:43
PorousFlowPorosity::datNegInfinityQp
virtual Real datNegInfinityQp(unsigned pvar) const override
d(a)/d(PorousFlow variable pvar)
Definition: PorousFlowPorosity.C:207
PorousFlowPorosity::atZeroQp
virtual Real atZeroQp() const override
Returns "b" at the quadpoint (porosity = a + (b - a) * exp(decay))
Definition: PorousFlowPorosity.C:219
PorousFlowPorosity::_phi0
const VariableValue & _phi0
Porosity at zero strain and zero porepressure and zero temperature.
Definition: PorousFlowPorosity.h:52
PorousFlowPorosity::_t_reference
const VariableValue & _t_reference
Reference temperature.
Definition: PorousFlowPorosity.h:67
PorousFlowPorosity::_p_reference
const VariableValue & _p_reference
Reference porepressure.
Definition: PorousFlowPorosity.h:70
PorousFlowPorosity::_exp_coeff
const Real _exp_coeff
Thermal expansion coefficient of the solid porous skeleton.
Definition: PorousFlowPorosity.h:58
PorousFlowPorosity::_porosity_old
const MaterialProperty< Real > *const _porosity_old
Old value of porosity.
Definition: PorousFlowPorosity.h:88
PorousFlowPorosity::_aq_ph
const unsigned int _aq_ph
Aqueous phase number.
Definition: PorousFlowPorosity.h:118
PorousFlowPorosity::_num_c_ref
const unsigned _num_c_ref
Number of reference mineral concentrations provided by user.
Definition: PorousFlowPorosity.h:73
PorousFlowPorosity::_initial_c
std::vector< const VariableValue * > _initial_c
Reference mineral concentrations.
Definition: PorousFlowPorosity.h:82
PorousFlowPorosity::_thermal
const bool _thermal
Porosity is a function of temperature.
Definition: PorousFlowPorosity.h:46
PorousFlowPorosity::PorousFlowPorosity
PorousFlowPorosity(const InputParameters &parameters)
Definition: PorousFlowPorosity.C:60
PorousFlowPorosityExponentialBase
Base class Material designed to provide the porosity.
Definition: PorousFlowPorosityExponentialBase.h:36
PorousFlowPorosity::_c_reference
std::vector< const VariableValue * > _c_reference
Reference mineral concentrations.
Definition: PorousFlowPorosity.h:76
PorousFlowPorosity.h
PorousFlowPorosity::ddecayQp_dgradvar
virtual RealGradient ddecayQp_dgradvar(unsigned pvar) const override
d(decay)/d(grad(PorousFlow variable pvar))
Definition: PorousFlowPorosity.C:290
PorousFlowPorosityExponentialBase::_strain_at_nearest_qp
const bool _strain_at_nearest_qp
When calculating nodal porosity, use the strain at the nearest quadpoint to the node.
Definition: PorousFlowPorosityExponentialBase.h:67
PorousFlowPorosity::_num_initial_c
const unsigned _num_initial_c
Number of reference mineral concentrations provided by user.
Definition: PorousFlowPorosity.h:79
validParams< PorousFlowPorosity >
InputParameters validParams< PorousFlowPorosity >()
Definition: PorousFlowPorosity.C:16
PorousFlowPorosity::_biot
const Real _biot
Biot coefficient.
Definition: PorousFlowPorosity.h:55
PorousFlowPorosity::_mechanical
const bool _mechanical
Porosity is a function of volumetric strain.
Definition: PorousFlowPorosity.h:40
PorousFlowPorosity::atNegInfinityQp
virtual Real atNegInfinityQp() const override
Returns "a" at the quadpoint (porosity = a + (b - a) * exp(decay))
Definition: PorousFlowPorosity.C:178