Merge pull request #2071 from paulromano/flf-improve-track

Major overhaul of track file capability
This commit is contained in:
Patrick Shriwise 2022-06-02 14:32:49 -05:00 committed by GitHub
commit fe230168fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 1166 additions and 111 deletions

View file

@ -4,18 +4,34 @@
Track File Format
=================
The current revision of the particle track file format is 2.0.
The current revision of the particle track file format is 3.0.
**/**
:Attributes: - **filetype** (*char[]*) -- String indicating the type of file.
- **version** (*int[2]*) -- Major and minor version of the track
file format.
- **n_particles** (*int*) -- Number of particles for which tracks
are recorded.
- **n_coords** (*int[]*) -- Number of coordinates for each
particle.
:Datasets:
- **coordinates_<i>** (*double[][3]*) -- (x,y,z) coordinates for the
*i*-th particle.
- **track_<b>_<g>_<p>** (Compound type) -- Particle track information
for source particle in batch *b*, generation *g*, and particle
number *p*. particle. The compound type has fields ``r``, ``u``,
``E``, ``time``, ``wgt``, ``cell_id``, ``cell_instance``, and
``material_id``, which represent the position (each coordinate in
[cm]), direction, energy in [eV], time in [s], weight, cell ID,
cell instance, and material ID, respectively. When the particle is
present in a cell with no material assigned, the material ID is
given as -1. Note that this array contains information for one or
more primary/secondary particles originating. The starting index
for each primary/secondary particle is given by the ``offsets``
attribute.
:Attributes: - **n_particles** (*int*) -- Number of
primary/secondary particles for the source history.
- **offsets** (*int[]*) Offset (starting index) into
the array for each primary/secondary particle. The
last offset should match the total size of the
array.
- **particles** (*int[]*) -- Particle type for each
primary/secondary particle (0=neutron, 1=photon,
2=electron, 3=positron).

View file

@ -185,8 +185,11 @@ Post-processing
:template: myclass.rst
openmc.Particle
openmc.ParticleTrack
openmc.StatePoint
openmc.Summary
openmc.Track
openmc.Tracks
The following classes and functions are used for functional expansion reconstruction.

View file

@ -47,7 +47,7 @@ flags:
-r, --restart file Restart a previous run from a state point or a particle
restart file
-s, --threads N Run with *N* OpenMP threads
-t, --track Write tracks for all particles
-t, --track Write tracks for all particles (up to max_tracks)
-v, --version Show version information
-h, --help Show help message
@ -112,6 +112,19 @@ otherwise.
tallies. The path to the statepoint file can be provided as an optional arugment
(if omitted, a file dialog will be presented).
.. _scripts_track_combine:
------------------------
``openmc-track-combine``
------------------------
This script combines multiple HDF5 :ref:`particle track files
<usersguide_track>` into a single HDF5 particle track file. The filenames of the
particle track files should be given as posititional arguments. The output
filename can also be changed with the ``-o`` flag:
-o OUT, --out OUT Output HDF5 particle track file
.. _scripts_track:
-----------------------

View file

@ -514,4 +514,108 @@ As an example, to write a statepoint file every five batches::
settings.batches = n
settings.statepoint = {'batches': range(5, n + 5, 5)}
.. _NIST ESTAR database: https://physics.nist.gov/PhysRefData/Star/Text/ESTAR.html
Particle Track Files
--------------------
OpenMC can generate a particle track file that contains track information
(position, direction, energy, time, weight, cell ID, and material ID) for each
state along a particle's history. There are two ways to indicate which particles
and/or how many particles should have their tracks written. First, you can
identify specific source particles by their batch, generation, and particle ID
numbers::
settings.tracks = [
(1, 1, 50),
(2, 1, 30),
(5, 1, 75)
]
In this example, track information would be written for the 50th particle in the
1st generation of batch 1, the 30th particle in the first generation of batch 2,
and the 75th particle in the 1st generation of batch 5. Unless you are using
more than one generation per batch (see :ref:`usersguide_particles`), the
generation number should be 1. Alternatively, you can run OpenMC in a mode where
track information is written for *all* particles, up to a user-specified limit::
openmc.run(tracks=True)
In this case, you can control the maximum number of source particles for which
tracks will be written as follows::
settings.max_tracks = 1000
Particle track information is written to the ``tracks.h5`` file, which can be
analyzed using the :class:`~openmc.Tracks` class::
>>> tracks = openmc.Tracks('tracks.h5')
>>> tracks
[<Track (1, 1, 50): 151 particles>,
<Track (2, 1, 30): 191 particles>,
<Track (5, 1, 75): 81 particles>]
Each :class:`~openmc.Track` object stores a list of track information for every
primary/secondary particle. In the above example, the first source particle
produced 150 secondary particles for a total of 151 particles. Information for
each primary/secondary particle can be accessed using the
:attr:`~openmc.Track.particle_tracks` attribute::
>>> first_track = tracks[0]
>>> first_track.particle_tracks
[<ParticleTrack: neutron, 120 states>,
<ParticleTrack: photon, 6 states>,
<ParticleTrack: electron, 2 states>,
<ParticleTrack: electron, 2 states>,
<ParticleTrack: electron, 2 states>,
...
<ParticleTrack: electron, 2 states>,
<ParticleTrack: electron, 2 states>]
>>> photon = first_track.particle_tracks[1]
The :class:`~openmc.ParticleTrack` class is a named tuple indicating the
particle type and then a NumPy array of the "states". The states array is a
compound type with a field for each physical quantity (position, direction,
energy, time, weight, cell ID, and material ID). For example, to get the
position for the above particle track::
>>> photon.states['r']
array([(-11.92987939, -12.28467295, 0.67837495),
(-11.95213726, -12.2682 , 0.68783964),
(-12.2682 , -12.03428339, 0.82223855),
(-12.5913778 , -11.79510096, 0.95966298),
(-12.6622572 , -11.74264344, 0.98980293),
(-12.6907775 , -11.7215357 , 1.00193058)],
dtype=[('x', '<f8'), ('y', '<f8'), ('z', '<f8')])
The full list of fields is as follows:
:r: Position (each direction in [cm])
:u: Direction
:E: Energy in [eV]
:time: Time in [s]
:wgt: Weight
:cell_id: Cell ID
:cell_instance: Cell instance
:material_id: Material ID
Both the :class:`~openmc.Tracks` and :class:`~openmc.Track` classes have a
``filter`` method that allows you to get a subset of tracks that meet a given
criteria. For example, to get all tracks that involved a photon::
>>> tracks.filter(particle='photon')
[<Track (1, 1, 50): 151 particles>,
<Track (2, 1, 30): 191 particles>,
<Track (5, 1, 75): 81 particles>]
The :meth:`openmc.Tracks.filter` method returns a new :class:`~openmc.Tracks`
instance, whereas the :meth:`openmc.Track.filter` method returns a new
:class:`~openmc.Track` instance.
.. note:: If you are using an MPI-enabled install of OpenMC and run a simulation
with more than one process, a separate track file will be written for
each MPI process with the filename ``tracks_p#.h5`` where # is the
rank of the corresponding process. Multiple track files can be
combined with the :ref:`scripts_track_combine` script:
.. code-block:: sh
openmc-track-combine tracks_p*.h5 --out tracks.h5

View file

@ -26,7 +26,7 @@ constexpr int HDF5_VERSION[] {3, 0};
// Version numbers for binary files
constexpr array<int, 2> VERSION_STATEPOINT {17, 0};
constexpr array<int, 2> VERSION_PARTICLE_RESTART {2, 0};
constexpr array<int, 2> VERSION_TRACK {2, 0};
constexpr array<int, 2> VERSION_TRACK {3, 0};
constexpr array<int, 2> VERSION_SUMMARY {6, 0};
constexpr array<int, 2> VERSION_VOLUME {1, 0};
constexpr array<int, 2> VERSION_VOXEL {2, 0};

View file

@ -56,6 +56,24 @@ struct SourceSite {
int64_t progeny_id;
};
//! State of a particle used for particle track files
struct TrackState {
Position r; //!< Position in [cm]
Direction u; //!< Direction
double E; //!< Energy in [eV]
double time {0.0}; //!< Time in [s]
double wgt {1.0}; //!< Weight
int cell_id; //!< Cell ID
int cell_instance; //!< Cell instance
int material_id {-1}; //!< Material ID (default value indicates void)
};
//! Full history of a single particle's track states
struct TrackStateHistory {
ParticleType particle;
std::vector<TrackState> states;
};
//! Saved ("banked") state of a particle, for nu-fission tallying
struct NuBank {
double E; //!< particle energy
@ -290,7 +308,7 @@ private:
vector<FilterMatch> filter_matches_; // tally filter matches
vector<vector<Position>> tracks_; // tracks for outputting to file
vector<TrackStateHistory> tracks_; // tracks for outputting to file
vector<NuBank> nu_bank_; // bank of most recently fissioned particles
@ -342,6 +360,9 @@ public:
const LocalCoord& coord(int i) const { return coord_[i]; }
const vector<LocalCoord>& coord() const { return coord_; }
LocalCoord& lowest_coord() { return coord_[n_coord_ - 1]; }
const LocalCoord& lowest_coord() const { return coord_[n_coord_ - 1]; }
int& n_coord_last() { return n_coord_last_; }
const int& n_coord_last() const { return n_coord_last_; }
int& cell_last(int i) { return cell_last_[i]; }
@ -357,6 +378,7 @@ public:
const int& g_last() const { return g_last_; }
double& wgt() { return wgt_; }
double wgt() const { return wgt_; }
double& mu() { return mu_; }
const double& mu() const { return mu_; }
double& time() { return time_; }
@ -479,6 +501,9 @@ public:
n_coord_ = 1;
}
//! Get track information based on particle's current state
TrackState get_track_state() const;
void zero_delayed_bank()
{
for (int& n : n_delayed_bank_) {

View file

@ -88,6 +88,7 @@ extern int max_order; //!< Maximum Legendre order for multigroup data
extern int n_log_bins; //!< number of bins for logarithmic energy grid
extern int n_batches; //!< number of (inactive+active) batches
extern int n_max_batches; //!< Maximum number of batches
extern int max_tracks; //!< Maximum number of particle tracks written to file
extern ResScatMethod res_scat_method; //!< resonance upscattering method
extern double res_scat_energy_min; //!< Min energy in [eV] for res. upscattering
extern double res_scat_energy_max; //!< Max energy in [eV] for res. upscattering

View file

@ -9,8 +9,31 @@ namespace openmc {
// Non-member functions
//==============================================================================
//! Open HDF5 track file for writing and create track datatype
void open_track_file();
//! Close HDF5 resources for track file
void close_track_file();
//! Determine whether a given particle should collect/write track information
//
//! \param[in] p Current particle
//! \return Whether to collect/write track information
bool check_track_criteria(const Particle& p);
//! Create a new track state history for a primary/secondary particle
//
//! \param[in] p Current particle
void add_particle_track(Particle& p);
//! Store particle's current state
//
//! \param[in] p Current particle
void write_particle_track(Particle& p);
//! Write full particle state history to HDF5 track file
//
//! \param[in] p Current particle
void finalize_particle_track(Particle& p);
} // namespace openmc

View file

@ -34,7 +34,7 @@ Restart a previous run from a state point or a particle restart file named
Use \fIN\fP OpenMP threads.
.TP
.B "\-t\fR, \fP\-\-track"
Write tracks for all particles.
Write tracks for all particles (up to max_tracks).
.TP
.B "\-v\fR, \fP\-\-version"
Show version information.

View file

@ -30,6 +30,7 @@ from openmc.mixin import *
from openmc.plotter import *
from openmc.search import *
from openmc.polynomial import *
from openmc.tracks import *
from . import examples
# Import a few names from the model module

View file

@ -2,6 +2,7 @@ import os
import typing # imported separately as py3.8 requires typing.Iterable
from collections.abc import Iterable, Mapping, MutableSequence
from enum import Enum
import itertools
from math import ceil
from numbers import Integral, Real
from pathlib import Path
@ -104,6 +105,10 @@ class Settings:
Maximum number of times a particle can split during a history
.. versionadded:: 0.13
max_tracks : int
Maximum number of tracks written to a track file (per MPI process).
.. versionadded:: 0.13.1
no_reduce : bool
Indicate that all user-defined and global tallies should not be reduced
across processes in a parallel calculation.
@ -187,7 +192,7 @@ class Settings:
integers: the batch number, generation number, and particle number
track : tuple or list
Specify particles for which track files should be written. Each particle
is identified by a triplet with the batch number, generation number, and
is identified by a tuple with the batch number, generation number, and
particle number.
trigger_active : bool
Indicate whether tally triggers are used
@ -290,6 +295,7 @@ class Settings:
self._weight_windows = cv.CheckedList(WeightWindows, 'weight windows')
self._weight_windows_on = None
self._max_splits = None
self._max_tracks = None
@property
def run_mode(self):
@ -475,6 +481,10 @@ class Settings:
def max_splits(self):
return self._max_splits
@property
def max_tracks(self):
return self._max_tracks
@run_mode.setter
def run_mode(self, run_mode: str):
cv.check_value('run mode', run_mode, {x.value for x in RunMode})
@ -776,16 +786,18 @@ class Settings:
self._trace = trace
@track.setter
def track(self, track: typing.Iterable[int]):
cv.check_type('track', track, Iterable, Integral)
if len(track) % 3 != 0:
msg = f'Unable to set the track to "{track}" since its length is ' \
'not a multiple of 3'
raise ValueError(msg)
for t in zip(track[::3], track[1::3], track[2::3]):
def track(self, track: typing.Iterable[typing.Iterable[int]]):
cv.check_type('track', track, Iterable)
for t in track:
if len(t) != 3:
msg = f'Unable to set the track to "{t}" since its length is not 3'
raise ValueError(msg)
cv.check_greater_than('track batch', t[0], 0)
cv.check_greater_than('track generation', t[0], 0)
cv.check_greater_than('track particle', t[0], 0)
cv.check_greater_than('track generation', t[1], 0)
cv.check_greater_than('track particle', t[2], 0)
cv.check_type('track batch', t[0], Integral)
cv.check_type('track generation', t[1], Integral)
cv.check_type('track particle', t[2], Integral)
self._track = track
@ufs_mesh.setter
@ -881,9 +893,15 @@ class Settings:
@max_splits.setter
def max_splits(self, value: int):
cv.check_type('maximum particle splits', value, Integral)
cv.check_greater_than('max particles in flight', value, 0)
cv.check_greater_than('max particle splits', value, 0)
self._max_splits = value
@max_tracks.setter
def max_tracks(self, value: int):
cv.check_type('maximum particle tracks', value, Integral)
cv.check_greater_than('maximum particle tracks', value, 0, True)
self._max_tracks = value
def _create_run_mode_subelement(self, root):
elem = ET.SubElement(root, "run_mode")
elem.text = self._run_mode.value
@ -1110,7 +1128,7 @@ class Settings:
def _create_track_subelement(self, root):
if self._track is not None:
element = ET.SubElement(root, "track")
element.text = ' '.join(map(str, self._track))
element.text = ' '.join(map(str, itertools.chain(*self._track)))
def _create_ufs_mesh_subelement(self, root):
if self.ufs_mesh is not None:
@ -1196,6 +1214,11 @@ class Settings:
elem = ET.SubElement(root, "max_splits")
elem.text = str(self._max_splits)
def _create_max_tracks_subelement(self, root):
if self._max_tracks is not None:
elem = ET.SubElement(root, "max_tracks")
elem.text = str(self._max_tracks)
def _eigenvalue_from_xml_element(self, root):
elem = root.find('eigenvalue')
if elem is not None:
@ -1424,7 +1447,8 @@ class Settings:
def _track_from_xml_element(self, root):
text = get_text(root, 'track')
if text is not None:
self.track = [int(x) for x in text.split()]
values = [int(x) for x in text.split()]
self.track = list(zip(values[::3], values[1::3], values[2::3]))
def _ufs_mesh_from_xml_element(self, root):
text = get_text(root, 'ufs_mesh')
@ -1498,6 +1522,11 @@ class Settings:
if text is not None:
self.max_splits = int(text)
def _max_tracks_from_xml_element(self, root):
text = get_text(root, 'max_tracks')
if text is not None:
self.max_tracks = int(text)
def export_to_xml(self, path: Union[str, os.PathLike] = 'settings.xml'):
"""Export simulation settings to an XML file.
@ -1554,6 +1583,7 @@ class Settings:
self._create_write_initial_source_subelement(root_element)
self._create_weight_windows_subelement(root_element)
self._create_max_splits_subelement(root_element)
self._create_max_tracks_subelement(root_element)
# Clean the indentation in the file to be user-readable
clean_indentation(root_element)
@ -1633,6 +1663,7 @@ class Settings:
settings._write_initial_source_from_xml_element(root)
settings._weight_windows_from_xml_element(root)
settings._max_splits_from_xml_element(root)
settings._max_tracks_from_xml_element(root)
# TODO: Get volume calculations

View file

@ -298,6 +298,10 @@ class SourceParticle:
self.surf_id = surf_id
self.particle = particle
def __repr__(self):
name = self.particle.name.lower()
return f'<SourceParticle: {name} at E={self.E:.6e} eV>'
def to_tuple(self):
"""Return source particle attributes as a tuple

291
openmc/tracks.py Normal file
View file

@ -0,0 +1,291 @@
from collections import namedtuple
from collections.abc import Sequence
import h5py
from .checkvalue import check_filetype_version
from .source import SourceParticle, ParticleType
ParticleTrack = namedtuple('ParticleTrack', ['particle', 'states'])
ParticleTrack.__doc__ = """\
Particle track information
Parameters
----------
particle : openmc.ParticleType
Type of the particle
states : numpy.ndarray
Structured array containing each state of the particle. The structured array
contains the following fields: ``r`` (position; each direction in [cm]),
``u`` (direction), ``E`` (energy in [eV]), ``time`` (time in [s]), ``wgt``
(weight), ``cell_id`` (cell ID) , ``cell_instance`` (cell instance), and
``material_id`` (material ID).
"""
def _particle_track_repr(self):
name = self.particle.name.lower()
return f"<ParticleTrack: {name}, {len(self.states)} states>"
ParticleTrack.__repr__ = _particle_track_repr
_VERSION_TRACK = 3
def _identifier(dset_name):
"""Return (batch, gen, particle) tuple given dataset name"""
_, batch, gen, particle = dset_name.split('_')
return (int(batch), int(gen), int(particle))
class Track(Sequence):
"""Tracks resulting from a single source particle
This class stores information for all tracks resulting from a primary source
particle and any secondary particles that it created. The track for each
primary/secondary particle is stored in the :attr:`particle_tracks`
attribute.
Parameters
----------
dset : h5py.Dataset
Dataset to read track data from
Attributes
----------
identifier : tuple
Tuple of (batch, generation, particle number)
particle_tracks : list
List of tuples containing (particle type, array of track states)
sources : list
List of :class:`SourceParticle` representing each primary/secondary
particle
"""
def __init__(self, dset):
tracks = dset[()]
offsets = dset.attrs['offsets']
particles = dset.attrs['particles']
self.identifier = _identifier(dset.name)
# Construct list of track histories
tracks_list = []
for particle, start, end in zip(particles, offsets[:-1], offsets[1:]):
ptype = ParticleType(particle)
tracks_list.append(ParticleTrack(ptype, tracks[start:end]))
self.particle_tracks = tracks_list
def __repr__(self):
return f'<Track {self.identifier}: {len(self.particle_tracks)} particles>'
def __getitem__(self, index):
return self.particle_tracks[index]
def __len__(self):
return len(self.particle_tracks)
def filter(self, particle=None, state_filter=None):
"""Filter particle tracks by given criteria
Parameters
----------
particle : {'neutron', 'photon', 'electron', 'positron'}
Matching particle type
state_filter : function
Function that takes a state (structured datatype) and returns a bool
depending on some criteria.
Returns
-------
Track
New instance with only matching :class:`openmc.ParticleTrack` objects
Examples
--------
Get all particle tracks for photons:
>>> track.filter(particle='photon')
Get all particle tracks that entered cell with ID=15:
>>> track.filter(state_filter=lambda s: s['cell_id'] == 15)
Get all particle tracks in entered material with ID=2:
>>> track.filter(state_filter=lambda s: s['material_id'] == 2)
See Also
--------
openmc.ParticleTrack
"""
matching = []
for t in self:
# Check for matching particle
if particle is not None:
if t.particle.name.lower() != particle:
continue
# Apply arbitrary state filter
match = True
if state_filter is not None:
for state in t.states:
if state_filter(state):
break
else:
match = False
if match:
matching.append(t)
# Return new Track instance with only matching particle tracks
track = type(self).__new__(type(self))
track.identifier = self.identifier
track.particle_tracks = matching
return track
def plot(self, axes=None):
"""Produce a 3D plot of particle tracks
Parameters
----------
axes : matplotlib.axes.Axes, optional
Axes for plot
Returns
-------
axes : matplotlib.axes.Axes
Axes for plot
"""
import matplotlib.pyplot as plt
# Setup axes is one wasn't passed
if axes is None:
fig = plt.figure()
ax = plt.axes(projection='3d')
ax.set_xlabel('x [cm]')
ax.set_ylabel('y [cm]')
ax.set_zlabel('z [cm]')
else:
ax = axes
# Plot each particle track
for _, states in self:
r = states['r']
ax.plot3D(r['x'], r['y'], r['z'])
return ax
@property
def sources(self):
sources = []
for particle_track in self:
particle_type = ParticleType(particle_track.particle)
state = particle_track.states[0]
sources.append(
SourceParticle(
r=state['r'], u=state['u'], E=state['E'],
time=state['time'], wgt=state['wgt'],
particle=particle_type
)
)
return sources
class Tracks(list):
"""Collection of particle tracks
This class behaves like a list and can be indexed using the normal subscript
notation. Each element in the list is a :class:`openmc.Track` object.
Parameters
----------
filepath : str or pathlib.Path
Path of file to load
"""
def __init__(self, filepath='tracks.h5'):
# Read data from track file
with h5py.File(filepath, 'r') as fh:
# Check filetype and version
check_filetype_version(fh, 'track', _VERSION_TRACK)
for dset_name in sorted(fh, key=_identifier):
dset = fh[dset_name]
self.append(Track(dset))
def filter(self, particle=None, state_filter=None):
"""Filter tracks by given criteria
Parameters
----------
particle : {'neutron', 'photon', 'electron', 'positron'}
Matching particle type
state_filter : function
Function that takes a state (structured datatype) and returns a bool
depending on some criteria.
Returns
-------
Tracks
List of :class:`openmc.Track` objects
See Also
--------
openmc.Track.filter
"""
# Create a new Tracks instance but avoid call to __init__
matching = type(self).__new__(type(self))
# Append matching Track objects
for track in self:
if track.filter(particle, state_filter):
matching.append(track)
return matching
def plot(self):
"""Produce a 3D plot of particle tracks
Returns
-------
matplotlib.axes.Axes
Axes for plot
"""
import matplotlib.pyplot as plt
fig = plt.figure()
ax = plt.axes(projection='3d')
ax.set_xlabel('x [cm]')
ax.set_ylabel('y [cm]')
ax.set_zlabel('z [cm]')
for track in self:
track.plot(ax)
return ax
@staticmethod
def combine(track_files, path='tracks.h5'):
"""Combine multiple track files into a single track file
Parameters
----------
track_files : list of path-like
Paths to track files to combine
path : path-like
Path of combined track file to create
"""
with h5py.File(path, 'w') as h5_out:
for i, fname in enumerate(track_files):
with h5py.File(fname, 'r') as h5_in:
# Copy file attributes for first file
if i == 0:
h5_out.attrs['filetype'] = h5_in.attrs['filetype']
h5_out.attrs['version'] = h5_in.attrs['version']
# Copy each 'track_*' dataset from input file
for dset in h5_in:
h5_in.copy(dset, h5_out)

24
scripts/openmc-track-combine Executable file
View file

@ -0,0 +1,24 @@
#!/usr/bin/env python3
"""Combine multiple HDF5 particle track files."""
import argparse
import openmc
def main():
# Parse command-line arguments
parser = argparse.ArgumentParser(
description='Combine particle track files into a single .h5 file.')
parser.add_argument('input', metavar='IN', nargs='+',
help='Input HDF5 particle track filename(s).')
parser.add_argument('-o', '--out', metavar='OUT', default='tracks.h5',
help='Output HDF5 particle track file.')
args = parser.parse_args()
openmc.Tracks.combine(args.input, args.out)
if __name__ == '__main__':
main()

View file

@ -4,18 +4,16 @@
"""
import os
import argparse
import struct
import h5py
import openmc
import vtk
def _parse_args():
# Create argument parser.
parser = argparse.ArgumentParser(
description='Convert particle track file to a .pvtp file.')
description='Convert particle track file(s) to a .pvtp file.')
parser.add_argument('input', metavar='IN', type=str, nargs='+',
help='Input particle track data filename(s).')
parser.add_argument('-o', '--out', metavar='OUT', type=str, dest='out',
@ -41,25 +39,22 @@ def main():
point_offset = 0
for fname in args.input:
# Write coordinate values to points array.
track = h5py.File(fname)
n_particles = track.attrs['n_particles']
n_coords = track.attrs['n_coords']
coords = []
for i in range(n_particles):
coords.append(track['coordinates_' + str(i + 1)][()])
for j in range(n_coords[i]):
points.InsertNextPoint(coords[i][j,:])
track_file = openmc.Tracks(fname)
for track in track_file:
for particle in track:
for state in particle.states:
points.InsertNextPoint(state['r'])
for i in range(n_particles):
# Create VTK line and assign points to line.
line = vtk.vtkPolyLine()
line.GetPointIds().SetNumberOfIds(n_coords[i])
for j in range(n_coords[i]):
line.GetPointIds().SetId(j, point_offset + j)
# Create VTK line and assign points to line.
n = particle.states.size
line = vtk.vtkPolyLine()
line.GetPointIds().SetNumberOfIds(n)
for i in range(n):
line.GetPointIds().SetId(i, point_offset + i)
point_offset += n
# Add line to cell array
cells.InsertNextCell(line)
point_offset += n_coords[i]
# Add line to cell array
cells.InsertNextCell(line)
data = vtk.vtkPolyData()
data.SetPoints(points)

View file

@ -85,6 +85,7 @@ int openmc_finalize()
settings::material_cell_offsets = true;
settings::max_particles_in_flight = 100000;
settings::max_splits = 1000;
settings::max_tracks = 1000;
settings::n_inactive = 0;
settings::n_particles = -1;
settings::output_summary = true;

View file

@ -318,7 +318,8 @@ void print_usage()
" -r, --restart Restart a previous run from a state point\n"
" or a particle restart file\n"
" -s, --threads Number of OpenMP threads\n"
" -t, --track Write tracks for all particles\n"
" -t, --track Write tracks for all particles (up to "
"max_tracks)\n"
" -e, --event Run using event-based parallelism\n"
" -v, --version Show version information\n"
" -h, --help Show this message\n");

View file

@ -337,6 +337,11 @@ void Particle::event_revive_from_secondary()
// Check for secondary particles if this particle is dead
if (!alive()) {
// Write final position for this particle
if (write_track()) {
write_particle_track(*this);
}
// If no secondary particles, break out of event loop
if (secondary_bank().empty())
return;
@ -359,7 +364,6 @@ void Particle::event_death()
// Finish particle track output.
if (write_track()) {
write_particle_track(*this);
finalize_particle_track(*this);
}

View file

@ -1,6 +1,8 @@
#include "openmc/particle_data.h"
#include "openmc/cell.h"
#include "openmc/geometry.h"
#include "openmc/material.h"
#include "openmc/nuclide.h"
#include "openmc/photon.h"
#include "openmc/settings.h"
@ -53,4 +55,20 @@ ParticleData::ParticleData()
photon_xs_.resize(data::elements.size());
}
TrackState ParticleData::get_track_state() const
{
TrackState state;
state.r = this->r();
state.u = this->u();
state.E = this->E();
state.time = this->time();
state.wgt = this->wgt();
state.cell_id = model::cells[this->lowest_coord().cell]->id_;
state.cell_instance = this->cell_instance();
if (this->material() != MATERIAL_VOID) {
state.material_id = model::materials[material()]->id_;
}
return state;
}
} // namespace openmc

View file

@ -95,6 +95,7 @@ int n_log_bins {8000};
int n_batches;
int n_max_batches;
int max_splits {1000};
int max_tracks {1000};
ResScatMethod res_scat_method {ResScatMethod::rvs};
double res_scat_energy_min {0.01};
double res_scat_energy_max {1000.0};
@ -877,6 +878,10 @@ void read_settings_xml()
if (check_for_node(root, "max_splits")) {
settings::max_splits = std::stoi(get_node_value(root, "max_splits"));
}
if (check_for_node(root, "max_tracks")) {
settings::max_tracks = std::stoi(get_node_value(root, "max_tracks"));
}
}
void free_memory_settings()

View file

@ -82,6 +82,11 @@ int openmc_simulation_init()
// Allocate source, fission and surface source banks.
allocate_banks();
// Create track file if needed
if (!settings::track_identifiers.empty() || settings::write_all_tracks) {
open_track_file();
}
// If doing an event-based simulation, intialize the particle buffer
// and event queues
if (settings::event_based) {
@ -152,6 +157,11 @@ int openmc_simulation_finalize()
mat->mat_nuclide_index_.clear();
}
// Close track file if open
if (!settings::track_identifiers.empty() || settings::write_all_tracks) {
close_track_file();
}
// Increment total number of generations
simulation::total_gen += simulation::current_batch * settings::gen_per_batch;
@ -507,18 +517,7 @@ void initialize_history(Particle& p, int64_t index_source)
p.trace() = true;
// Set particle track.
p.write_track() = false;
if (settings::write_all_tracks) {
p.write_track() = true;
} else if (settings::track_identifiers.size() > 0) {
for (const auto& t : settings::track_identifiers) {
if (simulation::current_batch == t[0] &&
simulation::current_gen == t[1] && p.id() == t[2]) {
p.write_track() = true;
break;
}
}
}
p.write_track() = check_track_criteria(p);
// Display message if high verbosity or trace is on
if (settings::verbosity >= 9 || p.trace()) {

View file

@ -2,6 +2,7 @@
#include "openmc/constants.h"
#include "openmc/hdf5_interface.h"
#include "openmc/message_passing.h"
#include "openmc/position.h"
#include "openmc/settings.h"
#include "openmc/simulation.h"
@ -9,6 +10,7 @@
#include "xtensor/xtensor.hpp"
#include <fmt/core.h>
#include <hdf5.h>
#include <cstddef> // for size_t
#include <string>
@ -19,6 +21,10 @@ namespace openmc {
// Global variables
//==============================================================================
hid_t track_file; //! HDF5 identifier for track file
hid_t track_dtype; //! HDF5 identifier for track datatype
int n_tracks_written; //! Number of tracks written
//==============================================================================
// Non-member functions
//==============================================================================
@ -26,45 +32,123 @@ namespace openmc {
void add_particle_track(Particle& p)
{
p.tracks().emplace_back();
p.tracks().back().particle = p.type();
}
void write_particle_track(Particle& p)
{
p.tracks().back().push_back(p.r());
p.tracks().back().states.push_back(p.get_track_state());
}
void open_track_file()
{
// Open file and write filetype/version -- when MPI is enabled and there is
// more than one rank, each rank writes its own file
#ifdef OPENMC_MPI
std::string filename;
if (mpi::n_procs > 1) {
filename = fmt::format("{}tracks_p{}.h5", settings::path_output, mpi::rank);
} else {
filename = fmt::format("{}tracks.h5", settings::path_output);
}
#else
std::string filename = fmt::format("{}tracks.h5", settings::path_output);
#endif
track_file = file_open(filename, 'w');
write_attribute(track_file, "filetype", "track");
write_attribute(track_file, "version", VERSION_TRACK);
// Create compound type for Position
hid_t postype = H5Tcreate(H5T_COMPOUND, sizeof(struct Position));
H5Tinsert(postype, "x", HOFFSET(Position, x), H5T_NATIVE_DOUBLE);
H5Tinsert(postype, "y", HOFFSET(Position, y), H5T_NATIVE_DOUBLE);
H5Tinsert(postype, "z", HOFFSET(Position, z), H5T_NATIVE_DOUBLE);
// Create compound type for TrackState
track_dtype = H5Tcreate(H5T_COMPOUND, sizeof(struct TrackState));
H5Tinsert(track_dtype, "r", HOFFSET(TrackState, r), postype);
H5Tinsert(track_dtype, "u", HOFFSET(TrackState, u), postype);
H5Tinsert(track_dtype, "E", HOFFSET(TrackState, E), H5T_NATIVE_DOUBLE);
H5Tinsert(track_dtype, "time", HOFFSET(TrackState, time), H5T_NATIVE_DOUBLE);
H5Tinsert(track_dtype, "wgt", HOFFSET(TrackState, wgt), H5T_NATIVE_DOUBLE);
H5Tinsert(
track_dtype, "cell_id", HOFFSET(TrackState, cell_id), H5T_NATIVE_INT);
H5Tinsert(track_dtype, "cell_instance", HOFFSET(TrackState, cell_instance),
H5T_NATIVE_INT);
H5Tinsert(track_dtype, "material_id", HOFFSET(TrackState, material_id),
H5T_NATIVE_INT);
H5Tclose(postype);
}
void close_track_file()
{
H5Tclose(track_dtype);
file_close(track_file);
// Reset number of tracks written
n_tracks_written = 0;
}
bool check_track_criteria(const Particle& p)
{
if (settings::write_all_tracks) {
// Increment number of tracks written and get previous value
int n;
#pragma omp atomic capture
n = n_tracks_written++;
// Indicate that track should be written for this particle
return n < settings::max_tracks;
}
// Check for match from explicit track identifiers
if (settings::track_identifiers.size() > 0) {
for (const auto& t : settings::track_identifiers) {
if (simulation::current_batch == t[0] &&
simulation::current_gen == t[1] && p.id() == t[2]) {
return true;
}
}
}
return false;
}
void finalize_particle_track(Particle& p)
{
std::string filename =
fmt::format("{}track_{}_{}_{}.h5", settings::path_output,
simulation::current_batch, simulation::current_gen, p.id());
// Determine number of coordinates for each particle
vector<int> n_coords;
for (auto& coords : p.tracks()) {
n_coords.push_back(coords.size());
vector<int> offsets;
vector<int> particles;
vector<TrackState> tracks;
int offset = 0;
for (auto& track_i : p.tracks()) {
offsets.push_back(offset);
particles.push_back(static_cast<int>(track_i.particle));
offset += track_i.states.size();
tracks.insert(tracks.end(), track_i.states.begin(), track_i.states.end());
}
offsets.push_back(offset);
#pragma omp critical(FinalizeParticleTrack)
{
hid_t file_id = file_open(filename, 'w');
write_attribute(file_id, "filetype", "track");
write_attribute(file_id, "version", VERSION_TRACK);
write_attribute(file_id, "n_particles", p.tracks().size());
write_attribute(file_id, "n_coords", n_coords);
for (auto i = 1; i <= p.tracks().size(); ++i) {
const auto& t {p.tracks()[i - 1]};
size_t n = t.size();
xt::xtensor<double, 2> data({n, 3});
for (int j = 0; j < n; ++j) {
data(j, 0) = t[j].x;
data(j, 1) = t[j].y;
data(j, 2) = t[j].z;
}
std::string name = fmt::format("coordinates_{}", i);
write_dataset(file_id, name.c_str(), data);
}
file_close(file_id);
// Create name for dataset
std::string dset_name = fmt::format("track_{}_{}_{}",
simulation::current_batch, simulation::current_gen, p.id());
// Write array of TrackState to file
hsize_t dims[] {static_cast<hsize_t>(tracks.size())};
hid_t dspace = H5Screate_simple(1, dims, nullptr);
hid_t dset = H5Dcreate(track_file, dset_name.c_str(), track_dtype, dspace,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Dwrite(dset, track_dtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, tracks.data());
// Write attributes
write_attribute(dset, "n_particles", p.tracks().size());
write_attribute(dset, "offsets", offsets);
write_attribute(dset, "particles", particles);
// Free resources
H5Dclose(dset);
H5Sclose(dspace);
}
// Clear particle tracks

View file

@ -1,9 +1,266 @@
<?xml version="1.0"?>
<VTKFile type="PPolyData" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
<PPolyData GhostLevel="0">
<PPoints>
<PDataArray type="Float32" Name="Points" NumberOfComponents="3"/>
</PPoints>
<Piece Source="poly_0.vtp"/>
</PPolyData>
</VTKFile>
ParticleType.NEUTRON [((-9.663085e-01, -6.616522e-01, -9.863690e-01), (-7.513921e-01, 4.140970e-01, 5.137447e-01), 5.293873e+06, 0.000000e+00, 1.000000e+00, 23, 2403, 1)
((-1.281491e+00, -4.879529e-01, -7.708709e-01), (-7.513921e-01, 4.140970e-01, 5.137447e-01), 5.293873e+06, 1.323629e-10, 1.000000e+00, 22, 2403, 3)
((-1.368452e+00, -4.400285e-01, -7.114141e-01), (-7.513921e-01, 4.140970e-01, 5.137447e-01), 5.293873e+06, 1.688824e-10, 1.000000e+00, 21, 2403, 2)
((-2.150539e+00, -9.015151e-03, -1.766823e-01), (-7.513921e-01, 4.140970e-01, 5.137447e-01), 5.293873e+06, 4.973246e-10, 1.000000e+00, 22, 2403, 3)
((-2.237499e+00, 3.890922e-02, -1.172255e-01), (-7.513921e-01, 4.140970e-01, 5.137447e-01), 5.293873e+06, 5.338441e-10, 1.000000e+00, 23, 2403, 1)
((-2.453640e+00, 1.580257e-01, 3.055504e-02), (-7.513921e-01, 4.140970e-01, 5.137447e-01), 5.293873e+06, 6.246136e-10, 1.000000e+00, 23, 2402, 1)
((-2.767485e+00, 3.309877e-01, 2.451383e-01), (-7.513921e-01, 4.140970e-01, 5.137447e-01), 5.293873e+06, 7.564146e-10, 1.000000e+00, 22, 2402, 3)
((-2.825099e+00, 3.627392e-01, 2.845305e-01), (-6.842434e-01, 3.658561e-01, 6.308409e-01), 5.292729e+06, 7.806100e-10, 1.000000e+00, 22, 2402, 3)
((-3.274427e+00, 6.029890e-01, 6.987901e-01), (-6.842434e-01, 3.658561e-01, 6.308409e-01), 5.292729e+06, 9.878481e-10, 1.000000e+00, 23, 2402, 1)
((-3.676327e+00, 8.178800e-01, 1.069324e+00), (-6.842434e-01, 3.658561e-01, 6.308409e-01), 5.292729e+06, 1.173212e-09, 1.000000e+00, 23, 2416, 1)
((-4.089400e+00, 1.038745e+00, 1.450158e+00), (-6.842434e-01, 3.658561e-01, 6.308409e-01), 5.292729e+06, 1.363728e-09, 1.000000e+00, 23, 2415, 1)
((-4.456639e+00, 1.235102e+00, 1.788735e+00), (-6.842434e-01, 3.658561e-01, 6.308409e-01), 5.292729e+06, 1.533105e-09, 1.000000e+00, 22, 2415, 3)
((-4.536974e+00, 1.278056e+00, 1.862800e+00), (-6.842434e-01, 3.658561e-01, 6.308409e-01), 5.292729e+06, 1.570157e-09, 1.000000e+00, 21, 2415, 2)
((-5.410401e+00, 1.745067e+00, 2.668060e+00), (-6.842434e-01, 3.658561e-01, 6.308409e-01), 5.292729e+06, 1.972998e-09, 1.000000e+00, 22, 2415, 3)
((-5.490736e+00, 1.788021e+00, 2.742125e+00), (-6.842434e-01, 3.658561e-01, 6.308409e-01), 5.292729e+06, 2.010050e-09, 1.000000e+00, 23, 2415, 1)
((-5.576301e+00, 1.833771e+00, 2.821012e+00), (-2.881377e-01, 1.217316e-01, -9.498200e-01), 4.458753e+06, 2.049514e-09, 1.000000e+00, 23, 2415, 1)
((-5.725160e+00, 1.896661e+00, 2.330311e+00), (-2.881377e-01, 1.217316e-01, -9.498200e-01), 4.458753e+06, 2.227030e-09, 1.000000e+00, 23, 2414, 1)
((-6.116514e+00, 2.061999e+00, 1.040248e+00), (-2.881377e-01, 1.217316e-01, -9.498200e-01), 4.458753e+06, 2.693724e-09, 1.000000e+00, 22, 2414, 3)
((-6.534762e+00, 2.238699e+00, -3.384686e-01), (-2.881377e-01, 1.217316e-01, -9.498200e-01), 4.458753e+06, 3.192489e-09, 1.000000e+00, 23, 2414, 1)
((-7.043525e+00, 2.453640e+00, -2.015560e+00), (-2.881377e-01, 1.217316e-01, -9.498200e-01), 4.458753e+06, 3.799195e-09, 1.000000e+00, 23, 2428, 1)
((-7.360920e+00, 2.587732e+00, -3.061825e+00), (-2.881377e-01, 1.217316e-01, -9.498200e-01), 4.458753e+06, 4.177692e-09, 1.000000e+00, 11, 1757, 1)
((-8.996680e+00, 3.278803e+00, -8.453960e+00), (-2.881377e-01, 1.217316e-01, -9.498200e-01), 4.458753e+06, 6.128354e-09, 1.000000e+00, 23, 2427, 1)
((-9.220205e+00, 3.373238e+00, -9.190791e+00), (-2.881377e-01, 1.217316e-01, -9.498200e-01), 4.458753e+06, 6.394910e-09, 1.000000e+00, 22, 2427, 3)
((-9.320244e+00, 3.415502e+00, -9.520561e+00), (-2.881377e-01, 1.217316e-01, -9.498200e-01), 4.458753e+06, 6.514208e-09, 1.000000e+00, 21, 2427, 2)
((-1.005591e+01, 3.726304e+00, -1.194562e+01), (-2.881377e-01, 1.217316e-01, -9.498200e-01), 4.458753e+06, 7.391498e-09, 1.000000e+00, 22, 2427, 3)
((-1.015595e+01, 3.768569e+00, -1.227539e+01), (-2.881377e-01, 1.217316e-01, -9.498200e-01), 4.458753e+06, 7.510796e-09, 1.000000e+00, 23, 2427, 1)
((-1.062054e+01, 3.964848e+00, -1.380687e+01), (-5.395885e-01, 2.109921e-01, -8.150623e-01), 4.068754e+06, 8.064826e-09, 1.000000e+00, 23, 2427, 1)
((-1.063244e+01, 3.969501e+00, -1.382484e+01), (-5.395885e-01, 2.109921e-01, -8.150623e-01), 4.068754e+06, 8.072756e-09, 1.000000e+00, 23, 2426, 1)
((-1.093907e+01, 4.089400e+00, -1.428802e+01), (-5.395885e-01, 2.109921e-01, -8.150623e-01), 4.068754e+06, 8.277097e-09, 1.000000e+00, 23, 2437, 1)
((-1.108410e+01, 4.146112e+00, -1.450710e+01), (4.855193e-01, 3.316053e-01, -8.088937e-01), 8.856868e+05, 8.373750e-09, 1.000000e+00, 23, 2437, 1)
((-1.080173e+01, 4.338973e+00, -1.497755e+01), (2.818553e-01, 5.419536e-02, -9.579251e-01), 7.653670e+05, 8.820862e-09, 1.000000e+00, 23, 2437, 1)
((-1.063244e+01, 4.371524e+00, -1.555290e+01), (2.818553e-01, 5.419536e-02, -9.579251e-01), 7.653670e+05, 9.317522e-09, 1.000000e+00, 23, 2438, 1)
((-1.041266e+01, 4.413783e+00, -1.629984e+01), (2.686183e-01, -3.269476e-01, -9.060626e-01), 6.562001e+05, 9.962308e-09, 1.000000e+00, 23, 2438, 1)
((-1.016754e+01, 4.115428e+00, -1.712667e+01), (-6.340850e-01, -7.142137e-01, -2.963697e-01), 7.155058e+04, 1.077718e-08, 1.000000e+00, 23, 2438, 1)
((-1.019064e+01, 4.089400e+00, -1.713747e+01), (-6.340850e-01, -7.142137e-01, -2.963697e-01), 7.155058e+04, 1.087569e-08, 1.000000e+00, 23, 2427, 1)
((-1.024915e+01, 4.023496e+00, -1.716481e+01), (1.827568e-01, -7.452255e-01, -6.412791e-01), 2.628504e+04, 1.112511e-08, 1.000000e+00, 23, 2427, 1)
((-1.018199e+01, 3.749638e+00, -1.740047e+01), (1.827568e-01, -7.452255e-01, -6.412791e-01), 2.628504e+04, 1.276389e-08, 1.000000e+00, 22, 2427, 3)
((-1.015866e+01, 3.654498e+00, -1.748234e+01), (1.827568e-01, -7.452255e-01, -6.412791e-01), 2.628504e+04, 1.333321e-08, 1.000000e+00, 21, 2427, 2)
((-1.009978e+01, 3.414404e+00, -1.768895e+01), (1.735861e-01, -9.678731e-01, 1.819053e-01), 2.620416e+04, 1.476994e-08, 1.000000e+00, 21, 2427, 2)
((-9.994809e+00, 2.829099e+00, -1.757894e+01), (4.635724e-01, 5.558106e-01, 6.900545e-01), 2.214649e+04, 1.747088e-08, 1.000000e+00, 21, 2427, 2)
((-9.553365e+00, 3.358379e+00, -1.692183e+01), (-5.990363e-01, 3.483710e-01, -7.209668e-01), 1.813617e+04, 2.209726e-08, 1.000000e+00, 21, 2427, 2)
((-1.011854e+01, 3.687059e+00, -1.760205e+01), (-5.990363e-01, 3.483710e-01, -7.209668e-01), 1.813617e+04, 2.716243e-08, 1.000000e+00, 22, 2427, 3)
((-1.020058e+01, 3.734765e+00, -1.770077e+01), (-5.990363e-01, 3.483710e-01, -7.209668e-01), 1.813617e+04, 2.789760e-08, 1.000000e+00, 23, 2427, 1)
((-1.063244e+01, 3.985917e+00, -1.822054e+01), (-5.990363e-01, 3.483710e-01, -7.209668e-01), 1.813617e+04, 3.176800e-08, 1.000000e+00, 23, 2426, 1)
((-1.081038e+01, 4.089400e+00, -1.843470e+01), (-5.990363e-01, 3.483710e-01, -7.209668e-01), 1.813617e+04, 3.336273e-08, 1.000000e+00, 23, 2437, 1)
((-1.081564e+01, 4.092455e+00, -1.844103e+01), (-6.690877e-01, 6.718700e-01, -3.176671e-01), 1.355236e+04, 3.340982e-08, 1.000000e+00, 23, 2437, 1)
((-1.096190e+01, 4.239327e+00, -1.851047e+01), (-5.904492e-01, 8.058629e-01, 4.421237e-02), 1.153343e+04, 3.476743e-08, 1.000000e+00, 23, 2437, 1)
((-1.109457e+01, 4.420404e+00, -1.850054e+01), (-5.904492e-01, 8.058629e-01, 4.421237e-02), 1.153343e+04, 3.628014e-08, 1.000000e+00, 22, 2437, 3)
((-1.113484e+01, 4.475368e+00, -1.849752e+01), (-3.382310e-01, -9.403895e-01, -3.560132e-02), 1.114105e+04, 3.673931e-08, 1.000000e+00, 22, 2437, 3)
((-1.117187e+01, 4.372425e+00, -1.850142e+01), (-3.382310e-01, -9.403895e-01, -3.560132e-02), 1.114105e+04, 3.748914e-08, 1.000000e+00, 23, 2437, 1)
((-1.127367e+01, 4.089400e+00, -1.851213e+01), (-3.382310e-01, -9.403895e-01, -3.560132e-02), 1.114105e+04, 3.955064e-08, 1.000000e+00, 23, 2426, 1)
((-1.135375e+01, 3.866733e+00, -1.852056e+01), (-3.382310e-01, -9.403895e-01, -3.560132e-02), 1.114105e+04, 4.117251e-08, 1.000000e+00, 22, 2426, 3)
((-1.138419e+01, 3.782113e+00, -1.852377e+01), (-3.382310e-01, -9.403895e-01, -3.560132e-02), 1.114105e+04, 4.178887e-08, 1.000000e+00, 21, 2426, 2)
((-1.172456e+01, 2.835777e+00, -1.855959e+01), (-3.382310e-01, -9.403895e-01, -3.560132e-02), 1.114105e+04, 4.868184e-08, 1.000000e+00, 22, 2426, 3)
((-1.175499e+01, 2.751157e+00, -1.856280e+01), (-3.382310e-01, -9.403895e-01, -3.560132e-02), 1.114105e+04, 4.929820e-08, 1.000000e+00, 23, 2426, 1)
((-1.179525e+01, 2.639224e+00, -1.856703e+01), (-4.738733e-01, -7.934600e-01, 3.819231e-01), 8.873828e+03, 5.011351e-08, 1.000000e+00, 23, 2426, 1)
((-1.190609e+01, 2.453640e+00, -1.847770e+01), (-4.738733e-01, -7.934600e-01, 3.819231e-01), 8.873828e+03, 5.190861e-08, 1.000000e+00, 23, 2411, 1)
((-1.222017e+01, 1.927741e+00, -1.822457e+01), (-5.716267e-01, 2.823908e-01, 7.703884e-01), 1.028345e+03, 5.699551e-08, 1.000000e+00, 23, 2411, 1)
((-1.226820e+01, 1.951470e+00, -1.815983e+01), (-5.716267e-01, 2.823908e-01, 7.703884e-01), 1.028345e+03, 5.888995e-08, 1.000000e+00, 23, 2100, 1)
((-1.236181e+01, 1.997712e+00, -1.803368e+01), (1.748787e-01, 6.613493e-01, 7.294070e-01), 4.250133e+02, 6.258186e-08, 1.000000e+00, 23, 2100, 1)
((-1.234968e+01, 2.043587e+00, -1.798308e+01), (-6.043263e-01, 1.493281e-01, 7.826180e-01), 4.022525e+02, 6.501444e-08, 1.000000e+00, 23, 2100, 1)
((-1.276513e+01, 2.146245e+00, -1.744506e+01), (-6.043263e-01, 1.493281e-01, 7.826180e-01), 4.022525e+02, 8.979603e-08, 1.000000e+00, 22, 2100, 3)
((-1.313233e+01, 2.236980e+00, -1.696953e+01), (-6.043263e-01, 1.493281e-01, 7.826180e-01), 4.022525e+02, 1.116994e-07, 1.000000e+00, 23, 2100, 1)
((-1.318468e+01, 2.249916e+00, -1.690173e+01), (-8.862976e-01, -6.402442e-02, 4.586692e-01), 3.113244e+02, 1.148223e-07, 1.000000e+00, 23, 2100, 1)
((-1.363685e+01, 2.217253e+00, -1.666773e+01), (5.149966e-01, 4.184610e-01, -7.481102e-01), 2.471907e+02, 1.357269e-07, 1.000000e+00, 23, 2100, 1)
((-1.334593e+01, 2.453640e+00, -1.709033e+01), (5.149966e-01, 4.184610e-01, -7.481102e-01), 2.471907e+02, 1.617034e-07, 1.000000e+00, 23, 2101, 1)
((-1.308145e+01, 2.668542e+00, -1.747452e+01), (5.149966e-01, 4.184610e-01, -7.481102e-01), 2.471907e+02, 1.853189e-07, 1.000000e+00, 22, 2101, 3)
((-1.304150e+01, 2.701005e+00, -1.753256e+01), (-1.624676e-01, -9.847331e-01, 6.248920e-02), 2.387811e+02, 1.888862e-07, 1.000000e+00, 22, 2101, 3)
((-1.304665e+01, 2.669815e+00, -1.753058e+01), (-1.624676e-01, -9.847331e-01, 6.248920e-02), 2.387811e+02, 1.903682e-07, 1.000000e+00, 23, 2101, 1)
((-1.308231e+01, 2.453640e+00, -1.751686e+01), (-1.624676e-01, -9.847331e-01, 6.248920e-02), 2.387811e+02, 2.006392e-07, 1.000000e+00, 23, 2100, 1)
((-1.311790e+01, 2.237916e+00, -1.750317e+01), (-1.624676e-01, -9.847331e-01, 6.248920e-02), 2.387811e+02, 2.108888e-07, 1.000000e+00, 22, 2100, 3)
((-1.313266e+01, 2.148507e+00, -1.749750e+01), (-1.624676e-01, -9.847331e-01, 6.248920e-02), 2.387811e+02, 2.151369e-07, 1.000000e+00, 21, 2100, 2)
((-1.320190e+01, 1.728791e+00, -1.747087e+01), (1.090151e-01, 4.333767e-01, -8.945950e-01), 2.357642e+02, 2.350787e-07, 1.000000e+00, 21, 2100, 2)
((-1.309582e+01, 2.150526e+00, -1.834143e+01), (1.090151e-01, 4.333767e-01, -8.945950e-01), 2.357642e+02, 2.808996e-07, 1.000000e+00, 22, 2100, 3)
((-1.307365e+01, 2.238628e+00, -1.852329e+01), (1.090151e-01, 4.333767e-01, -8.945950e-01), 2.357642e+02, 2.904717e-07, 1.000000e+00, 23, 2100, 1)
((-1.301957e+01, 2.453640e+00, -1.896713e+01), (1.090151e-01, 4.333767e-01, -8.945950e-01), 2.357642e+02, 3.138324e-07, 1.000000e+00, 23, 2101, 1)
((-1.297913e+01, 2.614390e+00, -1.929896e+01), (6.012134e-01, 7.985735e-01, -2.868317e-02), 4.041011e+01, 3.312976e-07, 1.000000e+00, 23, 2101, 1)
((-1.295975e+01, 2.640133e+00, -1.929988e+01), (6.762805e-01, -5.875192e-01, 4.443713e-01), 3.527833e+01, 3.349640e-07, 1.000000e+00, 23, 2101, 1)
((-1.282907e+01, 2.526604e+00, -1.921402e+01), (-1.767101e-01, -9.842348e-01, 7.448995e-03), 6.258032e+00, 3.584852e-07, 1.000000e+00, 23, 2101, 1)
((-1.284217e+01, 2.453640e+00, -1.921346e+01), (-1.767101e-01, -9.842348e-01, 7.448995e-03), 6.258032e+00, 3.799102e-07, 1.000000e+00, 23, 2100, 1)
((-1.288683e+01, 2.204886e+00, -1.921158e+01), (-1.767101e-01, -9.842348e-01, 7.448995e-03), 6.258032e+00, 4.529534e-07, 1.000000e+00, 22, 2100, 3)
((-1.290264e+01, 2.116831e+00, -1.921091e+01), (-1.767101e-01, -9.842348e-01, 7.448995e-03), 6.258032e+00, 4.788097e-07, 1.000000e+00, 21, 2100, 2)
((-1.308145e+01, 1.120923e+00, -1.920338e+01), (-1.767101e-01, -9.842348e-01, 7.448995e-03), 6.258032e+00, 7.712448e-07, 1.000000e+00, 22, 2100, 3)
((-1.309726e+01, 1.032868e+00, -1.920271e+01), (-1.767101e-01, -9.842348e-01, 7.448995e-03), 6.258032e+00, 7.971010e-07, 1.000000e+00, 23, 2100, 1)
((-1.312690e+01, 8.677798e-01, -1.920146e+01), (-6.009065e-01, -7.617185e-01, 2.422732e-01), 3.971935e+00, 8.455768e-07, 1.000000e+00, 23, 2100, 1)
((-1.316626e+01, 8.178800e-01, -1.918559e+01), (-6.009065e-01, -7.617185e-01, 2.422732e-01), 3.971935e+00, 8.693415e-07, 1.000000e+00, 23, 2099, 1)
((-1.324019e+01, 7.241633e-01, -1.915578e+01), (-9.367321e-01, -1.471894e-01, -3.175976e-01), 2.365289e+00, 9.139738e-07, 1.000000e+00, 23, 2099, 1)
((-1.348497e+01, 6.857011e-01, -1.923877e+01), (-9.722929e-01, 2.325825e-01, -2.349230e-02), 1.799413e+00, 1.036815e-06, 1.000000e+00, 23, 2099, 1)
((-1.390396e+01, 7.859275e-01, -1.924890e+01), (-9.722929e-01, 2.325825e-01, -2.349230e-02), 1.799413e+00, 1.269071e-06, 1.000000e+00, 23, 2114, 1)
((-1.403754e+01, 8.178800e-01, -1.925212e+01), (-9.722929e-01, 2.325825e-01, -2.349230e-02), 1.799413e+00, 1.343115e-06, 1.000000e+00, 23, 2115, 1)
((-1.504223e+01, 1.058212e+00, -1.927640e+01), (-4.085804e-01, -2.719942e-01, -8.712526e-01), 1.628266e+00, 1.900041e-06, 1.000000e+00, 23, 2115, 1)
((-1.523744e+01, 9.282558e-01, -1.969268e+01), (-6.666265e-01, 3.934879e-01, -6.330690e-01), 4.946445e-01, 2.170751e-06, 1.000000e+00, 23, 2115, 1)
((-1.553972e+01, 1.106680e+00, -1.997974e+01), (-6.666265e-01, 3.934879e-01, -6.330690e-01), 4.946445e-01, 2.636878e-06, 1.000000e+00, 23, 2129, 1)
((-1.585973e+01, 1.295571e+00, -2.028364e+01), (-6.666265e-01, 3.934879e-01, -6.330690e-01), 4.946445e-01, 3.130348e-06, 1.000000e+00, 22, 2129, 3)
((-1.593583e+01, 1.340489e+00, -2.035590e+01), (-6.666265e-01, 3.934879e-01, -6.330690e-01), 4.946445e-01, 3.247693e-06, 1.000000e+00, 21, 2129, 2)
((-1.647184e+01, 1.656882e+00, -2.086494e+01), (6.457458e-01, -1.162934e-01, -7.546444e-01), 4.958073e-01, 4.074258e-06, 1.000000e+00, 21, 2129, 2)
((-1.585080e+01, 1.545037e+00, -2.159072e+01), (6.457458e-01, -1.162934e-01, -7.546444e-01), 4.958073e-01, 5.061748e-06, 1.000000e+00, 22, 2129, 3)
((-1.576406e+01, 1.529415e+00, -2.169209e+01), (6.457458e-01, -1.162934e-01, -7.546444e-01), 4.958073e-01, 5.199673e-06, 1.000000e+00, 23, 2129, 1)
((-1.553972e+01, 1.489015e+00, -2.195425e+01), (6.457458e-01, -1.162934e-01, -7.546444e-01), 4.958073e-01, 5.556377e-06, 1.000000e+00, 23, 2115, 1)
((-1.546081e+01, 1.474803e+00, -2.204648e+01), (3.257038e-01, -9.420596e-01, -8.025439e-02), 3.076319e-01, 5.681852e-06, 1.000000e+00, 23, 2115, 1)
((-1.543563e+01, 1.401988e+00, -2.205268e+01), (-3.677195e-01, -8.784218e-01, -3.052172e-01), 8.422973e-02, 5.782605e-06, 1.000000e+00, 23, 2115, 1)
((-1.553972e+01, 1.153338e+00, -2.213907e+01), (-3.677195e-01, -8.784218e-01, -3.052172e-01), 8.422973e-02, 6.487752e-06, 1.000000e+00, 23, 2129, 1)
((-1.565955e+01, 8.670807e-01, -2.223854e+01), (1.611814e-01, 2.692337e-01, -9.494913e-01), 8.559448e-02, 7.299552e-06, 1.000000e+00, 23, 2129, 1)
((-1.563263e+01, 9.120446e-01, -2.239711e+01), (-6.773989e-01, 6.985688e-01, -2.305048e-01), 3.418159e-02, 7.712256e-06, 1.000000e+00, 23, 2129, 1)
((-1.592604e+01, 1.214620e+00, -2.249695e+01), (-6.773989e-01, 6.985688e-01, -2.305048e-01), 3.418159e-02, 9.406031e-06, 1.000000e+00, 22, 2129, 3)
((-1.598742e+01, 1.277922e+00, -2.251784e+01), (-6.773989e-01, 6.985688e-01, -2.305048e-01), 3.418159e-02, 9.760391e-06, 1.000000e+00, 21, 2129, 2)
((-1.670388e+01, 2.016770e+00, -2.276163e+01), (-6.773989e-01, 6.985688e-01, -2.305048e-01), 3.418159e-02, 1.389636e-05, 1.000000e+00, 22, 2129, 3)
((-1.676526e+01, 2.080073e+00, -2.278252e+01), (-6.773989e-01, 6.985688e-01, -2.305048e-01), 3.418159e-02, 1.425072e-05, 1.000000e+00, 23, 2129, 1)
((-1.681575e+01, 2.132139e+00, -2.279970e+01), (4.286076e-02, -9.409799e-01, -3.357375e-01), 1.813618e-02, 1.454218e-05, 1.000000e+00, 23, 2129, 1)
((-1.681374e+01, 2.087933e+00, -2.281547e+01), (-7.741702e-02, -7.222450e-01, -6.872909e-01), 1.529603e-02, 1.479439e-05, 1.000000e+00, 23, 2129, 1)
((-1.682083e+01, 2.021795e+00, -2.287841e+01), (-7.741702e-02, -7.222450e-01, -6.872909e-01), 1.529603e-02, 1.532970e-05, 1.000000e+00, 22, 2129, 3)
((-1.684417e+01, 1.804084e+00, -2.308558e+01), (-7.741702e-02, -7.222450e-01, -6.872909e-01), 1.529603e-02, 1.709182e-05, 1.000000e+00, 21, 2129, 2)
((-1.686879e+01, 1.574384e+00, -2.330417e+01), (-7.741702e-02, -7.222450e-01, -6.872909e-01), 1.529603e-02, 1.895097e-05, 1.000000e+00, 22, 2129, 3)
((-1.689212e+01, 1.356673e+00, -2.351134e+01), (-7.741702e-02, -7.222450e-01, -6.872909e-01), 1.529603e-02, 2.071309e-05, 1.000000e+00, 23, 2129, 1)
((-1.689233e+01, 1.354754e+00, -2.351317e+01), (6.002458e-01, 4.967948e-01, 6.268172e-01), 8.602342e-03, 2.072862e-05, 1.000000e+00, 23, 2129, 1)
((-1.689148e+01, 1.355453e+00, -2.351229e+01), (6.002458e-01, 4.967948e-01, 6.268172e-01), 8.602342e-03, 2.073958e-05, 1.000000e+00, 22, 2129, 3)
((-1.682182e+01, 1.413107e+00, -2.343954e+01), (6.002458e-01, 4.967948e-01, 6.268172e-01), 8.602342e-03, 2.164421e-05, 1.000000e+00, 21, 2129, 2)
((-1.636364e+01, 1.792326e+00, -2.296107e+01), (9.641593e-01, -1.162836e-01, 2.384846e-01), 7.837617e-03, 2.759442e-05, 1.000000e+00, 21, 2129, 2)
((-1.598564e+01, 1.746738e+00, -2.286758e+01), (9.641593e-01, -1.162836e-01, 2.384846e-01), 7.837617e-03, 3.079609e-05, 0.000000e+00, 21, 2129, 2)]
ParticleType.NEUTRON [((-9.469716e-01, -2.580266e-01, 1.414357e-01), (1.438873e-01, 2.365819e-01, 9.608983e-01), 9.724461e+05, 0.000000e+00, 1.000000e+00, 23, 2403, 1)
((-9.064818e-01, -1.914524e-01, 4.118326e-01), (9.231638e-01, 3.100833e-01, 2.271937e-01), 1.746594e+05, 2.064696e-10, 1.000000e+00, 23, 2403, 1)
((-8.178800e-01, -1.616918e-01, 4.336377e-01), (9.231638e-01, 3.100833e-01, 2.271937e-01), 1.746594e+05, 3.725262e-10, 1.000000e+00, 11, 1756, 1)
((-3.834875e-01, -1.578285e-02, 5.405432e-01), (-5.547498e-01, -6.358598e-02, 8.295839e-01), 1.474011e+05, 1.186660e-09, 1.000000e+00, 11, 1756, 1)
((-7.999329e-01, -6.351625e-02, 1.163304e+00), (-5.476898e-01, 2.985279e-03, 8.366761e-01), 1.467299e+05, 2.600465e-09, 1.000000e+00, 11, 1756, 1)
((-8.178800e-01, -6.341842e-02, 1.190721e+00), (-5.476898e-01, 2.985279e-03, 8.366761e-01), 1.467299e+05, 2.662321e-09, 1.000000e+00, 23, 2403, 1)
((-1.035984e+00, -6.222961e-02, 1.523906e+00), (-5.476898e-01, 2.985279e-03, 8.366761e-01), 1.467299e+05, 3.414026e-09, 1.000000e+00, 22, 2403, 3)
((-1.124618e+00, -6.174649e-02, 1.659308e+00), (-5.476898e-01, 2.985279e-03, 8.366761e-01), 1.467299e+05, 3.719509e-09, 1.000000e+00, 21, 2403, 2)
((-1.705404e+00, -5.858082e-02, 2.546543e+00), (-3.196694e-01, -8.974451e-01, 3.039799e-01), 1.460188e+05, 5.721217e-09, 1.000000e+00, 21, 2403, 2)
((-1.851116e+00, -4.676544e-01, 2.685103e+00), (-3.196694e-01, -8.974451e-01, 3.039799e-01), 1.460188e+05, 6.583734e-09, 1.000000e+00, 22, 2403, 3)
((-1.880791e+00, -5.509662e-01, 2.713322e+00), (-3.196694e-01, -8.974451e-01, 3.039799e-01), 1.460188e+05, 6.759394e-09, 1.000000e+00, 23, 2403, 1)
((-1.948026e+00, -7.397227e-01, 2.777257e+00), (-8.068708e-01, -5.218555e-01, -2.768147e-01), 6.012975e+04, 7.157380e-09, 1.000000e+00, 23, 2403, 1)
((-2.068870e+00, -8.178800e-01, 2.735799e+00), (-8.068708e-01, -5.218555e-01, -2.768147e-01), 6.012975e+04, 7.598974e-09, 1.000000e+00, 23, 2388, 1)
((-2.111345e+00, -8.453511e-01, 2.721228e+00), (-4.440083e-01, -4.097242e-01, 7.968580e-01), 7.445994e+03, 7.754188e-09, 1.000000e+00, 23, 2388, 1)
((-2.453640e+00, -1.161216e+00, 3.335542e+00), (-4.440083e-01, -4.097242e-01, 7.968580e-01), 7.445994e+03, 1.421339e-08, 1.000000e+00, 23, 2387, 1)
((-2.715369e+00, -1.402736e+00, 3.805265e+00), (-4.440083e-01, -4.097242e-01, 7.968580e-01), 7.445994e+03, 1.915229e-08, 1.000000e+00, 22, 2387, 3)
((-2.785083e+00, -1.467067e+00, 3.930380e+00), (-4.440083e-01, -4.097242e-01, 7.968580e-01), 7.445994e+03, 2.046780e-08, 1.000000e+00, 21, 2387, 2)
((-2.940196e+00, -1.610203e+00, 4.208760e+00), (-7.727102e-01, 4.333905e-01, -4.637797e-01), 6.395532e+03, 2.339483e-08, 1.000000e+00, 21, 2387, 2)
((-3.600602e+00, -1.239800e+00, 3.812386e+00), (-7.727102e-01, 4.333905e-01, -4.637797e-01), 6.395532e+03, 3.112139e-08, 1.000000e+00, 22, 2387, 3)
((-3.682067e+00, -1.194109e+00, 3.763490e+00), (-7.727102e-01, 4.333905e-01, -4.637797e-01), 6.395532e+03, 3.207450e-08, 1.000000e+00, 23, 2387, 1)
((-4.089400e+00, -9.656478e-01, 3.519009e+00), (-7.727102e-01, 4.333905e-01, -4.637797e-01), 6.395532e+03, 3.684019e-08, 1.000000e+00, 23, 2386, 1)
((-4.185927e+00, -9.115084e-01, 3.461074e+00), (4.334152e-01, -1.576729e-02, -9.010564e-01), 2.532713e+01, 3.796953e-08, 1.000000e+00, 23, 2386, 1)
((-4.089400e+00, -9.150200e-01, 3.260397e+00), (4.334152e-01, -1.576729e-02, -9.010564e-01), 2.532713e+01, 6.996444e-08, 1.000000e+00, 23, 2387, 1)
((-3.920090e+00, -9.211794e-01, 2.908406e+00), (9.094673e-01, -3.659267e-01, -1.974002e-01), 9.547085e+00, 1.260840e-07, 1.000000e+00, 23, 2387, 1)
((-3.729948e+00, -9.976834e-01, 2.867135e+00), (-2.916959e-01, -6.494657e-01, -7.022164e-01), 8.590591e+00, 1.750036e-07, 1.000000e+00, 23, 2387, 1)
((-3.744933e+00, -1.031047e+00, 2.831062e+00), (-2.916959e-01, -6.494657e-01, -7.022164e-01), 8.590591e+00, 1.876753e-07, 0.000000e+00, 23, 2387, 1)]
ParticleType.NEUTRON [((6.474155e+00, -5.192870e+00, 5.413003e+00), (-3.042035e-02, -9.914979e-01, 1.265170e-01), 2.052226e+06, 4.450859e-05, 1.000000e+00, 21, 2367, 2)
((6.467293e+00, -5.416535e+00, 5.441544e+00), (-3.042035e-02, -9.914979e-01, 1.265170e-01), 2.052226e+06, 4.450870e-05, 1.000000e+00, 22, 2367, 3)
((6.464574e+00, -5.505149e+00, 5.452851e+00), (-3.042035e-02, -9.914979e-01, 1.265170e-01), 2.052226e+06, 4.450874e-05, 1.000000e+00, 23, 2367, 1)
((6.461877e+00, -5.593034e+00, 5.464065e+00), (6.364108e-01, -7.713322e-01, 5.284745e-03), 1.141417e+06, 4.450879e-05, 1.000000e+00, 23, 2367, 1)
((6.570892e+00, -5.725160e+00, 5.464970e+00), (6.364108e-01, -7.713322e-01, 5.284745e-03), 1.141417e+06, 4.450891e-05, 1.000000e+00, 32, 7, 1)
((6.821003e+00, -6.028296e+00, 5.467047e+00), (6.364108e-01, -7.713322e-01, 5.284745e-03), 1.141417e+06, 4.450917e-05, 1.000000e+00, 31, 7, 4)
((7.101210e+00, -6.367908e+00, 5.469374e+00), (6.364108e-01, -7.713322e-01, 5.284745e-03), 1.141417e+06, 4.450947e-05, 1.000000e+00, 32, 7, 1)
((7.360920e+00, -6.682677e+00, 5.471531e+00), (6.364108e-01, -7.713322e-01, 5.284745e-03), 1.141417e+06, 4.450975e-05, 1.000000e+00, 23, 2353, 1)
((7.833926e+00, -7.255962e+00, 5.475459e+00), (9.404210e-01, 3.383106e-01, -3.397550e-02), 1.289848e+05, 4.451025e-05, 1.000000e+00, 23, 2353, 1)
((8.142528e+00, -7.144944e+00, 5.464309e+00), (9.404210e-01, 3.383106e-01, -3.397550e-02), 1.289848e+05, 4.451091e-05, 1.000000e+00, 22, 2353, 3)
((8.590199e+00, -6.983897e+00, 5.448136e+00), (9.404210e-01, 3.383106e-01, -3.397550e-02), 1.289848e+05, 4.451187e-05, 1.000000e+00, 23, 2353, 1)
((8.682515e+00, -6.950687e+00, 5.444801e+00), (6.997233e-01, 7.142820e-01, 1.373092e-02), 1.043159e+05, 4.451207e-05, 1.000000e+00, 23, 2353, 1)
((8.996680e+00, -6.629985e+00, 5.450966e+00), (6.997233e-01, 7.142820e-01, 1.373092e-02), 1.043159e+05, 4.451307e-05, 1.000000e+00, 23, 2354, 1)
((9.231138e+00, -6.390649e+00, 5.455567e+00), (6.997233e-01, 7.142820e-01, 1.373092e-02), 1.043159e+05, 4.451382e-05, 1.000000e+00, 22, 2354, 3)
((9.650189e+00, -5.962879e+00, 5.463790e+00), (6.997233e-01, 7.142820e-01, 1.373092e-02), 1.043159e+05, 4.451516e-05, 1.000000e+00, 23, 2354, 1)
((9.721007e+00, -5.890588e+00, 5.465180e+00), (6.565855e-01, -1.880518e-01, -7.304327e-01), 1.036285e+04, 4.451539e-05, 1.000000e+00, 23, 2354, 1)
((9.939012e+00, -5.953026e+00, 5.222655e+00), (6.565855e-01, -1.880518e-01, -7.304327e-01), 1.036285e+04, 4.451775e-05, 1.000000e+00, 22, 2354, 3)
((1.002133e+01, -5.976602e+00, 5.131083e+00), (6.565855e-01, -1.880518e-01, -7.304327e-01), 1.036285e+04, 4.451864e-05, 1.000000e+00, 23, 2354, 1)
((1.020258e+01, -6.028514e+00, 4.929446e+00), (8.848761e-01, -4.005580e-02, -4.641012e-01), 8.908873e+03, 4.452060e-05, 1.000000e+00, 23, 2354, 1)
((1.063244e+01, -6.047973e+00, 4.703991e+00), (8.848761e-01, -4.005580e-02, -4.641012e-01), 8.908873e+03, 4.452432e-05, 1.000000e+00, 23, 2355, 1)
((1.084241e+01, -6.057477e+00, 4.593868e+00), (9.066652e-01, -6.565865e-02, 4.167099e-01), 3.324374e+03, 4.452614e-05, 1.000000e+00, 23, 2355, 1)
((1.107130e+01, -6.074053e+00, 4.699070e+00), (9.066652e-01, -6.565865e-02, 4.167099e-01), 3.324374e+03, 4.452930e-05, 1.000000e+00, 22, 2355, 3)
((1.121611e+01, -6.084540e+00, 4.765623e+00), (9.066652e-01, -6.565865e-02, 4.167099e-01), 3.324374e+03, 4.453130e-05, 1.000000e+00, 21, 2355, 2)
((1.174815e+01, -6.123069e+00, 5.010155e+00), (9.066652e-01, -6.565865e-02, 4.167099e-01), 3.324374e+03, 4.453866e-05, 1.000000e+00, 22, 2355, 3)
((1.189296e+01, -6.133556e+00, 5.076709e+00), (9.066652e-01, -6.565865e-02, 4.167099e-01), 3.324374e+03, 4.454067e-05, 1.000000e+00, 23, 2355, 1)
((1.221698e+01, -6.157021e+00, 5.225634e+00), (5.263177e-01, -7.048209e-01, -4.756229e-01), 3.449618e+02, 4.454515e-05, 1.000000e+00, 23, 2355, 1)
((1.226820e+01, -6.225607e+00, 5.179351e+00), (5.263177e-01, -7.048209e-01, -4.756229e-01), 3.449618e+02, 4.454893e-05, 1.000000e+00, 23, 2519, 1)
((1.230378e+01, -6.273253e+00, 5.147199e+00), (9.203567e-01, -2.667811e-01, -2.859569e-01), 2.269067e+02, 4.455157e-05, 1.000000e+00, 23, 2519, 1)
((1.237909e+01, -6.295083e+00, 5.123800e+00), (8.444192e-01, -5.115818e-01, 1.588717e-01), 1.686474e+02, 4.455549e-05, 1.000000e+00, 23, 2519, 1)
((1.250758e+01, -6.372926e+00, 5.147974e+00), (8.444192e-01, -5.115818e-01, 1.588717e-01), 1.686474e+02, 4.456396e-05, 1.000000e+00, 22, 2519, 3)
((1.258603e+01, -6.420455e+00, 5.162734e+00), (8.444192e-01, -5.115818e-01, 1.588717e-01), 1.686474e+02, 4.456914e-05, 1.000000e+00, 21, 2519, 2)
((1.264082e+01, -6.453648e+00, 5.173042e+00), (3.837750e-01, -8.931658e-01, -2.344604e-01), 1.632815e+02, 4.457275e-05, 1.000000e+00, 21, 2519, 2)
((1.288240e+01, -7.015898e+00, 5.025449e+00), (3.837750e-01, -8.931658e-01, -2.344604e-01), 1.632815e+02, 4.460837e-05, 1.000000e+00, 22, 2519, 3)
((1.292943e+01, -7.125332e+00, 4.996722e+00), (3.837750e-01, -8.931658e-01, -2.344604e-01), 1.632815e+02, 4.461530e-05, 1.000000e+00, 23, 2519, 1)
((1.303065e+01, -7.360920e+00, 4.934879e+00), (3.837750e-01, -8.931658e-01, -2.344604e-01), 1.632815e+02, 4.463022e-05, 1.000000e+00, 23, 2520, 1)
((1.309295e+01, -7.505897e+00, 4.896822e+00), (3.189366e-01, -9.220512e-01, 2.193195e-01), 1.303968e+02, 4.463941e-05, 1.000000e+00, 23, 2520, 1)
((1.311741e+01, -7.576618e+00, 4.913644e+00), (3.189366e-01, -9.220512e-01, 2.193195e-01), 1.303968e+02, 4.464426e-05, 1.000000e+00, 22, 2520, 3)
((1.314895e+01, -7.667795e+00, 4.935331e+00), (3.189366e-01, -9.220512e-01, 2.193195e-01), 1.303968e+02, 4.465052e-05, 1.000000e+00, 21, 2520, 2)
((1.345125e+01, -8.541749e+00, 5.143210e+00), (3.189366e-01, -9.220512e-01, 2.193195e-01), 1.303968e+02, 4.471053e-05, 1.000000e+00, 22, 2520, 3)
((1.348278e+01, -8.632925e+00, 5.164897e+00), (3.189366e-01, -9.220512e-01, 2.193195e-01), 1.303968e+02, 4.471679e-05, 1.000000e+00, 23, 2520, 1)
((1.356121e+01, -8.859646e+00, 5.218825e+00), (3.469373e-01, -8.669828e-01, 3.577365e-01), 1.276458e+02, 4.473236e-05, 1.000000e+00, 23, 2520, 1)
((1.361604e+01, -8.996680e+00, 5.275368e+00), (3.469373e-01, -8.669828e-01, 3.577365e-01), 1.276458e+02, 4.474248e-05, 1.000000e+00, 23, 2521, 1)
((1.390396e+01, -9.716172e+00, 5.572247e+00), (3.469373e-01, -8.669828e-01, 3.577365e-01), 1.276458e+02, 4.479558e-05, 1.000000e+00, 23, 2536, 1)
((1.399742e+01, -9.949713e+00, 5.668611e+00), (-5.897476e-01, -6.217559e-01, 5.153807e-01), 3.643244e+01, 4.481282e-05, 1.000000e+00, 23, 2536, 1)
((1.390396e+01, -1.004824e+01, 5.750282e+00), (-5.897476e-01, -6.217559e-01, 5.153807e-01), 3.643244e+01, 4.483180e-05, 1.000000e+00, 23, 2521, 1)
((1.334984e+01, -1.063244e+01, 6.234531e+00), (-5.897476e-01, -6.217559e-01, 5.153807e-01), 3.643244e+01, 4.494435e-05, 1.000000e+00, 23, 2522, 1)
((1.317711e+01, -1.081455e+01, 6.385480e+00), (-4.211158e-01, -4.515418e-01, 7.866203e-01), 3.302717e+01, 4.497943e-05, 1.000000e+00, 23, 2522, 1)
((1.316679e+01, -1.082561e+01, 6.404749e+00), (-5.182259e-01, 3.860612e-01, 7.631505e-01), 1.437084e+01, 4.498251e-05, 1.000000e+00, 23, 2522, 1)
((1.292206e+01, -1.064329e+01, 6.765147e+00), (-8.169098e-01, 1.482852e-01, 5.573777e-01), 1.219816e+01, 4.507257e-05, 1.000000e+00, 23, 2522, 1)
((1.286229e+01, -1.063244e+01, 6.805923e+00), (-8.169098e-01, 1.482852e-01, 5.573777e-01), 1.219816e+01, 4.508772e-05, 1.000000e+00, 23, 2521, 1)
((1.284917e+01, -1.063006e+01, 6.814880e+00), (-5.213758e-01, -3.360250e-01, 7.843816e-01), 8.052778e+00, 4.509105e-05, 1.000000e+00, 23, 2521, 1)
((1.284547e+01, -1.063244e+01, 6.820442e+00), (-5.213758e-01, -3.360250e-01, 7.843816e-01), 8.052778e+00, 4.509285e-05, 1.000000e+00, 23, 2522, 1)
((1.249929e+01, -1.085555e+01, 7.341246e+00), (-1.520079e-01, -3.513652e-01, 9.238161e-01), 7.069024e+00, 4.526201e-05, 1.000000e+00, 23, 2522, 1)
((1.240103e+01, -1.108268e+01, 7.938428e+00), (-7.405967e-01, -3.230926e-01, 5.891754e-01), 4.460475e+00, 4.543779e-05, 1.000000e+00, 23, 2522, 1)
((1.229354e+01, -1.112958e+01, 8.023945e+00), (-6.892797e-01, 5.508903e-01, 4.705458e-01), 2.006774e+00, 4.548748e-05, 1.000000e+00, 23, 2522, 1)
((1.226820e+01, -1.110933e+01, 8.041241e+00), (-6.892797e-01, 5.508903e-01, 4.705458e-01), 2.006774e+00, 4.550624e-05, 1.000000e+00, 23, 2314, 1)
((1.198501e+01, -1.088299e+01, 8.234567e+00), (-7.677533e-01, 4.569444e-01, 4.491733e-01), 1.935517e+00, 4.571593e-05, 1.000000e+00, 23, 2314, 1)
((1.156403e+01, -1.063244e+01, 8.480859e+00), (-7.677533e-01, 4.569444e-01, 4.491733e-01), 1.935517e+00, 4.600087e-05, 1.000000e+00, 23, 2329, 1)
((1.150264e+01, -1.059590e+01, 8.516776e+00), (-7.780064e-01, -9.937785e-02, 6.203467e-01), 1.893413e+00, 4.604243e-05, 1.000000e+00, 23, 2329, 1)
((1.121659e+01, -1.063244e+01, 8.744860e+00), (-7.780064e-01, -9.937785e-02, 6.203467e-01), 1.893413e+00, 4.623561e-05, 1.000000e+00, 23, 2314, 1)
((1.063244e+01, -1.070706e+01, 9.210632e+00), (-7.780064e-01, -9.937785e-02, 6.203467e-01), 1.893413e+00, 4.663011e-05, 1.000000e+00, 23, 2313, 1)
((1.035391e+01, -1.074263e+01, 9.432717e+00), (-4.847677e-01, -8.685325e-01, -1.032060e-01), 5.647686e-01, 4.681821e-05, 1.000000e+00, 23, 2313, 1)
((1.031409e+01, -1.081397e+01, 9.424239e+00), (-4.227592e-01, -9.022601e-01, -8.486053e-02), 5.651902e-01, 4.689723e-05, 1.000000e+00, 23, 2313, 1)
((1.028497e+01, -1.087614e+01, 9.418392e+00), (1.549579e-01, -4.270887e-01, 8.908329e-01), 5.395517e-01, 4.696349e-05, 1.000000e+00, 23, 2313, 1)
((1.034128e+01, -1.103135e+01, 9.742126e+00), (5.631544e-01, 4.925564e-01, 6.635098e-01), 2.637257e-01, 4.732118e-05, 1.000000e+00, 23, 2313, 1)
((1.044415e+01, -1.094137e+01, 9.863334e+00), (-1.034377e-01, 7.912271e-01, 6.027108e-01), 1.474934e-01, 4.757836e-05, 1.000000e+00, 23, 2313, 1)
((1.043959e+01, -1.090643e+01, 9.889950e+00), (1.163182e-01, 9.160889e-01, -3.837331e-01), 1.522434e-01, 4.766149e-05, 1.000000e+00, 23, 2313, 1)
((1.045733e+01, -1.076664e+01, 9.831395e+00), (-8.136862e-01, 9.805444e-02, -5.729748e-01), 3.341488e-02, 4.794423e-05, 1.000000e+00, 23, 2313, 1)
((1.044231e+01, -1.076483e+01, 9.820815e+00), (-8.437241e-01, 5.222731e-01, -1.239373e-01), 3.874838e-02, 4.801727e-05, 1.000000e+00, 23, 2313, 1)
((1.028725e+01, -1.066884e+01, 9.798037e+00), (-8.066297e-01, 3.960430e-01, -4.387465e-01), 3.989754e-02, 4.869227e-05, 1.000000e+00, 23, 2313, 1)
((1.021310e+01, -1.063244e+01, 9.757708e+00), (-8.066297e-01, 3.960430e-01, -4.387465e-01), 3.989754e-02, 4.902498e-05, 1.000000e+00, 23, 2328, 1)
((1.012717e+01, -1.059025e+01, 9.710967e+00), (-4.762033e-01, 8.377852e-01, -2.671075e-01), 3.271721e-02, 4.941058e-05, 1.000000e+00, 23, 2328, 1)
((1.001043e+01, -1.038486e+01, 9.645483e+00), (-4.762033e-01, 8.377852e-01, -2.671075e-01), 3.271721e-02, 5.039049e-05, 1.000000e+00, 22, 2328, 3)
((9.971285e+00, -1.031600e+01, 9.623530e+00), (5.437395e-01, -6.104117e-01, -5.759730e-01), 2.765456e-02, 5.071901e-05, 1.000000e+00, 22, 2328, 3)
((1.002723e+01, -1.037881e+01, 9.564267e+00), (5.437395e-01, -6.104117e-01, -5.759730e-01), 2.765456e-02, 5.116633e-05, 1.000000e+00, 23, 2328, 1)
((1.025152e+01, -1.063060e+01, 9.326683e+00), (-8.159392e-01, -4.792697e-03, 5.781179e-01), 2.920905e-02, 5.295966e-05, 1.000000e+00, 23, 2328, 1)
((1.000779e+01, -1.063203e+01, 9.499373e+00), (-6.486477e-01, -4.621598e-01, -6.047020e-01), 2.383638e-02, 5.422329e-05, 1.000000e+00, 23, 2328, 1)
((1.000721e+01, -1.063244e+01, 9.498835e+00), (-6.486477e-01, -4.621598e-01, -6.047020e-01), 2.383638e-02, 5.422746e-05, 1.000000e+00, 23, 2313, 1)
((9.852478e+00, -1.074269e+01, 9.354584e+00), (-6.686452e-01, -2.988396e-01, 6.808880e-01), 2.993224e-02, 5.534454e-05, 1.000000e+00, 23, 2313, 1)
((9.765042e+00, -1.078177e+01, 9.443621e+00), (7.712484e-01, -5.215773e-01, 3.648739e-01), 3.590785e-02, 5.589099e-05, 1.000000e+00, 23, 2313, 1)
((9.798992e+00, -1.080472e+01, 9.459682e+00), (-4.563170e-01, 8.081811e-01, -3.723144e-01), 2.674168e-02, 5.605894e-05, 1.000000e+00, 23, 2313, 1)
((9.792857e+00, -1.079386e+01, 9.454677e+00), (-9.080336e-01, 4.172659e-01, 3.693418e-02), 9.753404e-03, 5.611838e-05, 1.000000e+00, 23, 2313, 1)
((9.653805e+00, -1.072996e+01, 9.460332e+00), (-3.727950e-01, 2.889342e-01, -8.817828e-01), 1.781716e-02, 5.723944e-05, 1.000000e+00, 23, 2313, 1)
((9.628677e+00, -1.071048e+01, 9.400895e+00), (-6.406523e-01, 7.657269e-01, -5.680598e-02), 1.764425e-02, 5.760453e-05, 1.000000e+00, 23, 2313, 1)
((9.563380e+00, -1.063244e+01, 9.395105e+00), (-6.406523e-01, 7.657269e-01, -5.680598e-02), 1.764425e-02, 5.815928e-05, 1.000000e+00, 23, 2328, 1)
((9.411305e+00, -1.045068e+01, 9.381621e+00), (3.205568e-01, -1.311309e-02, -9.471385e-01), 2.153422e-02, 5.945128e-05, 1.000000e+00, 23, 2328, 1)
((9.860026e+00, -1.046903e+01, 8.055798e+00), (6.278124e-01, 1.023095e-01, -7.716115e-01), 2.013742e-02, 6.634788e-05, 1.000000e+00, 23, 2328, 1)
((1.007604e+01, -1.043383e+01, 7.790303e+00), (6.790346e-01, 5.167838e-01, 5.213891e-01), 1.340865e-02, 6.810089e-05, 1.000000e+00, 23, 2328, 1)
((1.008869e+01, -1.042421e+01, 7.800011e+00), (2.792456e-01, 1.367953e-01, 9.504257e-01), 8.576635e-03, 6.821715e-05, 1.000000e+00, 23, 2328, 1)
((1.017046e+01, -1.038415e+01, 8.078330e+00), (-9.462370e-01, 3.185163e-01, 5.641780e-02), 1.119274e-01, 7.050324e-05, 1.000000e+00, 23, 2328, 1)
((1.008276e+01, -1.035463e+01, 8.083559e+00), (-9.462370e-01, 3.185163e-01, 5.641780e-02), 1.119274e-01, 7.070353e-05, 1.000000e+00, 22, 2328, 3)
((9.952201e+00, -1.031068e+01, 8.091343e+00), (-9.462370e-01, 3.185163e-01, 5.641780e-02), 1.119274e-01, 7.100170e-05, 1.000000e+00, 21, 2328, 2)
((9.404929e+00, -1.012646e+01, 8.123973e+00), (-9.462370e-01, 3.185163e-01, 5.641780e-02), 1.119274e-01, 7.225157e-05, 1.000000e+00, 22, 2328, 3)
((9.274369e+00, -1.008251e+01, 8.131758e+00), (-9.462370e-01, 3.185163e-01, 5.641780e-02), 1.119274e-01, 7.254974e-05, 1.000000e+00, 23, 2328, 1)
((9.126730e+00, -1.003281e+01, 8.140560e+00), (-8.389978e-01, -2.248732e-01, 4.954945e-01), 1.164832e-01, 7.288692e-05, 1.000000e+00, 23, 2328, 1)
((8.996680e+00, -1.006767e+01, 8.217365e+00), (-8.389978e-01, -2.248732e-01, 4.954945e-01), 1.164832e-01, 7.321528e-05, 1.000000e+00, 23, 2327, 1)
((8.694758e+00, -1.014859e+01, 8.395674e+00), (5.156148e-01, 7.316558e-01, 4.458937e-01), 1.391972e-01, 7.397758e-05, 1.000000e+00, 23, 2327, 1)
((8.996680e+00, -9.720167e+00, 8.656770e+00), (5.156148e-01, 7.316558e-01, 4.458937e-01), 1.391972e-01, 7.511228e-05, 1.000000e+00, 23, 2328, 1)
((9.263031e+00, -9.342216e+00, 8.887105e+00), (5.734531e-01, -5.017666e-01, 6.475970e-01), 9.798082e-02, 7.611330e-05, 1.000000e+00, 23, 2328, 1)
((9.334809e+00, -9.405021e+00, 8.968164e+00), (5.419546e-03, -7.721039e-01, -6.354732e-01), 1.234091e-01, 7.640240e-05, 1.000000e+00, 23, 2328, 1)
((9.335117e+00, -9.448857e+00, 8.932084e+00), (5.419546e-03, -7.721039e-01, -6.354732e-01), 1.234091e-01, 7.651925e-05, 1.000000e+00, 22, 2328, 3)
((9.336345e+00, -9.623801e+00, 8.788098e+00), (5.419546e-03, -7.721039e-01, -6.354732e-01), 1.234091e-01, 7.698556e-05, 1.000000e+00, 21, 2328, 2)
((9.339070e+00, -1.001201e+01, 8.468584e+00), (5.419546e-03, -7.721039e-01, -6.354732e-01), 1.234091e-01, 7.802034e-05, 1.000000e+00, 22, 2328, 3)
((9.340298e+00, -1.018696e+01, 8.324598e+00), (5.419546e-03, -7.721039e-01, -6.354732e-01), 1.234091e-01, 7.848665e-05, 1.000000e+00, 23, 2328, 1)
((9.343193e+00, -1.059945e+01, 7.985097e+00), (1.798796e-01, 3.522536e-02, -9.830577e-01), 1.283272e-01, 7.958616e-05, 1.000000e+00, 23, 2328, 1)
((9.397753e+00, -1.058877e+01, 7.686922e+00), (6.459563e-01, 7.279465e-03, -7.633397e-01), 1.319449e-01, 8.019832e-05, 1.000000e+00, 23, 2328, 1)
((9.462343e+00, -1.058804e+01, 7.610595e+00), (-5.748716e-01, 5.760301e-01, -5.811299e-01), 8.880732e-02, 8.039733e-05, 1.000000e+00, 23, 2328, 1)
((9.287877e+00, -1.041322e+01, 7.434230e+00), (-4.932135e-03, 1.668926e-01, 9.859627e-01), 3.503028e-02, 8.113361e-05, 1.000000e+00, 23, 2328, 1)
((9.286930e+00, -1.038117e+01, 7.623600e+00), (-9.325544e-02, -9.933000e-01, -6.825369e-02), 3.173764e-02, 8.187553e-05, 1.000000e+00, 23, 2328, 1)
((9.283901e+00, -1.041342e+01, 7.621384e+00), (-4.235208e-01, -5.129112e-01, 7.466942e-01), 4.258127e-02, 8.200731e-05, 1.000000e+00, 23, 2328, 1)
((9.264517e+00, -1.043690e+01, 7.655560e+00), (-7.165846e-01, 3.926265e-01, 5.764988e-01), 4.485063e-02, 8.216767e-05, 1.000000e+00, 23, 2328, 1)
((9.256348e+00, -1.043242e+01, 7.662132e+00), (1.703748e-01, -9.175599e-01, -3.592441e-01), 3.521226e-02, 8.220659e-05, 1.000000e+00, 23, 2328, 1)
((9.284015e+00, -1.058143e+01, 7.603793e+00), (3.963415e-01, -8.051509e-01, 4.411865e-01), 2.970280e-02, 8.283227e-05, 1.000000e+00, 23, 2328, 1)
((9.309126e+00, -1.063244e+01, 7.631745e+00), (3.963415e-01, -8.051509e-01, 4.411865e-01), 2.970280e-02, 8.309804e-05, 1.000000e+00, 23, 2313, 1)
((9.317824e+00, -1.065011e+01, 7.641427e+00), (7.190682e-01, 8.976507e-02, -6.891177e-01), 2.867417e-02, 8.319011e-05, 1.000000e+00, 23, 2313, 1)
((9.459378e+00, -1.063244e+01, 7.505770e+00), (7.190682e-01, 8.976507e-02, -6.891177e-01), 2.867417e-02, 8.403060e-05, 1.000000e+00, 23, 2328, 1)
((9.492454e+00, -1.062831e+01, 7.474071e+00), (4.092619e-03, -9.482095e-01, -3.176193e-01), 4.656141e-02, 8.422700e-05, 1.000000e+00, 23, 2328, 1)
((9.492472e+00, -1.063244e+01, 7.472688e+00), (4.092619e-03, -9.482095e-01, -3.176193e-01), 4.656141e-02, 8.424159e-05, 1.000000e+00, 23, 2313, 1)
((9.492761e+00, -1.069927e+01, 7.450302e+00), (9.457151e-01, -1.928731e-01, 2.615777e-01), 4.542312e-02, 8.447773e-05, 1.000000e+00, 23, 2313, 1)
((9.890524e+00, -1.078039e+01, 7.560320e+00), (7.849118e-01, -1.237812e-01, -6.071175e-01), 5.609444e-02, 8.590450e-05, 1.000000e+00, 23, 2313, 1)
((1.004645e+01, -1.080498e+01, 7.439717e+00), (7.849118e-01, -1.237812e-01, -6.071175e-01), 5.609444e-02, 8.651090e-05, 0.000000e+00, 23, 2313, 1)]

View file

@ -16,7 +16,8 @@
<track>
1 1 1
1 1 2
1 1 30
2 1 60
</track>
</settings>

View file

@ -1,11 +1,13 @@
import glob
import os
from pathlib import Path
from subprocess import call
import shutil
import numpy as np
import openmc
import pytest
from tests.testing_harness import TestHarness
from tests.testing_harness import TestHarness, config
class TrackTestHarness(TestHarness):
@ -13,26 +15,33 @@ class TrackTestHarness(TestHarness):
"""Make sure statepoint.* and track* have been created."""
TestHarness._test_output_created(self)
outputs = glob.glob('track_1_1_*.h5')
assert len(outputs) == 2, 'Expected two track files.'
if config['mpi'] and int(config['mpi_np']) > 1:
outputs = Path.cwd().glob('tracks_p*.h5')
assert len(list(outputs)) == int(config['mpi_np'])
else:
assert Path('tracks.h5').is_file()
def _get_results(self):
"""Digest info in the statepoint and return as a string."""
# Run the track-to-vtk conversion script.
call(['../../../scripts/openmc-track-to-vtk', '-o', 'poly'] +
glob.glob('track_1_1_*.h5'))
"""Get data from track file and return as a string."""
# Make sure the vtk file was created then return it's contents.
assert os.path.isfile('poly.pvtp'), 'poly.pvtp file not found.'
# For MPI mode, combine track files
if config['mpi']:
call(['../../../scripts/openmc-track-combine', '-o', 'tracks.h5'] +
glob.glob('tracks_p*.h5'))
with open('poly.pvtp', 'r') as fin:
outstr = fin.read()
# Get string of track file information
outstr = ''
tracks = openmc.Tracks('tracks.h5')
for track in tracks:
with np.printoptions(formatter={'float_kind': '{:.6e}'.format}):
for ptrack in track:
outstr += f"{ptrack.particle} {ptrack.states}\n"
return outstr
def _cleanup(self):
TestHarness._cleanup(self)
output = glob.glob('track*') + glob.glob('poly*')
output = glob.glob('tracks*') + glob.glob('poly*')
for f in output:
if os.path.exists(f):
os.remove(f)

View file

@ -14,6 +14,7 @@ def test_export_to_xml(run_in_tmpdir):
s.keff_trigger = {'type': 'std_dev', 'threshold': 0.001}
s.energy_mode = 'continuous-energy'
s.max_order = 5
s.max_tracks = 1234
s.source = openmc.Source(space=openmc.stats.Point())
s.output = {'summary': True, 'tallies': False, 'path': 'here'}
s.verbosity = 7
@ -42,7 +43,7 @@ def test_export_to_xml(run_in_tmpdir):
s.temperature = {'default': 293.6, 'method': 'interpolation',
'multipole': True, 'range': (200., 1000.)}
s.trace = (10, 1, 20)
s.track = [1, 1, 1, 2, 1, 1]
s.track = [(1, 1, 1), (2, 1, 1)]
s.ufs_mesh = mesh
s.resonance_scattering = {'enable': True, 'method': 'rvs',
'energy_min': 1.0, 'energy_max': 1000.0,
@ -71,6 +72,7 @@ def test_export_to_xml(run_in_tmpdir):
assert s.keff_trigger == {'type': 'std_dev', 'threshold': 0.001}
assert s.energy_mode == 'continuous-energy'
assert s.max_order == 5
assert s.max_tracks == 1234
assert isinstance(s.source[0], openmc.Source)
assert isinstance(s.source[0].space, openmc.stats.Point)
assert s.output == {'summary': True, 'tallies': False, 'path': 'here'}
@ -99,7 +101,7 @@ def test_export_to_xml(run_in_tmpdir):
assert s.temperature == {'default': 293.6, 'method': 'interpolation',
'multipole': True, 'range': [200., 1000.]}
assert s.trace == [10, 1, 20]
assert s.track == [1, 1, 1, 2, 1, 1]
assert s.track == [(1, 1, 1), (2, 1, 1)]
assert isinstance(s.ufs_mesh, openmc.RegularMesh)
assert s.ufs_mesh.lower_left == [-10., -10., -10.]
assert s.ufs_mesh.upper_right == [10., 10., 10.]

View file

@ -0,0 +1,143 @@
from pathlib import Path
import numpy as np
import openmc
import pytest
from tests.testing_harness import config
@pytest.fixture
def sphere_model():
openmc.reset_auto_ids()
mat = openmc.Material()
mat.add_nuclide('Zr90', 1.0)
mat.set_density('g/cm3', 1.0)
model = openmc.Model()
sph = openmc.Sphere(r=25.0, boundary_type='vacuum')
cell = openmc.Cell(fill=mat, region=-sph)
model.geometry = openmc.Geometry([cell])
model.settings.run_mode = 'fixed source'
model.settings.batches = 2
model.settings.particles = 50
return model
def generate_track_file(model, **kwargs):
# If running in MPI mode, setup proper keyword arguments for run()
kwargs.setdefault('openmc_exec', config['exe'])
if config['mpi']:
kwargs['mpi_args'] = [config['mpiexec'], '-n', config['mpi_np']]
model.run(**kwargs)
if config['mpi'] and int(config['mpi_np']) > 1:
# With MPI, we need to combine track files
track_files = Path.cwd().glob('tracks_p*.h5')
openmc.Tracks.combine(track_files, 'tracks.h5')
else:
track_file = Path('tracks.h5')
assert track_file.is_file()
@pytest.mark.parametrize("particle", ["neutron", "photon"])
def test_tracks(sphere_model, particle, run_in_tmpdir):
# Set track identifiers
sphere_model.settings.track = [(1, 1, 1), (1, 1, 10), (2, 1, 15)]
# Set source particle
sphere_model.settings.source = openmc.Source(particle=particle)
# Run OpenMC to generate tracks.h5 file
generate_track_file(sphere_model)
# Open track file and make sure we have correct number of tracks
tracks = openmc.Tracks('tracks.h5')
assert len(tracks) == len(sphere_model.settings.track)
for track, identifier in zip(tracks, sphere_model.settings.track):
# Check attributes on Track object
assert isinstance(track, openmc.Track)
assert track.identifier == identifier
assert isinstance(track.particle_tracks, list)
if particle == 'neutron':
assert len(track.particle_tracks) == 1
# Check attributes on ParticleTrack object
particle_track = track.particle_tracks[0]
assert isinstance(particle_track, openmc.ParticleTrack)
assert particle_track.particle.name.lower() == particle
assert isinstance(particle_track.states, np.ndarray)
# Sanity checks on actual data
for state in particle_track.states:
assert np.linalg.norm([*state['r']]) <= 25.0001
assert np.linalg.norm([*state['u']]) == pytest.approx(1.0)
assert 0.0 <= state['E'] <= 20.0e6
assert state['time'] >= 0.0
assert 0.0 <= state['wgt'] <= 1.0
assert state['cell_id'] == 1
assert state['material_id'] == 1
# Checks on 'sources' property
sources = track.sources
assert len(sources) == len(track.particle_tracks)
x = sources[0]
state = particle_track.states[0]
assert x.r == (*state['r'],)
assert x.u == (*state['u'],)
assert x.E == state['E']
assert x.time == state['time']
assert x.wgt == state['wgt']
assert x.particle == particle_track.particle
def test_max_tracks(sphere_model, run_in_tmpdir):
# Set maximum number of tracks per process to write
sphere_model.settings.max_tracks = expected_num_tracks = 10
if config['mpi']:
expected_num_tracks *= int(config['mpi_np'])
# Run OpenMC to generate tracks.h5 file
generate_track_file(sphere_model, tracks=True)
# Open track file and make sure we have correct number of tracks
tracks = openmc.Tracks('tracks.h5')
assert len(tracks) == expected_num_tracks
def test_filter(sphere_model, run_in_tmpdir):
# Set maximum number of tracks per process to write
sphere_model.settings.max_tracks = 25
sphere_model.settings.photon_transport = True
# Run OpenMC to generate tracks.h5 file
generate_track_file(sphere_model, tracks=True)
tracks = openmc.Tracks('tracks.h5')
for track in tracks:
# Test filtering by particle
matches = track.filter(particle='photon')
for x in matches:
assert x.particle == openmc.ParticleType.PHOTON
# Test general state filter
matches = track.filter(state_filter=lambda s: s['cell_id'] == 1)
assert isinstance(matches, openmc.Track)
assert matches.particle_tracks == track.particle_tracks
matches = track.filter(state_filter=lambda s: s['cell_id'] == 2)
assert matches.particle_tracks == []
matches = track.filter(state_filter=lambda s: s['E'] < 0.0)
assert matches.particle_tracks == []
# Test filter method on Tracks
matches = tracks.filter(particle='neutron')
assert isinstance(matches, openmc.Tracks)
assert matches == tracks
matches = tracks.filter(state_filter=lambda s: s['E'] > 0.0)
assert matches == tracks
matches = tracks.filter(particle='bunnytron')
assert matches == []