diff --git a/include/openmc/cell.h b/include/openmc/cell.h index 23cd0130a8..fd1883ce57 100644 --- a/include/openmc/cell.h +++ b/include/openmc/cell.h @@ -200,8 +200,6 @@ public: //! Definition of spatial region as Boolean expression of half-spaces vector region_; - //! Region in infix that may be modified depending on simplicity - vector region_infix_; bool simple_; //!< Does the region contain only intersections? //! \brief Neighboring cells in the same universe. diff --git a/src/cell.cpp b/src/cell.cpp index 6b4fcafdaa..4a61eb60e2 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -205,7 +205,7 @@ void add_precedence(std::vector& infix) //! This function uses the shunting-yard algorithm. //============================================================================== -vector generate_rpn(int32_t cell_id, vector infix) +vector generate_postfix(int32_t cell_id, vector infix) { vector rpn; vector stack; @@ -619,15 +619,14 @@ CSGCell::CSGCell(pugi::xml_node cell_node) } region_.shrink_to_fit(); - region_infix_ = region_; // If this cell is simple, remove all the superfluous operator tokens. if (simple_) { - for (auto it = region_infix_.begin(); it != region_infix_.end(); it++) { + for (auto it = region_.begin(); it != region_.end(); it++) { if (*it == OP_INTERSECTION || *it > OP_COMPLEMENT) { - region_infix_.erase(it); + region_.erase(it); } } - region_infix_.shrink_to_fit(); + region_.shrink_to_fit(); } // Read the translation vector. @@ -672,7 +671,7 @@ std::pair CSGCell::distance( double min_dist {INFTY}; int32_t i_surf {std::numeric_limits::max()}; - for (int32_t token : region_infix_) { + for (int32_t token : region_) { // Ignore this token if it corresponds to an operator rather than a region. if (token >= OP_UNION) continue; @@ -705,19 +704,18 @@ void CSGCell::to_hdf5_inner(hid_t group_id) const if (!region_.empty()) { std::stringstream region_spec {}; for (int32_t token : region_) { - if (token == OP_LEFT_PAREN) { - region_spec << " ("; - } else if (token == OP_RIGHT_PAREN) { - region_spec << " )"; - } else if (token == OP_COMPLEMENT) { - region_spec << " ~"; - } else if (token == OP_INTERSECTION) { - } else if (token == OP_UNION) { - region_spec << " |"; - } else { + if (token < OP_UNION) { // Note the off-by-one indexing auto surf_id = model::surfaces[abs(token) - 1]->id_; region_spec << " " << ((token > 0) ? surf_id : -surf_id); + } else if (token > OP_COMPLEMENT) { + if (token == OP_LEFT_PAREN) { + region_spec << " ("; + } else { + region_spec << " )"; + } + } else if (token == OP_UNION) { + region_spec << " |"; } } write_string(group_id, "region", region_spec.str(), false); @@ -727,7 +725,7 @@ void CSGCell::to_hdf5_inner(hid_t group_id) const BoundingBox CSGCell::bounding_box_simple() const { BoundingBox bbox; - for (int32_t token : region_infix_) { + for (int32_t token : region_) { bbox &= model::surfaces[abs(token) - 1]->bounding_box(token > 0); } return bbox; @@ -813,12 +811,12 @@ void CSGCell::remove_complement_ops(vector& infix) } } -BoundingBox CSGCell::bounding_box_complex(vector rpn) +BoundingBox CSGCell::bounding_box_complex(vector postfix) { - vector stack(rpn.size()); + vector stack(postfix.size()); int i_stack = -1; - for (auto& token : rpn) { + for (auto& token : postfix) { if (token == OP_UNION) { stack[i_stack - 1] = stack[i_stack - 1] | stack[i_stack]; i_stack--; @@ -837,14 +835,19 @@ BoundingBox CSGCell::bounding_box_complex(vector rpn) BoundingBox CSGCell::bounding_box() const { - return simple_ ? bounding_box_simple() : bounding_box_complex(region_infix_); + if (simple_) { + return bounding_box_simple(); + } else { + auto postfix = generate_postfix(this->id_, this->region_); + return bounding_box_complex(postfix); + } } //============================================================================== bool CSGCell::contains_simple(Position r, Direction u, int32_t on_surface) const { - for (int32_t token : region_infix_) { + for (int32_t token : region_) { // Assume that no tokens are operators. Evaluate the sense of particle with // respect to the surface and see if the token matches the sense. If the // particle's surface attribute is set and matches the token, that @@ -872,7 +875,7 @@ bool CSGCell::contains_complex( int total_depth = 0; // For each token - for (auto it = region_infix_.begin(); it != region_infix_.end(); it++) { + for (auto it = region_.begin(); it != region_.end(); it++) { int32_t token = *it; // If the token is a surface evaluate the sense diff --git a/src/geometry_aux.cpp b/src/geometry_aux.cpp index 7648d270ae..c3458d4697 100644 --- a/src/geometry_aux.cpp +++ b/src/geometry_aux.cpp @@ -154,7 +154,7 @@ void partition_universes() // Collect the set of surfaces in this universe. std::unordered_set surf_inds; for (auto i_cell : univ->cells_) { - for (auto token : model::cells[i_cell]->region_infix_) { + for (auto token : model::cells[i_cell]->region_) { if (token < OP_UNION) surf_inds.insert(std::abs(token) - 1); } diff --git a/src/universe.cpp b/src/universe.cpp index 723400ec05..873d03bb74 100644 --- a/src/universe.cpp +++ b/src/universe.cpp @@ -98,7 +98,7 @@ UniversePartitioner::UniversePartitioner(const Universe& univ) // Find all of the z-planes in this universe. A set is used here for the // O(log(n)) insertions that will ensure entries are not repeated. for (auto i_cell : univ.cells_) { - for (auto token : model::cells[i_cell]->region_infix_) { + for (auto token : model::cells[i_cell]->region_) { if (token < OP_UNION) { auto i_surf = std::abs(token) - 1; const auto* surf = model::surfaces[i_surf].get(); @@ -125,7 +125,7 @@ UniversePartitioner::UniversePartitioner(const Universe& univ) // Find the tokens for bounding z-planes. int32_t lower_token = 0, upper_token = 0; double min_z, max_z; - for (auto token : model::cells[i_cell]->region_infix_) { + for (auto token : model::cells[i_cell]->region_) { if (token < OP_UNION) { const auto* surf = model::surfaces[std::abs(token) - 1].get(); if (const auto* zplane = dynamic_cast(surf)) {