Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement BIH tree #849

Merged
merged 64 commits into from
Aug 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
70a9c2d
Implement BIH tree
elliottbiondo Jun 30, 2023
8394aab
Rename BIHMaker to BIHBuilder
elliottbiondo Jul 14, 2023
082e493
Fix axis comparison and make methods const
elliottbiondo Jul 14, 2023
6db249e
Clean up types
elliottbiondo Jul 14, 2023
328cee6
Moving BIHNodeId to OrangeTypes
elliottbiondo Jul 14, 2023
8ba6583
Create BIHParams struct
elliottbiondo Jul 19, 2023
2d760c6
Fix reading bbox from JSON
elliottbiondo Jul 20, 2023
f9a526d
Remove bitwise operation
elliottbiondo Jul 20, 2023
159ed7d
Rename bbox function to is_infinite
elliottbiondo Jul 20, 2023
3bb3a5c
Add BoundingBoxUtils and tests
elliottbiondo Jul 20, 2023
470b1b0
Fix doc string
elliottbiondo Jul 20, 2023
d66c9d9
Create separate partitioner class
elliottbiondo Jul 21, 2023
a824ba8
Store parent on each BIHNode
elliottbiondo Jul 21, 2023
1cb58a6
Move more functionality to BIHPartitioner
elliottbiondo Jul 24, 2023
b24e63f
Implement surface area heuristic partitioning scheme
elliottbiondo Jul 24, 2023
6c86191
Clean up doc strings
elliottbiondo Jul 24, 2023
e193a6a
Stop storing all partition candidates
elliottbiondo Jul 25, 2023
dc48e5a
Build BIH tree in terms of inner and leaf node structs
elliottbiondo Jul 25, 2023
594e1eb
Change appropriate EXPECTs to ASSERTs
elliottbiondo Jul 25, 2023
b82b08d
Add uniquify tolerance
elliottbiondo Jul 25, 2023
7f61028
Move BIHData to separate file
elliottbiondo Jul 25, 2023
266b057
Remove erroneous CELER_FUNCTION declarations
elliottbiondo Jul 25, 2023
5f32bde
Add is_inside function to BoundingBoxUtils
elliottbiondo Jul 26, 2023
5ebb9ed
Store bounding boxes with BIHData
elliottbiondo Jul 26, 2023
7943c76
Fix max double -> inf upon read-in for bounding boxes
elliottbiondo Jul 26, 2023
75c1faa
Fix Overload for perfect forwarding
elliottbiondo Jul 26, 2023
ffadd6f
Fix std::move and add operator bool
elliottbiondo Jul 26, 2023
e982592
Use EnumArray within BIHInderNode, change 'location' to 'position'
elliottbiondo Jul 26, 2023
f2cdff3
Rename BIHParams to BIHTree and move BoundingBoxUtils from detail to …
elliottbiondo Jul 26, 2023
f4ee3d8
Use constexpr on max_real
elliottbiondo Jul 26, 2023
22aaf1b
Implement minor changes from MR
elliottbiondo Jul 26, 2023
8d860c6
Use EnumArrays in Partition struct
elliottbiondo Jul 26, 2023
fabe139
Remove is_partitionable function
elliottbiondo Jul 26, 2023
c0e35ed
Pass nodes by pointer
elliottbiondo Jul 26, 2023
56d6401
Loop over edges
elliottbiondo Jul 26, 2023
40a1b46
Make partitioner local
elliottbiondo Jul 26, 2023
070f5b0
Remove bbox from VolumeRecord
elliottbiondo Jul 26, 2023
e9090e9
Changing BIHBuilder constructor args
elliottbiondo Jul 26, 2023
0cb1475
Fix BoundingBoxId CI error
elliottbiondo Jul 27, 2023
29c34e3
Change apply_partition to make_partition
elliottbiondo Jul 27, 2023
53f8919
Use SoftEqual in uniquify
elliottbiondo Jul 27, 2023
d2567d8
Move vector version of bbox_union function to BIHUtils
elliottbiondo Jul 27, 2023
bdd4d13
Merge remote-tracking branch 'upstream/develop' into bih
sethrj Aug 1, 2023
eab71aa
Create storage object for BIHTree and eventual BIHTraverser construction
elliottbiondo Aug 1, 2023
0230a88
Merge branch 'bih' of https://github.com/elliottbiondo/celeritas into…
elliottbiondo Aug 1, 2023
5ceb56f
Template BoundingBox class
elliottbiondo Aug 2, 2023
112840e
Change position_type to real_type
elliottbiondo Aug 2, 2023
852fa5a
Fix fabs(inf) issue
elliottbiondo Aug 2, 2023
21f3682
Check only a subset of possible partitions
elliottbiondo Aug 2, 2023
650c444
Use equally-spaced partition candidates
elliottbiondo Aug 2, 2023
7a43b5e
Merge remote-tracking branch 'upstream/develop' into bih
sethrj Aug 6, 2023
da16de5
Fix doc string
elliottbiondo Aug 7, 2023
9d52fc6
Change array_type to Real3
elliottbiondo Aug 7, 2023
1d134d9
Change float to fast real type
elliottbiondo Aug 7, 2023
cecf798
Initialize pointers to nullptr
elliottbiondo Aug 7, 2023
15644c7
Move anonymous namespace within celeritas namespace
elliottbiondo Aug 7, 2023
69d1acf
Implement minor changes to BIHPartitioner
elliottbiondo Aug 7, 2023
97d0537
Implement minor changes to BIHBuilder
elliottbiondo Aug 7, 2023
490fce6
Change Bounding_Planes within BIHInnerNode
elliottbiondo Aug 7, 2023
c879db4
Resolve BoundingBox merge conflicts
elliottbiondo Aug 7, 2023
019ee62
Add explaination for left and right bounding planes
elliottbiondo Aug 8, 2023
6819a0b
Undo erroneous change from merge conflict resolution
elliottbiondo Aug 8, 2023
afb3f8c
Use trailing return type in BoundingBox.hh
elliottbiondo Aug 8, 2023
e86e6f9
Remove unnecessary scoping from function definition
elliottbiondo Aug 8, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions src/orange/BoundingBox.hh
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class BoundingBox
//!@{
//! \name Type aliases
using value_type = T;
using Array3 = Array<value_type, 3>;
using Real3 = Array<value_type, 3>;
//!@}

// Construct from infinite extents
Expand All @@ -42,22 +42,22 @@ class BoundingBox
inline CELER_FUNCTION BoundingBox();

// Construct from upper and lower points
inline CELER_FUNCTION BoundingBox(Array3 const& lower, Array3 const& upper);
inline CELER_FUNCTION BoundingBox(Real3 const& lower, Real3 const& upper);

//// ACCESSORS ////

// Lower bbox coordinate
CELER_FORCEINLINE_FUNCTION Array3 const& lower() const;
CELER_FORCEINLINE_FUNCTION Real3 const& lower() const;

// Upper bbox coordinate
CELER_FORCEINLINE_FUNCTION Array3 const& upper() const;
CELER_FORCEINLINE_FUNCTION Real3 const& upper() const;

// Whether the bbox is assigned
CELER_FORCEINLINE_FUNCTION explicit operator bool() const;

private:
Array3 lower_;
Array3 upper_;
Real3 lower_;
Real3 upper_;
};

//---------------------------------------------------------------------------//
Expand Down Expand Up @@ -98,7 +98,7 @@ CELER_FUNCTION BoundingBox<T>::BoundingBox()
* at a single point) but upper must not be less than lower.
*/
template<class T>
CELER_FUNCTION BoundingBox<T>::BoundingBox(Array3 const& lo, Array3 const& hi)
CELER_FUNCTION BoundingBox<T>::BoundingBox(Real3 const& lo, Real3 const& hi)
: lower_(lo), upper_(hi)
{
CELER_EXPECT(lower_[0] <= upper_[0] && lower_[1] <= upper_[1]
Expand All @@ -110,8 +110,7 @@ CELER_FUNCTION BoundingBox<T>::BoundingBox(Array3 const& lo, Array3 const& hi)
* Lower bbox coordinate (must be valid).
*/
template<class T>
CELER_FUNCTION typename BoundingBox<T>::Array3 const&
BoundingBox<T>::lower() const
CELER_FUNCTION auto BoundingBox<T>::lower() const -> Real3 const&
{
CELER_EXPECT(*this);
return lower_;
Expand All @@ -122,8 +121,7 @@ BoundingBox<T>::lower() const
* Upper bbox coordinate (must be valid).
*/
template<class T>
CELER_FUNCTION typename BoundingBox<T>::Array3 const&
BoundingBox<T>::upper() const
CELER_FUNCTION auto BoundingBox<T>::upper() const -> Real3 const&
{
CELER_EXPECT(*this);
return upper_;
Expand Down
2 changes: 2 additions & 0 deletions src/orange/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ list(APPEND SOURCES
OrangeParams.cc
OrangeTypes.cc
construct/SurfaceInputBuilder.cc
detail/BIHBuilder.cc
detail/BIHPartitioner.cc
detail/RectArrayInserter.cc
detail/UnitInserter.cc
surf/SurfaceIO.cc
Expand Down
10 changes: 9 additions & 1 deletion src/orange/OrangeData.hh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
#include "corecel/data/CollectionBuilder.hh"
#include "corecel/sys/ThreadId.hh"

#include "BoundingBox.hh"
#include "OrangeTypes.hh"
#include "detail/BIHData.hh"
#include "univ/detail/Types.hh"

namespace celeritas
Expand Down Expand Up @@ -61,6 +63,7 @@ struct VolumeRecord
logic_int max_intersections{0};
logic_int flags{0};
DaughterId daughter_id;

// TODO (KENO geometry): zorder

//! Flag values (bit field)
Expand Down Expand Up @@ -161,8 +164,10 @@ struct SimpleUnitRecord
// Volume data [index by LocalVolumeId]
ItemMap<LocalVolumeId, VolumeRecordId> volumes;

// Bounding Interval Hierachy tree parameters
detail::BIHTree bih_params;

// TODO: transforms
// TODO: acceleration structure (bvh/kdtree/grid)
LocalVolumeId background{}; //!< Default if not in any other volume
bool simple_safety{};

Expand Down Expand Up @@ -273,6 +278,9 @@ struct OrangeParamsData
Items<SurfaceType> surface_types;
Items<Connectivity> connectivities;
Items<VolumeRecord> volume_records;
Items<FastBBox> bboxes;
Items<detail::BIHInnerNode> bih_inner_nodes;
Items<detail::BIHLeafNode> bih_leaf_nodes;

Items<Daughter> daughters;
Items<Translation> translations;
Expand Down
13 changes: 13 additions & 0 deletions src/orange/OrangeTypes.hh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "corecel/Types.hh"
#include "corecel/cont/Array.hh"
#include "corecel/math/NumericLimits.hh"
#include "orange/BoundingBox.hh"
#include "orange/Types.hh"

#include "Types.hh" // IWYU pragma: export
Expand All @@ -27,15 +28,27 @@ namespace celeritas
// TYPE ALIASES
//---------------------------------------------------------------------------//

//! Real type used for acceleration
using fast_real_type = float;

//! Integer type for volume CSG tree representation
using logic_int = unsigned short int;

//! Identifier for a BIHNode objects
using BIHNodeId = OpaqueId<struct BIHNode>;

//! Identifier for a daughter universe
using DaughterId = OpaqueId<struct Daughter>;

//! Identifier for a face within a volume
using FaceId = OpaqueId<struct Face>;

//! Bounding box used for acceleration
using FastBBox = BoundingBox<fast_real_type>;

//! Identifier for a bounding box used for acceleration
using FastBBoxId = OpaqueId<FastBBox>;

//! Identifier for the current "level", i.e., depth of embedded universe
using LevelId = OpaqueId<struct Level>;

Expand Down
222 changes: 222 additions & 0 deletions src/orange/detail/BIHBuilder.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
//----------------------------------*-C++-*----------------------------------//
// Copyright 2022-2023 UT-Battelle, LLC, and other Celeritas developers.
// See the top-level COPYRIGHT file for details.
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
//---------------------------------------------------------------------------//
//! \file orange/detail/BIHBuilder.cc
//---------------------------------------------------------------------------//
#include "BIHBuilder.hh"

#include "orange/BoundingBoxUtils.hh"
#include "orange/detail/BIHUtils.hh"

namespace celeritas
{
namespace detail
{
namespace
{
elliottbiondo marked this conversation as resolved.
Show resolved Hide resolved
//---------------------------------------------------------------------------//
/*!
* Variadic-templated struct for overloaded operator() calls.
*/
template<typename... Ts>
struct Overload : Ts...
{
using Ts::operator()...;
};

//---------------------------------------------------------------------------//
/*!
* "Deduction guide" for instantiating Overload objects w/o specifying types.
*/
template<class... Ts>
Overload(Ts&&...) -> Overload<Ts...>;
} // namespace
//---------------------------------------------------------------------------//
/*!
* Construct from a Storage object
*/
BIHBuilder::BIHBuilder(BIHStorage storage) : storage_(storage)
{
CELER_EXPECT(storage_);
}

//---------------------------------------------------------------------------//
/*!
* Create BIH Nodes.
*/
BIHTree BIHBuilder::operator()(VecBBox bboxes)
{
// Store bounding boxes and their corresponding centers
CELER_EXPECT(!bboxes.empty());
bboxes_ = std::move(bboxes);
centers_.resize(bboxes_.size());
std::transform(bboxes_.begin(),
bboxes_.end(),
centers_.begin(),
&celeritas::center<fast_real_type>);

VecIndices indices;
VecIndices inf_volids;

for (auto i : range(bboxes_.size()))
{
LocalVolumeId id(i);

if (!is_infinite(bboxes_[i]))
{
indices.push_back(id);
}
else
{
inf_volids.push_back(id);
}
}
sethrj marked this conversation as resolved.
Show resolved Hide resolved

VecNodes nodes;
this->construct_tree(indices, &nodes, BIHNodeId{});

auto [inner_nodes, leaf_nodes] = this->arrange_nodes(std::move(nodes));

BIHTree params;

params.bboxes = ItemMap<LocalVolumeId, FastBBoxId>(
make_builder(storage_.bboxes)
.insert_back(bboxes_.begin(), bboxes_.end()));

params.inner_nodes
= make_builder(storage_.inner_nodes)
.insert_back(inner_nodes.begin(), inner_nodes.end());
params.leaf_nodes = make_builder(storage_.leaf_nodes)
.insert_back(leaf_nodes.begin(), leaf_nodes.end());

params.inf_volids = make_builder(storage_.local_volume_ids)
.insert_back(inf_volids.begin(), inf_volids.end());

return params;
}

//---------------------------------------------------------------------------//
// HELPER FUNCTIONS
//---------------------------------------------------------------------------//
/*!
* Recursively construct BIH nodes for a vector of bbox indices.
*/
void BIHBuilder::construct_tree(VecIndices const& indices,
VecNodes* nodes,
BIHNodeId parent) const
{
using Edge = BIHInnerNode::Edge;

auto current_index = nodes->size();
nodes->resize(nodes->size() + 1);

BIHPartitioner partition(&bboxes_, &centers_);

if (auto p = partition(indices))
{
BIHInnerNode node;
node.parent = parent;
node.axis = p.axis;

auto ax = to_int(p.axis);

node.bounding_planes[Edge::left].position
= p.bboxes[Edge::left].upper()[ax];
node.bounding_planes[Edge::right].position
= p.bboxes[Edge::right].lower()[ax];

// Recursively construct the left and right branches

for (auto edge : range(Edge::size_))
{
node.bounding_planes[edge].child = BIHNodeId(nodes->size());
this->construct_tree(
p.indices[edge], nodes, BIHNodeId(current_index));
}

CELER_EXPECT(node);
(*nodes)[current_index] = node;
}
else
{
BIHLeafNode node;
node.parent = parent;
node.vol_ids = make_builder(storage_.local_volume_ids)
.insert_back(indices.begin(), indices.end());

CELER_EXPECT(node);
(*nodes)[current_index] = node;
}
}

//---------------------------------------------------------------------------//
/*!
* Seperate nodes into inner and leaf vectors and renumber accordingly.
*/
BIHBuilder::ArrangedNodes BIHBuilder::arrange_nodes(VecNodes nodes) const
{
VecInnerNodes inner_nodes;
VecLeafNodes leaf_nodes;

std::vector<bool> is_leaf;
std::vector<BIHNodeId> new_ids;

auto visit_node
= Overload{[&](BIHInnerNode const& node) {
new_ids.push_back(BIHNodeId(inner_nodes.size()));
inner_nodes.push_back(node);
is_leaf.push_back(false);
},
[&](BIHLeafNode const& node) {
new_ids.push_back(BIHNodeId(leaf_nodes.size()));
leaf_nodes.push_back(node);
is_leaf.push_back(true);
}};

for (auto const& node : nodes)
{
std::visit(visit_node, node);
}

size_type offset = inner_nodes.size();

for (auto i : range(nodes.size()))
{
if (is_leaf[i])
{
new_ids[i] = new_ids[i] + offset;
}
}

for (auto& inner_node : inner_nodes)
{
for (auto edge : range(BIHInnerNode::Edge::size_))
{
inner_node.bounding_planes[edge].child
= new_ids[inner_node.bounding_planes[edge].child.unchecked_get()];
}

// Handle root node
if (inner_node.parent)
{
inner_node.parent = new_ids[inner_node.parent.unchecked_get()];
}
}

for (auto& leaf_node : leaf_nodes)
{
// Handle where the entire tree is a single leaf node
if (leaf_node.parent)
{
leaf_node.parent = new_ids[leaf_node.parent.unchecked_get()];
}
}

return {std::move(inner_nodes), std::move(leaf_nodes)};
}

//---------------------------------------------------------------------------//
} // namespace detail
} // namespace celeritas
Loading