25#include "libmesh/numeric_vector.h"
26#include "libmesh/system.h"
32template <
typename DestinationContainer>
35 DestinationContainer & destination)
38 mooseAssert(source.size() == destination.size(),
39 "Gradient state component counts must match when copying states.");
43 mooseAssert(source[component],
"Source gradient component vector must be initialized.");
44 mooseAssert(destination[component],
45 "Destination gradient component vector must be initialized.");
46 *destination[component] = *source[component];
56 if (!fe_problem.hasFVGradientMethod(method_name))
58 if (method_name ==
"green-gauss")
61 fe_problem.addFVGradientMethod(
"FVGreenGaussGradient", method_name, params);
63 else if (method_name ==
"green-gauss-venkatakrishnan")
65 auto params = fe_problem.getMooseApp().getFactory().getValidParams(
"FVGreenGaussGradient");
66 params.set<
MooseEnum>(
"limiter") =
"venkatakrishnan";
67 fe_problem.addFVGradientMethod(
"FVGreenGaussGradient", method_name, params);
71 if (!fe_problem.hasFVGradientMethod(method_name))
72 mooseError(
"Unable to find FVGradientMethod with name '", method_name,
"'");
74 return fe_problem.getFVGradientMethod(method_name);
80 const unsigned int oldest_state)
82 auto *
const variable =
85 mooseError(
"Linear FV gradients were requested for variable number ",
89 "', but no field variable with that number exists on the system.");
92 container.variable_numbers.insert(variable_number);
97 if (current_solution && current_solution->initialized())
99 if (container.current_values.empty())
101 if (container.next_values.empty())
116 mooseAssert(perf_graph_interface,
117 "LinearFVGradientManager requires its owning system to implement "
118 "PerfGraphInterface.");
119 const auto perf_id = perf_graph_interface->registerTimedSection(
"LinearVariableFV_Gradients", 3);
120 mooseAssert(!
Threads::in_threads,
"PerfGraph timing cannot be used within threaded sections");
121 PerfGuard time_guard(perf_graph_interface->perfGraph(), perf_id);
138 mooseError(
"Requested update for a linear FV gradient field from a different system than '",
146 mooseAssert(perf_graph_interface,
147 "LinearFVGradientManager requires its owning system to implement "
148 "PerfGraphInterface.");
150 perf_graph_interface->registerTimedSection(
"LinearVariableFV_Gradients", 3);
151 mooseAssert(!
Threads::in_threads,
"PerfGraph timing cannot be used within threaded sections");
152 PerfGuard time_guard(perf_graph_interface->perfGraph(), perf_id);
159 mooseError(
"Requested update for an unregistered linear FV gradient field on system '",
175 mooseAssert(current_solution && current_solution->initialized(),
176 "Current solution must exist before building FV gradient storage.");
178 for (
auto & component : container)
179 component = current_solution->zero_clone();
184 const unsigned int oldest_state)
186 const auto required_states =
static_cast<std::size_t
>(oldest_state) + 1;
191 " was requested on system '",
193 "' after solution states were initialized. Old gradient states must be requested "
196 if (required_states > old_size)
204 for (
const auto state :
make_range(std::size_t(1), container.state_values.size()))
205 if (container.state_values[state].empty())
208 for (
const auto component :
index_range(state_values))
211 container.state_values[state] = std::move(state_values);
219 "Gradient state storage must contain a current state.");
221 current_view.clear();
224 current_view.push_back(component.get());
229 const unsigned int state,
230 const unsigned int component)
232 return "linear_fv_gradient_" + method.
name() +
"_state_" + std::to_string(state) +
"_component_" +
233 std::to_string(component);
248 if (!app.isRestarting() && !app.isRecovering())
259 if (!restartable_equation_systems.isVariableRestored(
260 _sys.
name(), vector_name, variable.name()))
265 "' using gradient method '",
267 "' was requested on system '",
271 "' was not available in the restart data.");
290 mooseAssert(!container.state_values.empty(),
291 "Gradient state storage must contain a current state.");
292 mooseAssert(!container.state_values[0].empty(),
293 "Gradient storage must be initialized before gradient computation.");
294 mooseAssert(!container.next_values.empty(),
295 "Replacement gradient storage must be initialized before gradient computation.");
296 mooseAssert(container.next_values.size() == container.current_values.size(),
297 "Next and current gradient containers must have the same size.");
308 "Gradient state storage must contain a current state.");
310 "Next and current gradient containers must have the same size.");
329 if (container.current_values.empty())
331 if (container.next_values.empty())
343 method_container_pair.second.current_values.clear();
344 method_container_pair.second.next_values.clear();
345 method_container_pair.second.has_computed_gradient =
false;
355 if (container.state_values.size() > 1 && !container.has_computed_gradient)
359 if (container.state_values.size() > 1 && !container.has_computed_gradient)
368 "Linear FV gradient storage does not support nonlinear iteration states.");
377 const auto number_of_states = container.state_values.size();
378 if (number_of_states <= 1)
381 mooseAssert(container.has_computed_gradient,
382 "Current gradient state must be initialized before advancing time states.");
385 const std::size_t stop = skip_current_to_old ? 1 : 0;
386 for (std::size_t state = number_of_states - 1; state > stop; --state)
387 copyGradient(container.state_values[state - 1], container.state_values[state]);
397 if (container.state_values.size() <= 1)
400 mooseAssert(container.has_computed_gradient,
401 "Current gradient state must be initialized before restoration.");
402 copyGradient(container.state_values[1], container.state_values[0]);
403 copyGradient(container.state_values[0], container.next_values);
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
const RestartableEquationSystems & getRestartableEquationSystems() const
Get the RestartableEquationSystems object.
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.
void resizeGradientStateStorage(LinearFVGradientContainer &container, unsigned int oldest_state)
Ensure that a method container stores every requested time state.
void setCurrentGradientState(LinearFVGradientContainer &container) const
Set solution state zero to the current gradient.
LinearFVGradientContainer & computeLinearFVGradientContainer(const FVGradientMethod &method)
Compute replacement field values for a registered gradient method.
LinearFVGradientReader::GradientContainer GradientContainer
Non-owning view with one vector per spatial component of a cell-centered gradient field.
void initializeContainer(OwnedGradientContainer &container) const
Allocate one zeroed vector per spatial component for gradient storage.
SystemBase & _sys
Reference to the system object.
void finalizeLinearFVGradientContainer(LinearFVGradientContainer &container)
Replace the current gradient storage with the freshly computed new gradients.
std::unordered_map< const FVGradientMethod *, LinearFVGradientContainer > _linear_fv_gradient_container_by_method
Gradient containers keyed by the method object that produces them.
void updateFVGradient(const LinearFVGradientReader &reader)
Update a registered gradient reader explicitly.
void computeGradients()
Compute and finalize all registered linear FV gradient fields.
static std::string gradientStateVectorName(const FVGradientMethod &method, unsigned int state, unsigned int component)
Return the stable system-vector name for one old gradient component.
void rebuildLinearFVGradientStorage()
Rebuild cached gradient values and reusable scratch storage after mesh/DOF changes.
void copyPreviousGradientStates(Moose::SolutionIterationType iteration_type, bool skip_current_to_old)
Copy published gradient values into requested older states.
void initializeGradientStatesForTimeAdvance()
Compute and publish uninitialized gradients before their first time-state advancement.
const FVGradientMethod & resolveFVGradientMethod(const GradientMethodName &method_name)
Resolve a named gradient method, constructing a built-in method when needed.
LinearFVGradientReader registerFVGradient(unsigned int variable_number, const FVGradientMethod &method, unsigned int oldest_state=0)
Register a variable for gradient values produced by a method object.
void checkRestartedGradientHistory(const FVGradientMethod &method, LinearFVGradientContainer &container)
Validate and mark gradient history loaded during restart or recovery.
std::vector< std::unique_ptr< libMesh::NumericVector< libMesh::Number > > > OwnedGradientContainer
Owned vectors used for the current gradient and its replacement.
bool hasLinearFVGradients() const
Whether any linear finite-volume gradient fields have been registered to this object.
void restoreGradientStates()
Restore current gradients from state one after a failed timestep.
void initializeLinearFVGradientHistoryStorage()
Register named system vectors for requested historical gradient states.
void initializeLinearFVGradientStorage()
Initialize private current and replacement gradient storage.
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.
std::vector< libMesh::NumericVector< libMesh::Number > * > GradientContainer
One vector per spatial component of the cell-centered gradient.
Factory & getFactory()
Retrieve a writable reference to the Factory associated with this App.
const std::string & name() const
Get the name of the class.
MooseApp & getMooseApp() const
Get the MooseApp this class is associated with.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
virtual unsigned int dimension() const
Returns MeshBase::mesh_dimension(), (not MeshBase::spatial_dimension()!) of the underlying libMesh me...
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.
MooseVariableFieldBase & getVariable(THREAD_ID tid, const std::string &var_name) const
Gets a reference to a variable of with specified name.
bool solutionStatesInitialized() const
Whether or not the solution states have been initialized via initSolutionState()
FEProblemBase & feProblem()
virtual const std::string & name() const
const VariableWarehouse & variableWarehouse(THREAD_ID tid=0) const
NumericVector< Number > & addVector(const std::string &vector_name, const bool project, const libMesh::ParallelType type)
Adds a solution length vector to the system.
virtual libMesh::System & system()=0
Get the reference to the libMesh system.
MooseVariableBase * getVariable(const std::string &var_name) const
Get a variable from the warehouse.
std::unique_ptr< NumericVector< Number > > current_local_solution
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
auto index_range(const T &sizable)
IntRange< T > make_range(T beg, T end)
Gradient values for all variables using the same gradient method.
bool has_computed_gradient
Whether the current gradient has received a computed value.
bool has_initialized_history
Whether the old gradient states contain valid values.
OwnedGradientContainer current_values
Owned current gradient values.
GradientStateContainer state_values
Published gradient values indexed by solution time state.
bool has_checked_restart_history
Whether restart data has been checked for this gradient method.
std::unordered_set< unsigned int > variable_numbers
Variable numbers whose gradients are stored in the gradient containers.
OwnedGradientContainer next_values
Replacement gradient values computed before publication.