OpenMC Guide
Cell Creation Techniques
What you'll learn
- Fill a cell with a material, a universe, a lattice, or nothing at all.
- Build a complicated region one surface at a time instead of in a single expression.
- Diagnose overlapping cells and undefined space.
Before you start
Filling cells, and building a region one piece at a time
A cell pairs a region — built in the previous page from surface half-spaces — with a fill. The fill can be a material, another universe for a nested structure, a lattice for a repeated array, or None for void space; the constructor is the sameopenmc.Cell(fill=..., region=...) in every case.
fuel_cell = openmc.Cell(fill=fuel_material, region=fuel_region) # material
void_cell = openmc.Cell(fill=None, region=void_region) # void
pin_cell = openmc.Cell(fill=pin_universe, region=pin_region) # nested universe
assembly_cell = openmc.Cell(fill=pin_lattice, region=assembly_region) # repeated array
# Temperature is an attribute, not a constructor argument — openmc.Cell()
# only takes cell_id, name, fill, and region. Setting it here overrides
# whatever fuel_material.temperature was set to.
hot_fuel_cell = openmc.Cell(fill=fuel_material, region=fuel_region)
hot_fuel_cell.temperature = 900 # KelvinTutorial snippet — no separate file in examples repo
For a region built from more than two or three surfaces, name the pieces and combine them last rather than writing one long expression — and parenthesize explicitly whenever you mix & and | in the same line, since getting the grouping wrong produces a region that OpenMC accepts without complaint but that describes the wrong shape.
base_region = +s1 & -s2
add_region = +s3 & -s4 & +s5
final_region = (base_region | add_region) & -s6 # parenthesized, not implicitTutorial snippet — no separate file in examples repo
One placement feature is worth knowing about even though the pin cell does not use it:cell.translation and cell.rotation move or turn a universe fill's local coordinate frame. Set either one on a cell filled directly with a material and OpenMC accepts it silently and does nothing, since a bare material has no local frame to move. Placing many copies of one pin universe in an assembly lattice is exactly where this matters — covered in Lattices & Universes.
The same two failure modes from surfaces carry over to cells: two cells claiming the same point (overlap) or no cell claiming a point at all (undefined space). Beyond plotting, OpenMC can check for both at every collision site during the run itself — pass --geometry-debug on the command line, or openmc.run(geometry_debug=True) from Python. It costs speed, so use it while debugging a new model rather than on every production run.
The pin cell's three cells and universe
The three regions from Geometry Basics finally get materials here. Fuel, cladding, and moderator each become one cell, and the three cells together form the universe that the rest of the model builds on. This is the same fragment that appears on Example: Pin Cell.
fuel_cell = openmc.Cell(fill=fuel, region=fuel_region)
clad_cell = openmc.Cell(fill=clad, region=clad_region)
water_cell = openmc.Cell(fill=water, region=water_region)
universe = openmc.Universe(cells=[fuel_cell, clad_cell, water_cell])
geometry = openmc.Geometry(universe)Tutorial snippet — no separate file in examples repo
Nothing about this pin uses a lattice or a translated cell — one universe, filled straight into geometry, is the whole geometry. Lattices arrive on Path B once you need many of these pins side by side.
Try It Yourself
RectangularPrism in the water cell region: use -box, not box.Check yourself
- Fill a cell with a material, a universe, a lattice, or nothing at all?
- Build a complicated region one surface at a time instead of in a single expression?
- Diagnose overlapping cells and undefined space?