Particle # could not be located after crossing a boundary of lattice #

The error “Particle # could not be located after crossing a boundary of lattice #” kept appearing when I try to run a basic simulation, I am guessing it has something to do with the lattice definition as the error indicates, I will include my full code as plain text and as a .py file.

import os

os.environ[‘OPENMC_CROSS_SECTIONS’] = ‘/home/eastdusty/openmc_env/share/data/endfb80/endfb-viii.0-hdf5/cross_sections.xml’

import openmc as openmc

U3Si2Al = openmc.Material(name=‘U3Si2Al’)
U3Si2Al.add_nuclide(‘U238’, 3 * 0.8025)
U3Si2Al.add_nuclide(‘U235’, 3 * 0.1975)
U3Si2Al.add_nuclide(‘Si28’, 2 * 0.922545)
U3Si2Al.add_nuclide(‘Si29’, 2 * 0.04672)
U3Si2Al.add_nuclide(‘Si30’, 2 * 0.030735)
U3Si2Al.add_nuclide(‘Al27’, 1)
U3Si2Al.set_density(‘g/cm3’, 5.55)

Al6061 = openmc.Material(name=‘Al6061’)
Al6061.add_nuclide(‘Al27’, 1)
Al6061.set_density(‘g/cm3’, 2.7)

water = openmc.Material(name=‘Water’)
water.add_nuclide(‘H1’, 0.111877)
water.add_nuclide(‘H2’, 0.000013)
water.add_nuclide(‘O16’, 0.88811)
water.set_density(‘g/cm3’, 1.0)

vacuum = openmc.Material(name=‘Vacuum’)
vacuum.add_nuclide(‘H1’, 1.0e-100) # Practically zero density
vacuum.set_density(‘g/cm3’, 1.0e-100)

materials = openmc.Materials([U3Si2Al, Al6061, water, vacuum])
materials.export_to_xml()

fuel_top = openmc.ZPlane(z0=30)
fuel_bottom = openmc.ZPlane(z0=-30)
fuel_right = openmc.XPlane(x0=2.98)
fuel_left = openmc.XPlane(x0=-2.98)
fuel_front = openmc.YPlane(y0=0.0255)
fuel_back = openmc.YPlane(y0=-0.0255)

fuel_region = +fuel_bottom & -fuel_top & +fuel_left & -fuel_right & -fuel_front & +fuel_back

fuel_cell = openmc.Cell(region=fuel_region, fill=U3Si2Al)

clad_top = openmc.ZPlane(z0=32.55)
clad_bottom = openmc.ZPlane(z0=-32.55)
clad_right = openmc.XPlane(x0=3.615)
clad_left = openmc.XPlane(x0=-3.615)
clad_front = openmc.YPlane(y0=0.0635)
clad_back = openmc.YPlane(y0=-0.0635)

for surf in [clad_top, clad_bottom, clad_right, clad_left]:
surf.boundary_type = ‘vacuum’

clad_region = +clad_bottom & -clad_top & +clad_left & -clad_right & -clad_front & +clad_back & ~fuel_region

clad_cell = openmc.Cell(region=clad_region, fill=Al6061)

coolant_front = openmc.YPlane(y0=0.2045)
coolant_back = openmc.YPlane(y0=-0.2045)

coolant_region = -clad_top & + clad_bottom & -coolant_front & +coolant_back & +clad_left & -clad_right & ~clad_region & ~ fuel_region

coolant_cell = openmc.Cell(region=coolant_region, fill=water)

infinite_water = openmc.Cell(fill= water)
infinite_water_universe = openmc.Universe(cells=[infinite_water])

fuel_plate = openmc.Universe(cells=[fuel_cell, clad_cell, coolant_cell])

fuel_assembly = openmc.RectLattice(name = ‘fuel assembly’)
fuel_assembly.lower_left = (-3.615, -2.863)
fuel_assembly.pitch = (7.23, 0.409)
fuel_assembly.universes = [[fuel_plate], [fuel_plate], [fuel_plate], [fuel_plate], [fuel_plate], [fuel_plate], [fuel_plate], [fuel_plate], [fuel_plate], [fuel_plate], [fuel_plate], [fuel_plate], [fuel_plate], [fuel_plate]]
fuel_assembly.outer = infinite_water_universe
fuel_assembly_cell = openmc.Cell()
fuel_assembly_cell.fill = fuel_assembly

fuel_assembly_universe = openmc.Universe()
fuel_assembly_universe.add_cell(fuel_assembly_cell)

‘’’
front_boundary = openmc.YPlane(y0=20.8644, boundary_type = ‘reflective’)
back_boundary = openmc.YPlane(y0=-20.8644, boundary_type = ‘reflective’)
upper_boundary = openmc.ZPlane(z0=20.8644, boundary_type = ‘reflective’)
lower_boundary = openmc.ZPlane(z0=-20.8644, boundary_type = ‘reflective’)
right_boundary = openmc.XPlane(x0=20.8644, boundary_type = ‘reflective’)
left_boundary = openmc.XPlane(x0=-20.8644, boundary_type = ‘reflective’)
‘’’
geometry = openmc.Geometry(root=fuel_assembly_universe)
geometry.export_to_xml()

colors = {1: ‘tomato’, 2: ‘silver’, 3: ‘blue’}

xy_plot = openmc.Plot()
xy_plot.basis = ‘xy’
xy_plot.origin = [0, 0, 0]
xy_plot.width = [8.43, 6.826]
xy_plot.pixels = [500, 500]
xy_plot.filename = ‘Geometry (XY)’
xy_plot.color_by = ‘material’
xy_plot.colors = colors

xz_plot = openmc.Plot()
xz_plot.basis = ‘xz’
xz_plot.origin = [0, 0, 0]
xz_plot.width = [8.43, 65]
xz_plot.pixels = [500, 500]
xz_plot.filename = ‘Geometry (XZ)’
xz_plot.color_by = ‘material’
xz_plot.colors = colors

yz_plot = openmc.Plot()
yz_plot.basis = ‘yz’
yz_plot.origin = [0, 0, 0]
yz_plot.width = [6.826, 65]
yz_plot.pixels = [500, 500]
yz_plot.filename = ‘Geometry (YZ)’
yz_plot.color_by = ‘material’
yz_plot.colors = colors

plots = openmc.Plots([xy_plot, xz_plot, yz_plot])

plots.export_to_xml()

openmc.plot_geometry()

space = openmc.stats.Point((0.0, 0.0, 0.0))
source = openmc.IndependentSource(space=space)

settings = openmc.Settings()
settings.source = source

settings.batches = 10
settings.inactive = 2
settings.particles = 10000

settings.export_to_xml()

openmc.run()

main code.py (4.5 KB)

Can you explain why declared a boundary condition here? for surf in [clad_top, clad_bottom, clad_right, clad_left]: surf.boundary_type = ‘vacuum’ . If I am guessing right you have bunch of pincells all of which have BC as vacuum. So, technically when a particle crosses one of those surfaces with vacuum bcs it should not be in the system (should be lost forever) but you have an assembly level geometry here. That’s why you were getting Particle # could not be located after crossing a boundary of lattice # error.

Fix you BCs. (You don’t declare BCs for a pincell when you are gonna use that to create an assembly. Apply BC to your assembly planes (which you have commented out.) )

Dear Abdullah Alharbi, welcome back to the openmc community.
I checked your model and I think you forgot to declare the axial region at the top and bottom of your fuel plate universe region. it could be seen from the axial plot of your model

So I add some corrections to your regions for cladding and the coolant cell surrounding the cladding. here is the notebook to show my correction to your script
AbdullahAlharbi.ipynb (59.2 KB)

Since your model is a single fuel assembly surrounded with water, then the k-eff will be low (subcritical), so if you want to calculate the infinite multiplication factor (k-inf), then I also activate your outer region for whole fuel assembly with reflective boundary conditions (BC).
you can also notice that I removed the vacuum BC from your cladding surface since I think it would be better to use the default transmission BC as mentioned by magnoxemo. that’s because you still have surrounding coolant in contact with those surfaces.

I also noticed that you have some issues with openmc.plot feature (Plotting Command Issue), so I add the script to use that feature in the notebook as shown here

regarding the inconsistency issue based on the plot figure (Inconsistency with Lattice Components Placement), if you think that it comes from the plot resolution, then you can increase the resolution. you can use a fine resolution of up to 1 pixel per 0.1 mm or more as you want, i.e. for a plot with a width of 8 cm, you can use 800 pixels, like this one

I also show you the simple methods for declaring your xsdir instead of using os.environ['OPENMC_CROSS_SECTIONS'] = ....

materials.cross_sections = '/home/eastdusty/openmc_env/share/data/endfb80/endfb-viii.0-hdf5/cross_sections.xml' # XSDIR

I hope this could help on your problems

Mr. Wahid,

Thank you so much for your effort, I am sincerely surprised that you actually went to that much length to resolve the issue, you did not just point it out but you actually tested the code and fixed it, so thank you again for your effort, it is truly appreciated.

As per the current state of my code, thanks to your advice about the outer boundaries, I was able to fix it simply by adjusting the boundaries of the coolant_cell, and it ran smoothly after that, there is one more thing that I would appreciate your help with though, I tried to replicate this one more time to create a fuel box that contains 4 fuel assemblies, but I ran into a similar error, I know it has something to do with the surfaces of the fuel box as the error indicates, but i see nothing wrong as the plot makes complete sense, I will upload the new code so you can take a look at it.
work space.py (5.8 KB)

The other issue is that even if I remove these surfaces and make the universe infinate, I get the error: “raise RuntimeError(error_msg)
RuntimeError: No fission sites banked on MPI rank 0”

Which indicates that the problem should be with surfaces, second lattice, or nesting lattices, cells, universes.

Hi Abdullah,
I made some corrections to your cladding cell region

clad_region = +clad_bottom & -clad_top & +clad_left & -clad_right & -clad_front & +clad_back
clad_cell = openmc.Cell(region=clad_region & ~fuel_region, fill=Al6061)

Also, I don’t really think that we can use 1 cell/universe as part of 2 separate universes because 1 cell/universe can only be part of 1 universe.


I use a separate water-filled universe as the outer universe for each lattice, for safety measure.

fuel_assembly.outer = openmc.Universe(cells=[openmc.Cell(fill= water)], name='water surrounding fuel plate lattice')
fuel_box.outer = openmc.Universe(cells=[openmc.Cell(fill= water)], name='water surrounding fuel assembly lattice')

Then I just add boundary conditions to your outer surface.
I recommend you check the size of your fuel plate pitch and fuel assembly pitch.

here is my notebook to check your geometry
UniverseError.ipynb (89.6 KB)

Hi @AbdullahAlharbi, I think @wahidluthfi already answered your questions.

Just a few suggestions to keep your mind sane while making a openmc model,

  • Try to use jupyter notebook so that you can run small segment of your code (if you aren’t using already)
  • Try to use better practice of variable naming style so that when you will be looking at your code again you can fully understand which part of your code ( which plane/cylinder is involved in which model)
  • I would try to avoid using magic number. For example clad_bottom = mc.ZPlane(z0=-32.55) try to declare a separate variable which will hold that CLAD_BOTTOM_Z0 = -32.55

Thank you

Hi @magnoxemo, I haven’t taken a look at @wahidluthfi code but I’ll have some time to look at it tomorrow, no I haven’t tried jupyter notebook but you know what, that sounds like a good idea, I’m too used to pycharm but it’s been very messy trying to model a big project like that, I’ll definitely give jupyter notebook a shot.

About the other two points you mentioned, could you be more specific on how to be clearer in declaring variables ?

And your tip about using magic numbers is very interesting, could you explain why we should follow that notion ?

Also if you guys @wahidluthfi @magnoxemo have any other general tips, that would be greatly appreciated, I’ve only started using OpenMC about a week ago and I am working on a specific project that might take a few months to complete, and honestly the CSG system for building the geometry is very confusing, at least at first, I hope it gets more intuitive with time.

Hi @wahidluthfi, thanks again for the feedback, I did not know about the debugging feature, it is very helpful, it turned out I had an overlab that could cause problem later on betwwen the cells fuel_cell and coolant cell, as I assigned the coolant cell region to be equal to ~clad_cell but I did not explicitly say &~fuel_cell, I believe that’s a headache down the road that just have been avoided. And as for the error, it turned out I did not assign boundaries for the far edges of my geometry, so its by default set to transmission, and for this small&simple simulation, more than 99% escape these boundaries, after I assigned the boundaries to vacuum, it ran smoothly, it even made sense because it was so weird, the plot was perfect, looked fine, but the simulation would not run, turned out its just a boundary issue. If you have any general tips for OpenMC specifically building geometry, like I said in the other post, it would be greatly appreciated, I’ve only started using OpenMC about a week ago and I am working on a specific project that might take a few months to complete, and honestly the CSG system for building the geometry is very confusing, at least at first, I hope it gets more intuitive with time.

Hi Abdullah,
I am developing the openmc CSG model with python jupyter notebook on my visual studio code since it is more convenient for troubleshooting. Later, if the model has been developed, I can use the python script for each case scenario being considered to run it from the terminal as a batch of run (controlled using a shell file). That’s why for your question, I am sending you the jupyter notebook file so you can see the step by step for my troubleshooting methods or how to develop an openmc model. About tips on CSG modeling, I usually take a look at the wall of my room when developing a CSG model, just to make sure that I get a sense of the region being modeled with the surface. Sometimes, I plot each cell with jupyter notebook just to make sure that each cell has been modeled as I want. Hehe

I think the recommendation from magnoxemo is good and you can try that.
About using a new code, I think it is about exposure time, so you will get that.

You can also check the openmc jupyter notebook example that I mentioned in this old topic. That notebook from openmc GitHub helps me when I want to do something.