forked from crp/ecp-benchmarks
Merge pull request #14 from mit-crpg/optional-differentiation
Make differentiation of materials optional for assembly-long and core-fresh
This commit is contained in:
commit
631fefebb8
2 changed files with 88 additions and 111 deletions
|
|
@ -20,16 +20,18 @@ from smr.pins import pin_universes, make_stack
|
|||
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('-t', '--tallies', choices=('cell', 'mat'), default='mat',
|
||||
help='Whether to use distribmats or distribcells for tallies')
|
||||
parser.add_argument('-a', '--axial', type=int, default=92,
|
||||
parser.add_argument('--clone', action='store_true',
|
||||
help='Clone materials for each cell instance')
|
||||
parser.add_argument('--no-clone', dest='clone', action='store_false',
|
||||
help='Do not clone materials for each cell instance')
|
||||
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)
|
||||
parser.set_defaults(clone=False, multipole=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
# Make directory for inputs
|
||||
|
|
@ -106,33 +108,52 @@ def clone(material):
|
|||
shared_mat.id = None
|
||||
return shared_mat
|
||||
|
||||
|
||||
#### "Differentiate" the geometry if using distribmats
|
||||
h = active_fuel_length / args.axial
|
||||
if args.tallies == 'mat':
|
||||
# Count the number of instances for each cell and material
|
||||
|
||||
fuel_mats = {}
|
||||
|
||||
# Count the number of instances for each cell and material
|
||||
if args.clone:
|
||||
geometry.determine_paths(instances_only=True)
|
||||
|
||||
for cell in tqdm(geometry.get_all_material_cells().values(),
|
||||
desc='Differentiating materials'):
|
||||
if cell.fill in materials:
|
||||
# Fill cell with list of "differentiated" materials
|
||||
for cell in tqdm(geometry.get_all_material_cells().values(),
|
||||
desc='Differentiating materials / assigning volume'):
|
||||
if cell.fill in materials:
|
||||
# Determine if this material is fuel
|
||||
is_fuel = 'UO2 Fuel' in cell.fill.name
|
||||
|
||||
# Fill cell with list of "differentiated" materials if requested
|
||||
if args.clone:
|
||||
cell.fill = [clone(cell.fill) for i in range(cell.num_instances)]
|
||||
|
||||
# Determine volume of each fuel material
|
||||
if 'UO2 Fuel' in cell.fill[0].name:
|
||||
upper_right = cell.region.bounding_box[1]
|
||||
if isclose(upper_right[0], rings[0]):
|
||||
ri, ro = 0.0, rings[0]
|
||||
elif isclose(upper_right[0], rings[1]):
|
||||
ri, ro = rings[0], rings[1]
|
||||
else:
|
||||
ri, ro = rings[1], pellet_OR
|
||||
# Determine volume of each fuel material
|
||||
if is_fuel:
|
||||
upper_right = cell.region.bounding_box[1]
|
||||
if isclose(upper_right[0], rings[0]):
|
||||
ri, ro = 0.0, rings[0]
|
||||
elif isclose(upper_right[0], rings[1]):
|
||||
ri, ro = rings[0], rings[1]
|
||||
else:
|
||||
ri, ro = rings[1], pellet_OR
|
||||
|
||||
if args.clone:
|
||||
for mat in cell.fill:
|
||||
mat.volume = pi * (ro*ro - ri*ri) * h
|
||||
else:
|
||||
# In non-clone mode, we still need to create a copy of the
|
||||
# material for each ring since they get different volumes
|
||||
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]
|
||||
else:
|
||||
if args.clone:
|
||||
for mat in cell.fill:
|
||||
mat.volume = 1.0
|
||||
else:
|
||||
cell.fill.volume = 1.0
|
||||
|
||||
#### Create OpenMC "materials.xml" file
|
||||
print('Getting materials...')
|
||||
|
|
@ -173,34 +194,3 @@ if args.multipole:
|
|||
}
|
||||
|
||||
settings.export_to_xml(str(directory / 'settings.xml'))
|
||||
|
||||
|
||||
#### Create OpenMC "tallies.xml" file
|
||||
tallies = openmc.Tallies()
|
||||
|
||||
# Extract all fuel materials
|
||||
materials = geometry.get_materials_by_name(name='Fuel', matching=False)
|
||||
|
||||
# If using distribcells, create distribcell tally needed for depletion
|
||||
if args.tallies == 'cell':
|
||||
# Extract all cells filled by a fuel material
|
||||
fuel_cells = []
|
||||
for cell in geometry.get_all_cells().values():
|
||||
if cell.fill in materials:
|
||||
tally = openmc.Tally(name='depletion tally')
|
||||
tally.scores = ['(n,p)', '(n,a)', '(n,gamma)',
|
||||
'fission', '(n,2n)', '(n,3n)', '(n,4n)']
|
||||
tally.nuclides = cell.fill.get_nuclides()
|
||||
tally.filters.append(openmc.DistribcellFilter([cell]))
|
||||
tallies.append(tally)
|
||||
|
||||
# If using distribmats, create material tally needed for depletion
|
||||
elif args.tallies == 'mat':
|
||||
tally = openmc.Tally(name='depletion tally')
|
||||
tally.scores = ['(n,p)', '(n,a)', '(n,gamma)',
|
||||
'fission', '(n,2n)', '(n,3n)', '(n,4n)']
|
||||
tally.nuclides = materials[0].get_nuclides()
|
||||
tally.filters = [openmc.MaterialFilter(materials)]
|
||||
tallies.append(tally)
|
||||
|
||||
tallies.export_to_xml(str(directory / 'tallies.xml'))
|
||||
|
|
|
|||
|
|
@ -1,36 +1,38 @@
|
|||
#!/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 tqdm import tqdm
|
||||
|
||||
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
|
||||
from smr.surfaces import lattice_pitch, bottom_fuel_stack, top_active_core, \
|
||||
pellet_OR, active_fuel_length
|
||||
from smr.core import core_geometry
|
||||
from smr import inlet_temperature
|
||||
|
||||
|
||||
def clone(mat):
|
||||
"""Make a shallow copy of a material (sharing compositions)."""
|
||||
mat_copy = copy.copy(mat)
|
||||
mat_copy.id = None
|
||||
return mat_copy
|
||||
def clone(material):
|
||||
"""Perform copy of material but share nuclide densities"""
|
||||
shared_mat = copy.copy(material)
|
||||
shared_mat.id = None
|
||||
return shared_mat
|
||||
|
||||
|
||||
# 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('-t', '--tallies', choices=('cell', 'mat'), default='cell',
|
||||
help='Whether to use distribmats or distribcells for tallies')
|
||||
parser.add_argument('--clone', action='store_true',
|
||||
help='Clone materials for each cell instance')
|
||||
parser.add_argument('--no-clone', dest='clone', action='store_false',
|
||||
help='Do not clone materials for each cell instance')
|
||||
parser.add_argument('-r', '--rings', type=int, default=10,
|
||||
help='Number of annular regions in fuel')
|
||||
parser.add_argument('-a', '--axial', type=int, default=196,
|
||||
|
|
@ -38,7 +40,7 @@ parser.add_argument('-a', '--axial', type=int, default=196,
|
|||
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)
|
||||
parser.set_defaults(clone=False, multipole=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
# Make directory for inputs
|
||||
|
|
@ -57,18 +59,38 @@ else:
|
|||
ring_radii = None
|
||||
geometry = core_geometry(ring_radii, args.axial, args.depleted)
|
||||
|
||||
#### "Differentiate" the geometry if using distribmats
|
||||
if args.tallies == 'mat':
|
||||
# Count the number of instances for each cell and material
|
||||
h = active_fuel_length / args.axial
|
||||
fuel_mats = {}
|
||||
|
||||
# Count the number of instances for each cell and material
|
||||
if args.clone:
|
||||
geometry.determine_paths(instances_only=True)
|
||||
|
||||
# Extract all cells filled by a fuel material
|
||||
fuel_mats = {m for m in materials if 'UO2 Fuel' in m.name}
|
||||
fuel_volume = pi * pellet_OR**2 * h / args.rings
|
||||
for cell in tqdm(geometry.get_all_cells().values(),
|
||||
desc='Differentiating materials / assigning volume'):
|
||||
if cell.fill in materials:
|
||||
# Determine if this material is fuel
|
||||
name = cell.fill.name
|
||||
is_fuel = 'UO2 Fuel' in name
|
||||
|
||||
for cell in geometry.get_all_cells().values():
|
||||
if cell.fill in fuel_mats:
|
||||
# Fill cell with list of "differentiated" materials
|
||||
cell.fill = [clone(cell.fill) for i in range(cell.num_instances)]
|
||||
# Determine volume of each fuel material
|
||||
if is_fuel:
|
||||
if args.clone:
|
||||
# Fill cell with list of "differentiated" materials if requested
|
||||
cell.fill = [clone(cell.fill) for i in range(cell.num_instances)]
|
||||
for mat in cell.fill:
|
||||
mat.volume = fuel_volume
|
||||
else:
|
||||
r_o = cell.region.bounding_box[1][0]
|
||||
if (name, r_o) not in fuel_mats:
|
||||
cell.fill = cell.fill.clone()
|
||||
cell.fill.volume = fuel_volume
|
||||
fuel_mats[name, r_o] = cell.fill
|
||||
else:
|
||||
cell.fill = fuel_mats[name, r_o]
|
||||
else:
|
||||
cell.fill.volume = 1.0
|
||||
|
||||
#### Create OpenMC "materials.xml" file
|
||||
all_materials = geometry.get_all_materials()
|
||||
|
|
@ -107,38 +129,3 @@ if args.multipole:
|
|||
|
||||
settings.export_to_xml(str(directory / 'settings.xml'))
|
||||
|
||||
|
||||
#### Create OpenMC "plots.xml" file
|
||||
plots = core_plots()
|
||||
plots.export_to_xml(str(directory / 'plots.xml'))
|
||||
|
||||
|
||||
#### Create OpenMC "tallies.xml" file
|
||||
tallies = openmc.Tallies()
|
||||
|
||||
# Extract all fuel materials
|
||||
materials = geometry.get_materials_by_name(name='Fuel', matching=False)
|
||||
|
||||
# If using distribcells, create distribcell tally needed for depletion
|
||||
if args.tallies == 'cell':
|
||||
# Extract all cells filled by a fuel material
|
||||
fuel_cells = []
|
||||
for cell in geometry.get_all_cells().values():
|
||||
if cell.fill in materials:
|
||||
tally = openmc.Tally(name='depletion tally')
|
||||
tally.scores = ['(n,p)', '(n,a)', '(n,gamma)',
|
||||
'fission', '(n,2n)', '(n,3n)', '(n,4n)']
|
||||
tally.nuclides = cell.fill.get_nuclides()
|
||||
tally.filters.append(openmc.DistribcellFilter([cell]))
|
||||
tallies.append(tally)
|
||||
|
||||
# If using distribmats, create material tally needed for depletion
|
||||
elif args.tallies == 'mat':
|
||||
tally = openmc.Tally(name='depletion tally')
|
||||
tally.scores = ['(n,p)', '(n,a)', '(n,gamma)',
|
||||
'fission', '(n,2n)', '(n,3n)', '(n,4n)']
|
||||
tally.nuclides = materials[0].get_nuclides()
|
||||
tally.filters = [openmc.MaterialFilter(materials)]
|
||||
tallies.append(tally)
|
||||
|
||||
tallies.export_to_xml(str(directory / 'tallies.xml'))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue