14 #include "MooseVariable.h"
15 #include "SystemBase.h"
17 #include "libmesh/quadrature.h"
25 InputParameters params = validParams<Kernel>();
26 params.addRequiredParam<std::vector<UserObjectName>>(
27 "relperm_UO",
"List of names of user objects that define relative permeability");
28 params.addRequiredParam<std::vector<UserObjectName>>(
30 "List of name of user objects that define effective saturation as a function of "
32 params.addRequiredParam<std::vector<UserObjectName>>(
33 "density_UO",
"List of names of user objects that define the fluid density");
34 params.addRequiredParam<UserObjectName>(
35 "richardsVarNames_UO",
"The UserObject that holds the list of Richards variable names.");
42 _num_p(_richards_name_UO.num_v()),
43 _pvar(_richards_name_UO.richards_var_num(_var.number())),
45 getParam<std::vector<UserObjectName>>(
"density_UO")[_pvar])),
47 getUserObjectByName<
RichardsSeff>(getParam<std::vector<UserObjectName>>(
"seff_UO")[_pvar])),
49 getParam<std::vector<UserObjectName>>(
"relperm_UO")[_pvar])),
50 _viscosity(getMaterialProperty<std::vector<Real>>(
"viscosity")),
51 _flux_no_mob(getMaterialProperty<std::vector<RealVectorValue>>(
"flux_no_mob")),
53 getMaterialProperty<std::vector<std::vector<RealVectorValue>>>(
"dflux_no_mob_dv")),
55 getMaterialProperty<std::vector<std::vector<RealTensorValue>>>(
"dflux_no_mob_dgradv")),
61 for (
unsigned int pnum = 0; pnum <
_num_p; ++pnum)
74 std::vector<Real> dseff_dp;
80 for (
unsigned int nodenum = 0; nodenum <
_num_nodes; ++nodenum)
96 for (
unsigned int ph = 0; ph <
_num_p; ++ph)
120 upwind(
false,
true, jvar.number());
145 DenseVector<Number> & re = _assembly.residualBlock(_var.number());
146 _local_re.resize(re.size());
149 for (_i = 0; _i < _test.size(); _i++)
150 for (_qp = 0; _qp < _qrule->n_points(); _qp++)
154 DenseMatrix<Number> & ke = _assembly.jacobianBlock(_var.number(), jvar);
157 _local_ke.resize(ke.m(), ke.n());
160 for (_i = 0; _i < _test.size(); _i++)
161 for (_j = 0; _j < _phi.size(); _j++)
162 for (_qp = 0; _qp < _qrule->n_points(); _qp++)
163 _local_ke(_i, _j) += _JxW[_qp] * _coord[_qp] *
computeQpJac(dvar);
196 bool reached_steady =
true;
197 for (
unsigned int nodenum = 0; nodenum <
_num_nodes; ++nodenum)
199 if (_local_re(nodenum) >= 1E-20)
201 reached_steady =
false;
208 Real total_mass_out = 0;
213 std::vector<Real> dtotal_mass_out;
214 std::vector<Real> dtotal_in;
219 for (
unsigned int nodenum = 0; nodenum <
_num_nodes; ++nodenum)
221 dtotal_mass_out[nodenum] = 0;
222 dtotal_in[nodenum] = 0;
227 for (
unsigned int nodenum = 0; nodenum <
_num_nodes; ++nodenum)
229 if (_local_re(nodenum) >= 0 || reached_steady)
233 for (_j = 0; _j < _phi.size(); _j++)
234 _local_ke(nodenum, _j) *=
_mobility[nodenum];
235 _local_ke(nodenum, nodenum) +=
_dmobility_dv[nodenum][dvar] * _local_re(nodenum);
236 for (_j = 0; _j < _phi.size(); _j++)
237 dtotal_mass_out[_j] += _local_ke(nodenum, _j);
239 _local_re(nodenum) *=
_mobility[nodenum];
240 total_mass_out += _local_re(nodenum);
244 total_in -= _local_re(nodenum);
246 for (_j = 0; _j < _phi.size(); _j++)
247 dtotal_in[_j] -= _local_ke(nodenum, _j);
254 for (
unsigned int nodenum = 0; nodenum <
_num_nodes; ++nodenum)
255 if (_local_re(nodenum) < 0)
258 for (_j = 0; _j < _phi.size(); _j++)
260 _local_ke(nodenum, _j) *= total_mass_out / total_in;
261 _local_ke(nodenum, _j) +=
262 _local_re(nodenum) * (dtotal_mass_out[_j] / total_in -
263 dtotal_in[_j] * total_mass_out / total_in / total_in);
265 _local_re(nodenum) *= total_mass_out / total_in;
275 Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
276 for (
unsigned int i = 0; i < _save_in.size(); i++)
277 _save_in[i]->sys().solution().add_vector(_local_re, _save_in[i]->dofIndices());
285 if (_has_diag_save_in && dvar ==
_pvar)
287 const unsigned int rows = ke.m();
288 DenseVector<Number> diag(rows);
289 for (
unsigned int i = 0; i < rows; i++)
290 diag(i) = _local_ke(i, i);
292 Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
293 for (
unsigned int i = 0; i < _diag_save_in.size(); i++)
294 _diag_save_in[i]->sys().solution().add_vector(diag, _diag_save_in[i]->dofIndices());