Skip to content

Commit c148683

Browse files
committed
Using find_cell to determine upward path through geometry
1 parent 2332dd2 commit c148683

File tree

3 files changed

+100
-35
lines changed

3 files changed

+100
-35
lines changed

include/openmc/cell.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,15 +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(
175176
int32_t instance = 0, Position* hint = nullptr) const;
176177

177178
protected:
178179
//! Determine the path to this cell instance in the geometry hierarchy
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
179183
vector<ParentCell> find_parent_cells(
180-
int32_t instance, Position* hint = nullptr) const;
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> find_parent_cells_exhaustive(
197+
int32_t instance) const;
181198

182199
//! Inner function for retrieving contained cells
183200
void get_contained_cells_inner(

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: 80 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,13 +1317,64 @@ struct ParentCellStack {
13171317
};
13181318

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

13281379
while (true) {
13291380
const auto& univ = model::universes[univ_idx];
@@ -1352,38 +1403,26 @@ vector<ParentCell> Cell::find_parent_cells(
13521403
const auto& lattice = model::lattices[cell->fill_];
13531404
const auto& lattice_univs = lattice->universes_;
13541405

1355-
// if a hint position is provided, look up the lattice cell
1356-
// for that position
1357-
if (hint && !hint_used) {
1358-
std::array<int, 3> hint_idx;
1359-
lattice->get_indices(*hint, Direction(0.0, 0.0, 0.0), hint_idx);
1360-
int hint_offset = lattice->get_flat_index(hint_idx);
1361-
if (univ_idx == lattice_univs[hint_offset]) {
1362-
hint_used = true;
1363-
stack.push(univ_idx, {model::cell_map[cell->id_], hint_offset});
1364-
}
1365-
} else {
1366-
// start search for universe
1367-
auto lat_it = lattice_univs.begin();
1368-
while (true) {
1369-
// find the next lattice cell with this universe
1370-
lat_it = std::find(lat_it, lattice_univs.end(), univ_idx);
1371-
if (lat_it == lattice_univs.end())
1372-
break;
1373-
1374-
int lattice_idx = lat_it - lattice_univs.begin();
1375-
1376-
// move iterator forward one to avoid finding the same entry
1377-
lat_it++;
1378-
if (stack.visited(
1379-
univ_idx, {model::cell_map[cell->id_], lattice_idx}))
1380-
continue;
1381-
1382-
// add this cell and lattice index to the stack and exit loop
1383-
stack.push(univ_idx, {model::cell_map[cell->id_], lattice_idx});
1384-
univ_idx = cell->universe_;
1406+
// start search for universe
1407+
auto lat_it = lattice_univs.begin();
1408+
while (true) {
1409+
// find the next lattice cell with this universe
1410+
lat_it = std::find(lat_it, lattice_univs.end(), univ_idx);
1411+
if (lat_it == lattice_univs.end())
13851412
break;
1386-
}
1413+
1414+
int lattice_idx = lat_it - lattice_univs.begin();
1415+
1416+
// move iterator forward one to avoid finding the same entry
1417+
lat_it++;
1418+
if (stack.visited(
1419+
univ_idx, {model::cell_map[cell->id_], lattice_idx}))
1420+
continue;
1421+
1422+
// add this cell and lattice index to the stack and exit loop
1423+
stack.push(univ_idx, {model::cell_map[cell->id_], lattice_idx});
1424+
univ_idx = cell->universe_;
1425+
break;
13871426
}
13881427
}
13891428
// if we've updated the universe, break
@@ -1426,7 +1465,14 @@ std::unordered_map<int32_t, vector<int32_t>> Cell::get_contained_cells(
14261465
return contained_cells;
14271466

14281467
// find the pathway through the geometry to this cell
1429-
vector<ParentCell> parent_cells = this->find_parent_cells(instance, hint);
1468+
vector<ParentCell> parent_cells;
1469+
1470+
// if a positional hint is provided, attempt to do a fast lookup
1471+
// of the parent cells
1472+
if (hint)
1473+
parent_cells = find_parent_cells(instance, *hint);
1474+
else
1475+
parent_cells = find_parent_cells_exhaustive(instance);
14301476

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

0 commit comments

Comments
 (0)