|
||||
File indexing completed on 2025-01-18 10:05:55
0001 //----------------------------------*-C++-*----------------------------------// 0002 // Copyright 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/orangeinp/detail/DeMorganSimplifier.hh 0007 //---------------------------------------------------------------------------// 0008 #pragma once 0009 0010 #include <utility> 0011 #include <vector> 0012 0013 #include "orange/orangeinp/CsgTree.hh" 0014 #include "orange/orangeinp/CsgTypes.hh" 0015 0016 namespace celeritas 0017 { 0018 namespace orangeinp 0019 { 0020 namespace detail 0021 { 0022 //---------------------------------------------------------------------------// 0023 /*! 0024 * Implement DeMorgan transformations on a \c CsgTree. 0025 * 0026 * This class serves as a helper for \c 0027 * celeritas::orangeinp::transform_negated_joins implementation. It applies 0028 * DeMorgan's law on a \c CsgTree so that all negations of a set operator are 0029 * removed and transformed into their equivalent operation. 0030 * 0031 * The simplification preserves subtrees referred to by \c CsgTree::volumes 0032 * 0033 * Instances of this class shouldn't outlive the \c CsgTree used to construct 0034 * it as we keep a reference to it. 0035 * 0036 * It is currently single-use: calling operator() twice on the same instance 0037 * isn't supported. 0038 * 0039 * The \c CsgTree being simplified shouldn't contain alias nodes or double 0040 * negations. 0041 */ 0042 class DeMorganSimplifier 0043 { 0044 public: 0045 // Construct a simplifier for the given tree 0046 explicit DeMorganSimplifier(CsgTree const&); 0047 0048 // Perform the simplification 0049 CsgTree operator()(); 0050 0051 private: 0052 //! CsgTree node 0 is always True{} and can't be the parent of any node 0053 //! so reuse that bit to tell that a given node is a volume 0054 static constexpr auto is_volume_index_{NodeId{0}}; 0055 //! CsgTree node 1 is always a Negated node parent of node 0, so we can 0056 //! reuse that bit to tell if a node has a parent as it's never set for 0057 //! node id >= 2 0058 static constexpr auto has_parents_index_{NodeId{1}}; 0059 0060 //! First meaningfull node id in a CsgTree 0061 static constexpr auto first_node_id_{NodeId{2}}; 0062 0063 //! Helper struct to translate ids from the original tree to ids in the 0064 //! simplified tree 0065 struct MatchingNodes 0066 { 0067 //! Set if a node has the exact same node in the simplified tree 0068 NodeId unmodified; 0069 0070 //! Indirections to new simplified join following DeMorgan's law 0071 //! Set if the original node is a negated node. 0072 NodeId simplified_to; 0073 //! If a join node has been negated, this points to the opposite join 0074 //! Set if the original node is a joined node. 0075 NodeId opposite_join; 0076 0077 //! Set if we need to insert a new negation of that node 0078 //! Set if the original node is a leaf node. 0079 NodeId new_negation; 0080 0081 //! Whether any matching node id is set 0082 explicit operator bool() const noexcept 0083 { 0084 return unmodified || simplified_to || opposite_join || new_negation; 0085 } 0086 0087 // Lookup a node an equal node in the simplified tree 0088 NodeId equivalent_node() const; 0089 }; 0090 0091 //! Rudimentary 2D square matrix view of a vector<bool> 0092 class Matrix2D 0093 { 0094 public: 0095 using indices = std::pair<NodeId, NodeId>; 0096 0097 // Create the matrix view with the given extent size 0098 explicit Matrix2D(size_type) noexcept; 0099 // Access the element at the given index 0100 std::vector<bool>::reference operator[](indices); 0101 // The extent along one dimension 0102 size_type extent() const noexcept; 0103 0104 private: 0105 // TODO: sparse storage 0106 std::vector<bool> data_; 0107 size_type extent_; 0108 }; 0109 0110 // Dereference Aliased nodes 0111 NodeId dealias(NodeId) const; 0112 0113 // First pass to find negated set operations 0114 void find_join_negations(); 0115 0116 // Declare negated nodes to add in the simplified tree 0117 void add_negation_for_operands(NodeId); 0118 0119 // Second pass to build the simplified tree 0120 CsgTree build_simplified_tree(); 0121 0122 // Special handling for a Joined or Negated node 0123 bool process_negated_joined_nodes(NodeId, CsgTree&); 0124 0125 // Create an opposite Joined node 0126 Joined build_negated_node(Joined const&) const; 0127 0128 // Check if this join node should be inserted in the simplified tree 0129 bool should_insert_join(NodeId); 0130 0131 //! the tree to simplify 0132 CsgTree const& tree_; 0133 0134 //! Set when we must insert a \c Negated parent for the given index 0135 std::vector<bool> new_negated_nodes_; 0136 0137 //! Set when \c Joined nodes have a \c Negated parent, so we need to insert 0138 //! an opposite join node with negated operands 0139 std::vector<bool> negated_join_nodes_; 0140 0141 //! Parents matrix. For nodes n1, n2, if n1 * tree_.size() + n2 is set, it 0142 //! means that n2 is a parent of n1 0143 Matrix2D parents_; 0144 0145 //! Used during construction of the simplified tree to map replaced nodes 0146 //! in the original tree to their new id in the simplified tree 0147 std::vector<MatchingNodes> node_ids_translation_; 0148 }; 0149 0150 //---------------------------------------------------------------------------// 0151 } // namespace detail 0152 } // namespace orangeinp 0153 } // namespace celeritas
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |