www.mooseframework.org
PorousFlowLineSink.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 "PorousFlowLineSink.h"
11 #include "libmesh/utility.h"
12 
13 template <>
14 InputParameters
16 {
17  InputParameters params = validParams<PorousFlowLineGeometry>();
18  MooseEnum p_or_t_choice("pressure=0 temperature=1", "pressure");
19  params.addParam<MooseEnum>("function_of",
20  p_or_t_choice,
21  "Modifying functions will be a function of either pressure and "
22  "permeability (eg, for boreholes that pump fluids) or "
23  "temperature and thermal conductivity (eg, for boreholes that "
24  "pump pure heat with no fluid flow)");
25  params.addRequiredParam<UserObjectName>(
26  "SumQuantityUO",
27  "User Object of type=PorousFlowSumQuantity in which to place the total "
28  "outflow from the line sink for each time step.");
29  params.addRequiredParam<UserObjectName>(
30  "PorousFlowDictator", "The UserObject that holds the list of PorousFlow variable names");
31  params.addParam<unsigned int>(
32  "fluid_phase",
33  0,
34  "The fluid phase whose pressure (and potentially mobility, enthalpy, etc) "
35  "controls the flux to the line sink. For p_or_t=temperature, and without "
36  "any use_*, this parameter is irrelevant");
37  params.addParam<unsigned int>("mass_fraction_component",
38  "The index corresponding to a fluid "
39  "component. If supplied, the flux will "
40  "be multiplied by the nodal mass "
41  "fraction for the component");
42  params.addParam<bool>(
43  "use_relative_permeability", false, "Multiply the flux by the fluid relative permeability");
44  params.addParam<bool>("use_mobility", false, "Multiply the flux by the fluid mobility");
45  params.addParam<bool>("use_enthalpy", false, "Multiply the flux by the fluid enthalpy");
46  params.addParam<bool>(
47  "use_internal_energy", false, "Multiply the flux by the fluid internal energy");
48  params.addClassDescription("Approximates a line sink in the mesh by a sequence of weighted Dirac "
49  "points whose positions are read from a file");
50  return params;
51 }
52 
53 PorousFlowLineSink::PorousFlowLineSink(const InputParameters & parameters)
54  : PorousFlowLineGeometry(parameters),
55  _dictator(getUserObject<PorousFlowDictator>("PorousFlowDictator")),
56  _total_outflow_mass(
57  const_cast<PorousFlowSumQuantity &>(getUserObject<PorousFlowSumQuantity>("SumQuantityUO"))),
58 
59  _has_porepressure(
60  hasMaterialProperty<std::vector<Real>>("PorousFlow_porepressure_qp") &&
61  hasMaterialProperty<std::vector<std::vector<Real>>>("dPorousFlow_porepressure_qp_dvar")),
62  _has_temperature(hasMaterialProperty<Real>("PorousFlow_temperature_qp") &&
63  hasMaterialProperty<std::vector<Real>>("dPorousFlow_temperature_qp_dvar")),
64  _has_mass_fraction(
65  hasMaterialProperty<std::vector<std::vector<Real>>>("PorousFlow_mass_frac_nodal") &&
66  hasMaterialProperty<std::vector<std::vector<std::vector<Real>>>>(
67  "dPorousFlow_mass_frac_nodal_dvar")),
68  _has_relative_permeability(
69  hasMaterialProperty<std::vector<Real>>("PorousFlow_relative_permeability_nodal") &&
70  hasMaterialProperty<std::vector<std::vector<Real>>>(
71  "dPorousFlow_relative_permeability_nodal_dvar")),
72  _has_mobility(
73  hasMaterialProperty<std::vector<Real>>("PorousFlow_relative_permeability_nodal") &&
74  hasMaterialProperty<std::vector<std::vector<Real>>>(
75  "dPorousFlow_relative_permeability_nodal_dvar") &&
76  hasMaterialProperty<std::vector<Real>>("PorousFlow_fluid_phase_density_nodal") &&
77  hasMaterialProperty<std::vector<std::vector<Real>>>(
78  "dPorousFlow_fluid_phase_density_nodal_dvar") &&
79  hasMaterialProperty<std::vector<Real>>("PorousFlow_viscosity_nodal") &&
80  hasMaterialProperty<std::vector<std::vector<Real>>>("dPorousFlow_viscosity_nodal_dvar")),
81  _has_enthalpy(hasMaterialProperty<std::vector<Real>>("PorousFlow_fluid_phase_enthalpy_nodal") &&
82  hasMaterialProperty<std::vector<std::vector<Real>>>(
83  "dPorousFlow_fluid_phase_enthalpy_nodal_dvar")),
84  _has_internal_energy(
85  hasMaterialProperty<std::vector<Real>>("PorousFlow_fluid_phase_internal_energy_nodal") &&
86  hasMaterialProperty<std::vector<std::vector<Real>>>(
87  "dPorousFlow_fluid_phase_internal_energy_nodal_dvar")),
88 
89  _p_or_t(getParam<MooseEnum>("function_of").getEnum<PorTchoice>()),
90  _use_mass_fraction(isParamValid("mass_fraction_component")),
91  _use_relative_permeability(getParam<bool>("use_relative_permeability")),
92  _use_mobility(getParam<bool>("use_mobility")),
93  _use_enthalpy(getParam<bool>("use_enthalpy")),
94  _use_internal_energy(getParam<bool>("use_internal_energy")),
95 
96  _ph(getParam<unsigned int>("fluid_phase")),
97  _sp(_use_mass_fraction ? getParam<unsigned int>("mass_fraction_component") : 0),
98 
99  _pp((_p_or_t == PorTchoice::pressure && _has_porepressure)
100  ? &getMaterialProperty<std::vector<Real>>("PorousFlow_porepressure_qp")
101  : nullptr),
102  _dpp_dvar((_p_or_t == PorTchoice::pressure && _has_porepressure)
103  ? &getMaterialProperty<std::vector<std::vector<Real>>>(
104  "dPorousFlow_porepressure_qp_dvar")
105  : nullptr),
106  _temperature((_p_or_t == PorTchoice::temperature && _has_temperature)
107  ? &getMaterialProperty<Real>("PorousFlow_temperature_qp")
108  : nullptr),
109  _dtemperature_dvar(
110  (_p_or_t == PorTchoice::temperature && _has_temperature)
111  ? &getMaterialProperty<std::vector<Real>>("dPorousFlow_temperature_qp_dvar")
112  : nullptr),
113  _fluid_density_node(
114  (_use_mobility && _has_mobility)
115  ? &getMaterialProperty<std::vector<Real>>("PorousFlow_fluid_phase_density_nodal")
116  : nullptr),
117  _dfluid_density_node_dvar((_use_mobility && _has_mobility)
118  ? &getMaterialProperty<std::vector<std::vector<Real>>>(
119  "dPorousFlow_fluid_phase_density_nodal_dvar")
120  : nullptr),
121  _fluid_viscosity((_use_mobility && _has_mobility)
122  ? &getMaterialProperty<std::vector<Real>>("PorousFlow_viscosity_nodal")
123  : nullptr),
124  _dfluid_viscosity_dvar((_use_mobility && _has_mobility)
125  ? &getMaterialProperty<std::vector<std::vector<Real>>>(
126  "dPorousFlow_viscosity_nodal_dvar")
127  : nullptr),
128  _relative_permeability(
129  ((_use_mobility && _has_mobility) ||
130  (_use_relative_permeability && _has_relative_permeability))
131  ? &getMaterialProperty<std::vector<Real>>("PorousFlow_relative_permeability_nodal")
132  : nullptr),
133  _drelative_permeability_dvar(((_use_mobility && _has_mobility) ||
134  (_use_relative_permeability && _has_relative_permeability))
135  ? &getMaterialProperty<std::vector<std::vector<Real>>>(
136  "dPorousFlow_relative_permeability_nodal_dvar")
137  : nullptr),
138  _mass_fractions(
139  (_use_mass_fraction && _has_mass_fraction)
140  ? &getMaterialProperty<std::vector<std::vector<Real>>>("PorousFlow_mass_frac_nodal")
141  : nullptr),
142  _dmass_fractions_dvar((_use_mass_fraction && _has_mass_fraction)
143  ? &getMaterialProperty<std::vector<std::vector<std::vector<Real>>>>(
144  "dPorousFlow_mass_frac_nodal_dvar")
145  : nullptr),
146  _enthalpy(_has_enthalpy ? &getMaterialPropertyByName<std::vector<Real>>(
147  "PorousFlow_fluid_phase_enthalpy_nodal")
148  : nullptr),
149  _denthalpy_dvar(_has_enthalpy ? &getMaterialPropertyByName<std::vector<std::vector<Real>>>(
150  "dPorousFlow_fluid_phase_enthalpy_nodal_dvar")
151  : nullptr),
152  _internal_energy(_has_internal_energy ? &getMaterialPropertyByName<std::vector<Real>>(
153  "PorousFlow_fluid_phase_internal_energy_nodal")
154  : nullptr),
155  _dinternal_energy_dvar(_has_internal_energy
156  ? &getMaterialPropertyByName<std::vector<std::vector<Real>>>(
157  "dPorousFlow_fluid_phase_internal_energy_nodal_dvar")
158  : nullptr)
159 {
160  // zero the outflow mass
162 
163  if (_ph >= _dictator.numPhases())
164  paramError("fluid_phase",
165  "The Dictator proclaims that the maximum phase index in this simulation is ",
166  _dictator.numPhases() - 1,
167  " whereas you have used ",
168  _ph,
169  ". Remember that indexing starts at 0. You must try harder.");
170 
172  paramError(
173  "mass_fraction_component",
174  "The Dictator proclaims that the maximum fluid component index in this simulation is ",
175  _dictator.numComponents() - 1,
176  " whereas you have used ",
177  _sp,
178  ". Remember that indexing starts at 0. Please be assured that the Dictator has noted your "
179  "error.");
180 
182  mooseError("PorousFlowLineSink: You have specified function_of=porepressure, but you do not "
183  "have a quadpoint porepressure material");
184 
186  mooseError("PorousFlowLineSink: You have specified function_of=temperature, but you do not "
187  "have a quadpoint temperature material");
188 
190  mooseError("PorousFlowLineSink: You have specified a fluid component, but do not have a nodal "
191  "mass-fraction material");
192 
194  mooseError("PorousFlowLineSink: You have set use_relative_permeability=true, but do not have a "
195  "nodal relative permeability material");
196 
198  mooseError("PorousFlowLineSink: You have set use_mobility=true, but do not have nodal density, "
199  "relative permeability or viscosity material");
200 
202  mooseError("PorousFlowLineSink: You have set use_enthalpy=true, but do not have a nodal "
203  "enthalpy material");
204 
206  mooseError("PorousFlowLineSink: You have set use_internal_energy=true, but do not have a nodal "
207  "internal-energy material");
208 
209  // To correctly compute the Jacobian terms,
210  // tell MOOSE that this DiracKernel depends on all the PorousFlow Variables
211  const std::vector<MooseVariableFEBase *> & coupled_vars = _dictator.getCoupledMooseVars();
212  for (unsigned int i = 0; i < coupled_vars.size(); i++)
213  addMooseVariableDependency(coupled_vars[i]);
214 }
215 
216 void
218 {
219  // This function gets called just before the DiracKernel is evaluated
220  // so this is a handy place to zero this out.
222 
224 }
225 
226 Real
228 {
229  // Get the ID we initially assigned to this point
230  const unsigned current_dirac_ptid = currentPointCachedID();
231  Real outflow = computeQpBaseOutflow(current_dirac_ptid);
232  if (outflow == 0.0)
233  return 0.0;
234 
236  outflow *= (*_relative_permeability)[_i][_ph];
237 
238  if (_use_mobility)
239  outflow *= (*_relative_permeability)[_i][_ph] * (*_fluid_density_node)[_i][_ph] /
240  (*_fluid_viscosity)[_i][_ph];
241 
242  if (_use_mass_fraction)
243  outflow *= (*_mass_fractions)[_i][_ph][_sp];
244 
245  if (_use_enthalpy)
246  outflow *= (*_enthalpy)[_i][_ph];
247 
249  outflow *= (*_internal_energy)[_i][_ph];
250 
252  outflow * _dt); // this is not thread safe, but DiracKernel's aren't currently threaded
253 
254  return outflow;
255 }
256 
257 Real
259 {
260  return jac(_var.number());
261 }
262 
263 Real
265 {
266  return jac(jvar);
267 }
268 
269 Real
270 PorousFlowLineSink::jac(unsigned int jvar)
271 {
273  return 0.0;
274  const unsigned pvar = _dictator.porousFlowVariableNum(jvar);
275 
276  Real outflow;
277  Real outflowp;
278  const unsigned current_dirac_ptid = currentPointCachedID();
279  computeQpBaseOutflowJacobian(jvar, current_dirac_ptid, outflow, outflowp);
280  if (outflow == 0.0 && outflowp == 0.0)
281  return 0.0;
282 
284  {
285  const Real relperm_prime = (_i != _j ? 0.0 : (*_drelative_permeability_dvar)[_i][_ph][pvar]);
286  outflowp = (*_relative_permeability)[_i][_ph] * outflowp + relperm_prime * outflow;
287  outflow *= (*_relative_permeability)[_i][_ph];
288  }
289 
290  if (_use_mobility)
291  {
292  const Real mob = (*_relative_permeability)[_i][_ph] * (*_fluid_density_node)[_i][_ph] /
293  (*_fluid_viscosity)[_i][_ph];
294  const Real mob_prime =
295  (_i != _j
296  ? 0.0
297  : (*_drelative_permeability_dvar)[_i][_ph][pvar] * (*_fluid_density_node)[_i][_ph] /
298  (*_fluid_viscosity)[_i][_ph] +
299  (*_relative_permeability)[_i][_ph] *
300  (*_dfluid_density_node_dvar)[_i][_ph][pvar] / (*_fluid_viscosity)[_i][_ph] -
301  (*_relative_permeability)[_i][_ph] * (*_fluid_density_node)[_i][_ph] *
302  (*_dfluid_viscosity_dvar)[_i][_ph][pvar] /
303  Utility::pow<2>((*_fluid_viscosity)[_i][_ph]));
304  outflowp = mob * outflowp + mob_prime * outflow;
305  outflow *= mob;
306  }
307 
308  if (_use_mass_fraction)
309  {
310  const Real mass_fractions_prime =
311  (_i != _j ? 0.0 : (*_dmass_fractions_dvar)[_i][_ph][_sp][pvar]);
312  outflowp = (*_mass_fractions)[_i][_ph][_sp] * outflowp + mass_fractions_prime * outflow;
313  outflow *= (*_mass_fractions)[_i][_ph][_sp];
314  }
315 
316  if (_use_enthalpy)
317  {
318  const Real enthalpy_prime = (_i != _j ? 0.0 : (*_denthalpy_dvar)[_i][_ph][pvar]);
319  outflowp = (*_enthalpy)[_i][_ph] * outflowp + enthalpy_prime * outflow;
320  outflow *= (*_enthalpy)[_i][_ph];
321  }
322 
324  {
325  const Real internal_energy_prime = (_i != _j ? 0.0 : (*_dinternal_energy_dvar)[_i][_ph][pvar]);
326  outflowp = (*_internal_energy)[_i][_ph] * outflowp + internal_energy_prime * outflow;
327  // this multiplication was performed, but the code does not need to know: outflow *=
328  // (*_internal_energy)[_i][_ph];
329  }
330 
331  return outflowp;
332 }
333 
334 Real
336 {
337  return (_p_or_t == PorTchoice::pressure ? (*_pp)[_qp][_ph] : (*_temperature)[_qp]);
338 }
339 
340 Real
341 PorousFlowLineSink::dptqp(unsigned pvar) const
342 {
343  return (_p_or_t == PorTchoice::pressure ? (*_dpp_dvar)[_qp][_ph][pvar]
344  : (*_dtemperature_dvar)[_qp][pvar]);
345 }
PorousFlowLineSink::_has_internal_energy
const bool _has_internal_energy
Whether an internal-energy material exists (for error checking)
Definition: PorousFlowLineSink.h:88
PorousFlowLineSink::PorTchoice
PorTchoice
whether the flux is a function of pressure or temperature
Definition: PorousFlowLineSink.h:91
PorousFlowDictator::notPorousFlowVariable
bool notPorousFlowVariable(unsigned int moose_var_num) const
Returns true if moose_var_num is not a porous flow variabe.
Definition: PorousFlowDictator.C:161
PorousFlowLineSink::PorTchoice::pressure
PorousFlowLineSink::_use_internal_energy
const bool _use_internal_energy
Whether the flux will be multiplied by the internal-energy.
Definition: PorousFlowLineSink.h:106
PorousFlowLineSink::PorousFlowLineSink
PorousFlowLineSink(const InputParameters &parameters)
Definition: PorousFlowLineSink.C:53
PorousFlowLineSink::_dpp_dvar
const MaterialProperty< std::vector< std::vector< Real > > > *const _dpp_dvar
d(quadpoint pore pressure in each phase)/d(PorousFlow variable)
Definition: PorousFlowLineSink.h:118
PorousFlowLineSink::_has_mass_fraction
const bool _has_mass_fraction
Whether a mass_fraction material exists (for error checking)
Definition: PorousFlowLineSink.h:76
PorousFlowLineSink::PorTchoice::temperature
PorousFlowLineSink::_sp
const unsigned int _sp
The component number (only used if _use_mass_fraction==true)
Definition: PorousFlowLineSink.h:112
PorousFlowLineGeometry::addPoints
virtual void addPoints() override
Add Dirac Points to the line sink.
Definition: PorousFlowLineGeometry.C:125
PorousFlowDictator::porousFlowVariableNum
unsigned int porousFlowVariableNum(unsigned int moose_var_num) const
The PorousFlow variable number.
Definition: PorousFlowDictator.C:135
PorousFlowLineGeometry
Approximates a borehole by a sequence of Dirac Points.
Definition: PorousFlowLineGeometry.h:22
PorousFlowLineSink::computeQpBaseOutflowJacobian
virtual void computeQpBaseOutflowJacobian(unsigned jvar, unsigned current_dirac_ptid, Real &outflow, Real &outflowp) const =0
Calculates the BaseOutflow as well as its derivative wrt jvar. Derived classes should override this.
PorousFlowLineSink::_use_mobility
const bool _use_mobility
Whether the flux will be multiplied by the mobility.
Definition: PorousFlowLineSink.h:100
PorousFlowLineSink::_dtemperature_dvar
const MaterialProperty< std::vector< Real > > *const _dtemperature_dvar
d(quadpoint temperature)/d(PorousFlow variable)
Definition: PorousFlowLineSink.h:124
PorousFlowDictator
This holds maps between the nonlinear variables used in a PorousFlow simulation and the variable numb...
Definition: PorousFlowDictator.h:71
PorousFlowDictator::numPhases
unsigned int numPhases() const
The number of fluid phases.
Definition: PorousFlowDictator.C:105
PorousFlowSumQuantity::zero
void zero()
Sets _total = 0.
Definition: PorousFlowSumQuantity.C:31
PorousFlowLineSink.h
validParams< PorousFlowLineGeometry >
InputParameters validParams< PorousFlowLineGeometry >()
Definition: PorousFlowLineGeometry.C:17
validParams< PorousFlowLineSink >
InputParameters validParams< PorousFlowLineSink >()
Definition: PorousFlowLineSink.C:15
PorousFlowLineSink::_temperature
const MaterialProperty< Real > *const _temperature
Quadpoint temperature.
Definition: PorousFlowLineSink.h:121
PorousFlowLineSink::_total_outflow_mass
PorousFlowSumQuantity & _total_outflow_mass
This is used to hold the total fluid flowing into the line sink for each time step.
Definition: PorousFlowLineSink.h:67
PorousFlowLineSink::_ph
const unsigned int _ph
The phase number.
Definition: PorousFlowLineSink.h:109
PorousFlowLineSink::_pp
const MaterialProperty< std::vector< Real > > *const _pp
Quadpoint pore pressure in each phase.
Definition: PorousFlowLineSink.h:115
PorousFlowLineSink::_has_relative_permeability
const bool _has_relative_permeability
Whether a relative permeability material exists (for error checking)
Definition: PorousFlowLineSink.h:79
PorousFlowLineSink::_use_enthalpy
const bool _use_enthalpy
Whether the flux will be multiplied by the enthalpy.
Definition: PorousFlowLineSink.h:103
PorousFlowLineSink::computeQpBaseOutflow
virtual Real computeQpBaseOutflow(unsigned current_dirac_ptid) const =0
Returns the flux from the line sink (before modification by mobility, etc). Derived classes should ov...
PorousFlowLineSink::_fluid_viscosity
const MaterialProperty< std::vector< Real > > *const _fluid_viscosity
Viscosity of each component in each phase.
Definition: PorousFlowLineSink.h:133
PorousFlowLineSink::_has_temperature
const bool _has_temperature
Whether a quadpoint temperature material exists (for error checking)
Definition: PorousFlowLineSink.h:73
PorousFlowLineSink::addPoints
virtual void addPoints() override
Add Dirac Points to the borehole.
Definition: PorousFlowLineSink.C:217
PorousFlowLineSink::_has_enthalpy
const bool _has_enthalpy
Whether an enthalpy material exists (for error checking)
Definition: PorousFlowLineSink.h:85
PorousFlowLineSink::_use_relative_permeability
const bool _use_relative_permeability
Whether the flux will be multiplied by the relative permeability.
Definition: PorousFlowLineSink.h:97
PorousFlowLineSink::_use_mass_fraction
const bool _use_mass_fraction
Whether the flux will be multiplied by the mass fraction.
Definition: PorousFlowLineSink.h:94
PorousFlowDictator::numComponents
unsigned int numComponents() const
The number of fluid components.
Definition: PorousFlowDictator.C:111
PorousFlowLineSink::computeQpOffDiagJacobian
virtual Real computeQpOffDiagJacobian(unsigned int jvar) override
Definition: PorousFlowLineSink.C:264
PorousFlowSumQuantity::add
void add(Real contrib)
Adds contrib to _total.
Definition: PorousFlowSumQuantity.C:37
NS::temperature
const std::string temperature
Definition: NS.h:26
PorousFlowSumQuantity
Sums into _total This is used, for instance, to record the total mass flowing into a borehole.
Definition: PorousFlowSumQuantity.h:26
PorousFlowLineSink::_p_or_t
enum PorousFlowLineSink::PorTchoice _p_or_t
PorousFlowLineSink::computeQpResidual
virtual Real computeQpResidual() override
Definition: PorousFlowLineSink.C:227
PorousFlowLineSink::computeQpJacobian
virtual Real computeQpJacobian() override
Definition: PorousFlowLineSink.C:258
PorousFlowLineSink::dptqp
Real dptqp(unsigned pvar) const
If _p_or_t==0, then returns d(quadpoint porepressure)/d(PorousFlow variable), else returns d(quadpoin...
Definition: PorousFlowLineSink.C:341
PorousFlowLineSink::_has_porepressure
const bool _has_porepressure
Whether a quadpoint porepressure material exists (for error checking)
Definition: PorousFlowLineSink.h:70
PorousFlowLineSink::ptqp
Real ptqp() const
If _p_or_t==0, then returns the quadpoint porepressure, else returns the quadpoint temperature.
Definition: PorousFlowLineSink.C:335
PorousFlowLineSink::_has_mobility
const bool _has_mobility
Whether enough materials exist to form the mobility (for error checking)
Definition: PorousFlowLineSink.h:82
PorousFlowLineSink::_dictator
const PorousFlowDictator & _dictator
PorousFlowDictator UserObject.
Definition: PorousFlowLineSink.h:60
NS::pressure
const std::string pressure
Definition: NS.h:25
PorousFlowLineSink::jac
Real jac(unsigned int jvar)
Jacobian contribution for the derivative wrt the variable jvar.
Definition: PorousFlowLineSink.C:270