11#include "libmesh/utility.h"
17 MooseEnum p_or_t_choice(
"pressure=0 temperature=1",
"pressure");
20 "Modifying functions will be a function of either pressure and "
21 "permeability (eg, for boreholes that pump fluids) or "
22 "temperature and thermal conductivity (eg, for boreholes that "
23 "pump pure heat with no fluid flow)");
26 "User Object of type=PorousFlowSumQuantity in which to place the total "
27 "outflow from the line sink for each time step.");
30 "Optional UserObject of type=PorousFlowPointFluxQuantity in which to record the "
31 "instantaneous flux (eg kg.s^-1 for fluid, J.s^-1 for heat) at each individual Dirac "
32 "point of this line sink, as computed during the most recent residual evaluation. Use a "
33 "PorousFlowPlotPointFluxQuantity VectorPostprocessor to output the recorded values. "
34 "Unlike SumQuantityUO, this is not multiplied by the timestep size. Use a separate "
35 "UserObject for each line sink.");
37 "PorousFlowDictator",
"The UserObject that holds the list of PorousFlow variable names");
41 "The fluid phase whose pressure (and potentially mobility, enthalpy, etc) "
42 "controls the flux to the line sink. For p_or_t=temperature, and without "
43 "any use_*, this parameter is irrelevant");
44 params.
addParam<
unsigned int>(
"mass_fraction_component",
45 "The index corresponding to a fluid "
46 "component. If supplied, the flux will "
47 "be multiplied by the nodal mass "
48 "fraction for the component");
50 "use_relative_permeability",
false,
"Multiply the flux by the fluid relative permeability");
51 params.
addParam<
bool>(
"use_mobility",
false,
"Multiply the flux by the fluid mobility");
52 params.
addParam<
bool>(
"use_enthalpy",
false,
"Multiply the flux by the fluid enthalpy");
54 "use_internal_energy",
false,
"Multiply the flux by the fluid internal energy");
55 params.
addCoupledVar(
"multiplying_var", 1.0,
"Fluxes will be moultiplied by this variable");
56 params.
addClassDescription(
"Approximates a line sink in the mesh by a sequence of weighted Dirac "
57 "points whose positions are read from a file");
66 _point_fluxes(isParamValid(
"PointFluxUO")
72 hasMaterialProperty<
std::vector<Real>>(
"PorousFlow_porepressure_qp") &&
73 hasMaterialProperty<
std::vector<
std::vector<Real>>>(
"dPorousFlow_porepressure_qp_dvar")),
74 _has_temperature(hasMaterialProperty<Real>(
"PorousFlow_temperature_qp") &&
75 hasMaterialProperty<
std::vector<Real>>(
"dPorousFlow_temperature_qp_dvar")),
77 hasMaterialProperty<
std::vector<
std::vector<Real>>>(
"PorousFlow_mass_frac_nodal") &&
78 hasMaterialProperty<
std::vector<
std::vector<
std::vector<Real>>>>(
79 "dPorousFlow_mass_frac_nodal_dvar")),
80 _has_relative_permeability(
81 hasMaterialProperty<
std::vector<Real>>(
"PorousFlow_relative_permeability_nodal") &&
82 hasMaterialProperty<
std::vector<
std::vector<Real>>>(
83 "dPorousFlow_relative_permeability_nodal_dvar")),
85 hasMaterialProperty<
std::vector<Real>>(
"PorousFlow_relative_permeability_nodal") &&
86 hasMaterialProperty<
std::vector<
std::vector<Real>>>(
87 "dPorousFlow_relative_permeability_nodal_dvar") &&
88 hasMaterialProperty<
std::vector<Real>>(
"PorousFlow_fluid_phase_density_nodal") &&
89 hasMaterialProperty<
std::vector<
std::vector<Real>>>(
90 "dPorousFlow_fluid_phase_density_nodal_dvar") &&
91 hasMaterialProperty<
std::vector<Real>>(
"PorousFlow_viscosity_nodal") &&
92 hasMaterialProperty<
std::vector<
std::vector<Real>>>(
"dPorousFlow_viscosity_nodal_dvar")),
93 _has_enthalpy(hasMaterialProperty<
std::vector<Real>>(
"PorousFlow_fluid_phase_enthalpy_nodal") &&
94 hasMaterialProperty<
std::vector<
std::vector<Real>>>(
95 "dPorousFlow_fluid_phase_enthalpy_nodal_dvar")),
97 hasMaterialProperty<
std::vector<Real>>(
"PorousFlow_fluid_phase_internal_energy_nodal") &&
98 hasMaterialProperty<
std::vector<
std::vector<Real>>>(
99 "dPorousFlow_fluid_phase_internal_energy_nodal_dvar")),
102 _use_mass_fraction(isParamValid(
"mass_fraction_component")),
103 _use_relative_permeability(getParam<bool>(
"use_relative_permeability")),
104 _use_mobility(getParam<bool>(
"use_mobility")),
105 _use_enthalpy(getParam<bool>(
"use_enthalpy")),
106 _use_internal_energy(getParam<bool>(
"use_internal_energy")),
108 _ph(getParam<unsigned
int>(
"fluid_phase")),
109 _sp(_use_mass_fraction ? getParam<unsigned
int>(
"mass_fraction_component") : 0),
111 _pp((_p_or_t ==
PorTchoice::pressure && _has_porepressure)
112 ? &getMaterialProperty<
std::vector<Real>>(
"PorousFlow_porepressure_qp")
114 _dpp_dvar((_p_or_t ==
PorTchoice::pressure && _has_porepressure)
115 ? &getMaterialProperty<
std::vector<
std::vector<Real>>>(
116 "dPorousFlow_porepressure_qp_dvar")
118 _temperature((_p_or_t ==
PorTchoice::temperature && _has_temperature)
119 ? &getMaterialProperty<Real>(
"PorousFlow_temperature_qp")
122 (_p_or_t ==
PorTchoice::temperature && _has_temperature)
123 ? &getMaterialProperty<
std::vector<Real>>(
"dPorousFlow_temperature_qp_dvar")
126 (_use_mobility && _has_mobility)
127 ? &getMaterialProperty<
std::vector<Real>>(
"PorousFlow_fluid_phase_density_nodal")
129 _dfluid_density_node_dvar((_use_mobility && _has_mobility)
130 ? &getMaterialProperty<
std::vector<
std::vector<Real>>>(
131 "dPorousFlow_fluid_phase_density_nodal_dvar")
133 _fluid_viscosity((_use_mobility && _has_mobility)
134 ? &getMaterialProperty<
std::vector<Real>>(
"PorousFlow_viscosity_nodal")
136 _dfluid_viscosity_dvar((_use_mobility && _has_mobility)
137 ? &getMaterialProperty<
std::vector<
std::vector<Real>>>(
138 "dPorousFlow_viscosity_nodal_dvar")
140 _relative_permeability(
141 ((_use_mobility && _has_mobility) ||
142 (_use_relative_permeability && _has_relative_permeability))
143 ? &getMaterialProperty<
std::vector<Real>>(
"PorousFlow_relative_permeability_nodal")
145 _drelative_permeability_dvar(((_use_mobility && _has_mobility) ||
146 (_use_relative_permeability && _has_relative_permeability))
147 ? &getMaterialProperty<
std::vector<
std::vector<Real>>>(
148 "dPorousFlow_relative_permeability_nodal_dvar")
151 (_use_mass_fraction && _has_mass_fraction)
152 ? &getMaterialProperty<
std::vector<
std::vector<Real>>>(
"PorousFlow_mass_frac_nodal")
154 _dmass_fractions_dvar((_use_mass_fraction && _has_mass_fraction)
155 ? &getMaterialProperty<
std::vector<
std::vector<
std::vector<Real>>>>(
156 "dPorousFlow_mass_frac_nodal_dvar")
158 _enthalpy(_has_enthalpy ? &getMaterialPropertyByName<
std::vector<Real>>(
159 "PorousFlow_fluid_phase_enthalpy_nodal")
161 _denthalpy_dvar(_has_enthalpy ? &getMaterialPropertyByName<
std::vector<
std::vector<Real>>>(
162 "dPorousFlow_fluid_phase_enthalpy_nodal_dvar")
164 _internal_energy(_has_internal_energy ? &getMaterialPropertyByName<
std::vector<Real>>(
165 "PorousFlow_fluid_phase_internal_energy_nodal")
167 _dinternal_energy_dvar(_has_internal_energy
168 ? &getMaterialPropertyByName<
std::vector<
std::vector<Real>>>(
169 "dPorousFlow_fluid_phase_internal_energy_nodal_dvar")
171 _multiplying_var(coupledValue(
"multiplying_var"))
178 "The Dictator proclaims that the maximum phase index in this simulation is ",
180 " whereas you have used ",
182 ". Remember that indexing starts at 0. You must try harder.");
186 "mass_fraction_component",
187 "The Dictator proclaims that the maximum fluid component index in this simulation is ",
189 " whereas you have used ",
191 ". Remember that indexing starts at 0. Please be assured that the Dictator has noted your "
195 mooseError(
"PorousFlowLineSink: You have specified function_of=porepressure, but you do not "
196 "have a quadpoint porepressure material");
199 mooseError(
"PorousFlowLineSink: You have specified function_of=temperature, but you do not "
200 "have a quadpoint temperature material");
203 mooseError(
"PorousFlowLineSink: You have specified a fluid component, but do not have a nodal "
204 "mass-fraction material");
207 mooseError(
"PorousFlowLineSink: You have set use_relative_permeability=true, but do not have a "
208 "nodal relative permeability material");
211 mooseError(
"PorousFlowLineSink: You have set use_mobility=true, but do not have nodal density, "
212 "relative permeability or viscosity material");
215 mooseError(
"PorousFlowLineSink: You have set use_enthalpy=true, but do not have a nodal "
216 "enthalpy material");
219 mooseError(
"PorousFlowLineSink: You have set use_internal_energy=true, but do not have a nodal "
220 "internal-energy material");
225 for (
unsigned int i = 0; i < coupled_vars.size(); i++)
253 outflow *= (*_relative_permeability)[
_i][
_ph];
256 outflow *= (*_relative_permeability)[
_i][
_ph] * (*_fluid_density_node)[
_i][
_ph] /
257 (*_fluid_viscosity)[
_i][
_ph];
260 outflow *= (*_mass_fractions)[
_i][
_ph][
_sp];
263 outflow *= (*_enthalpy)[
_i][
_ph];
266 outflow *= (*_internal_energy)[
_i][
_ph];
299 if (outflow == 0.0 && outflowp == 0.0)
307 const Real relperm_prime = (
_i !=
_j ? 0.0 : (*_drelative_permeability_dvar)[
_i][
_ph][pvar]);
308 outflowp = (*_relative_permeability)[
_i][
_ph] * outflowp + relperm_prime * outflow;
309 outflow *= (*_relative_permeability)[
_i][
_ph];
314 const Real mob = (*_relative_permeability)[
_i][
_ph] * (*_fluid_density_node)[
_i][
_ph] /
315 (*_fluid_viscosity)[
_i][
_ph];
316 const Real mob_prime =
319 : (*_drelative_permeability_dvar)[
_i][
_ph][pvar] * (*_fluid_density_node)[
_i][
_ph] /
320 (*_fluid_viscosity)[
_i][
_ph] +
321 (*_relative_permeability)[
_i][
_ph] *
322 (*_dfluid_density_node_dvar)[
_i][
_ph][pvar] / (*_fluid_viscosity)[
_i][
_ph] -
323 (*_relative_permeability)[
_i][
_ph] * (*_fluid_density_node)[
_i][
_ph] *
324 (*_dfluid_viscosity_dvar)[
_i][
_ph][pvar] /
326 outflowp = mob * outflowp + mob_prime * outflow;
332 const Real mass_fractions_prime =
333 (
_i !=
_j ? 0.0 : (*_dmass_fractions_dvar)[
_i][
_ph][
_sp][pvar]);
334 outflowp = (*_mass_fractions)[
_i][
_ph][
_sp] * outflowp + mass_fractions_prime * outflow;
335 outflow *= (*_mass_fractions)[
_i][
_ph][
_sp];
340 const Real enthalpy_prime = (
_i !=
_j ? 0.0 : (*_denthalpy_dvar)[
_i][
_ph][pvar]);
341 outflowp = (*_enthalpy)[
_i][
_ph] * outflowp + enthalpy_prime * outflow;
342 outflow *= (*_enthalpy)[
_i][
_ph];
347 const Real internal_energy_prime = (
_i !=
_j ? 0.0 : (*_dinternal_energy_dvar)[
_i][
_ph][pvar]);
348 outflowp = (*_internal_energy)[
_i][
_ph] * outflowp + internal_energy_prime * outflow;
366 : (*_dtemperature_dvar)[
_qp][pvar]);
void ErrorVector unsigned int
const std::vector< MooseVariableFieldBase * > & getCoupledMooseVars() const
unsigned currentPointCachedID()
MooseVariableField< T > & _var
void paramError(const std::string ¶m, Args... args) const
void mooseError(Args &&... args) const
unsigned int number() const
void addMooseVariableDependency(MooseVariableFieldBase *var)
This holds maps between the nonlinear variables used in a PorousFlow simulation and the variable numb...
unsigned int numPhases() const
The number of fluid phases.
unsigned int numComponents() const
The number of fluid components.
unsigned int porousFlowVariableNum(unsigned int moose_var_num) const
The PorousFlow variable number.
bool notPorousFlowVariable(unsigned int moose_var_num) const
Returns true if moose_var_num is not a porous flow variabe.
Approximates a borehole by a sequence of Dirac Points.
static InputParameters validParams()
Creates a new PorousFlowLineGeometry This reads the file containing the lines of the form weight x y ...
const std::vector< Real > *const _z_coord
const std::vector< Real > *const _y_coord
const std::vector< Real > *const _x_coord
virtual void addPoints() override
Add Dirac Points to the line sink.
Real dptqp(unsigned pvar) const
If _p_or_t==0, then returns d(quadpoint porepressure)/d(PorousFlow variable), else returns d(quadpoin...
const bool _has_temperature
Whether a quadpoint temperature material exists (for error checking)
const MaterialProperty< std::vector< Real > > *const _pp
Quadpoint pore pressure in each phase.
const PorousFlowDictator & _dictator
PorousFlowDictator UserObject.
const VariableValue & _multiplying_var
mass flux is multiplied by this variable evaluated at quadpoints
virtual Real computeQpResidual() override
PorTchoice
whether the flux is a function of pressure or temperature
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...
Real jac(unsigned int jvar)
Jacobian contribution for the derivative wrt the variable jvar.
virtual Real computeQpOffDiagJacobian(unsigned int jvar) override
PorousFlowPointFluxQuantity *const _point_fluxes
Optional recorder of the instantaneous flux at each Dirac point of this line sink.
const bool _use_mobility
Whether the flux will be multiplied by the mobility.
const bool _has_porepressure
Whether a quadpoint porepressure material exists (for error checking)
const bool _has_relative_permeability
Whether a relative permeability material exists (for error checking)
enum PorousFlowLineSink::PorTchoice _p_or_t
PorousFlowSumQuantity & _total_outflow_mass
This is used to hold the total fluid flowing into the line sink for each time step.
const bool _has_mass_fraction
Whether a mass_fraction material exists (for error checking)
const MaterialProperty< std::vector< Real > > *const _fluid_viscosity
Viscosity of each component in each phase.
const bool _use_mass_fraction
Whether the flux will be multiplied by the mass fraction.
static InputParameters validParams()
PorousFlowLineSink(const InputParameters ¶meters)
const bool _has_enthalpy
Whether an enthalpy material exists (for error checking)
const MaterialProperty< std::vector< std::vector< Real > > > *const _dpp_dvar
d(quadpoint pore pressure in each phase)/d(PorousFlow variable)
virtual void addPoints() override
Add Dirac Points to the borehole.
Real ptqp() const
If _p_or_t==0, then returns the quadpoint porepressure, else returns the quadpoint temperature.
virtual Real computeQpJacobian() override
const unsigned int _sp
The component number (only used if _use_mass_fraction==true)
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.
const unsigned int _ph
The phase number.
const bool _use_enthalpy
Whether the flux will be multiplied by the enthalpy.
const bool _has_internal_energy
Whether an internal-energy material exists (for error checking)
const bool _use_relative_permeability
Whether the flux will be multiplied by the relative permeability.
const bool _use_internal_energy
Whether the flux will be multiplied by the internal-energy.
const bool _has_mobility
Whether enough materials exist to form the mobility (for error checking)
Records the instantaneous flux at each Dirac point of a PorousFlow line sink (such as PorousFlowPeace...
void zero(const std::vector< Real > &xs, const std::vector< Real > &ys, const std::vector< Real > &zs)
Resets the flux recorded at every point to zero, and records the current point coordinates.
void add(std::size_t i, Real contrib)
Adds contrib to the flux recorded at point i.
Sums into _total This is used, for instance, to record the total mass flowing into a borehole.
void add(Real contrib)
Adds contrib to _total.
void zero()
Sets _total = 0.