Skip to content

Commit c8639e1

Browse files
authored
Merge pull request #1966 from pshriwise/contained_cells_hint
Acceleration for Cell::find_parent_cells.
2 parents 10f103c + 1f2f859 commit c8639e1

File tree

5 files changed

+105
-11
lines changed

5 files changed

+105
-11
lines changed

include/openmc/cell.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,14 +169,32 @@ class Cell {
169169
//! Get all cell instances contained by this cell
170170
//! \param[in] instance Instance of the cell for which to get contained cells
171171
//! (default instance is zero)
172+
//! \param[in] hint positional hint for determining the parent cells
172173
//! \return Map with cell indexes as keys and
173174
//! instances as values
174175
std::unordered_map<int32_t, vector<int32_t>> get_contained_cells(
175-
int32_t instance = 0) const;
176+
int32_t instance = 0, Position* hint = nullptr) const;
176177

177178
protected:
178179
//! Determine the path to this cell instance in the geometry hierarchy
179-
vector<ParentCell> find_parent_cells(int32_t instance) const;
180+
//! \param[in] instance of the cell to find parent cells for
181+
//! \param[in] r position used to do a fast search for parent cells
182+
//! \return parent cells
183+
vector<ParentCell> find_parent_cells(
184+
int32_t instance, const Position& r) const;
185+
186+
//! Determine the path to this cell instance in the geometry hierarchy
187+
//! \param[in] instance of the cell to find parent cells for
188+
//! \param[in] p particle used to do a fast search for parent cells
189+
//! \return parent cells
190+
vector<ParentCell> find_parent_cells(
191+
int32_t instance, Particle& p) const;
192+
193+
//! Determine the path to this cell instance in the geometry hierarchy
194+
//! \param[in] instance of the cell to find parent cells for
195+
//! \return parent cells
196+
vector<ParentCell> exhaustive_find_parent_cells(
197+
int32_t instance) const;
180198

181199
//! Inner function for retrieving contained cells
182200
void get_contained_cells_inner(

include/openmc/lattice.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ class Lattice {
9999
virtual void get_indices(
100100
Position r, Direction u, array<int, 3>& result) const = 0;
101101

102+
//! \brief Compute the the flat index for a set of lattice cell indices
103+
//! \param i_xyz The indices for a lattice cell.
104+
//! \return Flat index into the universes vector.
105+
virtual int get_flat_index(const array<int, 3>& i_xyz) const = 0;
106+
102107
//! \brief Get coordinates local to a lattice tile.
103108
//! \param r A 3D Cartesian coordinate.
104109
//! \param i_xyz The indices for a lattice tile.
@@ -210,6 +215,8 @@ class RectLattice : public Lattice {
210215

211216
void get_indices(Position r, Direction u, array<int, 3>& result) const;
212217

218+
int get_flat_index(const array<int, 3>& i_xyz) const;
219+
213220
Position get_local_position(Position r, const array<int, 3>& i_xyz) const;
214221

215222
int32_t& offset(int map, array<int, 3> const& i_xyz);
@@ -245,6 +252,8 @@ class HexLattice : public Lattice {
245252

246253
void get_indices(Position r, Direction u, array<int, 3>& result) const;
247254

255+
int get_flat_index(const array<int, 3>& i_xyz) const;
256+
248257
Position get_local_position(Position r, const array<int, 3>& i_xyz) const;
249258

250259
bool is_valid_index(int indx) const;

include/openmc/particle_data.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,8 @@ class ParticleData {
341341
const int& cell_instance() const { return cell_instance_; }
342342
LocalCoord& coord(int i) { return coord_[i]; }
343343
const LocalCoord& coord(int i) const { return coord_[i]; }
344+
const vector<LocalCoord>& coord() const { return coord_; }
345+
344346

345347
int& n_coord_last() { return n_coord_last_; }
346348
const int& n_coord_last() const { return n_coord_last_; }

src/cell.cpp

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,7 +1316,59 @@ struct ParentCellStack {
13161316
visited_cells_;
13171317
};
13181318

1319-
vector<ParentCell> Cell::find_parent_cells(int32_t instance) const
1319+
vector<ParentCell> Cell::find_parent_cells(
1320+
int32_t instance, const Position& r) const {
1321+
1322+
// create a temporary particle
1323+
Particle dummy_particle {};
1324+
dummy_particle.r() = r;
1325+
dummy_particle.u() = {0., 0., 1.};
1326+
1327+
return find_parent_cells(instance, dummy_particle);
1328+
}
1329+
1330+
vector<ParentCell> Cell::find_parent_cells(
1331+
int32_t instance, Particle& p) const {
1332+
// look up the particle's location
1333+
exhaustive_find_cell(p);
1334+
const auto& coords = p.coord();
1335+
1336+
// build a parent cell stack from the particle coordinates
1337+
ParentCellStack stack;
1338+
bool cell_found = false;
1339+
for (auto it = coords.begin(); it != coords.end(); it++) {
1340+
const auto& coord = *it;
1341+
const auto& cell = model::cells[coord.cell];
1342+
// if the cell at this level matches the current cell, stop adding to the stack
1343+
if (coord.cell == model::cell_map[this->id_]) {
1344+
cell_found = true;
1345+
break;
1346+
}
1347+
1348+
// if filled with a lattice, get the lattice index from the next
1349+
// level in the coordinates to push to the stack
1350+
int lattice_idx = C_NONE;
1351+
if (cell->type_ == Fill::LATTICE) {
1352+
const auto& next_coord = *(it + 1);
1353+
lattice_idx = model::lattices[next_coord.lattice]->get_flat_index(next_coord.lattice_i);
1354+
}
1355+
stack.push(coord.universe, {coord.cell, lattice_idx});
1356+
}
1357+
1358+
// if this loop finished because the cell was found and
1359+
// the instance matches the one requested in the call
1360+
// we have the correct path and can return the stack
1361+
if (cell_found && stack.compute_instance(this->distribcell_index_) == instance) {
1362+
return stack.parent_cells();
1363+
}
1364+
1365+
// fall back on an exhaustive search for the cell's parents
1366+
return exhaustive_find_parent_cells(instance);
1367+
}
1368+
1369+
1370+
vector<ParentCell> Cell::exhaustive_find_parent_cells(
1371+
int32_t instance) const
13201372
{
13211373
ParentCellStack stack;
13221374
// start with this cell's universe
@@ -1403,7 +1455,7 @@ vector<ParentCell> Cell::find_parent_cells(int32_t instance) const
14031455
}
14041456

14051457
std::unordered_map<int32_t, vector<int32_t>> Cell::get_contained_cells(
1406-
int32_t instance) const
1458+
int32_t instance, Position* hint) const
14071459
{
14081460
std::unordered_map<int32_t, vector<int32_t>> contained_cells;
14091461

@@ -1412,7 +1464,12 @@ std::unordered_map<int32_t, vector<int32_t>> Cell::get_contained_cells(
14121464
return contained_cells;
14131465

14141466
// find the pathway through the geometry to this cell
1415-
vector<ParentCell> parent_cells = this->find_parent_cells(instance);
1467+
vector<ParentCell> parent_cells;
1468+
1469+
// if a positional hint is provided, attempt to do a fast lookup
1470+
// of the parent cells
1471+
parent_cells = hint ? find_parent_cells(instance, *hint)
1472+
: exhaustive_find_parent_cells(instance);
14161473

14171474
// if this cell is filled w/ a material, it contains no other cells
14181475
if (type_ != Fill::MATERIAL) {

src/lattice.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -215,9 +215,7 @@ RectLattice::RectLattice(pugi::xml_node lat_node) : Lattice {lat_node}
215215

216216
int32_t const& RectLattice::operator[](array<int, 3> const& i_xyz)
217217
{
218-
int indx =
219-
n_cells_[0] * n_cells_[1] * i_xyz[2] + n_cells_[0] * i_xyz[1] + i_xyz[0];
220-
return universes_[indx];
218+
return universes_[get_flat_index(i_xyz)];
221219
}
222220

223221
//==============================================================================
@@ -323,6 +321,12 @@ void RectLattice::get_indices(
323321
}
324322
}
325323

324+
int RectLattice::get_flat_index(const array<int, 3>& i_xyz) const
325+
{
326+
return n_cells_[0] * n_cells_[1] * i_xyz[2] + n_cells_[0] * i_xyz[1] +
327+
i_xyz[0];
328+
}
329+
326330
//==============================================================================
327331

328332
Position RectLattice::get_local_position(
@@ -662,9 +666,7 @@ void HexLattice::fill_lattice_y(const vector<std::string>& univ_words)
662666

663667
int32_t const& HexLattice::operator[](array<int, 3> const& i_xyz)
664668
{
665-
int indx = (2 * n_rings_ - 1) * (2 * n_rings_ - 1) * i_xyz[2] +
666-
(2 * n_rings_ - 1) * i_xyz[1] + i_xyz[0];
667-
return universes_[indx];
669+
return universes_[get_flat_index(i_xyz)];
668670
}
669671

670672
//==============================================================================
@@ -929,6 +931,12 @@ void HexLattice::get_indices(
929931
result[1] += i2_chg;
930932
}
931933

934+
int HexLattice::get_flat_index(const array<int, 3>& i_xyz) const
935+
{
936+
return (2 * n_rings_ - 1) * (2 * n_rings_ - 1) * i_xyz[2] +
937+
(2 * n_rings_ - 1) * i_xyz[1] + i_xyz[0];
938+
}
939+
932940
//==============================================================================
933941

934942
Position HexLattice::get_local_position(

0 commit comments

Comments
 (0)