www.mooseframework.org
RichardsFlux.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #include "RichardsFlux.h"
11 
12 // MOOSE includes
13 #include "Material.h"
14 #include "MooseVariable.h"
15 
16 // C++ includes
17 #include <iostream>
18 
19 registerMooseObject("RichardsApp", RichardsFlux);
20 
23 {
25  params.addParam<bool>(
26  "linear_shape_fcns",
27  true,
28  "If you are using second-order Lagrange shape functions you need to set this to false.");
29  params.addRequiredParam<UserObjectName>(
30  "richardsVarNames_UO", "The UserObject that holds the list of Richards variable names.");
31  return params;
32 }
33 
35  : Kernel(parameters),
36  _richards_name_UO(getUserObject<RichardsVarNames>("richardsVarNames_UO")),
37  _pvar(_richards_name_UO.richards_var_num(_var.number())),
38 
39  // This kernel gets lots of things from the material
40  _flux(getMaterialProperty<std::vector<RealVectorValue>>("flux")),
41  _dflux_dv(getMaterialProperty<std::vector<std::vector<RealVectorValue>>>("dflux_dv")),
42  _dflux_dgradv(getMaterialProperty<std::vector<std::vector<RealTensorValue>>>("dflux_dgradv")),
43  _d2flux_dvdv(
44  getMaterialProperty<std::vector<std::vector<std::vector<RealVectorValue>>>>("d2flux_dvdv")),
45  _d2flux_dgradvdv(getMaterialProperty<std::vector<std::vector<std::vector<RealTensorValue>>>>(
46  "d2flux_dgradvdv")),
47  _d2flux_dvdgradv(getMaterialProperty<std::vector<std::vector<std::vector<RealTensorValue>>>>(
48  "d2flux_dvdgradv")),
49 
50  _second_u(getParam<bool>("linear_shape_fcns")
51  ? _second_zero
52  : (_is_implicit ? _var.secondSln() : _var.secondSlnOld())),
53  _second_phi(getParam<bool>("linear_shape_fcns") ? _second_phi_zero : secondPhi()),
54 
55  _tauvel_SUPG(getMaterialProperty<std::vector<RealVectorValue>>("tauvel_SUPG")),
56  _dtauvel_SUPG_dgradv(
57  getMaterialProperty<std::vector<std::vector<RealTensorValue>>>("dtauvel_SUPG_dgradv")),
58  _dtauvel_SUPG_dv(
59  getMaterialProperty<std::vector<std::vector<RealVectorValue>>>("dtauvel_SUPG_dv"))
60 {
61 }
62 
63 Real
65 {
66  Real flux_part = _grad_test[_i][_qp] * _flux[_qp][_pvar];
67 
68  Real supg_test = _tauvel_SUPG[_qp][_pvar] * _grad_test[_i][_qp];
69  Real supg_kernel = 0.0;
70  if (supg_test != 0)
71  // NOTE: Libmesh does not correctly calculate grad(_grad_u) correctly, so following might not be
72  // correct
73  // NOTE: The following is -divergence(flux)
74  // NOTE: The following must be generalised if a non PPPP formalism is used
75  // NOTE: The generalisation will look like
76  // supg_kernel = sum_j {-(_dflux_dgradv[_qp][_pvar][j]*_second_u[_qp][j]).tr() -
77  // _dflux_dv[_qp][_pvar][j]*_grad_u[_qp][j]}
78  // where _grad_u[_qp][j] is the gradient of the j^th variable at the quadpoint.
79  supg_kernel = -(_dflux_dgradv[_qp][_pvar][_pvar] * _second_u[_qp]).tr() -
81 
82  return flux_part + supg_test * supg_kernel;
83 }
84 
85 Real
86 RichardsFlux::computeQpJac(unsigned int wrt_num)
87 {
88  Real flux_prime = _grad_test[_i][_qp] * (_dflux_dgradv[_qp][_pvar][wrt_num] * _grad_phi[_j][_qp] +
89  _dflux_dv[_qp][_pvar][wrt_num] * _phi[_j][_qp]);
90 
91  Real supg_test = _tauvel_SUPG[_qp][_pvar] * _grad_test[_i][_qp];
92  Real supg_test_prime =
94  _phi[_j][_qp] * _dtauvel_SUPG_dv[_qp][_pvar][wrt_num] * _grad_test[_i][_qp];
95  Real supg_kernel = 0.0;
96  Real supg_kernel_prime = 0.0;
97 
98  if (supg_test != 0)
99  {
100  // NOTE: since Libmesh does not correctly calculate grad(_grad_u) correctly, so following might
101  // not be correct
102  supg_kernel = -(_dflux_dgradv[_qp][_pvar][_pvar] * _second_u[_qp]).tr() -
104 
105  // NOTE: just like supg_kernel, this must be generalised for non-PPPP formulations
106  supg_kernel_prime =
107  -(_d2flux_dvdv[_qp][_pvar][_pvar][wrt_num] * _phi[_j][_qp] * _grad_u[_qp] +
108  _phi[_j][_qp] * (_d2flux_dgradvdv[_qp][_pvar][_pvar][wrt_num] * _second_u[_qp]).tr() +
109  (_d2flux_dvdgradv[_qp][_pvar][_pvar][wrt_num] * _grad_u[_qp]) * _grad_phi[_j][_qp]);
110  if (wrt_num == _pvar)
111  supg_kernel_prime -= _dflux_dv[_qp][_pvar][_pvar] * _grad_phi[_j][_qp];
112  supg_kernel_prime -= (_dflux_dgradv[_qp][_pvar][_pvar] * _second_phi[_j][_qp]).tr();
113  }
114 
115  return flux_prime + supg_test_prime * supg_kernel + supg_test * supg_kernel_prime;
116 }
117 
118 Real
120 {
121  return computeQpJac(_pvar);
122 }
123 
124 Real
126 {
128  return 0.0;
129  unsigned int dvar = _richards_name_UO.richards_var_num(jvar);
130  return computeQpJac(dvar);
131 }
const MaterialProperty< std::vector< std::vector< std::vector< RealVectorValue > > > > & _d2flux_dvdv
d^2(Richards flux_i)/d(variable_j)/d(variable_k), here flux_i is the i_th flux, which is itself a Rea...
Definition: RichardsFlux.h:60
Kernel = grad(permeability*relativepermeability/viscosity * (grad(pressure) - density*gravity)) This ...
Definition: RichardsFlux.h:21
const VariableGradient & _grad_u
static InputParameters validParams()
unsigned int _pvar
the index of this variable in the list of Richards variables held by _richards_name_UO.
Definition: RichardsFlux.h:48
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
const MaterialProperty< std::vector< RealVectorValue > > & _tauvel_SUPG
SUPGtau*SUPGvel (a vector of these if multiphase)
Definition: RichardsFlux.h:75
const VariablePhiGradient & _grad_phi
const RichardsVarNames & _richards_name_UO
holds info regarding the names of the Richards variables and methods for extracting values of these v...
Definition: RichardsFlux.h:39
static InputParameters validParams()
Definition: RichardsFlux.C:22
virtual Real computeQpOffDiagJacobian(unsigned int jvar)
Definition: RichardsFlux.C:125
const MaterialProperty< std::vector< std::vector< RealTensorValue > > > & _dflux_dgradv
d(Richards flux_i)/d(grad(variable_j)), here flux_i is the i_th flux, which is itself a RealVectorVal...
Definition: RichardsFlux.h:57
bool not_richards_var(unsigned int moose_var_num) const
returns true if moose_var_num is not a richards var
RichardsFlux(const InputParameters &parameters)
Definition: RichardsFlux.C:34
const MaterialProperty< std::vector< std::vector< RealTensorValue > > > & _dtauvel_SUPG_dgradv
derivative of SUPGtau*SUPGvel_i wrt grad(variable_j)
Definition: RichardsFlux.h:78
This holds maps between pressure_var or pressure_var, sat_var used in RichardsMaterial and kernels...
void addRequiredParam(const std::string &name, const std::string &doc_string)
const VariablePhiSecond & _second_phi
interpolation function for the _second_u
Definition: RichardsFlux.h:72
TensorValue< Real > RealTensorValue
Real computeQpJac(unsigned int wrt_num)
Computes diagonal and off-diagonal jacobian entries.
Definition: RichardsFlux.C:86
const MaterialProperty< std::vector< RealVectorValue > > & _flux
Richards flux.
Definition: RichardsFlux.h:51
unsigned int _i
const MaterialProperty< std::vector< std::vector< RealVectorValue > > > & _dflux_dv
d(Richards flux_i)/d(variable_j), here flux_i is the i_th flux, which is itself a RealVectorValue ...
Definition: RichardsFlux.h:54
unsigned int _j
registerMooseObject("RichardsApp", RichardsFlux)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
unsigned int richards_var_num(unsigned int moose_var_num) const
the richards variable number
const VariableTestGradient & _grad_test
virtual Real computeQpJacobian()
Definition: RichardsFlux.C:119
const VariableSecond & _second_u
grad_i grad_j porepressure. This is used in SUPG
Definition: RichardsFlux.h:69
const VariablePhiValue & _phi
const MaterialProperty< std::vector< std::vector< RealVectorValue > > > & _dtauvel_SUPG_dv
derivative of SUPGtau*SUPGvel_i wrt variable_j
Definition: RichardsFlux.h:81
const MaterialProperty< std::vector< std::vector< std::vector< RealTensorValue > > > > & _d2flux_dvdgradv
d^2(Richards flux_i)/d(variable_j)/d(grad(variable_k)), here flux_i is the i_th flux, which is itself a RealVectorValue
Definition: RichardsFlux.h:66
const MaterialProperty< std::vector< std::vector< std::vector< RealTensorValue > > > > & _d2flux_dgradvdv
d^2(Richards flux_i)/d(grad(variable_j))/d(variable_k), here flux_i is the i_th flux, which is itself a RealVectorValue
Definition: RichardsFlux.h:63
virtual Real computeQpResidual()
Definition: RichardsFlux.C:64
unsigned int _qp