https://mooseframework.inl.gov
Loading...
Searching...
No Matches
PorousFlowPorosityLinear.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
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
13
16{
18 params.addParam<bool>("strain_at_nearest_qp",
19 false,
20 "When calculating nodal porosity that depends on strain, use the strain at "
21 "the nearest quadpoint. This adds a small extra computational burden, and "
22 "is not necessary for simulations involving only linear lagrange elements. "
23 " If you set this to true, you will also want to set the same parameter to "
24 "true for related Kernels and Materials");
26 "porosity_ref",
27 "The porosity at reference effective porepressure, temperature and volumetric strain. This "
28 "must be a real number or a constant monomial variable (not a linear lagrange or other type "
29 "of variable)");
30 params.addCoupledVar(
31 "P_ref",
32 0.0,
33 "The reference effective porepressure. This should usually be a linear-lagrange variable");
34 params.addCoupledVar(
35 "T_ref",
36 0.0,
37 "The reference temperature. This should usually be a linear-lagrange variable");
38 params.addCoupledVar("epv_ref",
39 0.0,
40 "The reference volumetric strain. This must be a real number or a constant "
41 "monomial variable (not a linear lagrange or other type of variable)");
42 params.addParam<Real>("P_coeff", 0.0, "Effective porepressure coefficient");
43 params.addParam<Real>("T_coeff", 0.0, "Temperature coefficient");
44 params.addParam<Real>("epv_coeff", 0.0, "Volumetric-strain coefficient");
46 "This Material calculates the porosity in PorousFlow simulations using the relationship "
47 "porosity_ref + P_coeff * (P - P_ref) + T_coeff * (T - T_ref) + epv_coeff * (epv - epv_ref), "
48 "where P is the effective porepressure, T is the temperature and epv is the volumetric "
49 "strain");
50 return params;
51}
52
54 : PorousFlowPorosityBase(parameters),
55 _strain_at_nearest_qp(getParam<bool>("strain_at_nearest_qp")),
56 _phi_ref(coupledValue("porosity_ref")),
57 _P_ref(nodalOrQpValue("P_ref")),
58 _T_ref(nodalOrQpValue("T_ref")),
59 _epv_ref(coupledValue("epv_ref")),
60 _P_coeff(getParam<Real>("P_coeff")),
61 _T_coeff(getParam<Real>("T_coeff")),
62 _epv_coeff(getParam<Real>("epv_coeff")),
63
64 _uses_volstrain(parameters.isParamSetByUser("epv_coeff") && _epv_coeff != 0.0),
65 _vol_strain_qp(getOptionalMaterialProperty<Real>("PorousFlow_total_volumetric_strain_qp")),
66 _dvol_strain_qp_dvar(getOptionalMaterialProperty<std::vector<RealGradient>>(
67 "dPorousFlow_total_volumetric_strain_qp_dvar")),
68
69 _uses_pf(parameters.isParamSetByUser("P_coeff") && _P_coeff != 0.0),
70 _pf_nodal(getOptionalMaterialProperty<Real>("PorousFlow_effective_fluid_pressure_nodal")),
71 _pf_qp(getOptionalMaterialProperty<Real>("PorousFlow_effective_fluid_pressure_qp")),
72 _dpf_dvar_nodal(getOptionalMaterialProperty<std::vector<Real>>(
73 "dPorousFlow_effective_fluid_pressure_nodal_dvar")),
74 _dpf_dvar_qp(getOptionalMaterialProperty<std::vector<Real>>(
75 "dPorousFlow_effective_fluid_pressure_qp_dvar")),
76
77 _uses_T(parameters.isParamSetByUser("T_coeff") && _T_coeff != 0.0),
78 _temperature_nodal(getOptionalMaterialProperty<Real>("PorousFlow_temperature_nodal")),
79 _temperature_qp(getOptionalMaterialProperty<Real>("PorousFlow_temperature_qp")),
80 _dtemperature_dvar_nodal(
81 getOptionalMaterialProperty<std::vector<Real>>("dPorousFlow_temperature_nodal_dvar")),
82 _dtemperature_dvar_qp(
83 getOptionalMaterialProperty<std::vector<Real>>("dPorousFlow_temperature_qp_dvar"))
84{
85}
86
87void
89{
90 _pf = _nodal_material ? _pf_nodal.get() : _pf_qp.get();
91 _dpf_dvar = _nodal_material ? _dpf_dvar_nodal.get() : _dpf_dvar_qp.get();
92 if (!(_pf && _dpf_dvar) && _uses_pf)
93 {
94 mooseError("PorousFlowPorosityLinear: When P_coeff is given you must have an effective fluid "
95 "pressure Material");
96 }
97
98 _temperature = _nodal_material ? _temperature_nodal.get() : _temperature_qp.get();
100 _nodal_material ? _dtemperature_dvar_nodal.get() : _dtemperature_dvar_qp.get();
101 if (!_temperature && _uses_T)
103 "PorousFlowPorosityLinear: When T_coeff is given you must have a temperature Material");
104
106 mooseError("PorousFlowPorosityLinear: When epv_coeff is given you must have a "
107 "volumetric-strain Material");
108
109 PorousFlowPorosityBase::initialSetup();
110}
111
112void
114{
115 _porosity[_qp] = _phi_ref[0];
116 (*_dporosity_dvar)[_qp].assign(_num_var, 0.0);
117 (*_dporosity_dgradvar)[_qp].assign(_num_var, 0.0);
118}
119
120void
126
127void
129{
130 // note the [0] below: _phi_ref is a constant monomial and we use [0] regardless of
131 // _nodal_material
132 Real porosity = _phi_ref[0];
133 if (_uses_pf)
134 porosity += _P_coeff * ((*_pf)[_qp] - _P_ref[_qp]);
135 if (_uses_T)
136 porosity += _T_coeff * ((*_temperature)[_qp] - _T_ref[_qp]);
137 if (_uses_volstrain)
138 {
139 // Note that in the following _strain[_qp] is evaluated at q quadpoint
140 // So _porosity_nodal[_qp], which should be the nodal value of porosity
141 // actually uses the strain at a quadpoint. This
142 // is OK for LINEAR elements, as strain is constant over the element anyway.
143 const unsigned qp_to_use =
144 (_nodal_material && (_bnd || _strain_at_nearest_qp) ? nearestQP(_qp) : _qp);
145 porosity += _epv_coeff * (_vol_strain_qp[qp_to_use] - _epv_ref[0]);
146 }
147
148 _porosity[_qp] = porosity;
149
150 (*_dporosity_dvar)[_qp].resize(_num_var);
151 (*_dporosity_dgradvar)[_qp].resize(_num_var);
152 for (unsigned int pvar = 0; pvar < _num_var; ++pvar)
153 {
154 Real deriv = 0.0;
155 if (_uses_pf)
156 deriv += _P_coeff * (*_dpf_dvar)[_qp][pvar];
157 if (_uses_T)
158 deriv += _T_coeff * (*_dtemperature_dvar)[_qp][pvar];
159 (*_dporosity_dvar)[_qp][pvar] = deriv;
160
161 RealGradient deriv_grad(0.0, 0.0, 0.0);
162 if (_uses_volstrain)
163 {
164 const unsigned qp_to_use =
165 (_nodal_material && (_bnd || _strain_at_nearest_qp) ? nearestQP(_qp) : _qp);
166 deriv_grad += _epv_coeff * _dvol_strain_qp_dvar[qp_to_use][pvar];
167 }
168 (*_dporosity_dgradvar)[_qp][pvar] = deriv_grad;
169 }
170}
void mooseError(Args &&... args)
registerMooseObject("PorousFlowApp", PorousFlowPorosityLinear)
void addRequiredCoupledVar(const std::string &name, 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 addClassDescription(const std::string &doc_string)
void addCoupledVar(const std::string &name, const std::string &doc_string)
const MooseArray< Moose::GenericType< T, is_ad > > & get() const
const unsigned int _num_var
Number of PorousFlow variables.
Base class Material designed to provide the porosity.
void applyPorosityMin()
If _porosity[_qp] < porosity_min, set _porosity[_qp] = porosity_min and multiply the derivatives of p...
GenericMaterialProperty< Real, is_ad > & _porosity
Computed porosity at the nodes or quadpoints.
static InputParameters validParams()
Material designed to provide the porosity in PorousFlow simulations porosity_ref + P_coeff * (P - P_r...
virtual void initQpStatefulProperties() override
const OptionalMaterialProperty< Real > & _pf_nodal
Effective porepressure at the quadpoints or nodes.
const Real _P_coeff
coefficient of effective porepressure
const OptionalMaterialProperty< Real > & _pf_qp
const VariableValue & _P_ref
Reference effective porepressure.
const bool _uses_T
whether T_coeff has been set
const OptionalMaterialProperty< std::vector< RealGradient > > & _dvol_strain_qp_dvar
d(strain)/(dvar) (first const means we never want to dereference and change the value,...
const bool _uses_volstrain
whether epv_coeff has been set
const Real _T_coeff
coefficient of temperature
static InputParameters validParams()
const OptionalMaterialProperty< std::vector< Real > > & _dtemperature_dvar_qp
PorousFlowPorosityLinear(const InputParameters &parameters)
const VariableValue & _phi_ref
Porosity at reference porepressure, temperature and volumetric strain.
const MaterialProperty< std::vector< Real > > * _dtemperature_dvar
virtual void computeQpProperties() override
const VariableValue & _epv_ref
Reference volumetric strain.
const OptionalMaterialProperty< std::vector< Real > > & _dtemperature_dvar_nodal
d(temperature)/(d porflow variable)
virtual void initialSetup() override
const OptionalMaterialProperty< std::vector< Real > > & _dpf_dvar_nodal
d(effective porepressure)/(d porflow variable)
const OptionalMaterialProperty< std::vector< Real > > & _dpf_dvar_qp
const bool _strain_at_nearest_qp
When calculating nodal porosity, use the strain at the nearest quadpoint to the node.
const OptionalMaterialProperty< Real > & _vol_strain_qp
Strain (first const means we never want to dereference and change the value, second means we'll alway...
const MaterialProperty< Real > * _pf
const bool _uses_pf
whether P_coeff has been set
virtual void computeUnboundedPorosityQp()
Computes porosity and its derivatives at the current node or quadrature point, without applying the p...
const MaterialProperty< std::vector< Real > > * _dpf_dvar
const MaterialProperty< Real > * _temperature
const VariableValue & _T_ref
Reference temperature.
const Real _epv_coeff
coefficient of volumetric strain
const OptionalMaterialProperty< Real > & _temperature_qp
const OptionalMaterialProperty< Real > & _temperature_nodal
Temperature at the quadpoints or nodes.