From c02ba6105d3ff46ef5827c58bc9d7782c248d761 Mon Sep 17 00:00:00 2001 From: yardasol Date: Thu, 15 Jan 2026 12:35:03 -0600 Subject: [PATCH 1/3] add random_ray_pincell model, refactor random_ray_lattice --- openmc/examples.py | 187 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 152 insertions(+), 35 deletions(-) diff --git a/openmc/examples.py b/openmc/examples.py index 01dd9d01f97..f2e0452b707 100644 --- a/openmc/examples.py +++ b/openmc/examples.py @@ -4,7 +4,7 @@ import openmc - +PINCELL_PITCH = 1.26 # cm def pwr_pin_cell() -> openmc.Model: """Create a PWR pin-cell model. @@ -51,7 +51,7 @@ def pwr_pin_cell() -> openmc.Model: model.materials = (fuel, clad, hot_water) # Instantiate ZCylinder surfaces - pitch = 1.26 + pitch = PINCELL_PITCH fuel_or = openmc.ZCylinder(x0=0, y0=0, r=0.39218, name='Fuel OR') clad_or = openmc.ZCylinder(x0=0, y0=0, r=0.45720, name='Clad OR') left = openmc.XPlane(x0=-pitch/2, name='left', boundary_type='reflective') @@ -319,14 +319,14 @@ def pwr_core() -> openmc.Model: l100 = openmc.RectLattice( name='Fuel assembly (lower half)', lattice_id=100) l100.lower_left = (-10.71, -10.71) - l100.pitch = (1.26, 1.26) + l100.pitch = (PINCELL_PITCH, PINCELL_PITCH) l100.universes = np.tile(fuel_cold, (17, 17)) l100.universes[tube_x, tube_y] = tube_cold l101 = openmc.RectLattice( name='Fuel assembly (upper half)', lattice_id=101) l101.lower_left = (-10.71, -10.71) - l101.pitch = (1.26, 1.26) + l101.pitch = (PINCELL_PITCH, PINCELL_PITCH) l101.universes = np.tile(fuel_hot, (17, 17)) l101.universes[tube_x, tube_y] = tube_hot @@ -350,7 +350,7 @@ def pwr_core() -> openmc.Model: # Define core lattices l200 = openmc.RectLattice(name='Core lattice (lower half)', lattice_id=200) l200.lower_left = (-224.91, -224.91) - l200.pitch = (21.42, 21.42) + l200.pitch = (17 * PINCELL_PITCH, 17 * PINCELL_PITCH) l200.universes = [ [fa_cw]*21, [fa_cw]*21, @@ -376,7 +376,7 @@ def pwr_core() -> openmc.Model: l201 = openmc.RectLattice(name='Core lattice (lower half)', lattice_id=201) l201.lower_left = (-224.91, -224.91) - l201.pitch = (21.42, 21.42) + l201.pitch = (17 * PINCELL_PITCH, 17 * PINCELL_PITCH) l201.universes = [ [fa_hw]*21, [fa_hw]*21, @@ -488,7 +488,7 @@ def pwr_assembly() -> openmc.Model: clad_or = openmc.ZCylinder(x0=0, y0=0, r=0.45720, name='Clad OR') # Create boundary planes to surround the geometry - pitch = 21.42 + pitch = 17 * PINCELL_PITCH min_x = openmc.XPlane(x0=-pitch/2, boundary_type='reflective') max_x = openmc.XPlane(x0=+pitch/2, boundary_type='reflective') min_y = openmc.YPlane(y0=-pitch/2, boundary_type='reflective') @@ -514,7 +514,7 @@ def pwr_assembly() -> openmc.Model: # Create fuel assembly Lattice assembly = openmc.RectLattice(name='Fuel Assembly') - assembly.pitch = (pitch/17, pitch/17) + assembly.pitch = (PINCELL_PITCH, PINCELL_PITCH) assembly.lower_left = (-pitch/2, -pitch/2) # Create array indices for guide tube locations in lattice @@ -656,24 +656,21 @@ def slab_mg(num_regions=1, mat_names=None, mgxslib_name='2g.h5') -> openmc.Model return model -def random_ray_lattice() -> openmc.Model: - """Create a 2x2 PWR pincell asymmetrical lattic eexample. - - This model is a 2x2 reflective lattice of fuel pins with one of the lattice - locations having just moderator instead of a fuel pin. It uses 7 group - cross section data. +def _generate_c5g7_materials() -> openmc.Materials: + """Generate materials utilizing multi-group cross sections based on the + the C5G7 Benchmark. Returns ------- - model : openmc.Model - A PWR 2x2 lattice model - + materials : openmc.Materials + Materials object containing UO2 and water materials. + + Data Sources + ------------ + All cross section data are from: + Lewis et al., "Benchmark specification for determinisitc 2D/3D MOX fuel + assembly transport calculations without spatial homogenization" """ - model = openmc.Model() - - ########################################################################### - # Create MGXS data for the problem - # Instantiate the energy group data group_edges = [1e-5, 0.0635, 10.0, 1.0e2, 1.0e3, 0.5e6, 1.0e6, 20.0e6] groups = openmc.mgxs.EnergyGroups(group_edges) @@ -704,9 +701,10 @@ def random_ray_lattice() -> openmc.Model: uo2_xsdata.set_fission([7.21206e-03, 8.19301e-04, 6.45320e-03, 1.85648e-02, 1.78084e-02, 8.30348e-02, 2.16004e-01]) - uo2_xsdata.set_nu_fission([2.005998e-02, 2.027303e-03, 1.570599e-02, - 4.518301e-02, 4.334208e-02, 2.020901e-01, - 5.257105e-01]) + nu_fission = np.array([2.005998e-02, 2.027303e-03, 1.570599e-02, + 4.518301e-02, 4.334208e-02, 2.020901e-01, + 5.257105e-01]) + uo2_xsdata.set_nu_fission(nu_fission) uo2_xsdata.set_chi([5.8791e-01, 4.1176e-01, 3.3906e-04, 1.1761e-07, 0.0000e+00, 0.0000e+00, 0.0000e+00]) @@ -752,14 +750,28 @@ def random_ray_lattice() -> openmc.Model: # Instantiate a Materials collection and export to XML materials = openmc.Materials([uo2, water]) materials.cross_sections = "mgxs.h5" + return materials - ########################################################################### - # Define problem geometry - ######################################## - # Define an unbounded pincell universe +def _generate_random_ray_pin_cell(uo2, water) -> openmc.Universe: + """Create a random ray pin cell universe. Helper function for + random_ray_pin_cell() and random_ray_lattice() - pitch = 1.26 + Parameters + ---------- + uo2 : openmc.Material + UO2 material + water : openmc.Material + Water material + + Returns + ------- + pincell : openmc.Universe + Universe containing an unbounded pin cell + + """ + ######################################## + # Define an unbounded pin cell universe # Create a surface for the fuel outer radius fuel_or = openmc.ZCylinder(r=0.54, name='Fuel OR') @@ -781,7 +793,7 @@ def random_ray_lattice() -> openmc.Model: moderator_c = openmc.Cell( fill=water, region=+outer_ring_b, name='moderator outer c') - # Create pincell universe + # Create pin cell universe pincell_base = openmc.Universe() # Register Cells with Universe @@ -801,19 +813,125 @@ def random_ray_lattice() -> openmc.Model: for i in range(8): azimuthal_cell = openmc.Cell(name=f'azimuthal_cell_{i}') azimuthal_cell.fill = pincell_base - azimuthal_cell.region = +azimuthal_planes[i] & -azimuthal_planes[(i+1) % 8] + azimuthal_cell.region = + \ + azimuthal_planes[i] & -azimuthal_planes[(i+1) % 8] azimuthal_cells.append(azimuthal_cell) # Create a geometry with the azimuthal universes pincell = openmc.Universe(cells=azimuthal_cells, name='pincell') + return pincell + + +def random_ray_pin_cell() -> openmc.Model: + """Create a PWR pin cell example using C5G7 cross section data. + cross section data. + + Returns + ------- + model : openmc.Model + A PWR pin cell model + + """ + model = openmc.Model() + + ########################################################################### + # Create Materials for the problem + materials = _generate_c5g7_materials() + uo2 = materials[0] + water = materials[1] + + ########################################################################### + # Define problem geometry + pincell = _generate_random_ray_pin_cell(uo2, water) + + ######################################## + # Define cell containing lattice and other stuff + pitch = PINCELL_PITCH + box = openmc.model.RectangularPrism(pitch, pitch, boundary_type='reflective') + + pincell = openmc.Cell(fill=pincell, region=-box, name='pincell') + + # Create a geometry with the top-level cell + geometry = openmc.Geometry([pincell]) + + ########################################################################### + # Define problem settings + + # Instantiate a Settings object, set all runtime parameters, and export to XML + settings = openmc.Settings() + settings.energy_mode = "multi-group" + settings.batches = 400 + settings.inactive = 200 + settings.particles = 100 + + # Create an initial uniform spatial source distribution over fissionable zones + lower_left = (-pitch / 2, -pitch / 2, -1) + upper_right = (pitch / 2, pitch / 2, 1) + uniform_dist = openmc.stats.Box(lower_left, upper_right) + rr_source = openmc.IndependentSource(space=uniform_dist) + + settings.random_ray['distance_active'] = 100.0 + settings.random_ray['distance_inactive'] = 20.0 + settings.random_ray['ray_source'] = rr_source + settings.random_ray['volume_normalized_flux_tallies'] = True + + ########################################################################### + # Define tallies + # Now use the mesh filter in a tally and indicate what scores are desired + tally = openmc.Tally(name="Pin tally") + tally.scores = ['flux', 'fission', 'nu-fission'] + tally.estimator = 'analog' + + # Instantiate a Tallies collection and export to XML + tallies = openmc.Tallies([tally]) + + ########################################################################### + # Exporting to OpenMC model + ########################################################################### + + model.geometry = geometry + model.materials = materials + model.settings = settings + model.tallies = tallies + return model + + +def random_ray_lattice() -> openmc.Model: + """Create a 2x2 PWR pin cell asymmetrical lattice example. + + This model is a 2x2 reflective lattice of fuel pins with one of the lattice + locations having just moderator instead of a fuel pin. It uses C5G7 + cross section data. + + Returns + ------- + model : openmc.Model + A PWR 2x2 lattice model + + """ + model = openmc.Model() + + ########################################################################### + # Create Materials for the problem + materials = _generate_c5g7_materials() + uo2 = materials[0] + water = materials[1] + + ########################################################################### + # Define problem geometry + pincell = _generate_random_ray_pin_cell(uo2, water) + ######################################## # Define a moderator lattice universe - moderator_infinite = openmc.Cell(fill=water, name='moderator infinite') + moderator_infinite = openmc.Cell(name='moderator infinite') + moderator_infinite.fill = water + mu = openmc.Universe() mu.add_cells([moderator_infinite]) + pitch = PINCELL_PITCH lattice = openmc.RectLattice() lattice.lower_left = [-pitch/2.0, -pitch/2.0] lattice.pitch = [pitch/10.0, pitch/10.0] @@ -837,8 +955,7 @@ def random_ray_lattice() -> openmc.Model: ######################################## # Define cell containing lattice and other stuff - box = openmc.model.RectangularPrism( - pitch*2, pitch*2, boundary_type='reflective') + box = openmc.model.RectangularPrism(pitch*2, pitch*2, boundary_type='reflective') assembly = openmc.Cell(fill=lattice2x2, region=-box, name='assembly') From b77a825fa0846595078d32132044098133e78274 Mon Sep 17 00:00:00 2001 From: yardasol Date: Thu, 22 Jan 2026 12:09:12 -0600 Subject: [PATCH 2/3] _generate_random_ray_pin_cell -> _generate_subdivided_pin_cell --- openmc/examples.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openmc/examples.py b/openmc/examples.py index f2e0452b707..8cdcfb496fc 100644 --- a/openmc/examples.py +++ b/openmc/examples.py @@ -753,9 +753,9 @@ def _generate_c5g7_materials() -> openmc.Materials: return materials -def _generate_random_ray_pin_cell(uo2, water) -> openmc.Universe: - """Create a random ray pin cell universe. Helper function for - random_ray_pin_cell() and random_ray_lattice() +def _generate_subdivided_pin_cell(uo2, water) -> openmc.Universe: + """Create a radially and azimuthally subdivided pin celluniverse. Helper + function for random_ray_pin_cell() and random_ray_lattice() Parameters ---------- @@ -843,7 +843,7 @@ def random_ray_pin_cell() -> openmc.Model: ########################################################################### # Define problem geometry - pincell = _generate_random_ray_pin_cell(uo2, water) + pincell = _generate_subdivided_pin_cell(uo2, water) ######################################## # Define cell containing lattice and other stuff @@ -920,7 +920,7 @@ def random_ray_lattice() -> openmc.Model: ########################################################################### # Define problem geometry - pincell = _generate_random_ray_pin_cell(uo2, water) + pincell = _generate_subdivided_pin_cell(uo2, water) ######################################## # Define a moderator lattice universe From ad09da37b8429598c8475815c53cadf49b5f6e7e Mon Sep 17 00:00:00 2001 From: Olek <45364492+yardasol@users.noreply.github.com> Date: Thu, 22 Jan 2026 21:34:17 -0600 Subject: [PATCH 3/3] Update examples.py Co-authored-by: John Tramm --- openmc/examples.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openmc/examples.py b/openmc/examples.py index 8cdcfb496fc..350a4d24d5e 100644 --- a/openmc/examples.py +++ b/openmc/examples.py @@ -754,7 +754,7 @@ def _generate_c5g7_materials() -> openmc.Materials: def _generate_subdivided_pin_cell(uo2, water) -> openmc.Universe: - """Create a radially and azimuthally subdivided pin celluniverse. Helper + """Create a radially and azimuthally subdivided pin cell universe. Helper function for random_ray_pin_cell() and random_ray_lattice() Parameters