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")),
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")),
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")),
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") &&
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
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;
221 Real advective_term_prime = 0.0;
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]) *
const VariableTestValue & _test
Real jac(unsigned int jvar) const
Derivative of residual with respect to the jvar variable.
bool notPorousFlowVariable(unsigned int moose_var_num) const
Returns true if moose_var_num is not a porous flow variabe.
const MooseArray< Point > & _normals
const MaterialProperty< std::vector< std::vector< RealTensorValue > > > & _dpermeability_dgradvar
d(permeabiity)/d(grad(PorousFlow variable))
unsigned int number() const
const bool _perm_derivs
Flag indicating whether to include derivatives of the permeability in the Jacobian.
const MaterialProperty< std::vector< std::vector< Real > > > & _dgrad_p_dgrad_var
Derivative of Grad porepressure in each phase wrt grad(PorousFlow variables)
const MaterialProperty< std::vector< Real > > *const _enthalpy
Enthalpy of each phase.
const MaterialProperty< std::vector< std::vector< Real > > > *const _mass_fractions
Mass fraction of each component in each phase.
const unsigned _num_phases
Number of phases in the simulation.
unsigned int numComponents() const
The number of fluid components.
static InputParameters validParams()
static constexpr std::size_t dim
const PorousFlowDictator & _dictator
PorousFlowDictator UserObject.
const MaterialProperty< std::vector< Real > > & _fluid_density_qp
Fluid density for each phase (at the qp)
virtual Real computeQpOffDiagJacobian(unsigned int jvar) override
const VariablePhiValue & _phi
enum PorousFlowOutflowBC::FluxTypeChoiceEnum _flux_type
virtual Real computeQpJacobian() override
const bool _has_mass_fraction
Whether there is a mass_frac_nodal Material.
Applies a flux to a boundary such that fluid or heat will flow freely out of the boundary.
const VariablePhiGradient & _grad_phi
const RealVectorValue _gravity
Gravitational acceleration.
TensorValue< Real > RealTensorValue
const bool _has_thermal_conductivity
Whether there is a thermal_conductivity_qp Material.
const bool _include_relperm
Whether to multiply the Darcy flux by the relative permeability.
PorousFlowOutflowBC(const InputParameters ¶meters)
FluxTypeChoiceEnum
Indicates the type of flux that this BC will apply.
void paramError(const std::string ¶m, Args... args) const
const MaterialProperty< std::vector< RealTensorValue > > & _dpermeability_dvar
d(permeabiity)/d(PorousFlow variable)
const bool _has_t
Whether there is a grad_temp Material.
const MaterialProperty< std::vector< Real > > *const _fluid_density_node
Fluid density for each phase (at the node)
Real darcy(unsigned ph) const
Darcy contribution to the outflowBC.
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) ...
static InputParameters validParams()
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const bool _has_density
Whether there is a fluid_phase_density_nodal Material.
Real prefactor(unsigned ph) const
Either mass_fraction or enthalpy, depending on _flux_type.
This holds maps between the nonlinear variables used in a PorousFlow simulation and the variable numb...
const MaterialProperty< std::vector< std::vector< Real > > > & _dfluid_viscosity_dvar
Derivative of the fluid viscosity for each phase wrt PorousFlow variables.
IntRange< T > make_range(T beg, T end)
void mooseError(Args &&... args) const
const Real _multiplier
Multiply the flux by this quantity. This is mainly used for testing purposes, for instance...
const MaterialProperty< std::vector< Real > > & _fluid_viscosity
Viscosity of each phase.
const MaterialProperty< std::vector< std::vector< RealGradient > > > & _dgrad_p_dvar
Derivative of Grad porepressure in each phase wrt PorousFlow variables.
unsigned int porousFlowVariableNum(unsigned int moose_var_num) const
The PorousFlow variable number.
const bool _has_enthalpy
Whether there is an enthalpy Material.
const bool _has_relperm
Whether there is a relative_permeability_nodal Material.
const MaterialProperty< RealTensorValue > & _permeability
Permeability of porous material.
const unsigned int _sp
The fluid component number (only used if _flux_type==FLUID))
const MaterialProperty< RealTensorValue > *const _thermal_conductivity
Thermal_Conductivity of porous material.
registerMooseObject("PorousFlowApp", PorousFlowOutflowBC)
Real mobility(unsigned ph) const
Mobility contribution to the outflowBC.
virtual Real computeQpResidual() override
const bool _multiply_by_density
Whether to multiply the Darcy flux by the fluid density. This is automatically set to true if _flux_t...
const MaterialProperty< std::vector< RealGradient > > & _grad_p
Gradient of the pore pressure in each phase.