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 <memory> 8 : #include <optional> 9 : #include <string> 10 : #include <unordered_map> 11 : #include <vector> 12 : 13 : #include "DataStructures/IdPair.hpp" 14 : #include "DataStructures/Tensor/TypeAliases.hpp" 15 : #include "Domain/FunctionsOfTime/FunctionOfTime.hpp" 16 : #include "Domain/Structure/BlockId.hpp" 17 : 18 : /// \cond 19 : class DataVector; 20 : template <size_t VolumeDim> 21 : class Domain; 22 : template <size_t VolumeDim> 23 : class Block; 24 : /// \endcond 25 : 26 : template <size_t Dim> 27 0 : using BlockLogicalCoords = std::optional< 28 : IdPair<domain::BlockId, tnsr::I<double, Dim, Frame::BlockLogical>>>; 29 : 30 : /// @{ 31 : /// \ingroup ComputationalDomainGroup 32 : /// 33 : /// Computes the block logical coordinates and the containing `BlockId` of 34 : /// a set of points, given coordinates in a particular frame. 35 : /// 36 : /// \details Returns a std::vector<std::optional<IdPair<BlockId,coords>>>, 37 : /// where the vector runs over the points and is indexed in the same order as 38 : /// the input coordinates `x`. For each point, the `IdPair` holds the 39 : /// block logical coords of that point and the `BlockId` of the `Block` that 40 : /// contains that point. 41 : /// The std::optional is invalid if the point is not in any Block. 42 : /// If a point is on a shared boundary of two or more `Block`s, it is 43 : /// returned only once, and is considered to belong to the `Block` 44 : /// with the smaller `BlockId`. 45 : /// 46 : /// The `block_logical_coordinates_single_point` function will search the passed 47 : /// in block for the passed in coordinate and return the logical coordinates of 48 : /// that point. It will return a `std::nullopt` if it can't find the point in 49 : /// that block. 50 : /// 51 : /// \warning Since map inverses can involve numerical roundoff error, care must 52 : /// be taken with points on shared block boundaries. They will be assigned to 53 : /// the first block (by block ID) that contains the point _within roundoff 54 : /// error_. Therefore, be advised to use the logical coordinates returned by 55 : /// this function, which are guaranteed to be in [-1, 1] and can be safely 56 : /// passed along to `element_logical_coordinates`. 57 : /// 58 : /// \warning `block_logical_coordinates` with x in 59 : /// `::Frame::Distorted` ignores all `Block`s that lack a distorted 60 : /// frame, and it will return std::nullopt for points that lie outside 61 : /// all distorted-frame-endowed `Block`s. This is what is expected for 62 : /// typical use cases. This means that `block_logical_coordinates` 63 : /// does not assume that grid and distorted frames are equal in 64 : /// `Block`s that lack a distorted frame. 65 : template <size_t Dim, typename Fr> 66 1 : auto block_logical_coordinates( 67 : const Domain<Dim>& domain, const tnsr::I<DataVector, Dim, Fr>& x, 68 : double time = std::numeric_limits<double>::signaling_NaN(), 69 : const domain::FunctionsOfTimeMap& functions_of_time = {}, 70 : std::optional<gsl::not_null<std::vector<size_t>*>> block_order = 71 : std::nullopt) -> std::vector<BlockLogicalCoords<Dim>>; 72 : 73 : template <size_t Dim, typename Fr> 74 : std::optional<tnsr::I<double, Dim, ::Frame::BlockLogical>> 75 1 : block_logical_coordinates_single_point( 76 : const tnsr::I<double, Dim, Fr>& input_point, const Block<Dim>& block, 77 : double time = std::numeric_limits<double>::signaling_NaN(), 78 : const domain::FunctionsOfTimeMap& functions_of_time = {}); 79 : 80 : /// A `block_order` can be provided to this overload to speed up the search for 81 : /// the block containing the point. When the point is found, the containing 82 : /// block will be pushed to the front of the list. If an empty block order is 83 : /// provided, it will be initially filled with the list of blocks in the domain 84 : /// and then updated. Note that when a block order is provided, the block with 85 : /// the smallest `BlockId` is no longer guaranteed to be chosen. 86 : template <size_t Dim, typename Fr> 87 1 : BlockLogicalCoords<Dim> block_logical_coordinates_single_point( 88 : const tnsr::I<double, Dim, Fr>& input_point, const Domain<Dim>& domain, 89 : double time = std::numeric_limits<double>::signaling_NaN(), 90 : const domain::FunctionsOfTimeMap& functions_of_time = {}, 91 : std::optional<gsl::not_null<std::vector<size_t>*>> block_order = 92 : std::nullopt); 93 : /// @}