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