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 : _fe_problem(fe_problem),
21 _dim(_fe_problem.mesh().dimension()),
22 _system(system),
23 _libmesh_system(system.system()),
24 _system_number(_libmesh_system.number()),
25 _temporary_gradient(temporary_gradient)
26{
27}
28
31 : _fe_problem(x._fe_problem),
32 _dim(x._dim),
33 _system(x._system),
34 _libmesh_system(x._libmesh_system),
35 _system_number(x._system_number),
36 // This will be the vector we work on since the old gradient might still be needed
37 // to compute extrapolated boundary conditions for example.
38 _temporary_gradient(x._temporary_gradient)
39{
40}
41
42void
44{
46 _tid = puid.id;
47
48 unsigned int size = 0;
49
50 for (const auto & variable : _system.getVariables(_tid))
51 {
52 _current_var = dynamic_cast<MooseLinearVariableFV<Real> *>(variable);
53 if (!_current_var)
54 continue;
55
57 {
58 if (!size)
59 size = range.size();
60
61 std::vector<std::vector<Real>> temporary_values_elem(_temporary_gradient.size(),
62 std::vector<Real>(size, 0.0));
63 std::vector<std::vector<Real>> temporary_values_neighbor(_temporary_gradient.size(),
64 std::vector<Real>(size, 0.0));
65 std::vector<dof_id_type> dof_indices_elem(size, 0);
66 std::vector<dof_id_type> dof_indices_neighbor(size, 0);
67
68 {
70
71 // Iterate over all the face infos in the range
72 auto face_iterator = range.begin();
73 for (const auto & face_i : make_range(size))
74 {
75 const auto & face_info = *face_iterator;
76
77 const auto current_face_type =
78 face_info->faceType(std::make_pair(_current_var->number(), _system_number));
79
80 // First we check if this face is internal to the variable, if yes, contribute to both
81 // sides
82 if (current_face_type == FaceInfo::VarFaceNeighbors::BOTH)
83 {
84 dof_indices_elem[face_i] =
85 face_info->elemInfo()->dofIndices()[_system_number][_current_var->number()];
86 dof_indices_neighbor[face_i] =
87 face_info->neighborInfo()->dofIndices()[_system_number][_current_var->number()];
88
89 const auto face_value =
90 Moose::FV::linearInterpolation(solution_reader(dof_indices_elem[face_i]),
91 solution_reader(dof_indices_neighbor[face_i]),
92 *face_info,
93 true);
94
95 const auto contribution =
96 face_info->normal() * face_info->faceArea() * face_info->faceCoord() * face_value;
97
98 for (const auto i : make_range(_dim))
99 {
100 temporary_values_elem[i][face_i] = contribution(i);
101 temporary_values_neighbor[i][face_i] = -contribution(i);
102 }
103 }
104 // If this face is on the boundary of the block where the variable is defined, we
105 // check for boundary conditions. If we don't find any we use an automatic one-term
106 // expansion to compute the face value.
107 else if (current_face_type == FaceInfo::VarFaceNeighbors::ELEM ||
108 current_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR)
109 {
110 auto * bc_pointer =
111 _current_var->getBoundaryCondition(*face_info->boundaryIDs().begin());
112
113 if (bc_pointer)
114 bc_pointer->setupFaceData(face_info, current_face_type);
115
116 const auto * const elem_info = current_face_type == FaceInfo::VarFaceNeighbors::ELEM
117 ? face_info->elemInfo()
118 : face_info->neighborInfo();
119
120 // We have to account for cases when this face is an internal boundary and the normal
121 // points in the wrong direction
122 const auto multiplier =
123 current_face_type == FaceInfo::VarFaceNeighbors::ELEM ? 1.0 : -1.0;
124 auto & dof_id_container = current_face_type == FaceInfo::VarFaceNeighbors::ELEM
125 ? dof_indices_elem
126 : dof_indices_neighbor;
127 auto & contribution_container = current_face_type == FaceInfo::VarFaceNeighbors::ELEM
128 ? temporary_values_elem
129 : temporary_values_neighbor;
130
131 dof_id_container[face_i] =
132 elem_info->dofIndices()[_system_number][_current_var->number()];
133
134 // If we don't have a boundary condition, then it's a natural condition. We'll use a
135 // one-term expansion approximation in that case
136 const auto contribution = multiplier * face_info->normal() * face_info->faceArea() *
137 face_info->faceCoord() *
138 (bc_pointer ? bc_pointer->computeBoundaryValue()
139 : solution_reader(dof_id_container[face_i]));
140 for (const auto i : make_range(_dim))
141 contribution_container[i][face_i] = contribution(i);
142 }
143 face_iterator++;
144 }
145 }
146 for (const auto i : make_range(_dim))
147 {
148 _temporary_gradient[i]->add_vector(temporary_values_elem[i].data(), dof_indices_elem);
149 _temporary_gradient[i]->add_vector(temporary_values_neighbor[i].data(),
150 dof_indices_neighbor);
151 }
152 }
153 }
154}
155
156void
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)
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.
const libMesh::System & _libmesh_system
Reference to the libMesh system backing the wrapper system.
ComputeLinearFVGreenGaussGradientFaceThread(FEProblemBase &fe_problem, SystemBase &system, std::vector< std::unique_ptr< NumericVector< Number > > > &temporary_gradient)
Class constructor.
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.
virtual bool needsGradientVectorStorage() const override
Check if cell gradient computations were requested for this variable.
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.