mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-23 19:45:34 -04:00
Co-authored-by: Gavin Ridley <gavin.keith.ridley@gmail.com> Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
202 lines
7.1 KiB
Python
Executable file
202 lines
7.1 KiB
Python
Executable file
from math import isnan
|
|
import os
|
|
import hashlib
|
|
|
|
import numpy as np
|
|
import openmc
|
|
|
|
from tests.testing_harness import PyAPITestHarness
|
|
from tests.regression_tests import config
|
|
|
|
# OpenMC simulation parameters
|
|
batches = 10
|
|
inactive = 5
|
|
particles = 100
|
|
|
|
|
|
def build_mgxs_library(convert):
|
|
# Instantiate the energy group data
|
|
groups = openmc.mgxs.EnergyGroups(group_edges=[1e-5, 0.625, 20.0e6])
|
|
|
|
# Instantiate the 2-group (C5G7) cross section data
|
|
uo2_xsdata = openmc.XSdata('UO2', groups)
|
|
uo2_xsdata.order = 2
|
|
uo2_xsdata.set_total([2., 2.])
|
|
uo2_xsdata.set_absorption([1., 1.])
|
|
scatter_matrix = np.array([[[0.75, 0.25],
|
|
[0.00, 1.00]],
|
|
[[0.75 / 3., 0.25 / 3.],
|
|
[0.00 / 3., 1.00 / 3.]],
|
|
[[0.75 / 4., 0.25 / 4.],
|
|
[0.00 / 4., 1.00 / 4.]]])
|
|
scatter_matrix = np.rollaxis(scatter_matrix, 0, 3)
|
|
uo2_xsdata.set_scatter_matrix(scatter_matrix)
|
|
uo2_xsdata.set_fission([0.5, 0.5])
|
|
uo2_xsdata.set_nu_fission([1., 1.])
|
|
uo2_xsdata.set_chi([1., 0.])
|
|
|
|
mg_cross_sections_file = openmc.MGXSLibrary(groups)
|
|
mg_cross_sections_file.add_xsdatas([uo2_xsdata])
|
|
|
|
if convert is not None:
|
|
if isinstance(convert[0], list):
|
|
for conv in convert:
|
|
if conv[0] in ['legendre', 'tabular', 'histogram']:
|
|
mg_cross_sections_file = \
|
|
mg_cross_sections_file.convert_scatter_format(
|
|
conv[0], conv[1])
|
|
elif conv[0] in ['angle', 'isotropic']:
|
|
mg_cross_sections_file = \
|
|
mg_cross_sections_file.convert_representation(
|
|
conv[0], conv[1], conv[1])
|
|
elif convert[0] in ['legendre', 'tabular', 'histogram']:
|
|
mg_cross_sections_file = \
|
|
mg_cross_sections_file.convert_scatter_format(
|
|
convert[0], convert[1])
|
|
elif convert[0] in ['angle', 'isotropic']:
|
|
mg_cross_sections_file = \
|
|
mg_cross_sections_file.convert_representation(
|
|
convert[0], convert[1], convert[1])
|
|
|
|
mg_cross_sections_file.export_to_hdf5()
|
|
|
|
|
|
class MGXSTestHarness(PyAPITestHarness):
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
# Instantiate some Macroscopic Data
|
|
uo2_data = openmc.Macroscopic('UO2')
|
|
|
|
# Instantiate some Materials and register the appropriate objects
|
|
mat = openmc.Material(material_id=1, name='UO2 fuel')
|
|
mat.set_density('macro', 1.1)
|
|
mat.add_macroscopic(uo2_data)
|
|
|
|
# Instantiate a Materials collection and export to XML
|
|
materials_file = openmc.Materials([mat])
|
|
materials_file.cross_sections = "./mgxs.h5"
|
|
self._model.materials = materials_file
|
|
|
|
# Instantiate ZCylinder surfaces
|
|
left = openmc.XPlane(surface_id=4, x0=-5., name='left')
|
|
right = openmc.XPlane(surface_id=5, x0=5., name='right')
|
|
bottom = openmc.YPlane(surface_id=6, y0=-5., name='bottom')
|
|
top = openmc.YPlane(surface_id=7, y0=5., name='top')
|
|
|
|
left.boundary_type = 'reflective'
|
|
right.boundary_type = 'vacuum'
|
|
top.boundary_type = 'reflective'
|
|
bottom.boundary_type = 'reflective'
|
|
|
|
# Instantiate Cells
|
|
fuel = openmc.Cell(cell_id=1, name='cell 1')
|
|
|
|
# Use surface half-spaces to define regions
|
|
fuel.region = +left & -right & +bottom & -top
|
|
|
|
# Register Materials with Cells
|
|
fuel.fill = mat
|
|
|
|
# Instantiate Universe
|
|
root = openmc.Universe(universe_id=0, name='root universe')
|
|
|
|
# Register Cells with Universe
|
|
root.add_cells([fuel])
|
|
|
|
# Instantiate a Geometry, register the root Universe, and export to XML
|
|
self._model.geometry = openmc.Geometry(root)
|
|
|
|
settings_file = openmc.Settings()
|
|
settings_file.energy_mode = "multi-group"
|
|
settings_file.batches = batches
|
|
settings_file.inactive = inactive
|
|
settings_file.particles = particles
|
|
|
|
# Create an initial uniform spatial source distribution
|
|
bounds = [-5, -5, -5, 5, 5, 5]
|
|
uniform_dist = openmc.stats.Box(bounds[:3], bounds[3:])
|
|
settings_file.source = openmc.IndependentSource(space=uniform_dist)
|
|
|
|
self._model.settings = settings_file
|
|
|
|
def _run_openmc(self):
|
|
# Run multiple conversions to compare results
|
|
cases = [['legendre', 2], ['legendre', 0],
|
|
['tabular', 33], ['histogram', 32],
|
|
[['tabular', 33], ['legendre', 1]],
|
|
[['tabular', 33], ['tabular', 3]],
|
|
[['tabular', 33], ['histogram', 32]],
|
|
[['histogram', 32], ['legendre', 1]],
|
|
[['histogram', 32], ['tabular', 3]],
|
|
[['histogram', 32], ['histogram', 16]],
|
|
['angle', 2], [['angle', 2], ['isotropic', None]]]
|
|
|
|
outstr = ''
|
|
for case in cases:
|
|
build_mgxs_library(case)
|
|
|
|
if config['mpi']:
|
|
mpi_args = [config['mpiexec'], '-n', config['mpi_np']]
|
|
openmc.run(openmc_exec=config['exe'], mpi_args=mpi_args)
|
|
|
|
else:
|
|
openmc.run(openmc_exec=config['exe'])
|
|
|
|
with openmc.StatePoint('statepoint.{}.h5'.format(batches)) as sp:
|
|
# Sometimes NaN results are produced; convert these to 0.0
|
|
std_dev = 0.0 if isnan(sp.keff.s) else sp.keff.s
|
|
|
|
# Write out k-combined.
|
|
outstr += 'k-combined:\n'
|
|
form = '{:12.6E} {:12.6E}\n'
|
|
outstr += form.format(sp.keff.n, std_dev)
|
|
|
|
return outstr
|
|
|
|
def _get_results(self, outstr, hash_output=False):
|
|
# Hash the results if necessary.
|
|
if hash_output:
|
|
sha512 = hashlib.sha512()
|
|
sha512.update(outstr.encode('utf-8'))
|
|
outstr = sha512.hexdigest()
|
|
|
|
return outstr
|
|
|
|
def _cleanup(self):
|
|
super()._cleanup()
|
|
f = os.path.join(os.getcwd(), 'mgxs.h5')
|
|
if os.path.exists(f):
|
|
os.remove(f)
|
|
|
|
def execute_test(self):
|
|
"""Build input XMLs, run OpenMC, and verify correct results."""
|
|
try:
|
|
self._build_inputs()
|
|
inputs = self._get_inputs()
|
|
self._write_inputs(inputs)
|
|
self._compare_inputs()
|
|
outstr = self._run_openmc()
|
|
results = self._get_results(outstr)
|
|
self._write_results(results)
|
|
self._compare_results()
|
|
finally:
|
|
self._cleanup()
|
|
|
|
def update_results(self):
|
|
"""Update results_true.dat and inputs_true.dat"""
|
|
try:
|
|
self._build_inputs()
|
|
inputs = self._get_inputs()
|
|
self._write_inputs(inputs)
|
|
self._overwrite_inputs()
|
|
outstr = self._run_openmc()
|
|
results = self._get_results(outstr)
|
|
self._write_results(results)
|
|
self._overwrite_results()
|
|
finally:
|
|
self._cleanup()
|
|
|
|
|
|
def test_mg_convert():
|
|
harness = MGXSTestHarness('statepoint.10.h5', model=openmc.Model())
|
|
harness.main()
|