Merge commit 'upstream/develop' into res_scat
4
.gitignore
vendored
|
|
@ -19,6 +19,7 @@ src/openmc
|
|||
|
||||
# Documentation builds
|
||||
docs/build
|
||||
docs/source/_images/*.pdf
|
||||
|
||||
# xml-fortran reader
|
||||
src/xml-fortran/xmlreader
|
||||
|
|
@ -28,3 +29,6 @@ src/templates/*.f90
|
|||
|
||||
# Test results error file
|
||||
results_error.dat
|
||||
|
||||
# HDF5 files
|
||||
*.h5
|
||||
|
|
|
|||
2
LICENSE
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2011-2013 Massachusetts Institute of Technology
|
||||
Copyright (c) 2011-2014 Massachusetts Institute of Technology
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
|
|
|
|||
1716
data/cross_sections_nndc.xml
Normal file
96
data/get_nndc_data.py
Executable file
|
|
@ -0,0 +1,96 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tarfile
|
||||
|
||||
try:
|
||||
from urllib.request import urlopen
|
||||
except ImportError:
|
||||
from urllib2 import urlopen
|
||||
|
||||
baseUrl = 'http://www.nndc.bnl.gov/endf/b7.1/aceFiles/'
|
||||
files = ['ENDF-B-VII.1-neutron-293.6K.tar.gz',
|
||||
'ENDF-B-VII.1-neutron-300K.tar.gz',
|
||||
'ENDF-B-VII.1-neutron-900K.tar.gz',
|
||||
'ENDF-B-VII.1-neutron-1500K.tar.gz',
|
||||
'ENDF-B-VII.1-tsl.tar.gz']
|
||||
block_size = 16384
|
||||
|
||||
# ==============================================================================
|
||||
# DOWNLOAD FILES FROM NNDC SITE
|
||||
|
||||
filesComplete = []
|
||||
for f in files:
|
||||
# Establish connection to URL
|
||||
url = baseUrl + f
|
||||
req = urlopen(url)
|
||||
|
||||
# Get file size from header
|
||||
file_size = int(req.info().getheaders('Content-Length')[0])
|
||||
downloaded = 0
|
||||
|
||||
# Check if file already downloaded
|
||||
if os.path.exists(f):
|
||||
if os.path.getsize(f) == file_size:
|
||||
print('Skipping ' + f)
|
||||
filesComplete.append(f)
|
||||
continue
|
||||
else:
|
||||
if sys.version_info[0] < 3:
|
||||
overwrite = raw_input('Overwrite {0}? ([y]/n) '.format(f))
|
||||
else:
|
||||
overwrite = input('Overwrite {0}? ([y]/n) '.format(f))
|
||||
if overwrite.lower().startswith('n'):
|
||||
continue
|
||||
|
||||
# Copy file to disk
|
||||
print('Downloading {0}... '.format(f), end='')
|
||||
with open(f, 'wb') as fh:
|
||||
while True:
|
||||
chunk = req.read(block_size)
|
||||
if not chunk: break
|
||||
fh.write(chunk)
|
||||
downloaded += len(chunk)
|
||||
status = '{0:10} [{1:3.2f}%]'.format(downloaded, downloaded * 100. / file_size)
|
||||
print(status + chr(8)*len(status), end='')
|
||||
print('')
|
||||
filesComplete.append(f)
|
||||
|
||||
# ==============================================================================
|
||||
# EXTRACT FILES FROM TGZ
|
||||
|
||||
for f in files:
|
||||
if not f in filesComplete:
|
||||
continue
|
||||
|
||||
# Extract files
|
||||
suffix = f[f.rindex('-') + 1:].rstrip('.tar.gz')
|
||||
with tarfile.open(f, 'r') as tgz:
|
||||
print('Extracting {0}...'.format(f))
|
||||
tgz.extractall(path='nndc/' + suffix)
|
||||
|
||||
# ==============================================================================
|
||||
# COPY CROSS_SECTIONS.XML
|
||||
|
||||
print('Copying cross_sections_nndc.xml...')
|
||||
shutil.copyfile('cross_sections_nndc.xml', 'nndc/cross_sections.xml')
|
||||
|
||||
# ==============================================================================
|
||||
# PROMPT USER TO DELETE .TAR.GZ FILES
|
||||
|
||||
# Ask user to delete
|
||||
if sys.version_info[0] < 3:
|
||||
response = raw_input('Delete *.tar.gz files? ([y]/n) ')
|
||||
else:
|
||||
response = input('Delete *.tar.gz files? ([y]/n) ')
|
||||
|
||||
# Delete files if requested
|
||||
if not response or response.lower().startswith('y'):
|
||||
for f in files:
|
||||
if os.path.exists(f):
|
||||
print('Removing {0}...'.format(f))
|
||||
os.remove(f)
|
||||
|
|
@ -15,6 +15,9 @@ work with a few common cross section sources.
|
|||
- **cross_sections_ascii.xml** -- This file matches ENDF/B-VII.0 cross sections
|
||||
distributed with MCNP5 / MCNP6 beta.
|
||||
|
||||
- **cross_sections_nndc.xml** -- This file matches ENDF/B-VII.1 cross sections
|
||||
distributed from the `NNDC website`_.
|
||||
|
||||
- **cross_sections_serpent.xml** -- This file matches ENDF/B-VII.0 cross
|
||||
sections distributed with Serpent 1.1.7.
|
||||
|
||||
|
|
@ -31,3 +34,4 @@ element in your settings.xml, or set the CROSS_SECTIONS environment variable to
|
|||
the full path of the cross_sections.xml file.
|
||||
|
||||
.. _user's guide: http://mit-crpg.github.io/openmc/usersguide/install.html#cross-section-configuration
|
||||
.. _NNDC website: http://www.nndc.bnl.gov/endf/b7.1/acefiles.html
|
||||
|
|
|
|||
|
|
@ -6,13 +6,19 @@ SPHINXOPTS =
|
|||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = build
|
||||
IMAGEDIR = source/_images
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
|
||||
# SVG to PDF conversion
|
||||
SVG2PDF = inkscape
|
||||
PDFS = $(patsubst %.svg,%.pdf,$(wildcard $(IMAGEDIR)/*.svg))
|
||||
|
||||
|
||||
.PHONY: help images clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
|
|
@ -33,8 +39,16 @@ help:
|
|||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
|
||||
# Pattern rule for converting SVG to PDF
|
||||
%.pdf: %.svg
|
||||
$(SVG2PDF) -f $< -A $@
|
||||
|
||||
# Rule to build PDFs
|
||||
images: $(PDFS)
|
||||
|
||||
clean:
|
||||
-rm -rf $(BUILDDIR)/*
|
||||
-rm $(PDFS)
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
|
|
@ -91,14 +105,14 @@ epub:
|
|||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
latex:
|
||||
latex: images
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
latexpdf:
|
||||
latexpdf: images
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
make -C $(BUILDDIR)/latex all-pdf
|
||||
|
|
|
|||
BIN
docs/source/_images/3dba.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 278 KiB After Width: | Height: | Size: 278 KiB |
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 460 KiB After Width: | Height: | Size: 460 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 4 KiB After Width: | Height: | Size: 4 KiB |
|
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 8.7 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
|
@ -39,7 +39,7 @@ master_doc = 'index'
|
|||
|
||||
# General information about the project.
|
||||
project = u'OpenMC'
|
||||
copyright = u'2011-2013, Massachusetts Institute of Technology'
|
||||
copyright = u'2011-2014, Massachusetts Institute of Technology'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
|
|
@ -121,7 +121,7 @@ html_title = "OpenMC Documentation"
|
|||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
html_logo = '../img/openmc.png'
|
||||
html_logo = '_images/openmc.png'
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
|
|
@ -188,6 +188,8 @@ latex_documents = [
|
|||
u'Massachusetts Institute of Technology', 'manual'),
|
||||
]
|
||||
|
||||
latex_elements = {'preamble': '\\usepackage{enumitem}\\setlistdepth{9}'}
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ features and bug fixes. The general steps for contributing are as follows:
|
|||
repository with the same name under your personal account. As such, you can
|
||||
commit to it as you please without disrupting other developers.
|
||||
|
||||
.. image:: ../../img/fork.png
|
||||
.. image:: ../_images/fork.png
|
||||
|
||||
2. Clone your fork of OpenMC and create a branch that branches off of *develop*:
|
||||
|
||||
|
|
@ -77,7 +77,7 @@ features and bug fixes. The general steps for contributing are as follows:
|
|||
4. Issue a pull request from GitHub and select the *develop* branch of
|
||||
mit-crpg/openmc as the target.
|
||||
|
||||
.. image:: ../../img/pullrequest.png
|
||||
.. image:: ../_images/pullrequest.png
|
||||
|
||||
At a minimum, you should describe what the changes you've made are and why
|
||||
you are making them. If the changes are related to an oustanding issue, make
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
License Agreement
|
||||
=================
|
||||
|
||||
Copyright © 2011-2013 Massachusetts Institute of Technology
|
||||
Copyright © 2011-2014 Massachusetts Institute of Technology
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ dashed box would need to be stored on a per-nuclide basis, and the union grid
|
|||
would need to be stored once. This method is also referred to as *double
|
||||
indexing* and is available as an option in Serpent (see paper by Leppanen_).
|
||||
|
||||
.. figure:: ../../img/uniongrid.svg
|
||||
.. figure:: ../_images/uniongrid.*
|
||||
:width: 600px
|
||||
:align: center
|
||||
:figclass: align-center
|
||||
|
|
|
|||
|
|
@ -108,6 +108,40 @@ at plots of :math:`k_{eff}` and the Shannon entropy. A number of methods have
|
|||
been proposed (see e.g. [Romano]_, [Ueki]_), but each of these is not without
|
||||
problems.
|
||||
|
||||
---------------------------
|
||||
Uniform Fission Site Method
|
||||
---------------------------
|
||||
|
||||
Generally speaking, the variance of a Monte Carlo tally will be inversely
|
||||
proportional to the number of events that score to the tally. In a reactor
|
||||
problem, this implies that regions with low relative power density will have
|
||||
higher variance that regions with high relative power density. One method to
|
||||
circumvent the uneven distribution of relative errors is the uniform fission
|
||||
site (UFS) method introduced by [Sutton]_. In this method, the portion of the
|
||||
problem containing fissionable material is subdivided into a number of cells
|
||||
(typically using a structured mesh). Rather than producing
|
||||
|
||||
.. math::
|
||||
|
||||
m = \frac{w}{k} \frac{\nu\Sigma_f}{\Sigma_t}
|
||||
|
||||
fission sites at each collision where :math:`w` is the weight of the neutron,
|
||||
:math:`k` is the previous-generation estimate of the neutron multiplication
|
||||
factor, :math:`\nu\Sigma_f` is the neutron production cross section, and
|
||||
:math:`\Sigma_t` is the total cross section, in the UFS method we produce
|
||||
|
||||
.. math::
|
||||
|
||||
m_{UFS} = \frac{w}{k} \frac{\nu\Sigma_f}{\Sigma_t} \frac{v_i}{s_i}
|
||||
|
||||
fission sites at each collision where :math:`v_i` is the fraction of the total
|
||||
volume occupied by cell :math:`i` and :math:`s_i` is the fraction of the fission
|
||||
source contained in cell :math:`i`. To ensure that no bias is introduced, the
|
||||
weight of each fission site stored in the fission bank is :math:`s_i/v_i` rather
|
||||
than unity. By ensuring that the expected number of fission sites in each mesh
|
||||
cell is constant, the collision density across all cells, and hence the variance
|
||||
of tallies, is more uniform than it would be otherwise.
|
||||
|
||||
.. _Shannon entropy: https://laws.lanl.gov/vhosts/mcnp.lanl.gov/pdf_files/la-ur-06-3737_entropy.pdf
|
||||
|
||||
.. [Lieberoth] J. Lieberoth, "A Monte Carlo Technique to Solve the Static
|
||||
|
|
@ -119,5 +153,9 @@ problems.
|
|||
*Proc. International Conference on Mathematics, Computational Methods, and
|
||||
Reactor Physics*, Saratoga Springs, New York (2009).
|
||||
|
||||
.. [Sutton] Daniel J. Kelly, Thomas M. Sutton, and Stephen C. Wilson, "MC21
|
||||
Analysis of the Nuclear Energy Agency Monte Carlo Performance Benchmark
|
||||
Problem," *Proc. PHYSOR 2012*, Knoxville, Tennessee, Apr. 15--20 (2012).
|
||||
|
||||
.. [Ueki] Taro Ueki, "On-the-Fly Judgments of Monte Carlo Fission Source
|
||||
Convergence," *Trans. Am. Nucl. Soc.*, **98**, 512 (2008).
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ surface by a combination of the unique ID of the surface and a positive/negative
|
|||
sign. The following illustration shows an example of an ellipse with unique ID 1
|
||||
dividing space into two half-spaces.
|
||||
|
||||
.. figure:: ../../img/halfspace.svg
|
||||
.. figure:: ../_images/halfspace.*
|
||||
:align: center
|
||||
:figclass: align-center
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ half-space references whose intersection defines the region. The region is then
|
|||
assigned a material defined elsewhere. The following illustration shows an
|
||||
example of a cell defined as the intersection of an ellipse and two planes.
|
||||
|
||||
.. figure:: ../../img/union.svg
|
||||
.. figure:: ../_images/union.*
|
||||
:align: center
|
||||
:figclass: align-center
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ in the case of an eigenvalue calculation). This idea is illustrated in
|
|||
|
||||
.. _figure-master-slave:
|
||||
|
||||
.. figure:: ../../img/master-slave.png
|
||||
.. figure:: ../_images/master-slave.png
|
||||
:align: center
|
||||
:figclass: align-center
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ needed. This concept is illustrated in :ref:`Figure 2
|
|||
|
||||
.. _figure-nearest-neighbor:
|
||||
|
||||
.. figure:: ../../img/nearest-neighbor.png
|
||||
.. figure:: ../_images/nearest-neighbor.png
|
||||
:align: center
|
||||
:figclass: align-center
|
||||
|
||||
|
|
@ -203,7 +203,7 @@ communicated between adjacent nodes.
|
|||
|
||||
.. _figure-neighbor-example:
|
||||
|
||||
.. figure:: ../../img/nearest-neighbor-example.png
|
||||
.. figure:: ../_images/nearest-neighbor-example.png
|
||||
:align: center
|
||||
:figclass: align-center
|
||||
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@ Publications
|
|||
|
||||
- Andrew R. Siegel, Kord Smith, Paul K. Romano, Benoit Forget, and Kyle Felker,
|
||||
"Multi-core performance studies of a Monte Carlo neutron transport code,"
|
||||
*Int. J. High Perform. Comput. Appl.*
|
||||
(2013). `<http://dx.doi.org/10.1177/1094342013492179>`_
|
||||
*Int. J. High Perform. Comput. Appl.*, **28** (1), 87--96
|
||||
(2014). `<http://dx.doi.org/10.1177/1094342013492179>`_
|
||||
|
||||
- Paul K. Romano, Andrew R. Siegel, Benoit Forget, and Kord Smith, "Data
|
||||
decomposition of Monte Carlo particle transport simulations via tally
|
||||
|
|
|
|||
|
|
@ -48,7 +48,12 @@ following commands in a terminal:
|
|||
sudo make install
|
||||
|
||||
This will build an executable named ``openmc`` and install it (by default in
|
||||
/usr/local/bin).
|
||||
/usr/local/bin). If you do not have administrator privileges, the last command
|
||||
can be replaced with a local install, e.g.
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
make install -e prefix=$HOME/.local
|
||||
|
||||
.. _GitHub: https://github.com/mit-crpg/openmc
|
||||
.. _git: http://git-scm.com
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ bugs fixed, and known issues for each successive release.
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
notes_0.5.4
|
||||
notes_0.5.3
|
||||
notes_0.5.2
|
||||
notes_0.5.1
|
||||
|
|
|
|||
63
docs/source/releasenotes/notes_0.5.4.rst
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
.. _notes_0.5.4:
|
||||
|
||||
==============================
|
||||
Release Notes for OpenMC 0.5.4
|
||||
==============================
|
||||
|
||||
.. note::
|
||||
These release notes are for an upcoming release of OpenMC and are still
|
||||
subject to change.
|
||||
|
||||
-------------------
|
||||
System Requirements
|
||||
-------------------
|
||||
|
||||
There are no special requirements for running the OpenMC code. As of this
|
||||
release, OpenMC has been tested on a variety of Linux distributions, Mac OS X,
|
||||
and Microsoft Windows 7. Memory requirements will vary depending on the size of
|
||||
the problem at hand (mostly on the number of nuclides in the problem).
|
||||
|
||||
------------
|
||||
New Features
|
||||
------------
|
||||
|
||||
- New XML parsing backend (FoX)
|
||||
- Ability to write particle track files
|
||||
- Handle lost particles more gracefully (via particle track files)
|
||||
- Source sites outside geometry are resampled
|
||||
- Multiple random number generator streams
|
||||
- plot_mesh_tally.py utility converted to use Tkinter rather than PyQt
|
||||
- Script added to download ACE data from NNDC
|
||||
- Mixed ASCII/binary cross_sections.xml now allowed
|
||||
- Expanded options for writing source bank
|
||||
- Re-enabled ability to use source file as starting source
|
||||
|
||||
---------
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- 32c03c_: Check for valid data in cross_sections.xml
|
||||
- c71ef5_: Fix bug in statepoint.py
|
||||
- 8884fb_: Check for all ZAIDs for S(a,b) tables
|
||||
- b38af0_: Fix XML reading on multiple levels of input
|
||||
- d28750_: Fix bug in convert_xsdir.py
|
||||
|
||||
.. _32c03c: https://github.com/mit-crpg/openmc/commit/32c03c
|
||||
.. _c71ef5: https://github.com/mit-crpg/openmc/commit/c71ef5
|
||||
.. _8884fb: https://github.com/mit-crpg/openmc/commit/8884fb
|
||||
.. _b38af0: https://github.com/mit-crpg/openmc/commit/b38af0
|
||||
.. _d28750: https://github.com/mit-crpg/openmc/commit/d28750
|
||||
|
||||
------------
|
||||
Contributors
|
||||
------------
|
||||
|
||||
This release contains new contributions from the following people:
|
||||
|
||||
- `Sterling Harper <smharper@mit.edu>`_
|
||||
- `Bryan Herman <bherman@mit.edu>`_
|
||||
- `Nick Horelik <nhorelik@mit.edu>`_
|
||||
- `Adam Nelson <nelsonag@umich.edu>`_
|
||||
- `Paul Romano <paul.k.romano@gmail.com>`_
|
||||
- `Tuomas Viitanen <tuomas.viitanen@vtt.fi>`_
|
||||
- `Jon Walsh <walshjon@mit.edu>`_
|
||||
|
|
@ -264,7 +264,9 @@ attributes/sub-elements:
|
|||
|
||||
:file:
|
||||
If this attribute is given, it indicates that the source is to be read from
|
||||
a binary source file whose path is given by the value of this element
|
||||
a binary source file whose path is given by the value of this element. Note,
|
||||
the number of source sites needs to be the same as the number of particles
|
||||
simulated in a fission source generation.
|
||||
|
||||
*Default*: None
|
||||
|
||||
|
|
@ -348,8 +350,10 @@ attributes/sub-elements:
|
|||
|
||||
The ``<state_point>`` element indicates at what batches a state point file
|
||||
should be written. A state point file can be used to restart a run or to get
|
||||
tally results at any batch. This element has the following
|
||||
attributes/sub-elements:
|
||||
tally results at any batch. The default behavior when using this tag is to
|
||||
write out the source bank in the state_point file. This behavior can be
|
||||
customized by using the ``<source_point>`` element. This element has the
|
||||
following attributes/sub-elements:
|
||||
|
||||
:batches:
|
||||
A list of integers separated by spaces indicating at what batches a state
|
||||
|
|
@ -364,19 +368,52 @@ attributes/sub-elements:
|
|||
|
||||
*Default*: None
|
||||
|
||||
``<source_point>`` Element
|
||||
--------------------------
|
||||
|
||||
The ``<source_point>`` element indicates at what batches the source bank
|
||||
should be written. The source bank can be either written out within a state
|
||||
point file or separately in a source point file. This element has the following
|
||||
attributes/sub-elements:
|
||||
|
||||
:batches:
|
||||
A list of integers separated by spaces indicating at what batches a state
|
||||
point file should be written. It should be noted that if source_separate
|
||||
tag is not set to "true", this list must be a subset of state point batches.
|
||||
|
||||
*Default*: Last batch only
|
||||
|
||||
:interval:
|
||||
A single integer :math:`n` indicating that a state point should be written
|
||||
every :math:`n` batches. This option can be given in lieu of listing
|
||||
batches explicitly. It should be noted that if source_separate tag is not
|
||||
set to "true", this value should produce a list of batches that is a subset
|
||||
of state point batches.
|
||||
|
||||
*Default*: None
|
||||
|
||||
:source_separate:
|
||||
If this element is set to "true", a separate binary source file will be
|
||||
If this element is set to "true", a separate binary source point file will be
|
||||
written. Otherwise, the source sites will be written in the state point
|
||||
directly.
|
||||
|
||||
*Default*: false
|
||||
|
||||
:source_write: If this element is set to "false", source sites are not written
|
||||
to the state point file. This can substantially reduce the size of state
|
||||
points if large numbers of particles per batch are used.
|
||||
:source_write:
|
||||
If this element is set to "false", source sites are not written
|
||||
to the state point or source point file. This can substantially reduce the
|
||||
size of state points if large numbers of particles per batch are used.
|
||||
|
||||
*Default*: true
|
||||
|
||||
:overwrite_latest:
|
||||
If this element is set to "true", a source point file containing
|
||||
the source bank will be written out to a separate file named
|
||||
``source.binary`` or ``source.h5`` depending on if HDF5 is enabled.
|
||||
This file will be overwritten at every single batch so that the latest
|
||||
source bank will be available. It should be noted that a user can set both
|
||||
this element to "true" and specify batches to write a permanent source bank.
|
||||
|
||||
``<survival_biasing>`` Element
|
||||
------------------------------
|
||||
|
||||
|
|
@ -1052,7 +1089,7 @@ sub-elements:
|
|||
the PNG format can often times reduce the file size by orders of
|
||||
magnitude without any loss of image quality. Likewise,
|
||||
high-resolution voxel files produced by OpenMC can be quite large,
|
||||
but the equivalent SILO files will by significantly smaller.
|
||||
but the equivalent SILO files will be significantly smaller.
|
||||
|
||||
*Default*: "slice"
|
||||
|
||||
|
|
|
|||
|
|
@ -189,7 +189,15 @@ the root directory of the source code:
|
|||
sudo make install
|
||||
|
||||
This will build an executable named ``openmc`` and install it (by default in
|
||||
/usr/local/bin).
|
||||
/usr/local/bin). If you do not have administrative privileges, you can install
|
||||
OpenMC locally by replacing the last command with:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
make install -e prefix=$HOME/.local
|
||||
|
||||
The ``prefix`` variable can be changed to any path for which you have
|
||||
write-access.
|
||||
|
||||
Compiling on Windows
|
||||
--------------------
|
||||
|
|
@ -264,10 +272,27 @@ Cross Section Configuration
|
|||
|
||||
In order to run a simulation with OpenMC, you will need cross section data for
|
||||
each nuclide in your problem. Since OpenMC uses ACE format cross sections, you
|
||||
can use nuclear data that was processed with NJOY, such as that distributed with
|
||||
MCNP_ or Serpent_. The TALYS-based evaluated nuclear data library, TENDL_, is
|
||||
can use nuclear data that was processed with NJOY_, such as that distributed
|
||||
with MCNP_ or Serpent_. Several sources provide free processed ACE data as
|
||||
described below. The TALYS-based evaluated nuclear data library, TENDL_, is also
|
||||
openly available in ACE format.
|
||||
|
||||
Using ENDF/B-VII.1 Cross Sections from NNDC
|
||||
-------------------------------------------
|
||||
|
||||
The NNDC_ provides ACE data from the ENDF/B-VII.1 neutron and thermal scattering
|
||||
sublibraries at four temperatures processed using NJOY_. To use this data with
|
||||
OpenMC, a script is provided with OpenMC that will automatically download,
|
||||
extract, and set up a confiuration file:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
cd openmc/data
|
||||
python get_nndc_data.py
|
||||
|
||||
At this point, you should set the :envvar:`CROSS_SECTIONS` environment variable
|
||||
to the absolute path of the file ``openmc/data/nndc/cross_sections.xml``.
|
||||
|
||||
Using JEFF Cross Sections from OECD/NEA
|
||||
---------------------------------------
|
||||
|
||||
|
|
@ -314,6 +339,8 @@ distribution to the location of the Serpent cross sections. Then, either set the
|
|||
environment variable to the absolute path of the ``cross_sections_serpent.xml``
|
||||
file.
|
||||
|
||||
.. _NJOY: http://t2.lanl.gov/nis/codes.shtml
|
||||
.. _NNDC: http://www.nndc.bnl.gov/endf/b7.1/acefiles.html
|
||||
.. _NEA: http://www.oecd-nea.org
|
||||
.. _JEFF: http://www.oecd-nea.org/dbdata/jeff/
|
||||
.. _here: http://www.oecd-nea.org/dbdata/pubs/jeff312-cd.html
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ Data Processing and Visualization
|
|||
=================================
|
||||
|
||||
This section is intended to explain in detail the recommended procedures for
|
||||
carrying out common tasks with OpenMC. While several utilities of varying
|
||||
complexity are provided to help automate the process, in many cases it will be
|
||||
extremely beneficial to do some coding in Python to quickly obtain results. In
|
||||
these cases, and for many of the provided utilities, it is necessary for your
|
||||
Python installation to contain:
|
||||
carrying out common post-processing tasks with OpenMC. While several utilities
|
||||
of varying complexity are provided to help automate the process, in many cases
|
||||
it will be extremely beneficial to do some coding in Python to quickly obtain
|
||||
results. In these cases, and for many of the provided utilities, it is necessary
|
||||
for your Python installation to contain:
|
||||
|
||||
* [1]_ `Numpy <http://www.numpy.org/>`_
|
||||
* [1]_ `Scipy <http://www.scipy.org/>`_
|
||||
|
|
@ -38,9 +38,58 @@ running OpenMC with the -plot or -p command-line option (See
|
|||
Plotting in 2D
|
||||
--------------
|
||||
|
||||
.. image:: ../../img/atr.png
|
||||
.. image:: ../_images/atr.png
|
||||
:height: 200px
|
||||
|
||||
See below for a simple example of a plots xml file that demonstrates the
|
||||
capabilities of 2D slice plots. Here we assume that there is a ``geometry.xml``
|
||||
file containing 7 cells.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<plots>
|
||||
|
||||
<plot id="1" type="slice" color="cell" basis="xy">
|
||||
<filename> myplot </filename>
|
||||
<origin> 0 0 </origin>
|
||||
<width> 10 10 </width>
|
||||
<pixels> 2000 2000 </pixels>
|
||||
<background> 0 0 0 </background>
|
||||
<col_spec id="1" rgb="198 226 255"/>
|
||||
<col_spec id="2" rgb="255 218 185"/>
|
||||
<col_spec id="3" rgb="255 255 255"/>
|
||||
<col_spec id="4" rgb="101 101 101"/>
|
||||
<col_spec id="7" rgb="123 123 231"/>
|
||||
<mask background="255 255 255">
|
||||
<components> 1 3 4 5 6 </components>
|
||||
</mask>
|
||||
</plot>
|
||||
|
||||
</plots>
|
||||
|
||||
|
||||
In this example, OpenMC will produce a plot named ``myplot.ppm`` when run in
|
||||
plotting mode. The picture will be on the xy-plane, depicting the rectangle
|
||||
between points (-5,-5) and (5,5) with 2000 pixels along each dimension. The
|
||||
color of each pixel is determined by placing a particle at the center of that
|
||||
pixel and using OpenMC's internal ``find_cell`` routine (the same one used for
|
||||
particle tracking during simulation) to determine the cell and material at that
|
||||
location. In this example, pixels are 10/2000=0.005 cm wide, so points will be
|
||||
at (-4.9975,-4.9975), (-4.9950,-4.9975), (-4.9925,-4.9975), etc. This is pointed
|
||||
out to demonstrate that this plot may miss any features smaller than 0.005 cm,
|
||||
since they could exist between pixel centers. More pixels can be used to resolve
|
||||
finer features, but could result in larger files.
|
||||
|
||||
The ``background``, ``col_spec``, and ``mask`` elements define how to set pixel
|
||||
colors based on the cell ids at each pixel center. In this example, RGB colors
|
||||
are specified for cells 1,2,3,4, and 7, a random color will be assigned to cells
|
||||
5 and 6, and a black background color (``rgb="0 0 0"``) will be applied to
|
||||
locations where no cell is defined. However, the ``mask`` element here says that
|
||||
only cells 1,3,4,5, and 6 should be displayed, with other cells taking a white
|
||||
color (``rgb="255 255 255"``), which overrides the ``col_spec`` for cell 2 and
|
||||
the random color assigned to cell 7.
|
||||
|
||||
After running OpenMC to obtain PPM files, images should be saved to another
|
||||
format before using them elsewhere. This cuts down the size of the file by
|
||||
orders of magnitude. Most image viewers and editors that can view PPM images
|
||||
|
|
@ -53,18 +102,45 @@ Ubuntu: ``sudo apt-get install imagemagick``). Images are then converted like:
|
|||
|
||||
.. code-block:: sh
|
||||
|
||||
convert plot.ppm plot.png
|
||||
convert myplot.ppm myplot.png
|
||||
|
||||
Plotting in 3D
|
||||
--------------
|
||||
|
||||
.. image:: ../../img/3dgeomplot.png
|
||||
.. image:: ../_images/3dgeomplot.png
|
||||
:height: 200px
|
||||
|
||||
See below for a simple example of a plots xml file that demonstrates the
|
||||
capabilities of 3D voxel plots.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<plots>
|
||||
|
||||
<plot id="1" type="voxel" color="mat">
|
||||
<filename> myplot </filename>
|
||||
<origin> 0 0 0 </origin>
|
||||
<width> 10 10 10 </width>
|
||||
<pixels> 500 500 500 </pixels>
|
||||
</plot>
|
||||
|
||||
</plots>
|
||||
|
||||
Voxel plots are built the same way 2D slice plots are, by determining the cell
|
||||
or material id of a particle at the center of each voxel. In this example, the
|
||||
space covered is the cube between the points (-5,-5,-5) and (5,5,5), with voxel
|
||||
centers 10/500 = 0.02 cm apart. The binary VOXEL files that are produced do not
|
||||
specify any color - instead containing only material or cell ids (material id
|
||||
in this example) - and thus the ``background``, ``col_spec``, and ``mask``
|
||||
elements are not used. If no cell is found at a voxel center, an id of -1 is
|
||||
stored.
|
||||
|
||||
The binary VOXEL files output by OpenMC can not be viewed directly by any
|
||||
existing viewers. In order to view them, they must be converted into a standard
|
||||
mesh format that can be viewed in ParaView, Visit, etc. The provided utility
|
||||
voxel.py accomplishes this for SILO:
|
||||
mesh format that can be viewed in ParaView, Visit, etc. This typically will
|
||||
compress the size of the file significantly. The provided utility voxel.py
|
||||
accomplishes this for SILO:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
|
|
@ -88,13 +164,21 @@ or
|
|||
Users can process the binary into any other format if desired by following the
|
||||
example of voxel.py. For the binary file structure, see :ref:`devguide_voxel`.
|
||||
|
||||
Once processed into a standard 3D file format, colors and masks can be defined
|
||||
using the stored id numbers to better explore the geometry. The process for
|
||||
doing this will depend on the 3D viewer, but should be straightforward.
|
||||
|
||||
.. image:: ../_images/3dba.png
|
||||
:height: 200px
|
||||
|
||||
.. note:: 3D voxel plotting can be very computer intensive for the viewing
|
||||
program (Visit, Paraview, etc.) if the number of voxels is large (>10
|
||||
million or so). Thus if you want an accurate picture that renders
|
||||
smoothly, consider using only one voxel in a certain direction. For
|
||||
instance, the 3D pin lattice figure above was generated with a
|
||||
500x500x1 voxel mesh, which allows for resolution of the cylinders
|
||||
without wasting too many voxels on the axial dimension.
|
||||
instance, the 3D pin lattice figure at the beginning of this section
|
||||
was generated with a 500x500x1 voxel mesh, which allows for resolution
|
||||
of the cylinders without wasting too many voxels on the axial
|
||||
dimension.
|
||||
|
||||
|
||||
-------------------
|
||||
|
|
@ -162,7 +246,7 @@ tasks will be described here in the following sections.
|
|||
Plotting in 2D
|
||||
--------------
|
||||
|
||||
.. image:: ../../img/plotmeshtally.png
|
||||
.. image:: ../_images/plotmeshtally.png
|
||||
:height: 200px
|
||||
|
||||
For simple viewing of 2D slices of a mesh plot, the utility plot_mesh_tally.py
|
||||
|
|
@ -170,7 +254,7 @@ is provided. This utility provides an interactive GUI to explore and plot
|
|||
mesh tallies for any scores and filter bins. It requires statepoint.py, as well
|
||||
as `PyQt <http://www.riverbankcomputing.com/software/pyqt>`_.
|
||||
|
||||
.. image:: ../../img/fluxplot.png
|
||||
.. image:: ../_images/fluxplot.png
|
||||
:height: 200px
|
||||
|
||||
Alternatively, the user can write their own Python script to manipulate the data
|
||||
|
|
@ -249,7 +333,7 @@ two heatmaps in the previous figure.
|
|||
Plotting in 3D
|
||||
--------------
|
||||
|
||||
.. image:: ../../img/3dcore.png
|
||||
.. image:: ../_images/3dcore.png
|
||||
:height: 200px
|
||||
|
||||
As with 3D plots of the geometry, meshtally data needs to be put into a standard
|
||||
|
|
@ -357,7 +441,7 @@ and dumped to MATLAB in one step.
|
|||
Particle Track Visualization
|
||||
----------------------------
|
||||
|
||||
.. image:: ../../img/Tracks.png
|
||||
.. image:: ../_images/Tracks.png
|
||||
:height: 200px
|
||||
|
||||
OpenMC can dump particle tracks—the position of particles as they are
|
||||
|
|
|
|||
|
|
@ -79,6 +79,14 @@ with the :envvar:`CROSS_SECTIONS` environment variable. It is recommended to add
|
|||
a line in your ``.profile`` or ``.bash_profile`` setting the
|
||||
:envvar:`CROSS_SECTIONS` environment variable.
|
||||
|
||||
ERROR: Invalid usage of L(I) in ACE data; Consider using more recent data set.
|
||||
******************************************************************************
|
||||
|
||||
The cross-sections requested in ``materials.xml`` do not conform to the current
|
||||
standard format. This typically happens with fissionable nuclides in a ``.6*c``
|
||||
library as distributed with MCNP. Please try a newer library such as any from
|
||||
the ``.7*c`` set.
|
||||
|
||||
Geometry Debugging
|
||||
******************
|
||||
|
||||
|
|
@ -107,8 +115,8 @@ have many particles travelling through them there will not be many locations
|
|||
where overlaps are checked for in that region. The user should refer to the
|
||||
output after a geometry debug run to see how many checks were performed in each
|
||||
cell, and then adjust the number of starting particles or starting source
|
||||
distributions accordingly to achieve good coverage.
|
||||
|
||||
distributions accordingly to achieve good coverage.
|
||||
|
||||
ERROR: After particle __ crossed surface __ it could not be located in any cell and it did not leak.
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ to locate ACE format cross section libraries if the user has not specified the
|
|||
<cross_sections> tag in
|
||||
.I settings.xml\fP.
|
||||
.SH LICENSE
|
||||
Copyright \(co 2011-2013 Massachusetts Institute of Technology.
|
||||
Copyright \(co 2011-2014 Massachusetts Institute of Technology.
|
||||
.PP
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
|
|
|
|||
10
src/Makefile
|
|
@ -181,17 +181,17 @@ endif
|
|||
|
||||
ifeq ($(OPENMP),yes)
|
||||
ifeq ($(COMPILER),intel)
|
||||
F90FLAGS += -openmp -DOPENMP
|
||||
F90FLAGS += -openmp
|
||||
LDFLAGS += -openmp
|
||||
endif
|
||||
|
||||
ifeq ($(COMPILER),gnu)
|
||||
F90FLAGS += -fopenmp -DOPENMP
|
||||
F90FLAGS += -fopenmp
|
||||
LDFLAGS += -fopenmp
|
||||
endif
|
||||
|
||||
ifeq ($(COMPILER),ibm)
|
||||
F90FLAGS += -qsmp=omp -WF,-DOPENMP
|
||||
F90FLAGS += -qsmp=omp
|
||||
LDFLAGS += -qsmp=omp
|
||||
endif
|
||||
endif
|
||||
|
|
@ -218,7 +218,7 @@ endif
|
|||
|
||||
ifeq ($(MACHINE),bluegene)
|
||||
F90 = /bgsys/drivers/ppcfloor/comm/xl/bin/mpixlf2003
|
||||
F90FLAGS = -WF,-DNO_F2008,-DMPI -O3
|
||||
F90FLAGS = -WF,-DNO_F2008,-DMPI,-DRESTRICTED_ASSOCIATED_BUG -O3
|
||||
LDFLAGS = -lmpich.cnkf90
|
||||
endif
|
||||
|
||||
|
|
@ -233,7 +233,7 @@ endif
|
|||
|
||||
ifeq ($(MACHINE),bluegeneq)
|
||||
F90 = mpixlf2003
|
||||
F90FLAGS = -WF,-DNO_F2008,-DMPI -O5
|
||||
F90FLAGS = -WF,-DNO_F2008,-DMPI,-DRESTRICTED_ASSOCIATED_BUG -O5
|
||||
endif
|
||||
|
||||
#===============================================================================
|
||||
|
|
|
|||
65
src/ace.F90
|
|
@ -1015,6 +1015,7 @@ contains
|
|||
integer :: NEa ! number of energies for Watt 'a'
|
||||
integer :: NRb ! number of interpolation regions for Watt 'b'
|
||||
integer :: NEb ! number of energies for Watt 'b'
|
||||
real(8), allocatable :: L(:) ! locations of distributions for each Ein
|
||||
|
||||
! initialize length
|
||||
length = 0
|
||||
|
|
@ -1039,6 +1040,22 @@ contains
|
|||
! Continuous tabular distribution
|
||||
NR = int(XSS(lc + 1))
|
||||
NE = int(XSS(lc + 2 + 2*NR))
|
||||
! Before progressing, check to see if data set uses L(I) values
|
||||
! in a way inconsistent with the current form of the ACE Format Guide
|
||||
! (MCNP5 Manual, Vol 3)
|
||||
allocate(L(NE))
|
||||
L = int(XSS(lc + 3 + 2*NR + NE: lc + 3 + 2*NR + 2*NE - 1))
|
||||
do i = 1,NE
|
||||
! Now check to see if L(i) is equal to any other entries
|
||||
! If so, then we must exit
|
||||
if (count(L == L(i)) > 1) then
|
||||
message = "Invalid usage of L(I) in ACE data; &
|
||||
&Consider using more recent data set."
|
||||
call fatal_error()
|
||||
end if
|
||||
end do
|
||||
deallocate(L)
|
||||
! Continue with finding data length
|
||||
length = length + 2 + 2*NR + 2*NE
|
||||
do i = 1,NE
|
||||
! determine length
|
||||
|
|
@ -1081,6 +1098,22 @@ contains
|
|||
! Kalbach-Mann correlated scattering
|
||||
NR = int(XSS(lc + 1))
|
||||
NE = int(XSS(lc + 2 + 2*NR))
|
||||
! Before progressing, check to see if data set uses L(I) values
|
||||
! in a way inconsistent with the current form of the ACE Format Guide
|
||||
! (MCNP5 Manual, Vol 3)
|
||||
allocate(L(NE))
|
||||
L = int(XSS(lc + 3 + 2*NR + NE: lc + 3 + 2*NR + 2*NE - 1))
|
||||
do i = 1,NE
|
||||
! Now check to see if L(i) is equal to any other entries
|
||||
! If so, then we must exit
|
||||
if (count(L == L(i)) > 1) then
|
||||
message = "Invalid usage of L(I) in ACE data; &
|
||||
&Consider using more recent data set."
|
||||
call fatal_error()
|
||||
end if
|
||||
end do
|
||||
deallocate(L)
|
||||
! Continue with finding data length
|
||||
length = length + 2 + 2*NR + 2*NE
|
||||
do i = 1,NE
|
||||
NP = int(XSS(lc + length + 2))
|
||||
|
|
@ -1095,6 +1128,22 @@ contains
|
|||
! Correlated energy and angle distribution
|
||||
NR = int(XSS(lc + 1))
|
||||
NE = int(XSS(lc + 2 + 2*NR))
|
||||
! Before progressing, check to see if data set uses L(I) values
|
||||
! in a way inconsistent with the current form of the ACE Format Guide
|
||||
! (MCNP5 Manual, Vol 3)
|
||||
allocate(L(NE))
|
||||
L = int(XSS(lc + 3 + 2*NR + NE: lc + 3 + 2*NR + 2*NE - 1))
|
||||
do i = 1,NE
|
||||
! Now check to see if L(i) is equal to any other entries
|
||||
! If so, then we must exit
|
||||
if (count(L == L(i)) > 1) then
|
||||
message = "Invalid usage of L(I) in ACE data; &
|
||||
&Consider using more recent data set."
|
||||
call fatal_error()
|
||||
end if
|
||||
end do
|
||||
deallocate(L)
|
||||
! Continue with finding data length
|
||||
length = length + 2 + 2*NR + 2*NE
|
||||
do i = 1,NE
|
||||
! outgoing energy distribution
|
||||
|
|
@ -1127,6 +1176,22 @@ contains
|
|||
! Laboratory energy-angle law
|
||||
NR = int(XSS(lc + 1))
|
||||
NE = int(XSS(lc + 2 + 2*NR))
|
||||
! Before progressing, check to see if data set uses L(I) values
|
||||
! in a way inconsistent with the current form of the ACE Format Guide
|
||||
! (MCNP5 Manual, Vol 3)
|
||||
allocate(L(NE))
|
||||
L = int(XSS(lc + 3 + 2*NR + NE: lc + 3 + 2*NR + 2*NE - 1))
|
||||
do i = 1,NE
|
||||
! Now check to see if L(i) is equal to any other entries
|
||||
! If so, then we must exit
|
||||
if (count(L == L(i)) > 1) then
|
||||
message = "Invalid usage of L(I) in ACE data; &
|
||||
&Consider using more recent data set."
|
||||
call fatal_error()
|
||||
end if
|
||||
end do
|
||||
deallocate(L)
|
||||
! Continue with finding data length
|
||||
NMU = int(XSS(lc + 4 + 2*NR + 2*NE))
|
||||
length = 4 + 2*(NR + NE + NMU)
|
||||
|
||||
|
|
|
|||
|
|
@ -577,7 +577,9 @@ contains
|
|||
end do
|
||||
|
||||
! Put cmfd tallies into active tally array and turn tallies on
|
||||
!$omp parallel
|
||||
call setup_active_cmfdtallies()
|
||||
!$omp end parallel
|
||||
tallies_on = .true.
|
||||
|
||||
end subroutine create_cmfd_tally
|
||||
|
|
|
|||
|
|
@ -11,13 +11,14 @@ module constants
|
|||
integer, parameter :: VERSION_RELEASE = 3
|
||||
|
||||
! Revision numbers for binary files
|
||||
integer, parameter :: REVISION_STATEPOINT = 10
|
||||
integer, parameter :: REVISION_STATEPOINT = 11
|
||||
integer, parameter :: REVISION_PARTICLE_RESTART = 1
|
||||
|
||||
! Binary file types
|
||||
integer, parameter :: &
|
||||
FILETYPE_STATEPOINT = -1, &
|
||||
FILETYPE_PARTICLE_RESTART = -2
|
||||
FILETYPE_PARTICLE_RESTART = -2, &
|
||||
FILETYPE_SOURCE = -3
|
||||
|
||||
! ============================================================================
|
||||
! ADJUSTABLE PARAMETERS
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ module eigenvalue
|
|||
use random_lcg, only: prn, set_particle_seed, prn_skip
|
||||
use search, only: binary_search
|
||||
use source, only: get_source_particle
|
||||
use state_point, only: write_state_point
|
||||
use state_point, only: write_state_point, write_source_point
|
||||
use string, only: to_str
|
||||
use tally, only: synchronize_tallies, setup_active_usertallies, &
|
||||
reset_result
|
||||
|
|
@ -166,7 +166,7 @@ contains
|
|||
|
||||
subroutine finalize_generation()
|
||||
|
||||
#ifdef OPENMP
|
||||
#ifdef _OPENMP
|
||||
! Join the fission bank from each thread into one global fission bank
|
||||
call join_bank_from_threads()
|
||||
#endif
|
||||
|
|
@ -222,6 +222,12 @@ contains
|
|||
call write_state_point()
|
||||
end if
|
||||
|
||||
! Write out source point if it's been specified for this batch
|
||||
if ((sourcepoint_batch % contains(current_batch) .or. source_latest) .and. &
|
||||
source_write) then
|
||||
call write_source_point()
|
||||
end if
|
||||
|
||||
if (master .and. current_batch == n_batches) then
|
||||
! Make sure combined estimate of k-effective is calculated at the last
|
||||
! batch in case no state point is written
|
||||
|
|
@ -821,7 +827,7 @@ contains
|
|||
|
||||
end subroutine replay_batch_history
|
||||
|
||||
#ifdef OPENMP
|
||||
#ifdef _OPENMP
|
||||
!===============================================================================
|
||||
! JOIN_BANK_FROM_THREADS
|
||||
!===============================================================================
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ module global
|
|||
! Source and fission bank
|
||||
type(Bank), allocatable, target :: source_bank(:)
|
||||
type(Bank), allocatable, target :: fission_bank(:)
|
||||
#ifdef OPENMP
|
||||
#ifdef _OPENMP
|
||||
type(Bank), allocatable, target :: master_fission_bank(:)
|
||||
#endif
|
||||
integer(8) :: n_bank ! # of sites in fission bank
|
||||
|
|
@ -189,6 +189,7 @@ module global
|
|||
! Write source at end of simulation
|
||||
logical :: source_separate = .false.
|
||||
logical :: source_write = .true.
|
||||
logical :: source_latest = .false.
|
||||
|
||||
! ============================================================================
|
||||
! PARALLEL PROCESSING VARIABLES
|
||||
|
|
@ -205,7 +206,7 @@ module global
|
|||
integer :: MPI_BANK ! MPI datatype for fission bank
|
||||
integer :: MPI_TALLYRESULT ! MPI datatype for TallyResult
|
||||
|
||||
#ifdef OPENMP
|
||||
#ifdef _OPENMP
|
||||
integer :: n_threads = NONE ! number of OpenMP threads
|
||||
integer :: thread_id ! ID of a given thread
|
||||
#endif
|
||||
|
|
@ -260,6 +261,7 @@ module global
|
|||
character(MAX_FILE_LEN) :: path_cross_sections ! Path to cross_sections.xml
|
||||
character(MAX_FILE_LEN) :: path_source = '' ! Path to binary source
|
||||
character(MAX_FILE_LEN) :: path_state_point ! Path to binary state point
|
||||
character(MAX_FILE_LEN) :: path_source_point ! Path to binary source point
|
||||
character(MAX_FILE_LEN) :: path_particle_restart ! Path to particle restart
|
||||
character(MAX_FILE_LEN) :: path_output = '' ! Path to output directory
|
||||
|
||||
|
|
@ -363,6 +365,10 @@ module global
|
|||
integer :: n_state_points = 0
|
||||
type(SetInt) :: statepoint_batch
|
||||
|
||||
! Information about source points to be written
|
||||
integer :: n_source_points = 0
|
||||
type(SetInt) :: sourcepoint_batch
|
||||
|
||||
! Various output options
|
||||
logical :: output_summary = .false.
|
||||
logical :: output_xs = .false.
|
||||
|
|
@ -450,7 +456,7 @@ contains
|
|||
!$omp parallel
|
||||
if (allocated(fission_bank)) deallocate(fission_bank)
|
||||
!$omp end parallel
|
||||
#ifdef OPENMP
|
||||
#ifdef _OPENMP
|
||||
if (allocated(master_fission_bank)) deallocate(master_fission_bank)
|
||||
#endif
|
||||
if (allocated(source_bank)) deallocate(source_bank)
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ contains
|
|||
|
||||
integer :: i, j, k, m
|
||||
integer :: n_x, n_y, n_z
|
||||
integer :: length(3)
|
||||
integer, allocatable :: lattice_universes(:,:,:)
|
||||
type(Cell), pointer :: c => null()
|
||||
type(Surface), pointer :: s => null()
|
||||
|
|
@ -312,8 +313,8 @@ contains
|
|||
end do
|
||||
end do
|
||||
end do
|
||||
call su % write_data(lattice_universes, "universes", &
|
||||
length=(/n_x, n_y, n_z/), &
|
||||
length = [n_x, n_y, n_z]
|
||||
call su % write_data(lattice_universes, "universes", length=length, &
|
||||
group="geometry/lattices/lattice " // trim(to_str(lat % id)))
|
||||
deallocate(lattice_universes)
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ module initialize
|
|||
use mpi
|
||||
#endif
|
||||
|
||||
#ifdef OPENMP
|
||||
#ifdef _OPENMP
|
||||
use omp_lib
|
||||
#endif
|
||||
|
||||
|
|
@ -363,8 +363,50 @@ contains
|
|||
case (FILETYPE_PARTICLE_RESTART)
|
||||
path_particle_restart = argv(i)
|
||||
particle_restart_run = .true.
|
||||
case default
|
||||
message = "Unrecognized file after restart flag."
|
||||
call fatal_error()
|
||||
end select
|
||||
|
||||
! If its a restart run check for additional source file
|
||||
if (restart_run .and. i + 1 <= argc) then
|
||||
|
||||
! Increment arg
|
||||
i = i + 1
|
||||
|
||||
! Check if it has extension we can read
|
||||
if ((ends_with(argv(i), '.binary') .or. &
|
||||
ends_with(argv(i), '.h5'))) then
|
||||
|
||||
! Check file type is a source file
|
||||
call sp % file_open(argv(i), 'r', serial = .false.)
|
||||
call sp % read_data(filetype, 'filetype')
|
||||
call sp % file_close()
|
||||
if (filetype /= FILETYPE_SOURCE) then
|
||||
message = "Second file after restart flag must be a source file"
|
||||
call fatal_error()
|
||||
end if
|
||||
|
||||
! It is a source file
|
||||
path_source_point = argv(i)
|
||||
|
||||
else ! Different option is specified not a source file
|
||||
|
||||
! Source is in statepoint file
|
||||
path_source_point = path_state_point
|
||||
|
||||
! Set argument back
|
||||
i = i - 1
|
||||
|
||||
end if
|
||||
|
||||
else ! No command line arg after statepoint
|
||||
|
||||
! Source is assumed to be in statepoint file
|
||||
path_source_point = path_state_point
|
||||
|
||||
end if
|
||||
|
||||
case ('-g', '-geometry-debug', '--geometry-debug')
|
||||
check_overlaps = .true.
|
||||
|
||||
|
|
@ -372,7 +414,7 @@ contains
|
|||
! Read number of threads
|
||||
i = i + 1
|
||||
|
||||
#ifdef OPENMP
|
||||
#ifdef _OPENMP
|
||||
! Read and set number of OpenMP threads
|
||||
n_threads = str_to_int(argv(i))
|
||||
if (n_threads < 1) then
|
||||
|
|
@ -830,14 +872,15 @@ contains
|
|||
call fatal_error()
|
||||
end if
|
||||
|
||||
#ifdef OPENMP
|
||||
#ifdef _OPENMP
|
||||
! If OpenMP is being used, each thread needs its own private fission
|
||||
! bank. Since the private fission banks need to be combined at the end of a
|
||||
! generation, there is also a 'master_fission_bank' that is used to collect
|
||||
! the sites from each thread.
|
||||
|
||||
n_threads = omp_get_max_threads()
|
||||
|
||||
!$omp parallel
|
||||
n_threads = omp_get_num_threads()
|
||||
thread_id = omp_get_thread_num()
|
||||
|
||||
if (thread_id == 0) then
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ contains
|
|||
|
||||
! Number of OpenMP threads
|
||||
if (check_for_node(doc, "threads")) then
|
||||
#ifdef OPENMP
|
||||
#ifdef _OPENMP
|
||||
if (n_threads == NONE) then
|
||||
call get_node_value(doc, "threads", n_threads)
|
||||
if (n_threads < 1) then
|
||||
|
|
@ -628,20 +628,6 @@ contains
|
|||
n_state_points = 1
|
||||
call statepoint_batch % add(n_batches)
|
||||
end if
|
||||
|
||||
! Check if the user has specified to write binary source file
|
||||
if (check_for_node(node_sp, "source_separate")) then
|
||||
call get_node_value(node_sp, "source_separate", temp_str)
|
||||
call lower_case(temp_str)
|
||||
if (trim(temp_str) == 'true' .or. &
|
||||
trim(temp_str) == '1') source_separate = .true.
|
||||
end if
|
||||
if (check_for_node(node_sp, "source_write")) then
|
||||
call get_node_value(node_sp, "source_write", temp_str)
|
||||
call lower_case(temp_str)
|
||||
if (trim(temp_str) == 'false' .or. &
|
||||
trim(temp_str) == '0') source_write = .false.
|
||||
end if
|
||||
else
|
||||
! If no <state_point> tag was present, by default write state point at
|
||||
! last batch only
|
||||
|
|
@ -649,6 +635,85 @@ contains
|
|||
call statepoint_batch % add(n_batches)
|
||||
end if
|
||||
|
||||
! Check if the user has specified to write source points
|
||||
if (check_for_node(doc, "source_point")) then
|
||||
|
||||
! Get pointer to source_point node
|
||||
call get_node_ptr(doc, "source_point", node_sp)
|
||||
|
||||
! Determine number of batches at which to store source points
|
||||
if (check_for_node(node_sp, "batches")) then
|
||||
n_source_points = get_arraysize_integer(node_sp, "batches")
|
||||
else
|
||||
n_source_points = 0
|
||||
end if
|
||||
|
||||
if (n_source_points > 0) then
|
||||
! User gave specific batches to write source points
|
||||
allocate(temp_int_array(n_source_points))
|
||||
call get_node_array(node_sp, "batches", temp_int_array)
|
||||
do i = 1, n_source_points
|
||||
call sourcepoint_batch % add(temp_int_array(i))
|
||||
end do
|
||||
deallocate(temp_int_array)
|
||||
elseif (check_for_node(node_sp, "interval")) then
|
||||
! User gave an interval for writing source points
|
||||
call get_node_value(node_sp, "interval", temp_int)
|
||||
n_source_points = n_batches / temp_int
|
||||
do i = 1, n_source_points
|
||||
call sourcepoint_batch % add(temp_int * i)
|
||||
end do
|
||||
else
|
||||
! If neither were specified, write source points with state points
|
||||
n_source_points = n_state_points
|
||||
do i = 1, n_state_points
|
||||
call sourcepoint_batch % add(statepoint_batch % get_item(i))
|
||||
end do
|
||||
end if
|
||||
|
||||
! Check if the user has specified to write binary source file
|
||||
if (check_for_node(node_sp, "separate")) then
|
||||
call get_node_value(node_sp, "separate", temp_str)
|
||||
call lower_case(temp_str)
|
||||
if (trim(temp_str) == 'true' .or. &
|
||||
trim(temp_str) == '1') source_separate = .true.
|
||||
end if
|
||||
if (check_for_node(node_sp, "write")) then
|
||||
call get_node_value(node_sp, "write", temp_str)
|
||||
call lower_case(temp_str)
|
||||
if (trim(temp_str) == 'false' .or. &
|
||||
trim(temp_str) == '0') source_write = .false.
|
||||
end if
|
||||
if (check_for_node(node_sp, "overwrite_latest")) then
|
||||
call get_node_value(node_sp, "overwrite_latest", temp_str)
|
||||
call lower_case(temp_str)
|
||||
if (trim(temp_str) == 'true' .or. &
|
||||
trim(temp_str) == '1') source_latest = .true.
|
||||
end if
|
||||
else
|
||||
! If no <source_point> tag was present, by default we keep source bank in
|
||||
! statepoint file and write it out at statepoints intervals
|
||||
source_separate = .false.
|
||||
n_source_points = n_state_points
|
||||
do i = 1, n_state_points
|
||||
call sourcepoint_batch % add(statepoint_batch % get_item(i))
|
||||
end do
|
||||
end if
|
||||
|
||||
! If source is not seperate and is to be written out in the statepoint file,
|
||||
! make sure that the sourcepoint batch numbers are contained in the
|
||||
! statepoint list
|
||||
if (.not. source_separate) then
|
||||
do i = 1, n_source_points
|
||||
if (.not. statepoint_batch % contains(sourcepoint_batch % &
|
||||
get_item(i))) then
|
||||
message = 'Sourcepoint batches are not a subset&
|
||||
& of statepoint batches.'
|
||||
call fatal_error()
|
||||
end if
|
||||
end do
|
||||
end if
|
||||
|
||||
! Check if the user has specified to not reduce tallies at the end of every
|
||||
! batch
|
||||
if (check_for_node(doc, "no_reduce")) then
|
||||
|
|
|
|||
|
|
@ -31,6 +31,10 @@ contains
|
|||
|
||||
subroutine title()
|
||||
|
||||
#ifdef _OPENMP
|
||||
use omp_lib
|
||||
#endif
|
||||
|
||||
write(UNIT=OUTPUT_UNIT, FMT='(/11(A/))') &
|
||||
' .d88888b. 888b d888 .d8888b.', &
|
||||
' d88P" "Y88b 8888b d8888 d88P Y88b', &
|
||||
|
|
@ -46,25 +50,31 @@ contains
|
|||
|
||||
! Write version information
|
||||
write(UNIT=OUTPUT_UNIT, FMT=*) &
|
||||
' Copyright: 2011-2013 Massachusetts Institute of Technology'
|
||||
' Copyright: 2011-2014 Massachusetts Institute of Technology'
|
||||
write(UNIT=OUTPUT_UNIT, FMT=*) &
|
||||
' License: http://mit-crpg.github.io/openmc/license.html'
|
||||
write(UNIT=OUTPUT_UNIT, FMT='(6X,"Version:",7X,I1,".",I1,".",I1)') &
|
||||
' License: http://mit-crpg.github.io/openmc/license.html'
|
||||
write(UNIT=OUTPUT_UNIT, FMT='(6X,"Version:",8X,I1,".",I1,".",I1)') &
|
||||
VERSION_MAJOR, VERSION_MINOR, VERSION_RELEASE
|
||||
#ifdef GIT_SHA1
|
||||
write(UNIT=OUTPUT_UNIT, FMT='(6X,"Git SHA1:",6X,A)') GIT_SHA1
|
||||
write(UNIT=OUTPUT_UNIT, FMT='(6X,"Git SHA1:",7X,A)') GIT_SHA1
|
||||
#endif
|
||||
|
||||
! Write the date and time
|
||||
write(UNIT=OUTPUT_UNIT, FMT='(6X,"Date/Time:",5X,A)') &
|
||||
write(UNIT=OUTPUT_UNIT, FMT='(6X,"Date/Time:",6X,A)') &
|
||||
time_stamp()
|
||||
|
||||
#ifdef MPI
|
||||
! Write number of processors
|
||||
write(UNIT=OUTPUT_UNIT, FMT='(6X,"MPI Processes:",1X,A)') &
|
||||
write(UNIT=OUTPUT_UNIT, FMT='(6X,"MPI Processes:",2X,A)') &
|
||||
trim(to_str(n_procs))
|
||||
#endif
|
||||
|
||||
#ifdef _OPENMP
|
||||
! Write number of OpenMP threads
|
||||
write(UNIT=OUTPUT_UNIT, FMT='(6X,"OpenMP Threads:",1X,A)') &
|
||||
trim(to_str(omp_get_max_threads()))
|
||||
#endif
|
||||
|
||||
end subroutine title
|
||||
|
||||
!===============================================================================
|
||||
|
|
|
|||
|
|
@ -5,8 +5,13 @@ module random_lcg
|
|||
private
|
||||
save
|
||||
|
||||
! Random number streams
|
||||
integer, parameter :: N_STREAMS = 2
|
||||
integer, parameter :: STREAM_TRACKING = 1
|
||||
integer, parameter :: STREAM_TALLIES = 2
|
||||
|
||||
integer(8) :: prn_seed0 ! original seed
|
||||
integer(8) :: prn_seed ! current seed
|
||||
integer(8) :: prn_seed(N_STREAMS) ! current seed
|
||||
integer(8) :: prn_mult ! multiplication factor, g
|
||||
integer(8) :: prn_add ! additive factor, c
|
||||
integer :: prn_bits ! number of bits, M
|
||||
|
|
@ -14,6 +19,7 @@ module random_lcg
|
|||
integer(8) :: prn_mask ! 2^M - 1
|
||||
integer(8) :: prn_stride ! stride between particles
|
||||
real(8) :: prn_norm ! 2^(-M)
|
||||
integer :: stream ! current RNG stream
|
||||
|
||||
!$omp threadprivate(prn_seed)
|
||||
|
||||
|
|
@ -21,6 +27,8 @@ module random_lcg
|
|||
public :: initialize_prng
|
||||
public :: set_particle_seed
|
||||
public :: prn_skip
|
||||
public :: prn_set_stream
|
||||
public :: STREAM_TRACKING, STREAM_TALLIES
|
||||
|
||||
contains
|
||||
|
||||
|
|
@ -35,12 +43,12 @@ contains
|
|||
! This algorithm uses bit-masking to find the next integer(8) value to be
|
||||
! used to calculate the random number
|
||||
|
||||
prn_seed = iand(prn_mult*prn_seed + prn_add, prn_mask)
|
||||
prn_seed(stream) = iand(prn_mult*prn_seed(stream) + prn_add, prn_mask)
|
||||
|
||||
! Once the integer is calculated, we just need to divide by 2**m,
|
||||
! represented here as multiplying by a pre-calculated factor
|
||||
|
||||
pseudo_rn = prn_seed * prn_norm
|
||||
pseudo_rn = prn_seed(stream) * prn_norm
|
||||
|
||||
end function prn
|
||||
|
||||
|
|
@ -53,8 +61,13 @@ contains
|
|||
|
||||
use global, only: seed
|
||||
|
||||
integer :: i
|
||||
|
||||
stream = STREAM_TRACKING
|
||||
prn_seed0 = seed
|
||||
prn_seed = prn_seed
|
||||
do i = 1, N_STREAMS
|
||||
prn_seed(i) = prn_seed0 + i - 1
|
||||
end do
|
||||
prn_mult = 2806196910506780709_8
|
||||
prn_add = 1_8
|
||||
prn_bits = 63
|
||||
|
|
@ -74,7 +87,11 @@ contains
|
|||
|
||||
integer(8), intent(in) :: id
|
||||
|
||||
prn_seed = prn_skip_ahead(id*prn_stride, prn_seed0)
|
||||
integer :: i
|
||||
|
||||
do i = 1, N_STREAMS
|
||||
prn_seed(i) = prn_skip_ahead(id*prn_stride, prn_seed0 + i - 1)
|
||||
end do
|
||||
|
||||
end subroutine set_particle_seed
|
||||
|
||||
|
|
@ -86,7 +103,7 @@ contains
|
|||
|
||||
integer(8), intent(in) :: n ! number of seeds to skip
|
||||
|
||||
prn_seed = prn_skip_ahead(n, prn_seed)
|
||||
prn_seed(stream) = prn_skip_ahead(n, prn_seed(stream))
|
||||
|
||||
end subroutine prn_skip
|
||||
|
||||
|
|
@ -151,4 +168,18 @@ contains
|
|||
|
||||
end function prn_skip_ahead
|
||||
|
||||
!===============================================================================
|
||||
! PRN_SET_STREAM changes the random number stream. If random numbers are needed
|
||||
! in routines not used directly for tracking (e.g. physics), this allows the
|
||||
! numbers to be generated without affecting reproducibility of the physics.
|
||||
!===============================================================================
|
||||
|
||||
subroutine prn_set_stream(i)
|
||||
|
||||
integer, intent(in) :: i
|
||||
|
||||
stream = i
|
||||
|
||||
end subroutine prn_set_stream
|
||||
|
||||
end module random_lcg
|
||||
|
|
|
|||
|
|
@ -92,11 +92,22 @@ element settings {
|
|||
attribute batches { list { xsd:positiveInteger+ } }) |
|
||||
(element interval { xsd:positiveInteger } |
|
||||
attribute interval { xsd:positiveInteger })
|
||||
) &
|
||||
(element source_separate { xsd:boolean } |
|
||||
attribute source_separate { xsd:boolean })? &
|
||||
(element source_write { xsd:boolean } |
|
||||
attribute source_write { xsd:boolean })?
|
||||
)
|
||||
}? &
|
||||
|
||||
element source_point {
|
||||
(
|
||||
(element batches { list { xsd:positiveInteger+ } } |
|
||||
attribute batches { list { xsd:positiveInteger+ } }) |
|
||||
(element interval { xsd:positiveInteger } |
|
||||
attribute interval { xsd:positiveInteger })
|
||||
)? &
|
||||
(element separate { xsd:boolean } |
|
||||
attribute separate { xsd:boolean })? &
|
||||
(element write { xsd:boolean } |
|
||||
attribute write { xsd:boolean })? &
|
||||
(element overwrite_latest { xsd:boolean} |
|
||||
attribute overwrite_latest {xsd:boolean})?
|
||||
}? &
|
||||
|
||||
element survival_biasing { xsd:boolean }? &
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
module source
|
||||
|
||||
use bank_header, only: Bank
|
||||
use bank_header, only: Bank
|
||||
use constants
|
||||
use error, only: fatal_error
|
||||
use geometry, only: find_cell
|
||||
use geometry_header, only: BASE_UNIVERSE
|
||||
use error, only: fatal_error
|
||||
use geometry, only: find_cell
|
||||
use geometry_header, only: BASE_UNIVERSE
|
||||
use global
|
||||
use math, only: maxwell_spectrum, watt_spectrum
|
||||
use output, only: write_message
|
||||
use particle_header, only: Particle
|
||||
use random_lcg, only: prn, set_particle_seed
|
||||
use string, only: to_str
|
||||
use math, only: maxwell_spectrum, watt_spectrum
|
||||
use output, only: write_message
|
||||
use output_interface, only: BinaryOutput
|
||||
use particle_header, only: Particle
|
||||
use random_lcg, only: prn, set_particle_seed
|
||||
use string, only: to_str
|
||||
|
||||
#ifdef MPI
|
||||
use mpi
|
||||
|
|
@ -28,8 +29,9 @@ contains
|
|||
|
||||
integer(8) :: i ! loop index over bank sites
|
||||
integer(8) :: id ! particle id
|
||||
|
||||
integer(4) :: itmp ! temporary integer
|
||||
type(Bank), pointer :: src => null() ! source bank site
|
||||
type(BinaryOutput) :: sp ! statepoint/source binary file
|
||||
|
||||
message = "Initializing source particles..."
|
||||
call write_message(6)
|
||||
|
|
@ -38,8 +40,26 @@ contains
|
|||
! Read the source from a binary file instead of sampling from some
|
||||
! assumed source distribution
|
||||
|
||||
message = 'This feature is currently disabled and will be added back in.'
|
||||
call fatal_error()
|
||||
message = 'Reading source file from ' // trim(path_source) // '...'
|
||||
call write_message(6)
|
||||
|
||||
! Open the binary file
|
||||
call sp % file_open(path_source, 'r', serial = .false.)
|
||||
|
||||
! Read the file type
|
||||
call sp % read_data(itmp, "filetype")
|
||||
|
||||
! Check to make sure this is a source file
|
||||
if (itmp /= FILETYPE_SOURCE) then
|
||||
message = "Specified starting source file not a source file type."
|
||||
call fatal_error()
|
||||
end if
|
||||
|
||||
! Read in the source bank
|
||||
call sp % read_source_bank()
|
||||
|
||||
! Close file
|
||||
call sp % file_close()
|
||||
|
||||
else
|
||||
! Generation source sites from specified distribution in user input
|
||||
|
|
|
|||
|
|
@ -232,6 +232,13 @@ contains
|
|||
|
||||
end if
|
||||
|
||||
! Indicate where source bank is stored in statepoint
|
||||
if (source_separate) then
|
||||
call sp % write_data(0, "source_present")
|
||||
else
|
||||
call sp % write_data(1, "source_present")
|
||||
end if
|
||||
|
||||
! Check for the no-tally-reduction method
|
||||
if (.not. reduce_tallies) then
|
||||
! If using the no-tally-reduction method, we need to collect tally
|
||||
|
|
@ -280,14 +287,45 @@ contains
|
|||
|
||||
end if
|
||||
|
||||
! Check for eigenvalue calculation
|
||||
if (run_mode == MODE_EIGENVALUE .and. source_write) then
|
||||
end subroutine write_state_point
|
||||
|
||||
! Check for writing source out separately
|
||||
!===============================================================================
|
||||
! WRITE_SOURCE_POINT
|
||||
!===============================================================================
|
||||
|
||||
subroutine write_source_point()
|
||||
|
||||
type(BinaryOutput) :: sp
|
||||
character(MAX_FILE_LEN) :: filename
|
||||
|
||||
! Check to write out source for a specified batch
|
||||
if (sourcepoint_batch % contains(current_batch)) then
|
||||
|
||||
! Create or open up file
|
||||
if (source_separate) then
|
||||
|
||||
! Set filename for source
|
||||
filename = trim(path_output) // 'source.' // &
|
||||
! Set filename
|
||||
filename = trim(path_output) // 'source.' // trim(to_str(current_batch))
|
||||
#ifdef HDF5
|
||||
filename = trim(filename) // '.h5'
|
||||
#else
|
||||
filename = trim(filename) // '.binary'
|
||||
#endif
|
||||
|
||||
! Write message for new file creation
|
||||
message = "Creating source file " // trim(filename) // "..."
|
||||
call write_message(1)
|
||||
|
||||
! Create separate source file
|
||||
call sp % file_create(filename, serial = .false.)
|
||||
|
||||
! Write file type
|
||||
call sp % write_data(FILETYPE_SOURCE, "filetype")
|
||||
|
||||
else
|
||||
|
||||
! Set filename for state point
|
||||
filename = trim(path_output) // 'statepoint.' // &
|
||||
trim(to_str(current_batch))
|
||||
#ifdef HDF5
|
||||
filename = trim(filename) // '.h5'
|
||||
|
|
@ -295,16 +333,7 @@ contains
|
|||
filename = trim(filename) // '.binary'
|
||||
#endif
|
||||
|
||||
! Write message
|
||||
message = "Creating source file " // trim(filename) // "..."
|
||||
call write_message(1)
|
||||
|
||||
! Create source file
|
||||
call sp % file_create(filename, serial = .false.)
|
||||
|
||||
else
|
||||
|
||||
! Reopen state point file in parallel
|
||||
! Reopen statepoint file in parallel
|
||||
call sp % file_open(filename, 'w', serial = .false.)
|
||||
|
||||
end if
|
||||
|
|
@ -317,7 +346,36 @@ contains
|
|||
|
||||
end if
|
||||
|
||||
end subroutine write_state_point
|
||||
! Also check to write source separately in overwritten file
|
||||
if (source_latest) then
|
||||
|
||||
! Set filename
|
||||
filename = trim(path_output) // 'source'
|
||||
#ifdef HDF5
|
||||
filename = trim(filename) // '.h5'
|
||||
#else
|
||||
filename = trim(filename) // '.binary'
|
||||
#endif
|
||||
|
||||
! Write message for new file creation
|
||||
message = "Creating source file " // trim(filename) // "..."
|
||||
call write_message(1)
|
||||
|
||||
! Always create this file because it will be overwritten
|
||||
call sp % file_create(filename, serial = .false.)
|
||||
|
||||
! Write file type
|
||||
call sp % write_data(FILETYPE_SOURCE, "filetype")
|
||||
|
||||
! Write out source
|
||||
call sp % write_source_bank()
|
||||
|
||||
! Close file
|
||||
call sp % file_close()
|
||||
|
||||
end if
|
||||
|
||||
end subroutine write_source_point
|
||||
|
||||
!===============================================================================
|
||||
! WRITE_TALLY_RESULTS_NR
|
||||
|
|
@ -464,8 +522,10 @@ contains
|
|||
character(19) :: current_time
|
||||
integer :: i
|
||||
integer :: j
|
||||
integer :: length(4)
|
||||
integer :: int_array(3)
|
||||
integer, allocatable :: temp_array(:)
|
||||
logical :: source_present
|
||||
real(8) :: real_array(3)
|
||||
type(TallyObject), pointer :: t => null()
|
||||
|
||||
|
|
@ -542,10 +602,9 @@ contains
|
|||
call sp % read_data(cmfd % indices, "indicies", length=4, group="cmfd")
|
||||
call sp % read_data(cmfd % k_cmfd, "k_cmfd", length=restart_batch, &
|
||||
group="cmfd")
|
||||
length = cmfd % indices([4,1,2,3])
|
||||
call sp % read_data(cmfd % cmfd_src, "cmfd_src", &
|
||||
length=(/cmfd % indices(4), cmfd % indices(1), &
|
||||
cmfd % indices(2), cmfd % indices(3)/), &
|
||||
group="cmfd")
|
||||
length=length, group="cmfd")
|
||||
call sp % read_data(cmfd % entropy, "cmfd_entropy", &
|
||||
length=restart_batch, group="cmfd")
|
||||
call sp % read_data(cmfd % balance, "cmfd_balance", &
|
||||
|
|
@ -671,6 +730,20 @@ contains
|
|||
|
||||
end do TALLY_METADATA
|
||||
|
||||
! Check for source in statepoint if needed
|
||||
call sp % read_data(int_array(1), "source_present")
|
||||
if (int_array(1) == 1) then
|
||||
source_present = .true.
|
||||
else
|
||||
source_present = .false.
|
||||
end if
|
||||
|
||||
! Check to make sure source bank is present
|
||||
if (path_source_point == path_state_point .and. .not. source_present) then
|
||||
message = "Source bank must be contained in statepoint restart file"
|
||||
call fatal_error()
|
||||
end if
|
||||
|
||||
! Read tallies to master
|
||||
if (master) then
|
||||
|
||||
|
|
@ -711,26 +784,20 @@ contains
|
|||
if (run_mode == MODE_EIGENVALUE) then
|
||||
|
||||
! Check if source was written out separately
|
||||
if (source_separate) then
|
||||
if (.not. source_present) then
|
||||
|
||||
! Close statepoint file
|
||||
call sp % file_close()
|
||||
|
||||
! Set filename for source
|
||||
filename = trim(path_output) // 'source.' // &
|
||||
trim(to_str(restart_batch))
|
||||
#ifdef HDF5
|
||||
filename = trim(filename) // '.h5'
|
||||
#else
|
||||
filename = trim(filename) // '.binary'
|
||||
#endif
|
||||
|
||||
! Write message
|
||||
message = "Loading source file " // trim(filename) // "..."
|
||||
call write_message(1)
|
||||
|
||||
! Open source file
|
||||
call sp % file_open(filename, 'r', serial = .false.)
|
||||
call sp % file_open(path_source_point, 'r', serial = .false.)
|
||||
|
||||
! Read file type
|
||||
call sp % read_data(int_array(1), "filetype")
|
||||
|
||||
end if
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ contains
|
|||
subroutine finalize_particle_track(p)
|
||||
type(Particle), intent(in) :: p
|
||||
|
||||
integer :: length(2)
|
||||
character(MAX_FILE_LEN) :: fname
|
||||
type(BinaryOutput) :: binout
|
||||
|
||||
|
|
@ -69,7 +70,8 @@ contains
|
|||
// '.binary'
|
||||
#endif
|
||||
call binout % file_create(fname)
|
||||
call binout % write_data(coords, 'coordinates', length=(/3, n_tracks/))
|
||||
length = [3, n_tracks]
|
||||
call binout % write_data(coords, 'coordinates', length=length)
|
||||
call binout % file_close()
|
||||
deallocate(coords)
|
||||
end subroutine finalize_particle_track
|
||||
|
|
|
|||
|
|
@ -35,8 +35,12 @@ class Xsdir(object):
|
|||
words = line.split()
|
||||
if words:
|
||||
if words[0].lower().startswith('datapath'):
|
||||
index = line.index('=')
|
||||
self.datapath = line[index+1:].strip()
|
||||
if '=' in words[0]:
|
||||
index = line.index('=')
|
||||
self.datapath = line[index+1:].strip()
|
||||
else:
|
||||
if len(line.strip()) > 8:
|
||||
self.datapath = line[8:].strip()
|
||||
else:
|
||||
self.f.seek(0)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,262 +1,279 @@
|
|||
#!/usr/bin/env python2
|
||||
|
||||
'''Python script to plot tally data generated by OpenMC.'''
|
||||
"""Python script to plot tally data generated by OpenMC."""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from statepoint import *
|
||||
|
||||
# Color intensity dependent on individual score?
|
||||
|
||||
from PyQt4.QtCore import *
|
||||
from PyQt4.QtGui import *
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
|
||||
from matplotlib.backends.backend_tkagg import NavigationToolbar2TkAgg
|
||||
from matplotlib.figure import Figure
|
||||
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
|
||||
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
class AppForm(QMainWindow):
|
||||
def __init__(self, parent=None):
|
||||
QMainWindow.__init__(self, parent)
|
||||
from statepoint import *
|
||||
|
||||
if sys.version_info[0] < 3:
|
||||
import Tkinter as tk
|
||||
else:
|
||||
import tkinter as tk
|
||||
import tkFileDialog
|
||||
import tkFont
|
||||
import tkMessageBox
|
||||
import ttk
|
||||
|
||||
|
||||
class MeshPlotter(tk.Frame):
|
||||
def __init__(self, parent, filename):
|
||||
tk.Frame.__init__(self, parent)
|
||||
|
||||
self.labels = {'cell': 'Cell:', 'cellborn': 'Cell born:',
|
||||
'surface': 'Surface:', 'material': 'Material:',
|
||||
'universe': 'Universe:', 'energyin': 'Energy in:',
|
||||
'energyout': 'Energy out:'}
|
||||
|
||||
self.filterBoxes = {}
|
||||
|
||||
# Read data from source or leakage fraction file
|
||||
self.get_file_data()
|
||||
self.main_frame = QWidget()
|
||||
self.setCentralWidget(self.main_frame)
|
||||
|
||||
# Create the Figure, Canvas, and Axes
|
||||
self.get_file_data(filename)
|
||||
|
||||
# Set up top-level window
|
||||
top = self.winfo_toplevel()
|
||||
top.title('Mesh Tally Plotter: ' + filename)
|
||||
top.rowconfigure(0, weight=1)
|
||||
top.columnconfigure(0, weight=1)
|
||||
self.grid(sticky=tk.W+tk.N)
|
||||
|
||||
# Create widgets and draw to screen
|
||||
self.create_widgets()
|
||||
self.update()
|
||||
|
||||
def create_widgets(self):
|
||||
figureFrame = tk.Frame(self)
|
||||
figureFrame.grid(row=0, column=0)
|
||||
|
||||
# Create the Figure and Canvas
|
||||
self.dpi = 100
|
||||
self.fig = Figure((5.0, 15.0), dpi=self.dpi)
|
||||
self.canvas = FigureCanvas(self.fig)
|
||||
self.canvas.setParent(self.main_frame)
|
||||
self.axes = self.fig.add_subplot(111)
|
||||
|
||||
self.fig = Figure((5.0, 5.0), dpi=self.dpi)
|
||||
self.canvas = FigureCanvasTkAgg(self.fig, master=figureFrame)
|
||||
self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
|
||||
|
||||
# Create the navigation toolbar, tied to the canvas
|
||||
self.mpl_toolbar = NavigationToolbar(self.canvas, self.main_frame)
|
||||
self.mpl_toolbar = NavigationToolbar2TkAgg(self.canvas, figureFrame)
|
||||
self.mpl_toolbar.update()
|
||||
self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
|
||||
|
||||
# Grid layout at bottom
|
||||
self.grid = QGridLayout()
|
||||
# Create frame for comboboxes
|
||||
self.selectFrame = tk.Frame(self)
|
||||
self.selectFrame.grid(row=1, column=0, sticky=tk.W+tk.E)
|
||||
|
||||
# Overall layout
|
||||
self.vbox = QVBoxLayout()
|
||||
self.vbox.addWidget(self.canvas)
|
||||
self.vbox.addWidget(self.mpl_toolbar)
|
||||
self.vbox.addLayout(self.grid)
|
||||
self.main_frame.setLayout(self.vbox)
|
||||
# Tally selection
|
||||
labelTally = tk.Label(self.selectFrame, text='Tally:')
|
||||
labelTally.grid(row=0, column=0, sticky=tk.W)
|
||||
self.tallyBox = ttk.Combobox(self.selectFrame, state='readonly')
|
||||
self.tallyBox['values'] = [self.datafile.tallies[i].id
|
||||
for i in self.meshTallies]
|
||||
self.tallyBox.current(0)
|
||||
self.tallyBox.grid(row=0, column=1, sticky=tk.W+tk.E)
|
||||
self.tallyBox.bind('<<ComboboxSelected>>', self.update)
|
||||
|
||||
# Tally selections
|
||||
label_tally = QLabel("Tally:")
|
||||
self.tally = QComboBox()
|
||||
self.tally.addItems([(str(i + 1)) for i in range(self.n_tallies)])
|
||||
self.connect(self.tally, SIGNAL('activated(int)'),
|
||||
self._update)
|
||||
self.connect(self.tally, SIGNAL('activated(int)'),
|
||||
self.populate_boxes)
|
||||
self.connect(self.tally, SIGNAL('activated(int)'),
|
||||
self.on_draw)
|
||||
# Planar basis selection
|
||||
labelBasis = tk.Label(self.selectFrame, text='Basis:')
|
||||
labelBasis.grid(row=1, column=0, sticky=tk.W)
|
||||
self.basisBox = ttk.Combobox(self.selectFrame, state='readonly')
|
||||
self.basisBox['values'] = ('xy', 'yz', 'xz')
|
||||
self.basisBox.current(0)
|
||||
self.basisBox.grid(row=1, column=1, sticky=tk.W+tk.E)
|
||||
self.basisBox.bind('<<ComboboxSelected>>', self.update)
|
||||
|
||||
# Planar basis
|
||||
label_basis = QLabel("Basis:")
|
||||
self.basis = QComboBox()
|
||||
self.basis.addItems(['xy', 'yz', 'xz'])
|
||||
# Axial level
|
||||
labelAxial = tk.Label(self.selectFrame, text='Axial level:')
|
||||
labelAxial.grid(row=2, column=0, sticky=tk.W)
|
||||
self.axialBox = ttk.Combobox(self.selectFrame, state='readonly')
|
||||
self.axialBox.grid(row=2, column=1, sticky=tk.W+tk.E)
|
||||
self.axialBox.bind('<<ComboboxSelected>>', self.redraw)
|
||||
|
||||
# Update window when 'Basis' selection is changed
|
||||
self.connect(self.basis, SIGNAL('activated(int)'),
|
||||
self._update)
|
||||
self.connect(self.basis, SIGNAL('activated(int)'),
|
||||
self.populate_boxes)
|
||||
self.connect(self.basis, SIGNAL('activated(int)'),
|
||||
self.on_draw)
|
||||
# Option for mean/uncertainty
|
||||
labelMean = tk.Label(self.selectFrame, text='Mean/Uncertainty:')
|
||||
labelMean.grid(row=3, column=0, sticky=tk.W)
|
||||
self.meanBox = ttk.Combobox(self.selectFrame, state='readonly')
|
||||
self.meanBox['values'] = ('Mean', 'Absolute uncertainty',
|
||||
'Relative uncertainty')
|
||||
self.meanBox.current(0)
|
||||
self.meanBox.grid(row=3, column=1, sticky=tk.W+tk.E)
|
||||
self.meanBox.bind('<<ComboboxSelected>>', self.update)
|
||||
|
||||
# Axial level within selected basis
|
||||
label_axial_level = QLabel("Axial Level:")
|
||||
self.axial_level = QComboBox()
|
||||
self.connect(self.axial_level, SIGNAL('activated(int)'),
|
||||
self.on_draw)
|
||||
|
||||
# Add Option to plot mean or uncertainty
|
||||
label_mean = QLabel("Mean or Uncertainty:")
|
||||
self.mean = QComboBox()
|
||||
self.mean.addItems(['Mean','Absolute Uncertainty',
|
||||
'Relative Uncertainty'])
|
||||
|
||||
# Update window when mean selection is changed
|
||||
self.connect(self.mean, SIGNAL('activated(int)'),
|
||||
self.on_draw)
|
||||
|
||||
# Scores
|
||||
labelScore = tk.Label(self.selectFrame, text='Score:')
|
||||
labelScore.grid(row=4, column=0, sticky=tk.W)
|
||||
self.scoreBox = ttk.Combobox(self.selectFrame, state='readonly')
|
||||
self.scoreBox.grid(row=4, column=1, sticky=tk.W+tk.E)
|
||||
self.scoreBox.bind('<<ComboboxSelected>>', self.redraw)
|
||||
|
||||
self.label_filters = QLabel("Filter options:")
|
||||
# Filter label
|
||||
font = tkFont.Font(weight='bold')
|
||||
labelFilters = tk.Label(self.selectFrame, text='Filters:', font=font)
|
||||
labelFilters.grid(row=5, column=0, sticky=tk.W)
|
||||
|
||||
# Labels for all possible filters
|
||||
self.labels = {'cell': 'Cell: ', 'cellborn': 'Cell born: ',
|
||||
'surface': 'Surface: ', 'material': 'Material',
|
||||
'universe': 'Universe: ', 'energyin': 'Energy in: ',
|
||||
'energyout': 'Energy out: '}
|
||||
def update(self, event=None):
|
||||
if not event:
|
||||
widget = None
|
||||
else:
|
||||
widget = event.widget
|
||||
|
||||
# Empty reusable labels
|
||||
self.qlabels = {}
|
||||
for j in range(8):
|
||||
self.nextLabel = QLabel
|
||||
self.qlabels[j] = self.nextLabel
|
||||
tally_id = self.meshTallies[self.tallyBox.current()]
|
||||
selectedTally = self.datafile.tallies[tally_id]
|
||||
|
||||
# Reusable comboboxes labelled with filter names
|
||||
self.boxes = {}
|
||||
for key in self.labels.keys():
|
||||
self.nextBox = QComboBox()
|
||||
self.connect(self.nextBox, SIGNAL('activated(int)'),
|
||||
self.on_draw)
|
||||
self.boxes[key] = self.nextBox
|
||||
# Get mesh for selected tally
|
||||
self.mesh = self.datafile.meshes[
|
||||
selectedTally.filters['mesh'].bins[0] - 1]
|
||||
|
||||
# Combobox to select among scores
|
||||
self.score_label = QLabel("Score:")
|
||||
self.scoreBox = QComboBox()
|
||||
for item in self.tally_scores[0]:
|
||||
self.scoreBox.addItems(str(item))
|
||||
self.connect(self.scoreBox, SIGNAL('activated(int)'),
|
||||
self.on_draw)
|
||||
# Get mesh dimensions
|
||||
self.nx, self.ny, self.nz = self.mesh.dimension
|
||||
|
||||
# Fill layout
|
||||
self.grid.addWidget(label_tally, 0, 0)
|
||||
self.grid.addWidget(self.tally, 0, 1)
|
||||
self.grid.addWidget(label_basis, 1, 0)
|
||||
self.grid.addWidget(self.basis, 1, 1)
|
||||
self.grid.addWidget(label_axial_level, 2, 0)
|
||||
self.grid.addWidget(self.axial_level, 2, 1)
|
||||
self.grid.addWidget(label_mean, 3, 0)
|
||||
self.grid.addWidget(self.mean, 3, 1)
|
||||
self.grid.addWidget(self.label_filters, 4, 0)
|
||||
# Repopulate comboboxes baesd on current basis selection
|
||||
text = self.basisBox['values'][self.basisBox.current()]
|
||||
if text == 'xy':
|
||||
self.axialBox['values'] = [str(i+1) for i in range(self.nz)]
|
||||
elif text == 'yz':
|
||||
self.axialBox['values'] = [str(i+1) for i in range(self.nx)]
|
||||
else:
|
||||
self.axialBox['values'] = [str(i+1) for i in range(self.ny)]
|
||||
self.axialBox.current(0)
|
||||
|
||||
self._update()
|
||||
self.populate_boxes()
|
||||
self.on_draw()
|
||||
# If update() was called by a change in the basis combobox, we don't
|
||||
# need to repopulate the filters
|
||||
if widget == self.basisBox:
|
||||
self.redraw()
|
||||
return
|
||||
|
||||
def get_file_data(self):
|
||||
# Get data file name from "open file" browser
|
||||
filename = QFileDialog.getOpenFileName(self, 'Select statepoint file', '.')
|
||||
# Update scores
|
||||
self.scoreBox['values'] = selectedTally.scores
|
||||
self.scoreBox.current(0)
|
||||
|
||||
# Create StatePoint object and read in data
|
||||
self.datafile = StatePoint(str(filename))
|
||||
self.datafile.read_results()
|
||||
self.datafile.generate_stdev()
|
||||
# Remove any filter labels/comboboxes that exist
|
||||
for row in range(6, self.selectFrame.grid_size()[1]):
|
||||
for w in self.selectFrame.grid_slaves(row=row):
|
||||
w.grid_forget()
|
||||
w.destroy()
|
||||
|
||||
self.setWindowTitle('Core Map Tool : ' + str(self.datafile.path))
|
||||
# create a label/combobox for each filter in selected tally
|
||||
count = 0
|
||||
for filterType in selectedTally.filters:
|
||||
if filterType == 'mesh':
|
||||
continue
|
||||
count += 1
|
||||
|
||||
# Set maximum colorbar value by maximum tally data value
|
||||
self.maxvalue = self.datafile.tallies[0].results.max()
|
||||
# Create label and combobox for this filter
|
||||
label = tk.Label(self.selectFrame, text=self.labels[filterType])
|
||||
label.grid(row=count+6, column=0, sticky=tk.W)
|
||||
combobox = ttk.Combobox(self.selectFrame, state='readonly')
|
||||
self.filterBoxes[filterType] = combobox
|
||||
|
||||
self.labelList = []
|
||||
# Set combobox items
|
||||
f = selectedTally.filters[filterType]
|
||||
if filterType in ['energyin', 'energyout']:
|
||||
combobox['values'] = ['{0} to {1}'.format(*f.bins[i:i+2])
|
||||
for i in range(f.length)]
|
||||
else:
|
||||
combobox['values'] = [str(i) for i in f.bins]
|
||||
|
||||
# Read mesh dimensions
|
||||
# for mesh in self.datafile.meshes:
|
||||
# self.nx, self.ny, self.nz = mesh.dimension
|
||||
combobox.current(0)
|
||||
combobox.grid(row=count+6, column=1, sticky=tk.W+tk.E)
|
||||
combobox.bind('<<ComboboxSelected>>', self.redraw)
|
||||
|
||||
# Read filter types from statepoint file
|
||||
self.n_tallies = len(self.datafile.tallies)
|
||||
self.tally_list = []
|
||||
for tally in self.datafile.tallies:
|
||||
self.filter_types = []
|
||||
for f in tally.filters:
|
||||
self.filter_types.append(f)
|
||||
self.tally_list.append(self.filter_types)
|
||||
# If There are no filters, leave a 'None available' message
|
||||
if count == 0:
|
||||
count += 1
|
||||
label = tk.Label(self.selectFrame, text="None Available")
|
||||
label.grid(row=count+6, column=0, sticky=tk.W)
|
||||
|
||||
# Read score types from statepoint file
|
||||
self.tally_scores = []
|
||||
for tally in self.datafile.tallies:
|
||||
self.score_types = []
|
||||
for s in tally.scores:
|
||||
self.score_types.append(s)
|
||||
self.tally_scores.append(self.score_types)
|
||||
# print 'self.tally_scores = ', self.tally_scores
|
||||
self.redraw()
|
||||
|
||||
def on_draw(self):
|
||||
""" Redraws the figure
|
||||
"""
|
||||
def redraw(self, event=None):
|
||||
basis = self.basisBox.current() + 1
|
||||
axial_level = self.axialBox.current() + 1
|
||||
is_mean = self.meanBox.current()
|
||||
|
||||
# print 'Calling on_draw...'
|
||||
# Get selected basis, axial_level and stage
|
||||
basis = self.basis.currentIndex() + 1
|
||||
axial_level = self.axial_level.currentIndex() + 1
|
||||
is_mean = self.mean.currentIndex()
|
||||
# Get selected tally
|
||||
tally_id = self.meshTallies[self.tallyBox.current()]
|
||||
selectedTally = self.datafile.tallies[tally_id]
|
||||
|
||||
# Create spec_list
|
||||
spec_list = []
|
||||
for tally in self.datafile.tallies[self.tally.currentIndex()].filters.values():
|
||||
if tally.type == 'mesh':
|
||||
for f in selectedTally.filters.values():
|
||||
if f.type == 'mesh':
|
||||
continue
|
||||
index = self.boxes[tally.type].currentIndex()
|
||||
spec_list.append((tally.type, index))
|
||||
|
||||
index = self.filterBoxes[f.type].current()
|
||||
spec_list.append((f.type, index))
|
||||
|
||||
# Take is_mean and convert it to an index of the score
|
||||
score_loc = is_mean
|
||||
if score_loc > 1:
|
||||
score_loc = 1
|
||||
|
||||
if self.basis.currentText() == 'xy':
|
||||
|
||||
text = self.basisBox['values'][self.basisBox.current()]
|
||||
if text == 'xy':
|
||||
matrix = np.zeros((self.nx, self.ny))
|
||||
for i in range(self.nx):
|
||||
for j in range(self.ny):
|
||||
matrix[i,j] = self.datafile.get_value(self.tally.currentIndex(),
|
||||
spec_list + [('mesh', (i, j, axial_level))],
|
||||
self.scoreBox.currentIndex())[score_loc]
|
||||
# Calculate relative uncertainty from absolute, if
|
||||
# requested
|
||||
matrix[i, j] = self.datafile.get_value(tally_id,
|
||||
spec_list + [('mesh', (i + 1, j + 1, axial_level))],
|
||||
self.scoreBox.current())[score_loc]
|
||||
# Calculate relative uncertainty from absolute, if requested
|
||||
if is_mean == 2:
|
||||
# Take care to handle zero means when normalizing
|
||||
mean_val = self.datafile.get_value(self.tally.currentIndex(),
|
||||
spec_list + [('mesh', (i, j, axial_level))],
|
||||
self.scoreBox.currentIndex())[0]
|
||||
mean_val = self.datafile.get_value(tally_id,
|
||||
spec_list + [('mesh', (i + 1, j + 1, axial_level))],
|
||||
self.scoreBox.current())[0]
|
||||
if mean_val > 0.0:
|
||||
matrix[i,j] = matrix[i,j] / mean_val
|
||||
matrix[i, j] = matrix[i, j] / mean_val
|
||||
else:
|
||||
matrix[i,j] = 0.0
|
||||
|
||||
elif self.basis.currentText() == 'yz':
|
||||
matrix[i, j] = 0.0
|
||||
|
||||
elif text == 'yz':
|
||||
matrix = np.zeros((self.ny, self.nz))
|
||||
for i in range(self.ny):
|
||||
for j in range(self.nz):
|
||||
matrix[i,j] = self.datafile.get_value(self.tally.currentIndex(),
|
||||
spec_list + [('mesh', (axial_level, i, j))],
|
||||
self.scoreBox.currentIndex())[score_loc]
|
||||
# Calculate relative uncertainty from absolute, if
|
||||
# requested
|
||||
matrix[i, j] = self.datafile.get_value(tally_id,
|
||||
spec_list + [('mesh', (axial_level, i + 1, j + 1))],
|
||||
self.scoreBox.current())[score_loc]
|
||||
# Calculate relative uncertainty from absolute, if requested
|
||||
if is_mean == 2:
|
||||
# Take care to handle zero means when normalizing
|
||||
mean_val = self.datafile.get_value(self.tally.currentIndex(),
|
||||
spec_list + [('mesh', (axial_level, i, j))],
|
||||
self.scoreBox.currentIndex())[0]
|
||||
mean_val = self.datafile.get_value(tally_id,
|
||||
spec_list + [('mesh', (axial_level, i + 1, j + 1))],
|
||||
self.scoreBox.current())[0]
|
||||
if mean_val > 0.0:
|
||||
matrix[i,j] = matrix[i,j] / mean_val
|
||||
matrix[i, j] = matrix[i, j] / mean_val
|
||||
else:
|
||||
matrix[i,j] = 0.0
|
||||
|
||||
matrix[i, j] = 0.0
|
||||
|
||||
else:
|
||||
matrix = np.zeros((self.nx, self.nz))
|
||||
for i in range(self.nx):
|
||||
for j in range(self.nz):
|
||||
matrix[i,j] = self.datafile.get_value(self.tally.currentIndex(),
|
||||
spec_list + [('mesh', (i, axial_level, j))],
|
||||
self.scoreBox.currentIndex())[score_loc]
|
||||
# Calculate relative uncertainty from absolute, if
|
||||
# requested
|
||||
matrix[i, j] = self.datafile.get_value(tally_id,
|
||||
spec_list + [('mesh', (i + 1, axial_level, j + 1))],
|
||||
self.scoreBox.current())[score_loc]
|
||||
# Calculate relative uncertainty from absolute, if requested
|
||||
if is_mean == 2:
|
||||
# Take care to handle zero means when normalizing
|
||||
mean_val = self.datafile.get_value(self.tally.currentIndex(),
|
||||
spec_list + [('mesh', (i, axial_level, j))],
|
||||
self.scoreBox.currentIndex())[0]
|
||||
mean_val = self.datafile.get_value(tally_id,
|
||||
spec_list + [('mesh', (i + 1, axial_level, j + 1))],
|
||||
self.scoreBox.current())[0]
|
||||
if mean_val > 0.0:
|
||||
matrix[i,j] = matrix[i,j] / mean_val
|
||||
matrix[i, j] = matrix[i, j] / mean_val
|
||||
else:
|
||||
matrix[i,j] = 0.0
|
||||
|
||||
# print spec_list
|
||||
matrix[i, j] = 0.0
|
||||
|
||||
# Clear the figure
|
||||
self.fig.clear()
|
||||
|
||||
# Make figure, set up color bar
|
||||
self.axes = self.fig.add_subplot(111)
|
||||
cax = self.axes.imshow(matrix, vmin=0.0, vmax=matrix.max(),
|
||||
interpolation="nearest")
|
||||
cax = self.axes.imshow(matrix.transpose(), vmin=0.0, vmax=matrix.max(),
|
||||
interpolation='none', origin='lower')
|
||||
self.fig.colorbar(cax)
|
||||
|
||||
self.axes.set_xticks([])
|
||||
|
|
@ -266,95 +283,43 @@ class AppForm(QMainWindow):
|
|||
# Draw canvas
|
||||
self.canvas.draw()
|
||||
|
||||
def _update(self):
|
||||
'''Updates widget to display new relevant comboboxes and figure data
|
||||
'''
|
||||
# print 'Calling _update...'
|
||||
def get_file_data(self, filename):
|
||||
# Create StatePoint object and read in data
|
||||
self.datafile = StatePoint(filename)
|
||||
self.datafile.read_results()
|
||||
self.datafile.generate_stdev()
|
||||
|
||||
self.mesh = self.datafile.meshes[
|
||||
self.datafile.tallies[
|
||||
self.tally.currentIndex()].filters['mesh'].bins[0] - 1]
|
||||
# Find which tallies are mesh tallies
|
||||
self.meshTallies = []
|
||||
for itally, tally in enumerate(self.datafile.tallies):
|
||||
if 'mesh' in tally.filters:
|
||||
self.meshTallies.append(itally)
|
||||
|
||||
self.nx, self.ny, self.nz = self.mesh.dimension
|
||||
|
||||
# Clear axial level combobox
|
||||
self.axial_level.clear()
|
||||
|
||||
# Repopulate axial level combobox based on current basis selection
|
||||
if (self.basis.currentText() == 'xy'):
|
||||
self.axial_level.addItems([str(i+1) for i in range(self.nz)])
|
||||
elif (self.basis.currentText() == 'yz'):
|
||||
self.axial_level.addItems([str(i+1) for i in range(self.nx)])
|
||||
else:
|
||||
self.axial_level.addItems([str(i+1) for i in range(self.ny)])
|
||||
|
||||
# Determine maximum value from current tally data set
|
||||
self.maxvalue = self.datafile.tallies[
|
||||
self.tally.currentIndex()].results.max()
|
||||
# print self.maxvalue
|
||||
|
||||
# Clear and hide old filter labels
|
||||
for item in self.labelList:
|
||||
item.clear()
|
||||
|
||||
# Clear and hide old filter boxes
|
||||
for j in self.labels:
|
||||
self.boxes[j].clear()
|
||||
self.boxes[j].setParent(None)
|
||||
|
||||
self.update()
|
||||
|
||||
def populate_boxes(self):
|
||||
# print 'Calling populate_boxes...'
|
||||
|
||||
n = 5
|
||||
labels = {'cell': 'Cell : ',
|
||||
'cellborn': 'Cell born: ',
|
||||
'surface': 'Surface: ',
|
||||
'material': 'Material: ',
|
||||
'universe': 'Universe: '}
|
||||
|
||||
# For each filter in newly-selected tally, name a label and fill the
|
||||
# relevant combobox with options
|
||||
for element in self.tally_list[self.tally.currentIndex()]:
|
||||
nextFilter = self.datafile.tallies[
|
||||
self.tally.currentIndex()].filters[element]
|
||||
if element == 'mesh':
|
||||
continue
|
||||
|
||||
label = QLabel(self.labels[element])
|
||||
self.labelList.append(label)
|
||||
combobox = self.boxes[element]
|
||||
self.grid.addWidget(label, n, 0)
|
||||
self.grid.addWidget(combobox, n, 1)
|
||||
n += 1
|
||||
|
||||
# print element
|
||||
if element in ['cell', 'cellborn', 'surface', 'material', 'universe']:
|
||||
combobox.addItems([str(i) for i in nextFilter.bins])
|
||||
# for i in nextFilter.bins:
|
||||
# print i
|
||||
|
||||
elif element == 'energyin' or element == 'energyout':
|
||||
for i in range(nextFilter.length):
|
||||
text = (str(nextFilter.bins[i]) + ' to ' +
|
||||
str(nextFilter.bins[i+1]))
|
||||
combobox.addItem(text)
|
||||
|
||||
self.scoreBox.clear()
|
||||
for item in self.tally_scores[self.tally.currentIndex()]:
|
||||
self.scoreBox.addItem(str(item))
|
||||
self.grid.addWidget(self.score_label, n, 0)
|
||||
self.grid.addWidget(self.scoreBox, n, 1)
|
||||
if not self.meshTallies:
|
||||
tkMessageBox.showerror("Invalid StatePoint File",
|
||||
"File does not contain mesh tallies!")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Hide root window
|
||||
root = tk.Tk()
|
||||
root.withdraw()
|
||||
|
||||
def main():
|
||||
app = QApplication(sys.argv)
|
||||
form = AppForm()
|
||||
form.show()
|
||||
app.exec_()
|
||||
# If no filename given as command-line argument, open file dialog
|
||||
if len(sys.argv) < 2:
|
||||
filename = tkFileDialog.askopenfilename(title='Select statepoint file',
|
||||
initialdir='.')
|
||||
else:
|
||||
filename = sys.argv[1]
|
||||
|
||||
if filename:
|
||||
# Check to make sure file exists
|
||||
if not os.path.isfile(filename):
|
||||
tkMessageBox.showerror("File not found",
|
||||
"Could not find regular file: " + filename)
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
app = MeshPlotter(root, filename)
|
||||
root.deiconify()
|
||||
root.mainloop()
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#!/usr/bin/env python2
|
||||
|
||||
import struct
|
||||
from math import sqrt
|
||||
from collections import OrderedDict
|
||||
|
||||
import numpy as np
|
||||
|
|
@ -10,10 +9,10 @@ import scipy.stats
|
|||
filter_types = {1: 'universe', 2: 'material', 3: 'cell', 4: 'cellborn',
|
||||
5: 'surface', 6: 'mesh', 7: 'energyin', 8: 'energyout'}
|
||||
|
||||
score_types = {-1: 'flux',
|
||||
score_types = {-1: 'flux',
|
||||
-2: 'total',
|
||||
-3: 'scatter',
|
||||
-4: 'nu-scatter',
|
||||
-4: 'nu-scatter',
|
||||
-5: 'scatter-n',
|
||||
-6: 'scatter-pn',
|
||||
-7: 'transport',
|
||||
|
|
@ -152,7 +151,7 @@ class StatePoint(object):
|
|||
|
||||
# Read statepoint revision
|
||||
self.revision = self._get_int(path='revision')[0]
|
||||
if self.revision != 10:
|
||||
if self.revision != 11:
|
||||
raise Exception('Statepoint Revision is not consistent.')
|
||||
|
||||
# Read OpenMC version
|
||||
|
|
@ -276,7 +275,7 @@ class StatePoint(object):
|
|||
f.bins = self._get_int(path=base+'bins')
|
||||
else:
|
||||
f.bins = self._get_int(f.length, path=base+'bins')
|
||||
|
||||
|
||||
base = 'tallies/tally' + str(i+1) + '/'
|
||||
|
||||
# Read nuclide bins
|
||||
|
|
@ -299,6 +298,13 @@ class StatePoint(object):
|
|||
f.stride = stride
|
||||
stride *= f.length
|
||||
|
||||
# Source bank present
|
||||
source_present = self._get_int(path='source_present')[0]
|
||||
if source_present == 1:
|
||||
self.source_present = True
|
||||
else:
|
||||
self.source_present = False
|
||||
|
||||
# Set flag indicating metadata has already been read
|
||||
self._metadata = True
|
||||
|
||||
|
|
@ -343,6 +349,11 @@ class StatePoint(object):
|
|||
if not self._results:
|
||||
self.read_results()
|
||||
|
||||
# Check if source bank is in statepoint
|
||||
if not self.source_present:
|
||||
print('Source not in statepoint file.')
|
||||
return
|
||||
|
||||
# For HDF5 state points, copy entire bank
|
||||
if self._hdf5:
|
||||
source_sites = self._f['source_bank'].value
|
||||
|
|
@ -379,7 +390,7 @@ class StatePoint(object):
|
|||
Calculates the sample mean and standard deviation of the mean for each
|
||||
tally bin.
|
||||
"""
|
||||
|
||||
|
||||
# Determine number of realizations
|
||||
n = self.n_realizations
|
||||
|
||||
|
|
@ -387,14 +398,14 @@ class StatePoint(object):
|
|||
for i in range(len(self.global_tallies)):
|
||||
# Get sum and sum of squares
|
||||
s, s2 = self.global_tallies[i]
|
||||
|
||||
|
||||
# Calculate sample mean and replace value
|
||||
s /= n
|
||||
self.global_tallies[i,0] = s
|
||||
|
||||
# Calculate standard deviation
|
||||
if s != 0.0:
|
||||
self.global_tallies[i,1] = t_value*sqrt((s2/n - s*s)/(n-1))
|
||||
self.global_tallies[i,1] = t_value*np.sqrt((s2/n - s*s)/(n-1))
|
||||
|
||||
# Regular tallies
|
||||
for t in self.tallies:
|
||||
|
|
@ -402,14 +413,14 @@ class StatePoint(object):
|
|||
for j in range(t.results.shape[1]):
|
||||
# Get sum and sum of squares
|
||||
s, s2 = t.results[i,j]
|
||||
|
||||
|
||||
# Calculate sample mean and replace value
|
||||
s /= n
|
||||
t.results[i,j,0] = s
|
||||
|
||||
# Calculate standard deviation
|
||||
if s != 0.0:
|
||||
t.results[i,j,1] = t_value*sqrt((s2/n - s*s)/(n-1))
|
||||
t.results[i,j,1] = t_value*np.sqrt((s2/n - s*s)/(n-1))
|
||||
|
||||
def get_value(self, tally_index, spec_list, score_index):
|
||||
"""Returns a tally score given a list of filters to satisfy.
|
||||
|
|
@ -458,7 +469,7 @@ class StatePoint(object):
|
|||
filter_index += value*t.filters[f_type].stride
|
||||
else:
|
||||
filter_index += f_index*t.filters[f_type].stride
|
||||
|
||||
|
||||
# Return the desired result from Tally.results. This could be the sum and
|
||||
# sum of squares, or it could be mean and stdev if self.generate_stdev()
|
||||
# has been called already.
|
||||
|
|
@ -531,7 +542,7 @@ class StatePoint(object):
|
|||
for i in range(n_filters):
|
||||
|
||||
# compute indices for filter combination
|
||||
filters[:,n_filters - i - 1] = np.floor((np.arange(n_bins) %
|
||||
filters[:,n_filters - i - 1] = np.floor((np.arange(n_bins) %
|
||||
np.prod(filtmax[0:i+2]))/(np.prod(filtmax[0:i+1]))) + 1
|
||||
|
||||
# append in dictionary bin with filter
|
||||
|
|
@ -544,14 +555,14 @@ class StatePoint(object):
|
|||
dims.reverse()
|
||||
dims = np.asarray(dims)
|
||||
if score_str == 'current':
|
||||
dims += 1
|
||||
meshmax[1:4] = dims
|
||||
dims += 1
|
||||
meshmax[1:4] = dims
|
||||
mesh_bins = np.zeros((n_bins,3))
|
||||
mesh_bins[:,2] = np.floor(((filters[:,n_filters - i - 1] - 1) %
|
||||
mesh_bins[:,2] = np.floor(((filters[:,n_filters - i - 1] - 1) %
|
||||
np.prod(meshmax[0:2]))/(np.prod(meshmax[0:1]))) + 1
|
||||
mesh_bins[:,1] = np.floor(((filters[:,n_filters - i - 1] - 1) %
|
||||
mesh_bins[:,1] = np.floor(((filters[:,n_filters - i - 1] - 1) %
|
||||
np.prod(meshmax[0:3]))/(np.prod(meshmax[0:2]))) + 1
|
||||
mesh_bins[:,0] = np.floor(((filters[:,n_filters - i - 1] - 1) %
|
||||
mesh_bins[:,0] = np.floor(((filters[:,n_filters - i - 1] - 1) %
|
||||
np.prod(meshmax[0:4]))/(np.prod(meshmax[0:3]))) + 1
|
||||
data.update({'mesh':zip(mesh_bins[:,0],mesh_bins[:,1],
|
||||
mesh_bins[:,2])})
|
||||
|
|
@ -576,7 +587,7 @@ class StatePoint(object):
|
|||
def _get_data(self, n, typeCode, size):
|
||||
return list(struct.unpack('={0}{1}'.format(n,typeCode),
|
||||
self._f.read(n*size)))
|
||||
|
||||
|
||||
def _get_int(self, n=1, path=None):
|
||||
if self._hdf5:
|
||||
return [int(v) for v in self._f[path].value]
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ module FoX_dom
|
|||
public :: createAttribute
|
||||
public :: createEntityReference
|
||||
public :: getElementsByTagName
|
||||
public :: getChildrenByTagName
|
||||
public :: getElementById
|
||||
|
||||
public :: importNode
|
||||
|
|
|
|||
|
|
@ -349,6 +349,7 @@ module m_dom_dom
|
|||
public :: createEntityReference
|
||||
public :: createEmptyEntityReference
|
||||
public :: getElementsByTagName
|
||||
public :: getChildrenByTagName
|
||||
public :: importNode
|
||||
public :: createElementNS
|
||||
public :: createAttributeNS
|
||||
|
|
@ -6908,6 +6909,166 @@ endif
|
|||
|
||||
end function getElementsByTagName
|
||||
|
||||
function getChildrenByTagName(doc, tagName, name, ex)result(list)
|
||||
type(DOMException), intent(out), optional :: ex
|
||||
type(Node), pointer :: doc
|
||||
character(len=*), intent(in), optional :: tagName, name
|
||||
type(NodeList), pointer :: list
|
||||
|
||||
type(NodeListPtr), pointer :: nll(:), temp_nll(:)
|
||||
type(Node), pointer :: arg, this, treeroot
|
||||
logical :: doneChildren, doneAttributes, allElements
|
||||
integer :: i, i_tree
|
||||
|
||||
if (.not.associated(doc)) then
|
||||
if (getFoX_checks().or.FoX_NODE_IS_NULL<200) then
|
||||
call throw_exception(FoX_NODE_IS_NULL, "getElementsByTagName", ex)
|
||||
if (present(ex)) then
|
||||
if (inException(ex)) then
|
||||
return
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
if (doc%nodeType==DOCUMENT_NODE) then
|
||||
if (present(name).or..not.present(tagName)) then
|
||||
if (getFoX_checks().or.FoX_INVALID_NODE<200) then
|
||||
call throw_exception(FoX_INVALID_NODE, "getElementsByTagName", ex)
|
||||
if (present(ex)) then
|
||||
if (inException(ex)) then
|
||||
return
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
endif
|
||||
elseif (doc%nodeType==ELEMENT_NODE) then
|
||||
if (present(name).or..not.present(tagName)) then
|
||||
if (getFoX_checks().or.FoX_INVALID_NODE<200) then
|
||||
call throw_exception(FoX_INVALID_NODE, "getElementsByTagName", ex)
|
||||
if (present(ex)) then
|
||||
if (inException(ex)) then
|
||||
return
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
endif
|
||||
else
|
||||
if (getFoX_checks().or.FoX_INVALID_NODE<200) then
|
||||
call throw_exception(FoX_INVALID_NODE, "getElementsByTagName", ex)
|
||||
if (present(ex)) then
|
||||
if (inException(ex)) then
|
||||
return
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
if (doc%nodeType==DOCUMENT_NODE) then
|
||||
arg => getDocumentElement(doc)
|
||||
else
|
||||
arg => doc
|
||||
endif
|
||||
|
||||
allocate(list)
|
||||
allocate(list%nodes(0))
|
||||
list%element => doc
|
||||
if (present(name)) list%nodeName => vs_str_alloc(name)
|
||||
if (present(tagName)) list%nodeName => vs_str_alloc(tagName)
|
||||
|
||||
allElements = (str_vs(list%nodeName)=="*")
|
||||
|
||||
if (doc%nodeType==DOCUMENT_NODE) then
|
||||
nll => doc%docExtras%nodelists
|
||||
elseif (doc%nodeType==ELEMENT_NODE) then
|
||||
nll => doc%ownerDocument%docExtras%nodelists
|
||||
endif
|
||||
allocate(temp_nll(size(nll)+1))
|
||||
do i = 1, size(nll)
|
||||
temp_nll(i)%this => nll(i)%this
|
||||
enddo
|
||||
temp_nll(i)%this => list
|
||||
deallocate(nll)
|
||||
if (doc%nodeType==DOCUMENT_NODE) then
|
||||
doc%docExtras%nodelists => temp_nll
|
||||
elseif (doc%nodeType==ELEMENT_NODE) then
|
||||
doc%ownerDocument%docExtras%nodelists => temp_nll
|
||||
endif
|
||||
|
||||
treeroot => arg
|
||||
|
||||
i_tree = 0
|
||||
doneChildren = .false.
|
||||
doneAttributes = .false.
|
||||
this => treeroot
|
||||
do
|
||||
if (.not.doneChildren.and..not.(getNodeType(this)==ELEMENT_NODE.and.doneAttributes)) then
|
||||
if (this%nodeType==ELEMENT_NODE) then
|
||||
if ((allElements .or. str_vs(this%nodeName)==tagName) &
|
||||
.and..not.(getNodeType(doc)==ELEMENT_NODE.and.associated(this, arg))) &
|
||||
call append(list, this)
|
||||
doneAttributes = .true.
|
||||
endif
|
||||
|
||||
else
|
||||
if (getNodeType(this)==ELEMENT_NODE.and..not.doneChildren) then
|
||||
doneAttributes = .true.
|
||||
else
|
||||
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
if (.not.doneChildren) then
|
||||
if (getNodeType(this)==ELEMENT_NODE.and..not.doneAttributes) then
|
||||
if (getLength(getAttributes(this))>0) then
|
||||
this => item(getAttributes(this), 0)
|
||||
else
|
||||
doneAttributes = .true.
|
||||
endif
|
||||
elseif (hasChildNodes(this) .and. .not. associated(getParentNode(this), treeroot)) then
|
||||
this => getFirstChild(this)
|
||||
doneChildren = .false.
|
||||
doneAttributes = .false.
|
||||
else
|
||||
doneChildren = .true.
|
||||
doneAttributes = .false.
|
||||
endif
|
||||
|
||||
else ! if doneChildren
|
||||
|
||||
if (associated(this, treeroot)) exit
|
||||
if (getNodeType(this)==ATTRIBUTE_NODE) then
|
||||
if (i_tree<getLength(getAttributes(getOwnerElement(this)))-1) then
|
||||
i_tree= i_tree+ 1
|
||||
this => item(getAttributes(getOwnerElement(this)), i_tree)
|
||||
doneChildren = .false.
|
||||
else
|
||||
i_tree= 0
|
||||
this => getOwnerElement(this)
|
||||
doneAttributes = .true.
|
||||
doneChildren = .false.
|
||||
endif
|
||||
elseif (associated(getNextSibling(this))) then
|
||||
|
||||
this => getNextSibling(this)
|
||||
doneChildren = .false.
|
||||
doneAttributes = .false.
|
||||
else
|
||||
this => getParentNode(this)
|
||||
endif
|
||||
endif
|
||||
|
||||
enddo
|
||||
|
||||
|
||||
|
||||
end function getChildrenByTagName
|
||||
|
||||
function importNode(doc , arg, deep , ex)result(np)
|
||||
type(DOMException), intent(out), optional :: ex
|
||||
type(Node), pointer :: doc
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ contains
|
|||
! node name. This should only be used for checking a single occurance of a
|
||||
! sub-element node. To check for sub-element nodes that repeat, use
|
||||
! get_node_list and get_list_size. This is to minimize number of calls
|
||||
! to getElementsByTagName.
|
||||
! to getChildrenByTagName.
|
||||
!===============================================================================
|
||||
|
||||
function check_for_node(ptr, node_name) result(found)
|
||||
|
|
@ -94,7 +94,7 @@ contains
|
|||
if (associated(temp_ptr)) return
|
||||
|
||||
! Check for a sub-element
|
||||
elem_list => getElementsByTagName(ptr, trim(node_name))
|
||||
elem_list => getChildrenByTagName(ptr, trim(node_name))
|
||||
|
||||
! Get the length of the list
|
||||
if (getLength(elem_list) == 0) then
|
||||
|
|
@ -124,7 +124,7 @@ contains
|
|||
found_ = .false.
|
||||
|
||||
! Check for a sub-element
|
||||
elem_list => getElementsByTagName(in_ptr, trim(node_name))
|
||||
elem_list => getChildrenByTagName(in_ptr, trim(node_name))
|
||||
|
||||
! Get the length of the list
|
||||
if (getLength(elem_list) == 0) return
|
||||
|
|
@ -149,7 +149,7 @@ contains
|
|||
type(NodeList), pointer, intent(out) :: out_ptr
|
||||
|
||||
! Check for a sub-element
|
||||
out_ptr => getElementsByTagName(in_ptr, trim(node_name))
|
||||
out_ptr => getChildrenByTagName(in_ptr, trim(node_name))
|
||||
|
||||
end subroutine get_node_list
|
||||
|
||||
|
|
@ -525,7 +525,7 @@ contains
|
|||
if (associated(out_ptr)) return
|
||||
|
||||
! Check for a sub-element
|
||||
elem_list => getElementsByTagName(in_ptr, trim(node_name))
|
||||
elem_list => getChildrenByTagName(in_ptr, trim(node_name))
|
||||
|
||||
! Get the length of the list
|
||||
if (getLength(elem_list) == 0) then
|
||||
|
|
|
|||
10
tests/cleanup
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash
|
||||
|
||||
# This simple script ensures that all binary
|
||||
# output files have been deleted in all the
|
||||
# folders. This can occur if a previous error
|
||||
# occurred and the test suite was rerun without
|
||||
# deleting left over binary files. This will
|
||||
# cause an assertion error in some of the
|
||||
# tests.
|
||||
find . \( -name "*.binary" -o -name "*.h5" \) -exec rm -f {} \;
|
||||
|
|
@ -117,6 +117,8 @@ if len(sys.argv) > 1:
|
|||
if j.rfind(suffix) != -1:
|
||||
if suffix == 'omp' and j == 'compile':
|
||||
continue
|
||||
if j == 'compile':
|
||||
continue
|
||||
tests__.append(j)
|
||||
else:
|
||||
tests__.append(i) # append specific test (e.g., mpi-debug)
|
||||
|
|
|
|||
8
tests/test_source_file/geometry.xml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
<geometry>
|
||||
|
||||
<!-- Sphere with radius 10 -->
|
||||
<surface id="1" type="sphere" coeffs="0 0 0 10" boundary="vacuum"/>
|
||||
<cell id="1" material="1" surfaces="-1" />
|
||||
|
||||
</geometry>
|
||||
9
tests/test_source_file/materials.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<materials>
|
||||
|
||||
<material id="1">
|
||||
<density value="4.5" units="g/cc" />
|
||||
<nuclide name="U-235" xs="70c" ao="1.0" />
|
||||
</material>
|
||||
|
||||
</materials>
|
||||
25
tests/test_source_file/results.py
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
if len(sys.argv) > 1:
|
||||
sp = statepoint.StatePoint(sys.argv[1])
|
||||
else:
|
||||
sp = statepoint.StatePoint('statepoint.10.binary')
|
||||
sp.read_results()
|
||||
|
||||
# set up output string
|
||||
outstr = ''
|
||||
|
||||
# write out k-combined
|
||||
outstr += 'k-combined:\n'
|
||||
outstr += "{0:12.6E} {1:12.6E}\n".format(sp.k_combined[0], sp.k_combined[1])
|
||||
|
||||
# write results to file
|
||||
with open('results_test.dat','w') as fh:
|
||||
fh.write(outstr)
|
||||
2
tests/test_source_file/results_true.dat
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
k-combined:
|
||||
2.977307E-01 2.848670E-03
|
||||
19
tests/test_source_file/settings.xml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0"?>
|
||||
<settings>
|
||||
|
||||
<state_point batches="10" />
|
||||
<source_point separate="true" />
|
||||
|
||||
<eigenvalue>
|
||||
<batches>10</batches>
|
||||
<inactive>5</inactive>
|
||||
<particles>1000</particles>
|
||||
</eigenvalue>
|
||||
|
||||
<source>
|
||||
<space type="box">
|
||||
<parameters>-4 -4 -4 4 4 4</parameters>
|
||||
</space>
|
||||
</source>
|
||||
|
||||
</settings>
|
||||
101
tests/test_source_file/test_source_file.py
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
from subprocess import Popen, STDOUT, PIPE, call
|
||||
import filecmp
|
||||
from nose_mpi import NoseMPI
|
||||
import glob
|
||||
|
||||
pwd = os.path.dirname(__file__)
|
||||
|
||||
settings1="""<?xml version="1.0"?>
|
||||
<settings>
|
||||
|
||||
<state_point batches="10" />
|
||||
<source_point separate="true" />
|
||||
|
||||
<eigenvalue>
|
||||
<batches>10</batches>
|
||||
<inactive>5</inactive>
|
||||
<particles>1000</particles>
|
||||
</eigenvalue>
|
||||
|
||||
<source>
|
||||
<space type="box">
|
||||
<parameters>-4 -4 -4 4 4 4</parameters>
|
||||
</space>
|
||||
</source>
|
||||
|
||||
</settings>
|
||||
"""
|
||||
|
||||
settings2 = """<?xml version="1.0"?>
|
||||
<settings>
|
||||
|
||||
<eigenvalue>
|
||||
<batches>10</batches>
|
||||
<inactive>5</inactive>
|
||||
<particles>1000</particles>
|
||||
</eigenvalue>
|
||||
|
||||
<source>
|
||||
<file> source.10.{0} </file>
|
||||
</source>
|
||||
|
||||
</settings>
|
||||
"""
|
||||
|
||||
def setup():
|
||||
os.putenv('PWD', pwd)
|
||||
os.chdir(pwd)
|
||||
|
||||
def test_run1():
|
||||
openmc_path = pwd + '/../../src/openmc'
|
||||
if int(NoseMPI.mpi_np) > 0:
|
||||
proc = Popen([NoseMPI.mpi_exec, '-np', NoseMPI.mpi_np, openmc_path],
|
||||
stderr=STDOUT, stdout=PIPE)
|
||||
else:
|
||||
proc = Popen([openmc_path], stderr=STDOUT, stdout=PIPE)
|
||||
print(proc.communicate()[0])
|
||||
returncode = proc.returncode
|
||||
assert returncode == 0
|
||||
|
||||
def test_statepoint_exists():
|
||||
statepoint = glob.glob(pwd + '/statepoint.10.*')
|
||||
assert len(statepoint) == 1
|
||||
assert statepoint[0].endswith('binary') or statepoint[0].endswith('h5')
|
||||
source = glob.glob(pwd + '/source.10.*')
|
||||
assert len(statepoint) == 1
|
||||
assert source[0].endswith('binary') or source[0].endswith('h5')
|
||||
|
||||
def test_run2():
|
||||
openmc_path = pwd + '/../../src/openmc'
|
||||
source = glob.glob(pwd + '/source.10.*')
|
||||
with open('settings.xml','w') as fh:
|
||||
fh.write(settings2.format(source[0].split('.')[2]))
|
||||
if int(NoseMPI.mpi_np) > 0:
|
||||
proc = Popen([NoseMPI.mpi_exec, '-np', NoseMPI.mpi_np, openmc_path],
|
||||
stderr=STDOUT, stdout=PIPE)
|
||||
else:
|
||||
proc = Popen([openmc_path], stderr=STDOUT, stdout=PIPE)
|
||||
print(proc.communicate()[0])
|
||||
returncode = proc.returncode
|
||||
assert returncode == 0
|
||||
|
||||
def test_results():
|
||||
statepoint = glob.glob(pwd + '/statepoint.10.*')
|
||||
call(['python', 'results.py', statepoint[0]])
|
||||
compare = filecmp.cmp('results_test.dat', 'results_true.dat')
|
||||
if not compare:
|
||||
os.rename('results_test.dat', 'results_error.dat')
|
||||
assert compare
|
||||
|
||||
def teardown():
|
||||
with open('settings.xml','w') as fh:
|
||||
fh.write(settings1)
|
||||
output = glob.glob(pwd + '/statepoint.10.*')
|
||||
output += glob.glob(pwd + '/source.10.*')
|
||||
output.append(pwd + '/results_test.dat')
|
||||
for f in output:
|
||||
if os.path.exists(f):
|
||||
os.remove(f)
|
||||
8
tests/test_sourcepoint_batch/geometry.xml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
<geometry>
|
||||
|
||||
<!-- Sphere with radius 10 -->
|
||||
<surface id="1" type="sphere" coeffs="0 0 0 10" boundary="vacuum"/>
|
||||
<cell id="1" material="1" surfaces="-1" />
|
||||
|
||||
</geometry>
|
||||
9
tests/test_sourcepoint_batch/materials.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<materials>
|
||||
|
||||
<material id="1">
|
||||
<density value="4.5" units="g/cc" />
|
||||
<nuclide name="U-235" xs="70c" ao="1.0" />
|
||||
</material>
|
||||
|
||||
</materials>
|
||||
32
tests/test_sourcepoint_batch/results.py
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
if len(sys.argv) > 1:
|
||||
sp = statepoint.StatePoint(sys.argv[1])
|
||||
else:
|
||||
sp = statepoint.StatePoint('statepoint.8.binary')
|
||||
sp.read_results()
|
||||
sp.read_source()
|
||||
|
||||
# set up output string
|
||||
outstr = ''
|
||||
|
||||
# write out k-combined
|
||||
outstr += 'k-combined:\n'
|
||||
outstr += "{0:12.6E} {1:12.6E}\n".format(sp.k_combined[0], sp.k_combined[1])
|
||||
|
||||
# write out xyz
|
||||
xyz = sp.source[0].xyz
|
||||
for i in xyz:
|
||||
outstr += "{0:12.6E} ".format(i)
|
||||
outstr += "\n"
|
||||
|
||||
# write results to file
|
||||
with open('results_test.dat','w') as fh:
|
||||
fh.write(outstr)
|
||||
3
tests/test_sourcepoint_batch/results_true.dat
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
k-combined:
|
||||
0.000000E+00 0.000000E+00
|
||||
-9.438655E-02 -4.436810E+00 -2.416825E+00
|
||||
19
tests/test_sourcepoint_batch/settings.xml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0"?>
|
||||
<settings>
|
||||
|
||||
<state_point batches="2 3 4 5 8"/>
|
||||
<source_point batches="2 5 8"/>
|
||||
|
||||
<eigenvalue>
|
||||
<batches>10</batches>
|
||||
<inactive>5</inactive>
|
||||
<particles>1000</particles>
|
||||
</eigenvalue>
|
||||
|
||||
<source>
|
||||
<space type="box">
|
||||
<parameters>-4 -4 -4 4 4 4</parameters>
|
||||
</space>
|
||||
</source>
|
||||
|
||||
</settings>
|
||||
44
tests/test_sourcepoint_batch/test_sourcepoint_batch.py
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
from subprocess import Popen, STDOUT, PIPE, call
|
||||
import filecmp
|
||||
from nose_mpi import NoseMPI
|
||||
import glob
|
||||
|
||||
pwd = os.path.dirname(__file__)
|
||||
|
||||
def setup():
|
||||
os.putenv('PWD', pwd)
|
||||
os.chdir(pwd)
|
||||
|
||||
def test_run():
|
||||
openmc_path = pwd + '/../../src/openmc'
|
||||
if int(NoseMPI.mpi_np) > 0:
|
||||
proc = Popen([NoseMPI.mpi_exec, '-np', NoseMPI.mpi_np, openmc_path],
|
||||
stderr=STDOUT, stdout=PIPE)
|
||||
else:
|
||||
proc = Popen([openmc_path], stderr=STDOUT, stdout=PIPE)
|
||||
print(proc.communicate()[0])
|
||||
returncode = proc.returncode
|
||||
assert returncode == 0
|
||||
|
||||
def test_statepoint_exists():
|
||||
statepoint = glob.glob(pwd + '/statepoint.*')
|
||||
assert len(statepoint) == 5
|
||||
assert statepoint[0].endswith('binary') or statepoint[0].endswith('h5')
|
||||
|
||||
def test_results():
|
||||
statepoint = glob.glob(pwd + '/statepoint.8.*')
|
||||
call(['python', 'results.py', statepoint[0]])
|
||||
compare = filecmp.cmp('results_test.dat', 'results_true.dat')
|
||||
if not compare:
|
||||
os.rename('results_test.dat', 'results_error.dat')
|
||||
assert compare
|
||||
|
||||
def teardown():
|
||||
output = glob.glob(pwd + '/statepoint.*')
|
||||
output.append(pwd + '/results_test.dat')
|
||||
for f in output:
|
||||
if os.path.exists(f):
|
||||
os.remove(f)
|
||||
8
tests/test_sourcepoint_interval/geometry.xml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
<geometry>
|
||||
|
||||
<!-- Sphere with radius 10 -->
|
||||
<surface id="1" type="sphere" coeffs="0 0 0 10" boundary="vacuum"/>
|
||||
<cell id="1" material="1" surfaces="-1" />
|
||||
|
||||
</geometry>
|
||||
9
tests/test_sourcepoint_interval/materials.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<materials>
|
||||
|
||||
<material id="1">
|
||||
<density value="4.5" units="g/cc" />
|
||||
<nuclide name="U-235" xs="70c" ao="1.0" />
|
||||
</material>
|
||||
|
||||
</materials>
|
||||
32
tests/test_sourcepoint_interval/results.py
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
if len(sys.argv) > 1:
|
||||
sp = statepoint.StatePoint(sys.argv[1])
|
||||
else:
|
||||
sp = statepoint.StatePoint('statepoint.8.binary')
|
||||
sp.read_results()
|
||||
sp.read_source()
|
||||
|
||||
# set up output string
|
||||
outstr = ''
|
||||
|
||||
# write out k-combined
|
||||
outstr += 'k-combined:\n'
|
||||
outstr += "{0:12.6E} {1:12.6E}\n".format(sp.k_combined[0], sp.k_combined[1])
|
||||
|
||||
# write out xyz
|
||||
xyz = sp.source[0].xyz
|
||||
for i in xyz:
|
||||
outstr += "{0:12.6E} ".format(i)
|
||||
outstr += "\n"
|
||||
|
||||
# write results to file
|
||||
with open('results_test.dat','w') as fh:
|
||||
fh.write(outstr)
|
||||
3
tests/test_sourcepoint_interval/results_true.dat
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
k-combined:
|
||||
0.000000E+00 0.000000E+00
|
||||
-9.438655E-02 -4.436810E+00 -2.416825E+00
|
||||
19
tests/test_sourcepoint_interval/settings.xml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0"?>
|
||||
<settings>
|
||||
|
||||
<state_point interval="2"/>
|
||||
<source_point interval="4"/>
|
||||
|
||||
<eigenvalue>
|
||||
<batches>10</batches>
|
||||
<inactive>5</inactive>
|
||||
<particles>1000</particles>
|
||||
</eigenvalue>
|
||||
|
||||
<source>
|
||||
<space type="box">
|
||||
<parameters>-4 -4 -4 4 4 4</parameters>
|
||||
</space>
|
||||
</source>
|
||||
|
||||
</settings>
|
||||
44
tests/test_sourcepoint_interval/test_sourcepoint_interval.py
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
from subprocess import Popen, STDOUT, PIPE, call
|
||||
import filecmp
|
||||
from nose_mpi import NoseMPI
|
||||
import glob
|
||||
|
||||
pwd = os.path.dirname(__file__)
|
||||
|
||||
def setup():
|
||||
os.putenv('PWD', pwd)
|
||||
os.chdir(pwd)
|
||||
|
||||
def test_run():
|
||||
openmc_path = pwd + '/../../src/openmc'
|
||||
if int(NoseMPI.mpi_np) > 0:
|
||||
proc = Popen([NoseMPI.mpi_exec, '-np', NoseMPI.mpi_np, openmc_path],
|
||||
stderr=STDOUT, stdout=PIPE)
|
||||
else:
|
||||
proc = Popen([openmc_path], stderr=STDOUT, stdout=PIPE)
|
||||
print(proc.communicate()[0])
|
||||
returncode = proc.returncode
|
||||
assert returncode == 0
|
||||
|
||||
def test_statepoint_exists():
|
||||
statepoint = glob.glob(pwd + '/statepoint.*')
|
||||
assert len(statepoint) == 5
|
||||
assert statepoint[0].endswith('binary') or statepoint[0].endswith('h5')
|
||||
|
||||
def test_results():
|
||||
statepoint = glob.glob(pwd + '/statepoint.8.*')
|
||||
call(['python', 'results.py', statepoint[0]])
|
||||
compare = filecmp.cmp('results_test.dat', 'results_true.dat')
|
||||
if not compare:
|
||||
os.rename('results_test.dat', 'results_error.dat')
|
||||
assert compare
|
||||
|
||||
def teardown():
|
||||
output = glob.glob(pwd + '/statepoint.*')
|
||||
output.append(pwd + '/results_test.dat')
|
||||
for f in output:
|
||||
if os.path.exists(f):
|
||||
os.remove(f)
|
||||
8
tests/test_sourcepoint_latest/geometry.xml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
<geometry>
|
||||
|
||||
<!-- Sphere with radius 10 -->
|
||||
<surface id="1" type="sphere" coeffs="0 0 0 10" boundary="vacuum"/>
|
||||
<cell id="1" material="1" surfaces="-1" />
|
||||
|
||||
</geometry>
|
||||
9
tests/test_sourcepoint_latest/materials.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<materials>
|
||||
|
||||
<material id="1">
|
||||
<density value="4.5" units="g/cc" />
|
||||
<nuclide name="U-235" xs="70c" ao="1.0" />
|
||||
</material>
|
||||
|
||||
</materials>
|
||||
25
tests/test_sourcepoint_latest/results.py
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
if len(sys.argv) > 1:
|
||||
sp = statepoint.StatePoint(sys.argv[1])
|
||||
else:
|
||||
sp = statepoint.StatePoint('statepoint.10.binary')
|
||||
sp.read_results()
|
||||
|
||||
# set up output string
|
||||
outstr = ''
|
||||
|
||||
# write out k-combined
|
||||
outstr += 'k-combined:\n'
|
||||
outstr += "{0:12.6E} {1:12.6E}\n".format(sp.k_combined[0], sp.k_combined[1])
|
||||
|
||||
# write results to file
|
||||
with open('results_test.dat','w') as fh:
|
||||
fh.write(outstr)
|
||||
2
tests/test_sourcepoint_latest/results_true.dat
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
k-combined:
|
||||
3.011353E-01 2.854556E-03
|
||||
18
tests/test_sourcepoint_latest/settings.xml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0"?>
|
||||
<settings>
|
||||
|
||||
<source_point batches="0" separate="true" overwrite_latest="true"/>
|
||||
|
||||
<eigenvalue>
|
||||
<batches>10</batches>
|
||||
<inactive>5</inactive>
|
||||
<particles>1000</particles>
|
||||
</eigenvalue>
|
||||
|
||||
<source>
|
||||
<space type="box">
|
||||
<parameters>-4 -4 -4 4 4 4</parameters>
|
||||
</space>
|
||||
</source>
|
||||
|
||||
</settings>
|
||||
48
tests/test_sourcepoint_latest/test_sourcepoint_latest.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
from subprocess import Popen, STDOUT, PIPE, call
|
||||
import filecmp
|
||||
from nose_mpi import NoseMPI
|
||||
import glob
|
||||
|
||||
pwd = os.path.dirname(__file__)
|
||||
|
||||
def setup():
|
||||
os.putenv('PWD', pwd)
|
||||
os.chdir(pwd)
|
||||
|
||||
def test_run():
|
||||
openmc_path = pwd + '/../../src/openmc'
|
||||
if int(NoseMPI.mpi_np) > 0:
|
||||
proc = Popen([NoseMPI.mpi_exec, '-np', NoseMPI.mpi_np, openmc_path],
|
||||
stderr=STDOUT, stdout=PIPE)
|
||||
else:
|
||||
proc = Popen([openmc_path], stderr=STDOUT, stdout=PIPE)
|
||||
print(proc.communicate()[0])
|
||||
returncode = proc.returncode
|
||||
assert returncode == 0
|
||||
|
||||
def test_statepoint_exists():
|
||||
statepoint = glob.glob(pwd + '/statepoint.10.*')
|
||||
assert len(statepoint) == 1
|
||||
assert statepoint[0].endswith('binary') or statepoint[0].endswith('h5')
|
||||
source = glob.glob(pwd + '/source.*')
|
||||
assert len(source) == 1
|
||||
assert source[0].endswith('binary') or source[0].endswith('h5')
|
||||
|
||||
def test_results():
|
||||
statepoint = glob.glob(pwd + '/statepoint.10.*')
|
||||
call(['python', 'results.py', statepoint[0]])
|
||||
compare = filecmp.cmp('results_test.dat', 'results_true.dat')
|
||||
if not compare:
|
||||
os.rename('results_test.dat', 'results_error.dat')
|
||||
assert compare
|
||||
|
||||
def teardown():
|
||||
output = glob.glob(pwd + '/statepoint.10.*')
|
||||
output += glob.glob(pwd + '/source.*')
|
||||
output.append(pwd + '/results_test.dat')
|
||||
for f in output:
|
||||
if os.path.exists(f):
|
||||
os.remove(f)
|
||||
8
tests/test_sourcepoint_restart/geometry.xml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
<geometry>
|
||||
|
||||
<!-- Sphere with radius 10 -->
|
||||
<surface id="1" type="sphere" coeffs="0 0 0 10" boundary="vacuum"/>
|
||||
<cell id="1" material="1" surfaces="-1" />
|
||||
|
||||
</geometry>
|
||||
9
tests/test_sourcepoint_restart/materials.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<materials>
|
||||
|
||||
<material id="1">
|
||||
<density value="4.5" units="g/cc" />
|
||||
<nuclide name="U-235" xs="70c" ao="1.0" />
|
||||
</material>
|
||||
|
||||
</materials>
|
||||
44
tests/test_sourcepoint_restart/results.py
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
if len(sys.argv) > 1:
|
||||
sp = statepoint.StatePoint(sys.argv[1])
|
||||
else:
|
||||
sp = statepoint.StatePoint('statepoint.10.binary')
|
||||
sp.read_results()
|
||||
|
||||
# extract tally results and convert to vector
|
||||
results1 = sp.tallies[0].results
|
||||
shape1 = results1.shape
|
||||
size1 = (np.product(shape1))
|
||||
results1 = np.reshape(results1, size1)
|
||||
results2 = sp.tallies[1].results
|
||||
shape2 = results2.shape
|
||||
size2 = (np.product(shape2))
|
||||
results2 = np.reshape(results2, size2)
|
||||
|
||||
# set up output string
|
||||
outstr = ''
|
||||
|
||||
# write out k-combined
|
||||
outstr += 'k-combined:\n'
|
||||
outstr += "{0:12.6E} {1:12.6E}\n".format(sp.k_combined[0], sp.k_combined[1])
|
||||
|
||||
# write out tally results
|
||||
outstr += 'tally 1:\n'
|
||||
for item in results1:
|
||||
outstr += "{0:12.6E}\n".format(item)
|
||||
outstr += 'tally 2:\n'
|
||||
for item in results2:
|
||||
outstr += "{0:12.6E}\n".format(item)
|
||||
|
||||
# write results to file
|
||||
with open('results_test.dat','w') as fh:
|
||||
fh.write(outstr)
|
||||
2412
tests/test_sourcepoint_restart/results_true.dat
Normal file
19
tests/test_sourcepoint_restart/settings.xml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0"?>
|
||||
<settings>
|
||||
|
||||
<state_point batches="7 10" />
|
||||
<source_point batches="7" separate="true" />
|
||||
|
||||
<eigenvalue>
|
||||
<batches>10</batches>
|
||||
<inactive>5</inactive>
|
||||
<particles>1000</particles>
|
||||
</eigenvalue>
|
||||
|
||||
<source>
|
||||
<space type="box">
|
||||
<parameters>-4 -4 -4 4 4 4</parameters>
|
||||
</space>
|
||||
</source>
|
||||
|
||||
</settings>
|
||||
23
tests/test_sourcepoint_restart/tallies.xml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0"?>
|
||||
<tallies>
|
||||
|
||||
<mesh id="1">
|
||||
<type>rectangular</type>
|
||||
<dimension>5 3 4</dimension>
|
||||
<lower_left>-10. -5. 0.</lower_left>
|
||||
<upper_right>10. 4. 9.</upper_right>
|
||||
</mesh>
|
||||
|
||||
<tally id="10">
|
||||
<filter type="mesh" bins="1" />
|
||||
<filter type="energy" bins="0.0 5.0 10.0" />
|
||||
<filter type="energyout" bins="0.0 5.0 10.0" />
|
||||
<scores>scatter-P3 nu-fission</scores>
|
||||
</tally>
|
||||
|
||||
<tally id="5">
|
||||
<filter type="cell" bins="1" />
|
||||
<scores>fission absorption total flux</scores>
|
||||
</tally>
|
||||
|
||||
</tallies>
|
||||
129
tests/test_sourcepoint_restart/test_sourcepoint_restart.py
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
from subprocess import Popen, STDOUT, PIPE, call
|
||||
import filecmp
|
||||
from nose_mpi import NoseMPI
|
||||
import glob
|
||||
|
||||
pwd = os.path.dirname(__file__)
|
||||
|
||||
def setup():
|
||||
os.putenv('PWD', pwd)
|
||||
os.chdir(pwd)
|
||||
|
||||
def test_run():
|
||||
openmc_path = pwd + '/../../src/openmc'
|
||||
if int(NoseMPI.mpi_np) > 0:
|
||||
proc = Popen([NoseMPI.mpi_exec, '-np', NoseMPI.mpi_np, openmc_path],
|
||||
stderr=STDOUT, stdout=PIPE)
|
||||
else:
|
||||
proc = Popen([openmc_path], stderr=STDOUT, stdout=PIPE)
|
||||
print(proc.communicate()[0])
|
||||
returncode = proc.returncode
|
||||
assert returncode == 0
|
||||
|
||||
def test_created_statepoint():
|
||||
statepoint = glob.glob(pwd + '/statepoint.*')
|
||||
assert len(statepoint) == 2
|
||||
assert statepoint[0].endswith('binary') or statepoint[0].endswith('h5')
|
||||
sourcepoint = glob.glob(pwd + '/source.7.*')
|
||||
assert len(sourcepoint) == 1
|
||||
assert sourcepoint[0].endswith('binary') or sourcepoint[0].endswith('h5')
|
||||
|
||||
def test_results():
|
||||
statepoint = glob.glob(pwd + '/statepoint.10.*')
|
||||
call(['python', 'results.py', statepoint[0]])
|
||||
compare = filecmp.cmp('results_test.dat', 'results_true.dat')
|
||||
if not compare:
|
||||
os.rename('results_test.dat', 'results_error.dat')
|
||||
assert compare
|
||||
os.remove(statepoint[0])
|
||||
|
||||
def test_restart_form1():
|
||||
statepoint = glob.glob(pwd + '/statepoint.7.*')
|
||||
sourcepoint = glob.glob(pwd + '/source.7.*')
|
||||
openmc_path = pwd + '/../../src/openmc'
|
||||
if int(NoseMPI.mpi_np) > 0:
|
||||
proc = Popen([NoseMPI.mpi_exec, '-np', NoseMPI.mpi_np, openmc_path,
|
||||
'-r', statepoint[0], sourcepoint[0]],
|
||||
stderr=STDOUT, stdout=PIPE)
|
||||
else:
|
||||
proc = Popen([openmc_path, '-r', statepoint[0], sourcepoint[0]], stderr=STDOUT, stdout=PIPE)
|
||||
print(proc.communicate()[0])
|
||||
returncode = proc.returncode
|
||||
assert returncode == 0
|
||||
|
||||
def test_created_statepoint_form1():
|
||||
statepoint = glob.glob(pwd + '/statepoint.10.*')
|
||||
assert len(statepoint) == 1
|
||||
assert statepoint[0].endswith('binary') or statepoint[0].endswith('h5')
|
||||
|
||||
def test_results_form1():
|
||||
statepoint = glob.glob(pwd + '/statepoint.10.*')
|
||||
call(['python', 'results.py', statepoint[0]])
|
||||
compare = filecmp.cmp('results_test.dat', 'results_true.dat')
|
||||
if not compare:
|
||||
os.rename('results_test.dat', 'results_error.dat')
|
||||
assert compare
|
||||
os.remove(statepoint[0])
|
||||
|
||||
def test_restart_form2():
|
||||
statepoint = glob.glob(pwd + '/statepoint.7.*')
|
||||
sourcepoint = glob.glob(pwd + '/source.7.*')
|
||||
openmc_path = pwd + '/../../src/openmc'
|
||||
if int(NoseMPI.mpi_np) > 0:
|
||||
proc = Popen([NoseMPI.mpi_exec, '-np', NoseMPI.mpi_np, openmc_path,
|
||||
'--restart', statepoint[0], sourcepoint[0]],
|
||||
stderr=STDOUT, stdout=PIPE)
|
||||
else:
|
||||
proc = Popen([openmc_path, '--restart', statepoint[0], sourcepoint[0]],
|
||||
stderr=STDOUT, stdout=PIPE)
|
||||
print(proc.communicate()[0])
|
||||
returncode = proc.returncode
|
||||
assert returncode == 0
|
||||
|
||||
def test_created_statepoint_form2():
|
||||
statepoint = glob.glob(pwd + '/statepoint.10.*')
|
||||
assert len(statepoint) == 1
|
||||
assert statepoint[0].endswith('binary') or statepoint[0].endswith('h5')
|
||||
|
||||
def test_results_form2():
|
||||
statepoint = glob.glob(pwd + '/statepoint.10.*')
|
||||
call(['python', 'results.py', statepoint[0]])
|
||||
compare = filecmp.cmp('results_test.dat', 'results_true.dat')
|
||||
if not compare:
|
||||
os.rename('results_test.dat', 'results_error.dat')
|
||||
assert compare
|
||||
os.remove(statepoint[0])
|
||||
|
||||
def test_restart_serial():
|
||||
statepoint = glob.glob(pwd + '/statepoint.7.*')
|
||||
sourcepoint = glob.glob(pwd + '/source.7.*')
|
||||
openmc_path = pwd + '/../../src/openmc'
|
||||
proc = Popen([openmc_path, '--restart', statepoint[0], sourcepoint[0]],
|
||||
stderr=STDOUT, stdout=PIPE)
|
||||
print(proc.communicate()[0])
|
||||
returncode = proc.returncode
|
||||
assert returncode == 0
|
||||
|
||||
def test_created_statepoint_serial():
|
||||
statepoint = glob.glob(pwd + '/statepoint.10.*')
|
||||
assert len(statepoint) == 1
|
||||
assert statepoint[0].endswith('binary') or statepoint[0].endswith('h5')
|
||||
|
||||
def test_results_serial():
|
||||
statepoint = glob.glob(pwd + '/statepoint.10.*')
|
||||
call(['python', 'results.py', statepoint[0]])
|
||||
compare = filecmp.cmp('results_test.dat', 'results_true.dat')
|
||||
if not compare:
|
||||
os.rename('results_test.dat', 'results_error.dat')
|
||||
assert compare
|
||||
|
||||
def teardown():
|
||||
output = glob.glob(pwd + '/statepoint.*')
|
||||
output += glob.glob(pwd + '/source.*')
|
||||
output.append(pwd + '/results_test.dat')
|
||||
for f in output:
|
||||
if os.path.exists(f):
|
||||
os.remove(f)
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
<settings>
|
||||
|
||||
<state_point batches="10" source_separate="true" />
|
||||
<state_point batches="10" />
|
||||
<source_point separate="true" />
|
||||
|
||||
<eigenvalue>
|
||||
<batches>10</batches>
|
||||
|
|
|
|||