Pulling in C++ side changes for counter caching.

This commit is contained in:
Patrick Shriwise 2019-10-07 00:11:51 -05:00
parent a6e6f1d2b1
commit cc6822f171
3 changed files with 189 additions and 11 deletions

View file

@ -7,8 +7,78 @@
#include <cstdint>
#include <string>
#include <vector>
#include <map>
namespace openmc {
struct CellCountStorage {
private:
CellCountStorage() {}
CellCountStorage(CellCountStorage& c) {}
CellCountStorage(const CellCountStorage& c) {}
static CellCountStorage* instance_;
std::map<int32_t, std::map<int32_t, int>> 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<int32_t, int> 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();

View file

@ -135,6 +135,10 @@ int openmc_finalize()
int openmc_reset()
{
CellCountStorage::instance()->clear();
LevelCountStorage::instance()->clear();
for (auto& t : model::tallies) {
t->reset();
}

View file

@ -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<int32_t, int> 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<int32_t, int> 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;
}