Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:05:54

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2022-2024 UT-Battelle, LLC, and other Celeritas developers.
0003 // See the top-level COPYRIGHT file for details.
0004 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0005 //---------------------------------------------------------------------------//
0006 //! \file orange/detail/BIHPartitioner.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include <vector>
0011 
0012 #include "corecel/cont/EnumArray.hh"
0013 #include "geocel/BoundingBox.hh"
0014 
0015 #include "../OrangeData.hh"
0016 
0017 namespace celeritas
0018 {
0019 namespace detail
0020 {
0021 //---------------------------------------------------------------------------//
0022 /*!
0023  * Partition bounding boxes using a surface area heuristic.
0024  *
0025  * The class take a vector of bounding boxes as an input, and outputs a
0026  * Partition object describing the optional partition. To find the optimal
0027  * partition, all possible candidate partitions along the x, y, and z axis are
0028  * evaluated using a cost function. The cost function is based on a standard
0029  * surface area heuristic.
0030  */
0031 class BIHPartitioner
0032 {
0033   public:
0034     //!@{
0035     //! \name Type aliases
0036     using Real3 = Array<fast_real_type, 3>;
0037     using VecBBox = std::vector<FastBBox>;
0038     using VecReal3 = std::vector<Real3>;
0039     using VecIndices = std::vector<LocalVolumeId>;
0040 
0041     struct Partition
0042     {
0043         using Edge = BIHInnerNode::Edge;
0044 
0045         Axis axis = Axis::size_;
0046         real_type position = std::numeric_limits<real_type>::infinity();
0047 
0048         EnumArray<Edge, VecIndices> indices;
0049         EnumArray<Edge, FastBBox> bboxes;
0050 
0051         explicit operator bool() const
0052         {
0053             return axis != Axis::size_ && std::isfinite(position)
0054                    && !indices[Edge::left].empty()
0055                    && !indices[Edge::right].empty() && bboxes[Edge::left]
0056                    && bboxes[Edge::right];
0057         }
0058     };
0059 
0060     //!@}
0061 
0062   public:
0063     //! Default constructor
0064     BIHPartitioner() = default;
0065 
0066     // Construct from vector of bounding boxes and respective centers.
0067     explicit BIHPartitioner(VecBBox const* bboxes, VecReal3 const* centers);
0068 
0069     explicit inline operator bool() const
0070     {
0071         return bboxes_ != nullptr && centers_ != nullptr;
0072     }
0073 
0074     // Find a suitable partition for the given bounding boxes
0075     Partition operator()(VecIndices const& indicies) const;
0076 
0077   private:
0078     /// TYPES ///
0079     using AxesCenters = std::vector<std::vector<real_type>>;
0080 
0081     //// DATA ////
0082     VecBBox const* bboxes_{nullptr};
0083     VecReal3 const* centers_{nullptr};
0084     static constexpr size_type candidates_per_axis_{3};
0085 
0086     //// HELPER FUNCTIONS ////
0087 
0088     // Create sorted and uniquified X, Y, Z values of bbox centers
0089     AxesCenters calc_axes_centers(VecIndices const& indices) const;
0090 
0091     // Create a partition object
0092     Partition make_partition(VecIndices const& indices,
0093                              Axis axis,
0094                              real_type position) const;
0095 
0096     // Calculate the cost of partition using a surface area heuristic
0097     real_type calc_cost(Partition const& partition) const;
0098 };
0099 
0100 //---------------------------------------------------------------------------//
0101 }  // namespace detail
0102 }  // namespace celeritas