.. _program_listing_file_src_pcms_localization_point_search.h: Program Listing for File point_search.h ======================================= |exhale_lsh| :ref:`Return to documentation for file ` (``src/pcms/localization/point_search.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #ifndef PCMS_COUPLING_POINT_SEARCH_H #define PCMS_COUPLING_POINT_SEARCH_H #include #include #include #include #include #include #include "pcms/utility/types.h" #include "pcms/utility/uniform_grid.h" #include "pcms/utility/bounding_box.h" namespace pcms { LO GetOwningElementId(Omega_h::Mesh& mesh, int mesh_dim, int entity_dim, LO element_id); template KOKKOS_INLINE_FUNCTION LO GetOwningElementIdFromAdj(const Omega_h::Adj& upward_adj, DimEnum entity_dim, DimEnum target_dim, LO element_id) { if (element_id < 0) return -1; // If entity is already at target dimension, return it directly if (static_cast(entity_dim) == static_cast(target_dim)) return element_id; const auto begin = upward_adj.a2ab[element_id]; const auto end = upward_adj.a2ab[element_id + 1]; if (begin >= end) return -1; // Find the smallest owning element ID LO owner = upward_adj.ab2b[begin]; for (auto i = begin + 1; i < end; ++i) { const LO candidate = upward_adj.ab2b[i]; if (candidate < owner) owner = candidate; } return owner; } // // TODO take a bounding box as we may want a bbox that's bigger than the mesh! // this function is in the public header for testing, but should not be directly // used namespace detail { Kokkos::Crs construct_intersection_map_2d(Omega_h::Mesh& mesh, Kokkos::View grid, int num_grid_cells); Kokkos::Crs construct_intersection_map_3d(Omega_h::Mesh& mesh, Kokkos::View grid, int num_grid_cells); Kokkos::Crs construct_intersection_map_reference_2d(Omega_h::Mesh& mesh, Kokkos::View grid, int num_grid_cells); Kokkos::Crs construct_intersection_map_reference_3d(Omega_h::Mesh& mesh, Kokkos::View grid, int num_grid_cells); } // namespace detail [[nodiscard]] KOKKOS_FUNCTION bool triangle_intersects_bbox( const Omega_h::Matrix<2, 3>& coords, const AABBox<2>& bbox); template class PointLocalizationSearch { public: struct Result { enum class Dimensionality { VERTEX = 0, EDGE = 1, FACE = 2, REGION = 3, NO_INTERSECT = 4 }; Dimensionality dimensionality; LO element_id; Omega_h::Vector parametric_coords; [[nodiscard]] KOKKOS_INLINE_FUNCTION static constexpr LO OutsideId(LO id) { return -id - 1; } [[nodiscard]] KOKKOS_INLINE_FUNCTION constexpr bool IsOutside() const { return element_id < 0; } [[nodiscard]] KOKKOS_INLINE_FUNCTION constexpr LO EntityId() const { if (dimensionality == Dimensionality::NO_INTERSECT) { return -1; } return element_id < 0 ? -element_id - 1 : element_id; } }; static constexpr auto DIM = dim; using PointSearchTolerances = Kokkos::View; explicit PointLocalizationSearch(const PointSearchTolerances& tolerances) : tolerances_(tolerances) { assert(tolerances_.is_allocated()); } virtual Kokkos::View operator()( Kokkos::View point) const = 0; [[nodiscard]] virtual LO GetOwningElementId(const Result& result) = 0; [[nodiscard]] virtual Kokkos::View GetOwningElementIds( Kokkos::View results) const = 0; virtual ~PointLocalizationSearch() = default; protected: PointSearchTolerances tolerances_; }; using PointLocalizationSearch2D = PointLocalizationSearch<2>; using PointLocalizationSearch3D = PointLocalizationSearch<3>; class GridPointSearch2D : public PointLocalizationSearch2D { using CandidateMapT = Kokkos::Crs; public: using Result = PointLocalizationSearch2D::Result; GridPointSearch2D(Omega_h::Mesh& mesh, LO Nx, LO Ny); GridPointSearch2D(Omega_h::Mesh& mesh, LO Nx, LO Ny, const PointSearchTolerances& tolerances); Kokkos::View operator()( Kokkos::View point) const override; [[nodiscard]] LO GetOwningElementId(const Result& result) override; [[nodiscard]] Kokkos::View GetOwningElementIds( Kokkos::View results) const override; private: Omega_h::Mesh mesh_; Omega_h::Adj tris2edges_adj_; Omega_h::Adj tris2verts_adj_; Omega_h::Adj edges2verts_adj_; Omega_h::Adj edges2faces_up_; Omega_h::Adj verts2faces_up_; Kokkos::View grid_{"uniform grid"}; CandidateMapT candidate_map_; Omega_h::LOs tris2verts_; Omega_h::Reals coords_; }; class GridPointSearch3D : public PointLocalizationSearch3D { using CandidateMapT = Kokkos::Crs; public: using Result = PointLocalizationSearch3D::Result; GridPointSearch3D(Omega_h::Mesh& mesh, LO Nx, LO Ny, LO Nz); GridPointSearch3D(Omega_h::Mesh& mesh, LO Nx, LO Ny, LO Nz, const PointSearchTolerances& tolerances); Kokkos::View operator()( Kokkos::View point) const override; [[nodiscard]] LO GetOwningElementId(const Result& result) override; [[nodiscard]] Kokkos::View GetOwningElementIds( Kokkos::View results) const override; private: Omega_h::Mesh mesh_; Omega_h::Adj tris2edges_adj_; Omega_h::Adj tris2verts_adj_; Omega_h::Adj edges2verts_adj_; Omega_h::Adj verts2regions_up_; Omega_h::Adj edges2regions_up_; Omega_h::Adj faces2regions_up_; Kokkos::View[1]> grid_{"uniform grid"}; CandidateMapT candidate_map_; Omega_h::LOs tris2verts_; Omega_h::Reals coords_; }; using GridPointSearchVariant = std::variant; } // namespace pcms #endif // PCMS_COUPLING_POINT_SEARCH_H