Line data Source code
1 1 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : /// \file 5 : /// Defines class ExcisionSphere. 6 : 7 : #pragma once 8 : 9 : #include <cstddef> 10 : #include <iosfwd> 11 : #include <limits> 12 : #include <memory> 13 : #include <optional> 14 : #include <unordered_map> 15 : 16 : #include "DataStructures/Tensor/Tensor.hpp" 17 : #include "Domain/CoordinateMaps/CoordinateMap.hpp" 18 : #include "Domain/Structure/Direction.hpp" 19 : #include "Domain/Structure/ElementId.hpp" 20 : 21 : /// \cond 22 : namespace Frame { 23 : struct Grid; 24 : struct Inertial; 25 : } // namespace Frame 26 : namespace PUP { 27 : class er; 28 : } // namespace PUP 29 : /// \endcond 30 : 31 : /// \ingroup ComputationalDomainGroup 32 : /// The excision sphere information of a computational domain. 33 : /// The excision sphere is assumed to be a coordinate sphere in the 34 : /// grid frame. 35 : /// 36 : /// \tparam VolumeDim the volume dimension. 37 : template <size_t VolumeDim> 38 1 : class ExcisionSphere { 39 : public: 40 : /// Constructor 41 : /// 42 : /// \param radius the radius of the excision sphere in the 43 : /// computational domain. 44 : /// \param center the coordinate center of the excision sphere 45 : /// in the computational domain. 46 : /// \param abutting_directions the set of blocks that touch the excision 47 : /// sphere, along with the direction in which they touch it. 48 1 : ExcisionSphere( 49 : double radius, tnsr::I<double, VolumeDim, Frame::Grid> center, 50 : std::unordered_map<size_t, Direction<VolumeDim>> abutting_directions); 51 : 52 : /// Default constructor needed for Charm++ serialization. 53 1 : ExcisionSphere() = default; 54 0 : ~ExcisionSphere() = default; 55 0 : ExcisionSphere(const ExcisionSphere<VolumeDim>& /*rhs*/); 56 0 : ExcisionSphere(ExcisionSphere<VolumeDim>&& /*rhs*/) = default; 57 0 : ExcisionSphere<VolumeDim>& operator=( 58 : const ExcisionSphere<VolumeDim>& /*rhs*/); 59 0 : ExcisionSphere<VolumeDim>& operator=(ExcisionSphere<VolumeDim>&& /*rhs*/) = 60 : default; 61 : 62 : /// \brief Add time dependent coordinate maps to the ExcisionSphere 63 : /// 64 : /// \note There is no actual mesh that is inside an excision sphere, but this 65 : /// region moves along with the domain just the same. Meaning that we 66 : /// should be able to take a point inside the excision sphere and map it to 67 : /// the Inertial frame. 68 1 : void inject_time_dependent_maps( 69 : std::unique_ptr< 70 : domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, VolumeDim>> 71 : moving_mesh_grid_to_inertial_map); 72 : 73 : /// \brief The map going from the last time independent frame to the frame in 74 : /// which the equations are solved. Only used when `is_time_dependent()` is 75 : /// true. 76 : const domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, VolumeDim>& 77 1 : moving_mesh_grid_to_inertial_map() const; 78 : 79 : /// \brief Return whether or not time dependent maps have been injected 80 1 : bool is_time_dependent() const { return grid_to_inertial_map_ != nullptr; } 81 : 82 : /// The radius of the ExcisionSphere. 83 1 : double radius() const { return radius_; } 84 : 85 : /// The coordinate center of the ExcisionSphere. 86 1 : const tnsr::I<double, VolumeDim, Frame::Grid>& center() const { 87 : return center_; 88 : } 89 : 90 : /// The set of blocks that touch the excision sphere, along with the direction 91 : /// in which they touch it 92 1 : const std::unordered_map<size_t, Direction<VolumeDim>>& abutting_directions() 93 : const { 94 : return abutting_directions_; 95 : } 96 : /// Checks whether an element abuts the excision sphere. If it does, returns 97 : /// the corresponding direction. Else, `nullopt` is returned. 98 1 : std::optional<Direction<VolumeDim>> abutting_direction( 99 : const ElementId<VolumeDim>& element_id) const; 100 : 101 : // NOLINTNEXTLINE(google-runtime-references) 102 0 : void pup(PUP::er& p); 103 : 104 : private: 105 : template <size_t LocalVolumeDim> 106 : // NOLINTNEXTLINE(readability-redundant-declaration) 107 0 : friend bool operator==(const ExcisionSphere<LocalVolumeDim>& lhs, 108 : const ExcisionSphere<LocalVolumeDim>& rhs); 109 : 110 0 : double radius_{std::numeric_limits<double>::signaling_NaN()}; 111 0 : tnsr::I<double, VolumeDim, Frame::Grid> center_{ 112 : std::numeric_limits<double>::signaling_NaN()}; 113 0 : std::unordered_map<size_t, Direction<VolumeDim>> abutting_directions_{}; 114 : std::unique_ptr< 115 : domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, VolumeDim>> 116 0 : grid_to_inertial_map_{}; 117 : }; 118 : 119 : template <size_t VolumeDim> 120 0 : std::ostream& operator<<(std::ostream& os, 121 : const ExcisionSphere<VolumeDim>& excision_sphere); 122 : 123 : template <size_t VolumeDim> 124 0 : bool operator!=(const ExcisionSphere<VolumeDim>& lhs, 125 : const ExcisionSphere<VolumeDim>& rhs);