14#include "libmesh/quadrature.h"
25 "PorousFlowDictator",
"The UserObject that holds the list of PorousFlow variable names");
26 params.
addParam<
unsigned int>(
"fluid_phase",
27 "If supplied, then this BC will potentially be a function of fluid "
28 "pressure, and you can use mass_fraction_component, use_mobility, "
29 "use_relperm, use_enthalpy and use_energy. If not supplied, then "
30 "this BC can only be a function of temperature");
31 params.
addParam<
unsigned int>(
"mass_fraction_component",
32 "The index corresponding to a fluid "
33 "component. If supplied, the flux will "
34 "be multiplied by the nodal mass "
35 "fraction for the component");
36 params.
addParam<
bool>(
"use_mobility",
38 "If true, then fluxes are multiplied by "
39 "(density*permeability_nn/viscosity), where the "
40 "'_nn' indicates the component normal to the "
41 "boundary. In this case bare_flux is measured in "
42 "Pa.m^-1. This can be used in conjunction with "
46 "If true, then fluxes are multiplied by relative "
47 "permeability. This can be used in conjunction with "
49 params.
addParam<
bool>(
"use_enthalpy",
51 "If true, then fluxes are multiplied by enthalpy. "
52 "In this case bare_flux is measured in kg.m^-2.s^-1 "
53 "/ (J.kg). This can be used in conjunction with "
55 params.
addParam<
bool>(
"use_internal_energy",
57 "If true, then fluxes are multiplied by fluid internal energy. "
58 " In this case bare_flux is measured in kg.m^-2.s^-1 / (J.kg). "
59 " This can be used in conjunction with other use_*");
60 params.
addParam<
bool>(
"use_thermal_conductivity",
62 "If true, then fluxes are multiplied by "
63 "thermal conductivity projected onto "
64 "the normal direction. This can be "
65 "used in conjunction with other use_*");
69 "The flux. The flux is OUT of the medium: hence positive values of "
70 "this function means this BC will act as a SINK, while negative values "
71 "indicate this flux will be a SOURCE. The functional form is useful "
72 "for spatially or temporally varying sinks. Without any use_*, this "
73 "function is measured in kg.m^-2.s^-1 (or J.m^-2.s^-1 for the case "
74 "with only heat and no fluids)");
82 _involves_fluid(isParamValid(
"fluid_phase")),
83 _ph(_involves_fluid ? getParam<unsigned
int>(
"fluid_phase") : 0),
84 _use_mass_fraction(isParamValid(
"mass_fraction_component")),
86 hasMaterialProperty<
std::vector<
std::vector<Real>>>(
"PorousFlow_mass_frac_nodal") &&
87 hasMaterialProperty<
std::vector<
std::vector<
std::vector<Real>>>>(
88 "dPorousFlow_mass_frac_nodal_dvar")),
89 _sp(_use_mass_fraction ? getParam<unsigned
int>(
"mass_fraction_component") : 0),
90 _use_mobility(getParam<bool>(
"use_mobility")),
92 hasMaterialProperty<RealTensorValue>(
"PorousFlow_permeability_qp") &&
93 hasMaterialProperty<
std::vector<RealTensorValue>>(
"dPorousFlow_permeability_qp_dvar") &&
94 hasMaterialProperty<
std::vector<Real>>(
"PorousFlow_fluid_phase_density_nodal") &&
95 hasMaterialProperty<
std::vector<
std::vector<Real>>>(
96 "dPorousFlow_fluid_phase_density_nodal_dvar") &&
97 hasMaterialProperty<
std::vector<Real>>(
"PorousFlow_viscosity_nodal") &&
98 hasMaterialProperty<
std::vector<
std::vector<Real>>>(
"dPorousFlow_viscosity_nodal_dvar")),
99 _use_relperm(getParam<bool>(
"use_relperm")),
100 _has_relperm(hasMaterialProperty<
std::vector<Real>>(
"PorousFlow_relative_permeability_nodal") &&
101 hasMaterialProperty<
std::vector<
std::vector<Real>>>(
102 "dPorousFlow_relative_permeability_nodal_dvar")),
103 _use_enthalpy(getParam<bool>(
"use_enthalpy")),
104 _has_enthalpy(hasMaterialProperty<
std::vector<Real>>(
"PorousFlow_fluid_phase_enthalpy_nodal") &&
105 hasMaterialProperty<
std::vector<
std::vector<Real>>>(
106 "dPorousFlow_fluid_phase_enthalpy_nodal_dvar")),
107 _use_internal_energy(getParam<bool>(
"use_internal_energy")),
108 _has_internal_energy(
109 hasMaterialProperty<
std::vector<Real>>(
"PorousFlow_fluid_phase_internal_energy_nodal") &&
110 hasMaterialProperty<
std::vector<
std::vector<Real>>>(
111 "dPorousFlow_fluid_phase_internal_energy_nodal_dvar")),
112 _use_thermal_conductivity(getParam<bool>(
"use_thermal_conductivity")),
113 _has_thermal_conductivity(
114 hasMaterialProperty<RealTensorValue>(
"PorousFlow_thermal_conductivity_qp") &&
115 hasMaterialProperty<
std::vector<RealTensorValue>>(
116 "dPorousFlow_thermal_conductivity_qp_dvar")),
117 _m_func(getFunction(
"flux_function")),
118 _permeability(_has_mobility
119 ? &getMaterialProperty<RealTensorValue>(
"PorousFlow_permeability_qp")
121 _dpermeability_dvar(_has_mobility ? &getMaterialProperty<
std::vector<RealTensorValue>>(
122 "dPorousFlow_permeability_qp_dvar")
124 _dpermeability_dgradvar(_has_mobility
125 ? &getMaterialProperty<
std::vector<
std::vector<RealTensorValue>>>(
126 "dPorousFlow_permeability_qp_dgradvar")
128 _fluid_density_node(_has_mobility ? &getMaterialProperty<
std::vector<Real>>(
129 "PorousFlow_fluid_phase_density_nodal")
131 _dfluid_density_node_dvar(_has_mobility ? &getMaterialProperty<
std::vector<
std::vector<Real>>>(
132 "dPorousFlow_fluid_phase_density_nodal_dvar")
134 _fluid_viscosity(_has_mobility
135 ? &getMaterialProperty<
std::vector<Real>>(
"PorousFlow_viscosity_nodal")
137 _dfluid_viscosity_dvar(_has_mobility ? &getMaterialProperty<
std::vector<
std::vector<Real>>>(
138 "dPorousFlow_viscosity_nodal_dvar")
140 _relative_permeability(_has_relperm ? &getMaterialProperty<
std::vector<Real>>(
141 "PorousFlow_relative_permeability_nodal")
143 _drelative_permeability_dvar(_has_relperm
144 ? &getMaterialProperty<
std::vector<
std::vector<Real>>>(
145 "dPorousFlow_relative_permeability_nodal_dvar")
147 _mass_fractions(_has_mass_fraction ? &getMaterialProperty<
std::vector<
std::vector<Real>>>(
148 "PorousFlow_mass_frac_nodal")
150 _dmass_fractions_dvar(_has_mass_fraction
151 ? &getMaterialProperty<
std::vector<
std::vector<
std::vector<Real>>>>(
152 "dPorousFlow_mass_frac_nodal_dvar")
154 _enthalpy(_has_enthalpy ? &getMaterialPropertyByName<
std::vector<Real>>(
155 "PorousFlow_fluid_phase_enthalpy_nodal")
157 _denthalpy_dvar(_has_enthalpy ? &getMaterialPropertyByName<
std::vector<
std::vector<Real>>>(
158 "dPorousFlow_fluid_phase_enthalpy_nodal_dvar")
160 _internal_energy(_has_internal_energy ? &getMaterialPropertyByName<
std::vector<Real>>(
161 "PorousFlow_fluid_phase_internal_energy_nodal")
163 _dinternal_energy_dvar(_has_internal_energy
164 ? &getMaterialPropertyByName<
std::vector<
std::vector<Real>>>(
165 "dPorousFlow_fluid_phase_internal_energy_nodal_dvar")
167 _thermal_conductivity(_has_thermal_conductivity ? &getMaterialProperty<RealTensorValue>(
168 "PorousFlow_thermal_conductivity_qp")
170 _dthermal_conductivity_dvar(_has_thermal_conductivity
171 ? &getMaterialProperty<
std::vector<RealTensorValue>>(
172 "dPorousFlow_thermal_conductivity_qp_dvar")
174 _perm_derivs(_dictator.usePermDerivs())
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 mooseError(
"PorousFlowSink: To use_mass_fraction, use_mobility, use_relperm, use_enthalpy or "
187 "use_internal_energy, you must provide a fluid phase number");
191 "The Dictator declares that the maximum fluid component index is ",
193 ", but you have set mass_fraction_component to ",
195 ". Remember that indexing starts at 0. Please be assured that the Dictator has "
196 "noted your error.");
199 mooseError(
"PorousFlowSink: You have used the use_mass_fraction flag, but you have no "
200 "mass_fraction Material");
203 mooseError(
"PorousFlowSink: You have used the use_mobility flag, but there are not the "
204 "required Materials for this");
208 "PorousFlowSink: You have used the use_relperm flag, but you have no relperm Material");
212 "PorousFlowSink: You have used the use_enthalpy flag, but you have no enthalpy Material");
215 mooseError(
"PorousFlowSink: You have used the use_internal_energy flag, but you have no "
216 "internal_energy Material");
219 mooseError(
"PorousFlowSink: You have used the use_thermal_conductivity flag, but you have no "
220 "thermal_conductivity Material");
231 flux *= (*_fluid_density_node)[
_i][
_ph] * k / (*_fluid_viscosity)[
_i][
_ph];
234 flux *= (*_relative_permeability)[
_i][
_ph];
236 flux *= (*_mass_fractions)[
_i][
_ph][
_sp];
238 flux *= (*_enthalpy)[
_i][
_ph];
240 flux *= (*_internal_energy)[
_i][
_ph];
279 const Real mob = (*_fluid_density_node)[
_i][
_ph] * k / (*_fluid_viscosity)[
_i][
_ph];
284 RealTensorValue ktprime = (*_dpermeability_dvar)[
_qp][pvar] *
_phi[
_j][
_qp];
289 mobprime += (*_fluid_density_node)[
_i][
_ph] * kprime / (*_fluid_viscosity)[
_i][
_ph];
295 : (*_dfluid_density_node_dvar)[
_i][
_ph][pvar] * k / (*_fluid_viscosity)[
_i][
_ph] -
296 (*_fluid_density_node)[
_i][
_ph] * k * (*_dfluid_viscosity_dvar)[
_i][
_ph][pvar] /
298 deriv = mob * deriv + mobprime * flux;
303 const Real relperm_prime = (
_i !=
_j ? 0.0 : (*_drelative_permeability_dvar)[
_i][
_ph][pvar]);
304 deriv = (*_relative_permeability)[
_i][
_ph] * deriv + relperm_prime * flux;
305 flux *= (*_relative_permeability)[
_i][
_ph];
309 const Real mf_prime = (
_i !=
_j ? 0.0 : (*_dmass_fractions_dvar)[
_i][
_ph][
_sp][pvar]);
310 deriv = (*_mass_fractions)[
_i][
_ph][
_sp] * deriv + mf_prime * flux;
311 flux *= (*_mass_fractions)[
_i][
_ph][
_sp];
315 const Real en_prime = (
_i !=
_j ? 0.0 : (*_denthalpy_dvar)[
_i][
_ph][pvar]);
316 deriv = (*_enthalpy)[
_i][
_ph] * deriv + en_prime * flux;
317 flux *= (*_enthalpy)[
_i][
_ph];
321 const Real ie_prime = (
_i !=
_j ? 0.0 : (*_dinternal_energy_dvar)[
_i][
_ph][pvar]);
322 deriv = (*_internal_energy)[
_i][
_ph] * deriv + ie_prime * flux;
323 flux *= (*_internal_energy)[
_i][
_ph];
328 const RealTensorValue tctprime = (*_dthermal_conductivity_dvar)[
_qp][pvar] *
_phi[
_j][
_qp];
330 deriv = tc * deriv + tcprime * flux;
registerMooseObject("PorousFlowApp", PorousFlowSink)
void ErrorVector unsigned int
virtual Real value(Real t, const Point &p) const
const MooseArray< Point > & _q_point
const VariablePhiGradient & _grad_phi
static InputParameters validParams()
const VariablePhiValue & _phi
const MooseArray< Point > & _normals
const VariableTestValue & _test
void paramError(const std::string ¶m, Args... args) const
void mooseError(Args &&... args) const
unsigned int number() const
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.
Applies a flux sink to a boundary.
virtual Real dmultiplier_dvar(unsigned int pvar) const
d(multiplier)/d(Porous flow variable pvar)
const MaterialProperty< std::vector< Real > > *const _fluid_viscosity
Viscosity of each component in each phase.
const bool _has_mobility
Whether there are Materials that can form "mobility". This is just for error checking.
const bool _use_mass_fraction
Whether the flux will be multiplied by the mass fraction.
const unsigned int _sp
The component number (only used if _use_mass_fraction==true)
virtual Real computeQpOffDiagJacobian(unsigned int jvar) override
const bool _use_thermal_conductivity
Whether to multiply the sink flux by thermal_conductivity.
const bool _perm_derivs
Flag to check whether permeabiity derivatives are non-zero.
const bool _has_thermal_conductivity
Whether there is an "thermal_conductivity" Material. This is just for error checking.
const bool _use_relperm
Whether to multiply the sink flux by relative permeability.
const PorousFlowDictator & _dictator
PorousFlowDictator UserObject.
const bool _involves_fluid
Whether this BC involves fluid (whether the user has supplied a fluid phase number)
const bool _use_internal_energy
Whether to multiply the sink flux by internal_energy.
const bool _use_mobility
Whether to multiply the sink flux by permeability*density/viscosity.
const bool _has_enthalpy
Whether there is an "enthalpy" Material. This is just for error checking.
const bool _use_enthalpy
Whether to multiply the sink flux by enthalpy.
virtual Real computeQpResidual() override
const Function & _m_func
The flux.
const bool _has_mass_fraction
Whether there is a "mass_fraction" Material. This is just for error checking.
virtual Real multiplier() const
The flux gets multiplied by this quantity.
const unsigned int _ph
The phase number.
PorousFlowSink(const InputParameters ¶meters)
const MaterialProperty< std::vector< std::vector< RealTensorValue > > > *const _dpermeability_dgradvar
d(Permeability)/d(grad(PorousFlow variable))
Real jac(unsigned int jvar) const
Derivative of residual with respect to the jvar variable.
virtual Real computeQpJacobian() override
static InputParameters validParams()
const bool _has_internal_energy
Whether there is an "internal_energy" Material. This is just for error checking.
const bool _has_relperm
Whether there is a "relperm" Material. This is just for error checking.
static constexpr std::size_t dim