Hi,
I’ve been looking at doses for a shielded reactor, and noticed some big differences between the dose results between v0.14 and v0.15 of OpenMC. The tally filters I was using were a mesh filter, a particle filter and an energy function filter.
I’ve managed to narrow down the difference in results to the effect of energy function filter, but can’t seem to find where the difference is coming from (about 80x as much neutron dose in v0.15 compared to v0.14 and 40x as much photon dose).
Has anyone else had a similar issue/can help diagnose the problem?
Thanks in advance.
I’m having the same issue. Is anyone else experiencing this please?
EdP
September 17, 2024, 4:59pm
3
On investigation, this issue appears to be related only to the cubic interpolation of the data.dose_coefficients function, when used with the EnergyFunctionFilter. Other interpolation schemes work fine.
It looks to me like there was potentially a bug before 0.15, however I can’t readily see any change in EnergyFunctionFilter between the two versions. Perhaps someone could confirm if this is related to a known PR… is #2887 is related somehow?
For full context, running the simple model below with 0.14 produces a tally value 60x smaller than running with 0.15. Other interpolation schemes are broadly equivalent.
""" DESCRIPTION: A simple cylinder of fuel"""
import openmc
import numpy as np
#### MATERIALS ####
uo2 = openmc.Material(1, "uo2")
uo2.add_nuclide('U235', 0.1)
uo2.add_nuclide('U238', 0.9)
uo2.add_nuclide('O16', 2.0)
uo2.set_density('g/cm3', 10.0)
mats = openmc.Materials([uo2, ])
mats.export_to_xml("materials.xml")
#### GEOMETRY ####
fuel_or = openmc.ZCylinder(r=10.0, boundary_type="vacuum")
top_plane = openmc.ZPlane(z0=10.0, boundary_type="vacuum")
bottom_plane = openmc.ZPlane(z0=-10.0, boundary_type="vacuum")
fuel_region = -fuel_or &+bottom_plane & -top_plane
fuel = openmc.Cell(name="fuel", fill =uo2, region = fuel_region)
geometry = openmc.Geometry([fuel, ])
geometry.export_to_xml("geometry.xml")
#### TALLIES ####
tallies = openmc.Tallies()
# Create dose coefficients
energy_bins_n, dose_coeffs_n = openmc.data.dose_coefficients(particle="neutron", geometry="AP", )
# Create a neutron energy filter
energy_function_filter_n = openmc.EnergyFunctionFilter(energy_bins_n, dose_coeffs_n)
# ****
energy_function_filter_n.interpolation = "cubic" # TOGGLE cubic/histogram FOR ERROR RE
# ****
# Create neutron tally to score dose
dose_cell_tally_n = openmc.Tally (name="neutron_dose_on_mesh")
dose_cell_tally_n.filters = [energy_function_filter_n, ]
dose_cell_tally_n.scores = ['flux']
tallies.append(dose_cell_tally_n)
tallies.export_to_xml("tallies.xml")
#### SETTINGS ####
settings = openmc.Settings()
uniform_dist = openmc.stats.Box([-10.0, -10.0, -10.0], [10.0, 10.0, 10.0],)
src =openmc.IndependentSource(space=uniform_dist,)
settings.source = src
settings.batches = 100
settings.inactive = 10
settings.particles = 1000
settings.export_to_xml("settings.xml")
## RUN! ##
openmc.run(threads=40)
## POST-PROCESS ##
sp_name = "statepoint.100.h5"
sp = openmc.StatePoint(sp_name)
tally_output = sp.get_tally(name="neutron_dose_on_mesh")
tally_val = tally_output.mean.flatten()
print("---tally:")
print(tally_val)
print("---keff:")
print("{:5.4f}".format(unumpy.nominal_values(sp.keff)))
1 Like
Hi all,
This was indeed a bug related to cubit interpolation for the EnergyFunctionFilter
. Please see the following issue and fix below:
opened 02:30PM - 09 Nov 23 UTC
closed 09:49AM - 15 Nov 23 UTC
Bugs
## Bug Description
When running a prompt photon dose simulation I have noticed … very different results when using cubic interpolation of dose coefficients compared to all other types of interpolation. This effect is consistent whichever dose coefficients you use. The cubic interpolation provides a dose that is an order of magnitude lower than all other interpolation methods.
For example, I have attached a plot produced from a shutdown dose simulation of a steel sphere that was first irradiated with neutrons and the photon dose from the activated steel then plotted on a mesh. Results are consistent between different dose coefficients and interpolation methods (I used ICRP116 and ICRU57 + Pellicioni which Fluka uses) except for cubic interpolation.
<img width="655" alt="compare_interpolation_methods" src="https://github.com/openmc-dev/openmc/assets/18331093/175b3317-cc25-435a-92b5-695e46a3b6da">
## Steps to Reproduce
I have put below a python script with a simple (2 spheres) geometry and a photon source. Dose tallies are performed for all 5 interpolation methods. All tally results agree the dose is roughly 18 pSvcm2, except the cubic interpolation tally which calculates 2 pSvcm2.
```python
import openmc
# Geometry
material1 = openmc.Material(material_id=1)
material1.add_element(element="H", percent=1)
my_materials = openmc.Materials([material1])
sphere1 = openmc.Sphere(r=10)
sphere2 = openmc.Sphere(r=20, boundary_type='vacuum')
region1 = -sphere1
region2 = -sphere2 & +sphere1
cell1 = openmc.Cell(region=region1, fill=material1)
cell2 = openmc.Cell(region=region2)
my_geometry = openmc.Geometry([cell1, cell2])
# Source
source1 = openmc.Source()
source1.space = openmc.stats.Point((0, 0, 0))
source1.angle = openmc.stats.Isotropic()
source1.energy = openmc.stats.Discrete([0.3e6, 0.9e6, 2e6], [0.3, 0.4, 0.3])
source1.particle = 'photon'
# Settings
my_settings = openmc.Settings(
batches=100,
particles=10_000,
run_mode="fixed source",
source=source1
)
# Tallies: one dose tally for each interpolation method
energies_p, pSv_cm2_p = openmc.data.dose_coefficients('photon', geometry="AP")
energy_function_filter_cubic = openmc.EnergyFunctionFilter(energies_p, pSv_cm2_p)
energy_function_filter_cubic.interpolation = "cubic"
energy_function_filter_log_log = openmc.EnergyFunctionFilter(energies_p, pSv_cm2_p)
energy_function_filter_log_log.interpolation = "log-log"
energy_function_filter_linear_linear = openmc.EnergyFunctionFilter(energies_p, pSv_cm2_p)
energy_function_filter_linear_linear.interpolation = "linear-linear"
energy_function_filter_linear_log = openmc.EnergyFunctionFilter(energies_p, pSv_cm2_p)
energy_function_filter_linear_log.interpolation = "linear-log"
energy_function_filter_log_linear = openmc.EnergyFunctionFilter(energies_p, pSv_cm2_p)
energy_function_filter_log_linear.interpolation = "log-linear"
cell_filter = openmc.CellFilter(cell2)
particle_filter = openmc.ParticleFilter('photon')
cubic_dose_tally = openmc.Tally(name='cubic_dose_tally')
cubic_dose_tally.filters = [
cell_filter,
particle_filter,
energy_function_filter_cubic]
cubic_dose_tally.scores = ['flux']
log_log_dose_tally = openmc.Tally(name='log_log_dose_tally')
log_log_dose_tally.filters = [
cell_filter,
particle_filter,
energy_function_filter_log_log]
log_log_dose_tally.scores = ['flux']
linear_linear_dose_tally = openmc.Tally(name='linear_linear_dose_tally')
linear_linear_dose_tally.filters = [
cell_filter,
particle_filter,
energy_function_filter_linear_linear]
linear_linear_dose_tally.scores = ['flux']
linear_log_dose_tally = openmc.Tally(name='linear_log_dose_tally')
linear_log_dose_tally.filters = [
cell_filter,
particle_filter,
energy_function_filter_linear_log]
linear_log_dose_tally.scores = ['flux']
log_linear_dose_tally = openmc.Tally(name='log_linear_dose_tally')
log_linear_dose_tally.filters = [
cell_filter,
particle_filter,
energy_function_filter_log_linear]
log_linear_dose_tally.scores = ['flux']
my_tallies = openmc.Tallies([
cubic_dose_tally,
log_log_dose_tally,
linear_linear_dose_tally,
linear_log_dose_tally,
log_linear_dose_tally
])
model = openmc.model.Model(
geometry=my_geometry,
materials=my_materials,
settings=my_settings,
tallies=my_tallies
)
output_file = model.run()
with openmc.StatePoint(output_file) as results:
cubic_dose_tally = results.get_tally(
name="cubic_dose_tally"
)
cubic_dose = cubic_dose_tally.get_pandas_dataframe()["mean"].sum()
log_log_dose_tally = results.get_tally(
name="log_log_dose_tally"
)
log_log_dose = log_log_dose_tally.get_pandas_dataframe()["mean"].sum()
linear_linear_dose_tally = results.get_tally(
name="linear_linear_dose_tally"
)
linear_linear_dose = linear_linear_dose_tally.get_pandas_dataframe()["mean"].sum()
linear_log_dose_tally = results.get_tally(
name="linear_log_dose_tally"
)
linear_log_dose = linear_log_dose_tally.get_pandas_dataframe()["mean"].sum()
log_linear_dose_tally = results.get_tally(
name="log_linear_dose_tally"
)
log_linear_dose = log_linear_dose_tally.get_pandas_dataframe()["mean"].sum()
print(f"cubic: {cubic_dose} pSv cm2")
print(f"log_log: {log_log_dose} pSv cm2")
print(f"linear_linear: {linear_linear_dose} pSv cm2")
print(f"linear_log: {linear_log_dose} pSv cm2")
print(f"log_linear: {log_linear_dose} pSv cm2")
```
## Environment
I am using the development branch of openmc version 0.13.4-dev. ENDF VIII data. Ubuntu OS.
Best,
Patrick
2 Likes