Add first moment test for expansion filters

This commit is contained in:
Paul Romano 2018-03-30 09:29:17 -05:00
parent 31ef72f2cd
commit f5137f7316
2 changed files with 77 additions and 2 deletions

View file

@ -311,9 +311,16 @@ class SphericalHarmonicsFilter(ExpansionFilter):
class ZernikeFilter(ExpansionFilter):
r"""Score Zernike expansion moments in space up to specified order.
This filter allows scores to be multiplied by Zernike polynomials of the the
This filter allows scores to be multiplied by Zernike polynomials of the
particle's position along a particular axis, normalized to a given unit
circle, up to a user-specified order.
circle, up to a user-specified order. Specifying a filter with order N
tallies moments for all radial orders from 0 to N and each azimuthal order
for a given radial order. The ordering of the Zernike polynomial moments
follows the ANSI Z80.28 standard, where bin :math:`j` corresponds to the
radial index :math:`n` and the azimuthal index :math:`m` by
.. math::
j = \frac{n(n + 2) + m}{2}.
Parameters
----------

View file

@ -1,4 +1,25 @@
from math import sqrt, pi
import openmc
from pytest import fixture, approx
@fixture(scope='module')
def box_model():
model = openmc.model.Model()
m = openmc.Material()
m.add_nuclide('U235', 1.0)
m.set_density('g/cm3', 1.0)
box = openmc.model.get_rectangular_prism(10., 10., boundary_type='vacuum')
c = openmc.Cell(fill=m, region=box)
model.geometry.root_universe = openmc.Universe(cells=[c])
model.settings.particles = 100
model.settings.batches = 10
model.settings.inactive = 0
model.settings.source = openmc.Source(space=openmc.stats.Point())
return model
def test_legendre():
@ -78,3 +99,50 @@ def test_zernike():
assert elem.tag == 'filter'
assert elem.attrib['type'] == 'zernike'
assert elem.find('order').text == str(n)
def test_first_moment(run_in_tmpdir, box_model):
plain_tally = openmc.Tally()
plain_tally.scores = ['flux', 'scatter']
# Create tallies with expansion filters
leg_tally = openmc.Tally()
leg_tally.filters = [openmc.LegendreFilter(3)]
leg_tally.scores = ['scatter']
leg_sptl_tally = openmc.Tally()
leg_sptl_tally.filters = [openmc.SpatialLegendreFilter(3, 'x', -5., 5.)]
leg_sptl_tally.scores = ['scatter']
sph_scat_filter = openmc.SphericalHarmonicsFilter(5)
sph_scat_filter.cosine = 'scatter'
sph_scat_tally = openmc.Tally()
sph_scat_tally.filters = [sph_scat_filter]
sph_scat_tally.scores = ['scatter']
sph_flux_filter = openmc.SphericalHarmonicsFilter(5)
sph_flux_filter.cosine = 'particle'
sph_flux_tally = openmc.Tally()
sph_flux_tally.filters = [sph_flux_filter]
sph_flux_tally.scores = ['flux']
zernike_tally = openmc.Tally()
zernike_tally.filters = [openmc.ZernikeFilter(3, r=10.)]
zernike_tally.scores = ['scatter']
# Add tallies to model and ensure they all use the same estimator
box_model.tallies = [plain_tally, leg_tally, leg_sptl_tally,
sph_scat_tally, sph_flux_tally, zernike_tally]
for t in box_model.tallies:
t.estimator = 'analog'
box_model.run()
# Check that first moment matches the score from the plain tally
with openmc.StatePoint('statepoint.10.h5') as sp:
# Get scores from tally without expansion filters
flux, scatter = sp.tallies[plain_tally.id].mean.ravel()
# Check that first moment matches
first_score = lambda t: sp.tallies[t.id].mean.ravel()[0]
assert first_score(leg_tally) == scatter
assert first_score(leg_sptl_tally) == scatter
assert first_score(sph_scat_tally) == scatter
assert first_score(sph_flux_tally) == approx(flux)
assert first_score(zernike_tally)*sqrt(pi) == approx(scatter)