https://mooseframework.inl.gov
Loading...
Searching...
No Matches
ComputeLinearFVGreenGaussGradientFaceThread.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
12#include "SystemBase.h"
13#include "PetscVectorReader.h"
14#include "FEProblemBase.h"
15
17 FEProblemBase & fe_problem,
18 SystemBase & system,
19 std::vector<std::unique_ptr<NumericVector<Number>>> & temporary_gradient,
20 const std::unordered_set<unsigned int> & gradient_variables)
21 : _fe_problem(fe_problem),
22 _dim(_fe_problem.mesh().dimension()),
23 _system(system),
24 _libmesh_system(system.system()),
25 _system_number(_libmesh_system.number()),
26 _temporary_gradient(temporary_gradient),
27 _gradient_variables(gradient_variables)
28{
29}
30
33 : _fe_problem(x._fe_problem),
34 _dim(x._dim),
35 _system(x._system),
36 _libmesh_system(x._libmesh_system),
37 _system_number(x._system_number),
38 // This will be the vector we work on since the old gradient might still be needed
39 // to compute extrapolated boundary conditions for example.
40 _temporary_gradient(x._temporary_gradient),
41 _gradient_variables(x._gradient_variables)
42{
43}
44
45void
47{
49 _tid = puid.id;
50
51 unsigned int size = 0;
52
53 for (const auto & variable : _system.getVariables(_tid))
54 {
55 _current_var = dynamic_cast<MooseLinearVariableFV<Real> *>(variable);
56 if (!_current_var)
57 continue;
58
60 {
61 if (!size)
62 size = range.size();
63
64 std::vector<std::vector<Real>> temporary_values_elem(_temporary_gradient.size(),
65 std::vector<Real>(size, 0.0));
66 std::vector<std::vector<Real>> temporary_values_neighbor(_temporary_gradient.size(),
67 std::vector<Real>(size, 0.0));
68 std::vector<dof_id_type> dof_indices_elem(size, 0);
69 std::vector<dof_id_type> dof_indices_neighbor(size, 0);
70
71 {
73
74 // Iterate over all the face infos in the range
75 auto face_iterator = range.begin();
76 for (const auto & face_i : make_range(size))
77 {
78 const auto & face_info = *face_iterator;
79
80 const auto current_face_type =
81 face_info->faceType(std::make_pair(_current_var->number(), _system_number));
82
83 // First we check if this face is internal to the variable, if yes, contribute to both
84 // sides
85 if (current_face_type == FaceInfo::VarFaceNeighbors::BOTH)
86 {
87 dof_indices_elem[face_i] =
88 face_info->elemInfo()->dofIndices()[_system_number][_current_var->number()];
89 dof_indices_neighbor[face_i] =
90 face_info->neighborInfo()->dofIndices()[_system_number][_current_var->number()];
91
92 const auto face_value =
93 Moose::FV::linearInterpolation(solution_reader(dof_indices_elem[face_i]),
94 solution_reader(dof_indices_neighbor[face_i]),
95 *face_info,
96 true);
97
98 const auto contribution =
99 face_info->normal() * face_info->faceArea() * face_info->faceCoord() * face_value;
100
101 for (const auto i : make_range(_dim))
102 {
103 temporary_values_elem[i][face_i] = contribution(i);
104 temporary_values_neighbor[i][face_i] = -contribution(i);
105 }
106 }
107 // If this face is on the boundary of the block where the variable is defined, we
108 // check for boundary conditions. If we don't find any we use an automatic one-term
109 // expansion to compute the face value.
110 else if (current_face_type == FaceInfo::VarFaceNeighbors::ELEM ||
111 current_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR)
112 {
113 auto * bc_pointer =
114 _current_var->getBoundaryCondition(*face_info->boundaryIDs().begin());
115
116 if (bc_pointer)
117 bc_pointer->setupFaceData(face_info, current_face_type);
118
119 const auto * const elem_info = current_face_type == FaceInfo::VarFaceNeighbors::ELEM
120 ? face_info->elemInfo()
121 : face_info->neighborInfo();
122
123 // We have to account for cases when this face is an internal boundary and the normal
124 // points in the wrong direction
125 const auto multiplier =
126 current_face_type == FaceInfo::VarFaceNeighbors::ELEM ? 1.0 : -1.0;
127 auto & dof_id_container = current_face_type == FaceInfo::VarFaceNeighbors::ELEM
128 ? dof_indices_elem
129 : dof_indices_neighbor;
130 auto & contribution_container = current_face_type == FaceInfo::VarFaceNeighbors::ELEM
131 ? temporary_values_elem
132 : temporary_values_neighbor;
133
134 dof_id_container[face_i] =
135 elem_info->dofIndices()[_system_number][_current_var->number()];
136
137 // If we don't have a boundary condition, then it's a natural condition. We'll use a
138 // one-term expansion approximation in that case
139 const auto contribution = multiplier * face_info->normal() * face_info->faceArea() *
140 face_info->faceCoord() *
141 (bc_pointer ? bc_pointer->computeBoundaryValue()
142 : solution_reader(dof_id_container[face_i]));
143 for (const auto i : make_range(_dim))
144 contribution_container[i][face_i] = contribution(i);
145 }
146 face_iterator++;
147 }
148 }
149 for (const auto i : make_range(_dim))
150 {
151 _temporary_gradient[i]->add_vector(temporary_values_elem[i].data(), dof_indices_elem);
152 _temporary_gradient[i]->add_vector(temporary_values_neighbor[i].data(),
153 dof_indices_neighbor);
154 }
155 }
156 }
157}
158
159void
The gradient in a volume using Green Gauss theorem and a cell-centered finite-volume approximation ca...
const unsigned int _system_number
Global system number (the number of this system in the libmesh equation system)
const std::unordered_set< unsigned int > & _gradient_variables
Indices of the variables this producer should compute gradients for.
void join(const ComputeLinearFVGreenGaussGradientFaceThread &y)
Join threads at the end of the execution.
std::vector< std::unique_ptr< NumericVector< Number > > > & _temporary_gradient
Cache for the temporary gradient being built.
void operator()(const FaceInfoRange &range)
Operator which is used to execute the thread over a certain iterator range.
MooseLinearVariableFV< Real > * _current_var
Pointer to the current variable.
StoredRange< MooseMesh::const_face_info_iterator, const FaceInfo * > FaceInfoRange
SystemBase & _system
The system wrapper this thread operates on.
ComputeLinearFVGreenGaussGradientFaceThread(FEProblemBase &fe_problem, SystemBase &system, std::vector< std::unique_ptr< NumericVector< Number > > > &temporary_gradient, const std::unordered_set< unsigned int > &gradient_variables)
Class constructor.
const libMesh::System & _libmesh_system
Reference to the libMesh system backing the wrapper system.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
void setupFaceData(const FaceInfo *face_info, const FaceInfo::VarFaceNeighbors face_type)
Set current face info.
This class provides variable solution interface for linear finite volume problems.
LinearFVBoundaryCondition * getBoundaryCondition(const BoundaryID bd_id) const
Get the boundary condition object which corresponds to the given boundary ID.
unsigned int number() const
Get variable number coming from libMesh.
A class which helps with repeated reading from a petsc vector.
Base class for a system (of equations)
Definition SystemBase.h:87
const std::vector< MooseVariableFieldBase * > & getVariables(THREAD_ID tid)
Definition SystemBase.h:770
std::unique_ptr< NumericVector< Number > > current_local_solution
MeshBase & mesh
libMesh::CompareTypes< T, T2 >::supertype linearInterpolation(const T &value1, const T2 &value2, const FaceInfo &fi, const bool one_is_elem, const InterpMethod interp_method=InterpMethod::Average)
A simple linear interpolation of values between cell centers to a cell face.