mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-24 03:55:38 -04:00
170 lines
5.8 KiB
Python
170 lines
5.8 KiB
Python
"""Test the 'collision_track' setting used to store particle information
|
|
during specified collision conditions in a file for a given simulation."""
|
|
|
|
import openmc
|
|
import pytest
|
|
import h5py
|
|
import numpy as np
|
|
import shutil
|
|
|
|
from tests.testing_harness import CollisionTrackTestHarness as ctt
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def geometry():
|
|
"""Simple hydrogen sphere geometry"""
|
|
openmc.reset_auto_ids()
|
|
material = openmc.Material(name="H1")
|
|
material.add_element("H", 1.0)
|
|
sphere = openmc.Sphere(r=1.0, boundary_type="vacuum")
|
|
cell = openmc.Cell(region=-sphere, fill=material)
|
|
return openmc.Geometry([cell])
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"parameter",
|
|
[
|
|
{"max_collisions": 200},
|
|
{"max_collisions": 200, "reactions": ["(n,disappear)"]},
|
|
{"max_collisions": 200, "cell_ids": [1]},
|
|
{"max_collisions": 200, "material_ids": [1]},
|
|
{"max_collisions": 200, "universe_ids": [1]},
|
|
{"max_collisions": 200, "nuclides": ["H1"]},
|
|
{"max_collisions": 200, "deposited_E_threshold": 200000.0},
|
|
{"max_collisions": 200, "mcpl": True}
|
|
|
|
],
|
|
ids=str
|
|
)
|
|
def test_xml_serialization(parameter, run_in_tmpdir):
|
|
"""Check that the different use cases can be written and read in XML."""
|
|
settings = openmc.Settings()
|
|
settings.collision_track = parameter
|
|
settings.export_to_xml()
|
|
|
|
read_settings = openmc.Settings.from_xml()
|
|
assert read_settings.collision_track == parameter
|
|
|
|
|
|
@pytest.fixture
|
|
def model():
|
|
"""Simple hydrogen sphere divided in two hemispheres
|
|
by a z-plane to form 2 cells."""
|
|
openmc.reset_auto_ids()
|
|
model = openmc.Model()
|
|
|
|
# Material
|
|
material = openmc.Material(name="H1")
|
|
material.add_element("H", 1.0)
|
|
|
|
# Geometry
|
|
radius = 1.0
|
|
sphere = openmc.Sphere(r=radius, boundary_type="reflective")
|
|
plane = openmc.ZPlane(0.0)
|
|
cell_1 = openmc.Cell(region=-sphere & -plane, fill=material, cell_id=1)
|
|
cell_2 = openmc.Cell(region=-sphere & +plane, fill=material, cell_id=2)
|
|
root = openmc.Universe(cells=[cell_1, cell_2])
|
|
model.geometry = openmc.Geometry(root)
|
|
|
|
# Settings
|
|
model.settings = openmc.Settings()
|
|
model.settings.run_mode = "fixed source"
|
|
model.settings.particles = 1
|
|
model.settings.batches = 1
|
|
model.settings.seed = 2
|
|
|
|
bounds = [-radius, -radius, -radius, radius, radius, radius]
|
|
distribution = openmc.stats.Box(bounds[:3], bounds[3:])
|
|
model.settings.source = openmc.IndependentSource(space=distribution)
|
|
|
|
return model
|
|
|
|
|
|
def test_particle_location(run_in_tmpdir, model):
|
|
"""Test the location of particles with respected to the "cell_ids"
|
|
and the location x, y, z of the particle itself. the upper sphere will
|
|
have positive z component and the bottom sphere a negative z compnent.
|
|
|
|
"""
|
|
model.settings.collision_track = {
|
|
"max_collisions": 200,
|
|
"reactions": ["elastic"],
|
|
"cell_ids": [1, 2]
|
|
}
|
|
model.run()
|
|
|
|
with h5py.File("collision_track.h5", "r") as f:
|
|
source = f["collision_track_bank"]
|
|
|
|
assert len(source) == 60
|
|
|
|
# We want to verify that the collisions happenening are in the right cells
|
|
# and the position of the particle is either positive or negative relative
|
|
# to the z plane. In this case, we track the position of the particle
|
|
# relative to the cell_id already set.
|
|
for point in source:
|
|
if point['cell_id'] == 1:
|
|
assert point['r'][2] < 0.0 # z component negative
|
|
elif point['cell_id'] == 2:
|
|
assert point["r"][2] > 0.0 # z component positive
|
|
else:
|
|
assert False
|
|
|
|
|
|
@pytest.mark.skipif(shutil.which("mcpl-config") is None, reason="MCPL is not available.")
|
|
def test_format_similarity(run_in_tmpdir, model):
|
|
model.settings.collision_track = {"max_collisions": 200, "reactions": ['elastic'],
|
|
"cell_ids": [1, 2], "mcpl": False}
|
|
model.run()
|
|
data_h5 = ctt._return_collision_track_data('collision_track.h5')
|
|
|
|
model.settings.collision_track["mcpl"] = True
|
|
model.run()
|
|
data_mcpl = ctt._return_collision_track_data('collision_track.mcpl')
|
|
|
|
assert len(data_h5) == 60
|
|
assert len(data_mcpl) == 60
|
|
|
|
np.testing.assert_allclose(data_h5, data_mcpl, rtol=1e-05)
|
|
# tolerance not that low due to the strings that is saved in MCPL,
|
|
# not enough precision!
|
|
|
|
|
|
def test_photon_particles(run_in_tmpdir, model):
|
|
"""Test that the collision track can be used to track photon particles."""
|
|
model.settings.collision_track = {"max_collisions": 200, "cell_ids": [1, 2]}
|
|
|
|
model.settings.source = openmc.IndependentSource(
|
|
space=openmc.stats.Box(*model.geometry.bounding_box),
|
|
energy=openmc.stats.delta_function(1e5),
|
|
particle='photon'
|
|
)
|
|
model.run()
|
|
|
|
with h5py.File("collision_track.h5", "r") as f:
|
|
source = f["collision_track_bank"]
|
|
|
|
assert len(source) < 200
|
|
|
|
allowed_particles = (openmc.ParticleType.PHOTON, openmc.ParticleType.ELECTRON)
|
|
|
|
for point in source:
|
|
particle_type = openmc.ParticleType(point['particle'])
|
|
assert particle_type in allowed_particles
|
|
|
|
if particle_type == openmc.ParticleType.ELECTRON:
|
|
assert point['nuclide_id'] == 0
|
|
|
|
|
|
def test_collision_track_two_threads(model, run_in_tmpdir):
|
|
# This test checks that the `max_collisions` setting is honored:
|
|
# no collisions beyond the specified limit should be recorded.
|
|
#
|
|
# The exact set of events in the capped bank is not reproducible with
|
|
# multiple threads because the bank stores whichever thread appends first
|
|
# until capacity is reached.
|
|
model.settings.collision_track = {"max_collisions": 200}
|
|
model.run(threads=2, particles=500)
|
|
|
|
collision_track = openmc.read_collision_track_hdf5("collision_track.h5")
|
|
assert len(collision_track) == 200
|