From b94174cf963806dede1dfe6917bdcb315522d448 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Sat, 17 Jul 2021 15:43:38 -0500 Subject: [PATCH 01/16] Adding algorithm for finding parent cells of a cell instance. --- include/openmc/cell.h | 21 ++++- src/cell.cpp | 180 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 197 insertions(+), 4 deletions(-) diff --git a/include/openmc/cell.h b/include/openmc/cell.h index 75d706535a..0502c75174 100644 --- a/include/openmc/cell.h +++ b/include/openmc/cell.h @@ -165,9 +165,15 @@ public: //! \param[in] name Cell name void set_name(const std::string& name) { name_ = name; }; + //! Determine the path to this cell instance in the geometry hierarchy + void find_parent_cells(vector& parent_cells, int32_t instance) const; + + //! Compute the cell's instance given a set of parent cells + int32_t compute_instance(const vector& parent_cells) const; + //! Get all cell instances contained by this cell //! \return Map with cell indexes as keys and instances as values - std::unordered_map> get_contained_cells() const; + std::unordered_map> get_contained_cells(int32_t instance=0) const; protected: void get_contained_cells_inner( @@ -303,10 +309,23 @@ private: //============================================================================== struct ParentCell { + bool operator ==(const ParentCell& other) const + { return cell_index == other.cell_index && lattice_index == other.lattice_index; } + + bool operator <(const ParentCell& other) const + { return cell_index < other.cell_index || (cell_index == other.cell_index && lattice_index < other.lattice_index); } + gsl::index cell_index; gsl::index lattice_index; }; +struct ParentCellHash { + std::size_t operator()(const ParentCell& p) const + { + return 4096*p.cell_index + p.lattice_index; + } +}; + //============================================================================== //! Define an instance of a particular cell //============================================================================== diff --git a/src/cell.cpp b/src/cell.cpp index a88e38541e..56dea76553 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -340,7 +340,7 @@ void Cell::set_temperature(double T, int32_t instance, bool set_contained) id_)}; } - auto contained_cells = this->get_contained_cells(); + auto contained_cells = this->get_contained_cells(instance); for (const auto& entry : contained_cells) { auto& cell = model::cells[entry.first]; Expects(cell->type_ == Fill::MATERIAL); @@ -1220,11 +1220,184 @@ extern "C" int openmc_cell_set_name(int32_t index, const char* name) return 0; } -std::unordered_map> Cell::get_contained_cells() const +void +Cell::find_parent_cells(vector& parent_cells, int32_t instance) const +{ + // clear out the list of parent cells + parent_cells.clear(); + // start with this cell's universe + int32_t visited_univ = -1; + int32_t prev_univ_idx = -1; + int32_t univ_idx = this->universe_; + int32_t search_instance = -1; + + std::set visited_cells; + + while (true) { + const auto& univ = model::universes[univ_idx]; + prev_univ_idx = univ_idx; + for (const auto& cell : model::cells) { + // if this is in our current set of visited cells, move on + if (visited_cells.count({model::cell_map[cell->id_], -1})) continue; + + if (cell->type_ == Fill::UNIVERSE) { + if(cell->fill_ == univ_idx) { + parent_cells.push_back({model::cell_map[cell->id_], -1}); + univ_idx = cell->universe_; + } + } else if (cell->type_ == Fill::LATTICE) { + const auto& lattice = model::lattices[cell->fill_]; + const auto& lattice_univs = lattice->universes_; + auto lat_it = lattice_univs.begin(); + while (true) { + // find the next lattice cell with this universe + lat_it = std::find(lat_it, lattice_univs.end(), univ_idx); + if (lat_it >= lattice_univs.end()) break; + + int lattice_idx = lat_it - lattice_univs.begin(); + + lat_it++; + + if (visited_cells.count({model::cell_map[cell->id_], lattice_idx})) continue; + + parent_cells.push_back({model::cell_map[cell->id_], 0}); + univ_idx = cell->universe_; + } + } + // if we've updated the universe, break + if (prev_univ_idx != univ_idx) break; + } + // if we're at the top of the geometry and the instance matches, we're done + if (univ_idx == model::root_universe && this->compute_instance(parent_cells) == instance) return; + + // if we don't find a suitable update, adjust the stack and continue + if (univ_idx == model::root_universe || univ_idx == prev_univ_idx) { + + // if there was no match on this cell's universe, report an error + if (univ_idx == this->universe_) { + std::cout << fmt::format("Could not find the parent cells for cell {}, instance {}.", this->id_, instance) << std::endl; + return; + } + + // remove previous cells from visited so we don't skip them later for a new + // path through the geometry hierarchy + if (visited_univ != -1 && univ_idx != model::root_universe) { + const auto& univ = model::universes[visited_univ]; + for (auto cell_indx : univ->cells_) { + for (auto p_cell = visited_cells.begin(); p_cell != visited_cells.end(); p_cell++) { + if (p_cell->cell_index == cell_indx) visited_cells.erase(p_cell++); + if (p_cell == visited_cells.end()) break; + } + } + } + + visited_cells.insert(parent_cells.back()); + visited_univ = model::cells[parent_cells.back().cell_index]->universe_; + parent_cells.pop_back(); + + if (parent_cells.empty()) univ_idx = this->universe_; + else univ_idx = model::cells[parent_cells.back().cell_index]->universe_; + } + + } // end while + + std::reverse(parent_cells.begin(), parent_cells.end()); + + // while (univ_idx != model::root_universe) { + // // find the cell (or lattice) that contains this universe + // int32_t old_idx = univ_idx; + // for (const auto& cell : model::cells) { + + // if (cell->type_ == Fill::UNIVERSE) { + // // if this cell is filled with the universe we're looking for, + // // add it to the parent cells and update the universe index + // if (cell->fill_ == univ_idx) { + // parent_cells.push_back({model::cell_map[cell->id_], -1}); + // univ_idx = cell->universe_; + // break; + // } + // } else if (cell->type_ == Fill::LATTICE) { + // // if any of the lattice cells contain the universe we're looking + // // for, add it to the set of parent cells + // const auto& lattice = model::lattices[cell->fill_]; + // for(auto lit = lattice->begin(); lit != lattice->end(); ++lit) { + // if (lattice->universes_[lit.indx_] == univ_idx) { + // parent_cells.push_back({model::cell_map[cell->id_], lit.indx_}); + // univ_idx = cell->universe_; + // break; + // } + // } + // } + // } + // if (old_idx == univ_idx) { + // fatal_error(fmt::format("Failed to find a cell filled with universe {}", openmc::model::universes[univ_idx]->id_)); + // } + // } + + // // reverse the set of parent cells so the order goes highest to + // // lowest level in the geometry + // std::reverse(parent_cells.begin(), parent_cells.end()); + + // // check the instance for this set of parent cells and + // // return the current parent cells if it matches + // if (this->compute_instance(parent_cells) == instance) return; + + // // TO-DO: Check the cell instance here and repeat process if needed + // for (auto it = parent_cells.begin(); it != parent_cells.end() - 1; it++) { + // // check for another cell containing this universe + // auto& cell = model::cells[it->cell_index]; + // auto& univ = model::universes[cell->universe_]; + + // // get the child cell's universe to look for + // int32_t fill_idx = model::cells[(it+1)->cell_index]->fill_; + // Fill fill_type = model::cells[(it+1)->cell_index]->type_; + + // for (auto& cell_indx : univ->cells_) { + // auto& univ_cell = model::cells[cell_indx]; + // // if we get a matching cell fill, try this out instead + // if (univ_cell->fill_ != fill_idx || univ_cell->type_ != fill_type) continue; + + // if (univ_cell->type_ == Fill::UNIVERSE) { + // *it = {cell_indx, -1}; + // if (this->compute_instance(parent_cells) == instance) return; + // } else if (univ_cell->type_ == Fill::LATTICE) { + // const auto& lattice = model::lattices[univ_cell->fill_]; + // int lat_univ = lattice->universes_[it->lattice_index]; + // for (auto lit = lattice->begin(); lit != lattice->end(); ++lit) { + // if (lat_univ == lattice->universes_[lit.indx_]) { + // *it = {cell_indx, lit.indx_}; + // if (this->compute_instance(parent_cells) == instance) return; + // } + // } + // } + // } + // } + + // fatal_error(fmt::format("Could not compute the parent cells of cell {} (instance {})", id_, instance)); +} + +int32_t Cell::compute_instance(const vector& parent_cells) const { + int32_t instance = 0; + for (const auto& parent_cell : parent_cells) { + auto& cell = model::cells[parent_cell.cell_index]; + if (cell->type_ == Fill::UNIVERSE) { + instance += cell->offset_[this->distribcell_index_]; + } else if (cell->type_ == Fill::LATTICE) { + auto& lattice = model::lattices[cell->fill_]; + instance += lattice->offset(this->distribcell_index_, parent_cell.lattice_index); + } + } + return instance; +} + +std::unordered_map> Cell::get_contained_cells(int32_t instance) const { std::unordered_map> contained_cells; vector parent_cells; + // find the pathway through the geometry to this cell + this->find_parent_cells(parent_cells, instance); + // if this cell is filled w/ a material, it contains no other cells if (type_ != Fill::MATERIAL) { this->get_contained_cells_inner(contained_cells, parent_cells); @@ -1242,9 +1415,10 @@ void Cell::get_contained_cells_inner( // filled by material, determine instance based on parent cells if (type_ == Fill::MATERIAL) { int instance = 0; + // std::cout << "Cell " << id_ << " offset: " << this->distribcell_index_ << std::endl; if (this->distribcell_index_ >= 0) { for (auto& parent_cell : parent_cells) { - auto& cell = openmc::model::cells[parent_cell.cell_index]; + auto& cell = model::cells[parent_cell.cell_index]; if (cell->type_ == Fill::UNIVERSE) { instance += cell->offset_[distribcell_index_]; } else if (cell->type_ == Fill::LATTICE) { From 0e68bb9b9a0f8a8dc443ce81c3d00ce6efad05a8 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Thu, 12 Aug 2021 12:56:03 -0500 Subject: [PATCH 02/16] Removing old, commented alg. --- src/cell.cpp | 72 ---------------------------------------------------- 1 file changed, 72 deletions(-) diff --git a/src/cell.cpp b/src/cell.cpp index 56dea76553..d9ab4cfea7 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -1302,78 +1302,6 @@ Cell::find_parent_cells(vector& parent_cells, int32_t instance) cons } // end while std::reverse(parent_cells.begin(), parent_cells.end()); - - // while (univ_idx != model::root_universe) { - // // find the cell (or lattice) that contains this universe - // int32_t old_idx = univ_idx; - // for (const auto& cell : model::cells) { - - // if (cell->type_ == Fill::UNIVERSE) { - // // if this cell is filled with the universe we're looking for, - // // add it to the parent cells and update the universe index - // if (cell->fill_ == univ_idx) { - // parent_cells.push_back({model::cell_map[cell->id_], -1}); - // univ_idx = cell->universe_; - // break; - // } - // } else if (cell->type_ == Fill::LATTICE) { - // // if any of the lattice cells contain the universe we're looking - // // for, add it to the set of parent cells - // const auto& lattice = model::lattices[cell->fill_]; - // for(auto lit = lattice->begin(); lit != lattice->end(); ++lit) { - // if (lattice->universes_[lit.indx_] == univ_idx) { - // parent_cells.push_back({model::cell_map[cell->id_], lit.indx_}); - // univ_idx = cell->universe_; - // break; - // } - // } - // } - // } - // if (old_idx == univ_idx) { - // fatal_error(fmt::format("Failed to find a cell filled with universe {}", openmc::model::universes[univ_idx]->id_)); - // } - // } - - // // reverse the set of parent cells so the order goes highest to - // // lowest level in the geometry - // std::reverse(parent_cells.begin(), parent_cells.end()); - - // // check the instance for this set of parent cells and - // // return the current parent cells if it matches - // if (this->compute_instance(parent_cells) == instance) return; - - // // TO-DO: Check the cell instance here and repeat process if needed - // for (auto it = parent_cells.begin(); it != parent_cells.end() - 1; it++) { - // // check for another cell containing this universe - // auto& cell = model::cells[it->cell_index]; - // auto& univ = model::universes[cell->universe_]; - - // // get the child cell's universe to look for - // int32_t fill_idx = model::cells[(it+1)->cell_index]->fill_; - // Fill fill_type = model::cells[(it+1)->cell_index]->type_; - - // for (auto& cell_indx : univ->cells_) { - // auto& univ_cell = model::cells[cell_indx]; - // // if we get a matching cell fill, try this out instead - // if (univ_cell->fill_ != fill_idx || univ_cell->type_ != fill_type) continue; - - // if (univ_cell->type_ == Fill::UNIVERSE) { - // *it = {cell_indx, -1}; - // if (this->compute_instance(parent_cells) == instance) return; - // } else if (univ_cell->type_ == Fill::LATTICE) { - // const auto& lattice = model::lattices[univ_cell->fill_]; - // int lat_univ = lattice->universes_[it->lattice_index]; - // for (auto lit = lattice->begin(); lit != lattice->end(); ++lit) { - // if (lat_univ == lattice->universes_[lit.indx_]) { - // *it = {cell_indx, lit.indx_}; - // if (this->compute_instance(parent_cells) == instance) return; - // } - // } - // } - // } - // } - - // fatal_error(fmt::format("Could not compute the parent cells of cell {} (instance {})", id_, instance)); } int32_t Cell::compute_instance(const vector& parent_cells) const { From 683a671d117be477f06e38c0ba15e583ec69f7e0 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Mon, 16 Aug 2021 15:54:33 -0500 Subject: [PATCH 03/16] Moving error message to a more universal location. Correction to lattice loop. --- src/cell.cpp | 38 ++++++++++---------------------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/src/cell.cpp b/src/cell.cpp index d9ab4cfea7..01282e35b0 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -1260,44 +1260,26 @@ Cell::find_parent_cells(vector& parent_cells, int32_t instance) cons if (visited_cells.count({model::cell_map[cell->id_], lattice_idx})) continue; - parent_cells.push_back({model::cell_map[cell->id_], 0}); + parent_cells.push_back({model::cell_map[cell->id_], lattice_idx}); univ_idx = cell->universe_; } } // if we've updated the universe, break if (prev_univ_idx != univ_idx) break; } + // if we're at the top of the geometry and the instance matches, we're done - if (univ_idx == model::root_universe && this->compute_instance(parent_cells) == instance) return; + if (univ_idx == model::root_universe && this->compute_instance(parent_cells) == instance) break; + + // if there was no match on this cell's universe, report an error + if (univ_idx == this->universe_) { + std::cout << fmt::format("Could not find the parent cells for cell {}, instance {}.", this->id_, instance) << std::endl; + return; + } // if we don't find a suitable update, adjust the stack and continue if (univ_idx == model::root_universe || univ_idx == prev_univ_idx) { - - // if there was no match on this cell's universe, report an error - if (univ_idx == this->universe_) { - std::cout << fmt::format("Could not find the parent cells for cell {}, instance {}.", this->id_, instance) << std::endl; - return; - } - - // remove previous cells from visited so we don't skip them later for a new - // path through the geometry hierarchy - if (visited_univ != -1 && univ_idx != model::root_universe) { - const auto& univ = model::universes[visited_univ]; - for (auto cell_indx : univ->cells_) { - for (auto p_cell = visited_cells.begin(); p_cell != visited_cells.end(); p_cell++) { - if (p_cell->cell_index == cell_indx) visited_cells.erase(p_cell++); - if (p_cell == visited_cells.end()) break; - } - } - } - - visited_cells.insert(parent_cells.back()); - visited_univ = model::cells[parent_cells.back().cell_index]->universe_; - parent_cells.pop_back(); - - if (parent_cells.empty()) univ_idx = this->universe_; - else univ_idx = model::cells[parent_cells.back().cell_index]->universe_; - } + } } // end while From 0817a792d92b89bb44b03b4e120be248fc3a4b23 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Mon, 16 Aug 2021 16:21:12 -0500 Subject: [PATCH 04/16] Applying a new stack to simplify parent cell traversal alg. --- include/openmc/cell.h | 28 ++++++++++++++++++++++++++++ src/cell.cpp | 23 ++++++++++------------- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/include/openmc/cell.h b/include/openmc/cell.h index 0502c75174..856337e46f 100644 --- a/include/openmc/cell.h +++ b/include/openmc/cell.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "hdf5.h" #include "pugixml.hpp" @@ -319,6 +320,33 @@ struct ParentCell { gsl::index lattice_index; }; +struct ParentCellStack { + + void push_back(int32_t search_universe, const ParentCell& pc) { + parent_cells_.push_back(pc); + // add parent cell to the set of cells we've visited for this search universe + visited_cells_[search_universe].insert(pc); + } + + void pop_back() { + visited_cells_[this->current_univ()].clear(); + parent_cells_.pop_back(); + } + + bool visited(int32_t univ_idx, const ParentCell& parent_cell) { + return visited_cells_[univ_idx].count(parent_cell) != 0; + } + + int32_t current_univ() const { return model::cells[parent_cells_.back().cell_index]->universe_; } + + bool empty() const { return parent_cells_.empty(); } + + std::vector parent_cells() { return parent_cells_; } + + std::vector parent_cells_; + std::unordered_map> visited_cells_; +}; + struct ParentCellHash { std::size_t operator()(const ParentCell& p) const { diff --git a/src/cell.cpp b/src/cell.cpp index 01282e35b0..568ec79014 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include @@ -1223,26 +1222,21 @@ extern "C" int openmc_cell_set_name(int32_t index, const char* name) void Cell::find_parent_cells(vector& parent_cells, int32_t instance) const { - // clear out the list of parent cells - parent_cells.clear(); + ParentCellStack stack; // start with this cell's universe - int32_t visited_univ = -1; - int32_t prev_univ_idx = -1; + int32_t prev_univ_idx = C_NONE; int32_t univ_idx = this->universe_; - int32_t search_instance = -1; - - std::set visited_cells; while (true) { const auto& univ = model::universes[univ_idx]; prev_univ_idx = univ_idx; for (const auto& cell : model::cells) { // if this is in our current set of visited cells, move on - if (visited_cells.count({model::cell_map[cell->id_], -1})) continue; + if (stack.visited(univ_idx, {model::cell_map[cell->id_], C_NONE})) continue; if (cell->type_ == Fill::UNIVERSE) { if(cell->fill_ == univ_idx) { - parent_cells.push_back({model::cell_map[cell->id_], -1}); + stack.push_back(univ_idx, {model::cell_map[cell->id_], C_NONE}); univ_idx = cell->universe_; } } else if (cell->type_ == Fill::LATTICE) { @@ -1258,9 +1252,9 @@ Cell::find_parent_cells(vector& parent_cells, int32_t instance) cons lat_it++; - if (visited_cells.count({model::cell_map[cell->id_], lattice_idx})) continue; + if (stack.visited(univ_idx, {model::cell_map[cell->id_], lattice_idx})) continue; - parent_cells.push_back({model::cell_map[cell->id_], lattice_idx}); + stack.push_back(univ_idx, {model::cell_map[cell->id_], lattice_idx}); univ_idx = cell->universe_; } } @@ -1279,10 +1273,13 @@ Cell::find_parent_cells(vector& parent_cells, int32_t instance) cons // if we don't find a suitable update, adjust the stack and continue if (univ_idx == model::root_universe || univ_idx == prev_univ_idx) { - } + stack.pop_back(); + univ_idx = stack.empty() ? this->universe_ : stack.current_univ(); + } } // end while + parent_cells = stack.parent_cells(); std::reverse(parent_cells.begin(), parent_cells.end()); } From b9851b4c36188a3143ac79fff69668060d1d5610 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Tue, 17 Aug 2021 19:30:54 -0500 Subject: [PATCH 05/16] Some cleanup of the alg and ParentStack accessor. --- include/openmc/cell.h | 12 ++++++++---- src/cell.cpp | 30 +++++++++++++++++------------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/include/openmc/cell.h b/include/openmc/cell.h index 856337e46f..0e3e4b5df6 100644 --- a/include/openmc/cell.h +++ b/include/openmc/cell.h @@ -167,7 +167,8 @@ public: void set_name(const std::string& name) { name_ = name; }; //! Determine the path to this cell instance in the geometry hierarchy - void find_parent_cells(vector& parent_cells, int32_t instance) const; + vector + find_parent_cells(vector& parent_cells, int32_t instance) const; //! Compute the cell's instance given a set of parent cells int32_t compute_instance(const vector& parent_cells) const; @@ -322,13 +323,13 @@ struct ParentCell { struct ParentCellStack { - void push_back(int32_t search_universe, const ParentCell& pc) { + void push(int32_t search_universe, const ParentCell& pc) { parent_cells_.push_back(pc); // add parent cell to the set of cells we've visited for this search universe visited_cells_[search_universe].insert(pc); } - void pop_back() { + void pop() { visited_cells_[this->current_univ()].clear(); parent_cells_.pop_back(); } @@ -341,8 +342,11 @@ struct ParentCellStack { bool empty() const { return parent_cells_.empty(); } - std::vector parent_cells() { return parent_cells_; } + // Accessors + std::vector& parent_cells() { return parent_cells_; } + const std::vector& parent_cells() const { return parent_cells_; } + // Data Members std::vector parent_cells_; std::unordered_map> visited_cells_; }; diff --git a/src/cell.cpp b/src/cell.cpp index 568ec79014..60e7f89f32 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -1219,7 +1219,7 @@ extern "C" int openmc_cell_set_name(int32_t index, const char* name) return 0; } -void +vector Cell::find_parent_cells(vector& parent_cells, int32_t instance) const { ParentCellStack stack; @@ -1233,10 +1233,12 @@ Cell::find_parent_cells(vector& parent_cells, int32_t instance) cons for (const auto& cell : model::cells) { // if this is in our current set of visited cells, move on if (stack.visited(univ_idx, {model::cell_map[cell->id_], C_NONE})) continue; + // if this is a material-filled cell, move on + if (cell->type_ == Fill::MATERIAL) continue; if (cell->type_ == Fill::UNIVERSE) { if(cell->fill_ == univ_idx) { - stack.push_back(univ_idx, {model::cell_map[cell->id_], C_NONE}); + stack.push(univ_idx, {model::cell_map[cell->id_], C_NONE}); univ_idx = cell->universe_; } } else if (cell->type_ == Fill::LATTICE) { @@ -1254,8 +1256,9 @@ Cell::find_parent_cells(vector& parent_cells, int32_t instance) cons if (stack.visited(univ_idx, {model::cell_map[cell->id_], lattice_idx})) continue; - stack.push_back(univ_idx, {model::cell_map[cell->id_], lattice_idx}); + stack.push(univ_idx, {model::cell_map[cell->id_], lattice_idx}); univ_idx = cell->universe_; + break; } } // if we've updated the universe, break @@ -1263,24 +1266,24 @@ Cell::find_parent_cells(vector& parent_cells, int32_t instance) cons } // if we're at the top of the geometry and the instance matches, we're done - if (univ_idx == model::root_universe && this->compute_instance(parent_cells) == instance) break; + if (univ_idx == model::root_universe && this->compute_instance(stack.parent_cells()) == instance) break; - // if there was no match on this cell's universe, report an error + // if there was no match on the current cell's universe, report an error if (univ_idx == this->universe_) { - std::cout << fmt::format("Could not find the parent cells for cell {}, instance {}.", this->id_, instance) << std::endl; - return; + fatal_error(fmt::format("Could not find the parent cells for cell {}, instance {}.", this->id_, instance)); } // if we don't find a suitable update, adjust the stack and continue if (univ_idx == model::root_universe || univ_idx == prev_univ_idx) { - stack.pop_back(); + stack.pop(); univ_idx = stack.empty() ? this->universe_ : stack.current_univ(); } } // end while - parent_cells = stack.parent_cells(); - std::reverse(parent_cells.begin(), parent_cells.end()); + // reverse the stack so the highest cell comes first + std::reverse(stack.parent_cells().begin(), stack.parent_cells().end()); + return stack.parent_cells(); } int32_t Cell::compute_instance(const vector& parent_cells) const { @@ -1300,10 +1303,12 @@ int32_t Cell::compute_instance(const vector& parent_cells) const { std::unordered_map> Cell::get_contained_cells(int32_t instance) const { std::unordered_map> contained_cells; - vector parent_cells; + + // if this is a material-filled cell it has no contained cells + if (this->type_ == Fill::MATERIAL) return contained_cells; // find the pathway through the geometry to this cell - this->find_parent_cells(parent_cells, instance); + vector parent_cells = this->find_parent_cells(parent_cells, instance); // if this cell is filled w/ a material, it contains no other cells if (type_ != Fill::MATERIAL) { @@ -1322,7 +1327,6 @@ void Cell::get_contained_cells_inner( // filled by material, determine instance based on parent cells if (type_ == Fill::MATERIAL) { int instance = 0; - // std::cout << "Cell " << id_ << " offset: " << this->distribcell_index_ << std::endl; if (this->distribcell_index_ >= 0) { for (auto& parent_cell : parent_cells) { auto& cell = model::cells[parent_cell.cell_index]; From 0bed3f53b251718984aa1ddf06cb7494b98be709 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Tue, 17 Aug 2021 19:31:50 -0500 Subject: [PATCH 06/16] Adding a test for setting cell temperatures under a specific higher level cell instance in the cpp driver test. --- tests/regression_tests/cpp_driver/driver.cpp | 9 ++++++++- tests/regression_tests/cpp_driver/inputs_true.dat | 9 +++++---- tests/regression_tests/cpp_driver/results_true.dat | 2 ++ tests/regression_tests/cpp_driver/test.py | 9 +++++++-- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/tests/regression_tests/cpp_driver/driver.cpp b/tests/regression_tests/cpp_driver/driver.cpp index 995d91e084..48ed7f3171 100644 --- a/tests/regression_tests/cpp_driver/driver.cpp +++ b/tests/regression_tests/cpp_driver/driver.cpp @@ -6,6 +6,7 @@ #include "openmc/cell.h" #include "openmc/error.h" #include "openmc/geometry.h" +#include "openmc/geometry_aux.h" #include "openmc/message_passing.h" #include "openmc/summary.h" #include "openmc/tallies/filter.h" @@ -31,11 +32,14 @@ int main(int argc, char** argv) { for (auto& entry : openmc::model::cell_map) { cell_indices.push_back(entry.second); } + // enable distribcells offsets for all cells + prepare_distribcell(&cell_indices); // sort to make sure the cell bins appear in the same // order as the test relying on the openmc exe std::sort(cell_indices.begin(), cell_indices.end()); cell_filter->set_cells(cell_indices); + // create a new tally auto tally = Tally::create(); std::vector filters = {cell_filter}; @@ -46,7 +50,7 @@ int main(int argc, char** argv) { // the lattice auto& root_univ = openmc::model::universes[openmc::model::root_universe]; auto& lattice_cell = openmc::model::cells[root_univ->cells_[0]]; - lattice_cell->set_temperature(300, 1, true); + lattice_cell->set_temperature(300.0, 0, true); // check that material-filled cells return no contained cells for (auto& cell : openmc::model::cells) { @@ -56,6 +60,9 @@ int main(int argc, char** argv) { } } + // set a higher temperature for only one of the lattice cells (ID is 4 in the model) + model::cells[model::cell_map[4]]->set_temperature(400.0, 3, true); + // the summary file will be used to check that // temperatures were set correctly so clear // error output can be provided diff --git a/tests/regression_tests/cpp_driver/inputs_true.dat b/tests/regression_tests/cpp_driver/inputs_true.dat index 84efa64672..faa3fa9b1a 100644 --- a/tests/regression_tests/cpp_driver/inputs_true.dat +++ b/tests/regression_tests/cpp_driver/inputs_true.dat @@ -3,14 +3,15 @@ - - + + + 4.0 4.0 2 2 -4.0 -4.0 -1 1 -1 1 +2 2 +2 2 diff --git a/tests/regression_tests/cpp_driver/results_true.dat b/tests/regression_tests/cpp_driver/results_true.dat index 47d47ff6b0..e44b45054a 100644 --- a/tests/regression_tests/cpp_driver/results_true.dat +++ b/tests/regression_tests/cpp_driver/results_true.dat @@ -9,3 +9,5 @@ tally 1: 9.919885E+02 2.174849E+02 5.292948E+03 +2.174849E+02 +5.292948E+03 diff --git a/tests/regression_tests/cpp_driver/test.py b/tests/regression_tests/cpp_driver/test.py index 42f0c2e581..0726e4c6ec 100644 --- a/tests/regression_tests/cpp_driver/test.py +++ b/tests/regression_tests/cpp_driver/test.py @@ -81,11 +81,15 @@ def model(): pincell_univ = openmc.Universe(cells=[fuel, cladding, moderator]) + # insert an additional cell to add another level to the geometry + extra_cell = openmc.Cell(fill=pincell_univ) + extra_univ = openmc.Universe(cells=[extra_cell]) + # lattice lattice = openmc.RectLattice() lattice.pitch = (4.0, 4.0) lattice.lower_left = (-4.0, -4.0) - lattice.universes = [[pincell_univ, pincell_univ], [pincell_univ, pincell_univ]] + lattice.universes = [[extra_univ, extra_univ], [extra_univ, extra_univ]] lattice_region = openmc.model.rectangular_prism(8.0, 8.0, boundary_type='reflective') @@ -130,7 +134,8 @@ class ExternalDriverTestHarness(PyAPITestHarness): for cell in cells.values(): if isinstance(cell.fill, openmc.Material): assert len(cell.temperature) == 4 - assert_allclose(cell.temperature, 300.0) + assert_allclose(cell.temperature[:3], 300.0) + assert_allclose(cell.temperature[-1:], 400.0) def test_cpp_driver(cpp_driver, model): From 64e93c930c1fe45f6784f7a09edf5fc0eb499ace Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Wed, 18 Aug 2021 08:52:10 -0500 Subject: [PATCH 07/16] Moving the compute_instance method to the ParentCellStack and adding some documentation there. --- include/openmc/cell.h | 26 +++++++++++++++++--------- src/cell.cpp | 12 +++++++----- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/include/openmc/cell.h b/include/openmc/cell.h index 0e3e4b5df6..6cce58f7a8 100644 --- a/include/openmc/cell.h +++ b/include/openmc/cell.h @@ -321,27 +321,42 @@ struct ParentCell { gsl::index lattice_index; }; +struct ParentCellHash { + std::size_t operator()(const ParentCell& p) const + { + return 4096*p.cell_index + p.lattice_index; + } +}; + struct ParentCellStack { + //! push method that adds to the parent_cells visited cells for this search universe void push(int32_t search_universe, const ParentCell& pc) { parent_cells_.push_back(pc); // add parent cell to the set of cells we've visited for this search universe visited_cells_[search_universe].insert(pc); } + //! removes the last parent_cell and clears the visited cells for the popped cell's universe void pop() { visited_cells_[this->current_univ()].clear(); parent_cells_.pop_back(); } - bool visited(int32_t univ_idx, const ParentCell& parent_cell) { - return visited_cells_[univ_idx].count(parent_cell) != 0; + //! checks whether or not the parent cell has been visited already for this search universe + bool visited(int32_t search_universe, const ParentCell& parent_cell) { + return visited_cells_[search_universe].count(parent_cell) != 0; } + //! return the next universe to search for a parent cell int32_t current_univ() const { return model::cells[parent_cells_.back().cell_index]->universe_; } + //! indicates whether nor not parent cells are present on the stack bool empty() const { return parent_cells_.empty(); } + //! compute an instance for the provided distribcell index + int32_t compute_instance(int32_t distribcell_index) const; + // Accessors std::vector& parent_cells() { return parent_cells_; } const std::vector& parent_cells() const { return parent_cells_; } @@ -351,13 +366,6 @@ struct ParentCellStack { std::unordered_map> visited_cells_; }; -struct ParentCellHash { - std::size_t operator()(const ParentCell& p) const - { - return 4096*p.cell_index + p.lattice_index; - } -}; - //============================================================================== //! Define an instance of a particular cell //============================================================================== diff --git a/src/cell.cpp b/src/cell.cpp index 60e7f89f32..9bfe2be31f 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -1266,7 +1266,7 @@ Cell::find_parent_cells(vector& parent_cells, int32_t instance) cons } // if we're at the top of the geometry and the instance matches, we're done - if (univ_idx == model::root_universe && this->compute_instance(stack.parent_cells()) == instance) break; + if (univ_idx == model::root_universe && stack.compute_instance(this->distribcell_index_) == instance) break; // if there was no match on the current cell's universe, report an error if (univ_idx == this->universe_) { @@ -1286,15 +1286,17 @@ Cell::find_parent_cells(vector& parent_cells, int32_t instance) cons return stack.parent_cells(); } -int32_t Cell::compute_instance(const vector& parent_cells) const { +int32_t +ParentCellStack::compute_instance(int32_t distribcell_index) const +{ int32_t instance = 0; - for (const auto& parent_cell : parent_cells) { + for (const auto& parent_cell : this->parent_cells_) { auto& cell = model::cells[parent_cell.cell_index]; if (cell->type_ == Fill::UNIVERSE) { - instance += cell->offset_[this->distribcell_index_]; + instance += cell->offset_[distribcell_index]; } else if (cell->type_ == Fill::LATTICE) { auto& lattice = model::lattices[cell->fill_]; - instance += lattice->offset(this->distribcell_index_, parent_cell.lattice_index); + instance += lattice->offset(distribcell_index, parent_cell.lattice_index); } } return instance; From e5e1c6eccc389538a9be25b89b87b3255e2cf265 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Wed, 18 Aug 2021 09:20:29 -0500 Subject: [PATCH 08/16] Adding a few more comments. Changing to use of openmc::vector. --- include/openmc/cell.h | 15 ++++++++------- src/cell.cpp | 20 ++++++++++++++------ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/include/openmc/cell.h b/include/openmc/cell.h index 6cce58f7a8..ac0c324300 100644 --- a/include/openmc/cell.h +++ b/include/openmc/cell.h @@ -166,10 +166,6 @@ public: //! \param[in] name Cell name void set_name(const std::string& name) { name_ = name; }; - //! Determine the path to this cell instance in the geometry hierarchy - vector - find_parent_cells(vector& parent_cells, int32_t instance) const; - //! Compute the cell's instance given a set of parent cells int32_t compute_instance(const vector& parent_cells) const; @@ -178,6 +174,11 @@ public: std::unordered_map> get_contained_cells(int32_t instance=0) const; protected: + //! Determine the path to this cell instance in the geometry hierarchy + vector + find_parent_cells(vector& parent_cells, int32_t instance) const; + + //! Inner function for retrieving contained cells void get_contained_cells_inner( std::unordered_map>& contained_cells, vector& parent_cells) const; @@ -358,11 +359,11 @@ struct ParentCellStack { int32_t compute_instance(int32_t distribcell_index) const; // Accessors - std::vector& parent_cells() { return parent_cells_; } - const std::vector& parent_cells() const { return parent_cells_; } + vector& parent_cells() { return parent_cells_; } + const vector& parent_cells() const { return parent_cells_; } // Data Members - std::vector parent_cells_; + vector parent_cells_; std::unordered_map> visited_cells_; }; diff --git a/src/cell.cpp b/src/cell.cpp index 9bfe2be31f..0e7adcdf64 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -1224,26 +1224,33 @@ Cell::find_parent_cells(vector& parent_cells, int32_t instance) cons { ParentCellStack stack; // start with this cell's universe - int32_t prev_univ_idx = C_NONE; + int32_t prev_univ_idx; int32_t univ_idx = this->universe_; while (true) { const auto& univ = model::universes[univ_idx]; prev_univ_idx = univ_idx; + + // search for a cell that is filled w/ this universe for (const auto& cell : model::cells) { - // if this is in our current set of visited cells, move on - if (stack.visited(univ_idx, {model::cell_map[cell->id_], C_NONE})) continue; // if this is a material-filled cell, move on if (cell->type_ == Fill::MATERIAL) continue; if (cell->type_ == Fill::UNIVERSE) { + // if this is in the set of cells previously visited for this universe, move on + if (stack.visited(univ_idx, {model::cell_map[cell->id_], C_NONE})) continue; + + // if this cell contains the universe we're searching for, add it to the stack if(cell->fill_ == univ_idx) { stack.push(univ_idx, {model::cell_map[cell->id_], C_NONE}); univ_idx = cell->universe_; } } else if (cell->type_ == Fill::LATTICE) { + // retrieve the lattice and lattice universes const auto& lattice = model::lattices[cell->fill_]; const auto& lattice_univs = lattice->universes_; + + // start search for universe auto lat_it = lattice_univs.begin(); while (true) { // find the next lattice cell with this universe @@ -1252,10 +1259,11 @@ Cell::find_parent_cells(vector& parent_cells, int32_t instance) cons int lattice_idx = lat_it - lattice_univs.begin(); + // move iterator forward one to avoid finding the same entry lat_it++; - if (stack.visited(univ_idx, {model::cell_map[cell->id_], lattice_idx})) continue; + // add this cell and lattice index to the stack and exit loop stack.push(univ_idx, {model::cell_map[cell->id_], lattice_idx}); univ_idx = cell->universe_; break; @@ -1263,12 +1271,12 @@ Cell::find_parent_cells(vector& parent_cells, int32_t instance) cons } // if we've updated the universe, break if (prev_univ_idx != univ_idx) break; - } + } // end cell loop search for universe // if we're at the top of the geometry and the instance matches, we're done if (univ_idx == model::root_universe && stack.compute_instance(this->distribcell_index_) == instance) break; - // if there was no match on the current cell's universe, report an error + // if there is no match on the original cell's universe, report an error if (univ_idx == this->universe_) { fatal_error(fmt::format("Could not find the parent cells for cell {}, instance {}.", this->id_, instance)); } From 5f2961cd55266486f51a604c00372b7810bb8ba0 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Wed, 18 Aug 2021 09:55:54 -0500 Subject: [PATCH 09/16] Moving to unordered set. Applying style formatter. --- include/openmc/cell.h | 15 +++++++-------- src/cell.cpp | 1 + 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/openmc/cell.h b/include/openmc/cell.h index ac0c324300..29d6c51bd5 100644 --- a/include/openmc/cell.h +++ b/include/openmc/cell.h @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include "hdf5.h" #include "pugixml.hpp" @@ -166,12 +166,10 @@ public: //! \param[in] name Cell name void set_name(const std::string& name) { name_ = name; }; - //! Compute the cell's instance given a set of parent cells - int32_t compute_instance(const vector& parent_cells) const; - //! Get all cell instances contained by this cell //! \return Map with cell indexes as keys and instances as values - std::unordered_map> get_contained_cells(int32_t instance=0) const; + std::unordered_map> get_contained_cells( + int32_t instance = 0) const; protected: //! Determine the path to this cell instance in the geometry hierarchy @@ -312,10 +310,10 @@ private: //============================================================================== struct ParentCell { - bool operator ==(const ParentCell& other) const + bool operator==(const ParentCell& other) const { return cell_index == other.cell_index && lattice_index == other.lattice_index; } - bool operator <(const ParentCell& other) const + bool operator<(const ParentCell& other) const { return cell_index < other.cell_index || (cell_index == other.cell_index && lattice_index < other.lattice_index); } gsl::index cell_index; @@ -364,7 +362,8 @@ struct ParentCellStack { // Data Members vector parent_cells_; - std::unordered_map> visited_cells_; + std::unordered_map> + visited_cells_; }; //============================================================================== diff --git a/src/cell.cpp b/src/cell.cpp index 0e7adcdf64..accec7d08a 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include From d8e4535d51cb71661913617bd2ce6353e51fcde6 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Mon, 23 Aug 2021 08:09:04 -0500 Subject: [PATCH 10/16] Apply suggestions from code review Co-authored-by: Paul Romano --- src/cell.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cell.cpp b/src/cell.cpp index accec7d08a..61520709bf 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -1256,7 +1256,7 @@ Cell::find_parent_cells(vector& parent_cells, int32_t instance) cons while (true) { // find the next lattice cell with this universe lat_it = std::find(lat_it, lattice_univs.end(), univ_idx); - if (lat_it >= lattice_univs.end()) break; + if (lat_it == lattice_univs.end()) break; int lattice_idx = lat_it - lattice_univs.begin(); From ccfaca8bdb659ee406d8565d3dce90556a122635 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Mon, 23 Aug 2021 07:55:28 -0500 Subject: [PATCH 11/16] Adding doc strings for PartentCell* and CellInstance* --- include/openmc/cell.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/include/openmc/cell.h b/include/openmc/cell.h index 29d6c51bd5..23340317f1 100644 --- a/include/openmc/cell.h +++ b/include/openmc/cell.h @@ -167,7 +167,9 @@ public: void set_name(const std::string& name) { name_ = name; }; //! Get all cell instances contained by this cell - //! \return Map with cell indexes as keys and instances as values + //! \param[in] instance Instance of the cell for which to get contained cells + //! (default instance is zero) \return Map with cell indexes as keys and + //! instances as values std::unordered_map> get_contained_cells( int32_t instance = 0) const; @@ -196,7 +198,7 @@ public: //! \brief Index corresponding to this cell in distribcell arrays int distribcell_index_ {C_NONE}; - //! \brief Material(s) within this cell. + //! \brief Material(s) within this cel //! //! May be multiple materials for distribcell. vector material_; @@ -309,6 +311,7 @@ private: //! Define a containing (parent) cell //============================================================================== +//! Used to locate a universe fill in the geometry struct ParentCell { bool operator==(const ParentCell& other) const { return cell_index == other.cell_index && lattice_index == other.lattice_index; } @@ -320,6 +323,7 @@ struct ParentCell { gsl::index lattice_index; }; +//! Structure used to insert ParentCell into hashed STL data structures struct ParentCellHash { std::size_t operator()(const ParentCell& p) const { @@ -327,6 +331,8 @@ struct ParentCellHash { } }; +//! Used to manage a traversal stack when locating parent cells of a cell +//! instance in the model struct ParentCellStack { //! push method that adds to the parent_cells visited cells for this search universe @@ -370,6 +376,7 @@ struct ParentCellStack { //! Define an instance of a particular cell //============================================================================== +//! Stores information used to identify a unique cell in the model struct CellInstance { //! Check for equality bool operator==(const CellInstance& other) const @@ -381,6 +388,8 @@ struct CellInstance { gsl::index instance; }; +//! Structure necessary for inserting CellInstance into hashed STL data +//! structures struct CellInstanceHash { std::size_t operator()(const CellInstance& k) const { From 137abfeedc9b2ab20121421b005fa69b87a2a2db Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Mon, 23 Aug 2021 08:02:39 -0500 Subject: [PATCH 12/16] Moving ParentCell* into cell.cpp --- include/openmc/cell.h | 65 ------------------------ src/cell.cpp | 112 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 96 insertions(+), 81 deletions(-) diff --git a/include/openmc/cell.h b/include/openmc/cell.h index 23340317f1..2dfe2d7f34 100644 --- a/include/openmc/cell.h +++ b/include/openmc/cell.h @@ -307,71 +307,6 @@ private: vector> partitions_; }; -//============================================================================== -//! Define a containing (parent) cell -//============================================================================== - -//! Used to locate a universe fill in the geometry -struct ParentCell { - bool operator==(const ParentCell& other) const - { return cell_index == other.cell_index && lattice_index == other.lattice_index; } - - bool operator<(const ParentCell& other) const - { return cell_index < other.cell_index || (cell_index == other.cell_index && lattice_index < other.lattice_index); } - - gsl::index cell_index; - gsl::index lattice_index; -}; - -//! Structure used to insert ParentCell into hashed STL data structures -struct ParentCellHash { - std::size_t operator()(const ParentCell& p) const - { - return 4096*p.cell_index + p.lattice_index; - } -}; - -//! Used to manage a traversal stack when locating parent cells of a cell -//! instance in the model -struct ParentCellStack { - - //! push method that adds to the parent_cells visited cells for this search universe - void push(int32_t search_universe, const ParentCell& pc) { - parent_cells_.push_back(pc); - // add parent cell to the set of cells we've visited for this search universe - visited_cells_[search_universe].insert(pc); - } - - //! removes the last parent_cell and clears the visited cells for the popped cell's universe - void pop() { - visited_cells_[this->current_univ()].clear(); - parent_cells_.pop_back(); - } - - //! checks whether or not the parent cell has been visited already for this search universe - bool visited(int32_t search_universe, const ParentCell& parent_cell) { - return visited_cells_[search_universe].count(parent_cell) != 0; - } - - //! return the next universe to search for a parent cell - int32_t current_univ() const { return model::cells[parent_cells_.back().cell_index]->universe_; } - - //! indicates whether nor not parent cells are present on the stack - bool empty() const { return parent_cells_.empty(); } - - //! compute an instance for the provided distribcell index - int32_t compute_instance(int32_t distribcell_index) const; - - // Accessors - vector& parent_cells() { return parent_cells_; } - const vector& parent_cells() const { return parent_cells_; } - - // Data Members - vector parent_cells_; - std::unordered_map> - visited_cells_; -}; - //============================================================================== //! Define an instance of a particular cell //============================================================================== diff --git a/src/cell.cpp b/src/cell.cpp index 61520709bf..cfcb206994 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -1220,6 +1220,102 @@ extern "C" int openmc_cell_set_name(int32_t index, const char* name) return 0; } +//============================================================================== +//! Define a containing (parent) cell +//============================================================================== + +//! Used to locate a universe fill in the geometry +struct ParentCell { + bool operator==(const ParentCell& other) const + { + return cell_index == other.cell_index && + lattice_index == other.lattice_index; + } + + bool operator<(const ParentCell& other) const + { + return cell_index < other.cell_index || + (cell_index == other.cell_index && + lattice_index < other.lattice_index); + } + + gsl::index cell_index; + gsl::index lattice_index; +}; + +//! Structure used to insert ParentCell into hashed STL data structures +struct ParentCellHash { + std::size_t operator()(const ParentCell& p) const + { + return 4096 * p.cell_index + p.lattice_index; + } +}; + +//! Used to manage a traversal stack when locating parent cells of a cell +//! instance in the model +struct ParentCellStack { + + //! push method that adds to the parent_cells visited cells for this search + //! universe + void push(int32_t search_universe, const ParentCell& pc) + { + parent_cells_.push_back(pc); + // add parent cell to the set of cells we've visited for this search + // universe + visited_cells_[search_universe].insert(pc); + } + + //! removes the last parent_cell and clears the visited cells for the popped + //! cell's universe + void pop() + { + visited_cells_[this->current_univ()].clear(); + parent_cells_.pop_back(); + } + + //! checks whether or not the parent cell has been visited already for this + //! search universe + bool visited(int32_t search_universe, const ParentCell& parent_cell) + { + return visited_cells_[search_universe].count(parent_cell) != 0; + } + + //! return the next universe to search for a parent cell + int32_t current_univ() const + { + return model::cells[parent_cells_.back().cell_index]->universe_; + } + + //! indicates whether nor not parent cells are present on the stack + bool empty() const { return parent_cells_.empty(); } + + //! compute an instance for the provided distribcell index + int32_t compute_instance(int32_t distribcell_index) const + { + int32_t instance = 0; + for (const auto& parent_cell : this->parent_cells_) { + auto& cell = model::cells[parent_cell.cell_index]; + if (cell->type_ == Fill::UNIVERSE) { + instance += cell->offset_[distribcell_index]; + } else if (cell->type_ == Fill::LATTICE) { + auto& lattice = model::lattices[cell->fill_]; + instance += + lattice->offset(distribcell_index, parent_cell.lattice_index); + } + } + return instance; + } + + // Accessors + vector& parent_cells() { return parent_cells_; } + const vector& parent_cells() const { return parent_cells_; } + + // Data Members + vector parent_cells_; + std::unordered_map> + visited_cells_; +}; + vector Cell::find_parent_cells(vector& parent_cells, int32_t instance) const { @@ -1295,22 +1391,6 @@ Cell::find_parent_cells(vector& parent_cells, int32_t instance) cons return stack.parent_cells(); } -int32_t -ParentCellStack::compute_instance(int32_t distribcell_index) const -{ - int32_t instance = 0; - for (const auto& parent_cell : this->parent_cells_) { - auto& cell = model::cells[parent_cell.cell_index]; - if (cell->type_ == Fill::UNIVERSE) { - instance += cell->offset_[distribcell_index]; - } else if (cell->type_ == Fill::LATTICE) { - auto& lattice = model::lattices[cell->fill_]; - instance += lattice->offset(distribcell_index, parent_cell.lattice_index); - } - } - return instance; -} - std::unordered_map> Cell::get_contained_cells(int32_t instance) const { std::unordered_map> contained_cells; From ed54e4df190a25fc851632e150376b971262586f Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Mon, 23 Aug 2021 08:08:33 -0500 Subject: [PATCH 13/16] Removing unused parameter in Cell::find_parent_cells --- include/openmc/cell.h | 3 +-- src/cell.cpp | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/include/openmc/cell.h b/include/openmc/cell.h index 2dfe2d7f34..876ee9e50d 100644 --- a/include/openmc/cell.h +++ b/include/openmc/cell.h @@ -175,8 +175,7 @@ public: protected: //! Determine the path to this cell instance in the geometry hierarchy - vector - find_parent_cells(vector& parent_cells, int32_t instance) const; + vector find_parent_cells(int32_t instance) const; //! Inner function for retrieving contained cells void get_contained_cells_inner( diff --git a/src/cell.cpp b/src/cell.cpp index cfcb206994..6cea7fbdf1 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -1316,8 +1316,7 @@ struct ParentCellStack { visited_cells_; }; -vector -Cell::find_parent_cells(vector& parent_cells, int32_t instance) const +vector Cell::find_parent_cells(int32_t instance) const { ParentCellStack stack; // start with this cell's universe @@ -1399,7 +1398,7 @@ std::unordered_map> Cell::get_contained_cells(int32_t i if (this->type_ == Fill::MATERIAL) return contained_cells; // find the pathway through the geometry to this cell - vector parent_cells = this->find_parent_cells(parent_cells, instance); + vector parent_cells = this->find_parent_cells(instance); // if this cell is filled w/ a material, it contains no other cells if (type_ != Fill::MATERIAL) { From 80dc5af4db8326a9079675221d17fdad8330a038 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Mon, 23 Aug 2021 14:45:08 -0500 Subject: [PATCH 14/16] Update include/openmc/cell.h Co-authored-by: Paul Romano --- include/openmc/cell.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/openmc/cell.h b/include/openmc/cell.h index 876ee9e50d..7e652d680c 100644 --- a/include/openmc/cell.h +++ b/include/openmc/cell.h @@ -197,7 +197,7 @@ public: //! \brief Index corresponding to this cell in distribcell arrays int distribcell_index_ {C_NONE}; - //! \brief Material(s) within this cel + //! \brief Material(s) within this cell. //! //! May be multiple materials for distribcell. vector material_; From 1c848b3b4041ece90950384dd0bc0bd315d240f3 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Mon, 23 Aug 2021 14:47:42 -0500 Subject: [PATCH 15/16] Applying clang-format. --- src/cell.cpp | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/cell.cpp b/src/cell.cpp index 6cea7fbdf1..109b66dde8 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -1330,14 +1330,18 @@ vector Cell::find_parent_cells(int32_t instance) const // search for a cell that is filled w/ this universe for (const auto& cell : model::cells) { // if this is a material-filled cell, move on - if (cell->type_ == Fill::MATERIAL) continue; + if (cell->type_ == Fill::MATERIAL) + continue; if (cell->type_ == Fill::UNIVERSE) { - // if this is in the set of cells previously visited for this universe, move on - if (stack.visited(univ_idx, {model::cell_map[cell->id_], C_NONE})) continue; + // if this is in the set of cells previously visited for this universe, + // move on + if (stack.visited(univ_idx, {model::cell_map[cell->id_], C_NONE})) + continue; - // if this cell contains the universe we're searching for, add it to the stack - if(cell->fill_ == univ_idx) { + // if this cell contains the universe we're searching for, add it to the + // stack + if (cell->fill_ == univ_idx) { stack.push(univ_idx, {model::cell_map[cell->id_], C_NONE}); univ_idx = cell->universe_; } @@ -1351,13 +1355,16 @@ vector Cell::find_parent_cells(int32_t instance) const while (true) { // find the next lattice cell with this universe lat_it = std::find(lat_it, lattice_univs.end(), univ_idx); - if (lat_it == lattice_univs.end()) break; + if (lat_it == lattice_univs.end()) + break; int lattice_idx = lat_it - lattice_univs.begin(); // move iterator forward one to avoid finding the same entry lat_it++; - if (stack.visited(univ_idx, {model::cell_map[cell->id_], lattice_idx})) continue; + if (stack.visited( + univ_idx, {model::cell_map[cell->id_], lattice_idx})) + continue; // add this cell and lattice index to the stack and exit loop stack.push(univ_idx, {model::cell_map[cell->id_], lattice_idx}); @@ -1366,15 +1373,20 @@ vector Cell::find_parent_cells(int32_t instance) const } } // if we've updated the universe, break - if (prev_univ_idx != univ_idx) break; + if (prev_univ_idx != univ_idx) + break; } // end cell loop search for universe // if we're at the top of the geometry and the instance matches, we're done - if (univ_idx == model::root_universe && stack.compute_instance(this->distribcell_index_) == instance) break; + if (univ_idx == model::root_universe && + stack.compute_instance(this->distribcell_index_) == instance) + break; // if there is no match on the original cell's universe, report an error if (univ_idx == this->universe_) { - fatal_error(fmt::format("Could not find the parent cells for cell {}, instance {}.", this->id_, instance)); + fatal_error( + fmt::format("Could not find the parent cells for cell {}, instance {}.", + this->id_, instance)); } // if we don't find a suitable update, adjust the stack and continue @@ -1390,12 +1402,14 @@ vector Cell::find_parent_cells(int32_t instance) const return stack.parent_cells(); } -std::unordered_map> Cell::get_contained_cells(int32_t instance) const +std::unordered_map> Cell::get_contained_cells( + int32_t instance) const { std::unordered_map> contained_cells; // if this is a material-filled cell it has no contained cells - if (this->type_ == Fill::MATERIAL) return contained_cells; + if (this->type_ == Fill::MATERIAL) + return contained_cells; // find the pathway through the geometry to this cell vector parent_cells = this->find_parent_cells(instance); From f769afed933b5bb243f4e13fc6c29c5931358a0a Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Wed, 25 Aug 2021 07:32:12 -0500 Subject: [PATCH 16/16] Correction to docstring. --- include/openmc/cell.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/openmc/cell.h b/include/openmc/cell.h index 7e652d680c..5f6d33c974 100644 --- a/include/openmc/cell.h +++ b/include/openmc/cell.h @@ -168,7 +168,8 @@ public: //! Get all cell instances contained by this cell //! \param[in] instance Instance of the cell for which to get contained cells - //! (default instance is zero) \return Map with cell indexes as keys and + //! (default instance is zero) + //! \return Map with cell indexes as keys and //! instances as values std::unordered_map> get_contained_cells( int32_t instance = 0) const;