13#include "libmesh/string_to_enum.h"
14#include "libmesh/quadrature.h"
23 "PorousFlowDictator",
"The UserObject that holds the list of PorousFlow variable names");
25 "Gravitational acceleration vector downwards (m/s^2)");
26 MooseEnum flux_type_enum(
"fluid heat",
"fluid");
30 "The type of boundary condition to apply. 'fluid' means this boundary condition will allow "
31 "a fluid component to flow freely from the boundary. 'heat' means this boundary condition "
32 "will allow heat energy to flow freely from the boundary");
34 "mass_fraction_component",
36 "The index corresponding to a fluid "
37 "component. If supplied, the residual contribution will be "
38 "multiplied by the mass fraction, corresponding to allowing the "
39 "given mass fraction to flow freely from the boundary. This is ignored if flux_type = heat");
40 params.
addParam<
bool>(
"multiply_by_density",
42 "If true, this BC represents mass flux. If false, it represents volume "
43 "flux. User input of this flag is ignored if flux_type = heat as "
44 "multiply_by_density should always be true in that case");
48 "If true, the Darcy flux will include the relative permeability. If false, the relative "
49 "permeability will not be used, which must only be used for fully-saturated situations "
50 "where there is no notion of relative permeability");
54 "Multiply the flux by this number. This is mainly used for testing purposes");
57 "Applies an 'outflow' boundary condition, which allows fluid components or heat energy to "
58 "flow freely out of the boundary as if it weren't there. This is fully upwinded");
65 _num_phases(_dictator.numPhases()),
66 _perm_derivs(_dictator.usePermDerivs()),
68 _sp(getParam<unsigned>(
"mass_fraction_component")),
70 _flux_type ==
FluxTypeChoiceEnum::FLUID ? getParam<bool>(
"multiply_by_density") : true),
71 _include_relperm(getParam<bool>(
"include_relperm")),
72 _gravity(getParam<RealVectorValue>(
"gravity")),
73 _multiplier(getParam<Real>(
"multiplier")),
74 _grad_p(getMaterialProperty<
std::vector<RealGradient>>(
"PorousFlow_grad_porepressure_qp")),
75 _dgrad_p_dgrad_var(getMaterialProperty<
std::vector<
std::vector<Real>>>(
76 "dPorousFlow_grad_porepressure_qp_dgradvar")),
77 _dgrad_p_dvar(getMaterialProperty<
std::vector<
std::vector<RealGradient>>>(
78 "dPorousFlow_grad_porepressure_qp_dvar")),
79 _fluid_density_qp(getMaterialProperty<
std::vector<Real>>(
"PorousFlow_fluid_phase_density_qp")),
80 _dfluid_density_qp_dvar(getMaterialProperty<
std::vector<
std::vector<Real>>>(
81 "dPorousFlow_fluid_phase_density_qp_dvar")),
82 _permeability(getMaterialProperty<RealTensorValue>(
"PorousFlow_permeability_qp")),
84 getMaterialProperty<
std::vector<RealTensorValue>>(
"dPorousFlow_permeability_qp_dvar")),
85 _dpermeability_dgradvar(getMaterialProperty<
std::vector<
std::vector<RealTensorValue>>>(
86 "dPorousFlow_permeability_qp_dgradvar")),
87 _fluid_viscosity(getMaterialProperty<
std::vector<Real>>(
"PorousFlow_viscosity_nodal")),
88 _dfluid_viscosity_dvar(
89 getMaterialProperty<
std::vector<
std::vector<Real>>>(
"dPorousFlow_viscosity_nodal_dvar")),
91 _has_density(hasMaterialProperty<
std::vector<Real>>(
"PorousFlow_fluid_phase_density_nodal") &&
92 hasMaterialProperty<
std::vector<
std::vector<Real>>>(
93 "dPorousFlow_fluid_phase_density_nodal_dvar")),
95 hasMaterialProperty<
std::vector<
std::vector<Real>>>(
"PorousFlow_mass_frac_nodal") &&
96 hasMaterialProperty<
std::vector<
std::vector<
std::vector<Real>>>>(
97 "dPorousFlow_mass_frac_nodal_dvar")),
98 _has_relperm(hasMaterialProperty<
std::vector<Real>>(
"PorousFlow_relative_permeability_nodal") &&
99 hasMaterialProperty<
std::vector<
std::vector<Real>>>(
100 "dPorousFlow_relative_permeability_nodal_dvar")),
101 _has_enthalpy(hasMaterialProperty<
std::vector<Real>>(
"PorousFlow_fluid_phase_enthalpy_nodal") &&
102 hasMaterialProperty<
std::vector<
std::vector<Real>>>(
103 "dPorousFlow_fluid_phase_enthalpy_nodal_dvar")),
104 _has_thermal_conductivity(
105 hasMaterialProperty<RealTensorValue>(
"PorousFlow_thermal_conductivity_qp") &&
106 hasMaterialProperty<
std::vector<RealTensorValue>>(
107 "dPorousFlow_thermal_conductivity_qp_dvar")),
108 _has_t(hasMaterialProperty<RealGradient>(
"PorousFlow_grad_temperature_qp") &&
109 hasMaterialProperty<
std::vector<RealGradient>>(
"dPorousFlow_grad_temperature_qp_dvar") &&
110 hasMaterialProperty<
std::vector<Real>>(
"dPorousFlow_grad_temperature_qp_dgradvar")),
112 _fluid_density_node(_has_density ? &getMaterialProperty<
std::vector<Real>>(
113 "PorousFlow_fluid_phase_density_nodal")
115 _dfluid_density_node_dvar(_has_density ? &getMaterialProperty<
std::vector<
std::vector<Real>>>(
116 "dPorousFlow_fluid_phase_density_nodal_dvar")
118 _relative_permeability(_has_relperm ? &getMaterialProperty<
std::vector<Real>>(
119 "PorousFlow_relative_permeability_nodal")
121 _drelative_permeability_dvar(_has_relperm
122 ? &getMaterialProperty<
std::vector<
std::vector<Real>>>(
123 "dPorousFlow_relative_permeability_nodal_dvar")
125 _mass_fractions(_has_mass_fraction ? &getMaterialProperty<
std::vector<
std::vector<Real>>>(
126 "PorousFlow_mass_frac_nodal")
128 _dmass_fractions_dvar(_has_mass_fraction
129 ? &getMaterialProperty<
std::vector<
std::vector<
std::vector<Real>>>>(
130 "dPorousFlow_mass_frac_nodal_dvar")
132 _enthalpy(_has_enthalpy ? &getMaterialPropertyByName<
std::vector<Real>>(
133 "PorousFlow_fluid_phase_enthalpy_nodal")
135 _denthalpy_dvar(_has_enthalpy ? &getMaterialPropertyByName<
std::vector<
std::vector<Real>>>(
136 "dPorousFlow_fluid_phase_enthalpy_nodal_dvar")
138 _thermal_conductivity(_has_thermal_conductivity ? &getMaterialProperty<RealTensorValue>(
139 "PorousFlow_thermal_conductivity_qp")
141 _dthermal_conductivity_dvar(_has_thermal_conductivity
142 ? &getMaterialProperty<
std::vector<RealTensorValue>>(
143 "dPorousFlow_thermal_conductivity_qp_dvar")
145 _grad_t(_has_t ? &getMaterialProperty<RealGradient>(
"PorousFlow_grad_temperature_qp")
147 _dgrad_t_dvar(_has_t ? &getMaterialProperty<
std::vector<RealGradient>>(
148 "dPorousFlow_grad_temperature_qp_dvar")
151 _has_t ? &getMaterialProperty<
std::vector<Real>>(
"dPorousFlow_grad_temperature_qp_dgradvar")
156 "The Dictator declares that the maximum fluid component index is ",
158 ", but you have set mass_fraction_component to ",
160 ". Remember that indexing starts at 0. Please be assured that the Dictator has "
161 "noted your error.");
164 mooseError(
"PorousFlowOutflowBC: You requested to multiply_by_density, but you have no nodal "
165 "fluid density Material");
167 mooseError(
"PorousFlowOutflowBC: You requested to include the relative permeability, but you "
168 "have no nodal relative permeability Material");
171 "PorousFlowOutflowBC: For flux_type = fluid, you need a nodal mass-fraction Material");
174 "PorousFlowOutflowBC: For flux_type = heat, you need a nodal fluid enthalpy Material");
177 "PorousFlowOutflowBC: For flux_type = heat, you need a thermal conductivity Material");
179 mooseError(
"PorousFlowOutflowBC: For flux_type = heat, you need a temperature Material");
185 Real advective_term = 0.0;
192 const Real conduction_term = -
_normals[
_qp] * ((*_thermal_conductivity)[
_qp] * (*_grad_t)[
_qp]);
221 Real advective_term_prime = 0.0;
242 const Real dar =
darcy(ph);
249 const Real densityprime = (*_dfluid_density_node_dvar)[
_i][ph][pvar];
250 mobprime = densityprime * mob + (*_fluid_density_node)[
_i][ph] * mobprime;
251 mob *= (*_fluid_density_node)[
_i][ph];
255 const Real relpermprime = (*_drelative_permeability_dvar)[
_i][ph][pvar];
256 mobprime = relpermprime * mob + (*_relative_permeability)[
_i][ph] * mobprime;
257 mob *= (*_relative_permeability)[
_i][ph];
261 const Real preprime =
263 : (*_denthalpy_dvar)[
_i][ph][pvar]);
265 advective_term_prime -= preprime * mob * dar + pre * mobprime * dar + pre * mob * darcyprime;
271 const Real conduction_term_prime =
273 ((*_dthermal_conductivity_dvar)[
_qp][pvar] * (*_grad_t)[
_qp] +
274 (*_thermal_conductivity)[
_qp] * (*_dgrad_t_dvar)[
_qp][pvar]) *
299 : (*_enthalpy)[
_i][ph]);
registerMooseObject("PorousFlowApp", PorousFlowOutflowBC)
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 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 to a boundary such that fluid or heat will flow freely out of the boundary.
const MaterialProperty< std::vector< Real > > *const _fluid_density_node
Fluid density for each phase (at the node)
PorousFlowOutflowBC(const InputParameters ¶meters)
const bool _perm_derivs
Flag indicating whether to include derivatives of the permeability in the Jacobian.
virtual Real computeQpOffDiagJacobian(unsigned int jvar) override
const Real _multiplier
Multiply the flux by this quantity. This is mainly used for testing purposes, for instance,...
Real prefactor(unsigned ph) const
Either mass_fraction or enthalpy, depending on _flux_type.
static InputParameters validParams()
const MaterialProperty< std::vector< std::vector< Real > > > & _dfluid_viscosity_dvar
Derivative of the fluid viscosity for each phase wrt PorousFlow variables.
const MaterialProperty< std::vector< Real > > *const _relative_permeability
Relative permeability of each phase.
const MaterialProperty< RealTensorValue > & _permeability
Permeability of porous material.
const unsigned _num_phases
Number of phases in the simulation.
const MaterialProperty< std::vector< RealGradient > > & _grad_p
Gradient of the pore pressure in each phase.
const bool _has_enthalpy
Whether there is an enthalpy Material.
Real jac(unsigned int jvar) const
Derivative of residual with respect to the jvar variable.
const bool _has_t
Whether there is a grad_temp Material.
const bool _include_relperm
Whether to multiply the Darcy flux by the relative permeability.
const bool _has_mass_fraction
Whether there is a mass_frac_nodal Material.
const MaterialProperty< std::vector< std::vector< Real > > > & _dfluid_density_qp_dvar
Derivative of the fluid density for each phase wrt PorousFlow variables (at the qp)
const MaterialProperty< RealTensorValue > *const _thermal_conductivity
Thermal_Conductivity of porous material.
Real mobility(unsigned ph) const
Mobility contribution to the outflowBC.
const RealVectorValue _gravity
Gravitational acceleration.
virtual Real computeQpJacobian() override
Real darcy(unsigned ph) const
Darcy contribution to the outflowBC.
const unsigned int _sp
The fluid component number (only used if _flux_type==FLUID))
FluxTypeChoiceEnum
Indicates the type of flux that this BC will apply.
const MaterialProperty< std::vector< std::vector< RealGradient > > > & _dgrad_p_dvar
Derivative of Grad porepressure in each phase wrt PorousFlow variables.
const MaterialProperty< std::vector< std::vector< Real > > > *const _mass_fractions
Mass fraction of each component in each phase.
const MaterialProperty< std::vector< std::vector< RealTensorValue > > > & _dpermeability_dgradvar
d(permeabiity)/d(grad(PorousFlow variable))
const MaterialProperty< std::vector< Real > > & _fluid_density_qp
Fluid density for each phase (at the qp)
const bool _has_thermal_conductivity
Whether there is a thermal_conductivity_qp Material.
const MaterialProperty< std::vector< RealTensorValue > > & _dpermeability_dvar
d(permeabiity)/d(PorousFlow variable)
virtual Real computeQpResidual() override
const MaterialProperty< std::vector< std::vector< Real > > > & _dgrad_p_dgrad_var
Derivative of Grad porepressure in each phase wrt grad(PorousFlow variables)
const bool _has_relperm
Whether there is a relative_permeability_nodal Material.
const PorousFlowDictator & _dictator
PorousFlowDictator UserObject.
const MaterialProperty< std::vector< Real > > & _fluid_viscosity
Viscosity of each phase.
const bool _has_density
Whether there is a fluid_phase_density_nodal Material.
const bool _multiply_by_density
Whether to multiply the Darcy flux by the fluid density. This is automatically set to true if _flux_t...
enum PorousFlowOutflowBC::FluxTypeChoiceEnum _flux_type
static constexpr std::size_t dim