From cc6822f171e9963f91a6adeb7d3fabcbbe363f46 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Mon, 7 Oct 2019 00:11:51 -0500 Subject: [PATCH] Pulling in C++ side changes for counter caching. --- include/openmc/geometry_aux.h | 70 +++++++++++++++++++ src/finalize.cpp | 4 ++ src/geometry_aux.cpp | 126 +++++++++++++++++++++++++++++++--- 3 files changed, 189 insertions(+), 11 deletions(-) diff --git a/include/openmc/geometry_aux.h b/include/openmc/geometry_aux.h index ffcdcf885f..557d82193f 100644 --- a/include/openmc/geometry_aux.h +++ b/include/openmc/geometry_aux.h @@ -7,8 +7,78 @@ #include #include #include +#include namespace openmc { + struct CellCountStorage { + private: + CellCountStorage() {} + CellCountStorage(CellCountStorage& c) {} + CellCountStorage(const CellCountStorage& c) {} + + static CellCountStorage* instance_; + + std::map> counts; + + public: + + static CellCountStorage* instance() { + if (instance_ == nullptr) + instance_ = new CellCountStorage; + + return instance_; + } + + + + void clear(); + + void set_cell_count_for_univ(int32_t univ, int32_t cell, int count); + + void increment_count_for_univ(int32_t univ, int32_t cell); + + bool has_count(int32_t univ, int32_t cell); + + bool has_count(int32_t univ); + + void absorb_b_into_a(int32_t a, int32_t b); + + auto get_count(int32_t univ); + }; + + struct LevelCountStorage { + private: + LevelCountStorage() {} + LevelCountStorage(LevelCountStorage& c) {} + LevelCountStorage(const LevelCountStorage& c) {} + + static LevelCountStorage* instance_; + + std::map counts; + + public: + + static LevelCountStorage* instance() { + if (instance_ == nullptr) + instance_ = new LevelCountStorage; + + return instance_; + } + + void clear(); + + void set_cell_count_for_univ(int32_t univ, int count); + + void increment_count_for_univ(int32_t univ); + + bool has_count(int32_t univ); + + void absorb_b_into_a(int32_t a, int32_t b); + + void set_count(int32_t univ, int count); + + int get_count(int32_t univ); + }; void read_geometry_xml(); diff --git a/src/finalize.cpp b/src/finalize.cpp index 3de20d6d09..f2cbc973c2 100644 --- a/src/finalize.cpp +++ b/src/finalize.cpp @@ -135,6 +135,10 @@ int openmc_finalize() int openmc_reset() { + + CellCountStorage::instance()->clear(); + LevelCountStorage::instance()->clear(); + for (auto& t : model::tallies) { t->reset(); } diff --git a/src/geometry_aux.cpp b/src/geometry_aux.cpp index d195a9de39..662b6790d5 100644 --- a/src/geometry_aux.cpp +++ b/src/geometry_aux.cpp @@ -60,6 +60,91 @@ void read_geometry_xml() model::root_universe = find_root_universe(); } +void CellCountStorage::clear() { + if (instance_ != nullptr) { + delete instance_; + instance_ = nullptr; + } +} + +void CellCountStorage::set_cell_count_for_univ(int32_t univ, int32_t cell, int count) { + counts[univ][cell] = count; +} + + void CellCountStorage::increment_count_for_univ(int32_t univ, int32_t cell) { + if (has_count(univ,cell)) { + counts[univ][cell] += 1; + } else { + counts[univ][cell] = 1; + } + } + +bool CellCountStorage::has_count(int32_t univ, int32_t cell) { + return counts.count(univ) && counts[univ].count(cell); +} + +bool CellCountStorage::has_count(int32_t univ) { + return counts.count(univ); +} + +void CellCountStorage::absorb_b_into_a(int32_t a, int32_t b) { + std::map b_map = counts[b]; + + for (auto it : b_map) { + if (has_count(a, it.first)) { + counts[a][it.first] += it.second; + } else { + counts[a][it.first] = it.second; + } + } +} + +auto CellCountStorage::get_count(int32_t univ) { + return counts[univ]; +} + +void LevelCountStorage::clear() { + if (instance_ != nullptr) { + delete instance_; + instance_ = nullptr; + } +} + +void LevelCountStorage::set_cell_count_for_univ(int32_t univ, int count) { + counts[univ] = count; +} + +void LevelCountStorage::increment_count_for_univ(int32_t univ) { + if (has_count(univ)) { + counts[univ] += 1; + } else { + counts[univ] = 1; + } +} + +bool LevelCountStorage::has_count(int32_t univ) { + return counts.count(univ); +} + +void LevelCountStorage::absorb_b_into_a(int32_t a, int32_t b) { + if (has_count(a)) { + counts[a] += counts[b]; + } else { + counts[a] = counts[b]; + } +} + +void LevelCountStorage::set_count(int32_t univ, int count) { + counts[univ] = count; +} + +int LevelCountStorage::get_count(int32_t univ) { + return counts[univ]; +} + +CellCountStorage* CellCountStorage::instance_ = nullptr; +LevelCountStorage* LevelCountStorage::instance_ = nullptr; + //============================================================================== void @@ -395,19 +480,31 @@ prepare_distribcell() void count_cell_instances(int32_t univ_indx) { - for (int32_t cell_indx : model::universes[univ_indx]->cells_) { - Cell& c = *model::cells[cell_indx]; - ++c.n_instances_; + CellCountStorage* counter = CellCountStorage::instance(); - if (c.type_ == FILL_UNIVERSE) { - // This cell contains another universe. Recurse into that universe. - count_cell_instances(c.fill_); + if (counter->has_count(univ_indx)) { + std::map univ_counts = counter->get_count(univ_indx); + for(auto it : univ_counts) { + Cell& c = *model::cells[it.first]; + c.n_instances_ += it.second; + } + } else { + for (int32_t cell_indx : model::universes[univ_indx]->cells_) { + Cell& c = *model::cells[cell_indx]; + ++c.n_instances_; + counter->increment_count_for_univ(univ_indx, cell_indx); - } else if (c.type_ == FILL_LATTICE) { - // This cell contains a lattice. Recurse into the lattice universes. - Lattice& lat = *model::lattices[c.fill_]; - for (auto it = lat.begin(); it != lat.end(); ++it) { - count_cell_instances(*it); + if (c.type_ == FILL_UNIVERSE) { + // This cell contains another universe. Recurse into that universe. + count_cell_instances(c.fill_); + counter->absorb_b_into_a(univ_indx, c.fill_); + } else if (c.type_ == FILL_LATTICE) { + // This cell contains a lattice. Recurse into the lattice universes. + Lattice& lat = *model::lattices[c.fill_]; + for (auto it = lat.begin(); it != lat.end(); ++it) { + count_cell_instances(*it); + counter->absorb_b_into_a(univ_indx, *it); + } } } } @@ -529,6 +626,12 @@ distribcell_path(int32_t target_cell, int32_t map, int32_t target_offset) int maximum_levels(int32_t univ) { + LevelCountStorage* counter = LevelCountStorage::instance(); + + if (counter->has_count(univ)) { + return counter->get_count(univ); + } + int levels_below {0}; for (int32_t cell_indx : model::universes[univ]->cells_) { @@ -546,6 +649,7 @@ maximum_levels(int32_t univ) } ++levels_below; + counter->set_count(univ, levels_below); return levels_below; }