https://mooseframework.inl.gov
Loading...
Searching...
No Matches
LinearFVGradientInterface.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
15#include "FEProblemBase.h"
16#include "PerfGraphInterface.h"
17#include "PerfGuard.h"
18#include "SystemBase.h"
20#include "MooseError.h"
21
22#include "libmesh/numeric_vector.h"
23
24using namespace libMesh;
25
26void
28{
29 // No gradients have been requested, by now we should have set up the
30 // containers to receive the gradients. Time to early return.
31 if (_raw_grad_container.empty())
32 return;
33
34 auto & temporary_gradient = temporaryLinearFVGradientContainer();
35 mooseAssert(temporary_gradient.size() == _raw_grad_container.size(),
36 "Temporary and raw gradient containers must have the same size.");
37 for (auto & vec : temporary_gradient)
38 vec->zero();
39
40 auto & fe_problem = _sys.feProblem();
41 auto * const perf_graph_interface = dynamic_cast<PerfGraphInterface *>(&_sys);
42 mooseAssert(perf_graph_interface,
43 "LinearFVGradientInterface requires its owning system to implement "
44 "PerfGraphInterface.");
45 const auto perf_id = perf_graph_interface->registerTimedSection("LinearVariableFV_Gradients", 3);
46 mooseAssert(!Threads::in_threads, "PerfGraph timing cannot be used within threaded sections");
47 PerfGuard time_guard(perf_graph_interface->perfGraph(), perf_id);
48
49 PARALLEL_TRY
50 {
52 FaceInfoRange face_info_range(fe_problem.mesh().ownedFaceInfoBegin(),
53 fe_problem.mesh().ownedFaceInfoEnd());
54
56 fe_problem, _sys, temporary_gradient);
57 Threads::parallel_reduce(face_info_range, gradient_face_thread);
58 }
59 fe_problem.checkExceptionAndStopSolve();
60
61 for (auto & vec : temporary_gradient)
62 vec->close();
63
64 PARALLEL_TRY
65 {
67 ElemInfoRange elem_info_range(fe_problem.mesh().ownedElemInfoBegin(),
68 fe_problem.mesh().ownedElemInfoEnd());
69
71 fe_problem, _sys, temporary_gradient);
72 Threads::parallel_reduce(elem_info_range, gradient_volume_thread);
73 }
74 fe_problem.checkExceptionAndStopSolve();
75
76 for (const auto i : index_range(_raw_grad_container))
77 temporary_gradient[i]->close();
78
79 _raw_grad_container.swap(temporary_gradient);
80
82 {
84 ElemInfoRange elem_info_range(fe_problem.mesh().ownedElemInfoBegin(),
85 fe_problem.mesh().ownedElemInfoEnd());
86
87 for (const auto limiter_type : requestedLinearFVLimitedGradientTypes())
88 {
89 if (limiter_type == Moose::FV::GradientLimiterType::None)
90 continue;
91
92 auto & raw_container = rawLinearFVLimitedGradientContainer(limiter_type);
93 auto & temporary_container = temporaryLinearFVLimitedGradientContainer(limiter_type);
94 mooseAssert(temporary_container.size() == raw_container.size(),
95 "Temporary and raw limited gradient containers must have the same size.");
96 for (auto & vec : temporary_container)
97 vec->zero();
98
99 PARALLEL_TRY
100 {
101 ComputeLinearFVLimitedGradientThread limited_gradient_thread(
102 fe_problem,
103 _sys,
105 temporary_container,
106 limiter_type,
108 Threads::parallel_reduce(elem_info_range, limited_gradient_thread);
109 }
110 fe_problem.checkExceptionAndStopSolve();
111
112 for (auto & vec : temporary_container)
113 vec->close();
114
115 raw_container.swap(temporary_container);
116 }
117 }
118}
119
120bool
122{
123 for (const auto * const field_var : _sys.variableWarehouse().fieldVariables())
124 if (field_var->needsGradientVectorStorage())
125 return true;
126
127 return false;
128}
129
130void
132 std::vector<std::unique_ptr<NumericVector<Number>>> & container) const
133{
134 container.clear();
135 mooseAssert(_sys.currentSolution(),
136 "Current solution must exist before building FV gradient storage.");
137 for (unsigned int i = 0; i < _sys.mesh().dimension(); ++i)
138 container.push_back(_sys.currentSolution()->zero_clone());
139}
140
141void
164
165void
167 const Moose::FV::GradientLimiterType limiter_type, const unsigned int variable_number)
168{
169 if (limiter_type == Moose::FV::GradientLimiterType::None)
170 return;
171
172 auto * const variable =
173 dynamic_cast<MooseVariableFieldBase *>(_sys.variableWarehouse().getVariable(variable_number));
174 if (!variable)
175 mooseError("Limited gradients were requested for variable number ",
176 variable_number,
177 " on system '",
178 _sys.name(),
179 "', but no field variable with that number exists on the system.");
180
181 if (!variable->needsGradientVectorStorage())
182 mooseError("Limited gradients were requested for variable '",
183 variable->name(),
184 "' on system '",
185 _sys.name(),
186 "', but regular gradients were not requested for that variable.");
187
188 _requested_limited_gradient_variables[limiter_type].insert(variable_number);
189
190 if (_requested_limited_gradient_types.insert(limiter_type).second && !_raw_grad_container.empty())
191 {
194 }
195}
196
197const std::vector<std::unique_ptr<NumericVector<Number>>> &
199 const Moose::FV::GradientLimiterType limiter_type) const
200{
201 if (limiter_type == Moose::FV::GradientLimiterType::None)
202 return _raw_grad_container;
203
204 const auto it = _raw_limited_grad_containers.find(limiter_type);
205 if (it == _raw_limited_grad_containers.end())
206 mooseError("Limited gradient container was requested but not initialized on system '",
207 _sys.name(),
208 "'.");
209
210 return it->second;
211}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
The gradient in a volume using Green Gauss theorem and a cell-centered finite-volume approximation ca...
The gradient in a volume using Green Gauss theorem and a cell-centered finite-volume approximation ca...
Compute limited cell gradients for linear FV variables.
void rebuildLinearFVGradientStorage()
Rebuild persistent raw and temporary gradient storage after mesh/DOF changes.
std::vector< std::unique_ptr< libMesh::NumericVector< libMesh::Number > > > & temporaryLinearFVLimitedGradientContainer(const Moose::FV::GradientLimiterType limiter_type)
Return temporary storage for limited gradients during gradient assembly.
std::vector< std::unique_ptr< libMesh::NumericVector< libMesh::Number > > > & temporaryLinearFVGradientContainer()
Return temporary storage for gradients during gradient assembly.
SystemBase & _sys
Reference to the system object.
std::vector< std::unique_ptr< libMesh::NumericVector< libMesh::Number > > > _raw_grad_container
Persisted raw cell-centered gradient components keyed by spatial direction.
const std::unordered_set< unsigned int > & requestedLinearFVLimitedGradientVariables(const Moose::FV::GradientLimiterType limiter_type) const
Access the variable numbers that requested limited gradients for a specific limiter.
std::unordered_map< Moose::FV::GradientLimiterType, std::vector< std::unique_ptr< libMesh::NumericVector< libMesh::Number > > > > _temporary_limited_gradient
Scratch storage for limited gradients assembled during the current compute pass.
void initializeContainer(std::vector< std::unique_ptr< libMesh::NumericVector< libMesh::Number > > > &container) const
std::vector< std::unique_ptr< libMesh::NumericVector< libMesh::Number > > > _temporary_gradient
Scratch storage for raw gradients assembled during the current compute pass.
void requestLinearFVLimitedGradients(const Moose::FV::GradientLimiterType limiter_type, unsigned int variable_number)
Request storage and assembly of limiter-specific cell gradients.
const std::vector< std::unique_ptr< libMesh::NumericVector< libMesh::Number > > > & linearFVLimitedGradientContainer(const Moose::FV::GradientLimiterType limiter_type) const
Access the stored raw or limited cell-centered gradient components.
std::unordered_map< Moose::FV::GradientLimiterType, std::unordered_set< unsigned int > > _requested_limited_gradient_variables
Variable numbers requesting limited gradients, keyed by limiter type.
const std::unordered_set< Moose::FV::GradientLimiterType > & requestedLinearFVLimitedGradientTypes() const
Access the limiter types requested for this system.
std::unordered_set< Moose::FV::GradientLimiterType > _requested_limited_gradient_types
Set of requested limiter types for which limited gradients should be computed.
void computeGradients()
Compute and store raw and requested limited Green-Gauss gradients for linear FV variables.
std::unordered_map< Moose::FV::GradientLimiterType, std::vector< std::unique_ptr< libMesh::NumericVector< libMesh::Number > > > > _raw_limited_grad_containers
Persisted limited gradient components keyed by limiter type.
std::vector< std::unique_ptr< libMesh::NumericVector< libMesh::Number > > > & rawLinearFVLimitedGradientContainer(const Moose::FV::GradientLimiterType limiter_type)
Access the persisted limited-gradient storage for a specific limiter.
This class provides an interface for common operations on field variables of both FE and FV types wit...
Interface for objects interacting with the PerfGraph.
Scope guard for starting and stopping timing for a node.
Definition PerfGuard.h:26
virtual const NumericVector< Number > *const & currentSolution() const =0
The solution vector that is currently being operated on.
FEProblemBase & feProblem()
Definition SystemBase.h:104
virtual const std::string & name() const
const VariableWarehouse & variableWarehouse(THREAD_ID tid=0) const
Definition SystemBase.h:775
MooseMesh & mesh()
Definition SystemBase.h:100
MooseVariableBase * getVariable(const std::string &var_name) const
Get a variable from the warehouse.
const std::vector< MooseVariableFieldBase * > & fieldVariables() const
Get the list of variables.
virtual std::unique_ptr< NumericVector< T > > zero_clone() const=0
GradientLimiterType
Cell-gradient limiter variants used for MUSCL-style reconstructions.
@ None
No gradient limiting.
void parallel_reduce(const Range &range, Body &body, unsigned int n_threads=libMesh::n_threads())
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
auto index_range(const T &sizable)