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
12#include "FEProblemBase.h"
13#include "FVGradientMethod.h"
14#include "PerfGraphInterface.h"
15#include "PerfGuard.h"
16#include "SystemBase.h"
18#include "MooseError.h"
19#include "ElemInfo.h"
20#include "FaceInfo.h"
21#include "MathFVUtils.h"
22
23#include "libmesh/numeric_vector.h"
24
25const FVGradientMethod &
26LinearFVGradientInterface::resolveFVGradientMethod(const GradientMethodName & method_name)
27{
28 auto & fe_problem = _sys.feProblem();
29
30 if (!fe_problem.hasFVGradientMethod(method_name))
31 {
32 if (method_name == "green-gauss")
33 {
34 auto params = fe_problem.getMooseApp().getFactory().getValidParams("FVGreenGaussGradient");
35 fe_problem.addFVGradientMethod("FVGreenGaussGradient", method_name, params);
36 }
37 else if (method_name == "green-gauss-venkatakrishnan")
38 {
39 auto params = fe_problem.getMooseApp().getFactory().getValidParams("FVGreenGaussGradient");
40 params.set<MooseEnum>("limiter") = "venkatakrishnan";
41 fe_problem.addFVGradientMethod("FVGreenGaussGradient", method_name, params);
42 }
43 }
44
45 if (!fe_problem.hasFVGradientMethod(method_name))
46 mooseError("Unable to find FVGradientMethod with name '", method_name, "'");
47
48 return fe_problem.getFVGradientMethod(method_name);
49}
50
52LinearFVGradientInterface::registerFVGradient(const unsigned int variable_number,
53 const FVGradientMethod & method)
54{
55 auto * const variable =
56 dynamic_cast<MooseVariableFieldBase *>(_sys.variableWarehouse().getVariable(variable_number));
57 if (!variable)
58 mooseError("Linear FV gradients were requested for variable number ",
59 variable_number,
60 " on system '",
61 _sys.name(),
62 "', but no field variable with that number exists on the system.");
63
64 auto & container = _linear_fv_gradient_container_by_method[&method];
65 container.variable_numbers.insert(variable_number);
67 if (container.values.empty() && _sys.currentSolution())
68 initializeContainer(container.values);
69
70 if (container.next_values.empty() && _sys.currentSolution())
71 initializeContainer(container.next_values);
73 return LinearFVGradientReader(_sys, container.values, method, variable_number);
74}
75
76void
78{
80 return;
81
82 auto * const perf_graph_interface = dynamic_cast<PerfGraphInterface *>(&_sys);
83 mooseAssert(perf_graph_interface,
84 "LinearFVGradientInterface requires its owning system to implement "
85 "PerfGraphInterface.");
86 const auto perf_id = perf_graph_interface->registerTimedSection("LinearVariableFV_Gradients", 3);
87 mooseAssert(!Threads::in_threads, "PerfGraph timing cannot be used within threaded sections");
88 PerfGuard time_guard(perf_graph_interface->perfGraph(), perf_id);
89
90 // Keep current values unchanged until every replacement has been computed so boundary
91 // conditions consistently use gradients from the previous update.
92 // BCs may use cell gradients to compute the boundary face value, which is itself used to
93 // compute cell gradients
94 for (auto & method_container_pair : _linear_fv_gradient_container_by_method)
95 computeLinearFVGradientContainer(*method_container_pair.first);
96
97 for (auto & method_container_pair : _linear_fv_gradient_container_by_method)
98 finalizeLinearFVGradientContainer(method_container_pair.second);
99}
100
101void
103{
104 if (&reader.system() != &_sys)
105 mooseError("Requested update for a linear FV gradient field from a different system than '",
106 _sys.name(),
107 "'.");
108
109 const auto method_container_pair = _linear_fv_gradient_container_by_method.find(&reader.method());
110 if (method_container_pair != _linear_fv_gradient_container_by_method.end())
111 {
112 auto * const perf_graph_interface = dynamic_cast<PerfGraphInterface *>(&_sys);
113 mooseAssert(perf_graph_interface,
114 "LinearFVGradientInterface requires its owning system to implement "
115 "PerfGraphInterface.");
116 const auto perf_id =
117 perf_graph_interface->registerTimedSection("LinearVariableFV_Gradients", 3);
118 mooseAssert(!Threads::in_threads, "PerfGraph timing cannot be used within threaded sections");
119 PerfGuard time_guard(perf_graph_interface->perfGraph(), perf_id);
120
121 auto & container = computeLinearFVGradientContainer(reader.method());
123 return;
124 }
125
126 mooseError("Requested update for an unregistered linear FV gradient field on system '",
127 _sys.name(),
128 "'.");
129}
130
131bool
136
137void
139{
140 container.clear();
141 mooseAssert(_sys.currentSolution(),
142 "Current solution must exist before building FV gradient storage.");
143 for (unsigned int i = 0; i < _sys.mesh().dimension(); ++i)
144 container.push_back(_sys.currentSolution()->zero_clone());
145}
146
149{
150 auto & container = libmesh_map_find(_linear_fv_gradient_container_by_method, &method);
151
152 mooseAssert(!container.values.empty(),
153 "Gradient storage must be initialized before gradient computation.");
154 mooseAssert(!container.next_values.empty(),
155 "Replacement gradient storage must be initialized before gradient computation.");
156 mooseAssert(container.next_values.size() == container.values.size(),
157 "Next and current gradient containers must have the same size.");
158
159 method.computeGradient(_sys, container.next_values, container.variable_numbers);
160
161 return container;
162}
163
164void
166{
167 mooseAssert(container.next_values.size() == container.values.size(),
168 "Next and current gradient containers must have the same size.");
169 container.values.swap(container.next_values);
170}
171
172void
174{
175 for (auto & method_container_pair : _linear_fv_gradient_container_by_method)
176 {
177 method_container_pair.second.values.clear();
178 method_container_pair.second.next_values.clear();
179 }
180
182 return;
183
184 for (auto & method_container_pair : _linear_fv_gradient_container_by_method)
185 {
186 initializeContainer(method_container_pair.second.values);
187 initializeContainer(method_container_pair.second.next_values);
188 }
189}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
Base class for linear finite-volume cell-gradient methods.
void computeGradient(SystemBase &system, GradientContainer &gradient, const std::unordered_set< unsigned int > &variable_numbers) const
Compute the final gradient values for the requested variables.
InputParameters getValidParams(const std::string &name) const
Get valid parameters for the object.
Definition Factory.C:68
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
void rebuildLinearFVGradientStorage()
Rebuild cached gradient values and reusable scratch storage after mesh/DOF changes.
void initializeContainer(GradientContainer &container) const
Allocate one zeroed vector per spatial component for gradient storage.
void finalizeLinearFVGradientContainer(LinearFVGradientContainer &container)
Replace the current gradient storage with the freshly computed new gradients.
SystemBase & _sys
Reference to the system object.
const FVGradientMethod & resolveFVGradientMethod(const GradientMethodName &method_name)
Resolve a named gradient method, constructing a built-in method when needed.
LinearFVGradientContainer & computeLinearFVGradientContainer(const FVGradientMethod &method)
Compute replacement field values for a registered gradient method.
std::unordered_map< const FVGradientMethod *, LinearFVGradientContainer > _linear_fv_gradient_container_by_method
Gradient containers keyed by the method object that produces them.
LinearFVGradientReader::GradientContainer GradientContainer
One vector per spatial component of a cell-centered gradient field.
bool hasLinearFVGradients() const
Whether any linear finite-volume gradient fields have been registered to this object.
void updateFVGradient(const LinearFVGradientReader &reader)
Update a registered gradient reader explicitly.
void computeGradients()
Compute and finalize all registered linear FV gradient fields.
LinearFVGradientReader registerFVGradient(unsigned int variable_number, const FVGradientMethod &method)
Register a variable for gradient values produced by a method object.
Read-only view of one variable's cell-centered linear finite-volume gradient values.
const FVGradientMethod & method() const
Method object that produces the stored values.
const SystemBase & system() const
System whose DOF map indexes the stored values.
Factory & getFactory()
Retrieve a writable reference to the Factory associated with this App.
Definition MooseApp.h:407
MooseApp & getMooseApp() const
Get the MooseApp this class is associated with.
Definition MooseBase.h:87
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
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.
virtual std::unique_ptr< NumericVector< T > > zero_clone() const=0
Gradient values for all variables using the same gradient method.
GradientContainer next_values
Replacement gradient values computed before publication.
GradientContainer values
Current gradient values read by consumers.