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");
45 params.addRangeCheckedParam<Real>(
46 "porosity_min",
47 0.0,
48 "porosity_min >= 0",
49 "Minimum allowed value of the porosity: if the linear relationship gives "
50 "values less than this value, then porosity is set to this value instead");
51 params.addParam<Real>(
52 "zero_modifier",
53 1E-3,
54 "If the linear relationship produces porosity < porosity_min, then porosity is set "
55 "porosity_min. This means the derivatives of it will be zero. However, these zero "
56 "derivatives often result in poor NR convergence, so the derivatives are set to "
57 "_zero_modifier * (values that are relevant for min porosity) to hint to the NR that "
58 "porosity is not always constant");
59 params.addParamNamesToGroup("zero_modifier", "Advanced");
61 "This Material calculates the porosity in PorousFlow simulations using the relationship "
62 "porosity_ref + P_coeff * (P - P_ref) + T_coeff * (T - T_ref) + epv_coeff * (epv - epv_ref), "
63 "where P is the effective porepressure, T is the temperature and epv is the volumetric "
64 "strain");
65 return params;
66}
67
69 : PorousFlowPorosityBase(parameters),
70 _strain_at_nearest_qp(getParam<bool>("strain_at_nearest_qp")),
71 _porosity_min(getParam<Real>("porosity_min")),
72 _phi_ref(coupledValue("porosity_ref")),
73 _P_ref(nodalOrQpValue("P_ref")),
74 _T_ref(nodalOrQpValue("T_ref")),
75 _epv_ref(coupledValue("epv_ref")),
76 _P_coeff(getParam<Real>("P_coeff")),
77 _T_coeff(getParam<Real>("T_coeff")),
78 _epv_coeff(getParam<Real>("epv_coeff")),
79
80 _uses_volstrain(parameters.isParamSetByUser("epv_coeff") && _epv_coeff != 0.0),
81 _vol_strain_qp(getOptionalMaterialProperty<Real>("PorousFlow_total_volumetric_strain_qp")),
82 _dvol_strain_qp_dvar(getOptionalMaterialProperty<std::vector<RealGradient>>(
83 "dPorousFlow_total_volumetric_strain_qp_dvar")),
84
85 _uses_pf(parameters.isParamSetByUser("P_coeff") && _P_coeff != 0.0),
86 _pf_nodal(getOptionalMaterialProperty<Real>("PorousFlow_effective_fluid_pressure_nodal")),
87 _pf_qp(getOptionalMaterialProperty<Real>("PorousFlow_effective_fluid_pressure_qp")),
88 _dpf_dvar_nodal(getOptionalMaterialProperty<std::vector<Real>>(
89 "dPorousFlow_effective_fluid_pressure_nodal_dvar")),
90 _dpf_dvar_qp(getOptionalMaterialProperty<std::vector<Real>>(
91 "dPorousFlow_effective_fluid_pressure_qp_dvar")),
92
93 _uses_T(parameters.isParamSetByUser("T_coeff") && _T_coeff != 0.0),
94 _temperature_nodal(getOptionalMaterialProperty<Real>("PorousFlow_temperature_nodal")),
95 _temperature_qp(getOptionalMaterialProperty<Real>("PorousFlow_temperature_qp")),
96 _dtemperature_dvar_nodal(
97 getOptionalMaterialProperty<std::vector<Real>>("dPorousFlow_temperature_nodal_dvar")),
98 _dtemperature_dvar_qp(
99 getOptionalMaterialProperty<std::vector<Real>>("dPorousFlow_temperature_qp_dvar")),
100 _zero_modifier(getParam<Real>("zero_modifier"))
101{
102}
103
104void
106{
107 _pf = _nodal_material ? _pf_nodal.get() : _pf_qp.get();
108 _dpf_dvar = _nodal_material ? _dpf_dvar_nodal.get() : _dpf_dvar_qp.get();
109 if (!(_pf && _dpf_dvar) && _uses_pf)
110 {
111 mooseError("PorousFlowPorosityLinear: When P_coeff is given you must have an effective fluid "
112 "pressure Material");
113 }
114
115 _temperature = _nodal_material ? _temperature_nodal.get() : _temperature_qp.get();
117 _nodal_material ? _dtemperature_dvar_nodal.get() : _dtemperature_dvar_qp.get();
118 if (!_temperature && _uses_T)
120 "PorousFlowPorosityLinear: When T_coeff is given you must have a temperature Material");
121
123 mooseError("PorousFlowPorosityLinear: When epv_coeff is given you must have a "
124 "volumetric-strain Material");
125
126 PorousFlowPorosityBase::initialSetup();
127}
128
129void
131{
132 _porosity[_qp] = _phi_ref[0];
133 (*_dporosity_dvar)[_qp].assign(_num_var, 0.0);
134 (*_dporosity_dgradvar)[_qp].assign(_num_var, 0.0);
135}
136
137void
139{
140 // note the [0] below: _phi_ref is a constant monomial and we use [0] regardless of
141 // _nodal_material
142 Real porosity = _phi_ref[0];
143 if (_uses_pf)
144 porosity += _P_coeff * ((*_pf)[_qp] - _P_ref[_qp]);
145 if (_uses_T)
146 porosity += _T_coeff * ((*_temperature)[_qp] - _T_ref[_qp]);
147 if (_uses_volstrain)
148 {
149 // Note that in the following _strain[_qp] is evaluated at q quadpoint
150 // So _porosity_nodal[_qp], which should be the nodal value of porosity
151 // actually uses the strain at a quadpoint. This
152 // is OK for LINEAR elements, as strain is constant over the element anyway.
153 const unsigned qp_to_use =
154 (_nodal_material && (_bnd || _strain_at_nearest_qp) ? nearestQP(_qp) : _qp);
155 porosity += _epv_coeff * (_vol_strain_qp[qp_to_use] - _epv_ref[0]);
156 }
157
158 if (porosity < _porosity_min)
160 else
161 _porosity[_qp] = porosity;
162
163 (*_dporosity_dvar)[_qp].resize(_num_var);
164 (*_dporosity_dgradvar)[_qp].resize(_num_var);
165 for (unsigned int pvar = 0; pvar < _num_var; ++pvar)
166 {
167 Real deriv = 0.0;
168 if (_uses_pf)
169 deriv += _P_coeff * (*_dpf_dvar)[_qp][pvar];
170 if (_uses_T)
171 deriv += _T_coeff * (*_dtemperature_dvar)[_qp][pvar];
172 if (porosity < _porosity_min)
173 (*_dporosity_dvar)[_qp][pvar] = _zero_modifier * deriv;
174 else
175 (*_dporosity_dvar)[_qp][pvar] = deriv;
176
177 RealGradient deriv_grad(0.0, 0.0, 0.0);
178 if (_uses_volstrain)
179 {
180 const unsigned qp_to_use =
181 (_nodal_material && (_bnd || _strain_at_nearest_qp) ? nearestQP(_qp) : _qp);
182 deriv_grad += _epv_coeff * _dvol_strain_qp_dvar[qp_to_use][pvar];
183 }
184 if (porosity < _porosity_min)
185 (*_dporosity_dgradvar)[_qp][pvar] = _zero_modifier * deriv_grad;
186 else
187 (*_dporosity_dgradvar)[_qp][pvar] = deriv_grad;
188 }
189}
void mooseError(Args &&... args)
registerMooseObject("PorousFlowApp", PorousFlowPorosityLinear)
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
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)
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, 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.
MaterialProperty< std::vector< RealGradient > > *const _dporosity_dgradvar
d(porosity)/d(grad PorousFlow variable)
MaterialProperty< std::vector< Real > > *const _dporosity_dvar
d(porosity)/d(PorousFlow variable)
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
const MaterialProperty< std::vector< Real > > * _dpf_dvar
const Real _zero_modifier
If the linear relationship produces porosity < _porosity_min, then porosity is set to _porosity_min....
const MaterialProperty< Real > * _temperature
const VariableValue & _T_ref
Reference temperature.
const Real _epv_coeff
coefficient of volumetric strain
const OptionalMaterialProperty< Real > & _temperature_qp
const Real _porosity_min
If the linear relationship produces porosity < _porosity_min, then porosity is set to _porosity_min.
const OptionalMaterialProperty< Real > & _temperature_nodal
Temperature at the quadpoints or nodes.