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