https://mooseframework.inl.gov
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"
19 #include "MooseVariableFieldBase.h"
20 #include "MooseError.h"
21 
22 #include "libmesh/numeric_vector.h"
23 
24 using namespace libMesh;
25 
26 void
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 
70  ComputeLinearFVGreenGaussGradientVolumeThread gradient_volume_thread(
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 
81  if (!requestedLinearFVLimitedGradientTypes().empty())
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,
104  _raw_grad_container,
105  temporary_container,
106  limiter_type,
107  requestedLinearFVLimitedGradientVariables(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 
120 bool
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 
130 void
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 
141 void
143 {
144  _raw_grad_container.clear();
145  _temporary_gradient.clear();
146  _raw_limited_grad_containers.clear();
147  _temporary_limited_gradient.clear();
148 
149  if (!needsLinearFVGradientStorage())
150  return;
151 
152  initializeContainer(_raw_grad_container);
153  initializeContainer(_temporary_gradient);
154 
155  for (const auto limiter_type : _requested_limited_gradient_types)
156  {
157  if (limiter_type == Moose::FV::GradientLimiterType::None)
158  continue;
159 
160  initializeContainer(_raw_limited_grad_containers[limiter_type]);
161  initializeContainer(_temporary_limited_gradient[limiter_type]);
162  }
163 }
164 
165 void
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  {
192  initializeContainer(_raw_limited_grad_containers[limiter_type]);
193  initializeContainer(_temporary_limited_gradient[limiter_type]);
194  }
195 }
196 
197 const 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 }
The gradient in a volume using Green Gauss theorem and a cell-centered finite-volume approximation ca...
void rebuildLinearFVGradientStorage()
Rebuild persistent raw and temporary gradient storage after mesh/DOF changes.
GradientLimiterType
Cell-gradient limiter variants used for MUSCL-style reconstructions.
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...
This class provides an interface for common operations on field variables of both FE and FV types wit...
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
Compute limited cell gradients for linear FV variables.
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.
void requestLinearFVLimitedGradients(const Moose::FV::GradientLimiterType limiter_type, unsigned int variable_number)
Request storage and assembly of limiter-specific cell gradients.
void initializeContainer(std::vector< std::unique_ptr< libMesh::NumericVector< libMesh::Number >>> &container) const
Scope guard for starting and stopping timing for a node.
Definition: PerfGuard.h:25
Interface for objects interacting with the PerfGraph.
void parallel_reduce(const Range &range, Body &body, unsigned int n_threads=libMesh::n_threads())
auto index_range(const T &sizable)
void computeGradients()
Compute and store raw and requested limited Green-Gauss gradients for linear FV variables.