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
13#include "SystemBase.h"
14#include "PetscVectorReader.h"
15#include "FEProblemBase.h"
16
18 FEProblemBase & fe_problem,
19 SystemBase & system,
20 std::vector<std::unique_ptr<NumericVector<Number>>> & temporary_gradient,
21 const std::unordered_set<unsigned int> & gradient_variables,
22 const FVGreenGaussGradient & gradient_method)
23 : _fe_problem(fe_problem),
24 _dim(_fe_problem.mesh().dimension()),
25 _system(system),
26 _libmesh_system(system.system()),
27 _system_number(_libmesh_system.number()),
28 _temporary_gradient(temporary_gradient),
29 _gradient_variables(gradient_variables),
30 _gradient_method(gradient_method)
31{
32}
33
36 : _fe_problem(x._fe_problem),
37 _dim(x._dim),
38 _system(x._system),
39 _libmesh_system(x._libmesh_system),
40 _system_number(x._system_number),
41 // This will be the vector we work on since the old gradient might still be needed
42 // to compute extrapolated boundary conditions for example.
43 _temporary_gradient(x._temporary_gradient),
44 _gradient_variables(x._gradient_variables),
45 _gradient_method(x._gradient_method)
46{
47}
48
49void
51{
53 _tid = puid.id;
54
55 unsigned int size = 0;
56
57 for (const auto & variable : _system.getVariables(_tid))
58 {
59 _current_var = dynamic_cast<MooseLinearVariableFV<Real> *>(variable);
60 if (!_current_var)
61 continue;
62
64 {
65 if (!size)
66 size = range.size();
67
68 std::vector<std::vector<Real>> temporary_values_elem(_temporary_gradient.size(),
69 std::vector<Real>(size, 0.0));
70 std::vector<std::vector<Real>> temporary_values_neighbor(_temporary_gradient.size(),
71 std::vector<Real>(size, 0.0));
72 std::vector<dof_id_type> dof_indices_elem(size, 0);
73 std::vector<dof_id_type> dof_indices_neighbor(size, 0);
74
75 {
77
78 // Iterate over all the face infos in the range
79 auto face_iterator = range.begin();
80 for (const auto & face_i : make_range(size))
81 {
82 const auto & face_info = *face_iterator;
83
84 const auto current_face_type =
85 face_info->faceType(std::make_pair(_current_var->number(), _system_number));
86
87 // First we check if this face is internal to the variable, if yes, contribute to both
88 // sides
89 if (current_face_type == FaceInfo::VarFaceNeighbors::BOTH)
90 {
91 dof_indices_elem[face_i] =
92 face_info->elemInfo()->dofIndices()[_system_number][_current_var->number()];
93 dof_indices_neighbor[face_i] =
94 face_info->neighborInfo()->dofIndices()[_system_number][_current_var->number()];
95
96 const auto face_values =
98 *face_info->elemInfo(),
99 *face_info->neighborInfo(),
101 solution_reader(dof_indices_elem[face_i]),
102 solution_reader(dof_indices_neighbor[face_i]));
103
104 const auto surface_vector =
105 face_info->normal() * face_info->faceArea() * face_info->faceCoord();
106 const auto elem_contribution = surface_vector * face_values.first;
107 const auto neighbor_contribution = -surface_vector * face_values.second;
108
109 for (const auto i : make_range(_dim))
110 {
111 temporary_values_elem[i][face_i] = elem_contribution(i);
112 temporary_values_neighbor[i][face_i] = neighbor_contribution(i);
113 }
114 }
115 // If this face is on the boundary of the block where the variable is defined, we
116 // check for boundary conditions. If we don't find any we use an automatic one-term
117 // expansion to compute the face value.
118 else if (current_face_type == FaceInfo::VarFaceNeighbors::ELEM ||
119 current_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR)
120 {
121 auto * bc_pointer =
122 _current_var->getBoundaryCondition(*face_info->boundaryIDs().begin());
123
124 if (bc_pointer)
125 bc_pointer->setupFaceData(face_info, current_face_type);
126
127 const auto * const elem_info = current_face_type == FaceInfo::VarFaceNeighbors::ELEM
128 ? face_info->elemInfo()
129 : face_info->neighborInfo();
130
131 // We have to account for cases when this face is an internal boundary and the normal
132 // points in the wrong direction
133 const auto multiplier =
134 current_face_type == FaceInfo::VarFaceNeighbors::ELEM ? 1.0 : -1.0;
135 auto & dof_id_container = current_face_type == FaceInfo::VarFaceNeighbors::ELEM
136 ? dof_indices_elem
137 : dof_indices_neighbor;
138 auto & contribution_container = current_face_type == FaceInfo::VarFaceNeighbors::ELEM
139 ? temporary_values_elem
140 : temporary_values_neighbor;
141
142 dof_id_container[face_i] =
143 elem_info->dofIndices()[_system_number][_current_var->number()];
144
145 // If we don't have a boundary condition, then it's a natural condition. We'll use a
146 // one-term expansion approximation in that case
147 const auto contribution = multiplier * face_info->normal() * face_info->faceArea() *
148 face_info->faceCoord() *
149 (bc_pointer ? bc_pointer->computeBoundaryValue()
150 : solution_reader(dof_id_container[face_i]));
151 for (const auto i : make_range(_dim))
152 contribution_container[i][face_i] = contribution(i);
153 }
154 face_iterator++;
155 }
156 }
157 for (const auto i : make_range(_dim))
158 {
159 _temporary_gradient[i]->add_vector(temporary_values_elem[i].data(), dof_indices_elem);
160 _temporary_gradient[i]->add_vector(temporary_values_neighbor[i].data(),
161 dof_indices_neighbor);
162 }
163 }
164 }
165}
166
167void
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
const FVGreenGaussGradient & _gradient_method
Method providing the two Green-Gauss values on an internal face.
ComputeLinearFVGreenGaussGradientFaceThread(FEProblemBase &fe_problem, SystemBase &system, std::vector< std::unique_ptr< NumericVector< Number > > > &temporary_gradient, const std::unordered_set< unsigned int > &gradient_variables, const FVGreenGaussGradient &gradient_method)
Class constructor.
SystemBase & _system
The system wrapper this thread operates on.
const libMesh::System & _libmesh_system
Reference to the libMesh system backing the wrapper system.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
Green-Gauss cell-centered gradient method for linear finite-volume variables.
virtual InternalFaceValues internalFaceValues(const FaceInfo &fi, const ElemInfo &elem_info, const ElemInfo &neighbor_info, const MooseLinearVariableFV< Real > &variable, Real elem_value, Real neighbor_value) const
Return the two Green-Gauss face values on an internal face.
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:782
std::unique_ptr< NumericVector< Number > > current_local_solution
MeshBase & mesh