Hi,
I am trying to compare the absorbed dose rate on a cylinder due to a punctual source with both neutron and photon emissions between 3 Monte-Carlo codes: TRIPOLI-4, RayXpert and OpenMC.
Both TRIPOLI-4 and RayXpert gives the same results (around 10% discrepancy, mostly due to some simplification in the TRIPOLI modelling).
However, my OpemnMC input should be identical to the TRIPOLI one but I have a discrepancy factor of 10 000.
Here are the results:
Here is my python script for OpenMC:
#!/opt/conda/bin/python3.10
"""Contain test"""
import datetime
import math
import matplotlib.pyplot as plt
from matplotlib import colors
import openmc
import sys
pwd = os.getcwd()
# Interpolation type
inter_lin_lin = "linear-linear"
inter_log_lin = "log-linear"
inter_lin_log = "linear-log"
inter_log_log = "log-log"
if __name__ == "__main__":#
# Temperature in K
t = 293.6
# Define materials
# ----------------
mat = []
mat_moteur = openmc.Material(material_id=1, name="material_tally", temperature=t)
mat_moteur.add_element('C', 0.015 , 'wo')
mat_moteur.add_element('Si', 0.5 , 'wo')
mat_moteur.add_element('P', 0.0225, 'wo')
mat_moteur.add_element('S', 0.0150, 'wo')
mat_moteur.add_element('Cr', 8.5 , 'wo')
mat_moteur.add_element('Mn', 1 , 'wo')
mat_moteur.add_element('Fe', 32.6975, 'wo')
mat_moteur.add_element('Ni', 6 , 'wo')
mat_moteur.add_element('Mo', 1.25 , 'wo')
mat_moteur.add_element('Cu', 50 , 'wo')
mat_moteur.set_density("g/cm3", 8.45283)
mat.append(mat_moteur)
mat_air = openmc.Material(material_id=2, name="Air", temperature=t)
mat_air.add_element('N', 80, 'ao')
mat_air.add_element('O', 20, 'ao')
mat_air.set_density("g/cm3", 1.29E-3)
mat.append(mat_air)
# Materials collection
materials = openmc.Materials(mat)
init=os.getcwd()
for s in ["gamma", "neutron"]:
os.chdir(init)
if not os.path.isdir(s):
os.mkdir(s)
os.chdir(init+"/"+s)
materials.export_to_xml()
# Define geometry = univers = cellules = materials = surfaces
# -----------------------------------------------------------
# Surfaces creation
# moteur
surf_moteur_ext = openmc.ZCylinder(r=20, x0=-220)
surf_moteur_zmin = openmc.ZPlane(z0=-20)
surf_moteur_zmax = openmc.ZPlane(z0=+20)
# Air ext
surf_air_ext = openmc.XCylinder(r=50, boundary_type='vacuum')
surf_air_xmin = openmc.XPlane(x0=-250, boundary_type='vacuum')
surf_air_xmax = openmc.XPlane(x0=+250, boundary_type='vacuum')
# Regions creation
region_moteur = -surf_moteur_ext & -surf_moteur_zmax & +surf_moteur_zmin
region_air = -surf_air_ext & -surf_air_xmax & +surf_air_xmin
# Cell creation = regions + materials
cell_tally = openmc.Cell(fill=mat_moteur, region=region_moteur)
cell_air = openmc.Cell(fill=mat_air, region=region_air)
# Universe creation
root_universe = openmc.Universe(universe_id = 1,
name = "Univers",
cells=[cell_tally, cell_air])
geometry = openmc.Geometry(root_universe)
# Export
geometry.export_to_xml()
# Define settings
# ---------------
settings = openmc.Settings()
# Run mode
settings.run_mode = 'fixed source'
# Run strategy
settings.particles = 20000
if s == "gamma":
settings.batches = 100000
elif s == "neutron":
settings.batches = 100000
settings.create_delayed_neutrons = False
settings.create_fission_neutrons = False
settings.temperature = {"method": "interpolation"}
settings.output = {'tallies': True}
# Sources
position = [220,0,0]
source = openmc.IndependentSource()
source.space = openmc.stats.Point(position)
source.angle = openmc.stats.Isotropic()
if s == "neutron":
# Source neutron
source.particle = "neutron"
energy_bound = [
1.500E-11,
3.000E-09,
7.500E-09,
1.000E-08,
2.530E-08,
3.000E-08,
4.000E-08,
5.000E-08,
7.000E-08,
1.000E-07,
1.500E-07,
2.000E-07,
2.250E-07,
2.500E-07,
2.750E-07,
3.250E-07,
3.500E-07,
3.750E-07,
4.000E-07,
6.250E-07,
1.000E-06,
1.770E-06,
3.000E-06,
4.750E-06,
6.000E-06,
8.100E-06,
1.000E-05,
3.000E-05,
1.000E-04,
5.500E-04,
3.000E-03,
1.700E-02,
2.500E-02,
1.000E-01,
4.000E-01,
9.000E-01,
1.400E+00,
1.850E+00,
2.350E+00,
2.480E+00,
3.000E+00,
4.800E+00,
6.430E+00,
8.190E+00,
2.000E+01]
probability = [
1.328E+08,
1.048E+09,
1.233E+09,
1.383E+10,
6.686E+09,
1.772E+10,
2.203E+10,
5.285E+10,
9.419E+10,
1.725E+11,
1.707E+11,
8.055E+10,
7.485E+10,
6.893E+10,
1.211E+11,
5.598E+10,
5.176E+10,
4.740E+10,
3.051E+11,
2.944E+11,
3.450E+11,
3.178E+11,
2.765E+11,
1.395E+11,
1.806E+11,
1.280E+11,
6.580E+11,
6.808E+11,
8.461E+11,
6.766E+11,
4.960E+11,
8.628E+10,
2.468E+11,
1.227E+11,
5.755E+10,
3.067E+10,
1.382E+10,
8.411E+09,
1.412E+09,
3.225E+09,
5.480E+09,
2.693E+09,
1.235E+09,
2.884E+08 ]
elif s == "gamma":
# Source gamma
source.particle = "photon"
energy_bound = [
1.000E-02,
2.000E-02,
5.000E-02,
7.000E-02,
1.000E-01,
1.500E-01,
2.000E-01,
2.500E-01,
3.000E-01,
3.500E-01,
4.000E-01,
4.200E-01,
4.400E-01,
4.600E-01,
4.800E-01,
5.000E-01,
5.200E-01,
5.400E-01,
5.600E-01,
5.800E-01,
6.000E-01,
6.200E-01,
6.400E-01,
6.600E-01,
6.800E-01,
7.000E-01,
7.200E-01,
7.400E-01,
7.600E-01,
7.800E-01,
8.000E-01,
8.200E-01,
8.400E-01,
8.600E-01,
8.800E-01,
8.900E-01,
9.000E-01,
9.100E-01,
9.200E-01,
9.300E-01,
9.400E-01,
9.500E-01,
9.600E-01,
9.700E-01,
9.800E-01,
9.900E-01,
1.000E+00,
1.100E+00,
1.200E+00,
1.300E+00,
1.400E+00,
1.500E+00,
1.600E+00,
1.700E+00,
1.800E+00,
1.900E+00,
2.000E+00,
2.100E+00,
2.200E+00,
2.300E+00,
2.400E+00,
2.500E+00,
2.600E+00,
2.700E+00,
2.800E+00,
2.900E+00,
3.000E+00,
3.200E+00,
3.400E+00,
3.600E+00,
3.800E+00,
4.000E+00,
4.500E+00,
5.000E+00,
5.500E+00,
6.000E+00,
6.500E+00,
7.000E+00,
8.000E+00,
1.000E+01,
1.200E+01,
1.400E+01,
1.600E+01,
1.800E+01,
2.000E+01 ]
probability = [
1.389E+08,
6.037E+09,
4.089E+10,
1.130E+11,
1.723E+11,
1.265E+11,
9.420E+10,
7.663E+10,
6.537E+10,
5.945E+10,
2.207E+10,
2.058E+10,
2.033E+10,
1.059E+11,
9.525E+09,
2.883E+10,
7.594E+09,
7.305E+09,
6.726E+09,
6.632E+09,
6.444E+09,
6.311E+09,
6.516E+09,
6.202E+09,
5.871E+09,
5.273E+09,
5.314E+09,
6.601E+09,
5.670E+09,
4.799E+09,
4.422E+09,
4.939E+09,
4.921E+09,
4.258E+09,
2.230E+09,
2.462E+09,
2.206E+09,
2.096E+09,
1.922E+09,
2.242E+09,
2.083E+09,
2.076E+09,
2.340E+09,
2.209E+09,
2.223E+09,
1.957E+09,
1.875E+10,
1.744E+10,
2.446E+10,
1.471E+10,
1.358E+10,
1.267E+10,
1.184E+10,
1.611E+10,
1.070E+10,
9.505E+09,
2.304E+10,
8.271E+09,
1.050E+10,
7.997E+09,
1.034E+10,
7.515E+09,
7.283E+09,
1.019E+10,
6.688E+09,
6.309E+09,
1.664E+10,
1.180E+10,
8.665E+10,
1.320E+10,
1.077E+10,
1.458E+10,
1.051E+11,
1.032E+10,
3.881E+09,
2.197E+10,
5.117E+09,
1.565E+10,
6.740E+09,
6.825E+08,
0.000E+00,
0.000E+00,
0.000E+00,
0.000E+00 ]
nb_particle = sum(probability)
energy_bound = [1E6*e for e in energy_bound] # transformation from MeV to eV
delta_energy = []
for i in range(len(energy_bound)-1):
de = energy_bound[i+1]-energy_bound[i]
delta_energy.append(de)
probability_normalized = [p/e for p, e in zip(probability, delta_energy)]
probability_normalized.append(0) # adding final 0
source.energy = openmc.stats.Tabular(x=energy_bound, p=probability_normalized, interpolation="histogram")
settings.source = [source]
settings.photon_transport = True # for secondary photon
# Define tallies
# --------------
# Tallies definition
tallies = openmc.Tallies()
for p in ["neutron", "electron", "photon", "positron"]:
tally = openmc.Tally()
tally.filters = [openmc.CellFilter(bins=cell_tally), openmc.ParticleFilter(p)]
tally.scores = ["heating"]
tallies.append(tally)
tally = openmc.Tally()
tally.filters = [openmc.CellFilter(bins=cell_tally)]
tally.scores = ["heating"]
tallies.append(tally)
# Export
tallies.export_to_xml()
# Export
settings.export_to_xml()
# Define model = geometry + materials + settings + tallies
#--------------
model = openmc.model.Model(geometry=geometry,
materials=materials,
settings=settings,
tallies=tallies)
openmc.run()
if 1:
print("\n########## TALLIES RESULTS ##########")
with open("resu.txt", "w") as f_out:
f_out.write(f"Number of particles: {'{:.3E}'.format(nb_particle)}\n")
f_mult = nb_particle*72800*1.60218e-19/(math.pi*20**2*40*mat_moteur.density/1000)
f_out.write(f"Multiplication factor is: {'{:.6E}'.format(f_mult)}\n") # from eV/s/source to Gy/s
with open("tallies.out", "r") as f_in:
f_out.write("Résultats : \n")
for line in f_in:
if "Particle" in line:
name = "Particle"
f_out.write(f"{'{:10}'.format(line.split()[1].capitalize())} : ")
elif "heating" in line:
energy_depose = 3600*float(line.split()[1]) # units : from eV/s/source to eV/h/source
std_dev = float(line.split()[3])
std_dev_pc = 3600*std_dev/energy_depose*100 if energy_depose > 0 else 100.0
f_out.write(f"{'{:.3E}'.format(energy_depose)} eV/h/source -> {'{:.3E}'.format(energy_depose*f_mult)} Gy/h +/- {'{:.2f}'.format(std_dev_pc)} %\n") # results in Gy/h
I cannot see where I could be wrong. Any idea is welcome.