Cell search via a tree

(note I am new to OpenMC, so sorry in advance if this idea is non-sense; I also did not make much research about this yet)

Hi,

the cell search algorithm is described such that when the universe is known

loop over each cell within that universe. For each cell, we check whether the specified point is inside the cell using the algorithm described in Finding a Lattice Tile.

This is intuitive. However, it’s possible that some cells are checked multiple times.

I’ll use the BWR example’s, universe for fuel pin

# Geometry definitions for the fuel rod

fuel_or  = openmc.ZCylinder(r=1.0414/2, name='Fuel OR')
fclad_ir = openmc.ZCylinder(r=1.06426/2, name='Clad IR')
fclad_or = openmc.ZCylinder(r=1.22682/2, name='Clad OR')

fuel_region = -fuel_or 
gap_region  = +fuel_or & -fclad_ir
fclad_region  = +fclad_ir & -fclad_or
fwater_region = pin_cell_box & +fclad_or

fuel_cell = openmc.Cell(name='fuel')
fuel_cell.fill = uo2
fuel_cell.region = fuel_region 

gap_cell = openmc.Cell(name='air gap')
gap_cell.region = gap_region

clad_cell = openmc.Cell(name='clad')
clad_cell.fill = zircaloy
clad_cell.region = fclad_region

fwater_cell = openmc.Cell(name='fwater')
fwater_cell.fill = water
fwater_cell.region = fwater_region

fuel_pin_universe = openmc.Universe(cells=[fuel_cell, gap_cell, clad_cell, fwater_cell])

Not sure how are the cells and surfaces arranged, but if the order was [fuel_cell, gap_cell, clad_cell, fwater_cell], the possible scenarios in the cell search routine would be (each bullet point corresponds to possible scenario depending on where the particle is)

  • test_fuel_cell(-fuel_or)return fuel_cell
  • test_fuel_cell(+fuel_or), test_gap_cell(+fuel_or, -fclad_ir)return gap_cell
  • test_fuel_cell(+fuel_or), test_gap_cell(+fuel_or, +fclad_ir), test_clad_cell(+fclad_ir -fclad_or)return clad_cell
  • test_fuel_cell(+fuel_or), test_gap_cell(+fuel_or), +fclad_ir), test_clad_cell(+fclad_ir +fclad_or), test_fwater_cell(pin_cell_box, +fclad_or)return fwater_cell

The scenario above is rather pessimistic – thanks to the short-circuiting (PR 2178), it could be simpler:

  • test_fuel_cell(-fuel_or)return fuel_cell
  • test_fuel_cell(+fuel_or), test_gap_cell(+fuel_or, -fclad_ir)return gap_cell
  • test_fuel_cell(+fuel_or), test_gap_cell(+fclad_ir), test_clad_cell(+fclad_ir, -fclad_or)return clad_cell
  • test_fuel_cell(+fuel_or), test_gap_cell(+fclad_ir), test_clad_cell(+fclad_or), test_fwater_cell(pin_cell_box, +fclad_or)return fwater_cell

Still, especially in cases when the particle is in cladding or water, some surface tests are repetitive

  • fuel_or is tested 2 times if particle is in gap_cell,
  • fclad_ir is tested 2 times if particle is in clad_cell,
  • fclad_or is tested 2 times if particle is in fwater_cell.

I was wondering if cell search could be done via binary tree of surfaces, as illuestrated in figure below, where branch up is + and down is -. In such case, the scenarios would look like

  • -fclad_ir, -fuel_orreturn fuel_cell
  • -fclad_ir, +fuel_orreturn gap_cell
  • +fclad_ir, -fclad_orreturn clad_cell
  • +fclad_ir, +fclad_orreturn fwater_cell

The advantage of such approach would be

  • theoretically faster cell search – best scenario would be O(log_2(N_surfaces)) surface tests, while the current would be O(N_cells*N_surfaces_per_cell) or something like that

The disadvantages would be

  • likely more compicated data structure to store surfaces and cells,
  • information about arrangement of surfaces – e.g. tree above was done with knowledge that fclad_ir is inside fclad_or and fuel_or is inside fclad_ir, so that they don’t need to be tested if the particle is outside of the outer surface,
  • the balanced tree above is best case scenario when surfaces are inside each other – but it might detoriate from tree to line and ending de facto with the same algorithm as now,
  • it does not check for potentially undefined regions,
  • in some cases, there are more surface checks – in the BWR example, this is true for fuel_cell, which would have just 1 surface check, but now has 2… Technically, the tree could be manually biased to check some surfaces sooner,
  • it would be useful only in cases where cell search occupies most

Let me know if such idea is worth further investigation or not – or if someone has already investigated this (which I guess someone has done already). If it would be worth trying, I’ll try implementing that – but I did not want to do unless I have some confidence it’s worth it.

Thanks for any thoughts on that.