mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-21 14:35:27 -04:00
Co-authored-by: church89 <l.chierici89@gmail.com> Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
141 lines
4.9 KiB
Python
141 lines
4.9 KiB
Python
"""
|
|
This script builds a single PWR assembly and is a slightly more advanced
|
|
demonstration of model building using Python. The creation of two universes for
|
|
fuel pins and guide tube pins has been separated into functions, and then the
|
|
overall model is built by an `assembly` function. This script also demonstrates
|
|
the use of the `Model` class, which provides some extra convenience over using
|
|
`Geometry`, `Materials`, and `Settings` classes directly. Finally, the script
|
|
takes two command-line flags that indicate whether to build and/or run the
|
|
model.
|
|
|
|
"""
|
|
|
|
import argparse
|
|
from math import log10
|
|
|
|
import numpy as np
|
|
import openmc
|
|
|
|
# Define surfaces
|
|
fuel_or = openmc.ZCylinder(r=0.39218, name='Fuel OR')
|
|
clad_or = openmc.ZCylinder(r=0.45720, name='Clad OR')
|
|
|
|
# Define materials
|
|
fuel = openmc.Material(name='Fuel')
|
|
fuel.set_density('g/cm3', 10.29769)
|
|
fuel.add_nuclide('U234', 4.4843e-6)
|
|
fuel.add_nuclide('U235', 5.5815e-4)
|
|
fuel.add_nuclide('U238', 2.2408e-2)
|
|
fuel.add_nuclide('O16', 4.5829e-2)
|
|
|
|
clad = openmc.Material(name='Cladding')
|
|
clad.set_density('g/cm3', 6.55)
|
|
clad.add_nuclide('Zr90', 2.1827e-2)
|
|
clad.add_nuclide('Zr91', 4.7600e-3)
|
|
clad.add_nuclide('Zr92', 7.2758e-3)
|
|
clad.add_nuclide('Zr94', 7.3734e-3)
|
|
clad.add_nuclide('Zr96', 1.1879e-3)
|
|
|
|
hot_water = openmc.Material(name='Hot borated water')
|
|
hot_water.set_density('g/cm3', 0.740582)
|
|
hot_water.add_nuclide('H1', 4.9457e-2)
|
|
hot_water.add_nuclide('O16', 2.4672e-2)
|
|
hot_water.add_nuclide('B10', 8.0042e-6)
|
|
hot_water.add_nuclide('B11', 3.2218e-5)
|
|
hot_water.add_s_alpha_beta('c_H_in_H2O')
|
|
|
|
|
|
def fuel_pin():
|
|
"""Returns a fuel pin universe."""
|
|
|
|
fuel_cell = openmc.Cell(fill=fuel, region=-fuel_or)
|
|
clad_cell = openmc.Cell(fill=clad, region=+fuel_or & -clad_or)
|
|
hot_water_cell = openmc.Cell(fill=hot_water, region=+clad_or)
|
|
|
|
univ = openmc.Universe(name='Fuel Pin')
|
|
univ.add_cells([fuel_cell, clad_cell, hot_water_cell])
|
|
return univ
|
|
|
|
|
|
def guide_tube_pin():
|
|
"""Returns a control rod guide tube universe."""
|
|
|
|
gt_inner_cell = openmc.Cell(fill=hot_water, region=-fuel_or)
|
|
gt_clad_cell = openmc.Cell(fill=clad, region=+fuel_or & -clad_or)
|
|
gt_outer_cell = openmc.Cell(fill=hot_water, region=+clad_or)
|
|
|
|
univ = openmc.Universe(name='Guide Tube')
|
|
univ.add_cells([gt_inner_cell, gt_clad_cell, gt_outer_cell])
|
|
return univ
|
|
|
|
|
|
def assembly_model():
|
|
"""Returns a single PWR fuel assembly."""
|
|
|
|
model = openmc.model.Model()
|
|
|
|
# Create fuel assembly Lattice
|
|
pitch = 21.42
|
|
assembly = openmc.RectLattice(name='Fuel Assembly')
|
|
assembly.pitch = (pitch/17, pitch/17)
|
|
assembly.lower_left = (-pitch/2, -pitch/2)
|
|
|
|
# Create array indices for guide tube locations in lattice
|
|
gt_pos = np.array([
|
|
[2, 5], [2, 8], [2, 11],
|
|
[3, 3], [3, 13],
|
|
[5, 2], [5, 5], [5, 8], [5, 11], [5, 14],
|
|
[8, 2], [8, 5], [8, 8], [8, 11], [8, 14],
|
|
[11, 2], [11, 5], [11, 8], [11, 11], [11, 14],
|
|
[13, 3], [13, 13],
|
|
[14, 5], [14, 8], [14, 11]
|
|
])
|
|
|
|
# Create 17x17 array of universes. First we create a 17x17 array all filled
|
|
# with the fuel pin universe. Then, we replace the guide tube positions with
|
|
# the guide tube pin universe (note the use of numpy fancy indexing to
|
|
# achieve this).
|
|
assembly.universes = np.full((17, 17), fuel_pin())
|
|
assembly.universes[gt_pos[:, 0], gt_pos[:, 1]] = guide_tube_pin()
|
|
|
|
# Create outer boundary of the geometry to surround the lattice
|
|
outer_boundary = openmc.model.RectangularPrism(
|
|
pitch, pitch, boundary_type='reflective')
|
|
|
|
# Create a cell filled with the lattice
|
|
main_cell = openmc.Cell(fill=assembly, region=-outer_boundary)
|
|
|
|
# Finally, create geometry by providing a list of cells that fill the root
|
|
# universe
|
|
model.geometry = openmc.Geometry([main_cell])
|
|
|
|
model.settings.batches = 150
|
|
model.settings.inactive = 50
|
|
model.settings.particles = 1000
|
|
model.settings.source = openmc.IndependentSource(
|
|
space=openmc.stats.Box((-pitch/2, -pitch/2, -1), (pitch/2, pitch/2, 1)),
|
|
constraints={'fissionable': True}
|
|
)
|
|
|
|
# NOTE: We never actually created a Materials object. When you export/run
|
|
# using the Model object, if no materials were assigned it will look through
|
|
# the Geometry object and automatically export any materials that are
|
|
# necessary to build the model.
|
|
return model
|
|
|
|
|
|
if __name__ == '__main__':
|
|
# Set up command-line arguments for generating/running the model
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('--generate', action='store_true')
|
|
parser.add_argument('--run', action='store_true')
|
|
args = parser.parse_args()
|
|
if not args.generate and not args.run:
|
|
parser.print_help()
|
|
|
|
if args.generate or args.run:
|
|
model = assembly_model()
|
|
if args.generate:
|
|
model.export_to_xml()
|
|
if args.run:
|
|
model.run()
|