From 0b3546f23a8f04ab5c7531204415db22d4ffd0fa Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 19 Dec 2019 15:00:03 -0600 Subject: [PATCH 1/7] Remove assemblies with burnable absorber pins --- smr/smr/assemblies.py | 157 ---------------------------------- smr/smr/core.py | 34 ++++---- smr/smr/pins.py | 193 ------------------------------------------ 3 files changed, 17 insertions(+), 367 deletions(-) diff --git a/smr/smr/assemblies.py b/smr/smr/assemblies.py index 2fffb51..b13d0f9 100644 --- a/smr/smr/assemblies.py +++ b/smr/smr/assemblies.py @@ -147,7 +147,6 @@ def assembly_universes(ring_radii, num_axial, depleted): # commonly needed universes gtu = pins['GT empty stack'] gti = pins['GT empty instr'] - bas = pins['BA stack'] ins = pins['IT stack'] crA = pins['GT CR bank A'] crB = pins['GT CR bank B'] @@ -232,33 +231,6 @@ def assembly_universes(ring_radii, num_axial, depleted): univs['Assembly (2.4%) CR D' + comment] = \ make_assembly('Assembly (2.4%) CR D' + comment, universes) - # WITH 12 BURNABLE ABSORBERS - universes = np.empty((17,17), dtype=openmc.Universe) - universes[:,:] = pins['Fuel (2.4%) stack'] - universes[nonfuel_y, nonfuel_x] = [ bas, gtu, bas, - bas, bas, - bas, gtu, gtu, gtu, bas, - gtu, gtu, cent, gtu, gtu, - bas, gtu, gtu, gtu, bas, - bas, bas, - bas, gtu, bas ] - univs['Assembly (2.4%) 12BA' + comment] = \ - make_assembly('Assembly (2.4%) 12BA' + comment, universes) - - # WITH 16 BURNABLE ABSORBERS - universes = np.empty((17,17), dtype=openmc.Universe) - universes[:,:] = pins['Fuel (2.4%) stack'] - universes[nonfuel_y, nonfuel_x] = [ bas, bas, bas, - bas, bas, - bas, gtu, gtu, gtu, bas, - bas, gtu, cent, gtu, bas, - bas, gtu, gtu, gtu, bas, - bas, bas, - bas, bas, bas ] - univs['Assembly (2.4%) 16BA' + comment] = \ - make_assembly('Assembly (2.4%) 16BA' + comment, universes) - - #### 3.1% ENRICHED ASSEMBLIES for cent, comment in [(gti, ''), (ins, ' instr')]: @@ -289,134 +261,5 @@ def assembly_universes(ring_radii, num_axial, depleted): univs['Assembly (3.1%) CR SA' + comment] = \ make_assembly('Assembly (3.1%) CR SA' + comment, universes) - # WITH 20 BURNABLE ABSORBERS - universes = np.empty((17,17), dtype=openmc.Universe) - universes[:,:] = pins['Fuel (3.1%) stack'] - universes[nonfuel_y, nonfuel_x] = [ bas, bas, bas, - bas, bas, - bas, bas, gtu, bas, bas, - bas, gtu, cent, gtu, bas, - bas, bas, gtu, bas, bas, - bas, bas, - bas, bas, bas ] - univs['Assembly (3.1%) 20BA' + comment] = \ - make_assembly('Assembly (3.1%) 20BA' + comment, universes) - - # WITH 16 BURNABLE ABSORBERS - universes = np.empty((17,17), dtype=openmc.Universe) - universes[:,:] = pins['Fuel (3.1%) stack'] - universes[nonfuel_y, nonfuel_x] = [ bas, bas, bas, - bas, bas, - bas, gtu, gtu, gtu, bas, - bas, gtu, cent, gtu, bas, - bas, gtu, gtu, gtu, bas, - bas, bas, - bas, bas, bas ] - univs['Assembly (3.1%) 16BA' + comment] = \ - make_assembly('Assembly (3.1%) 16BA' + comment, universes) - - # WITH 15 BURNABLE ABSORBERS NW - universes = np.empty((17,17), dtype=openmc.Universe) - universes[:,:] = pins['Fuel (3.1%) stack'] - universes[nonfuel_y, nonfuel_x] = [ gtu, gtu, gtu, - gtu, gtu, - gtu, bas, bas, bas, bas, - gtu, bas, cent, bas, bas, - gtu, bas, bas, bas, bas, - gtu, bas, - bas, bas, bas ] - univs['Assembly (3.1%) 15BANW' + comment] = \ - make_assembly('Assembly (3.1%) 15BANW' + comment, universes) - - # WITH 15 BURNABLE ABSORBERS NE - universes = np.empty((17,17), dtype=openmc.Universe) - universes[:,:] = pins['Fuel (3.1%) stack'] - universes[nonfuel_y, nonfuel_x] = [ gtu, gtu, gtu, - gtu, gtu, - bas, bas, bas, bas, gtu, - bas, bas, cent, bas, gtu, - bas, bas, bas, bas, gtu, - bas, gtu, - bas, bas, bas ] - univs['Assembly (3.1%) 15BANE' + comment] = \ - make_assembly('Assembly (3.1%) 15BANE' + comment, universes) - - # WITH 15 BURNABLE ABSORBERS SW - universes = np.empty((17,17), dtype=openmc.Universe) - universes[:,:] = pins['Fuel (3.1%) stack'] - universes[nonfuel_y, nonfuel_x] = [ bas, bas, bas, - gtu, bas, - gtu, bas, bas, bas, bas, - gtu, bas, cent, bas, bas, - gtu, bas, bas, bas, bas, - gtu, gtu, - gtu, gtu, gtu ] - univs['Assembly (3.1%) 15BASW' + comment] = \ - make_assembly('Assembly (3.1%) 15BASW' + comment, universes) - - # WITH 15 BURNABLE ABSORBERS SE - universes = np.empty((17,17), dtype=openmc.Universe) - universes[:,:] = pins['Fuel (3.1%) stack'] - universes[nonfuel_y, nonfuel_x] = [ bas, bas, bas, - bas, gtu, - bas, bas, bas, bas, gtu, - bas, bas, cent, bas, gtu, - bas, bas, bas, bas, gtu, - gtu, gtu, - gtu, gtu, gtu ] - univs['Assembly (3.1%) 15BASE' + comment] = \ - make_assembly('Assembly (3.1%) 15BASE' + comment, universes) - - # WITH 6 BURNABLE ABSORBERS N - universes = np.empty((17,17), dtype=openmc.Universe) - universes[:,:] = pins['Fuel (3.1%) stack'] - universes[nonfuel_y, nonfuel_x] = [ gtu, gtu, gtu, - gtu, gtu, - gtu, gtu, gtu, gtu, gtu, - gtu, gtu, cent, gtu, gtu, - bas, gtu, gtu, gtu, bas, - bas, bas, - bas, gtu, bas ] - univs['Assembly (3.1%) 6BAN' + comment] = \ - make_assembly('Assembly (3.1%) 6BAN' + comment, universes) - - # WITH 6 BURNABLE ABSORBERS S - universes = np.empty((17,17), dtype=openmc.Universe) - universes[:,:] = pins['Fuel (3.1%) stack'] - universes[nonfuel_y, nonfuel_x] = [ bas, gtu, bas, - bas, bas, - bas, gtu, gtu, gtu, bas, - gtu, gtu, cent, gtu, gtu, - gtu, gtu, gtu, gtu, gtu, - gtu, gtu, - gtu, gtu, gtu ] - univs['Assembly (3.1%) 6BAS' + comment] = \ - make_assembly('Assembly (3.1%) 6BAS' + comment, universes) - - # WITH 6 BURNABLE ABSORBERS W - universes = np.empty((17,17), dtype=openmc.Universe) - universes[:,:] = pins['Fuel (3.1%) stack'] - universes[nonfuel_y, nonfuel_x] = [ gtu, gtu, bas, - gtu, bas, - gtu, gtu, gtu, gtu, bas, - gtu, gtu, cent, gtu, gtu, - gtu, gtu, gtu, gtu, bas, - gtu, bas, - gtu, gtu, bas ] - univs['Assembly (3.1%) 6BAW' + comment] = \ - make_assembly('Assembly (3.1%) 6BAW' + comment, universes) - - # WITH 6 BURNABLE ABSORBERS E - universes = np.empty((17,17), dtype=openmc.Universe) - universes[:,:] = pins['Fuel (3.1%) stack'] - universes[nonfuel_y, nonfuel_x] = [ bas, gtu, gtu, - bas, gtu, - bas, gtu, gtu, gtu, gtu, - gtu, gtu, cent, gtu, gtu, - bas, gtu, gtu, gtu, gtu, - bas, gtu, - bas, gtu, gtu ] - univs['Assembly (3.1%) 6BAE' + comment] = \ - make_assembly('Assembly (3.1%) 6BAE' + comment, universes) return univs diff --git a/smr/smr/core.py b/smr/smr/core.py index c150e06..2e75dfe 100644 --- a/smr/smr/core.py +++ b/smr/smr/core.py @@ -46,9 +46,9 @@ def core_geometry(ring_radii, num_axial, depleted): universes[1, 1] = reflector['1,1'] universes[1, 2] = reflector['NW'] - universes[1, 3] = assembly['Assembly (3.1%) instr'] + universes[1, 3] = assembly['Assembly (3.1%)'] universes[1, 4] = assembly['Assembly (2.4%) CR D'] - universes[1, 5] = assembly['Assembly (3.1%) instr'] + universes[1, 5] = assembly['Assembly (3.1%)'] universes[1, 6] = reflector['NE'] universes[1, 7] = reflector['1,7'] @@ -56,47 +56,47 @@ def core_geometry(ring_radii, num_axial, depleted): universes[2, 1] = reflector['NW'] universes[2, 2] = assembly['Assembly (3.1%) instr'] universes[2, 3] = assembly['Assembly (2.4%) CR D'] - universes[2, 4] = assembly['Assembly (3.1%) 16BA'] + universes[2, 4] = assembly['Assembly (3.1%) instr'] universes[2, 5] = assembly['Assembly (2.4%) CR D'] universes[2, 6] = assembly['Assembly (3.1%) instr'] universes[2, 7] = reflector['NE'] universes[2, 8] = reflector['2,8'] universes[3, 0] = reflector['3,0'] - universes[3, 1] = assembly['Assembly (3.1%) instr'] + universes[3, 1] = assembly['Assembly (3.1%)'] universes[3, 2] = assembly['Assembly (2.4%) CR D'] - universes[3, 3] = assembly['Assembly (3.1%) 16BA'] + universes[3, 3] = assembly['Assembly (3.1%) instr'] universes[3, 4] = assembly['Assembly (2.4%) CR D'] - universes[3, 5] = assembly['Assembly (3.1%) 16BA'] + universes[3, 5] = assembly['Assembly (3.1%) instr'] universes[3, 6] = assembly['Assembly (2.4%) CR D'] - universes[3, 7] = assembly['Assembly (3.1%) instr'] + universes[3, 7] = assembly['Assembly (3.1%)'] universes[3, 8] = reflector['3,8'] universes[4, 0] = reflector['4,0'] universes[4, 1] = assembly['Assembly (2.4%) CR D'] - universes[4, 2] = assembly['Assembly (3.1%) 16BA'] + universes[4, 2] = assembly['Assembly (3.1%) instr'] universes[4, 3] = assembly['Assembly (2.4%) CR D'] - universes[4, 4] = assembly['Assembly (1.6%) instr'] + universes[4, 4] = assembly['Assembly (1.6%)'] universes[4, 5] = assembly['Assembly (2.4%) CR D'] - universes[4, 6] = assembly['Assembly (3.1%) 16BA'] + universes[4, 6] = assembly['Assembly (3.1%) instr'] universes[4, 7] = assembly['Assembly (2.4%) CR D'] universes[4, 8] = reflector['4,8'] universes[5, 0] = reflector['5,0'] - universes[5, 1] = assembly['Assembly (3.1%) instr'] + universes[5, 1] = assembly['Assembly (3.1%)'] universes[5, 2] = assembly['Assembly (2.4%) CR D'] - universes[5, 3] = assembly['Assembly (3.1%) 16BA'] + universes[5, 3] = assembly['Assembly (3.1%) instr'] universes[5, 4] = assembly['Assembly (2.4%) CR D'] - universes[5, 5] = assembly['Assembly (3.1%) 16BA'] + universes[5, 5] = assembly['Assembly (3.1%) instr'] universes[5, 6] = assembly['Assembly (2.4%) CR D'] - universes[5, 7] = assembly['Assembly (3.1%) instr'] + universes[5, 7] = assembly['Assembly (3.1%)'] universes[5, 8] = reflector['5,8'] universes[6, 0] = reflector['6,0'] universes[6, 1] = reflector['SW'] universes[6, 2] = assembly['Assembly (3.1%) instr'] universes[6, 3] = assembly['Assembly (2.4%) CR D'] - universes[6, 4] = assembly['Assembly (3.1%) 16BA'] + universes[6, 4] = assembly['Assembly (3.1%) instr'] universes[6, 5] = assembly['Assembly (2.4%) CR D'] universes[6, 6] = assembly['Assembly (3.1%) instr'] universes[6, 7] = reflector['SE'] @@ -104,9 +104,9 @@ def core_geometry(ring_radii, num_axial, depleted): universes[7, 1] = reflector['7,1'] universes[7, 2] = reflector['SW'] - universes[7, 3] = assembly['Assembly (3.1%) instr'] + universes[7, 3] = assembly['Assembly (3.1%)'] universes[7, 4] = assembly['Assembly (2.4%) CR D'] - universes[7, 5] = assembly['Assembly (3.1%) instr'] + universes[7, 5] = assembly['Assembly (3.1%)'] universes[7, 6] = reflector['SE'] universes[7, 7] = reflector['7,7'] diff --git a/smr/smr/pins.py b/smr/smr/pins.py index d804951..3966997 100644 --- a/smr/smr/pins.py +++ b/smr/smr/pins.py @@ -473,199 +473,6 @@ def pin_universes(ring_radii=None, num_axial=196, depleted=False): univs['GT CR bank {} dummy bare'.format(b)]]) - #### BURNABLE ABSORBER PIN CELLS - - univs['BA'] = make_pin( - 'BA', - surfaces=[surfs['BA IR 1'], - surfs['BA IR 2'], - surfs['BA IR 3'], - surfs['BA IR 4'], - surfs['BA IR 5'], - surfs['BA IR 6'], - surfs['BA IR 7'], - surfs['BA IR 8']], - materials=[mats['Air'], - mats['SS'], - mats['Air'], - mats['BSG'], - mats['Air'], - mats['SS'], - mats['H2O'], - mats['Zr'], - mats['H2O']]) - - univs['BA grid (bottom)'] = make_pin( - 'BA grid (bottom)', - surfaces=[surfs['BA IR 1'], - surfs['BA IR 2'], - surfs['BA IR 3'], - surfs['BA IR 4'], - surfs['BA IR 5'], - surfs['BA IR 6'], - surfs['BA IR 7'], - surfs['BA IR 8']], - materials=[mats['Air'], - mats['SS'], - mats['Air'], - mats['BSG'], - mats['Air'], - mats['SS'], - mats['H2O'], - mats['Zr'], - mats['H2O']], - grid='bottom') - - univs['BA grid (intermediate)'] = make_pin( - 'BA grid (intermediate)', - surfaces=[surfs['BA IR 1'], - surfs['BA IR 2'], - surfs['BA IR 3'], - surfs['BA IR 4'], - surfs['BA IR 5'], - surfs['BA IR 6'], - surfs['BA IR 7'], - surfs['BA IR 8']], - materials=[mats['Air'], - mats['SS'], - mats['Air'], - mats['BSG'], - mats['Air'], - mats['SS'], - mats['H2O'], - mats['Zr'], - mats['H2O']], - grid='intermediate') - - univs['BA dashpot'] = make_pin( - 'BA dashpot', - surfaces=[surfs['BA IR 1'], - surfs['BA IR 2'], - surfs['BA IR 3'], - surfs['BA IR 4'], - surfs['BA IR 5'], - surfs['BA IR 6'], - surfs['GT dashpot IR'], - surfs['GT dashpot OR']], - materials=[mats['Air'], - mats['SS'], - mats['Air'], - mats['BSG'], - mats['Air'], - mats['SS'], - mats['H2O'], - mats['Zr'], - mats['H2O']]) - - univs['BA dashpot grid (bottom)'] = make_pin( - 'BA dashpot grid (bottom)', - surfaces=[surfs['BA IR 1'], - surfs['BA IR 2'], - surfs['BA IR 3'], - surfs['BA IR 4'], - surfs['BA IR 5'], - surfs['BA IR 6'], - surfs['GT dashpot IR'], - surfs['GT dashpot OR']], - materials=[mats['Air'], - mats['SS'], - mats['Air'], - mats['BSG'], - mats['Air'], - mats['SS'], - mats['H2O'], - mats['Zr'], - mats['H2O']], - grid='bottom') - - univs['BA dashpot grid (intermediate)'] = make_pin( - 'BA dashpot grid (intermediate)', - surfaces=[surfs['BA IR 1'], - surfs['BA IR 2'], - surfs['BA IR 3'], - surfs['BA IR 4'], - surfs['BA IR 5'], - surfs['BA IR 6'], - surfs['GT dashpot IR'], - surfs['GT dashpot OR']], - materials=[mats['Air'], - mats['SS'], - mats['Air'], - mats['BSG'], - mats['Air'], - mats['SS'], - mats['H2O'], - mats['Zr'], - mats['H2O']], - grid='intermediate') - - univs['BA blank SS'] = make_pin( - 'BA blank SS', - surfaces=[surfs['BA IR 6'], - surfs['BA IR 7'], - surfs['BA IR 8']], - materials=[mats['SS'], - mats['H2O'], - mats['Zr'], - mats['H2O']]) - - univs['BA blank SS bare'] = make_pin( - 'BA blank SS bare', - surfaces=[surfs['BA IR 6']], - materials=[mats['SS'], - mats['H2O']]) - - stack_surfs_BA = [ - surfs['bot support plate'], - surfs['top support plate'], - surfs['top lower nozzle'], - surfs['top lower thimble'], - surfs['grid1bot'], - surfs['BA bot'], - surfs['grid1top'], - surfs['dashpot top'], - surfs['grid2bot'], - surfs['grid2top'], - surfs['grid3bot'], - surfs['grid3top'], - surfs['grid4bot'], - surfs['grid4top'], - surfs['top active core'], - surfs['grid5bot'], - surfs['grid5top'], - surfs['top pin plenum'], - surfs['top FR'], - surfs['bot upper nozzle'], - surfs['top upper nozzle']] - - # Stack all axial pieces of control rod tubes together for each bank - - univs['BA stack'] = make_stack( - 'BA stack', stack_surfs_BA, - universes=[univs['water pin'], - univs['water pin'], - univs['water pin'], - univs['GTd empty'], - univs['GTd empty'], - univs['GTd empty grid (bottom)'], - univs['BA dashpot grid (bottom)'], - univs['BA dashpot'], - univs['BA'], - univs['BA grid (intermediate)'], - univs['BA'], - univs['BA grid (intermediate)'], - univs['BA'], - univs['BA grid (intermediate)'], - univs['BA'], - univs['BA blank SS'], - univs['BA blank SS'], - univs['BA blank SS'], - univs['BA blank SS'], - univs['BA blank SS'], - univs['BA blank SS bare'], - univs['water pin']]) - - # Fuel pin cells univs['SS pin'] = make_pin( 'SS pin', From 6abc157770303149bbd8d0c1be45df27fe0b8d39 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 21 Jun 2021 11:58:42 +0700 Subject: [PATCH 2/7] Add script for building short full core, manually change lattice_pitch --- smr/build-core-short.py | 118 ++++++++++++++++++++++++++++++++++++++++ smr/smr/surfaces.py | 3 +- 2 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 smr/build-core-short.py diff --git a/smr/build-core-short.py b/smr/build-core-short.py new file mode 100644 index 0000000..5ed19b9 --- /dev/null +++ b/smr/build-core-short.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 + +import os +import shutil +import copy +import argparse +from math import pi +from pathlib import Path + +import numpy as np + +import openmc +from smr.materials import materials +from smr.plots import core_plots +from smr.surfaces import lattice_pitch, bottom_fuel_stack, top_active_core, \ + pellet_OR, surfs, pin_pitch +import smr.surfaces +import smr.pins +from smr.core import core_geometry +from smr import inlet_temperature + + +# Define command-line options +parser = argparse.ArgumentParser() +parser.add_argument('--multipole', action='store_true', + help='Use multipole cross sections') +parser.add_argument('--no-multipole', action='store_false', + help='Do not use multipole cross sections') +parser.add_argument('-a', '--axial', type=int, default=3, + help='Number of axial subdivisions in fuel') +parser.add_argument('-d', '--depleted', action='store_true', + help='Whether UO2 compositions should represent depleted fuel') +parser.add_argument('-o', '--output-dir', type=Path, default=None) +parser.set_defaults(multipole=True) +args = parser.parse_args() + +# Make directory for inputs +if args.output_dir is None: + if args.depleted: + directory = Path('core-short-depleted') + else: + directory = Path('core-short-fresh') +else: + directory = args.output_dir +directory.mkdir(exist_ok=True) + +# Modify fuel length +length = 3. * pin_pitch +smr.surfaces.active_fuel_length = length +smr.pins.top_active_core = length +surfs['top active core'].z0 = length + +# Change top and bottom of model to contain only fuel +surfs['lower bound'].z0 = 0.0 +surfs['lower bound'].boundary_type = 'reflective' +surfs['upper bound'].z0 = length +surfs['upper bound'].boundary_type = 'reflective' + +ring_radii = [0.1*pin_pitch, 0.2*pin_pitch] + +geometry = core_geometry(ring_radii, args.axial, args.depleted) + +h = length / args.axial +fuel_mats = {} + +fuel_volume = pi * pellet_OR**2 * h / (len(ring_radii) + 1) +for cell in geometry.get_all_cells().values(): + if cell.fill in materials: + # Determine volume of each fuel material + if 'UO2 Fuel' in cell.fill.name: + r_o = cell.region.bounding_box[1][0] + if r_o not in fuel_mats: + cell.fill = cell.fill.clone() + cell.fill.volume = fuel_volume + fuel_mats[r_o] = cell.fill + else: + cell.fill = fuel_mats[r_o] + else: + cell.fill.volume = 1.0 + + +#### Create OpenMC "materials.xml" file +all_materials = geometry.get_all_materials() +materials = openmc.Materials(all_materials.values()) +materials.export_to_xml(str(directory / 'materials.xml')) + + +#### Create OpenMC "geometry.xml" file +geometry.export_to_xml(str(directory / 'geometry.xml')) + + +#### Create OpenMC "settings.xml" file + +# Construct uniform initial source distribution over fissionable zones +lower_left = [-7.*lattice_pitch/2., -7.*lattice_pitch/2., bottom_fuel_stack] +upper_right = [+7.*lattice_pitch/2., +7.*lattice_pitch/2., top_active_core] +source = openmc.source.Source(space=openmc.stats.Box(lower_left, upper_right)) +source.space.only_fissionable = True + +settings = openmc.Settings() +settings.batches = 200 +settings.inactive = 100 +settings.particles = 10000 +settings.output = {'tallies': False, 'summary': False} +settings.source = source +settings.sourcepoint_write = False + +settings.temperature = { + 'default': inlet_temperature, + 'method': 'interpolation', + 'range': (300.0, 1500.0), +} +if args.multipole: + settings.temperature['multipole'] = True + settings.temperature['tolerance'] = 1000 + +settings.export_to_xml(str(directory / 'settings.xml')) + diff --git a/smr/smr/surfaces.py b/smr/smr/surfaces.py index b454c61..d91ec92 100644 --- a/smr/smr/surfaces.py +++ b/smr/smr/surfaces.py @@ -69,7 +69,8 @@ spacer_height = 1.750*INCHES # ML17013A274, Figure 4.2-7 # assembly parameters assembly_length = 95.89*INCHES # ML17013A274, Table 4.1-2 pin_pitch = 0.496*INCHES # ML17013A274, Table 4.1-2 -lattice_pitch = 8.466*INCHES # ML17013A274, Table 4.1-2 +#lattice_pitch = 8.466*INCHES # ML17013A274, Table 4.1-2 +lattice_pitch = 17*pin_pitch grid_strap_side = 21.47270 top_nozzle_height = 3.551*INCHES # ML17013A274, Figure 4.2-2 top_nozzle_width = 8.406*INCHES # ML17013A274, Figure 4.2-2 From 1713a4df1b49e09c4530e034946afa597c124a4c Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 26 Jul 2021 22:36:48 -0500 Subject: [PATCH 3/7] Fix volumes in fullcore short model --- smr/build-core-short.py | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/smr/build-core-short.py b/smr/build-core-short.py index 5ed19b9..2e3033f 100644 --- a/smr/build-core-short.py +++ b/smr/build-core-short.py @@ -4,7 +4,7 @@ import os import shutil import copy import argparse -from math import pi +from math import pi, isclose from pathlib import Path import numpy as np @@ -13,7 +13,7 @@ import openmc from smr.materials import materials from smr.plots import core_plots from smr.surfaces import lattice_pitch, bottom_fuel_stack, top_active_core, \ - pellet_OR, surfs, pin_pitch + pellet_OR, surfs, pin_pitch, clad_IR, clad_OR import smr.surfaces import smr.pins from smr.core import core_geometry @@ -63,18 +63,27 @@ geometry = core_geometry(ring_radii, args.axial, args.depleted) h = length / args.axial fuel_mats = {} -fuel_volume = pi * pellet_OR**2 * h / (len(ring_radii) + 1) for cell in geometry.get_all_cells().values(): if cell.fill in materials: # Determine volume of each fuel material if 'UO2 Fuel' in cell.fill.name: - r_o = cell.region.bounding_box[1][0] - if r_o not in fuel_mats: - cell.fill = cell.fill.clone() - cell.fill.volume = fuel_volume - fuel_mats[r_o] = cell.fill + upper_right = cell.region.bounding_box[1][0] + if isclose(upper_right, ring_radii[0]): + ri, ro = 0.0, ring_radii[0] + elif isclose(upper_right, ring_radii[1]): + ri, ro = ring_radii[0], ring_radii[1] else: - cell.fill = fuel_mats[r_o] + ri, ro = ring_radii[1], pellet_OR + if ri not in fuel_mats: + cell.fill = cell.fill.clone() + cell.fill.volume = pi * (ro*ro - ri*ri) * h + fuel_mats[ri] = cell.fill + else: + cell.fill = fuel_mats[ri] + elif cell.fill.name == 'Helium': + cell.fill.volume = pi * (clad_IR**2 - pellet_OR**2) * h + elif cell.fill.name == 'M5': + cell.fill.volume = pi * (clad_OR**2 - clad_IR**2) * h else: cell.fill.volume = 1.0 From c9554e003a218dcd9140f7e44f0041931bb70835 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 9 Aug 2021 12:40:55 -0500 Subject: [PATCH 4/7] Fix volume assignment to clad/gap, use proper assemblies --- smr/build-core-short.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/smr/build-core-short.py b/smr/build-core-short.py index 2e3033f..317a8a0 100644 --- a/smr/build-core-short.py +++ b/smr/build-core-short.py @@ -66,7 +66,8 @@ fuel_mats = {} for cell in geometry.get_all_cells().values(): if cell.fill in materials: # Determine volume of each fuel material - if 'UO2 Fuel' in cell.fill.name: + name = cell.fill.name + if 'UO2 Fuel' in name: upper_right = cell.region.bounding_box[1][0] if isclose(upper_right, ring_radii[0]): ri, ro = 0.0, ring_radii[0] @@ -74,16 +75,17 @@ for cell in geometry.get_all_cells().values(): ri, ro = ring_radii[0], ring_radii[1] else: ri, ro = ring_radii[1], pellet_OR - if ri not in fuel_mats: + if (name, ri) not in fuel_mats: cell.fill = cell.fill.clone() cell.fill.volume = pi * (ro*ro - ri*ri) * h - fuel_mats[ri] = cell.fill + fuel_mats[name, ri] = cell.fill else: - cell.fill = fuel_mats[ri] - elif cell.fill.name == 'Helium': + cell.fill = fuel_mats[name, ri] + elif name == 'Helium': cell.fill.volume = pi * (clad_IR**2 - pellet_OR**2) * h - elif cell.fill.name == 'M5': - cell.fill.volume = pi * (clad_OR**2 - clad_IR**2) * h + elif name == 'M5': + # Clad is not subdivided + cell.fill.volume = pi * (clad_OR**2 - clad_IR**2) * length else: cell.fill.volume = 1.0 @@ -93,7 +95,6 @@ all_materials = geometry.get_all_materials() materials = openmc.Materials(all_materials.values()) materials.export_to_xml(str(directory / 'materials.xml')) - #### Create OpenMC "geometry.xml" file geometry.export_to_xml(str(directory / 'geometry.xml')) @@ -125,3 +126,11 @@ if args.multipole: settings.export_to_xml(str(directory / 'settings.xml')) +# Check assembly power distribution +core_lattice = geometry.get_cells_by_fill_name('Main core')[0].fill +mesh = openmc.RegularMesh.from_rect_lattice(core_lattice) +assembly_power = openmc.Tally() +assembly_power.filters = [openmc.MeshFilter(mesh)] +assembly_power.scores = ['nu-fission'] +tallies = openmc.Tallies([assembly_power]) +tallies.export_to_xml(directory / 'tallies.xml') From 2a8764b04f5aaf06741f6af0e056693bf93be1bf Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 9 Aug 2021 12:43:58 -0500 Subject: [PATCH 5/7] Change enrichment pattern to flatten power distribution --- smr/smr/assemblies.py | 2 +- smr/smr/core.py | 58 +++++++++++++++++++++---------------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/smr/smr/assemblies.py b/smr/smr/assemblies.py index b13d0f9..6f10aaa 100644 --- a/smr/smr/assemblies.py +++ b/smr/smr/assemblies.py @@ -215,7 +215,7 @@ def assembly_universes(ring_radii, num_axial, depleted): gtu, gtu, gtu, gtu, gtu, gtu, gtu, gtu, gtu, gtu ] - univs['Assembly (2.4%) no BAs' + comment] = \ + univs['Assembly (2.4%)' + comment] = \ make_assembly('Assembly (2.4%) no BAs' + comment, universes) # WITH CONTROL ROD D BANK diff --git a/smr/smr/core.py b/smr/smr/core.py index 2e75dfe..68f3275 100644 --- a/smr/smr/core.py +++ b/smr/smr/core.py @@ -47,65 +47,65 @@ def core_geometry(ring_radii, num_axial, depleted): universes[1, 1] = reflector['1,1'] universes[1, 2] = reflector['NW'] universes[1, 3] = assembly['Assembly (3.1%)'] - universes[1, 4] = assembly['Assembly (2.4%) CR D'] + universes[1, 4] = assembly['Assembly (3.1%)'] universes[1, 5] = assembly['Assembly (3.1%)'] universes[1, 6] = reflector['NE'] universes[1, 7] = reflector['1,7'] universes[2, 0] = reflector['2,0'] universes[2, 1] = reflector['NW'] - universes[2, 2] = assembly['Assembly (3.1%) instr'] - universes[2, 3] = assembly['Assembly (2.4%) CR D'] - universes[2, 4] = assembly['Assembly (3.1%) instr'] - universes[2, 5] = assembly['Assembly (2.4%) CR D'] - universes[2, 6] = assembly['Assembly (3.1%) instr'] + universes[2, 2] = assembly['Assembly (3.1%)'] + universes[2, 3] = assembly['Assembly (2.4%)'] + universes[2, 4] = assembly['Assembly (1.6%)'] + universes[2, 5] = assembly['Assembly (2.4%)'] + universes[2, 6] = assembly['Assembly (3.1%)'] universes[2, 7] = reflector['NE'] universes[2, 8] = reflector['2,8'] universes[3, 0] = reflector['3,0'] universes[3, 1] = assembly['Assembly (3.1%)'] - universes[3, 2] = assembly['Assembly (2.4%) CR D'] - universes[3, 3] = assembly['Assembly (3.1%) instr'] - universes[3, 4] = assembly['Assembly (2.4%) CR D'] - universes[3, 5] = assembly['Assembly (3.1%) instr'] - universes[3, 6] = assembly['Assembly (2.4%) CR D'] + universes[3, 2] = assembly['Assembly (2.4%)'] + universes[3, 3] = assembly['Assembly (1.6%)'] + universes[3, 4] = assembly['Assembly (1.6%)'] + universes[3, 5] = assembly['Assembly (1.6%)'] + universes[3, 6] = assembly['Assembly (2.4%)'] universes[3, 7] = assembly['Assembly (3.1%)'] universes[3, 8] = reflector['3,8'] universes[4, 0] = reflector['4,0'] - universes[4, 1] = assembly['Assembly (2.4%) CR D'] - universes[4, 2] = assembly['Assembly (3.1%) instr'] - universes[4, 3] = assembly['Assembly (2.4%) CR D'] - universes[4, 4] = assembly['Assembly (1.6%)'] - universes[4, 5] = assembly['Assembly (2.4%) CR D'] - universes[4, 6] = assembly['Assembly (3.1%) instr'] - universes[4, 7] = assembly['Assembly (2.4%) CR D'] + universes[4, 1] = assembly['Assembly (3.1%)'] + universes[4, 2] = assembly['Assembly (1.6%)'] + universes[4, 3] = assembly['Assembly (1.6%)'] + universes[4, 4] = assembly['Assembly (2.4%)'] + universes[4, 5] = assembly['Assembly (1.6%)'] + universes[4, 6] = assembly['Assembly (1.6%)'] + universes[4, 7] = assembly['Assembly (3.1%)'] universes[4, 8] = reflector['4,8'] universes[5, 0] = reflector['5,0'] universes[5, 1] = assembly['Assembly (3.1%)'] - universes[5, 2] = assembly['Assembly (2.4%) CR D'] - universes[5, 3] = assembly['Assembly (3.1%) instr'] - universes[5, 4] = assembly['Assembly (2.4%) CR D'] - universes[5, 5] = assembly['Assembly (3.1%) instr'] - universes[5, 6] = assembly['Assembly (2.4%) CR D'] + universes[5, 2] = assembly['Assembly (2.4%)'] + universes[5, 3] = assembly['Assembly (1.6%)'] + universes[5, 4] = assembly['Assembly (1.6%)'] + universes[5, 5] = assembly['Assembly (1.6%)'] + universes[5, 6] = assembly['Assembly (2.4%)'] universes[5, 7] = assembly['Assembly (3.1%)'] universes[5, 8] = reflector['5,8'] universes[6, 0] = reflector['6,0'] universes[6, 1] = reflector['SW'] - universes[6, 2] = assembly['Assembly (3.1%) instr'] - universes[6, 3] = assembly['Assembly (2.4%) CR D'] - universes[6, 4] = assembly['Assembly (3.1%) instr'] - universes[6, 5] = assembly['Assembly (2.4%) CR D'] - universes[6, 6] = assembly['Assembly (3.1%) instr'] + universes[6, 2] = assembly['Assembly (3.1%)'] + universes[6, 3] = assembly['Assembly (2.4%)'] + universes[6, 4] = assembly['Assembly (1.6%)'] + universes[6, 5] = assembly['Assembly (2.4%)'] + universes[6, 6] = assembly['Assembly (3.1%)'] universes[6, 7] = reflector['SE'] universes[6, 8] = reflector['6,8'] universes[7, 1] = reflector['7,1'] universes[7, 2] = reflector['SW'] universes[7, 3] = assembly['Assembly (3.1%)'] - universes[7, 4] = assembly['Assembly (2.4%) CR D'] + universes[7, 4] = assembly['Assembly (3.1%)'] universes[7, 5] = assembly['Assembly (3.1%)'] universes[7, 6] = reflector['SE'] universes[7, 7] = reflector['7,7'] From 30355e218c42c19e16744a9762eedd86a78bca4a Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 25 Aug 2021 07:39:01 -0500 Subject: [PATCH 6/7] Add script for building full length core model --- smr/build-core-long.py | 116 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 smr/build-core-long.py diff --git a/smr/build-core-long.py b/smr/build-core-long.py new file mode 100644 index 0000000..9fba0e5 --- /dev/null +++ b/smr/build-core-long.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 + +import argparse +from math import pi, isclose +from pathlib import Path + +import openmc +from smr.materials import materials +from smr.surfaces import lattice_pitch, bottom_fuel_stack, top_active_core, \ + pellet_OR, pin_pitch, clad_IR, clad_OR, active_fuel_length +from smr.core import core_geometry +from smr import inlet_temperature + + +# Define command-line options +parser = argparse.ArgumentParser() +parser.add_argument('--multipole', action='store_true', + help='Use multipole cross sections') +parser.add_argument('--no-multipole', action='store_false', + help='Do not use multipole cross sections') +parser.add_argument('-a', '--axial', type=int, default=100, + help='Number of axial subdivisions in fuel') +parser.add_argument('-d', '--depleted', action='store_true', + help='Whether UO2 compositions should represent depleted fuel') +parser.add_argument('-o', '--output-dir', type=Path, default=None) +parser.set_defaults(multipole=True) +args = parser.parse_args() + +# Make directory for inputs +if args.output_dir is None: + if args.depleted: + directory = Path('core-long-depleted') + else: + directory = Path('core-long-fresh') +else: + directory = args.output_dir +directory.mkdir(exist_ok=True) + +ring_radii = [0.1*pin_pitch, 0.2*pin_pitch] + +geometry = core_geometry(ring_radii, args.axial, args.depleted) + +h = active_fuel_length / args.axial +fuel_mats = {} + +for cell in geometry.get_all_cells().values(): + if cell.fill in materials: + # Determine volume of each fuel material + name = cell.fill.name + if 'UO2 Fuel' in name: + upper_right = cell.region.bounding_box[1][0] + if isclose(upper_right, ring_radii[0]): + ri, ro = 0.0, ring_radii[0] + elif isclose(upper_right, ring_radii[1]): + ri, ro = ring_radii[0], ring_radii[1] + else: + ri, ro = ring_radii[1], pellet_OR + if (name, ri) not in fuel_mats: + cell.fill = cell.fill.clone() + cell.fill.volume = pi * (ro*ro - ri*ri) * h + fuel_mats[name, ri] = cell.fill + else: + cell.fill = fuel_mats[name, ri] + elif name == 'Helium': + cell.fill.volume = pi * (clad_IR**2 - pellet_OR**2) * h + elif name == 'M5': + # Clad is not subdivided + cell.fill.volume = pi * (clad_OR**2 - clad_IR**2) * active_fuel_length + else: + cell.fill.volume = 1.0 + + +#### Create OpenMC "materials.xml" file +all_materials = geometry.get_all_materials() +materials = openmc.Materials(all_materials.values()) +materials.export_to_xml(str(directory / 'materials.xml')) + +#### Create OpenMC "geometry.xml" file +geometry.export_to_xml(str(directory / 'geometry.xml')) + + +#### Create OpenMC "settings.xml" file + +# Construct uniform initial source distribution over fissionable zones +lower_left = [-7.*lattice_pitch/2., -7.*lattice_pitch/2., bottom_fuel_stack] +upper_right = [+7.*lattice_pitch/2., +7.*lattice_pitch/2., top_active_core] +source = openmc.source.Source(space=openmc.stats.Box(lower_left, upper_right)) +source.space.only_fissionable = True + +settings = openmc.Settings() +settings.batches = 200 +settings.inactive = 100 +settings.particles = 20_000_000 +settings.output = {'tallies': False, 'summary': False} +settings.source = source +settings.sourcepoint_write = False + +settings.temperature = { + 'default': inlet_temperature, + 'method': 'interpolation', + 'range': (300.0, 1500.0), +} +if args.multipole: + settings.temperature['multipole'] = True + settings.temperature['tolerance'] = 1000 + +settings.export_to_xml(str(directory / 'settings.xml')) + +# Check assembly power distribution +core_lattice = geometry.get_cells_by_fill_name('Main core')[0].fill +mesh = openmc.RegularMesh.from_rect_lattice(core_lattice) +assembly_power = openmc.Tally() +assembly_power.filters = [openmc.MeshFilter(mesh)] +assembly_power.scores = ['nu-fission'] +tallies = openmc.Tallies([assembly_power]) +tallies.export_to_xml(directory / 'tallies.xml') From 9c4c8c87fbda027907de5e5392321d570fdbe650 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 6 Jun 2022 21:32:09 -0500 Subject: [PATCH 7/7] Only modify lattice_pitch in build-core-short/long.py scripts --- smr/build-core-long.py | 9 ++++++--- smr/build-core-short.py | 12 ++++-------- smr/smr/core.py | 4 +++- smr/smr/reflector.py | 3 ++- smr/smr/surfaces.py | 3 +-- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/smr/build-core-long.py b/smr/build-core-long.py index 9fba0e5..c3531c6 100644 --- a/smr/build-core-long.py +++ b/smr/build-core-long.py @@ -6,17 +6,17 @@ from pathlib import Path import openmc from smr.materials import materials -from smr.surfaces import lattice_pitch, bottom_fuel_stack, top_active_core, \ +from smr.surfaces import bottom_fuel_stack, top_active_core, \ pellet_OR, pin_pitch, clad_IR, clad_OR, active_fuel_length from smr.core import core_geometry from smr import inlet_temperature - +import smr.surfaces # Define command-line options parser = argparse.ArgumentParser() parser.add_argument('--multipole', action='store_true', help='Use multipole cross sections') -parser.add_argument('--no-multipole', action='store_false', +parser.add_argument('--no-multipole', dest='multipole', action='store_false', help='Do not use multipole cross sections') parser.add_argument('-a', '--axial', type=int, default=100, help='Number of axial subdivisions in fuel') @@ -36,6 +36,9 @@ else: directory = args.output_dir directory.mkdir(exist_ok=True) +# Modify lattice pitch +smr.surfaces.lattice_pitch = lattice_pitch = 17*smr.surfaces.pin_pitch + ring_radii = [0.1*pin_pitch, 0.2*pin_pitch] geometry = core_geometry(ring_radii, args.axial, args.depleted) diff --git a/smr/build-core-short.py b/smr/build-core-short.py index 317a8a0..e9cabc8 100644 --- a/smr/build-core-short.py +++ b/smr/build-core-short.py @@ -1,25 +1,18 @@ #!/usr/bin/env python3 -import os -import shutil -import copy import argparse from math import pi, isclose from pathlib import Path -import numpy as np - import openmc from smr.materials import materials -from smr.plots import core_plots -from smr.surfaces import lattice_pitch, bottom_fuel_stack, top_active_core, \ +from smr.surfaces import bottom_fuel_stack, top_active_core, \ pellet_OR, surfs, pin_pitch, clad_IR, clad_OR import smr.surfaces import smr.pins from smr.core import core_geometry from smr import inlet_temperature - # Define command-line options parser = argparse.ArgumentParser() parser.add_argument('--multipole', action='store_true', @@ -44,6 +37,9 @@ else: directory = args.output_dir directory.mkdir(exist_ok=True) +# Modify lattice pitch +smr.surfaces.lattice_pitch = lattice_pitch = 17*smr.surfaces.pin_pitch + # Modify fuel length length = 3. * pin_pitch smr.surfaces.active_fuel_length = length diff --git a/smr/smr/core.py b/smr/smr/core.py index 68f3275..81763fe 100644 --- a/smr/smr/core.py +++ b/smr/smr/core.py @@ -5,9 +5,9 @@ import numpy as np import openmc from .materials import mats -from .surfaces import surfs, lattice_pitch from .reflector import reflector_universes from .assemblies import assembly_universes +from smr import surfaces def core_geometry(ring_radii, num_axial, depleted): @@ -34,6 +34,7 @@ def core_geometry(ring_radii, num_axial, depleted): # Construct main core lattice core = openmc.RectLattice(name='Main core') + lattice_pitch = surfaces.lattice_pitch core.lower_left = (-9*lattice_pitch/2, -9*lattice_pitch/2) core.pitch = (lattice_pitch, lattice_pitch) universes = np.tile(reflector['solid'], (9, 9)) @@ -119,6 +120,7 @@ def core_geometry(ring_radii, num_axial, depleted): core.universes = universes root_univ = openmc.Universe(universe_id=0, name='root universe') + surfs = surfaces.surfs # Cylinder filled with core lattice cell = openmc.Cell(name='Main core') diff --git a/smr/smr/reflector.py b/smr/smr/reflector.py index ed143cc..74aa4bd 100644 --- a/smr/smr/reflector.py +++ b/smr/smr/reflector.py @@ -12,7 +12,7 @@ converted to actual dimensions by scaling according to the width of an assembly. import openmc from .materials import mats -from .surfaces import lattice_pitch +from smr import surfaces def make_reflector(name, parameters): @@ -91,6 +91,7 @@ def reflector_universes(): # All pixel widths are scaled according to the actual width of an assembly # divided by the width of an assembly in pixels + lattice_pitch = surfaces.lattice_pitch scale = lattice_pitch/width # Physical positions diff --git a/smr/smr/surfaces.py b/smr/smr/surfaces.py index d91ec92..b454c61 100644 --- a/smr/smr/surfaces.py +++ b/smr/smr/surfaces.py @@ -69,8 +69,7 @@ spacer_height = 1.750*INCHES # ML17013A274, Figure 4.2-7 # assembly parameters assembly_length = 95.89*INCHES # ML17013A274, Table 4.1-2 pin_pitch = 0.496*INCHES # ML17013A274, Table 4.1-2 -#lattice_pitch = 8.466*INCHES # ML17013A274, Table 4.1-2 -lattice_pitch = 17*pin_pitch +lattice_pitch = 8.466*INCHES # ML17013A274, Table 4.1-2 grid_strap_side = 21.47270 top_nozzle_height = 3.551*INCHES # ML17013A274, Figure 4.2-2 top_nozzle_width = 8.406*INCHES # ML17013A274, Figure 4.2-2