updated beavrs scripts of openmc to generate 2D and/or symmetric models

This commit is contained in:
liangjg 2018-09-12 14:56:39 -04:00
parent 66caecf98b
commit 39af932296
9 changed files with 267 additions and 187 deletions

View file

@ -35,5 +35,27 @@ model.write_openmc_settings()
```
For convenience, also provided are a script `make_beavrs.py` to build the model
and a Jupyter notebook `extract-assm.ipynb` to extract a single assembly of BEAVRS.
and Jupyter notebooks `extract-assm.ipynb` and `extract-pin.ipynb` to extract
single assemblies and pin cells of BEAVRS respectively.
For those looking to generate the input files for the 2D BEAVRS model and/or a model
that is symmetric in the x-y plane, the `-d` and `-s` flags can be used with the
`make_beavrs.py` script respectively. Details about these two models can be found
below:
2D BEAVRS Model
---------------
The 2D BEAVRS model is created from the 3D model by creating a bounding box around the
full core to restrict the problem to one assembly-width outside the outer-most assemblies
(i.e. 17 assemblies wide) in the x-y direction, and a 10cm slice in the z-direction.
The x-y surfaces have vacuum boundary conditions, while the 10cm slice is arbitrarily
chosen in a non-grid spacer region with reflective boundary conditions. The initial source
distribution is also updated accordingly.
Symmetric BEAVRS Model in x-y Plane
-----------------------------------
The only source of asymmetry in the x-y plane stems from the insertion of instrument tubes,
so the symmetric model replaces all instrument tubes with empty guide tubes, similar to all
other assemblies.

View file

@ -34,7 +34,7 @@ class Assemblies(object):
def __init__(self, pincells, mats):
""" Creates BEAVRS pincell universes """
self.pins = pincells
self.mats = mats
@ -63,12 +63,12 @@ class Assemblies(object):
def _add_bpra_layouts(self):
""" Adds BEAVRS BPRA layouts """
self.ba_specs = []
u_gt = self.pins.u_gt
u_bp = self.pins.u_bp
self.ba_specs.append(('no BAs',{
'a': u_gt, 'b': u_gt, 'c': u_gt,
'd': u_gt, 'e': u_gt,
@ -169,7 +169,7 @@ class Assemblies(object):
'u': u_gt, 'v': u_gt,
'w': u_gt, 'x': u_gt, 'y': u_gt,
}))
self.ba_specs.append(('15SW',{
'a': u_gt, 'b': u_gt, 'c': u_gt,
'd': u_gt, 'e': u_gt,
@ -179,7 +179,7 @@ class Assemblies(object):
'u': u_bp, 'v': u_gt,
'w': u_bp, 'x': u_bp, 'y': u_bp,
}))
self.ba_specs.append(('15SE',{
'a': u_gt, 'b': u_gt, 'c': u_gt,
'd': u_gt, 'e': u_gt,
@ -215,7 +215,7 @@ class Assemblies(object):
""" Adds BEAVRS RCCA layouts """
self.cr_specs = []
for bank_label, u_b in self.pins.u_rcca.items():
for bank_label, u_b in sorted(self.pins.u_rcca.items()):
self.cr_specs.append(("RCCA {0}".format(bank_label),{
'a': u_b, 'b': u_b, 'c': u_b,
'd': u_b, 'e': u_b,
@ -229,24 +229,24 @@ class Assemblies(object):
def _add_all_assembly_combinations(self):
""" Adds all BEAVRS assembly layouts
Here we make every possible combination of enrichments, control and shutdown
banks, with or without instrument tubes.
"""
types_fuel = self.pins.enrichments
types_gt = self.ba_specs + self.cr_specs
types_instr = [(self.pins.u_it_nt,'no instr'), (self.pins.u_it,'instr')]
self.u_fuel = {}
self.u_fuel_no_sleeve = {}
for enr in types_fuel:
self.u_fuel[enr] = {}
self.u_fuel_no_sleeve[enr] = {}
for gt_label, gt_spec in types_gt:
self.u_fuel[enr][gt_label] = {}
self.u_fuel_no_sleeve[enr][gt_label] = {}
for u_c, center_label in types_instr:
@ -262,14 +262,14 @@ class Assemblies(object):
lattice.setPosition('fuel', self.pins.u_fuel_p[enr])
lattice.updatePositions(gt_spec)
lattice.finalize()
# Wrap the lattice with the grid sleeve universe
u_lattice = InfinitePinCell(name='{0} universe'.format(name))
u_lattice.add_ring(lattice, self.lattice_surfs, box=True)
u_lattice.add_last_ring(self.pins.u_gridsleeve)
self.u_fuel[enr][gt_label][center_label] = u_lattice
u_lattice.finalize()
# Store the lattice without the gridsleeve
u_latticePins = InfinitePinCell(name='{0} pins'.format(name))
u_latticePins.add_ring(lattice, self.lattice_surfs, box=True)

View file

@ -18,14 +18,13 @@ from beavrs.core import Core
from beavrs.univzero import UniverseZero
from beavrs.plots import Plots
# Suppress DeprecationWarnings from OpenMC's Cell.add_surface(...) method
warnings.simplefilter('once', DeprecationWarning)
class BEAVRS(object):
""" Main BEAVRS class"""
def __init__(self, boron_ppm=c.nominalBoronPPM):
def __init__(self, boron_ppm=c.nominalBoronPPM, is_symmetric=False, is_2d=False):
""" We build the entire geometry in memory in the constructor """
# TODO: make the control rod bank insertion heights attributes
@ -36,8 +35,8 @@ class BEAVRS(object):
self.pincells = Pincells(self.mats)
self.assemblies = Assemblies(self.pincells, self.mats)
self.baffle = Baffle(self.assemblies, self.mats)
self.core = Core(self.pincells, self.assemblies, self.baffle)
self.main_universe = UniverseZero(self.core, self.mats)
self.core = Core(self.pincells, self.assemblies, self.baffle, is_symmetric=is_symmetric)
self.main_universe = UniverseZero(self.core, self.mats, is_2d=is_2d)
self.openmc_geometry = openmc.Geometry(self.main_universe)
@ -45,8 +44,12 @@ class BEAVRS(object):
self.settings_inactive = 5
self.settings_particles = 1000
baffle_flat = 7.5*c.latticePitch
self.settings_sourcebox = [-baffle_flat, -baffle_flat, c.fuel_Rod_bot,
baffle_flat, baffle_flat, c.fuel_Rod_top]
if is_2d:
self.settings_sourcebox = [-baffle_flat, -baffle_flat, c.struct_LowestExtent_2d,
baffle_flat, baffle_flat, c.struct_HighestExtent_2d]
else:
self.settings_sourcebox = [-baffle_flat, -baffle_flat, c.fuel_Rod_bot,
baffle_flat, baffle_flat, c.fuel_Rod_top]
self.settings_output_tallies = False
self.settings_summary = True
self.settings_output_distribmats = False

View file

@ -23,14 +23,14 @@ rcca_bank_steps_withdrawn = {
rcca_banks = rcca_bank_steps_withdrawn.keys()
## pincell parameters
pelletOR = 0.39218 #
cladIR = 0.40005 #
cladOR = 0.45720 #
pelletOR = 0.39218 #
cladIR = 0.40005 #
cladOR = 0.45720 #
rodGridSide_tb = 1.22030 #
rodGridSide_i = 1.22098 #
guideTubeIR = 0.56134 #
guideTubeOR = 0.60198 #
guideTubeDashIR = 0.50419 #
guideTubeIR = 0.56134 #
guideTubeOR = 0.60198 #
guideTubeDashIR = 0.50419 #
guideTubeDashOR = 0.54610 #
rcca_clad_OR = 0.48387 # ML033530020 page 15
rcca_clad_IR = 0.38608 # ML033530020 page 15
@ -38,104 +38,106 @@ rcca_b4c_OR = 0.37338 # ML033530020 page 15
rcca_aic_OR = 0.38227 # ML033530020 page 15
rcca_spacer_OR = 0.37845 # ML033530020 page 15
rcca_spring_OR = 0.06459 # Assumed same as fuel
burnabs1 = 0.21400 #
burnabs2 = 0.23051 #
burnabs3 = 0.24130 #
burnabs4 = 0.42672 #
burnabs5 = 0.43688 #
burnabs6 = 0.48387 #
instrTubeIR = 0.43688 # no source
instrTubeOR = 0.48387 # no source
burnabs1 = 0.21400 #
burnabs2 = 0.23051 #
burnabs3 = 0.24130 #
burnabs4 = 0.42672 #
burnabs5 = 0.43688 #
burnabs6 = 0.48387 #
instrTubeIR = 0.43688 # no source
instrTubeOR = 0.48387 # no source
plenumSpringOR = 0.06459 # frapcon source - see beavrs_spring.ods
## lattice parameters
pinPitch = 1.25984 #
pinPitch = 1.25984 #
latticePitch = 21.50364 #
gridstrapSide = 21.49595 #
gridstrapSide = 21.49595 #
## <!--- axials copied straight from rod_axials.ods
# Core Structures
struct_LowestExtent = 0.00000 #
struct_SupportPlate_bot = 20.0000 # arbitrary amount of water below core
struct_SupportPlate_top = 25.0000 # guessed
struct_LowerNozzle_bot = 25.0000 # same as struct_SupportPlate_top
struct_LowerNozzle_top = 35.0000 # approx from ** NDR of 4.088in for lower nozzle height
struct_UpperNozzle_bot = 423.049 # fig 4.2-3 from Watts Bar Unit 2 safety analysis report
struct_UpperNozzle_top = 431.876 # fig 4.2-3 from Watts Bar Unit 2 safety analysis report
struct_HighestExtent = 460.000 # arbitrary amount of water above core
# Fuel Rod
fuel_Rod_bot = 35.0000 # same as struct_LowerNozzle_top
fuel_LowerFitting_bot = 35.0000 # ML033530020 Fig 2-7
fuel_LowerFitting_top = 36.7480 # ML033530020 Fig 2-7
fuel_ActiveFuel_bot = 36.7480 # ML033530020 Fig 2-7
fuel_ActiveFuel_top = 402.508 # ML033530020 Fig 2-7
fuel_Plenum_bot = 402.508 # ML033530020 Fig 2-7
fuel_Plenum_top = 417.164 # ML033530020 Fig 2-7
fuel_UpperFitting_bot = 417.164 # ML033530020 Fig 2-7
fuel_UpperFitting_top = 419.704 # ML033530020 Fig 2-7
fuel_Rod_top = 419.704 # ML033530020 Fig 2-7
# RCCAs (0 steps withdraw, i.e., fully inserted)
rcca_Rod_bot = 39.9580 # ML033530020 Fig 2-8
rcca_LowerFitting_bot = 39.9580 # ML033530020 Fig 2-8
rcca_LowerFitting_top = 41.8280 # ML033530020 Fig 2-8
rcca_AIC_bot = 41.8280 # ML033530020 Fig 2-8
rcca_AIC_top = 143.428 # ML033530020 Fig 2-8
rcca_B4C_bot = 143.428 # ML033530020 Fig 2-8
rcca_B4C_top = 402.508 # ML033530020 Fig 2-8
rcca_Spacer_bot = 402.508 # ML033530020 Fig 2-8
rcca_Spacer_top = 403.778 # ML033530020 Fig 2-8
rcca_Plenum_bot = 403.778 # ML033530020 Fig 2-8
rcca_Plenum_top = 415.558 # ML033530020 Fig 2-8
rcca_Rod_top = 460.000 # same as struct_HighestExtent
rcca_StepWidth = 1.58193 # Active height divided into 228 steps
# BPRAs
bpra_Rod_bot = 38.6600 # ML033530020 Fig 2-9
bpra_LowerFitting_bot = 38.6600 # ML033530020 Fig 2-9
bpra_LowerFitting_top = 40.5580 # ML033530020 Fig 2-9
bpra_Active_bot = 40.5580 # ML033530020 Fig 2-9
bpra_Active_top = 401.238 # ML033530020 Fig 2-9
bpra_Plenum_bot = 401.238 # ML033530020 Fig 2-9
bpra_Plenum_top = 421.532 # ML033530020 Fig 2-9
bpra_Rod_top = 431.876 # same as struct_UpperNozzle_top
# Guide Tube
gt_Rod_bot = 35.0000 # same as fuel_Rod_bot
gt_Dashpot_bot = 35.0000 #
gt_Dashpot_top = 39.9580 # same as rcca_Rod_bot for full insertion
gt_Upper_bot = 39.9580 #
gt_Upper_top = 423.049 # same as struct_UpperNozzle_bot
gt_Rod_top = 423.049 #
# Intrument Tube
instr_Rod_bot = 35.0000 # same as fuel_Rod_bot
instr_Rod_top = 423.049 # same as struct_UpperNozzle_bot
# Grid Spacers (centers provided by utiliy) (heights 1.65 top/bottom, 2.25 intermediate)
grid1_bot = 37.1621 #
grid1_top = 40.5200 #
grid2_bot = 98.0250 #
grid2_top = 103.740 #
grid3_bot = 150.222 #
grid3_top = 155.937 #
grid4_bot = 202.419 #
grid4_top = 208.134 #
grid5_bot = 254.616 #
grid5_top = 260.331 #
grid6_bot = 306.813 #
grid6_top = 312.528 #
grid7_bot = 359.010 #
grid7_top = 364.725 #
grid8_bot = 411.806 #
grid8_top = 415.164 #
# Core Structures
struct_LowestExtent = 0.00000 #
struct_SupportPlate_bot = 20.0000 # arbitrary amount of water below core
struct_SupportPlate_top = 25.0000 # guessed
struct_LowerNozzle_bot = 25.0000 # same as struct_SupportPlate_top
struct_LowerNozzle_top = 35.0000 # approx from ** NDR of 4.088in for lower nozzle height
struct_LowestExtent_2d = 220.000 # arbitrary lower slice for 2D problem
struct_HighestExtent_2d = 230.000 # arbitrary upper slice for 2D problem
struct_UpperNozzle_bot = 423.049 # fig 4.2-3 from Watts Bar Unit 2 safety analysis report
struct_UpperNozzle_top = 431.876 # fig 4.2-3 from Watts Bar Unit 2 safety analysis report
struct_HighestExtent = 460.000 # arbitrary amount of water above core
# Fuel Rod
fuel_Rod_bot = 35.0000 # same as struct_LowerNozzle_top
fuel_LowerFitting_bot = 35.0000 # ML033530020 Fig 2-7
fuel_LowerFitting_top = 36.7480 # ML033530020 Fig 2-7
fuel_ActiveFuel_bot = 36.7480 # ML033530020 Fig 2-7
fuel_ActiveFuel_top = 402.508 # ML033530020 Fig 2-7
fuel_Plenum_bot = 402.508 # ML033530020 Fig 2-7
fuel_Plenum_top = 417.164 # ML033530020 Fig 2-7
fuel_UpperFitting_bot = 417.164 # ML033530020 Fig 2-7
fuel_UpperFitting_top = 419.704 # ML033530020 Fig 2-7
fuel_Rod_top = 419.704 # ML033530020 Fig 2-7
# RCCAs (0 steps withdraw, i.e., fully inserted)
rcca_Rod_bot = 39.9580 # ML033530020 Fig 2-8
rcca_LowerFitting_bot = 39.9580 # ML033530020 Fig 2-8
rcca_LowerFitting_top = 41.8280 # ML033530020 Fig 2-8
rcca_AIC_bot = 41.8280 # ML033530020 Fig 2-8
rcca_AIC_top = 143.428 # ML033530020 Fig 2-8
rcca_B4C_bot = 143.428 # ML033530020 Fig 2-8
rcca_B4C_top = 402.508 # ML033530020 Fig 2-8
rcca_Spacer_bot = 402.508 # ML033530020 Fig 2-8
rcca_Spacer_top = 403.778 # ML033530020 Fig 2-8
rcca_Plenum_bot = 403.778 # ML033530020 Fig 2-8
rcca_Plenum_top = 415.558 # ML033530020 Fig 2-8
rcca_Rod_top = 460.000 # same as struct_HighestExtent
rcca_StepWidth = 1.58193 # Active height divided into 228 steps
# BPRAs
bpra_Rod_bot = 38.6600 # ML033530020 Fig 2-9
bpra_LowerFitting_bot = 38.6600 # ML033530020 Fig 2-9
bpra_LowerFitting_top = 40.5580 # ML033530020 Fig 2-9
bpra_Active_bot = 40.5580 # ML033530020 Fig 2-9
bpra_Active_top = 401.238 # ML033530020 Fig 2-9
bpra_Plenum_bot = 401.238 # ML033530020 Fig 2-9
bpra_Plenum_top = 421.532 # ML033530020 Fig 2-9
bpra_Rod_top = 431.876 # same as struct_UpperNozzle_top
# Guide Tube
gt_Rod_bot = 35.0000 # same as fuel_Rod_bot
gt_Dashpot_bot = 35.0000 #
gt_Dashpot_top = 39.9580 # same as rcca_Rod_bot for full insertion
gt_Upper_bot = 39.9580 #
gt_Upper_top = 423.049 # same as struct_UpperNozzle_bot
gt_Rod_top = 423.049 #
# Intrument Tube
instr_Rod_bot = 35.0000 # same as fuel_Rod_bot
instr_Rod_top = 423.049 # same as struct_UpperNozzle_bot
# Grid Spacers (centers provided by utiliy) (heights 1.65 top/bottom, 2.25 intermediate)
grid1_bot = 37.1621 #
grid1_top = 40.5200 #
grid2_bot = 98.0250 #
grid2_top = 103.740 #
grid3_bot = 150.222 #
grid3_top = 155.937 #
grid4_bot = 202.419 #
grid4_top = 208.134 #
grid5_bot = 254.616 #
grid5_top = 260.331 #
grid6_bot = 306.813 #
grid6_top = 312.528 #
grid7_bot = 359.010 #
grid7_top = 364.725 #
grid8_bot = 411.806 #
grid8_top = 415.164 #
# data for nozzle and support plate region
n_nozzle_pins = 264 # number of pins
# volume fractions from ML033530020 (table 2-3)
nozzle_water_vol_frac = 0.8280 # water volume fraction
nozzle_water_vol_frac = 0.8280 # water volume fraction
nozzle_ss_vol_frac = 0.1720 # stainless steel volume fraction
## -- axials copied straight from rod_axials.ods -->

View file

@ -57,22 +57,23 @@ class Core(object):
'J___1', 'J___2', 'J___3', 'J___8', 'J___9', 'K__15', 'K__14', 'K__13',
'K__12', 'K__11', 'K__10']
def __init__(self, pincells, assemblies, baffle):
def __init__(self, pincells, assemblies, baffle, is_symmetric=False):
""" Creates BEAVRS core lattice universe """
self.pins = pincells
self.assem = assemblies
self.baffle = baffle
self.is_symmetric = is_symmetric
self._set_enrichment_positions()
self._set_instrument_tube_positions()
self._set_bpra_positions()
self._set_rcca_positions()
self._make_core_universe()
def _set_enrichment_positions(self):
""" Sets the specification for BEAVRS assembly enrichment positions """
self.enr_positions ={
'L___1': '3.1%', 'K___1': '3.1%', 'J___1': '3.1%', 'H___1': '3.1%', 'G___1': '3.1%', 'F___1': '3.1%', 'E___1': '3.1%',
'N___2': '3.1%', 'M___2': '3.1%', 'L___2': '3.1%', 'K___2': '1.6%', 'J___2': '3.1%', 'H___2': '1.6%', 'G___2': '3.1%', 'F___2': '1.6%', 'E___2': '3.1%', 'D___2': '3.1%', 'C___2': '3.1%',
@ -116,7 +117,7 @@ class Core(object):
def _set_bpra_positions(self):
""" Sets the specification for BEAVRS BPRA positions """
self.ba_positions = {
'K___1': '6S', 'H___1': '6S', 'F___1': '6S',
'L___2': '16', 'J___2': '20', 'G___2': '20', 'E___2': '16',
@ -137,7 +138,7 @@ class Core(object):
def _set_rcca_positions(self):
""" Sets the specification for BEAVRS RCCA positions """
self.rcca_positions = {
'M___2': 'SA', 'K___2': 'B', 'H___2': 'C', 'F___2': 'B', 'D___2': 'SA',
'L___3': 'SD', 'J___3': 'SB', 'G___3': 'SB', 'E___3': 'SC',
@ -172,12 +173,15 @@ class Core(object):
ba = "RCCA {0}".format(self.rcca_positions[pos])
else:
ba = 'no BAs'
if pos in self.instr_positions:
instr = 'instr'
else:
if self.is_symmetric:
instr = 'no instr'
else:
if pos in self.instr_positions:
instr = 'instr'
else:
instr = 'no instr'
lattice.setPosition(pos, self.assem.u_fuel[enr][ba][instr])
lattice.finalize()
self.u_coreLattice = lattice

View file

@ -18,7 +18,7 @@ class TemplatedLattice(openmc.RectLattice):
def setTemplate(self, template):
""" Set the lattice template
:param template:
"""
self.template = template
@ -26,13 +26,13 @@ class TemplatedLattice(openmc.RectLattice):
def setPosition(self, key, univ):
"""Set an individual position in the lattice"""
self.positions[key] = univ
def updatePositions(self, univs):
"""Update multiple positions in the lattice with a dictionary"""
self.positions.update(univs)
def finalize(self):
if self.template == []:
raise Exception("No template set for:\n{0}".format(self))
@ -54,14 +54,14 @@ _created_cells = {}
class InfinitePinCell(openmc.Universe):
""" Class for creating a simple pincell universe infinite in the z direction
InfinitePinCells consist of a set of radii and materials that define rings.
This class provides an easy way to wrap a pincell inside additional rings, or
a square grid around the outside.
"""
def __init__(self, *args, **kwargs):
""" Create a new InfinitePinCell
"""
@ -74,19 +74,19 @@ class InfinitePinCell(openmc.Universe):
def add_ring(self, fill, surf, box=False, rot=None):
""" Adds a ring to the pincell
Pincells must be built from the inside out. Materials for new rings are from
the surface of the previous ring to the provided new surface.
If the ring we want to add is a box, surf should be a rectangular prism.
It's up to the user to check for overlapping cell definitions.
:param fill: material or filling universe for new ring
:param surf: outer surface of new ring (or a rectangular region)
:param box: whether or not we're adding a boxy ring (e.g. for grids)
:param rot: openmc rotation string for filled cells
"""
self.radii.append(surf)
self.box.append(box)
@ -195,12 +195,12 @@ class InfinitePinCell(openmc.Universe):
class AxialPinCell(openmc.Universe):
""" Class for containing a complete axial description of a pincell
AxialPinCells consist of a set of InfinitePincells and the axial planes that
define the axial boundaries of each. They also allow for a fully-constructed
pincell to be "wrapped" by another pincell, e.g., pincells containing grids or
guide tubes.
"""
def __init__(self, *args, **kwargs):
@ -214,11 +214,11 @@ class AxialPinCell(openmc.Universe):
def add_axial_section(self, axial_plane, pincell):
""" Adds an axial section to the stack
Stacks must be built from the bottom-up. Each new section goes from the
previous axial_plane to the given axial_plane (or from infinity to the
given plane if it's the first section added).
It's up to the user to ensure that all planes are z-planes, and that
sections are added in the correct order.
@ -235,9 +235,9 @@ class AxialPinCell(openmc.Universe):
def add_last_axial_section(self, pincell):
""" Adds the last axial section to the top of the stack
:param pincell: InfinitePincell or material that goes to infinity at the top
"""
self.pincells.append(pincell)
if isinstance(pincell, InfinitePinCell):
@ -265,7 +265,7 @@ class AxialPinCell(openmc.Universe):
def add_wrapper(self, wrapper, surf=None):
""" Adds a pincell to wrap the height, returning a new InfinitePinCell
This should only be called AFTER all axial sections are added.
If the splitting surface is not given, this function will use the outer-most
@ -306,7 +306,7 @@ class AxialPinCell(openmc.Universe):
# Fill the outermost ring with the wrapping universe
new_pin.add_last_ring(wrapper)
_created_cells[new_name] = new_pin
return new_pin
@ -321,7 +321,7 @@ class AxialPinCell(openmc.Universe):
for pin in self.pincells:
if isinstance(pin, InfinitePinCell) and not pin.finalized:
pin.finalize()
# Instantiate the axial cells
for i, (pin, plane) in enumerate(zip(self.pincells, self.axials)):
@ -342,8 +342,8 @@ class AxialPinCell(openmc.Universe):
label = "{0} axial top: {1}".format(self.name, self.pincells[-1].name)
cell = openmc.Cell(name=label, fill=self.pincells[-1])
cell.region = +self.axials[-1]
self.add_cell(cell)
self.finalized = True

View file

@ -147,7 +147,7 @@ class Pincells(object):
self.u_gridsleeve.add_axial_section(self.s_struct_upperNozzle_top, self.mats['Water SPN'])
self.u_gridsleeve.add_last_axial_section(self.mats['Borated Water'])
self.u_gridsleeve.finalize()
def _add_fuel_pincells(self):
""" Adds BEAVRS fuel pincells """
@ -173,7 +173,7 @@ class Pincells(object):
self.s_fuel_upperFitting_top = openmc.ZPlane(name='Fuel upper fitting top', z0=c.fuel_UpperFitting_top)
# Fuel pincell universes
self.u_fuel_active_pin = {}
for enr in self.enrichments:
self.u_fuel_active_pin[enr] = InfinitePinCell(name='Fuel rod active region - {0} enr'.format(enr))
@ -207,7 +207,7 @@ class Pincells(object):
def _add_guide_tube_pincells(self):
""" Adds BEAVRS guide tube pincells """
# GT radial surfaces
self.s_gt_IR = openmc.ZCylinder(name='Guide tube IR', R=c.guideTubeIR)
@ -346,7 +346,7 @@ class Pincells(object):
def _add_rcca_pincells(self):
""" Adds BEAVRS RCCA pincells """
# RCCA rod radial surfaces
self.s_rcca_clad_IR = openmc.ZCylinder(name='RCCA rod clad IR', R=c.rcca_clad_IR)
@ -364,7 +364,7 @@ class Pincells(object):
self.s_rcca_b4c_top = {}
self.s_rcca_spacer_top = {}
self.s_rcca_plenum_top = {}
for b in c.rcca_banks:
for b in sorted(c.rcca_banks):
d = c.rcca_bank_steps_withdrawn[b]*c.rcca_StepWidth
self.s_rcca_rod_bot[b] = openmc.ZPlane(name='Bottom of RCCA rod bank {0}'.format(b), z0=c.rcca_Rod_bot + d)
self.s_rcca_lowerFitting_top[b] = openmc.ZPlane(name='Top of RCCA rod lower fitting bank {0}'.format(b), z0=c.rcca_LowerFitting_top + d)
@ -386,23 +386,23 @@ class Pincells(object):
self.u_rcca_aic.add_ring(self.mats['Air'], self.s_rcca_clad_IR)
self.u_rcca_aic.add_last_ring( self.mats['Zircaloy 4'])
self.u_rcca_aic.finalize()
self.u_rcca_b4c = InfinitePinCell(name='RCCA B4C')
self.u_rcca_b4c.add_ring(self.mats['B4C'], self.s_rcca_b4c_OR)
self.u_rcca_b4c.add_ring(self.mats['Air'], self.s_rcca_clad_IR)
self.u_rcca_b4c.add_last_ring(self.mats['Zircaloy 4'])
self.u_rcca_b4c.finalize()
self.u_rcca_spacer = InfinitePinCell(name='RCCA Spacer')
self.u_rcca_spacer.add_ring(self.mats['SS304'], self.s_rcca_spacer_OR)
self.u_rcca_spacer.add_ring(self.mats['Air'], self.s_rcca_clad_IR)
self.u_rcca_spacer.add_last_ring(self.mats['Zircaloy 4'])
self.u_rcca_spacer.finalize()
# RCCA rod axial stack
self.u_rcca = {}
for b in c.rcca_banks:
for b in sorted(c.rcca_banks):
self.u_rcca[b] = AxialPinCell(name='RCCA bank {0}'.format(b))
self.u_rcca[b].add_axial_section(self.s_struct_supportPlate_bot, self.mats['Borated Water'])
self.u_rcca[b].add_axial_section(self.s_struct_lowerNozzle_top, self.mats['Water SPN'])

View file

@ -10,14 +10,14 @@ import openmc
class UniverseZero(openmc.Universe):
def __init__(self, core, mats):
def __init__(self, core, mats, is_2d=False):
""" Creates BEAVRS main universe """
super(UniverseZero, self).__init__(name='Main BEAVRS universe', universe_id=0)
self.core = core
self.mats = mats
self.is_2d = is_2d
self._add_outer_rings()
self._add_shield_panels()
self._add_core_barrel()
@ -27,26 +27,31 @@ class UniverseZero(openmc.Universe):
def _add_outer_rings(self):
""" Adds BEAVRS RPV, liner, and downcomer """
self.s_upperBound = openmc.ZPlane(name='Highest Extent', z0=c.struct_HighestExtent, boundary_type='vacuum')
self.s_lowerBound = openmc.ZPlane(name='Lowest Extent', z0=c.struct_LowestExtent, boundary_type='vacuum')
# Change z-dimension based on whether 2D or 3D problem
if self.is_2d:
self.s_upperBound = openmc.ZPlane(name='Highest Extent', z0=c.struct_HighestExtent_2d, boundary_type='reflective')
self.s_lowerBound = openmc.ZPlane(name='Lowest Extent', z0=c.struct_LowestExtent_2d, boundary_type='reflective')
else:
self.s_upperBound = openmc.ZPlane(name='Highest Extent', z0=c.struct_HighestExtent, boundary_type='vacuum')
self.s_lowerBound = openmc.ZPlane(name='Lowest Extent', z0=c.struct_LowestExtent, boundary_type='vacuum')
# RPV
self.s_RPVOR = openmc.ZCylinder(name='RPV OR', R=c.rpvOR, boundary_type='vacuum')
self.s_RPVIR = openmc.ZCylinder(name='RPV IR', R=c.rpvIR)
self.c_RPV = openmc.Cell(name="RPV", fill=self.mats['Carbon Steel'])
self.c_RPV.region = (-self.s_RPVOR & +self.s_RPVIR &
-self.s_upperBound & +self.s_lowerBound)
# RPV liner
self.s_linerIR = openmc.ZCylinder(name='RPV Liner IR', R=c.linerIR)
self.c_liner = openmc.Cell(name="RPV Liner", fill=self.mats['SS304'])
self.c_liner.region = (-self.s_RPVIR & +self.s_linerIR &
-self.s_upperBound & +self.s_lowerBound)
# Downcomer
self.s_neutronShieldOR = openmc.ZCylinder(name='Shield Panel OR', R=c.neutronShieldOR)
self.c_downcomer = openmc.Cell(name="Downcomer", fill=self.mats['Borated Water'])
self.c_downcomer.region = (-self.s_linerIR & +self.s_neutronShieldOR &
@ -62,33 +67,33 @@ class UniverseZero(openmc.Universe):
self.s_ns_NWtop_SEbot = openmc.Plane(name='Shield Panel NWtop/SEbot', **c.neutronShield_NWtop_SEbot)
self.s_ns_NEbot_SWtop = openmc.Plane(name='Shield Panel NEbot/SWtop', **c.neutronShield_NEbot_SWtop)
self.s_ns_NEtop_SWbot = openmc.Plane(name='Shield Panel NEtop/SWbot', **c.neutronShield_NEtop_SWbot)
self.c_shieldPanels = []
self.c_sp_NW = openmc.Cell(name='NW Shield Panel', fill=self.mats['SS304'])
self.c_sp_NW.region = (+self.s_neutronShieldIR & -self.s_neutronShieldOR &
+self.s_ns_NWbot_SEtop & -self.s_ns_NWtop_SEbot &
-self.s_upperBound & +self.s_lowerBound)
self.c_shieldPanels.append(self.c_sp_NW)
self.c_sp_SE = openmc.Cell(name='SE Shield Panel', fill=self.mats['SS304'])
self.c_sp_SE.region = (+self.s_neutronShieldIR & -self.s_neutronShieldOR &
-self.s_ns_NWbot_SEtop & +self.s_ns_NWtop_SEbot &
-self.s_upperBound & +self.s_lowerBound)
self.c_shieldPanels.append(self.c_sp_SE)
self.c_sp_NE = openmc.Cell(name='NE Shield Panel', fill=self.mats['SS304'])
self.c_sp_NE.region = (+self.s_neutronShieldIR & -self.s_neutronShieldOR &
+self.s_ns_NEbot_SWtop & -self.s_ns_NEtop_SWbot &
-self.s_upperBound & +self.s_lowerBound)
self.c_shieldPanels.append(self.c_sp_NE)
self.c_sp_SW = openmc.Cell(name='SW Shield Panel', fill=self.mats['SS304'])
self.c_sp_SW.region = (+self.s_neutronShieldIR & -self.s_neutronShieldOR &
-self.s_ns_NEbot_SWtop & +self.s_ns_NEtop_SWbot &
-self.s_upperBound & +self.s_lowerBound)
self.c_shieldPanels.append(self.c_sp_SW)
self.c_sp_N = openmc.Cell(name='N Shield Water', fill=self.mats['Borated Water'])
self.c_sp_N.region = (+self.s_neutronShieldIR & -self.s_neutronShieldOR &
+self.s_ns_NWtop_SEbot & -self.s_ns_NEtop_SWbot &
@ -100,19 +105,19 @@ class UniverseZero(openmc.Universe):
+self.s_ns_NEtop_SWbot & -self.s_ns_NWtop_SEbot &
-self.s_upperBound & +self.s_lowerBound)
self.c_shieldPanels.append(self.c_sp_S)
self.c_sp_E = openmc.Cell(name='E Shield Water', fill=self.mats['Borated Water'])
self.c_sp_E.region = (+self.s_neutronShieldIR & -self.s_neutronShieldOR &
+self.s_ns_NWbot_SEtop & +self.s_ns_NEbot_SWtop &
-self.s_upperBound & +self.s_lowerBound)
self.c_shieldPanels.append(self.c_sp_E)
self.c_sp_W = openmc.Cell(name='W Shield Water', fill=self.mats['Borated Water'])
self.c_sp_W.region = (+self.s_neutronShieldIR & -self.s_neutronShieldOR &
-self.s_ns_NWbot_SEtop & -self.s_ns_NEbot_SWtop &
-self.s_upperBound & +self.s_lowerBound)
self.c_shieldPanels.append(self.c_sp_W)
self.s_coreBarrelOR = openmc.ZCylinder(name='Core Barrel OR', R=c.coreBarrelOR)
self.c_sp_inner = openmc.Cell(name='Water between barrel and shield', fill=self.mats['Borated Water'])
self.c_sp_inner.region = (+self.s_coreBarrelOR & -self.s_neutronShieldIR &
@ -122,14 +127,14 @@ class UniverseZero(openmc.Universe):
def _add_core_barrel(self):
""" Adds BEAVRS core barrel and core lattice """
# Core barrel
self.s_coreBarrelIR = openmc.ZCylinder(name='Core Barrel IR', R=c.coreBarrelIR)
self.c_coreBarrel = openmc.Cell(name="Core Barrel", fill=self.mats['SS304'])
self.c_coreBarrel.region = (-self.s_coreBarrelOR & +self.s_coreBarrelIR &
-self.s_upperBound & +self.s_lowerBound)
# Core lattice
self.c_core = openmc.Cell(name="Core lattice", fill=self.core.u_coreLattice)
@ -139,10 +144,40 @@ class UniverseZero(openmc.Universe):
def _create_main_universe(self):
""" Creates the main BEAVRS universe """
self.add_cell(self.c_RPV)
self.add_cell(self.c_liner)
self.add_cell(self.c_downcomer)
for cell in self.c_shieldPanels: self.add_cell(cell)
self.add_cell(self.c_coreBarrel)
self.add_cell(self.c_core)
# For 3D problem, add full core to main universe
if not self.is_2d:
self.add_cell(self.c_RPV)
self.add_cell(self.c_liner)
self.add_cell(self.c_downcomer)
for cell in self.c_shieldPanels: self.add_cell(cell)
self.add_cell(self.c_coreBarrel)
self.add_cell(self.c_core)
# For 2D problem, create core universe separately and set bounding box as main universe
else:
# Define core universe that will be fill of main universe
self.core_univ = openmc.Universe(name='BEAVRS core universe')
self.core_univ.add_cell(self.c_RPV)
self.core_univ.add_cell(self.c_liner)
self.core_univ.add_cell(self.c_downcomer)
for cell in self.c_shieldPanels: self.core_univ.add_cell(cell)
self.core_univ.add_cell(self.c_coreBarrel)
self.core_univ.add_cell(self.c_core)
# Define boundaries of bounding box
outer_bound = 8.5*c.latticePitch
self.s_leftBound = openmc.XPlane(name='Left Box', x0=-outer_bound, boundary_type='vacuum')
self.s_rightBound = openmc.XPlane(name='Right Box', x0=outer_bound, boundary_type='vacuum')
self.s_backBound = openmc.YPlane(name='Back Box', y0=-outer_bound, boundary_type='vacuum')
self.s_frontBound = openmc.YPlane(name='Front Box', y0=outer_bound, boundary_type='vacuum')
# Bounding box
self.c_boundbox = openmc.Cell(name="Bounding box", fill=self.core_univ)
self.c_boundbox.region = \
(+self.s_leftBound & -self.s_rightBound &
+self.s_backBound & -self.s_frontBound &
-self.s_upperBound & +self.s_lowerBound)
self.add_cell(self.c_boundbox)

View file

@ -2,13 +2,27 @@
import os
from beavrs.builder import BEAVRS
from optparse import OptionParser
try:
os.mkdir('build')
except OSError: pass
os.chdir('build')
b = BEAVRS()
usage = """usage: %prog [options]"""
p = OptionParser(usage=usage)
p.add_option('-d', '--2d', action='store_true', dest='is_2d',
default=False, help='Create 2D BEAVRS input files,' \
+ ' 3D by default')
p.add_option('-s', '--symmetric', action='store_true', dest='is_symmetric',
default=False, help='Create octant-symmetric input files,' \
+ ' not symmetric by default')
(options, args) = p.parse_args()
if not len(args) == 0:
p.print_help()
b = BEAVRS(is_symmetric=options.is_symmetric, is_2d=options.is_2d)
b.write_openmc_geometry()
b.write_openmc_materials()
b.write_openmc_plots()