ResetSubdomainSolver.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 #include <tuple>
8 
11 #include "IO/Logging/Tags.hpp"
12 #include "IO/Logging/Verbosity.hpp"
13 #include "Parallel/Printf.hpp"
14 #include "ParallelAlgorithms/LinearSolver/Schwarz/Tags.hpp"
15 #include "Utilities/Gsl.hpp"
16 #include "Utilities/TMPL.hpp"
17 
18 /// \cond
19 namespace Parallel {
20 template <typename Metavariables>
21 struct GlobalCache;
22 } // namespace Parallel
23 namespace tuples {
24 template <typename...>
25 struct TaggedTuple;
26 } // namespace tuples
27 /// \endcond
28 
30 
31 /*!
32  * \brief Reset the subdomain solver, clearing its caches related to the linear
33  * operator it has solved so far.
34  *
35  * Invoke this action when the linear operator has changed. For example, an
36  * operator representing the linearization of a nonlinear operator changes
37  * whenever the point around which it is being linearized gets updated, i.e. in
38  * every iteration of a nonlinear solve. Note that the operator does _not_
39  * change between iterations of a linear solve, so make sure you place this
40  * action _outside_ the looping action list for the linear solve.
41  *
42  * \par Skipping the reset:
43  * Depending on the subdomain solver in use, the reset may incur significant
44  * re-initialization cost the next time the subdomain solver is invoked. See the
45  * `LinearSolver::Serial::ExplicitInverse` solver for an example of a subdomain
46  * solver with high initialization cost. For this reason the reset can be
47  * skipped with the option
48  * `LinearSolver::Schwarz::Tags::SkipSubdomainSolverResets`. Skipping resets
49  * means that caches built up for the linear operator are never cleared, so
50  * expensive re-initializations are avoided but the subdomain solves may be
51  * increasingly inaccurate or slow down as the linear operator changes over
52  * nonlinear solver iterations. Whether or not skipping resets helps with the
53  * overall convergence of the solve is highly problem-dependent. A possible
54  * optimization would be to decide at runtime whether or not to reset the
55  * subdomain solver.
56  */
57 template <typename OptionsGroup>
59  using const_global_cache_tags = tmpl::list<
62  template <typename DbTagsList, typename... InboxTags, typename Metavariables,
63  size_t Dim, typename ActionList, typename ParallelComponent>
64  static std::tuple<db::DataBox<DbTagsList>&&> apply(
65  db::DataBox<DbTagsList>& box,
66  const tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
67  const Parallel::GlobalCache<Metavariables>& /*cache*/,
68  const ElementId<Dim>& element_id, const ActionList /*meta*/,
69  const ParallelComponent* const /*meta*/) noexcept {
71  OptionsGroup>>(box)) {
73  ::Verbosity::Debug)) {
74  Parallel::printf("%s %s: Reset subdomain solver\n", element_id,
75  Options::name<OptionsGroup>());
76  }
77  db::mutate<
79  make_not_null(&box), [](const auto subdomain_solver) noexcept {
80  // Dereference the gsl::not_null pointer, and then the
81  // std::unique_ptr for the subdomain solver's abstract superclass.
82  // This needs adjustment if the subdomain solver is stored in the
83  // DataBox directly as a derived class and thus there's no
84  // std::unique_ptr. Note that std::unique_ptr also has a `reset`
85  // function, which must not be confused with the serial linear
86  // solver's `reset` function here.
87  (*subdomain_solver)->reset();
88  });
89  }
90  return {std::move(box)};
91  }
92 };
93 
94 } // namespace LinearSolver::Schwarz::Actions
UNLIKELY
#define UNLIKELY(x)
Definition: Gsl.hpp:73
Parallel::GlobalCache
Definition: ElementReceiveInterpPoints.hpp:15
Parallel::printf
void printf(const std::string &format, Args &&... args)
Print an atomic message to stdout with C printf usage.
Definition: Printf.hpp:103
tuple
db::get
const auto & get(const DataBox< TagList > &box) noexcept
Retrieve the item with tag Tag from the DataBox.
Definition: DataBox.hpp:791
ElementId< Dim >
ElementId.hpp
db::mutate
decltype(auto) mutate(const gsl::not_null< DataBox< TagList > * > box, Invokable &&invokable, Args &&... args) noexcept
Allows changing the state of one or more non-computed elements in the DataBox.
Definition: DataBox.hpp:641
LinearSolver::Schwarz::Tags::SubdomainSolverBase
The serial linear solver used to solve subdomain operators.
Definition: Tags.hpp:75
Printf.hpp
DataBox.hpp
cstddef
logging::Tags::Verbosity
Tag for putting Verbosity in a DataBox.
Definition: Tags.hpp:33
LinearSolver::Schwarz::Tags::SkipSubdomainSolverResets
Skip resets of the subdomain solver.
Definition: Tags.hpp:98
tuples::TaggedTuple
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:271
LinearSolver::Schwarz::Actions::ResetSubdomainSolver
Reset the subdomain solver, clearing its caches related to the linear operator it has solved so far.
Definition: ResetSubdomainSolver.hpp:58
LinearSolver::Schwarz::Actions
Actions related to the Schwarz solver.
Definition: CommunicateOverlapFields.hpp:39
Gsl.hpp
make_not_null
gsl::not_null< T * > make_not_null(T *ptr) noexcept
Construct a not_null from a pointer. Often this will be done as an implicit conversion,...
Definition: Gsl.hpp:880
Parallel
Functionality for parallelization.
Definition: ElementReceiveInterpPoints.hpp:13
TMPL.hpp