A collection of useful analysis tools for interacting with MCNP meshtal files
This is a pre-release version for testing and development. The core library is written, so it is just matter of finding the time to extend all the high-level features and functionality
Full library documentation here
Direct from github:
cargo install --git https://github.com/repositony/meshtal.git
All executables are under ~/.cargo/bin/
, which should already be in your path
after installing Rust.
Click here if you have never used Rust
If you have never used the Rust programming language, the toolchain is easily installed from the official website
curl https://sh.rustup.rs -sSf | sh
This should have added source $HOME/.cargo/env
to the bash profile, so update
your environment with source ~/.bashrc
.
The crate contains several command line tools for quickly performing common tasks relating to MCNP meshes. More may be added based on time/usefulness.
Command line | Description |
---|---|
mesh2vtk |
Convert any meshtal tally to various VTK formats |
mesh2ww |
Convert any meshtal tally to a mesh-based weight window |
pointextract |
Extract voxel results for any point(s) in a mesh |
splitmesh |
Split meshtal tallies into individual files |
posvol |
Inspect and convert binary UKAEA CuV posvol files |
All tools are fully documented with detailed --help
messages, including
examples for common use cases.
For more detail, see the OUT
keyword for the FMESH
card definition in
the MCNPv6.2
or MCNPv6.3
user manuals.
Output format | Supported? | Description |
---|---|---|
COL | Yes | Column data (MCNP default) |
CF | Yes | Column data including voxel volume |
IJ | Yes | 2D matrix of I (col) and J (row) data, grouped by K |
IK | Yes | 2D matrix of I (col) and K (row) data, grouped by J |
JK | Yes | 2D matrix of J (col) and K (row) data, grouped by I |
CUV (UKAEA) | Yes | UKAEA Cell-under-Voxel column data |
NONE | N/A | NONE or unknown output format |
Once I get my paws on MCNPv6.3 this will be extended to include the new COLSCI, CFSCI, and XDMF/HDF5 formats.
Currently spherical meshes are not supported because barely anyone knows about them, let alone uses them. They are currently a low priority.
Mesh geometry | Supported? | MCNP designators |
---|---|---|
Rectangular | Yes | rec, xyz |
Cylindrical | Yes | cyl, rzt |
Spherical | No | sph, rpt |
Convert mesh tallies to VTK formats for plotting
Usage: mesh2vtk <meshtal> <number> [options]
Click to see detailed examples
Help is printed with the -h
flag, and --help
will show examples, default
values, examples, and any important behaviour.
By default, the results of every time/energy bin are extracted
Corresponding uncertainty meshes are optional in case of large meshtal files.
# Extract every energy and time group, with corresponding error meshes
mesh2vtk /path/to/meshtal.msht 104 --errors
Often only the Total
energy/time bins are of interest, and a quick way of
only converting this subset is provided.
# Extract only the 'Total' energy and time groups
mesh2vtk /path/to/meshtal.msht 104 --total
If specific energy or time groups are required,
# Extract specific energy and time groups
mesh2vtk /path/to/meshtal.msht 104 \
--energy 1.0 1e5 \
--time 1e12 total
For intuitive use, the groups correspond with values defined on the EMESH
and TMESH
cards.
Note: mesh tallies label groups by the upper bounds defined on EMESH/TMESH
cards. i.e the energy group 1.0
corresponds to the 0.0>=E<1.0
bin,
though in reality 1 MeV particle would end up in the next group up.
Mcnp normalises everything so it is often the case that the results must be rescaled to provide physical values.
# Rescale the result by a constant multiplier, e.g 6.50E+18 neutrons/s
mesh2vtk /path/to/meshtal.msht 104 --scale 6.50E+18
Mesh rotations are a work in progress.
There is no VTK representation of cylindrical meshes, so an unstructured mesh is generated from verticies based on the RZT bounds.
Unfortunately, this can result in "low-resolution" plots for meshes with few theta bins. The number of theta bins can be increased to round off these edges. This simply subdivides the voxels by an integer number of theta bins.
# Subdivide voxels into 3 to round off cylindrical unstructured mesh
mesh2vtk /path/to/meshtal.msht 104 --resolution 3
Note that this will increase the file size and memory usage significantly in some cases.
By default the file prefix is fmesh
, so the output files will be
fmesh_<number>.vtk
. This may be changed as needed.
# Change the output name to `myvtk_104.vtr`
mesh2vtk /path/to/meshtal.msht 104 --output myvtk
Most useful may be the ability to decide on output formats. XML and legacy formats are supported, with both ascii and binary variants.
# Output as a binary vtk with legacy formatting
mesh2vtk /path/to/meshtal.msht 104 --format legacy-binary
For more advanced usage, things like byte ordering and xml compression methods are also configurable.
# Output as an xml using lzma and setting the byte order to big endian
mesh2vtk /path/to/meshtal.msht 104 \
--format xml \
--compresser lzma \
--endian big-endian
Note - VisIt only reads big-endian, but most sytems are natively little-endian. For personal convenience the default is big, but I am open to arguments for little endian as the default.
Conversion of meshes to MCNP mesh-based global weight windows
Usage: mesh2ww <meshtal> <number> [options]
Click to see detailed examples
Converts a mesh tally of any type to a weight window using the magic method with configurable de-tuning options.
# Single particle type weight window
Usage: mesh2ww <meshtal> <number> [options]
# Multiple particle types
Usage: mesh2ww <meshtal> <number> [options] + <meshtal> <number> [options]
Help is printed with the -h
flag, and --help
will show examples, default
values, examples, and any important behaviour.
Typical usage will generally define a de-tuning factor (-p
/--power
) and
possibly a relative error cutoff (-e
/--error
) for generating weights.
mesh2ww run0.msht 104 --power 0.70 --error 0.25
The --power
value modifies calculated weights by w => w^(power)
, which
helps with softening extreme values. Any voxels with errors above --error
(>25% in this case) continue to use analogue transport until the uncertainty
imporves.
Of course, the weight window file may be renamed as needed:
mesh2ww run0.msht 104 --output mywwmesh.wwinp
It is often desirable to simply generate a global weight window mesh using only the 'Total' group rather than every explicit energy/time group.
mesh2ww run0.msht 104 --total
This is probably the recommended use case for any finely binned groups, as nobody should really be trying to optimise for every energy in a 175-group mesh anyway.
Generated weights are typically normalised to the total flux for each group. These may be rescaled by a constant multiplier.
# Multiply all normalised weights by x2.5
mesh2ww run0.msht 104 --scale 2.5
For fine control, the --power
and --error
parameters may be set
explicitly for every unique group.
For example, if a mesh had 3 energy groups at 1.0 MeV, 10.0 MeV, and 100.0 MeV, the power factor for each may be set to 0.8, 0.7, and 0.65 respectively.
# Set energy group power factors individually
mesh2ww run0.msht 104 --power 0.8 0.7 0.65
Of course this applies to time bins also. To set values for all unique groups, the values must be given in order. For example, a mesh with 3x energy groups and 2x time groups:
Energy 1.0 Power
Time 1e10 0.9
Time 1e20 0.7
Energy 10.0
Time 1e10 0.8
Time 1e20 0.8
Energy 100.0
Time 1e10 0.6
Time 1e20 0.5
# Set energy group power factors individually
mesh2ww run0.msht 104 --power 0.9 0.7 0.8 0.8 0.6 0.5
Multiple tallies may be combined for weight windows covering multiple
particle types. This may be achieved using the +
operator.
The usage is as simple as combining multiple argument sets with +
as the
delimiter.
mesh2ww <meshtal> <number> [options] + \
<meshtal> <number> [options] + \
<meshtal> <number> [options]
For example: 'NP_tallies.msht' contains neutron (FMESH14:n) and photon (FMESH24:p) tallies, and 'E_tallies.msht' contains an electron (FMESH34:e) tally.
If all of these are the same geometry, they may be combined with all the usual optionas applied to each weight set individually:
mesh2ww NP_tallies.msht 14 + \
NP_tallies.msht 24 -p 0.8 -e 0.15 + \
E_tallies.msht 34 --total \
A Visual Toolkit file can be generated for every weight window set using the
--vtk
flag.
WARNING: Cylindrical weight window plotting is a WIP
mesh2ww file.msht 14 --vtk
Of course all the usual options are available, such as increasing the resolution of cylindrical meshes with few theta bins.
mesh2ww file.msht 14 --vtk --resolution 2
Advanced options include changing the file format, byte ordering of binary outputs, and which compressor to use for XML.
mesh2ww file.msht 14 --vtk \\
--format legacy-ascii \\
--compressor lzma \\
--endian big-endian
Extracts point data from any mesh in a meshtal file.
Usage: pointextract <meshtal> <number> [options]
Click to see detailed examples
Help is printed with the -h
flag, and --help
will show examples, default
values, examples, and any important behaviour.
A Point
in may be defined three ways. Using cartesian xyz
as an example:
- (x, y, z)
- (energy, x, y, z)
- (energy, time, x, y, z)
where are energy
/time
groups are either a value or 'total', and x
,
y
, z
are the location to search for.
The 'Total' group is used by default for omitted energy
and time
groups.
Note that no matter what coordinates are provided, they are converted into
the appropriate coordinate system in the background. For example, xyz
coordinates are converted to rzt
if the target mesh is cylindrical.
Points can be retrieved in two ways:
- Single point via the
-p
/--point
argument - Multiple points via the
-f
/--file
argument
To quickly get a single point:
# Find the point at (x,y,z) = (1.0, 2.0, 3.0)
pointextract /path/to/meshtal.msht 104 -p 1.0 2.0 3.0
# Find the same point, but for the 100.0 MeV energy group
pointextract /path/to/meshtal.msht 104 -p 1.0E+02 1.0 2.0 3.0
# Find the same point, but for the 'Total' energy group and 6.0e+15 time group
pointextract /path/to/meshtal.msht 104 -p total 6e+15 1.0 2.0 3.0
This works for both the Rectangular
and Cylindrical
mesh types.
Coordinates default to being XYZ cartesian, but the --type
argument allows
this to be specified explicitly
# Find the point at (r,z,t) = (1.0, 2.0, 90.0)
pointextract /path/to/meshtal.msht 104 -p 1.0 2.0 0.53 --type rzt
The input file (default points.txt
) is interpreted with the following
rules for a line:
Example line | Interpretation |
---|---|
Starts with # |
comment |
rzt , cyl , xyz , rec |
geometry keyword |
1.0 2.0 3.0 | i, j, k |
1e2 1.0 2.0 3.0 | energy, i, j, k |
1e2 total 1.0 2.0 3.0 | energy, time, i, j, k |
Anything else is ignored. For an example file see data/points.txt
, though
a simplified input is shown below.
# this is a line comment in points.txt
xyz # points below explicitly interpreted as cartesian
1.0 5.0 7.0 # 'Total' energy, 'Total' time, (x, y, z)
total 1.0 5.0 7.0 # 'Total' energy, 'Total' time, (x, y, z)
total total 1.0 5.0 7.0 # 'Total' energy, 'Total' time, (x, y, z)
rzt # points below explicitly interpreted as cylindrical
4.0 1.0 5.0 0.5 # 4 MeV energy, 'Total' time, (r, z, t)
4.0 1e16 1.0 5.0 0.5 # 4 MeV energy, 1e16 time, (r, z, t)
This is used as
# Find all points in file
pointextract /path/to/meshtal.msht 104 --file points.txt
It is fine to mix and match coordinates in the same file because all points are converted into the appropriate coordinate system in the background.
Lines that can not be parsed into a Point
are ignored, and warnings are
raised for invalid points that are outside of the mesh bounds.
Results are written to results.dat
by default but this can be renamed as
needed.
# Search for all locations in points.txt, output results to 'myoutput.txt'
pointextract /path/to/meshtal.msht 104 --file points.txt --output myoutput.txt
These may also be written to the terminal directly with the -d
/--dump
flag.
Both the parsed user input and search results are presented in tables. For example, a 'points.txt' file may have the following
total 1.111e16 0.5 0.0 -1.9 # (energy, time, x, y, z), inside of mesh bounds
total 1.111e16 50.5 0.0 -1.9 # (energy, time, x, y, z), outside of mesh bounds
Tables show the user provided points to search for, and detail of the voxel containing these points.
Points to search
id energy time i_coord j_coord k_coord system
-----------------------------------------------------------------------------
0 Total 1.11100e+16 5.00000e-01 0.00000e+00 -1.90000e+00 xyz
1 Total 1.11100e+16 5.05000e+01 0.00000e+00 -1.90000e+00 xyz
Voxels found (fmesh334, Rectangular)
id energy time i_coord j_coord k_coord result error
--------------------------------------------------------------------------------
0 Total 1.11100e+16 0.500 0.000 -2.625 1.37928e-02 0.0092
1 Not found in mesh
Note the second point was outside of the mesh and failed, which will warn
you with a Not found in mesh
entry. Corresponding rows are numbered for
convenience.
Note - long rows are really inconvenient for reading results on a lot of
screens, so the choice was made to split up the two tables. A case could be
made for doing somthing else with the results for easier parsing.
Command line tool to split up meshtal files
Usage: splitmesh <meshtal> [options]
Click to see detailed examples
Splits up all meshes found in a meshtal file into their own individual files.
This is very useful for processing large meshtal files with multiple tallies, or for just reducing file sizes to a minimum for post-processing.
Help is printed with the -h
flag, and --help
will show examples, default
values, examples, and any important behaviour.
By default, every tally found in the file is splt into individual files.
Use the --tallies
option to specify one or more tallies to be separated
out. Invalid entries are simply ignored.
# Extract only tallies with ID 104, 204, and 504 from the primary file
splitmesh /path/to/meshtal.msht --tallies 104 204 504
The name of the output files is appended with the tally number as
<output>_<id>.msht
. Output defaults to fmesh
, but this may be changed.
# Change output file names to "mymesh_<id>.msht"
splitmesh /path/to/meshtal.msht --output mymesh
Command line tool to inspect and convert posvol files
Usage: posvol <file> [options]
Click to see detailed examples
Very simple reader for UKAEA CuV posvol binaries, skipping the need to open a special viewer or sort it out manually just to check simple properties.
Allows for 1:1 conversion to ASCII, but also JSON and a more readable text file.
The endian is assumed to be the same as the native type of the system this tool is run on. If needed, an option can be provided in future updates.
Help is printed with the -h
flag, and --help
will show examples, default
values, examples, and any important behaviour.
By default a simple summary of the posvol dimensions is logged.
# Print a summary of dimension properties
posvol plot_fmesh_104.bin
It can be useful just to have something that can be open and read, so --ascii
converts to text.
# Output a file named 'posvol.txt'
posvol plot_fmesh_104.bin --ascii
For somthing a bit more human-friendly, the dimensions are split up and cells grouped into single voxels separated by blank lines.
# Output a file named 'posvol.txt'
posvol plot_fmesh_104.bin --ascii --pretty
For lovers of python and other languages there is a JSON output option because it takes about 5 seconds for me to implement.
# Output a file named 'posvol.json'
posvol plot_fmesh_104.bin --json
By default the file names are 'posvol.txt' for ascii file formats, and 'posvol.json' for a json format.
This can be changed by providing --output with a name
# Output a files named 'myfile.txt' and 'myfile.json'
posvol plot_fmesh_104.bin \
--json \
--ascii \
--output myfile
An API with full cargo documentation is available with details for using the crate
The command line interface is a set of QoL tools written for colleagues. The crate itself is far more useful since the challenge with meshtal files is always just trying to parse the horrible MCNP output files.
This crate allows any format to be read into a struct with a one-liner, and
from there you can do whatever you want with the mesh data. All mesh formats
are coerced into the same core Mesh
structure.
// read a mesh from any of the meshtal formats
let mesh = meshtal::read_meshtal_target("./data/example_114.msht", 114).unwrap();
// now do whatever you want with it
The full library documentation is published here for convenience.
Priority:
- HDF5 support is a priority with the release of MCNPv6.3 (behind feature flag as it depends on
libhdf5
) - Various tools for working with/converting to the new HDF5 formats
- Python bindings to make core functionality accessible
Time/need permitting, and in no particular order:
- Cell-under-Voxel sub-voxel plotting
Posvol
deserialisation allowing user to specify byte size and endian- Allow mesh2vtk rotations/translation from command line
- Tools for extracting lines and planes from meshes, not just points
- Voxel result averaging for points exactly on 2-4 voxel boundaries
- Spherical mesh types just in case anyone cares
- WWINP file reader