Skip to content

Commit

Permalink
simplify unitproto after build the CsgUnit
Browse files Browse the repository at this point in the history
  • Loading branch information
esseivaju committed Sep 19, 2024
1 parent 417ee2f commit 083ba80
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 20 deletions.
2 changes: 1 addition & 1 deletion src/orange/orangeinp/CsgTreeUtils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ void simplify(CsgTree* tree, NodeId start)
* This is required if the tree's logic expression is used with
* \c InfixEvaluator as negated joins are not supported.
*/
CsgTree transform_negated_joins(CsgTree const& tree)
DeMorganSimplifierResult transform_negated_joins(CsgTree const& tree)
{
return detail::DeMorganSimplifier{tree}();
}
Expand Down
4 changes: 3 additions & 1 deletion src/orange/orangeinp/CsgTreeUtils.hh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <vector>

#include "orange/OrangeTypes.hh"
#include "orange/orangeinp/detail/DeMorganSimplifier.hh"

#include "CsgTypes.hh"

Expand All @@ -33,7 +34,8 @@ orangeinp::NodeId simplify_up(CsgTree* tree, orangeinp::NodeId start);
void simplify(CsgTree* tree, orangeinp::NodeId start);

// Replace ~&(xs...) with |(~xs...) and ~|(xs...) with &(~xs...)
[[nodiscard]] CsgTree transform_negated_joins(CsgTree const& tree);
[[nodiscard]] DeMorganSimplifierResult
transform_negated_joins(CsgTree const& tree);

// Transform a CSG node into a string expression
[[nodiscard]] std::string
Expand Down
2 changes: 1 addition & 1 deletion src/orange/orangeinp/UnitProto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ auto UnitProto::build(Tol const& tol, BBox const& bbox) const -> Unit
", ",
write_node_labels);
}

unit_builder.simplifiy_joins();
/*! \todo We can sometimes eliminate CSG surfaces and nodes that aren't
* used by the actual volumes>
*/
Expand Down
30 changes: 30 additions & 0 deletions src/orange/orangeinp/detail/CsgUnitBuilder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "corecel/io/Logger.hh"
#include "corecel/io/StreamableVariant.hh"
#include "orange/OrangeData.hh"
#include "orange/orangeinp/CsgTreeUtils.hh"
#include "orange/transform/TransformIO.hh"
#include "orange/transform/TransformSimplifier.hh"

Expand Down Expand Up @@ -193,6 +194,35 @@ void CsgUnitBuilder::fill_volume(LocalVolumeId v,
CELER_ENSURE(is_filled(unit_->fills[v.unchecked_get()]));
}

//---------------------------------------------------------------------------//
/*!
* Simplify negated joins for Infix evaluation
*/
void CsgUnitBuilder::simplifiy_joins()
{
auto& tree = unit_->tree;
auto simplification = transform_negated_joins(tree);
CELER_EXPECT(tree.size() == simplification.equivalent_nodes.size());
std::vector<std::set<CsgUnit::Metadata>> md;
md.resize(simplification.tree.size());

std::map<NodeId, CsgUnit::Region> regions;

for (auto node_id : range(tree.size()))
{
if (auto equivalent_node = simplification.equivalent_nodes[node_id];
equivalent_node)
{
CELER_EXPECT(equivalent_node < md.size());
md[equivalent_node.unchecked_get()] = unit_->metadata[node_id];
regions[equivalent_node] = unit_->regions[NodeId{node_id}];
}
}
unit_->metadata = std::move(md);
unit_->regions = std::move(regions);
unit_->tree = std::move(simplification.tree);
}

//---------------------------------------------------------------------------//
/*!
* Get a variant surface from a node ID.
Expand Down
3 changes: 3 additions & 0 deletions src/orange/orangeinp/detail/CsgUnitBuilder.hh
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ class CsgUnitBuilder
void
fill_volume(LocalVolumeId, UniverseId, VariantTransform const& transform);

// Simplify negated joins for Infix evaluation
void simplifiy_joins();

private:
CsgUnit* unit_;
Tol tol_;
Expand Down
12 changes: 10 additions & 2 deletions src/orange/orangeinp/detail/DeMorganSimplifier.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,18 @@ DeMorganSimplifier::DeMorganSimplifier(CsgTree const& tree)
* Perform the simplification. The state of the instance isn't cleared, so only
* call this once.
*/
CsgTree DeMorganSimplifier::operator()()
DeMorganSimplifierResult DeMorganSimplifier::operator()()
{
this->find_join_negations();
return this->build_simplified_tree();
auto simplified_tree{this->build_simplified_tree()};
std::vector<NodeId> equivalent_nodes;
equivalent_nodes.reserve(tree_.size());
for (auto node_id : range(tree_.size()))
{
equivalent_nodes.push_back(
node_ids_translation_[node_id].equivalent_node());
}
return {simplified_tree, equivalent_nodes};
}

//---------------------------------------------------------------------------//
Expand Down
13 changes: 12 additions & 1 deletion src/orange/orangeinp/detail/DeMorganSimplifier.hh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@ namespace celeritas
{
namespace orangeinp
{
//---------------------------------------------------------------------------//
/*!
* Result of a DeMorgan simplification.
*/
struct DeMorganSimplifierResult
{
CsgTree tree;
std::vector<NodeId> equivalent_nodes;
};

//---------------------------------------------------------------------------//
namespace detail
{
//---------------------------------------------------------------------------//
Expand Down Expand Up @@ -46,7 +57,7 @@ class DeMorganSimplifier
explicit DeMorganSimplifier(CsgTree const&);

// Perform the simplification
CsgTree operator()();
DeMorganSimplifierResult operator()();

private:
//! CsgTree node 0 is always True{} and can't be the parent of any node
Expand Down
28 changes: 14 additions & 14 deletions test/orange/orangeinp/CsgTreeUtils.test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ TEST_F(CsgTreeUtilsTest, transform_negated_joins)
auto s1 = this->insert(Surface{S{1}});
auto n0 = this->insert(Negated{s1});
auto j0 = this->insert(Joined{op_and, {s0, n0}});
auto simplified = transform_negated_joins(tree_);
auto simplified = transform_negated_joins(tree_).tree;

// Check a well-formed tree
EXPECT_EQ(
Expand All @@ -414,7 +414,7 @@ TEST_F(CsgTreeUtilsTest, transform_negated_joins)
to_string(tree_));

// Check an easy case with just a single negated operand
simplified = transform_negated_joins(tree_);
simplified = transform_negated_joins(tree_).tree;
EXPECT_EQ(
"{0: true, 1: not{0}, 2: surface 0, 3: not{2}, 4: surface 1, 5: "
"any{3,4}, }",
Expand All @@ -429,7 +429,7 @@ TEST_F(CsgTreeUtilsTest, transform_negated_joins)

// Check that the non-negated operand maps to correct new node_ids and
// that not{2} is not deleted
simplified = transform_negated_joins(tree_);
simplified = transform_negated_joins(tree_).tree;
EXPECT_EQ(
"{0: true, 1: not{0}, 2: surface 0, 3: not{2}, 4: surface 1, 5: "
"not{4}, 6: any{3,4}, 7: any{2,5}, }",
Expand All @@ -443,7 +443,7 @@ TEST_F(CsgTreeUtilsTest, transform_negated_joins)
to_string(tree_));

// Check that the two operands are transformed, removing dangling operators
simplified = transform_negated_joins(tree_);
simplified = transform_negated_joins(tree_).tree;
EXPECT_EQ(
"{0: true, 1: not{0}, 2: surface 0, 3: not{2}, 4: surface 1, 5: "
"any{3,4}, 6: all{3,4}, }",
Expand All @@ -459,7 +459,7 @@ TEST_F(CsgTreeUtilsTest, transform_negated_joins)
to_string(tree_));

// Check that disjoint trees are correctly handled
simplified = transform_negated_joins(tree_);
simplified = transform_negated_joins(tree_).tree;
EXPECT_EQ(
"{0: true, 1: not{0}, 2: surface 0, 3: not{2}, 4: surface 1, 5: "
"any{3,4}, 6: all{3,4}, 7: surface 2, 8: not{7}, }",
Expand All @@ -474,7 +474,7 @@ TEST_F(CsgTreeUtilsTest, transform_negated_joins)
to_string(tree_));

// Add a non-transformed operand with suboperands
simplified = transform_negated_joins(tree_);
simplified = transform_negated_joins(tree_).tree;
EXPECT_EQ(
"{0: true, 1: not{0}, 2: surface 0, 3: not{2}, 4: surface 1, 5: "
"not{4}, 6: any{3,4}, 7: all{2,5}, 8: all{3,4}, 9: any{2,5}, 10: "
Expand All @@ -491,7 +491,7 @@ TEST_F(CsgTreeUtilsTest, transform_negated_joins)

// Top-level operand is negated and should be simplified, no need to
// duplicate intermediary Joined nodes
simplified = transform_negated_joins(tree_);
simplified = transform_negated_joins(tree_).tree;
EXPECT_EQ(
"{0: true, 1: not{0}, 2: surface 0, 3: not{2}, 4: surface 1, 5: "
"any{3,4}, 6: all{3,4}, 7: surface 2, 8: not{7}, 9: any{5,6}, }",
Expand All @@ -506,7 +506,7 @@ TEST_F(CsgTreeUtilsTest, transform_negated_joins)
to_string(tree_));

// Top-level joined has Negated{Joined{}} chldrens
simplified = transform_negated_joins(tree_);
simplified = transform_negated_joins(tree_).tree;
EXPECT_EQ(
"{0: true, 1: not{0}, 2: surface 0, 3: not{2}, 4: surface 1, 5: "
"any{3,4}, 6: all{3,4}, 7: surface 2, 8: not{7}, 9: any{5,6}, 10: "
Expand All @@ -522,7 +522,7 @@ TEST_F(CsgTreeUtilsTest, transform_negated_joins)
to_string(tree_));

// Complex case with a negated join with negated join as children
simplified = transform_negated_joins(tree_);
simplified = transform_negated_joins(tree_).tree;
EXPECT_EQ(
"{0: true, 1: not{0}, 2: surface 0, 3: not{2}, 4: surface 1, 5: "
"not{4}, 6: any{3,4}, 7: all{2,5}, 8: all{3,4}, 9: any{2,5}, 10: "
Expand All @@ -549,7 +549,7 @@ TEST_F(CsgTreeUtilsTest, transform_negated_joins)
to_string(tree_));

// Complex case with a negated join with negated children
simplified = transform_negated_joins(tree_);
simplified = transform_negated_joins(tree_).tree;
EXPECT_EQ(
"{0: true, 1: not{0}, 2: surface 0, 3: surface 1, 4: all{2,3}, 5: "
"surface 2, 6: not{5}, 7: all{4,6}, }",
Expand All @@ -567,7 +567,7 @@ TEST_F(CsgTreeUtilsTest, transform_negated_joins)
"{0: true, 1: not{0}, 2: surface 0, 3: surface 1, 4: not{2}, 5: "
"not{3}, 6: all{4,5}, 7: any{4,5}, 8: not{7}, }",
to_string(tree_));
simplified = transform_negated_joins(tree_);
simplified = transform_negated_joins(tree_).tree;
EXPECT_EQ(
"{0: true, 1: not{0}, 2: surface 0, 3: surface 1, 4: not{2}, 5: "
"not{3}, 6: all{4,5}, 7: all{2,3}, }",
Expand Down Expand Up @@ -596,7 +596,7 @@ TEST_F(CsgTreeUtilsTest, transform_negated_joins_with_volumes)
to_string(tree_));

// Complex case with a negated join with negated children
auto simplified = transform_negated_joins(tree_);
auto simplified = transform_negated_joins(tree_).tree;
EXPECT_EQ(
"{0: true, 1: not{0}, 2: surface 0, 3: surface 1, 4: not{2}, 5: "
"not{3}, 6: all{2,3}, 7: any{4,5}, 8: surface 2, 9: not{8}, 10: "
Expand Down Expand Up @@ -625,7 +625,7 @@ TEST_F(CsgTreeUtilsTest, transform_negated_joins_with_volumes)
this->insert(Joined{op_and, {bdy_outer, mz, below_pz}});
this->insert(Joined{op_and, {mz, below_pz}});
tree_.insert_volume(inner_cyl);
simplified = transform_negated_joins(tree_);
simplified = transform_negated_joins(tree_).tree;
EXPECT_EQ(
"{0: true, 1: not{0}, 2: surface 0, 3: not{2}, 4: surface 1, 5: "
"not{4}, 6: surface 2, 7: not{6}, 8: any{3,4,6}, 9: all{2,5,7}, 10: "
Expand Down Expand Up @@ -687,7 +687,7 @@ TEST_F(CsgTreeUtilsTest, transform_negated_joins_with_volumes)
to_string(tree_));

tree_.insert_volume(N{16});
simplified = transform_negated_joins(tree_);
simplified = transform_negated_joins(tree_).tree;
EXPECT_EQ(
"{0: true, 1: not{0}, 2: surface 0, 3: not{2}, 4: surface 1, 5: "
"not{4}, 6: surface 2, 7: not{6}, 8: any{3,4,6}, 9: all{2,5,7}, 10: "
Expand Down

0 comments on commit 083ba80

Please sign in to comment.