12 #include "MooseVariable.h"
14 #include "libmesh/quadrature.h"
24 InputParameters params = validParams<IntegratedBC>();
25 params.addRequiredParam<UserObjectName>(
26 "PorousFlowDictator",
"The UserObject that holds the list of PorousFlow variable names");
27 params.addParam<
unsigned int>(
"fluid_phase",
28 "If supplied, then this BC will potentially be a function of fluid "
29 "pressure, and you can use mass_fraction_component, use_mobility, "
30 "use_relperm, use_enthalpy and use_energy. If not supplied, then "
31 "this BC can only be a function of temperature");
32 params.addParam<
unsigned int>(
"mass_fraction_component",
33 "The index corresponding to a fluid "
34 "component. If supplied, the flux will "
35 "be multiplied by the nodal mass "
36 "fraction for the component");
37 params.addParam<
bool>(
"use_mobility",
39 "If true, then fluxes are multiplied by "
40 "(density*permeability_nn/viscosity), where the "
41 "'_nn' indicates the component normal to the "
42 "boundary. In this case bare_flux is measured in "
43 "Pa.m^-1. This can be used in conjunction with "
45 params.addParam<
bool>(
"use_relperm",
47 "If true, then fluxes are multiplied by relative "
48 "permeability. This can be used in conjunction with "
50 params.addParam<
bool>(
"use_enthalpy",
52 "If true, then fluxes are multiplied by enthalpy. "
53 "In this case bare_flux is measured in kg.m^-2.s^-1 "
54 "/ (J.kg). This can be used in conjunction with "
56 params.addParam<
bool>(
"use_internal_energy",
58 "If true, then fluxes are multiplied by fluid internal energy. "
59 " In this case bare_flux is measured in kg.m^-2.s^-1 / (J.kg). "
60 " This can be used in conjunction with other use_*");
61 params.addParam<
bool>(
"use_thermal_conductivity",
63 "If true, then fluxes are multiplied by "
64 "thermal conductivity projected onto "
65 "the normal direction. This can be "
66 "used in conjunction with other use_*");
67 params.addParam<FunctionName>(
70 "The flux. The flux is OUT of the medium: hence positive values of "
71 "this function means this BC will act as a SINK, while negative values "
72 "indicate this flux will be a SOURCE. The functional form is useful "
73 "for spatially or temporally varying sinks. Without any use_*, this "
74 "function is measured in kg.m^-2.s^-1 (or J.m^-2.s^-1 for the case "
75 "with only heat and no fluids)");
76 params.addClassDescription(
"Applies a flux sink to a boundary.");
81 : IntegratedBC(parameters),
83 _involves_fluid(isParamValid(
"fluid_phase")),
84 _ph(_involves_fluid ? getParam<unsigned int>(
"fluid_phase") : 0),
85 _use_mass_fraction(isParamValid(
"mass_fraction_component")),
87 hasMaterialProperty<std::vector<std::vector<Real>>>(
"PorousFlow_mass_frac_nodal") &&
88 hasMaterialProperty<std::vector<std::vector<std::vector<Real>>>>(
89 "dPorousFlow_mass_frac_nodal_dvar")),
90 _sp(_use_mass_fraction ? getParam<unsigned int>(
"mass_fraction_component") : 0),
91 _use_mobility(getParam<bool>(
"use_mobility")),
93 hasMaterialProperty<RealTensorValue>(
"PorousFlow_permeability_qp") &&
94 hasMaterialProperty<std::vector<RealTensorValue>>(
"dPorousFlow_permeability_qp_dvar") &&
95 hasMaterialProperty<std::vector<Real>>(
"PorousFlow_fluid_phase_density_nodal") &&
96 hasMaterialProperty<std::vector<std::vector<Real>>>(
97 "dPorousFlow_fluid_phase_density_nodal_dvar") &&
98 hasMaterialProperty<std::vector<Real>>(
"PorousFlow_viscosity_nodal") &&
99 hasMaterialProperty<std::vector<std::vector<Real>>>(
"dPorousFlow_viscosity_nodal_dvar")),
100 _use_relperm(getParam<bool>(
"use_relperm")),
101 _has_relperm(hasMaterialProperty<std::vector<Real>>(
"PorousFlow_relative_permeability_nodal") &&
102 hasMaterialProperty<std::vector<std::vector<Real>>>(
103 "dPorousFlow_relative_permeability_nodal_dvar")),
104 _use_enthalpy(getParam<bool>(
"use_enthalpy")),
105 _has_enthalpy(hasMaterialProperty<std::vector<Real>>(
"PorousFlow_fluid_phase_enthalpy_nodal") &&
106 hasMaterialProperty<std::vector<std::vector<Real>>>(
107 "dPorousFlow_fluid_phase_enthalpy_nodal_dvar")),
108 _use_internal_energy(getParam<bool>(
"use_internal_energy")),
109 _has_internal_energy(
110 hasMaterialProperty<std::vector<Real>>(
"PorousFlow_fluid_phase_internal_energy_nodal") &&
111 hasMaterialProperty<std::vector<std::vector<Real>>>(
112 "dPorousFlow_fluid_phase_internal_energy_nodal_dvar")),
113 _use_thermal_conductivity(getParam<bool>(
"use_thermal_conductivity")),
114 _has_thermal_conductivity(
115 hasMaterialProperty<RealTensorValue>(
"PorousFlow_thermal_conductivity_qp") &&
116 hasMaterialProperty<std::vector<RealTensorValue>>(
117 "dPorousFlow_thermal_conductivity_qp_dvar")),
118 _m_func(getFunction(
"flux_function")),
119 _permeability(_has_mobility
120 ? &getMaterialProperty<RealTensorValue>(
"PorousFlow_permeability_qp")
122 _dpermeability_dvar(_has_mobility ? &getMaterialProperty<std::vector<RealTensorValue>>(
123 "dPorousFlow_permeability_qp_dvar")
125 _dpermeability_dgradvar(_has_mobility
126 ? &getMaterialProperty<std::vector<std::vector<RealTensorValue>>>(
127 "dPorousFlow_permeability_qp_dgradvar")
129 _fluid_density_node(_has_mobility ? &getMaterialProperty<std::vector<Real>>(
130 "PorousFlow_fluid_phase_density_nodal")
132 _dfluid_density_node_dvar(_has_mobility ? &getMaterialProperty<std::vector<std::vector<Real>>>(
133 "dPorousFlow_fluid_phase_density_nodal_dvar")
135 _fluid_viscosity(_has_mobility
136 ? &getMaterialProperty<std::vector<Real>>(
"PorousFlow_viscosity_nodal")
138 _dfluid_viscosity_dvar(_has_mobility ? &getMaterialProperty<std::vector<std::vector<Real>>>(
139 "dPorousFlow_viscosity_nodal_dvar")
141 _relative_permeability(_has_relperm ? &getMaterialProperty<std::vector<Real>>(
142 "PorousFlow_relative_permeability_nodal")
144 _drelative_permeability_dvar(_has_relperm
145 ? &getMaterialProperty<std::vector<std::vector<Real>>>(
146 "dPorousFlow_relative_permeability_nodal_dvar")
148 _mass_fractions(_has_mass_fraction ? &getMaterialProperty<std::vector<std::vector<Real>>>(
149 "PorousFlow_mass_frac_nodal")
151 _dmass_fractions_dvar(_has_mass_fraction
152 ? &getMaterialProperty<std::vector<std::vector<std::vector<Real>>>>(
153 "dPorousFlow_mass_frac_nodal_dvar")
155 _enthalpy(_has_enthalpy ? &getMaterialPropertyByName<std::vector<Real>>(
156 "PorousFlow_fluid_phase_enthalpy_nodal")
158 _denthalpy_dvar(_has_enthalpy ? &getMaterialPropertyByName<std::vector<std::vector<Real>>>(
159 "dPorousFlow_fluid_phase_enthalpy_nodal_dvar")
161 _internal_energy(_has_internal_energy ? &getMaterialPropertyByName<std::vector<Real>>(
162 "PorousFlow_fluid_phase_internal_energy_nodal")
164 _dinternal_energy_dvar(_has_internal_energy
165 ? &getMaterialPropertyByName<std::vector<std::vector<Real>>>(
166 "dPorousFlow_fluid_phase_internal_energy_nodal_dvar")
168 _thermal_conductivity(_has_thermal_conductivity ? &getMaterialProperty<RealTensorValue>(
169 "PorousFlow_thermal_conductivity_qp")
171 _dthermal_conductivity_dvar(_has_thermal_conductivity
172 ? &getMaterialProperty<std::vector<RealTensorValue>>(
173 "dPorousFlow_thermal_conductivity_qp_dvar")
175 _perm_derivs(_dictator.usePermDerivs())
178 paramError(
"fluid_phase",
179 "The Dictator proclaims that the maximum phase index in this simulation is ",
181 " whereas you have used ",
183 ". Remember that indexing starts at 0. You must try harder.");
187 mooseError(
"PorousFlowSink: To use_mass_fraction, use_mobility, use_relperm, use_enthalpy or "
188 "use_internal_energy, you must provide a fluid phase number");
191 paramError(
"mass_fraction_component",
192 "The Dictator declares that the maximum fluid component index is ",
194 ", but you have set mass_fraction_component to ",
196 ". Remember that indexing starts at 0. Please be assured that the Dictator has "
197 "noted your error.");
200 mooseError(
"PorousFlowSink: You have used the use_mass_fraction flag, but you have no "
201 "mass_fraction Material");
204 mooseError(
"PorousFlowSink: You have used the use_mobility flag, but there are not the "
205 "required Materials for this");
209 "PorousFlowSink: You have used the use_relperm flag, but you have no relperm Material");
213 "PorousFlowSink: You have used the use_enthalpy flag, but you have no enthalpy Material");
216 mooseError(
"PorousFlowSink: You have used the use_internal_energy flag, but you have no "
217 "internal_energy Material");
220 mooseError(
"PorousFlowSink: You have used the use_thermal_conductivity flag, but you have no "
221 "thermal_conductivity Material");
231 ((*_permeability)[_qp] * _normals[_qp]) * _normals[_qp];
232 flux *= (*_fluid_density_node)[_i][
_ph] * k / (*_fluid_viscosity)[_i][
_ph];
235 flux *= (*_relative_permeability)[_i][
_ph];
237 flux *= (*_mass_fractions)[_i][
_ph][
_sp];
239 flux *= (*_enthalpy)[_i][
_ph];
241 flux *= (*_internal_energy)[_i][
_ph];
243 flux *= ((*_thermal_conductivity)[_qp] * _normals[_qp]) *
252 return jac(_var.number());
279 const Real k = ((*_permeability)[_qp] * _normals[_qp]) * _normals[_qp];
280 const Real mob = (*_fluid_density_node)[_i][
_ph] * k / (*_fluid_viscosity)[_i][
_ph];
285 RealTensorValue ktprime = (*_dpermeability_dvar)[_qp][pvar] * _phi[_j][_qp];
286 for (
unsigned int i = 0; i < LIBMESH_DIM; ++i)
288 const Real kprime = (ktprime * _normals[_qp]) * _normals[_qp];
290 mobprime += (*_fluid_density_node)[_i][
_ph] * kprime / (*_fluid_viscosity)[_i][
_ph];
296 : (*_dfluid_density_node_dvar)[_i][
_ph][pvar] * k / (*_fluid_viscosity)[_i][
_ph] -
297 (*_fluid_density_node)[_i][
_ph] * k * (*_dfluid_viscosity_dvar)[_i][
_ph][pvar] /
299 deriv = mob * deriv + mobprime * flux;
304 const Real relperm_prime = (_i != _j ? 0.0 : (*_drelative_permeability_dvar)[_i][
_ph][pvar]);
305 deriv = (*_relative_permeability)[_i][
_ph] * deriv + relperm_prime * flux;
306 flux *= (*_relative_permeability)[_i][
_ph];
310 const Real mf_prime = (_i != _j ? 0.0 : (*_dmass_fractions_dvar)[_i][
_ph][
_sp][pvar]);
311 deriv = (*_mass_fractions)[_i][
_ph][
_sp] * deriv + mf_prime * flux;
312 flux *= (*_mass_fractions)[_i][
_ph][
_sp];
316 const Real en_prime = (_i != _j ? 0.0 : (*_denthalpy_dvar)[_i][
_ph][pvar]);
317 deriv = (*_enthalpy)[_i][
_ph] * deriv + en_prime * flux;
318 flux *= (*_enthalpy)[_i][
_ph];
322 const Real ie_prime = (_i != _j ? 0.0 : (*_dinternal_energy_dvar)[_i][
_ph][pvar]);
323 deriv = (*_internal_energy)[_i][
_ph] * deriv + ie_prime * flux;
324 flux *= (*_internal_energy)[_i][
_ph];
328 const Real tc = ((*_thermal_conductivity)[_qp] * _normals[_qp]) * _normals[_qp];
329 const RealTensorValue tctprime = (*_dthermal_conductivity_dvar)[_qp][pvar] * _phi[_j][_qp];
330 const Real tcprime = (tctprime * _normals[_qp]) * _normals[_qp];
331 deriv = tc * deriv + tcprime * flux;
340 return _m_func.value(_t, _q_point[_qp]);