https://mooseframework.inl.gov
Loading...
Searching...
No Matches
PorousFlowFluidStateSingleComponent.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
12
15
16template <bool is_ad>
19{
21 params.addRequiredCoupledVar("porepressure",
22 "Variable that is the porepressure of the liquid phase");
23 params.addRequiredCoupledVar("enthalpy", "Enthalpy of the fluid");
24 params.addRequiredParam<UserObjectName>("fluid_state", "Name of the FluidState UserObject");
26 "Class for single component multiphase fluid state calculations using pressure and enthalpy");
27 return params;
28}
29
30template <bool is_ad>
32 const InputParameters & parameters)
33 : PorousFlowFluidStateBaseMaterialTempl<is_ad>(parameters),
34 _liquid_porepressure(_nodal_material
35 ? this->template coupledGenericDofValue<is_ad>("porepressure")
36 : this->template coupledGenericValue<is_ad>("porepressure")),
37 _liquid_gradp_qp(this->template coupledGenericGradient<is_ad>("porepressure")),
38 _liquid_porepressure_varnum(coupled("porepressure")),
39 _pvar(_dictator.isPorousFlowVariable(_liquid_porepressure_varnum)
40 ? _dictator.porousFlowVariableNum(_liquid_porepressure_varnum)
41 : 0),
42 _enthalpy(_nodal_material ? this->template coupledGenericDofValue<is_ad>("enthalpy")
43 : this->template coupledGenericValue<is_ad>("enthalpy")),
44 _gradh_qp(this->template coupledGenericGradient<is_ad>("enthalpy")),
45 _enthalpy_varnum(coupled("enthalpy")),
46 _hvar(_dictator.isPorousFlowVariable(_enthalpy_varnum)
47 ? _dictator.porousFlowVariableNum(_enthalpy_varnum)
48 : 0),
49 _fs(this->template getUserObject<PorousFlowFluidStateSingleComponentBase>("fluid_state")),
50 _aqueous_phase_number(_fs.aqueousPhaseIndex()),
51 _gas_phase_number(_fs.gasPhaseIndex()),
52 _temperature(
53 this->template declareGenericProperty<Real, is_ad>("PorousFlow_temperature" + _sfx)),
54 _grad_temperature_qp(_nodal_material
55 ? nullptr
56 : &this->template declareGenericProperty<RealGradient, is_ad>(
57 "PorousFlow_grad_temperature_qp")),
58 _dtemperature_dvar(is_ad ? nullptr
59 : &this->template declareProperty<std::vector<Real>>(
60 "dPorousFlow_temperature" + _sfx + "_dvar")),
61 _dgrad_temperature_dgradv(is_ad || _nodal_material
62 ? nullptr
63 : &this->template declareProperty<std::vector<Real>>(
64 "dPorousFlow_grad_temperature_qp_dgradvar")),
65 _dgrad_temperature_dv(is_ad ? nullptr
66 : _nodal_material
67 ? nullptr
68 : &this->template declareProperty<std::vector<RealGradient>>(
69 "dPorousFlow_grad_temperature_qp_dvar")),
70 _pidx(_fs.getPressureIndex()),
71 _hidx(_fs.getEnthalpyIndex())
72{
73 this->checkNodalVariables({"porepressure", "enthalpy"});
74
75 // Check that the number of phases in the fluidstate class is also provided in the Dictator
76 if (_fs.numPhases() != _num_phases)
78 ": only ",
79 _fs.numPhases(),
80 " phases are allowed. Please check the number of phases entered in the dictator is "
81 "correct");
82}
83
84template <bool is_ad>
85void
87{
88 _fs.clearFluidStateProperties(_fsp);
89 _fs.thermophysicalProperties(_liquid_porepressure[_qp], _enthalpy[_qp], _qp, _fsp);
90}
91
92template <bool is_ad>
93void
95{
96 _is_initqp = true;
97 // Set the size of pressure and saturation vectors
99
100 // Set the initial values of the temperature at the nodes.
101 // Note: not required for qp materials as no old values at the qps are requested
102 if (_nodal_material)
103 {
104 // Temperature doesn't depend on fluid phase
105 _temperature[_qp] = genericValue(_fsp[_aqueous_phase_number].temperature) - _T_c2k;
106 }
107}
108
109template <bool is_ad>
110void
112{
113
115
116 // Temperature doesn't depend on fluid phase
117 _temperature[_qp] = genericValue(_fsp[_aqueous_phase_number].temperature) - _T_c2k;
118
119 if (!is_ad)
120 {
121 (*_dtemperature_dvar)[_qp][_pvar] =
122 _fsp[_aqueous_phase_number].temperature.derivatives()[_pidx];
123 (*_dtemperature_dvar)[_qp][_hvar] =
124 _fsp[_aqueous_phase_number].temperature.derivatives()[_hidx];
125 }
126
127 // Derivative of pressure, saturation and fluid properties wrt variables
128 if (!is_ad)
129 for (unsigned int ph = 0; ph < _num_phases; ++ph)
130 {
131 (*_dporepressure_dvar)[_qp][ph][_pvar] = _fsp[ph].pressure.derivatives()[_pidx];
132 (*_dporepressure_dvar)[_qp][ph][_hvar] = _fsp[ph].pressure.derivatives()[_hidx];
133
134 (*_dsaturation_dvar)[_qp][ph][_pvar] = _fsp[ph].saturation.derivatives()[_pidx];
135 (*_dsaturation_dvar)[_qp][ph][_hvar] = _fsp[ph].saturation.derivatives()[_hidx];
136
137 (*_dfluid_density_dvar)[_qp][ph][_pvar] = _fsp[ph].density.derivatives()[_pidx];
138 (*_dfluid_density_dvar)[_qp][ph][_hvar] = _fsp[ph].density.derivatives()[_hidx];
139
140 (*_dfluid_viscosity_dvar)[_qp][ph][_pvar] = _fsp[ph].viscosity.derivatives()[_pidx];
141 (*_dfluid_viscosity_dvar)[_qp][ph][_hvar] = _fsp[ph].viscosity.derivatives()[_hidx];
142
143 (*_dfluid_enthalpy_dvar)[_qp][ph][_pvar] = _fsp[ph].enthalpy.derivatives()[_pidx];
144 (*_dfluid_enthalpy_dvar)[_qp][ph][_hvar] = _fsp[ph].enthalpy.derivatives()[_hidx];
145
146 (*_dfluid_internal_energy_dvar)[_qp][ph][_pvar] =
147 _fsp[ph].internal_energy.derivatives()[_pidx];
148 (*_dfluid_internal_energy_dvar)[_qp][ph][_hvar] =
149 _fsp[ph].internal_energy.derivatives()[_hidx];
150 }
151
152 // If the material properties are being evaluated at the qps, calculate the
153 // gradients as well. Note: only nodal properties are evaluated in
154 // initQpStatefulProperties(), so no need to check _is_initqp flag for qp
155 // properties
156 if (!_nodal_material)
157 if constexpr (!is_ad)
158 {
159 // Need to compute second derivatives of properties wrt variables for some of
160 // the gradient derivatives. Use finite differences for now
161 const Real dp = 1.0e-5 * _liquid_porepressure[_qp];
162 const Real dh = 1.0e-5 * _enthalpy[_qp];
163
164 std::vector<FluidStateProperties> fsp_dp(_num_phases, FluidStateProperties(_num_components));
165 _fs.thermophysicalProperties(_liquid_porepressure[_qp] + dp, _enthalpy[_qp], _qp, fsp_dp);
166
167 std::vector<FluidStateProperties> fsp_dh(_num_phases, FluidStateProperties(_num_components));
168 _fs.thermophysicalProperties(_liquid_porepressure[_qp], _enthalpy[_qp] + dh, _qp, fsp_dh);
169
170 // Gradient of temperature (non-zero in all phases)
171 (*_grad_temperature_qp)[_qp] = (*_dtemperature_dvar)[_qp][_pvar] * _liquid_gradp_qp[_qp] +
172 (*_dtemperature_dvar)[_qp][_hvar] * _gradh_qp[_qp];
173 (*_dgrad_temperature_dgradv)[_qp][_pvar] = (*_dtemperature_dvar)[_qp][_pvar];
174 (*_dgrad_temperature_dgradv)[_qp][_hvar] = (*_dtemperature_dvar)[_qp][_hvar];
175
176 const auto d2T_dp2 = (fsp_dp[_aqueous_phase_number].temperature.derivatives()[_pidx] -
177 _fsp[_aqueous_phase_number].temperature.derivatives()[_pidx]) /
178 dp;
179
180 const auto d2T_dh2 = (fsp_dh[_aqueous_phase_number].temperature.derivatives()[_hidx] -
181 _fsp[_aqueous_phase_number].temperature.derivatives()[_hidx]) /
182 dh;
183
184 const auto d2T_dph = (fsp_dp[_aqueous_phase_number].temperature.derivatives()[_hidx] -
185 _fsp[_aqueous_phase_number].temperature.derivatives()[_hidx]) /
186 dp +
187 (fsp_dh[_aqueous_phase_number].temperature.derivatives()[_pidx] -
188 _fsp[_aqueous_phase_number].temperature.derivatives()[_pidx]) /
189 dh;
190
191 (*_dgrad_temperature_dv)[_qp][_pvar] =
192 d2T_dp2 * _liquid_gradp_qp[_qp] + d2T_dph * _gradh_qp[_qp];
193 (*_dgrad_temperature_dv)[_qp][_hvar] =
194 d2T_dph * _liquid_gradp_qp[_qp] + d2T_dh2 * _gradh_qp[_qp];
195
196 // Gradient of saturation and derivatives
197 (*_grads_qp)[_qp][_gas_phase_number] =
198 (*_dsaturation_dvar)[_qp][_gas_phase_number][_pvar] * _liquid_gradp_qp[_qp] +
199 (*_dsaturation_dvar)[_qp][_gas_phase_number][_hvar] * _gradh_qp[_qp];
200 (*_grads_qp)[_qp][_aqueous_phase_number] = -(*_grads_qp)[_qp][_gas_phase_number];
201
202 (*_dgrads_qp_dgradv)[_qp][_gas_phase_number][_pvar] =
203 (*_dsaturation_dvar)[_qp][_gas_phase_number][_pvar];
204 (*_dgrads_qp_dgradv)[_qp][_aqueous_phase_number][_pvar] =
205 -(*_dgrads_qp_dgradv)[_qp][_gas_phase_number][_pvar];
206
207 (*_dgrads_qp_dgradv)[_qp][_gas_phase_number][_hvar] =
208 (*_dsaturation_dvar)[_qp][_gas_phase_number][_hvar];
209 (*_dgrads_qp_dgradv)[_qp][_aqueous_phase_number][_hvar] =
210 -(*_dgrads_qp_dgradv)[_qp][_gas_phase_number][_hvar];
211
212 const Real d2s_dp2 = (fsp_dp[_gas_phase_number].saturation.derivatives()[_pidx] -
213 _fsp[_gas_phase_number].saturation.derivatives()[_pidx]) /
214 dp;
215
216 const Real d2s_dh2 = (fsp_dh[_gas_phase_number].saturation.derivatives()[_hidx] -
217 _fsp[_gas_phase_number].saturation.derivatives()[_hidx]) /
218 dh;
219
220 const Real d2s_dph = (fsp_dp[_gas_phase_number].saturation.derivatives()[_hidx] -
221 _fsp[_gas_phase_number].saturation.derivatives()[_hidx]) /
222 dp +
223 (fsp_dh[_gas_phase_number].saturation.derivatives()[_pidx] -
224 _fsp[_gas_phase_number].saturation.derivatives()[_pidx]) /
225 dh;
226
227 (*_dgrads_qp_dv)[_qp][_gas_phase_number][_pvar] =
228 d2s_dp2 * _liquid_gradp_qp[_qp] + d2s_dph * _gradh_qp[_qp];
229 (*_dgrads_qp_dv)[_qp][_aqueous_phase_number][_pvar] =
230 -(*_dgrads_qp_dv)[_qp][_gas_phase_number][_pvar];
231
232 (*_dgrads_qp_dv)[_qp][_gas_phase_number][_hvar] =
233 d2s_dh2 * _gradh_qp[_qp] + d2s_dph * _liquid_gradp_qp[_qp];
234 (*_dgrads_qp_dv)[_qp][_aqueous_phase_number][_hvar] =
235 -(*_dgrads_qp_dv)[_qp][_gas_phase_number][_hvar];
236
237 // Gradient of porepressure and derivatives
238 // Note: need first and second derivativea of capillary pressure
239 const Real dpc = _pc.dCapillaryPressure(_fsp[_aqueous_phase_number].saturation.value());
240 const Real d2pc = _pc.d2CapillaryPressure(_fsp[_aqueous_phase_number].saturation.value());
241
242 (*_gradp_qp)[_qp][_aqueous_phase_number] = _liquid_gradp_qp[_qp];
243 (*_gradp_qp)[_qp][_gas_phase_number] =
244 _liquid_gradp_qp[_qp] + dpc * (*_grads_qp)[_qp][_aqueous_phase_number];
245
246 for (unsigned int ph = 0; ph < _num_phases; ++ph)
247 (*_dgradp_qp_dgradv)[_qp][ph][_pvar] = 1.0;
248
249 (*_dgradp_qp_dgradv)[_qp][_gas_phase_number][_pvar] +=
250 dpc * (*_dgrads_qp_dgradv)[_qp][_aqueous_phase_number][_pvar];
251 (*_dgradp_qp_dgradv)[_qp][_gas_phase_number][_hvar] =
252 dpc * (*_dgrads_qp_dgradv)[_qp][_aqueous_phase_number][_hvar];
253
254 (*_dgradp_qp_dv)[_qp][_gas_phase_number][_pvar] =
255 d2pc * (*_grads_qp)[_qp][_aqueous_phase_number] *
256 (*_dsaturation_dvar)[_qp][_aqueous_phase_number][_pvar] +
257 dpc * (*_dgrads_qp_dv)[_qp][_aqueous_phase_number][_pvar];
258
259 (*_dgradp_qp_dv)[_qp][_gas_phase_number][_hvar] =
260 d2pc * (*_grads_qp)[_qp][_aqueous_phase_number] *
261 (*_dsaturation_dvar)[_qp][_aqueous_phase_number][_hvar] +
262 dpc * (*_dgrads_qp_dv)[_qp][_aqueous_phase_number][_hvar];
263 }
264}
265
266template <bool is_ad>
267void
269{
271
272 // Derivatives and gradients are not required in initQpStatefulProperties
273 if (!_is_initqp)
274 {
275 // Temperature doesn't depend of fluid phase
276 (*_dtemperature_dvar)[_qp].assign(_num_pf_vars, 0.0);
277
278 // The gradient of the temperature is needed for qp materials and AD materials
279 if (!_nodal_material || is_ad)
280 (*_grad_temperature_qp)[_qp] = RealGradient();
281
282 // No derivatives are required for AD materials
283 if (!is_ad)
284 if (!_nodal_material)
285 {
286 (*_dgrad_temperature_dgradv)[_qp].assign(_num_pf_vars, 0.0);
287 (*_dgrad_temperature_dv)[_qp].assign(_num_pf_vars, RealGradient());
288 }
289 }
290}
291
void mooseError(Args &&... args)
registerMooseObject("PorousFlowApp", PorousFlowFluidStateSingleComponent)
const std::string name
Definition Setup.h:21
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
Fluid state base class using a persistent set of primary variables for multiphase,...
virtual void setMaterialVectorSize() const
Size material property vectors and initialise with zeros.
unsigned int numPhases() const
The maximum number of phases in this model.
Base class for miscible multiphase flow classes with a single fluid component using a pressure and en...
Fluid state class using a persistent set of primary variables for the mutliphase, single component ca...
const PorousFlowFluidStateSingleComponentBase & _fs
FluidState UserObject.
PorousFlowFluidStateSingleComponentTempl(const InputParameters &parameters)
virtual void thermophysicalProperties() override
Calculates all required thermophysical properties and derivatives for each phase and fluid component.
virtual void setMaterialVectorSize() const override
Size material property vectors and initialise with zeros.
const unsigned int _num_phases
Number of phases.
AD data structure to pass calculated thermophysical properties.