https://mooseframework.inl.gov
Loading...
Searching...
No Matches
PorousFlowFluxLimitedTVDAdvection.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
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
18{
20 params.addClassDescription("Advective flux of fluid species or heat using "
21 "the Flux Limited TVD scheme invented by Kuzmin and Turek");
22 params.addRequiredParam<UserObjectName>(
23 "PorousFlowDictator", "The UserObject that holds the list of PorousFlow variable names");
24 params.addRequiredParam<UserObjectName>(
25 "advective_flux_calculator",
26 "PorousFlowAdvectiveFluxCalculator UserObject. This determines whether the advection "
27 "describes a movement of a fluid component in a fluid phase, or movement of heat energy in a "
28 "fluid phase");
29 return params;
30}
31
33 const InputParameters & parameters)
34 : Kernel(parameters),
35 _dictator(getUserObject<PorousFlowDictator>("PorousFlowDictator")),
36 _fluo(getUserObject<PorousFlowAdvectiveFluxCalculatorBase>("advective_flux_calculator"))
37{
38}
39
40Real
42{
43 mooseError("PorousFlowFluxLimitedTVDAdvection::computeQpResidual() called\n");
44 return 0.0;
45}
46
47void
49{
52
53 // get the residual contributions from _fluo
54 for (unsigned i = 0; i < _current_elem->n_nodes(); ++i)
55 {
56 const dof_id_type node_id_i = _current_elem->node_id(i);
57 _local_re(i) = _fluo.getFluxOut(node_id_i) / _fluo.getValence(node_id_i);
58 }
59
61
62 if (_has_save_in)
63 {
64 Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
65 for (unsigned int i = 0; i < _save_in.size(); i++)
66 _save_in[i]->sys().solution().add_vector(_local_re, _save_in[i]->dofIndices());
67 }
68}
69
70void
72{
75
76 // Run through the nodes of this element using "i", getting the Jacobian contributions
77 // d(residual_i)/du(node_j) for all nodes j that can have a nonzero Jacobian contribution. Some
78 // of these node_j will live in this element, but some will live in other elements connected with
79 // node "i", and some will live in the next layer of nodes (eg, in 1D residual_3 could have
80 // contributions from node1, node2, node3, node4 and node5).
81 for (unsigned i = 0; i < _current_elem->n_nodes(); ++i)
82 {
83 // global id of node "i"
84 const dof_id_type node_id_i = _current_elem->node_id(i);
85 // dof number of _var on node "i"
86 std::vector<dof_id_type> idof_indices(
87 1, _current_elem->node_ref(i).dof_number(_sys.number(), _var.number(), 0));
88 // number of times node "i" is encountered in a sweep over elements
89 const unsigned valence = _fluo.getValence(node_id_i);
90
91 // retrieve the derivative information from _fluo
92 const std::map<dof_id_type, std::vector<Real>> derivs = _fluo.getdFluxOut_dvars(node_id_i);
93
94 // now build up the dof numbers of all the "j" nodes and the derivative matrix
95 // d(residual_i)/d(var_j)
96 for (unsigned pvar = 0; pvar < _dictator.numVariables(); ++pvar)
97 {
98 const unsigned varnum = _dictator.mooseVariableNum(pvar);
99 std::vector<dof_id_type> jdof_indices(derivs.size());
100 DenseMatrix<Number> deriv_matrix(1, derivs.size());
101 unsigned j = 0;
102 for (const auto & node_j_deriv : derivs)
103 {
104 // global id of j:
105 const dof_id_type node_id_j = node_j_deriv.first;
106 // dof of pvar at node j:
107 jdof_indices[j] = _mesh.getMesh().node_ref(node_id_j).dof_number(_sys.number(), varnum, 0);
108 // derivative must be divided by valence, otherwise the loop over elements will
109 // multiple-count
110 deriv_matrix(0, j) = node_j_deriv.second[pvar] / valence;
111 j++;
112 }
113 // Add the result to the system's Jacobian matrix
114 addJacobian(_assembly, deriv_matrix, idof_indices, jdof_indices, _var.scalingFactor());
115 }
116 }
117}
registerMooseObject("PorousFlowApp", PorousFlowFluxLimitedTVDAdvection)
Real getFluxOut(dof_id_type node_i) const
Returns the flux out of lobal node id.
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 ...
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
std::vector< MooseVariableFEBase * > _save_in
bool _has_save_in
const Elem *const & _current_elem
MooseVariable & _var
static InputParameters validParams()
void mooseError(Args &&... args) const
MeshBase & getMesh()
void scalingFactor(const std::vector< Real > &factor)
unsigned int number() const
Base class to compute the advective flux of fluid in PorousFlow situations using the Kuzmin-Turek FEM...
const std::map< dof_id_type, std::vector< Real > > & getdFluxOut_dvars(unsigned node_id) const
Returns d(flux_out)/d(porous_flow_variables.
This holds maps between the nonlinear variables used in a PorousFlow simulation and the variable numb...
unsigned int numVariables() const
The number of PorousFlow variables.
unsigned int mooseVariableNum(unsigned int porous_flow_var_num) const
The Moose variable number.
Advection of a quantity with velocity set in the PorousFlowAdvectiveFluxCalculator Depending on the P...
const PorousFlowAdvectiveFluxCalculatorBase & _fluo
The user object that computes Kuzmin and Turek's K_ij, R+ and R-, etc quantities.
const PorousFlowDictator & _dictator
PorousFlowDictator UserObject.
PorousFlowFluxLimitedTVDAdvection(const InputParameters &parameters)
virtual void precalculateJacobian()
MooseMesh & _mesh
Assembly & _assembly
SystemBase & _sys
virtual void precalculateResidual()
unsigned int number() const
void prepareMatrixTag(Assembly &assembly, unsigned int ivar, unsigned int jvar)
void addJacobian(Assembly &assembly, const Residuals &residuals, const Indices &dof_indices, Real scaling_factor)
void accumulateTaggedLocalResidual()
void prepareVectorTag(Assembly &assembly, unsigned int ivar)
DenseVector< Number > _local_re