Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <cstddef> 7 : #include <deque> 8 : #include <optional> 9 : #include <unordered_map> 10 : #include <unordered_set> 11 : #include <vector> 12 : 13 : #include "DataStructures/IdPair.hpp" 14 : #include "DataStructures/Tensor/TypeAliases.hpp" 15 : #include "DataStructures/Variables.hpp" 16 : #include "Domain/BlockLogicalCoordinates.hpp" 17 : #include "Domain/Structure/BlockId.hpp" 18 : #include "Domain/Structure/ElementId.hpp" 19 : 20 : namespace intrp { 21 : 22 : /// Data structures holding quantities that are interpolated by 23 : /// `Interpolator` for use by `InterpolationTarget`s 24 1 : namespace Vars { 25 : /// \brief Holds a `Variables` interpolated onto a list of points, and 26 : /// information about those points, for a local `Interpolator`. 27 : /// 28 : /// `TagList` is a `tmpl::list` of tags that go into the `Variables`. 29 : template <size_t VolumeDim, typename TagList> 30 1 : struct Info { 31 : /// `block_coord_holders` holds the list of all points (in block 32 : /// logical coordinates) that need to be interpolated onto for a 33 : /// given `InterpolationTarget`. 34 : /// 35 : /// The number of interpolated points for which results are stored 36 : /// in this `Info` (in `vars` and `global_offsets` below) 37 : /// corresponds to only the subset of the points in 38 : /// `block_coord_holders` that are contained in local `Element`s. 39 : /// Moreover, the number of interpolated points stored in this 40 : /// `Info` will change as more `Elements` send data to this 41 : /// `Interpolator`, and will be less than or equal to the size of 42 : /// `block_coord_holders` even after all `Element`s have sent their 43 : /// data (this is because this `Info` lives only on a single core, 44 : /// and this core will have access only to the local `Element`s). 45 1 : std::vector<BlockLogicalCoords<VolumeDim>> block_coord_holders; 46 : /// If a target needs to send points in a specific order, it should also send 47 : /// along which iteration the `block_coord_holders` are for. That way they can 48 : /// be properly ordered in the Interpolator. 49 1 : size_t iteration{0_st}; 50 : /// `vars` holds the interpolated `Variables` on some subset of the 51 : /// points in `block_coord_holders`. The grid points inside vars 52 : /// are indexed according to `global_offsets` below. The size of 53 : /// `vars` changes as more `Element`s send data to this `Interpolator`. 54 1 : std::vector<Variables<TagList>> vars{}; 55 : /// `global_offsets[j][i]` is the index into `block_coord_holders` that 56 : /// corresponds to the index `i` of the `DataVector` held in `vars[j]`. 57 : /// The size of `global_offsets` changes as more `Element`s 58 : /// send data to this `Interpolator`. 59 1 : std::vector<std::vector<size_t>> global_offsets{}; 60 : /// Holds the `ElementId`s of `Element`s for which interpolation has 61 : /// already been done for this `Info`. 62 : std::unordered_set<ElementId<VolumeDim>> 63 1 : interpolation_is_done_for_these_elements{}; 64 : 65 0 : Info() = default; 66 0 : explicit Info( 67 : std::vector<BlockLogicalCoords<VolumeDim>> block_coord_holders_in, 68 : const size_t iteration_in = 0, 69 : std::vector<Variables<TagList>> vars_in = {}, 70 : std::vector<std::vector<size_t>> global_offsets_in = {}, 71 : std::unordered_set<ElementId<VolumeDim>> 72 : interpolation_is_done_for_these_elements_in = {}) 73 : : block_coord_holders(std::move(block_coord_holders_in)), 74 : iteration(iteration_in), 75 : vars(std::move(vars_in)), 76 : global_offsets(std::move(global_offsets_in)), 77 : interpolation_is_done_for_these_elements( 78 : std::move(interpolation_is_done_for_these_elements_in)) {} 79 : }; 80 : 81 : template <size_t VolumeDim, typename TagList> 82 0 : void pup(PUP::er& p, Info<VolumeDim, TagList>& t) { // NOLINT 83 : p | t.block_coord_holders; 84 : p | t.vars; 85 : p | t.global_offsets; 86 : p | t.interpolation_is_done_for_these_elements; 87 : } 88 : 89 : template <size_t VolumeDim, typename TagList> 90 0 : void operator|(PUP::er& p, Info<VolumeDim, TagList>& t) { // NOLINT 91 : pup(p, t); 92 : } 93 : 94 : /// Holds `Info`s at all `temporal_id`s for a given 95 : /// `InterpolationTargetTag`. Also holds `temporal_id`s when data has 96 : /// been interpolated; this is used for cleanup purposes. All 97 : /// `Holder`s for all `InterpolationTargetTags` are held in a single 98 : /// `TaggedTuple` that is in the `Interpolator`'s `DataBox` with the 99 : /// tag `Tags::InterpolatedVarsHolders`. 100 : template <typename Metavariables, 101 : typename InterpolationTargetTag, typename TagList> 102 1 : struct Holder { 103 0 : using temporal_id = typename InterpolationTargetTag::temporal_id; 104 : std::unordered_map<typename InterpolationTargetTag::temporal_id::type, 105 : Info<Metavariables::volume_dim, TagList>> 106 0 : infos; 107 : std::deque<typename InterpolationTargetTag::temporal_id::type> 108 0 : temporal_ids_when_data_has_been_interpolated; 109 : }; 110 : 111 : template <typename Metavariables, typename InterpolationTargetTag, 112 : typename TagList> 113 0 : void pup(PUP::er& p, // NOLINT 114 : Holder<Metavariables, InterpolationTargetTag, TagList>& // NOLINT 115 : t) { // NOLINT 116 : p | t.infos; 117 : p | t.temporal_ids_when_data_has_been_interpolated; 118 : } 119 : 120 : template <typename Metavariables, typename InterpolationTargetTag, 121 : typename TagList> 122 0 : void operator|( 123 : PUP::er& p, // NOLINT 124 : Holder<Metavariables, InterpolationTargetTag, TagList>& t) { // NOLINT 125 : pup(p, t); 126 : } 127 : 128 : /// Indexes a particular `Holder` in the `TaggedTuple` that is 129 : /// accessed from the `Interpolator`'s `DataBox` with tag 130 : /// `Tags::InterpolatedVarsHolders`. 131 : template <typename InterpolationTargetTag, typename Metavariables> 132 1 : struct HolderTag { 133 0 : using type = 134 : Holder<Metavariables, InterpolationTargetTag, 135 : typename InterpolationTargetTag::vars_to_interpolate_to_target>; 136 : }; 137 : 138 : } // namespace Vars 139 : } // namespace intrp