www.mooseframework.org
Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | List of all members
PorousFlowHeatAdvection Class Reference

Advection of heat via flux of component k in fluid phase alpha. More...

#include <PorousFlowHeatAdvection.h>

Inheritance diagram for PorousFlowHeatAdvection:
[legend]

Public Member Functions

 PorousFlowHeatAdvection (const InputParameters &parameters)
 

Protected Types

enum  JacRes { JacRes::CALCULATE_RESIDUAL = 0, JacRes::CALCULATE_JACOBIAN = 1 }
 
enum  FallbackEnum { FallbackEnum::QUICK, FallbackEnum::HARMONIC }
 If full upwinding is failing due to nodes swapping between upwind and downwind in successive nonlinear iterations (within one timestep and element) a fallback scheme is used instead. More...
 

Protected Member Functions

virtual Real mobility (unsigned nodenum, unsigned phase) const override
 The mobility of the fluid. More...
 
virtual Real dmobility (unsigned nodenum, unsigned phase, unsigned pvar) const override
 The derivative of mobility with respect to PorousFlow variable pvar. More...
 
virtual void timestepSetup () override
 
virtual Real computeQpResidual () override
 
virtual void computeResidual () override
 
virtual void computeJacobian () override
 
virtual void computeOffDiagJacobian (MooseVariableFEBase &jvar) override
 
virtual Real darcyQp (unsigned int ph) const
 The Darcy part of the flux (this is the non-upwinded part) More...
 
virtual Real darcyQpJacobian (unsigned int jvar, unsigned int ph) const
 Jacobian of the Darcy part of the flux. More...
 
void computeResidualAndJacobian (JacRes res_or_jac, unsigned int jvar)
 Computation of the residual and Jacobian. More...
 
void fullyUpwind (JacRes res_or_jac, unsigned int ph, unsigned int pvar)
 Calculate the residual or Jacobian using full upwinding. More...
 
void quickUpwind (JacRes res_or_jac, unsigned int ph, unsigned int pvar)
 Calculate the residual or Jacobian using the nodal mobilities, but without conserving fluid mass. More...
 
void harmonicMean (JacRes res_or_jac, unsigned int ph, unsigned int pvar)
 Calculate the residual or Jacobian by using the harmonic mean of the nodal mobilities for the entire element. More...
 

Protected Attributes

const MaterialProperty< std::vector< Real > > & _enthalpy
 Enthalpy of each phase. More...
 
const MaterialProperty< std::vector< std::vector< Real > > > & _denthalpy_dvar
 Derivative of the enthalpy wrt PorousFlow variables. More...
 
const MaterialProperty< std::vector< Real > > & _relative_permeability
 Relative permeability of each phase. More...
 
const MaterialProperty< std::vector< std::vector< Real > > > & _drelative_permeability_dvar
 Derivative of relative permeability of each phase wrt PorousFlow variables. More...
 
const MaterialProperty< RealTensorValue > & _permeability
 Permeability of porous material. More...
 
const MaterialProperty< std::vector< RealTensorValue > > & _dpermeability_dvar
 d(permeabiity)/d(PorousFlow variable) More...
 
const MaterialProperty< std::vector< std::vector< RealTensorValue > > > & _dpermeability_dgradvar
 d(permeabiity)/d(grad(PorousFlow variable)) More...
 
const MaterialProperty< std::vector< Real > > & _fluid_density_node
 Fluid density for each phase (at the node) More...
 
const MaterialProperty< std::vector< std::vector< Real > > > & _dfluid_density_node_dvar
 Derivative of the fluid density for each phase wrt PorousFlow variables (at the node) More...
 
const MaterialProperty< std::vector< Real > > & _fluid_density_qp
 Fluid density for each phase (at the qp) More...
 
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) More...
 
const MaterialProperty< std::vector< Real > > & _fluid_viscosity
 Viscosity of each component in each phase. More...
 
const MaterialProperty< std::vector< std::vector< Real > > > & _dfluid_viscosity_dvar
 Derivative of the fluid viscosity for each phase wrt PorousFlow variables. More...
 
const MaterialProperty< std::vector< Real > > & _pp
 Nodal pore pressure in each phase. More...
 
const MaterialProperty< std::vector< RealGradient > > & _grad_p
 Gradient of the pore pressure in each phase. More...
 
const MaterialProperty< std::vector< std::vector< Real > > > & _dgrad_p_dgrad_var
 Derivative of Grad porepressure in each phase wrt grad(PorousFlow variables) More...
 
const MaterialProperty< std::vector< std::vector< RealGradient > > > & _dgrad_p_dvar
 Derivative of Grad porepressure in each phase wrt PorousFlow variables. More...
 
const PorousFlowDictator_dictator
 PorousFlowDictator UserObject. More...
 
const unsigned int _num_phases
 The number of fluid phases. More...
 
const RealVectorValue _gravity
 Gravity. Defaults to 9.81 m/s^2. More...
 
const bool _perm_derivs
 Flag to check whether permeabiity derivatives are non-zero. More...
 
const unsigned _full_upwind_threshold
 If the number of upwind-downwind swaps is less than this amount then full upwinding is used. More...
 
enum PorousFlowDarcyBase::FallbackEnum _fallback_scheme
 
std::vector< std::vector< Real > > _proto_flux
 The Darcy flux. More...
 
std::vector< std::vector< std::vector< Real > > > _jacobian
 Derivative of _proto_flux with respect to nodal variables. More...
 
std::unordered_map< unsigned, std::vector< std::vector< unsigned > > > _num_upwinds
 Number of nonlinear iterations (in this timestep and this element) that a node is an upwind node for a given fluid phase. More...
 
std::unordered_map< unsigned, std::vector< std::vector< unsigned > > > _num_downwinds
 Number of nonlinear iterations (in this timestep and this element) that a node is an downwind node for a given fluid phase. More...
 

Detailed Description

Advection of heat via flux of component k in fluid phase alpha.

A fully-updwinded version is implemented, where the mobility of the upstream nodes is used.

Definition at line 24 of file PorousFlowHeatAdvection.h.

Member Enumeration Documentation

◆ FallbackEnum

enum PorousFlowDarcyBase::FallbackEnum
strongprotectedinherited

If full upwinding is failing due to nodes swapping between upwind and downwind in successive nonlinear iterations (within one timestep and element) a fallback scheme is used instead.

QUICK: use the nodal mobilities, as in full upwinding, but do not attempt to conserve fluid mass. HARMONIC: assign the harmonic mean of the mobilities to the entire element.

Enumerator
QUICK 
HARMONIC 

Definition at line 152 of file PorousFlowDarcyBase.h.

152 { QUICK, HARMONIC } _fallback_scheme;

◆ JacRes

enum PorousFlowDarcyBase::JacRes
strongprotectedinherited
Enumerator
CALCULATE_RESIDUAL 
CALCULATE_JACOBIAN 

Definition at line 63 of file PorousFlowDarcyBase.h.

64  {
65  CALCULATE_RESIDUAL = 0,
66  CALCULATE_JACOBIAN = 1
67  };

Constructor & Destructor Documentation

◆ PorousFlowHeatAdvection()

PorousFlowHeatAdvection::PorousFlowHeatAdvection ( const InputParameters &  parameters)

Definition at line 23 of file PorousFlowHeatAdvection.C.

24  : PorousFlowDarcyBase(parameters),
25  _enthalpy(getMaterialProperty<std::vector<Real>>("PorousFlow_fluid_phase_enthalpy_nodal")),
26  _denthalpy_dvar(getMaterialProperty<std::vector<std::vector<Real>>>(
27  "dPorousFlow_fluid_phase_enthalpy_nodal_dvar")),
29  getMaterialProperty<std::vector<Real>>("PorousFlow_relative_permeability_nodal")),
30  _drelative_permeability_dvar(getMaterialProperty<std::vector<std::vector<Real>>>(
31  "dPorousFlow_relative_permeability_nodal_dvar"))
32 {
33 }

Member Function Documentation

◆ computeJacobian()

void PorousFlowDarcyBase::computeJacobian ( )
overrideprotectedvirtualinherited

Definition at line 141 of file PorousFlowDarcyBase.C.

142 {
144 }

◆ computeOffDiagJacobian()

void PorousFlowDarcyBase::computeOffDiagJacobian ( MooseVariableFEBase &  jvar)
overrideprotectedvirtualinherited

Definition at line 147 of file PorousFlowDarcyBase.C.

148 {
150 }

◆ computeQpResidual()

Real PorousFlowDarcyBase::computeQpResidual ( )
overrideprotectedvirtualinherited

Definition at line 128 of file PorousFlowDarcyBase.C.

129 {
130  mooseError("PorousFlowDarcyBase: computeQpResidual called");
131  return 0.0;
132 }

◆ computeResidual()

void PorousFlowDarcyBase::computeResidual ( )
overrideprotectedvirtualinherited

Definition at line 135 of file PorousFlowDarcyBase.C.

◆ computeResidualAndJacobian()

void PorousFlowDarcyBase::computeResidualAndJacobian ( JacRes  res_or_jac,
unsigned int  jvar 
)
protectedinherited

Computation of the residual and Jacobian.

If res_or_jac=CALCULATE_JACOBIAN then the residual gets calculated anyway (becuase we have to know which nodes are upwind and which are downwind) except we don't actually need to store the residual in _assembly.residualBlock and we don't need to save in save_in.

If res_or_jac=CALCULATE_RESIDUAL then we don't have to do all the Jacobian calculations.

Parameters
res_or_jacWhether to calculate the residual or the jacobian.
jvarPorousFlow variable to take derivatives wrt to

Definition at line 153 of file PorousFlowDarcyBase.C.

154 {
155  if ((res_or_jac == JacRes::CALCULATE_JACOBIAN) && _dictator.notPorousFlowVariable(jvar))
156  return;
157 
158  // The PorousFlow variable index corresponding to the variable number jvar
159  const unsigned int pvar =
160  ((res_or_jac == JacRes::CALCULATE_JACOBIAN) ? _dictator.porousFlowVariableNum(jvar) : 0);
161 
162  DenseMatrix<Number> & ke = _assembly.jacobianBlock(_var.number(), jvar);
163  if ((ke.n() == 0) && (res_or_jac == JacRes::CALCULATE_JACOBIAN)) // this removes a problem
164  // encountered in the initial
165  // timestep when
166  // use_displaced_mesh=true
167  return;
168 
169  // The number of nodes in the element
170  const unsigned int num_nodes = _test.size();
171 
172  // Compute the residual and jacobian without the mobility terms. Even if we are computing the
173  // Jacobian we still need this in order to see which nodes are upwind and which are downwind.
174  for (unsigned ph = 0; ph < _num_phases; ++ph)
175  {
176  _proto_flux[ph].assign(num_nodes, 0);
177  for (_qp = 0; _qp < _qrule->n_points(); _qp++)
178  {
179  for (_i = 0; _i < num_nodes; ++_i)
180  _proto_flux[ph][_i] += _JxW[_qp] * _coord[_qp] * darcyQp(ph);
181  }
182  }
183 
184  // for this element, record whether each node is "upwind" or "downwind" (or neither)
185  const unsigned elem = _current_elem->id();
186  if (_num_upwinds.find(elem) == _num_upwinds.end())
187  {
188  _num_upwinds[elem] = std::vector<std::vector<unsigned>>(_num_phases);
189  _num_downwinds[elem] = std::vector<std::vector<unsigned>>(_num_phases);
190  for (unsigned ph = 0; ph < _num_phases; ++ph)
191  {
192  _num_upwinds[elem][ph].assign(num_nodes, 0);
193  _num_downwinds[elem][ph].assign(num_nodes, 0);
194  }
195  }
196  // record the information once per nonlinear iteration
197  if (res_or_jac == JacRes::CALCULATE_JACOBIAN && jvar == _var.number())
198  {
199  for (unsigned ph = 0; ph < _num_phases; ++ph)
200  {
201  for (unsigned nod = 0; nod < num_nodes; ++nod)
202  {
203  if (_proto_flux[ph][nod] > 0)
204  _num_upwinds[elem][ph][nod]++;
205  else if (_proto_flux[ph][nod] < 0)
206  _num_downwinds[elem][ph][nod]++;
207  }
208  }
209  }
210 
211  // based on _num_upwinds and _num_downwinds, calculate the maximum number
212  // of upwind-downwind swaps that have been encountered in this timestep
213  // for this element
214  std::vector<unsigned> max_swaps(_num_phases, 0);
215  for (unsigned ph = 0; ph < _num_phases; ++ph)
216  {
217  for (unsigned nod = 0; nod < num_nodes; ++nod)
218  max_swaps[ph] = std::max(
219  max_swaps[ph], std::min(_num_upwinds[elem][ph][nod], _num_downwinds[elem][ph][nod]));
220  }
221 
222  // size the _jacobian correctly and calculate it for the case residual = _proto_flux
223  if (res_or_jac == JacRes::CALCULATE_JACOBIAN)
224  {
225  for (unsigned ph = 0; ph < _num_phases; ++ph)
226  {
227  _jacobian[ph].resize(ke.m());
228  for (_i = 0; _i < _test.size(); _i++)
229  {
230  _jacobian[ph][_i].assign(ke.n(), 0.0);
231  for (_j = 0; _j < _phi.size(); _j++)
232  for (_qp = 0; _qp < _qrule->n_points(); _qp++)
233  _jacobian[ph][_i][_j] += _JxW[_qp] * _coord[_qp] * darcyQpJacobian(jvar, ph);
234  }
235  }
236  }
237 
238  // Loop over all the phases, computing the mass flux, which
239  // gets placed into _proto_flux, and the derivative of this
240  // which gets placed into _jacobian
241  for (unsigned int ph = 0; ph < _num_phases; ++ph)
242  {
243  if (max_swaps[ph] < _full_upwind_threshold)
244  fullyUpwind(res_or_jac, ph, pvar);
245  else
246  {
247  switch (_fallback_scheme)
248  {
249  case FallbackEnum::QUICK:
250  quickUpwind(res_or_jac, ph, pvar);
251  break;
253  harmonicMean(res_or_jac, ph, pvar);
254  break;
255  }
256  }
257  }
258 
259  // Add results to the Residual or Jacobian
260  if (res_or_jac == JacRes::CALCULATE_RESIDUAL)
261  {
262  DenseVector<Number> & re = _assembly.residualBlock(_var.number());
263 
264  _local_re.resize(re.size());
265  _local_re.zero();
266  for (_i = 0; _i < _test.size(); _i++)
267  for (unsigned int ph = 0; ph < _num_phases; ++ph)
268  _local_re(_i) += _proto_flux[ph][_i];
269 
270  re += _local_re;
271 
272  if (_has_save_in)
273  {
274  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
275  for (unsigned int i = 0; i < _save_in.size(); i++)
276  _save_in[i]->sys().solution().add_vector(_local_re, _save_in[i]->dofIndices());
277  }
278  }
279 
280  if (res_or_jac == JacRes::CALCULATE_JACOBIAN)
281  {
282  _local_ke.resize(ke.m(), ke.n());
283  _local_ke.zero();
284 
285  for (_i = 0; _i < _test.size(); _i++)
286  for (_j = 0; _j < _phi.size(); _j++)
287  for (unsigned int ph = 0; ph < _num_phases; ++ph)
288  _local_ke(_i, _j) += _jacobian[ph][_i][_j];
289 
290  ke += _local_ke;
291 
292  if (_has_diag_save_in && jvar == _var.number())
293  {
294  unsigned int rows = ke.m();
295  DenseVector<Number> diag(rows);
296  for (unsigned int i = 0; i < rows; i++)
297  diag(i) = _local_ke(i, i);
298 
299  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
300  for (unsigned int i = 0; i < _diag_save_in.size(); i++)
301  _diag_save_in[i]->sys().solution().add_vector(diag, _diag_save_in[i]->dofIndices());
302  }
303  }
304 }

Referenced by PorousFlowDarcyBase::computeJacobian(), PorousFlowDarcyBase::computeOffDiagJacobian(), and PorousFlowDarcyBase::computeResidual().

◆ darcyQp()

Real PorousFlowDarcyBase::darcyQp ( unsigned int  ph) const
protectedvirtualinherited

The Darcy part of the flux (this is the non-upwinded part)

Definition at line 95 of file PorousFlowDarcyBase.C.

96 {
97  return _grad_test[_i][_qp] *
98  (_permeability[_qp] * (_grad_p[_qp][ph] - _fluid_density_qp[_qp][ph] * _gravity));
99 }

Referenced by PorousFlowDarcyBase::computeResidualAndJacobian().

◆ darcyQpJacobian()

Real PorousFlowDarcyBase::darcyQpJacobian ( unsigned int  jvar,
unsigned int  ph 
) const
protectedvirtualinherited

Jacobian of the Darcy part of the flux.

Definition at line 102 of file PorousFlowDarcyBase.C.

103 {
105  return 0.0;
106 
107  const unsigned int pvar = _dictator.porousFlowVariableNum(jvar);
108 
109  RealVectorValue deriv =
110  _permeability[_qp] * (_grad_phi[_j][_qp] * _dgrad_p_dgrad_var[_qp][ph][pvar] -
111  _phi[_j][_qp] * _dfluid_density_qp_dvar[_qp][ph][pvar] * _gravity);
112 
113  deriv += _permeability[_qp] * (_dgrad_p_dvar[_qp][ph][pvar] * _phi[_j][_qp]);
114 
115  if (_perm_derivs)
116  {
117  deriv += _dpermeability_dvar[_qp][pvar] * _phi[_j][_qp] *
118  (_grad_p[_qp][ph] - _fluid_density_qp[_qp][ph] * _gravity);
119  for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
120  deriv += _dpermeability_dgradvar[_qp][i][pvar] * _grad_phi[_j][_qp](i) *
121  (_grad_p[_qp][ph] - _fluid_density_qp[_qp][ph] * _gravity);
122  }
123 
124  return _grad_test[_i][_qp] * deriv;
125 }

Referenced by PorousFlowDarcyBase::computeResidualAndJacobian().

◆ dmobility()

Real PorousFlowHeatAdvection::dmobility ( unsigned  nodenum,
unsigned  phase,
unsigned  pvar 
) const
overrideprotectedvirtual

The derivative of mobility with respect to PorousFlow variable pvar.

Parameters
nodenumThe node-number to evaluate the mobility for
phasethe fluid phase number
pvarthe PorousFlow variable pvar

Reimplemented from PorousFlowDarcyBase.

Definition at line 43 of file PorousFlowHeatAdvection.C.

44 {
45  Real dm = _denthalpy_dvar[nodenum][phase][pvar] * _fluid_density_node[nodenum][phase] *
46  _relative_permeability[nodenum][phase] / _fluid_viscosity[nodenum][phase];
47  dm += _enthalpy[nodenum][phase] * _dfluid_density_node_dvar[nodenum][phase][pvar] *
48  _relative_permeability[nodenum][phase] / _fluid_viscosity[nodenum][phase];
49  dm += _enthalpy[nodenum][phase] * _fluid_density_node[nodenum][phase] *
50  _drelative_permeability_dvar[nodenum][phase][pvar] / _fluid_viscosity[nodenum][phase];
51  dm -= _enthalpy[nodenum][phase] * _fluid_density_node[nodenum][phase] *
52  _relative_permeability[nodenum][phase] * _dfluid_viscosity_dvar[nodenum][phase][pvar] /
53  std::pow(_fluid_viscosity[nodenum][phase], 2);
54  return dm;
55 }

◆ fullyUpwind()

void PorousFlowDarcyBase::fullyUpwind ( JacRes  res_or_jac,
unsigned int  ph,
unsigned int  pvar 
)
protectedinherited

Calculate the residual or Jacobian using full upwinding.

Parameters
res_or_jacwhether to compute the residual or jacobian
phfluid phase number
pvardifferentiate wrt to this PorousFlow variable (when computing the jacobian)

Perform the full upwinding by multiplying the residuals at the upstream nodes by their mobilities. Mobility is different for each phase, and in each situation: mobility = density / viscosity for single-component Darcy flow mobility = mass_fraction * density * relative_perm / viscosity for multi-component, multiphase flow mobility = enthalpy * density * relative_perm / viscosity for heat convection

The residual for the kernel is the sum over Darcy fluxes for each phase. The Darcy flux for a particular phase is R_i = int{mobility*flux_no_mob} = int{mobility*grad(pot)*permeability*grad(test_i)} for node i. where int is the integral over the element. However, in fully-upwind, the first step is to take the mobility outside the integral, which was done in the _proto_flux calculation above.

NOTE: Physically _proto_flux[i][ph] is a measure of fluid of phase ph flowing out of node i. If we had left in mobility, it would be exactly the component mass flux flowing out of node i.

This leads to the definition of upwinding:

If _proto_flux(i)[ph] is positive then we use mobility_i. That is we use the upwind value of mobility.

The final subtle thing is we must also conserve fluid mass: the total component mass flowing out of node i must be the sum of the masses flowing into the other nodes.

note the -= means the result is positive

Definition at line 307 of file PorousFlowDarcyBase.C.

308 {
338  // The number of nodes in the element
339  const unsigned int num_nodes = _test.size();
340 
341  Real mob;
342  Real dmob;
343  // Define variables used to ensure mass conservation
344  Real total_mass_out = 0.0;
345  Real total_in = 0.0;
346 
347  // The following holds derivatives of these
348  std::vector<Real> dtotal_mass_out;
349  std::vector<Real> dtotal_in;
350  if (res_or_jac == JacRes::CALCULATE_JACOBIAN)
351  {
352  dtotal_mass_out.assign(num_nodes, 0.0);
353  dtotal_in.assign(num_nodes, 0.0);
354  }
355 
356  // Perform the upwinding using the mobility
357  std::vector<bool> upwind_node(num_nodes);
358  for (unsigned int n = 0; n < num_nodes; ++n)
359  {
360  if (_proto_flux[ph][n] >= 0.0) // upstream node
361  {
362  upwind_node[n] = true;
363  // The mobility at the upstream node
364  mob = mobility(n, ph);
365  if (res_or_jac == JacRes::CALCULATE_JACOBIAN)
366  {
367  // The derivative of the mobility wrt the PorousFlow variable
368  dmob = dmobility(n, ph, pvar);
369 
370  for (_j = 0; _j < _phi.size(); _j++)
371  _jacobian[ph][n][_j] *= mob;
372 
373  if (_test.size() == _phi.size())
374  /* mobility at node=n depends only on the variables at node=n, by construction. For
375  * linear-lagrange variables, this means that Jacobian entries involving the derivative
376  * of mobility will only be nonzero for derivatives wrt variables at node=n. Hence the
377  * [n][n] in the line below. However, for other variable types (eg constant monomials)
378  * I cannot tell what variable number contributes to the derivative. However, in all
379  * cases I can possibly imagine, the derivative is zero anyway, since in the full
380  * upwinding scheme, mobility shouldn't depend on these other sorts of variables.
381  */
382  _jacobian[ph][n][n] += dmob * _proto_flux[ph][n];
383 
384  for (_j = 0; _j < _phi.size(); _j++)
385  dtotal_mass_out[_j] += _jacobian[ph][n][_j];
386  }
387  _proto_flux[ph][n] *= mob;
388  total_mass_out += _proto_flux[ph][n];
389  }
390  else
391  {
392  upwind_node[n] = false;
393  total_in -= _proto_flux[ph][n];
394  if (res_or_jac == JacRes::CALCULATE_JACOBIAN)
395  for (_j = 0; _j < _phi.size(); _j++)
396  dtotal_in[_j] -= _jacobian[ph][n][_j];
397  }
398  }
399 
400  // Conserve mass over all phases by proportioning the total_mass_out mass to the inflow nodes,
401  // weighted by their proto_flux values
402  for (unsigned int n = 0; n < num_nodes; ++n)
403  {
404  if (!upwind_node[n]) // downstream node
405  {
406  if (res_or_jac == JacRes::CALCULATE_JACOBIAN)
407  for (_j = 0; _j < _phi.size(); _j++)
408  {
409  _jacobian[ph][n][_j] *= total_mass_out / total_in;
410  _jacobian[ph][n][_j] +=
411  _proto_flux[ph][n] * (dtotal_mass_out[_j] / total_in -
412  dtotal_in[_j] * total_mass_out / total_in / total_in);
413  }
414  _proto_flux[ph][n] *= total_mass_out / total_in;
415  }
416  }
417 }

Referenced by PorousFlowDarcyBase::computeResidualAndJacobian().

◆ harmonicMean()

void PorousFlowDarcyBase::harmonicMean ( JacRes  res_or_jac,
unsigned int  ph,
unsigned int  pvar 
)
protectedinherited

Calculate the residual or Jacobian by using the harmonic mean of the nodal mobilities for the entire element.

Parameters
res_or_jacwhether to compute the residual or jacobian
phfluid phase number
pvardifferentiate wrt to this PorousFlow variable (when computing the jacobian)

Definition at line 457 of file PorousFlowDarcyBase.C.

458 {
459  // The number of nodes in the element
460  const unsigned int num_nodes = _test.size();
461 
462  std::vector<Real> mob(num_nodes);
463  unsigned num_zero = 0;
464  unsigned zero_mobility_node = std::numeric_limits<unsigned>::max();
465  Real harmonic_mob = 0;
466  for (unsigned n = 0; n < num_nodes; ++n)
467  {
468  mob[n] = mobility(n, ph);
469  if (mob[n] == 0.0)
470  {
471  zero_mobility_node = n;
472  num_zero++;
473  }
474  else
475  harmonic_mob += 1.0 / mob[n];
476  }
477  if (num_zero > 0)
478  harmonic_mob = 0.0;
479  else
480  harmonic_mob = (1.0 * num_nodes) / harmonic_mob;
481 
482  // d(harmonic_mob)/d(PorousFlow variable at node n)
483  std::vector<Real> dharmonic_mob(num_nodes, 0.0);
484  if (res_or_jac == JacRes::CALCULATE_JACOBIAN)
485  {
486  const Real harm2 = std::pow(harmonic_mob, 2) / (1.0 * num_nodes);
487  if (num_zero == 0)
488  for (unsigned n = 0; n < num_nodes; ++n)
489  dharmonic_mob[n] = dmobility(n, ph, pvar) * harm2 / std::pow(mob[n], 2);
490  else if (num_zero == 1)
491  dharmonic_mob[zero_mobility_node] =
492  num_nodes * dmobility(zero_mobility_node, ph, pvar); // other derivs are zero
493  // if num_zero > 1 then all dharmonic_mob = 0.0
494  }
495 
496  if (res_or_jac == JacRes::CALCULATE_JACOBIAN)
497  for (unsigned n = 0; n < num_nodes; ++n)
498  for (_j = 0; _j < _phi.size(); _j++)
499  {
500  _jacobian[ph][n][_j] *= harmonic_mob;
501  if (_test.size() == _phi.size())
502  _jacobian[ph][n][_j] += dharmonic_mob[_j] * _proto_flux[ph][n];
503  }
504 
505  if (res_or_jac == JacRes::CALCULATE_RESIDUAL)
506  for (unsigned n = 0; n < num_nodes; ++n)
507  _proto_flux[ph][n] *= harmonic_mob;
508 }

Referenced by PorousFlowDarcyBase::computeResidualAndJacobian().

◆ mobility()

Real PorousFlowHeatAdvection::mobility ( unsigned  nodenum,
unsigned  phase 
) const
overrideprotectedvirtual

The mobility of the fluid.

For multi-component Darcy flow this is mass_fraction * fluid_density * relative_permeability / fluid_viscosity

Parameters
nodenumThe node-number to evaluate the mobility for
phasethe fluid phase number

Reimplemented from PorousFlowDarcyBase.

Definition at line 36 of file PorousFlowHeatAdvection.C.

37 {
38  return _enthalpy[nodenum][phase] * _fluid_density_node[nodenum][phase] *
39  _relative_permeability[nodenum][phase] / _fluid_viscosity[nodenum][phase];
40 }

◆ quickUpwind()

void PorousFlowDarcyBase::quickUpwind ( JacRes  res_or_jac,
unsigned int  ph,
unsigned int  pvar 
)
protectedinherited

Calculate the residual or Jacobian using the nodal mobilities, but without conserving fluid mass.

Parameters
res_or_jacwhether to compute the residual or jacobian
phfluid phase number
pvardifferentiate wrt to this PorousFlow variable (when computing the jacobian)

Definition at line 420 of file PorousFlowDarcyBase.C.

421 {
422  // The number of nodes in the element
423  const unsigned int num_nodes = _test.size();
424 
425  Real mob;
426  Real dmob;
427 
428  // Use the raw nodal mobility
429  for (unsigned int n = 0; n < num_nodes; ++n)
430  {
431  // The mobility at the node
432  mob = mobility(n, ph);
433  if (res_or_jac == JacRes::CALCULATE_JACOBIAN)
434  {
435  // The derivative of the mobility wrt the PorousFlow variable
436  dmob = dmobility(n, ph, pvar);
437 
438  for (_j = 0; _j < _phi.size(); _j++)
439  _jacobian[ph][n][_j] *= mob;
440 
441  if (_test.size() == _phi.size())
442  /* mobility at node=n depends only on the variables at node=n, by construction. For
443  * linear-lagrange variables, this means that Jacobian entries involving the derivative
444  * of mobility will only be nonzero for derivatives wrt variables at node=n. Hence the
445  * [n][n] in the line below. However, for other variable types (eg constant monomials)
446  * I cannot tell what variable number contributes to the derivative. However, in all
447  * cases I can possibly imagine, the derivative is zero anyway, since in the full
448  * upwinding scheme, mobility shouldn't depend on these other sorts of variables.
449  */
450  _jacobian[ph][n][n] += dmob * _proto_flux[ph][n];
451  }
452  _proto_flux[ph][n] *= mob;
453  }
454 }

Referenced by PorousFlowDarcyBase::computeResidualAndJacobian().

◆ timestepSetup()

void PorousFlowDarcyBase::timestepSetup ( )
overrideprotectedvirtualinherited

Definition at line 87 of file PorousFlowDarcyBase.C.

88 {
89  Kernel::timestepSetup();
90  _num_upwinds = std::unordered_map<unsigned, std::vector<std::vector<unsigned>>>();
91  _num_downwinds = std::unordered_map<unsigned, std::vector<std::vector<unsigned>>>();
92 }

Member Data Documentation

◆ _denthalpy_dvar

const MaterialProperty<std::vector<std::vector<Real> > >& PorousFlowHeatAdvection::_denthalpy_dvar
protected

Derivative of the enthalpy wrt PorousFlow variables.

Definition at line 37 of file PorousFlowHeatAdvection.h.

Referenced by dmobility().

◆ _dfluid_density_node_dvar

const MaterialProperty<std::vector<std::vector<Real> > >& PorousFlowDarcyBase::_dfluid_density_node_dvar
protectedinherited

Derivative of the fluid density for each phase wrt PorousFlow variables (at the node)

Definition at line 99 of file PorousFlowDarcyBase.h.

Referenced by PorousFlowAdvectiveFlux::dmobility(), dmobility(), and PorousFlowDarcyBase::dmobility().

◆ _dfluid_density_qp_dvar

const MaterialProperty<std::vector<std::vector<Real> > >& PorousFlowDarcyBase::_dfluid_density_qp_dvar
protectedinherited

Derivative of the fluid density for each phase wrt PorousFlow variables (at the qp)

Definition at line 105 of file PorousFlowDarcyBase.h.

Referenced by PorousFlowDarcyBase::darcyQpJacobian().

◆ _dfluid_viscosity_dvar

const MaterialProperty<std::vector<std::vector<Real> > >& PorousFlowDarcyBase::_dfluid_viscosity_dvar
protectedinherited

Derivative of the fluid viscosity for each phase wrt PorousFlow variables.

Definition at line 111 of file PorousFlowDarcyBase.h.

Referenced by PorousFlowAdvectiveFlux::dmobility(), dmobility(), and PorousFlowDarcyBase::dmobility().

◆ _dgrad_p_dgrad_var

const MaterialProperty<std::vector<std::vector<Real> > >& PorousFlowDarcyBase::_dgrad_p_dgrad_var
protectedinherited

Derivative of Grad porepressure in each phase wrt grad(PorousFlow variables)

Definition at line 120 of file PorousFlowDarcyBase.h.

Referenced by PorousFlowDarcyBase::darcyQpJacobian().

◆ _dgrad_p_dvar

const MaterialProperty<std::vector<std::vector<RealGradient> > >& PorousFlowDarcyBase::_dgrad_p_dvar
protectedinherited

Derivative of Grad porepressure in each phase wrt PorousFlow variables.

Definition at line 123 of file PorousFlowDarcyBase.h.

Referenced by PorousFlowDarcyBase::darcyQpJacobian().

◆ _dictator

const PorousFlowDictator& PorousFlowDarcyBase::_dictator
protectedinherited

◆ _dpermeability_dgradvar

const MaterialProperty<std::vector<std::vector<RealTensorValue> > >& PorousFlowDarcyBase::_dpermeability_dgradvar
protectedinherited

d(permeabiity)/d(grad(PorousFlow variable))

Definition at line 93 of file PorousFlowDarcyBase.h.

Referenced by PorousFlowDarcyBase::darcyQpJacobian().

◆ _dpermeability_dvar

const MaterialProperty<std::vector<RealTensorValue> >& PorousFlowDarcyBase::_dpermeability_dvar
protectedinherited

d(permeabiity)/d(PorousFlow variable)

Definition at line 90 of file PorousFlowDarcyBase.h.

Referenced by PorousFlowDarcyBase::darcyQpJacobian().

◆ _drelative_permeability_dvar

const MaterialProperty<std::vector<std::vector<Real> > >& PorousFlowHeatAdvection::_drelative_permeability_dvar
protected

Derivative of relative permeability of each phase wrt PorousFlow variables.

Definition at line 43 of file PorousFlowHeatAdvection.h.

Referenced by dmobility().

◆ _enthalpy

const MaterialProperty<std::vector<Real> >& PorousFlowHeatAdvection::_enthalpy
protected

Enthalpy of each phase.

Definition at line 34 of file PorousFlowHeatAdvection.h.

Referenced by dmobility(), and mobility().

◆ _fallback_scheme

enum PorousFlowDarcyBase::FallbackEnum PorousFlowDarcyBase::_fallback_scheme
protectedinherited

◆ _fluid_density_node

const MaterialProperty<std::vector<Real> >& PorousFlowDarcyBase::_fluid_density_node
protectedinherited

◆ _fluid_density_qp

const MaterialProperty<std::vector<Real> >& PorousFlowDarcyBase::_fluid_density_qp
protectedinherited

Fluid density for each phase (at the qp)

Definition at line 102 of file PorousFlowDarcyBase.h.

Referenced by PorousFlowDarcyBase::darcyQp(), and PorousFlowDarcyBase::darcyQpJacobian().

◆ _fluid_viscosity

const MaterialProperty<std::vector<Real> >& PorousFlowDarcyBase::_fluid_viscosity
protectedinherited

◆ _full_upwind_threshold

const unsigned PorousFlowDarcyBase::_full_upwind_threshold
protectedinherited

If the number of upwind-downwind swaps is less than this amount then full upwinding is used.

Otherwise the fallback scheme is employed

Definition at line 141 of file PorousFlowDarcyBase.h.

Referenced by PorousFlowDarcyBase::computeResidualAndJacobian().

◆ _grad_p

const MaterialProperty<std::vector<RealGradient> >& PorousFlowDarcyBase::_grad_p
protectedinherited

Gradient of the pore pressure in each phase.

Definition at line 117 of file PorousFlowDarcyBase.h.

Referenced by PorousFlowDarcyBase::darcyQp(), and PorousFlowDarcyBase::darcyQpJacobian().

◆ _gravity

const RealVectorValue PorousFlowDarcyBase::_gravity
protectedinherited

Gravity. Defaults to 9.81 m/s^2.

Definition at line 132 of file PorousFlowDarcyBase.h.

Referenced by PorousFlowDarcyBase::darcyQp(), and PorousFlowDarcyBase::darcyQpJacobian().

◆ _jacobian

std::vector<std::vector<std::vector<Real> > > PorousFlowDarcyBase::_jacobian
protectedinherited

Derivative of _proto_flux with respect to nodal variables.

This gets modified with the mobility and its derivative during computation of MOOSE's Jacobian

Definition at line 167 of file PorousFlowDarcyBase.h.

Referenced by PorousFlowDarcyBase::computeResidualAndJacobian(), PorousFlowDarcyBase::fullyUpwind(), PorousFlowDarcyBase::harmonicMean(), and PorousFlowDarcyBase::quickUpwind().

◆ _num_downwinds

std::unordered_map<unsigned, std::vector<std::vector<unsigned> > > PorousFlowDarcyBase::_num_downwinds
protectedinherited

Number of nonlinear iterations (in this timestep and this element) that a node is an downwind node for a given fluid phase.

_num_upwinds[element_number][phase][node_number_in_element]

Definition at line 181 of file PorousFlowDarcyBase.h.

Referenced by PorousFlowDarcyBase::computeResidualAndJacobian(), and PorousFlowDarcyBase::timestepSetup().

◆ _num_phases

const unsigned int PorousFlowDarcyBase::_num_phases
protectedinherited

The number of fluid phases.

Definition at line 129 of file PorousFlowDarcyBase.h.

Referenced by PorousFlowDarcyBase::computeResidualAndJacobian().

◆ _num_upwinds

std::unordered_map<unsigned, std::vector<std::vector<unsigned> > > PorousFlowDarcyBase::_num_upwinds
protectedinherited

Number of nonlinear iterations (in this timestep and this element) that a node is an upwind node for a given fluid phase.

_num_upwinds[element_number][phase][node_number_in_element]

Definition at line 174 of file PorousFlowDarcyBase.h.

Referenced by PorousFlowDarcyBase::computeResidualAndJacobian(), and PorousFlowDarcyBase::timestepSetup().

◆ _perm_derivs

const bool PorousFlowDarcyBase::_perm_derivs
protectedinherited

Flag to check whether permeabiity derivatives are non-zero.

Definition at line 135 of file PorousFlowDarcyBase.h.

Referenced by PorousFlowDarcyBase::darcyQpJacobian().

◆ _permeability

const MaterialProperty<RealTensorValue>& PorousFlowDarcyBase::_permeability
protectedinherited

Permeability of porous material.

Definition at line 87 of file PorousFlowDarcyBase.h.

Referenced by PorousFlowDarcyBase::darcyQp(), and PorousFlowDarcyBase::darcyQpJacobian().

◆ _pp

const MaterialProperty<std::vector<Real> >& PorousFlowDarcyBase::_pp
protectedinherited

Nodal pore pressure in each phase.

Definition at line 114 of file PorousFlowDarcyBase.h.

◆ _proto_flux

std::vector<std::vector<Real> > PorousFlowDarcyBase::_proto_flux
protectedinherited

The Darcy flux.

When multiplied by the mobility, this is the mass flux of fluid moving out of a node. This multiplication occurs during the formation of the residual and Jacobian. _proto_flux[num_phases][num_nodes]

Definition at line 160 of file PorousFlowDarcyBase.h.

Referenced by PorousFlowDarcyBase::computeResidualAndJacobian(), PorousFlowDarcyBase::fullyUpwind(), PorousFlowDarcyBase::harmonicMean(), and PorousFlowDarcyBase::quickUpwind().

◆ _relative_permeability

const MaterialProperty<std::vector<Real> >& PorousFlowHeatAdvection::_relative_permeability
protected

Relative permeability of each phase.

Definition at line 40 of file PorousFlowHeatAdvection.h.

Referenced by dmobility(), and mobility().


The documentation for this class was generated from the following files:
PorousFlowHeatAdvection::_denthalpy_dvar
const MaterialProperty< std::vector< std::vector< Real > > > & _denthalpy_dvar
Derivative of the enthalpy wrt PorousFlow variables.
Definition: PorousFlowHeatAdvection.h:37
PorousFlowDarcyBase::_dictator
const PorousFlowDictator & _dictator
PorousFlowDictator UserObject.
Definition: PorousFlowDarcyBase.h:126
PorousFlowDarcyBase::_full_upwind_threshold
const unsigned _full_upwind_threshold
If the number of upwind-downwind swaps is less than this amount then full upwinding is used.
Definition: PorousFlowDarcyBase.h:141
PorousFlowDarcyBase::_dgrad_p_dgrad_var
const MaterialProperty< std::vector< std::vector< Real > > > & _dgrad_p_dgrad_var
Derivative of Grad porepressure in each phase wrt grad(PorousFlow variables)
Definition: PorousFlowDarcyBase.h:120
PorousFlowDarcyBase::quickUpwind
void quickUpwind(JacRes res_or_jac, unsigned int ph, unsigned int pvar)
Calculate the residual or Jacobian using the nodal mobilities, but without conserving fluid mass.
Definition: PorousFlowDarcyBase.C:420
PorousFlowDarcyBase::JacRes::CALCULATE_RESIDUAL
PorousFlowDarcyBase::_fallback_scheme
enum PorousFlowDarcyBase::FallbackEnum _fallback_scheme
PorousFlowDarcyBase::_grad_p
const MaterialProperty< std::vector< RealGradient > > & _grad_p
Gradient of the pore pressure in each phase.
Definition: PorousFlowDarcyBase.h:117
PorousFlowDarcyBase::_fluid_viscosity
const MaterialProperty< std::vector< Real > > & _fluid_viscosity
Viscosity of each component in each phase.
Definition: PorousFlowDarcyBase.h:108
PorousFlowDarcyBase::_dfluid_density_qp_dvar
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)
Definition: PorousFlowDarcyBase.h:105
pow
ExpressionBuilder::EBTerm pow(const ExpressionBuilder::EBTerm &left, T exponent)
Definition: ExpressionBuilder.h:673
PorousFlowDictator::notPorousFlowVariable
bool notPorousFlowVariable(unsigned int moose_var_num) const
Returns true if moose_var_num is not a porous flow variabe.
Definition: PorousFlowDictator.C:161
PorousFlowDarcyBase::_perm_derivs
const bool _perm_derivs
Flag to check whether permeabiity derivatives are non-zero.
Definition: PorousFlowDarcyBase.h:135
PorousFlowDarcyBase::_fluid_density_node
const MaterialProperty< std::vector< Real > > & _fluid_density_node
Fluid density for each phase (at the node)
Definition: PorousFlowDarcyBase.h:96
PorousFlowDarcyBase::_num_upwinds
std::unordered_map< unsigned, std::vector< std::vector< unsigned > > > _num_upwinds
Number of nonlinear iterations (in this timestep and this element) that a node is an upwind node for ...
Definition: PorousFlowDarcyBase.h:174
PorousFlowHeatAdvection::_drelative_permeability_dvar
const MaterialProperty< std::vector< std::vector< Real > > > & _drelative_permeability_dvar
Derivative of relative permeability of each phase wrt PorousFlow variables.
Definition: PorousFlowHeatAdvection.h:43
PorousFlowDarcyBase::_permeability
const MaterialProperty< RealTensorValue > & _permeability
Permeability of porous material.
Definition: PorousFlowDarcyBase.h:87
PorousFlowDarcyBase::JacRes::CALCULATE_JACOBIAN
PorousFlowDarcyBase::_dpermeability_dvar
const MaterialProperty< std::vector< RealTensorValue > > & _dpermeability_dvar
d(permeabiity)/d(PorousFlow variable)
Definition: PorousFlowDarcyBase.h:90
PorousFlowDictator::porousFlowVariableNum
unsigned int porousFlowVariableNum(unsigned int moose_var_num) const
The PorousFlow variable number.
Definition: PorousFlowDictator.C:135
PorousFlowDarcyBase::_jacobian
std::vector< std::vector< std::vector< Real > > > _jacobian
Derivative of _proto_flux with respect to nodal variables.
Definition: PorousFlowDarcyBase.h:167
PorousFlowHeatAdvection::_enthalpy
const MaterialProperty< std::vector< Real > > & _enthalpy
Enthalpy of each phase.
Definition: PorousFlowHeatAdvection.h:34
PorousFlowDarcyBase::_dgrad_p_dvar
const MaterialProperty< std::vector< std::vector< RealGradient > > > & _dgrad_p_dvar
Derivative of Grad porepressure in each phase wrt PorousFlow variables.
Definition: PorousFlowDarcyBase.h:123
PorousFlowDarcyBase::mobility
virtual Real mobility(unsigned nodenum, unsigned phase) const
The mobility of the fluid.
Definition: PorousFlowDarcyBase.C:511
PorousFlowDarcyBase::fullyUpwind
void fullyUpwind(JacRes res_or_jac, unsigned int ph, unsigned int pvar)
Calculate the residual or Jacobian using full upwinding.
Definition: PorousFlowDarcyBase.C:307
PorousFlowDarcyBase::_num_downwinds
std::unordered_map< unsigned, std::vector< std::vector< unsigned > > > _num_downwinds
Number of nonlinear iterations (in this timestep and this element) that a node is an downwind node fo...
Definition: PorousFlowDarcyBase.h:181
PorousFlowDarcyBase::_dfluid_viscosity_dvar
const MaterialProperty< std::vector< std::vector< Real > > > & _dfluid_viscosity_dvar
Derivative of the fluid viscosity for each phase wrt PorousFlow variables.
Definition: PorousFlowDarcyBase.h:111
PorousFlowDarcyBase::FallbackEnum::HARMONIC
PorousFlowDarcyBase::_dfluid_density_node_dvar
const MaterialProperty< std::vector< std::vector< Real > > > & _dfluid_density_node_dvar
Derivative of the fluid density for each phase wrt PorousFlow variables (at the node)
Definition: PorousFlowDarcyBase.h:99
PorousFlowDarcyBase::harmonicMean
void harmonicMean(JacRes res_or_jac, unsigned int ph, unsigned int pvar)
Calculate the residual or Jacobian by using the harmonic mean of the nodal mobilities for the entire ...
Definition: PorousFlowDarcyBase.C:457
PorousFlowDarcyBase::darcyQp
virtual Real darcyQp(unsigned int ph) const
The Darcy part of the flux (this is the non-upwinded part)
Definition: PorousFlowDarcyBase.C:95
PorousFlowDarcyBase::darcyQpJacobian
virtual Real darcyQpJacobian(unsigned int jvar, unsigned int ph) const
Jacobian of the Darcy part of the flux.
Definition: PorousFlowDarcyBase.C:102
PorousFlowDarcyBase::_num_phases
const unsigned int _num_phases
The number of fluid phases.
Definition: PorousFlowDarcyBase.h:129
PorousFlowDarcyBase::computeResidualAndJacobian
void computeResidualAndJacobian(JacRes res_or_jac, unsigned int jvar)
Computation of the residual and Jacobian.
Definition: PorousFlowDarcyBase.C:153
PorousFlowDarcyBase::_gravity
const RealVectorValue _gravity
Gravity. Defaults to 9.81 m/s^2.
Definition: PorousFlowDarcyBase.h:132
PorousFlowHeatAdvection::_relative_permeability
const MaterialProperty< std::vector< Real > > & _relative_permeability
Relative permeability of each phase.
Definition: PorousFlowHeatAdvection.h:40
PorousFlowDarcyBase::FallbackEnum::QUICK
PorousFlowDarcyBase::_fluid_density_qp
const MaterialProperty< std::vector< Real > > & _fluid_density_qp
Fluid density for each phase (at the qp)
Definition: PorousFlowDarcyBase.h:102
PorousFlowDarcyBase::PorousFlowDarcyBase
PorousFlowDarcyBase(const InputParameters &parameters)
Definition: PorousFlowDarcyBase.C:45
PorousFlowDarcyBase::dmobility
virtual Real dmobility(unsigned nodenum, unsigned phase, unsigned pvar) const
The derivative of mobility with respect to PorousFlow variable pvar.
Definition: PorousFlowDarcyBase.C:517
PorousFlowDarcyBase::_proto_flux
std::vector< std::vector< Real > > _proto_flux
The Darcy flux.
Definition: PorousFlowDarcyBase.h:160
PorousFlowDarcyBase::_dpermeability_dgradvar
const MaterialProperty< std::vector< std::vector< RealTensorValue > > > & _dpermeability_dgradvar
d(permeabiity)/d(grad(PorousFlow variable))
Definition: PorousFlowDarcyBase.h:93