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 : /// @{ 27 : /// \ingroup ComputationalDomainGroup 28 : /// 29 : /// Computes the block logical coordinates and the containing `BlockId` of 30 : /// a set of points, given coordinates in a particular frame. 31 : /// 32 : /// \details Returns a std::vector<std::optional<IdPair<BlockId,coords>>>, 33 : /// where the vector runs over the points and is indexed in the same order as 34 : /// the input coordinates `x`. For each point, the `IdPair` holds the 35 : /// block logical coords of that point and the `BlockId` of the `Block` that 36 : /// contains that point. 37 : /// The std::optional is invalid if the point is not in any Block. 38 : /// If a point is on a shared boundary of two or more `Block`s, it is 39 : /// returned only once, and is considered to belong to the `Block` 40 : /// with the smaller `BlockId`. 41 : /// 42 : /// The `block_logical_coordinates_single_point` function will search the passed 43 : /// in block for the passed in coordinate and return the logical coordinates of 44 : /// that point. It will return a `std::nullopt` if it can't find the point in 45 : /// that block. 46 : /// 47 : /// \warning Since map inverses can involve numerical roundoff error, care must 48 : /// be taken with points on shared block boundaries. They will be assigned to 49 : /// the first block (by block ID) that contains the point _within roundoff 50 : /// error_. Therefore, be advised to use the logical coordinates returned by 51 : /// this function, which are guaranteed to be in [-1, 1] and can be safely 52 : /// passed along to `element_logical_coordinates`. 53 : /// 54 : /// \warning `block_logical_coordinates` with x in 55 : /// `::Frame::Distorted` ignores all `Block`s that lack a distorted 56 : /// frame, and it will return std::nullopt for points that lie outside 57 : /// all distorted-frame-endowed `Block`s. This is what is expected for 58 : /// typical use cases. This means that `block_logical_coordinates` 59 : /// does not assume that grid and distorted frames are equal in 60 : /// `Block`s that lack a distorted frame. 61 : template <size_t Dim, typename Frame> 62 1 : auto block_logical_coordinates( 63 : const Domain<Dim>& domain, const tnsr::I<DataVector, Dim, Frame>& x, 64 : double time = std::numeric_limits<double>::signaling_NaN(), 65 : const std::unordered_map< 66 : std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>& 67 : functions_of_time = std::unordered_map< 68 : std::string, 69 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>{}) 70 : -> std::vector<std::optional< 71 : IdPair<domain::BlockId, tnsr::I<double, Dim, ::Frame::BlockLogical>>>>; 72 : 73 : template <size_t Dim, typename Frame> 74 : std::optional<tnsr::I<double, Dim, ::Frame::BlockLogical>> 75 1 : block_logical_coordinates_single_point( 76 : const tnsr::I<double, Dim, Frame>& input_point, const Block<Dim>& block, 77 : double time = std::numeric_limits<double>::signaling_NaN(), 78 : const std::unordered_map< 79 : std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>& 80 : functions_of_time = std::unordered_map< 81 : std::string, 82 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>{}); 83 : /// @}