TimeFilter on flux tally

Hello forum,

I am trying to use TimeFilter to tally the flux of neutrons of certain lifetime. I started with a simple case to verify the feature but I found some weird results.

As shown in the diagram below: the neutron source is a mono-energetic (1000 eV), mono directional (+x direction) point neutron source released at t=0. The flux is tallied within the 10x10x10 box centered at (130, 0, 0). In other words, the left side is located at x=125cm and right boundary at x=135cm. The model is vacuum everywhere.

Speed of 1000 eV neutrons would be 4.38E7 cm/s. Thus, it takes 2.86E-6s to reach the left side of the tally box and 3.08E-6s to reach the right side of the tally box. As a result, if I understand correctly, if a timefilter is applied to the flux tally, all the flux should be in the time range [2.86E-6, 3.08E-6] s.

However, that’s not what I got. My results are attached below:

======================> TALLY 1: HALL TALLY <======================

Mesh Index (1, 1, 1)
Time [0.0, 2.8467358545984326e-06)
Total Material
Flux 8.58719 +/- 0.00000
Time [2.8467358545984326e-06, 3.0870506644926456e-06)
Total Material
Flux 0.72491 +/- 0.00000
Time [3.0870506644926456e-06, 1.0)
Total Material
Flux 0.687901 +/- 0.00000

One can see that, the majority of the flux are in the range <2.86E-6 s. Did I misunderstand anything?

Thank you very much for your help!
Xinyan

My code are attached below:

import openmc as omc
import numpy as np
import neutronics_material_maker as nmm
import math

surface

hall_xy = 290.0
hall_z = 10.0
hall_W = omc.XPlane(- hall_xy / 2.0, boundary_type = ‘vacuum’);
hall_E = omc.XPlane(hall_xy / 2.0, boundary_type = ‘vacuum’);
hall_N = omc.YPlane(- hall_xy / 2.0, boundary_type = ‘vacuum’);
hall_S = omc.YPlane(hall_xy / 2.0, boundary_type = ‘vacuum’);
hall_B = omc.ZPlane(- hall_z / 2.0, boundary_type = ‘vacuum’);
hall_T = omc.ZPlane(hall_z / 2.0, boundary_type = ‘vacuum’);

region

Inside_reg = +hall_W & -hall_E & +hall_N & -hall_S & +hall_B & -hall_T
Outside_reg = -hall_W | +hall_E | -hall_N | +hall_S | -hall_B | +hall_T

material

nmm.AddMaterialFromFile(“material_library.json”)
air = nmm.Material.from_library(“air”).openmc_material
materials = omc.Materials([air])
materials.cross_sections = “/usr/local/share/xs_data/endfb71_hdf5/cross_sections.xml”

cell

Inside_cell = omc.Cell(name = ‘inside_cell’, fill = None, region = Inside_reg);
Outside_cell = omc.Cell(name = ‘outside_cell’, fill = None, region = Outside_reg);

#geometry
universe = omc.Universe(cells = [Inside_cell, Outside_cell])
geometry = omc.Geometry(universe)

source

point = omc.stats.Point((0.0, 0.0, 0.0))
src1 = omc.Source()
src1.space = point
src1.energy = omc.stats.Discrete([1.0E3], [1.0])
src1.time = omc.stats.Discrete([0.0], [1.0])
#src1.angle = omc.stats.Isotropic()
src1.angle = omc.stats.Monodirectional(reference_uvw=[1.0, 0.0, 0.0])
src1.strength = 1.0

src_set = [src1]

#tally
hall_mesh = omc.RectilinearMesh()
hall_mesh.x_grid = np.arange(125.0, 135.01, 10.0)
hall_mesh.y_grid = np.arange(- 5.0, 5.01, 10.0)
hall_mesh.z_grid = np.arange(- 5.0, 5.01, 10.0)

hall_meshfilter = omc.MeshFilter(hall_mesh)

n_spd = 1.383E6 * math.sqrt(1.0E3) # cm/s
time_bins = [0, 124.5 / n_spd, 135.01 / n_spd, 1.0]
hall_timefilter = omc.TimeFilter(time_bins)

Hall_Tally = omc.Tally(name = ‘Hall Tally’)
Hall_Tally.filters = [hall_meshfilter, hall_timefilter]
Hall_Tally.scores = [‘flux’]

#settings
settings = omc.Settings()
settings.run_mode = ‘fixed source’
settings.source = src_set
settings.batches = 100
settings.particles = 100000

#run
model = omc.Model(materials=materials, geometry=geometry, settings=settings, tallies=[Hall_Tally])
model.run(threads = 32)

@paulromano I believe that you are an expert on timefilter. May I kindly ask for your help?
Xinyan

Hi Wxinyan

Thanks for writing up such a detailed and clear question with a diagram. :pray:

I read through it noticed you have a few vacuum boundary_type around the hall probe :eyes:

I’ve got a similar example over here (filename is 1_time_filter_tally.py) which doesn’t use a RectilinearMesh but just a simple cell tally on the detector. However it is otherwise very similar.

The detector cell is defined on these lines without vacuum surfaces but the whole geometry is in a vacuum sphere defined on this line

Let me know if that helps or not

1 Like

Hello @Shimwell ,

Thank you again for your quick reply. Yes it works! If I use a cell tally in place of the mesh tally for the detector, timefilter will work properly. The code and results are attached below. You can see that there are still a little flux before the expected lower bound of the time bin. This could be due to the rounding errors when I convert energy to speed.

Xinyan

----- Code -------
import openmc as omc
import numpy as np
import neutronics_material_maker as nmm
import math

#cubic hall and cell tally for detector

surface

hall_xy = 290.0
hall_z = 100.0
hall_W = omc.XPlane(- hall_xy / 2.0, boundary_type = ‘vacuum’);
hall_E = omc.XPlane(hall_xy / 2.0, boundary_type = ‘vacuum’);
hall_N = omc.YPlane(- hall_xy / 2.0, boundary_type = ‘vacuum’);
hall_S = omc.YPlane(hall_xy / 2.0, boundary_type = ‘vacuum’);
hall_B = omc.ZPlane(- hall_z / 2.0, boundary_type = ‘vacuum’);
hall_T = omc.ZPlane(hall_z / 2.0, boundary_type = ‘vacuum’);

detector

det_x = 100.0;
det_y = 0.0;
det_z = 0.0;
det_width = 10.0
det_W = omc.XPlane(x0 = det_x - det_width / 2.0);
det_E = omc.XPlane(x0 = det_x + det_width / 2.0);
det_N = omc.YPlane(y0 = det_y - det_width / 2.0);
det_S = omc.YPlane(y0 = det_y + det_width / 2.0);
det_B = omc.ZPlane(z0 = det_z - det_width / 2.0);
det_T = omc.ZPlane(z0 = det_z + det_width / 2.0);

region

det_reg = +det_W & -det_E & +det_N & -det_S & +det_B & -det_T
Hall_reg = +hall_W & -hall_E & +hall_N & -hall_S & +hall_B & -hall_T & ~det_reg
#Outside_reg = -hall_W | +hall_E | -hall_N | +hall_S | -hall_B | +hall_T

material

nmm.AddMaterialFromFile(“material_library.json”)

mod = nmm.Material.from_library(“Cadmium”).openmc_material

air = nmm.Material.from_library(“air”).openmc_material
materials = omc.Materials([air])
materials.cross_sections = “/usr/local/share/xs_data/endfb71_hdf5/cross_sections.xml”

cell

det_cell = omc.Cell(name = ‘det_cell’, fill = None, region = det_reg);
Hall_cell = omc.Cell(name = ‘Hall_cell’, fill = None, region = Hall_reg);
#Outside_cell = omc.Cell(name = ‘outside_cell’, fill = None, region = Outside_reg);

#geometry
universe = omc.Universe(cells = [det_cell, Hall_cell])
geometry = omc.Geometry(universe)

source

point = omc.stats.Point((0.0, 0.0, 0.0))
src1 = omc.Source()
src1.space = point
src1.energy = omc.stats.Discrete([1.4E3], [1.0])
#src1.time = omc.stats.Discrete([0.0], [1.0])
#src1.angle = omc.stats.Isotropic()
src1.angle = omc.stats.Monodirectional(reference_uvw=[1.0, 0.0, 0.0])
src1.strength = 1.0

src_set = [src1]

#tally
cell_filter = omc.CellFilter(det_cell)

n_spd = 1.383E6 * math.sqrt(1.4E3) # cm/s
time_bins = [0, 94.99 / n_spd, 105.0 / n_spd, 10]
timefilter = omc.TimeFilter(time_bins)

Det_Tally = omc.Tally(name = ‘Det_Tally’)
Det_Tally.filters = [cell_filter, timefilter]
Det_Tally.scores = [‘flux’]

#settings
settings = omc.Settings()
settings.run_mode = ‘fixed source’
settings.source = src_set
settings.batches = 100
settings.particles = 20000

#plot
“”"
plot1 = omc.Plot()
plot1.basis = ‘yz’
plot1.origin = (50.0, 0.0, 0.0)
plot1.color_by = ‘material’
plot1.width = (150., 150.)
plot1.pixels = (300, 300)
plot1.colors = {
mod: (0, 0, 255)
}

plots = omc.Plots([plot1])
plots.export_to_xml()
omc.plot_geometry()
“”"
#run
model = omc.Model(materials=materials, geometry=geometry, settings=settings, tallies=[Det_Tally])
model.run(threads = 32)

----- Result ------
======================> TALLY 1: DET_TALLY <=======================

Cell 1
Time [0.0, 1.835657655044193e-06)
Total Material
Flux 0.000832399 +/- 0.00000
Time [1.835657655044193e-06, 2.0290983659294692e-06)
Total Material
Flux 9.99917 +/- 6.45196e-08
Time [2.0290983659294692e-06, 10.0)
Total Material
Flux 0.00000 +/- 0.00000