SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/LinearSolver/Schwarz - Tags.hpp Hit Total Coverage
Commit: edb1b5199a4a86c269aedbb831767801169f3e8a Lines: 10 50 20.0 %
Date: 2021-04-19 16:23:01
Legend: Lines: hit not hit

          Line data    Source code
       1           0 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : #pragma once
       5             : 
       6             : #include <array>
       7             : #include <cstddef>
       8             : #include <string>
       9             : 
      10             : #include "DataStructures/DataBox/Subitems.hpp"
      11             : #include "DataStructures/DataBox/Tag.hpp"
      12             : #include "DataStructures/DataVector.hpp"
      13             : #include "DataStructures/Tensor/Tensor.hpp"
      14             : #include "DataStructures/Variables.hpp"
      15             : #include "Options/Auto.hpp"
      16             : #include "Options/Options.hpp"
      17             : #include "Parallel/Serialize.hpp"
      18             : #include "ParallelAlgorithms/LinearSolver/Schwarz/OverlapHelpers.hpp"
      19             : #include "Utilities/Gsl.hpp"
      20             : #include "Utilities/TMPL.hpp"
      21             : 
      22             : namespace LinearSolver::Schwarz {
      23             : 
      24             : /// Option tags related to the Schwarz solver
      25           1 : namespace OptionTags {
      26             : 
      27             : template <typename OptionsGroup>
      28           0 : struct MaxOverlap {
      29           0 :   using type = size_t;
      30           0 :   using group = OptionsGroup;
      31           0 :   static constexpr Options::String help =
      32             :       "Number of points that subdomains can extend into neighbors";
      33             : };
      34             : 
      35             : template <typename SolverType, typename OptionsGroup>
      36           0 : struct SubdomainSolver {
      37           0 :   using type = SolverType;
      38           0 :   using group = OptionsGroup;
      39           0 :   static constexpr Options::String help = "The linear solver on subdomains";
      40             : };
      41             : 
      42             : template <typename OptionsGroup>
      43           0 : struct SkipSubdomainSolverResets {
      44           0 :   static std::string name() noexcept { return "SkipResets"; }
      45           0 :   using type = bool;
      46           0 :   using group = OptionsGroup;
      47           0 :   static constexpr Options::String help =
      48             :       "Skip resets of the subdomain solver. This only has an effect in cases "
      49             :       "where the operator changes, e.g. between nonlinear-solver iterations. "
      50             :       "Skipping resets avoids expensive re-building of the operator, but comes "
      51             :       "at the cost of less accurate preconditioning and thus potentially more "
      52             :       "preconditioned iterations. Whether or not this helps convergence "
      53             :       "overall is highly problem-dependent.";
      54             : };
      55             : 
      56             : }  // namespace OptionTags
      57             : 
      58             : /// Tags related to the Schwarz solver
      59             : namespace Tags {
      60             : 
      61             : /// Number of points a subdomain can overlap with its neighbor
      62             : template <typename OptionsGroup>
      63           1 : struct MaxOverlap : db::SimpleTag {
      64           0 :   static std::string name() noexcept {
      65             :     return "MaxOverlap(" + Options::name<OptionsGroup>() + ")";
      66             :   }
      67           0 :   using type = size_t;
      68           0 :   static constexpr bool pass_metavariables = false;
      69           0 :   using option_tags = tmpl::list<OptionTags::MaxOverlap<OptionsGroup>>;
      70           0 :   static type create_from_options(const type& value) noexcept { return value; }
      71             : };
      72             : 
      73             : /// The serial linear solver used to solve subdomain operators
      74             : template <typename OptionsGroup>
      75           1 : struct SubdomainSolverBase : db::BaseTag {
      76           0 :   static std::string name() noexcept {
      77             :     return "SubdomainSolver(" + Options::name<OptionsGroup>() + ")";
      78             :   }
      79             : };
      80             : 
      81             : /// The serial linear solver of type `SolverType` used to solve subdomain
      82             : /// operators
      83             : template <typename SolverType, typename OptionsGroup>
      84           1 : struct SubdomainSolver : SubdomainSolverBase<OptionsGroup>, db::SimpleTag {
      85           0 :   using type = SolverType;
      86           0 :   static constexpr bool pass_metavariables = false;
      87           0 :   using option_tags =
      88             :       tmpl::list<OptionTags::SubdomainSolver<SolverType, OptionsGroup>>;
      89           0 :   static type create_from_options(const type& value) noexcept {
      90             :     return deserialize<type>(serialize<type>(value).data());
      91             :   }
      92             : };
      93             : 
      94             : /// Skip resets of the subdomain solver.
      95             : ///
      96             : /// \see LinearSolver::Schwarz::Actions::ResetSubdomainSolver
      97             : template <typename OptionsGroup>
      98           1 : struct SkipSubdomainSolverResets : db::SimpleTag {
      99           0 :   using type = bool;
     100           0 :   static constexpr bool pass_metavariables = false;
     101           0 :   using option_tags =
     102             :       tmpl::list<OptionTags::SkipSubdomainSolverResets<OptionsGroup>>;
     103           0 :   static bool create_from_options(const bool value) noexcept { return value; }
     104             : };
     105             : 
     106             : /*!
     107             :  * \brief The `Tag` on the overlap region with each neighbor, i.e. on a region
     108             :  * extruding from the central element.
     109             :  *
     110             :  * Note that data on an overlap with a neighbor is typically oriented according
     111             :  * to the neighbor's orientation, so re-orientation needs to happen whenever
     112             :  * the data cross element boundaries.
     113             :  */
     114             : template <typename Tag, size_t Dim, typename OptionsGroup>
     115           1 : struct Overlaps : db::SimpleTag {
     116           0 :   static std::string name() noexcept {
     117             :     return "Overlaps(" + db::tag_name<Tag>() + ", " +
     118             :            Options::name<OptionsGroup>() + ")";
     119             :   }
     120           0 :   using tag = Tag;
     121           0 :   using type = OverlapMap<Dim, typename Tag::type>;
     122             : };
     123             : 
     124             : /// The number of points a neighbor's subdomain extends into the element
     125             : template <size_t Dim, typename OptionsGroup>
     126           1 : struct IntrudingExtents : db::SimpleTag {
     127           0 :   static std::string name() noexcept {
     128             :     return "IntrudingExtents(" + Options::name<OptionsGroup>() + ")";
     129             :   }
     130           0 :   using type = std::array<size_t, Dim>;
     131             : };
     132             : 
     133             : /// The width in element-logical coordinates that a neighbor's subdomain extends
     134             : /// into the element
     135             : template <size_t Dim, typename OptionsGroup>
     136           1 : struct IntrudingOverlapWidths : db::SimpleTag {
     137           0 :   static std::string name() noexcept {
     138             :     return "IntrudingOverlapWidths(" + Options::name<OptionsGroup>() + ")";
     139             :   }
     140           0 :   using type = std::array<double, Dim>;
     141             : };
     142             : 
     143             : /// Weighting field for combining data from multiple overlapping subdomains
     144             : template <typename OptionsGroup>
     145           1 : struct Weight : db::SimpleTag {
     146           0 :   static std::string name() noexcept {
     147             :     return "Weight(" + Options::name<OptionsGroup>() + ")";
     148             :   }
     149           0 :   using type = Scalar<DataVector>;
     150             : };
     151             : 
     152             : /*!
     153             :  * \brief A diagnostic quantity to check that weights are conserved
     154             :  *
     155             :  * This quantity and the `Tags::Weight` on the element should sum to one on all
     156             :  * grid points. Residual values indicate that overlap data from neighboring
     157             :  * subdomains and data on the element are combined in a non-conservative way.
     158             :  */
     159             : template <typename OptionsGroup>
     160           1 : struct SummedIntrudingOverlapWeights : db::SimpleTag {
     161           0 :   static std::string name() noexcept {
     162             :     return "SummedIntrudingOverlapWeights(" + Options::name<OptionsGroup>() +
     163             :            ")";
     164             :   }
     165           0 :   using type = Scalar<DataVector>;
     166             : };
     167             : 
     168             : }  // namespace Tags
     169             : }  // namespace LinearSolver::Schwarz
     170             : 
     171             : namespace db {
     172             : namespace detail {
     173             : // This implementation mirrors the interface tag subitems in `Domain/Tags.hpp`.
     174             : // Please see that implementation for details.
     175             : template <typename VariablesTag, size_t Dim, typename OptionsGroup,
     176             :           typename Tags = typename VariablesTag::type::tags_list>
     177             : struct OverlapSubitemsImpl;
     178             : 
     179             : template <typename VariablesTag, size_t Dim, typename OptionsGroup,
     180             :           typename... Tags>
     181             : struct OverlapSubitemsImpl<VariablesTag, Dim, OptionsGroup,
     182             :                            tmpl::list<Tags...>> {
     183             :   using type = tmpl::list<
     184             :       LinearSolver::Schwarz::Tags::Overlaps<Tags, Dim, OptionsGroup>...>;
     185             :   using tag =
     186             :       LinearSolver::Schwarz::Tags::Overlaps<VariablesTag, Dim, OptionsGroup>;
     187             :   using return_type = NoSuchType;
     188             :   template <typename Subtag>
     189             :   static void create_item(
     190             :       const gsl::not_null<typename tag::type*> parent_value,
     191             :       const gsl::not_null<typename Subtag::type*> sub_value) noexcept {
     192             :     sub_value->clear();
     193             :     for (auto& [overlap_id, parent_overlap_vars] : *parent_value) {
     194             :       auto& parent_overlap_field =
     195             :           get<typename Subtag::tag>(parent_overlap_vars);
     196             :       auto& sub_overlap_field = (*sub_value)[overlap_id];
     197             :       for (size_t i = 0; i < parent_overlap_field.size(); ++i) {
     198             :         sub_overlap_field[i].set_data_ref(&parent_overlap_field[i]);
     199             :       }
     200             :     }
     201             :   }
     202             :   template <typename Subtag>
     203             :   static void create_compute_item(
     204             :       const gsl::not_null<typename Subtag::type*> sub_value,
     205             :       const typename tag::type& parent_value) noexcept {
     206             :     for (const auto& [overlap_id, parent_overlap_vars] : parent_value) {
     207             :       const auto& parent_overlap_field =
     208             :           get<typename Subtag::tag>(parent_overlap_vars);
     209             :       auto& sub_overlap_field = (*sub_value)[overlap_id];
     210             :       for (size_t i = 0; i < parent_overlap_field.size(); ++i) {
     211             :         // clang-tidy: do not use const_cast
     212             :         // The DataBox will only give out a const reference to the result of a
     213             :         // compute item. Here, that is a reference to a const map to Tensors of
     214             :         // DataVectors. There is no (publicly visible) indirection there, so
     215             :         // having the map const will allow only const access to the contained
     216             :         // DataVectors, so no modification through the pointer cast here is
     217             :         // possible. See the implementation of subitems in `Domain/Tags.hpp` for
     218             :         // details.
     219             :         sub_overlap_field[i].set_data_ref(
     220             :             const_cast<DataVector*>(&parent_overlap_field[i]));  // NOLINT
     221             :       }
     222             :     }
     223             :   }
     224             : };
     225             : }  // namespace detail
     226             : 
     227             : template <typename VariablesTag, size_t Dim, typename OptionsGroup>
     228             : struct Subitems<
     229             :     LinearSolver::Schwarz::Tags::Overlaps<VariablesTag, Dim, OptionsGroup>,
     230             :     Requires<tt::is_a_v<Variables, typename VariablesTag::type>>>
     231           0 :     : detail::OverlapSubitemsImpl<VariablesTag, Dim, OptionsGroup> {};
     232             : 
     233             : }  // namespace db

Generated by: LCOV version 1.14