www.mooseframework.org
FluxLimitedTVDAdvection.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 
11 #include "SystemBase.h"
12 #include "Assembly.h"
13 
15 
16 template <>
17 InputParameters
19 {
20  InputParameters params = validParams<Kernel>();
21  params.addClassDescription("Conservative form of $\\nabla \\cdot \\vec{v} u$ (advection), using "
22  "the Flux Limited TVD scheme invented by Kuzmin and Turek");
23  params.addRequiredParam<UserObjectName>("advective_flux_calculator",
24  "AdvectiveFluxCalculator UserObject");
25  return params;
26 }
27 
28 FluxLimitedTVDAdvection::FluxLimitedTVDAdvection(const InputParameters & parameters)
29  : Kernel(parameters),
30  _fluo(getUserObject<AdvectiveFluxCalculatorBase>("advective_flux_calculator"))
31 {
32 }
33 
34 Real
36 {
37  mooseError("FluxLimitedTVDAdvection::computeQpResidual() called\n");
38  return 0.0;
39 }
40 
41 void
43 {
44  prepareVectorTag(_assembly, _var.number());
45  precalculateResidual();
46 
47  // get the residual contributions from _fluo
48  for (unsigned i = 0; i < _current_elem->n_nodes(); ++i)
49  {
50  const dof_id_type node_id_i = _current_elem->node_id(i);
51  _local_re(i) = _fluo.getFluxOut(node_id_i) / _fluo.getValence(node_id_i);
52  }
53 
54  accumulateTaggedLocalResidual();
55 
56  if (_has_save_in)
57  {
58  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
59  for (unsigned int i = 0; i < _save_in.size(); i++)
60  _save_in[i]->sys().solution().add_vector(_local_re, _save_in[i]->dofIndices());
61  }
62 }
63 
64 void
66 {
67  prepareMatrixTag(_assembly, _var.number(), _var.number());
68  precalculateJacobian();
69 
70  // Run through the nodes of this element using "i", getting the Jacobian contributions
71  // d(residual_i)/du(node_j) for all nodes j that can have a nonzero Jacobian contribution. Some
72  // of these node_j will live in this element, but some will live in other elements connected with
73  // node "i", and some will live in the next layer of nodes (eg, in 1D residual_3 could have
74  // contributions from node1, node2, node3, node4 and node5).
75  for (unsigned i = 0; i < _current_elem->n_nodes(); ++i)
76  {
77  // global id of node "i"
78  const dof_id_type node_id_i = _current_elem->node_id(i);
79  // dof number of _var on node "i"
80  std::vector<dof_id_type> idof_indices(
81  1, _current_elem->node_ref(i).dof_number(_sys.number(), _var.number(), 0));
82  // number of times node "i" is encountered in a sweep over elements
83  const unsigned valence = _fluo.getValence(node_id_i);
84 
85  // retrieve the derivative information from _fluo
86  const std::map<dof_id_type, Real> derivs = _fluo.getdFluxOutdu(node_id_i);
87 
88  // now build up the dof numbers of all the "j" nodes and the derivative matrix
89  // d(residual_i)/d(u_j)
90  std::vector<dof_id_type> jdof_indices(derivs.size());
91  DenseMatrix<Number> deriv_matrix(1, derivs.size());
92  unsigned j = 0;
93  for (const auto & node_j_deriv : derivs)
94  {
95  // global id of j:
96  const dof_id_type node_id_j = node_j_deriv.first;
97  // dof at node j:
98  jdof_indices[j] =
99  _mesh.getMesh().node_ref(node_id_j).dof_number(_sys.number(), _var.number(), 0);
100  // derivative must be divided by valence, otherwise the loop over elements will multiple-count
101  deriv_matrix(0, j) = node_j_deriv.second / valence;
102  j++;
103  }
104  // Add the result to the system's Jacobian matrix
105  _assembly.cacheJacobianBlock(deriv_matrix, idof_indices, jdof_indices, _var.scalingFactor());
106  }
107 }
FluxLimitedTVDAdvection::computeQpResidual
virtual Real computeQpResidual() override
Definition: FluxLimitedTVDAdvection.C:35
FluxLimitedTVDAdvection
Advection of the variable with velocity set in the AdvectiveFluxCalculator.
Definition: FluxLimitedTVDAdvection.h:32
FluxLimitedTVDAdvection::_fluo
const AdvectiveFluxCalculatorBase & _fluo
The user object that computes Kuzmin and Turek's K_ij, R+ and R-, etc quantities.
Definition: FluxLimitedTVDAdvection.h:43
AdvectiveFluxCalculatorBase::getdFluxOutdu
const std::map< dof_id_type, Real > & getdFluxOutdu(dof_id_type node_i) const
Returns r where r[j] = d(flux out of global node i)/du(global node j) used in Jacobian computations.
Definition: AdvectiveFluxCalculatorBase.C:731
AdvectiveFluxCalculatorBase::getValence
unsigned getValence(dof_id_type node_i) const
Returns the valence of the global node i Valence is the number of times the node is encountered in a ...
Definition: AdvectiveFluxCalculatorBase.C:749
FluxLimitedTVDAdvection::computeJacobian
virtual void computeJacobian() override
Definition: FluxLimitedTVDAdvection.C:65
registerMooseObject
registerMooseObject("PorousFlowApp", FluxLimitedTVDAdvection)
validParams< FluxLimitedTVDAdvection >
InputParameters validParams< FluxLimitedTVDAdvection >()
Definition: FluxLimitedTVDAdvection.C:18
FluxLimitedTVDAdvection::FluxLimitedTVDAdvection
FluxLimitedTVDAdvection(const InputParameters &parameters)
Definition: FluxLimitedTVDAdvection.C:28
AdvectiveFluxCalculatorBase
Base class to compute Advective fluxes.
Definition: AdvectiveFluxCalculatorBase.h:33
AdvectiveFluxCalculatorBase::getFluxOut
Real getFluxOut(dof_id_type node_i) const
Returns the flux out of lobal node id.
Definition: AdvectiveFluxCalculatorBase.C:743
FluxLimitedTVDAdvection::computeResidual
virtual void computeResidual() override
Definition: FluxLimitedTVDAdvection.C:42
FluxLimitedTVDAdvection.h