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 <unordered_map>
9 : #include <vector>
10 :
11 : #include "DataStructures/DataBox/Tag.hpp"
12 : #include "Domain/Creators/Tags/Domain.hpp"
13 : #include "Domain/ElementDistribution.hpp"
14 : #include "Domain/Tags/ElementDistribution.hpp"
15 : #include "Evolution/DiscontinuousGalerkin/OnlyDgBlockIds.hpp"
16 : #include "Evolution/DiscontinuousGalerkin/OptionTags.hpp"
17 : #include "Evolution/DiscontinuousGalerkin/UsingSubcell.hpp"
18 : #include "Parallel/GlobalCache.hpp"
19 : #include "Utilities/ErrorHandling/Error.hpp"
20 : #include "Utilities/TMPL.hpp"
21 :
22 : namespace evolution::dg {
23 : /*!
24 : * \brief Returns the per-block extents to use in place of `initial_extents`
25 : * when weighting subcell-capable elements by their finite-difference grid
26 : * instead of their DG grid (see
27 : * `evolution::dg::Tags::UseSubcellGridPointsForDistribution`).
28 : *
29 : * For each block not in `only_dg_block_ids`, the returned extents are the
30 : * number of finite-difference grid points \f$2N-1\f$ corresponding to the
31 : * \f$N\f$ DG grid points in `initial_extents`, matching the subcell mesh built
32 : * by `evolution::dg::subcell::fd::mesh`. Blocks in `only_dg_block_ids` are
33 : * omitted from the returned map, since they always run on the DG grid.
34 : */
35 : template <size_t Dim>
36 : std::unordered_map<size_t, std::array<size_t, Dim>>
37 1 : compute_weighting_extents_override(
38 : const std::vector<size_t>& only_dg_block_ids,
39 : const std::vector<std::array<size_t, Dim>>& initial_extents);
40 :
41 : namespace Tags {
42 : /// \ingroup DataBoxTagsGroup
43 : /// Tag that holds whether to use the number of finite-difference subcell
44 : /// grid points (instead of the number of DG grid points) when weighting
45 : /// subcell-capable elements for the `domain::Tags::ElementDistribution`.
46 : ///
47 : /// Errors unless the `ElementDistribution` is
48 : /// `domain::ElementWeight::NumGridPoints`, since that is the only weight
49 : /// whose cost depends on the extents in a way that makes substituting the
50 : /// subcell extents meaningful.
51 1 : struct UseSubcellGridPointsForDistribution : db::SimpleTag {
52 0 : using type = bool;
53 0 : using option_tags =
54 : tmpl::list<OptionTags::UseSubcellGridPointsForDistribution,
55 : domain::OptionTags::ElementDistribution>;
56 :
57 0 : static constexpr bool pass_metavariables = false;
58 0 : static type create_from_options(
59 : const bool use_subcell_grid_points,
60 : const std::optional<domain::ElementWeight>& element_weight) {
61 : // `ElementWeight::NumGridPoints` is the only weight for which
62 : // substituting the subcell extents produces the intended cost ratio.
63 : // `ElementWeight::Uniform` ignores the extents entirely, so the option
64 : // would silently do nothing. `ElementWeight::NumGridPointsAndGridSpacing`
65 : // derives a minimum grid spacing from the extents by building a DG mesh,
66 : // which for the subcell extents describes neither the DG grid nor the
67 : // (uniform) finite-difference grid, and so mis-weights the cost.
68 : //
69 : // This could be improved in the future by telling
70 : // `domain::get_element_costs()` about the finite-difference grid, so that
71 : // `ElementWeight::NumGridPointsAndGridSpacing` can be supported too.
72 : if (use_subcell_grid_points and
73 : element_weight != std::optional{domain::ElementWeight::NumGridPoints}) {
74 : ERROR(
75 : "UseSubcellGridPointsForDistribution is only supported with "
76 : "ElementDistribution: NumGridPoints. Either set "
77 : "UseSubcellGridPointsForDistribution to false or set "
78 : "ElementDistribution to NumGridPoints.");
79 : }
80 : return use_subcell_grid_points;
81 : }
82 : };
83 : } // namespace Tags
84 :
85 : /// \brief The global cache tags needed to distribute elements, for use as the
86 : /// `const_global_cache_tags` of a component that creates the elements.
87 : ///
88 : /// The subcell-specific tags are only included for executables with DG-subcell
89 : /// support, since the options they are built from only exist there.
90 : template <typename Metavariables, size_t Dim>
91 1 : using element_distribution_cache_tags = tmpl::append<
92 : tmpl::list<domain::Tags::Domain<Dim>, domain::Tags::ElementDistribution>,
93 : tmpl::conditional_t<using_subcell_v<Metavariables>,
94 : tmpl::list<Tags::UseSubcellGridPointsForDistribution,
95 : Tags::OnlyDgBlockIds<Dim>>,
96 : tmpl::list<>>>;
97 :
98 : /*!
99 : * \brief Reads `element_distribution_cache_tags` out of the \p cache and
100 : * returns the `weighting_extents_override` to pass to
101 : * `Parallel::create_elements_using_distribution`.
102 : *
103 : * Always `std::nullopt` for executables without DG-subcell support, and for
104 : * those with it whenever
105 : * `evolution::dg::Tags::UseSubcellGridPointsForDistribution` is `false`.
106 : */
107 : template <size_t Dim, typename Metavariables>
108 : std::optional<std::unordered_map<size_t, std::array<size_t, Dim>>>
109 1 : weighting_extents_override_from_cache(
110 : const Parallel::GlobalCache<Metavariables>& cache,
111 : const std::vector<std::array<size_t, Dim>>& initial_extents) {
112 : if constexpr (using_subcell_v<Metavariables>) {
113 : if (Parallel::get<Tags::UseSubcellGridPointsForDistribution>(cache)) {
114 : return {compute_weighting_extents_override(
115 : Parallel::get<Tags::OnlyDgBlockIds<Dim>>(cache), initial_extents)};
116 : }
117 : }
118 : return std::nullopt;
119 : }
120 : } // namespace evolution::dg
|