Fixed merge conflicts with develop

This commit is contained in:
Will Boyd 2017-02-19 17:04:14 -05:00
commit 24146ecfa0
135 changed files with 1762 additions and 980 deletions

View file

@ -266,15 +266,105 @@ add_library(faddeeva STATIC src/Faddeeva.c)
#===============================================================================
set(program "openmc")
file(GLOB source src/*.F90 src/xml/openmc_fox.F90)
add_executable(${program} ${source})
set(LIBOPENMC_FORTRAN_SRC
src/algorithm.F90
src/angle_distribution.F90
src/angleenergy_header.F90
src/bank_header.F90
src/cmfd_data.F90
src/cmfd_execute.F90
src/cmfd_header.F90
src/cmfd_input.F90
src/cmfd_loss_operator.F90
src/cmfd_prod_operator.F90
src/cmfd_solver.F90
src/constants.F90
src/cross_section.F90
src/dict_header.F90
src/distribution_multivariate.F90
src/distribution_univariate.F90
src/doppler.F90
src/eigenvalue.F90
src/endf.F90
src/endf_header.F90
src/energy_distribution.F90
src/energy_grid.F90
src/error.F90
src/finalize.F90
src/geometry.F90
src/geometry_header.F90
src/global.F90
src/hdf5_interface.F90
src/initialize.F90
src/input_xml.F90
src/list_header.F90
src/material_header.F90
src/math.F90
src/matrix_header.F90
src/mesh.F90
src/mesh_header.F90
src/message_passing.F90
src/mgxs_data.F90
src/mgxs_header.F90
src/multipole.F90
src/multipole_header.F90
src/nuclide_header.F90
src/output.F90
src/particle_header.F90
src/particle_restart.F90
src/particle_restart_write.F90
src/physics_common.F90
src/physics.F90
src/physics_mg.F90
src/plot.F90
src/plot_header.F90
src/ppmlib.F90
src/product_header.F90
src/progress_header.F90
src/random_lcg.F90
src/reaction_header.F90
src/relaxng
src/sab_header.F90
src/scattdata_header.F90
src/secondary_correlated.F90
src/secondary_kalbach.F90
src/secondary_nbody.F90
src/secondary_uncorrelated.F90
src/set_header.F90
src/simulation.F90
src/source.F90
src/source_header.F90
src/state_point.F90
src/stl_vector.F90
src/string.F90
src/summary.F90
src/surface_header.F90
src/tally.F90
src/tally_filter.F90
src/tally_filter_header.F90
src/tally_header.F90
src/tally_initialize.F90
src/timer_header.F90
src/tracking.F90
src/track_output.F90
src/trigger.F90
src/trigger_header.F90
src/urr_header.F90
src/vector_header.F90
src/volume_calc.F90
src/volume_header.F90
src/xml_interface.F90
src/xml/openmc_fox.F90)
add_library(libopenmc STATIC ${LIBOPENMC_FORTRAN_SRC})
set_target_properties(libopenmc PROPERTIES OUTPUT_NAME openmc)
add_executable(${program} src/main.F90)
# target_include_directories was added in CMake 2.8.11 and is the recommended
# way to set include directories. For lesser versions, we revert to set_property
if(CMAKE_VERSION VERSION_LESS 2.8.11)
include_directories(${HDF5_INCLUDE_DIRS})
else()
target_include_directories(${program} PUBLIC ${HDF5_INCLUDE_DIRS})
target_include_directories(libopenmc PUBLIC ${HDF5_INCLUDE_DIRS})
endif()
# target_compile_options was added in CMake 2.8.12 and is the recommended way to
@ -288,6 +378,7 @@ if (CMAKE_VERSION VERSION_LESS 2.8.12)
set_property(TARGET faddeeva PROPERTY COMPILE_FLAGS "${cflags}")
else()
target_compile_options(${program} PUBLIC ${f90flags})
target_compile_options(libopenmc PUBLIC ${f90flags})
target_compile_options(faddeeva PRIVATE ${cflags})
endif()
@ -298,7 +389,8 @@ endforeach()
# target_link_libraries treats any arguments starting with - but not -l as
# linker flags. Thus, we can pass both linker flags and libraries together.
target_link_libraries(${program} ${ldflags} ${HDF5_LIBRARIES} fox_dom faddeeva)
target_link_libraries(libopenmc ${ldflags} ${HDF5_LIBRARIES} fox_dom faddeeva)
target_link_libraries(${program} ${ldflags} libopenmc)
#===============================================================================
# Install executable, scripts, manpage, license

View file

@ -248,7 +248,7 @@ napoleon_use_ivar = True
intersphinx_mapping = {
'python': ('https://docs.python.org/3', None),
'numpy': ('http://docs.scipy.org/doc/numpy/', None),
'numpy': ('https://docs.scipy.org/doc/numpy/', None),
'pandas': ('http://pandas.pydata.org/pandas-docs/stable/', None),
'matplotlib': ('http://matplotlib.org/', None)
}

View file

@ -115,6 +115,19 @@ Many of the above classes are derived from several abstract classes:
openmc.Region
openmc.Lattice
Two helper function are also available to create rectangular and hexagonal
prisms defined by the intersection of four and six surface half-spaces,
respectively.
.. autosummary::
:toctree: generated
:nosignatures:
:template: myfunction.rst
openmc.get_hexagonal_prism
openmc.get_rectangular_prism
>>>>>>> upstream/develop
Constructing Tallies
--------------------

View file

@ -94,6 +94,18 @@ Settings Specification -- settings.xml
All simulation parameters and miscellaneous options are specified in the
settings.xml file.
``<batches>`` Element
---------------------
The ``<batches>`` element indicates the total number of batches to execute,
where each batch corresponds to a tally realization. In a fixed source
calculation, each batch consists of a number of source particles. In an
eigenvalue calculation, each batch consists of one or many fission source
iterations (generations), where each generation itself consists of a number of
source neutrons.
*Default*: None
``<confidence_intervals>`` Element
----------------------------------
@ -132,67 +144,6 @@ you care. This element has the following attributes/sub-elements:
*Default*: 0.0
.. _eigenvalue:
``<eigenvalue>`` Element
------------------------
The ``<eigenvalue>`` element indicates that a :math:`k`-eigenvalue calculation
should be performed. It has the following attributes/sub-elements:
:batches:
The total number of batches, where each batch corresponds to multiple
fission source iterations. Batching is done to eliminate correlation between
realizations of random variables.
*Default*: None
:generations_per_batch:
The number of total fission source iterations per batch.
*Default*: 1
:inactive:
The number of inactive batches. In general, the starting cycles in a
criticality calculation can not be used to contribute to tallies since the
fission source distribution and eigenvalue are generally not converged
immediately.
*Default*: None
:particles:
The number of neutrons to simulate per fission source iteration.
*Default*: None
:keff_trigger:
This tag specifies a precision trigger on the combined :math:`k_{eff}`. The
trigger is a convergence criterion on the uncertainty of the estimated
eigenvalue. It has the following attributes/sub-elements:
:type:
The type of precision trigger. Accepted options are "variance", "std_dev",
and "rel_err".
:variance:
Variance of the batch mean :math:`\sigma^2`
:std_dev:
Standard deviation of the batch mean :math:`\sigma`
:rel_err:
Relative error of the batch mean :math:`\frac{\sigma}{\mu}`
*Default*: None
:threshold:
The precision trigger's convergence criterion for the
combined :math:`k_{eff}`.
*Default*: None
.. note:: See section on the :ref:`trigger` for more information.
``<energy_grid>`` Element
-------------------------
@ -247,23 +198,58 @@ problem. It has the following attributes/sub-elements:
*Default*: None
``<fixed_source>`` Element
``<generations_per_batch>`` Element
-----------------------------------
The ``<generations_per_batch>`` element indicates the number of total fission
source iterations per batch for an eigenvalue calculation. This element is
ignored for all run modes other than "eigenvalue".
*Default*: 1
``<inactive>`` Element
----------------------
The ``<inactive>`` element indicates the number of inactive batches used in a
k-eigenvalue calculation. In general, the starting fission source iterations in
an eigenvalue calculation can not be used to contribute to tallies since the
fission source distribution and eigenvalue are generally not converged
immediately. This element is ignored for all run modes other than "eigenvalue".
*Default*: 0
``<keff_trigger>`` Element
--------------------------
The ``<fixed_source>`` element indicates that a fixed source calculation should
be performed. It has the following attributes/sub-elements:
The ``<keff_trigger>`` element (ignored for all run modes other than
"eigenvalue".) specifies a precision trigger on the combined
:math:`k_{eff}`. The trigger is a convergence criterion on the uncertainty of
the estimated eigenvalue. It has the following attributes/sub-elements:
:batches:
The total number of batches. For fixed source calculations, each batch
represents a realization of random variables for tallies.
:type:
The type of precision trigger. Accepted options are "variance", "std_dev",
and "rel_err".
:variance:
Variance of the batch mean :math:`\sigma^2`
:std_dev:
Standard deviation of the batch mean :math:`\sigma`
:rel_err:
Relative error of the batch mean :math:`\frac{\sigma}{\mu}`
*Default*: None
:particles:
The number of particles to simulate per batch.
:threshold:
The precision trigger's convergence criterion for the
combined :math:`k_{eff}`.
*Default*: None
.. note:: See section on the :ref:`trigger` for more information.
``<log_grid_bins>`` Element
---------------------------
@ -336,6 +322,15 @@ will abort.
*Default*: Current working directory
``<particles>`` Element
-----------------------
This element indicates the number of neutrons to simulate per fission source
iteration when a k-eigenvalue calculation is performed or the number of neutrons
per batch for a fixed source simulation.
*Default*: None
``<ptables>`` Element
---------------------
@ -408,7 +403,16 @@ The ``<run_cmfd>`` element indicates whether or not CMFD acceleration should be
turned on or off. This element has no attributes or sub-elements and can be set
to either "false" or "true".
*Defualt*: false
*Default*: false
``<run_mode>`` Element
----------------------
The ``<run_mode>`` element indicates which run mode should be used when OpenMC
is executed. This element has no attributes or sub-elements and can be set to
"eigenvalue", "fixed source", "plot", "volume", or "particle restart".
*Default*: None
``<seed>`` Element
------------------
@ -774,13 +778,13 @@ number, and particle number, respectively.
-------------------------
OpenMC includes tally precision triggers which allow the user to define
uncertainty thresholds on :math:`k_{eff}` in the ``<eigenvalue>`` subelement of
``settings.xml``, and/or tallies in ``tallies.xml``. When using triggers,
uncertainty thresholds on :math:`k_{eff}` in the ``<keff_trigger>`` subelement
of ``settings.xml``, and/or tallies in ``tallies.xml``. When using triggers,
OpenMC will run until it completes as many batches as defined by ``<batches>``.
At this point, the uncertainties on all tallied values are computed and
compared with their corresponding trigger thresholds. If any triggers have not
been met, OpenMC will continue until either all trigger thresholds have been
satisfied or ``<max_batches>`` has been reached.
At this point, the uncertainties on all tallied values are computed and compared
with their corresponding trigger thresholds. If any triggers have not been met,
OpenMC will continue until either all trigger thresholds have been satisfied or
``<max_batches>`` has been reached.
The ``<trigger>`` element provides an active "toggle switch" for tally
precision trigger(s), the maximum number of batches and the batch interval. It
@ -793,8 +797,8 @@ has the following attributes/sub-elements:
:max_batches:
This describes the maximum number of batches allowed when using trigger(s).
.. note:: When max_batches is set, the number of ``batches`` shown in
``<eigenvalue>`` element represents minimum number of batches to
.. note:: When max_batches is set, the number of ``batches`` shown in the
``<batches>`` element represents minimum number of batches to
simulate when using the trigger(s).
:batch_interval:

View file

@ -1,12 +1,10 @@
<?xml version="1.0"?>
<settings>
<!-- Parameters for k-eigenvalue calculation -->
<eigenvalue>
<batches>15</batches>
<inactive>5</inactive>
<particles>10000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>15</batches>
<inactive>5</inactive>
<particles>10000</particles>
<!-- Starting source -->
<source>

View file

@ -2,11 +2,10 @@
<settings>
<!-- Parameters for k-eigenvalue calculation -->
<eigenvalue>
<batches>15</batches>
<inactive>5</inactive>
<particles>10000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>15</batches>
<inactive>5</inactive>
<particles>10000</particles>
<!-- Starting source -->
<source>

View file

@ -2,11 +2,10 @@
<settings>
<!-- Parameters for k-eigenvalue calculation -->
<eigenvalue>
<batches>20</batches>
<inactive>10</inactive>
<particles>10000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>20</batches>
<inactive>10</inactive>
<particles>10000</particles>
<!-- Starting source -->
<source>

View file

@ -2,11 +2,10 @@
<settings>
<!-- Parameters for k-eigenvalue calculation -->
<eigenvalue>
<batches>20</batches>
<inactive>10</inactive>
<particles>10000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>20</batches>
<inactive>10</inactive>
<particles>10000</particles>
<!-- Starting source -->
<source>

View file

@ -2,11 +2,10 @@
<settings>
<!-- Define how many particles to run and for how many batches -->
<eigenvalue>
<batches>100</batches>
<inactive>10</inactive>
<particles>1000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>100</batches>
<inactive>10</inactive>
<particles>1000</particles>
<!-- The starting source is a uniform distribution over the entire pin
cell. Note that since this is effectively a 2D model, the z coordinates
@ -29,4 +28,4 @@
<dimension>10 10 1</dimension>
</entropy>
</settings>
</settings>

View file

@ -1,14 +1,10 @@
<?xml version='1.0' encoding='utf-8'?>
<settings>
<eigenvalue>
<particles>1000</particles>
<batches>100</batches>
<inactive>10</inactive>
</eigenvalue>
<source strength="1.0">
<space type="box">
<parameters>-0.63 -0.63 -1 0.63 0.63 1</parameters>
</space>
</source>
<energy_mode>multi-group</energy_mode>
<run_mode>eigenvalue</run_mode>
<source strength="1.0">
<space type="box">
<parameters>-0.63 -0.63 -1 0.63 0.63 1</parameters>
</space>
</source>
<energy_mode>multi-group</energy_mode>
</settings>

View file

@ -2,11 +2,10 @@
<settings>
<!-- Parameters for k-eigenvalue calculation -->
<eigenvalue>
<batches>500</batches>
<inactive>10</inactive>
<particles>10000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>500</batches>
<inactive>10</inactive>
<particles>10000</particles>
<!-- Starting source -->
<source>

View file

@ -44,8 +44,8 @@ def plot_geometry(output=True, openmc_exec='openmc', cwd='.'):
def run(particles=None, threads=None, geometry_debug=False,
restart_file=None, tracks=False, mpi_procs=1, output=True,
openmc_exec='openmc', mpi_exec='mpiexec', cwd='.'):
restart_file=None, tracks=False, output=True, cwd='.',
openmc_exec='openmc', mpi_args=None):
"""Run an OpenMC simulation.
Parameters
@ -56,23 +56,23 @@ def run(particles=None, threads=None, geometry_debug=False,
Number of OpenMP threads. If OpenMC is compiled with OpenMP threading
enabled, the default is implementation-dependent but is usually equal to
the number of hardware threads available (or a value set by the
OMP_NUM_THREADS environment variable).
:envvar:`OMP_NUM_THREADS` environment variable).
geometry_debug : bool, optional
Turn on geometry debugging during simulation. Defaults to False.
restart_file : str, optional
Path to restart file to use
tracks : bool, optional
Write tracks for all particles. Defaults to False.
mpi_procs : int, optional
Number of MPI processes.
output : bool, optional
Capture OpenMC output from standard out. Defaults to True.
cwd : str, optional
Path to working directory to run in. Defaults to the current working
directory.
openmc_exec : str, optional
Path to OpenMC executable. Defaults to 'openmc'.
mpi_exec : str, optional
MPI execute command. Defaults to 'mpiexec'.
cwd : str, optional
Path to working directory to run in. Defaults to the current working directory.
mpi_args : list of str, optional
MPI execute command and any additional MPI arguments to pass,
e.g. ['mpiexec', '-n', '8'].
"""
@ -94,8 +94,8 @@ def run(particles=None, threads=None, geometry_debug=False,
if tracks:
post_args += '-t'
if isinstance(mpi_procs, Integral) and mpi_procs > 1:
pre_args += '{} -n {} '.format(mpi_exec, mpi_procs)
if mpi_args is not None:
pre_args = ' '.join(mpi_args) + ' '
command = pre_args + openmc_exec + ' ' + post_args

View file

@ -56,6 +56,9 @@ class Material(object):
Units used for `density`. Can be one of 'g/cm3', 'g/cc', 'kg/cm3',
'atom/b-cm', 'atom/cm3', 'sum', or 'macro'. The 'macro' unit only
applies in the case of a multi-group calculation.
depletable : bool
Indicate whether the material is depletable. This attribute can be used
by downstream depletion applications.
elements : list of tuple
List in which each item is a 4-tuple consisting of an
:class:`openmc.Element` instance, the percent density, the percent
@ -78,6 +81,7 @@ class Material(object):
self.temperature = temperature
self._density = None
self._density_units = ''
self._depletable = False
# A list of tuples (nuclide, percent, percent type)
self._nuclides = []
@ -127,37 +131,36 @@ class Material(object):
def __repr__(self):
string = 'Material\n'
string += '{0: <16}{1}{2}\n'.format('\tID', '=\t', self._id)
string += '{0: <16}{1}{2}\n'.format('\tName', '=\t', self._name)
string += '{0: <16}{1}{2}\n'.format('\tTemperature', '=\t',
self._temperature)
string += '{: <16}=\t{}\n'.format('\tID', self._id)
string += '{: <16}=\t{}\n'.format('\tName', self._name)
string += '{: <16}=\t{}\n'.format('\tTemperature', self._temperature)
string += '{0: <16}{1}{2}'.format('\tDensity', '=\t', self._density)
string += ' [{0}]\n'.format(self._density_units)
string += '{: <16}=\t{}'.format('\tDensity', self._density)
string += ' [{}]\n'.format(self._density_units)
string += '{0: <16}\n'.format('\tS(a,b) Tables')
string += '{: <16}\n'.format('\tS(a,b) Tables')
for sab in self._sab:
string += '{0: <16}{1}{2}\n'.format('\tS(a,b)', '=\t', sab)
string += '{: <16}=\t{}\n'.format('\tS(a,b)', sab)
string += '{0: <16}\n'.format('\tNuclides')
string += '{: <16}\n'.format('\tNuclides')
for nuclide, percent, percent_type in self._nuclides:
string += '{0: <16}'.format('\t{0.name}'.format(nuclide))
string += '=\t{0: <12} [{1}]\n'.format(percent, percent_type)
string += '=\t{: <12} [{}]\n'.format(percent, percent_type)
if self._macroscopic is not None:
string += '{0: <16}\n'.format('\tMacroscopic Data')
string += '{0: <16}'.format('\t{0}'.format(self._macroscopic))
string += '{: <16}\n'.format('\tMacroscopic Data')
string += '{: <16}'.format('\t{}'.format(self._macroscopic))
string += '{0: <16}\n'.format('\tElements')
string += '{: <16}\n'.format('\tElements')
for element, percent, percent_type, enr in self._elements:
string += '{0: <16}'.format('\t{0.name}'.format(element))
if enr is None:
string += '=\t{0: <12} [{1}]\n'.format(percent, percent_type)
string += '=\t{: <12} [{}]\n'.format(percent, percent_type)
else:
string += '=\t{0: <12} [{1}] @ {2} w/o enrichment\n'\
string += '=\t{: <12} [{}] @ {} w/o enrichment\n'\
.format(percent, percent_type, enr)
return string
@ -182,6 +185,10 @@ class Material(object):
def density_units(self):
return self._density_units
@property
def depletable(self):
return self._depletable
@property
def elements(self):
return self._elements
@ -234,7 +241,7 @@ class Material(object):
@name.setter
def name(self, name):
if name is not None:
cv.check_type('name for Material ID="{0}"'.format(self._id),
cv.check_type('name for Material ID="{}"'.format(self._id),
name, string_types)
self._name = name
else:
@ -242,10 +249,16 @@ class Material(object):
@temperature.setter
def temperature(self, temperature):
cv.check_type('Temperature for Material ID="{0}"'.format(self._id),
cv.check_type('Temperature for Material ID="{}"'.format(self._id),
temperature, (Real, type(None)))
self._temperature = temperature
@depletable.setter
def depletable(self, depletable):
cv.check_type('Depletable flag for Material ID="{}"'.format(self.id),
depletable, bool)
self._depletable = depletable
def set_density(self, units, density=None):
"""Set the density of the material
@ -264,17 +277,17 @@ class Material(object):
if units is 'sum':
if density is not None:
msg = 'Density "{0}" for Material ID="{1}" is ignored ' \
msg = 'Density "{}" for Material ID="{}" is ignored ' \
'because the unit is "sum"'.format(density, self.id)
warnings.warn(msg)
else:
if density is None:
msg = 'Unable to set the density for Material ID="{0}" ' \
msg = 'Unable to set the density for Material ID="{}" ' \
'because a density value must be given when not using ' \
'"sum" unit'.format(self.id)
raise ValueError(msg)
cv.check_type('the density for Material ID="{0}"'.format(self.id),
cv.check_type('the density for Material ID="{}"'.format(self.id),
density, Real)
self._density = density
@ -285,8 +298,8 @@ class Material(object):
'version of openmc')
if not isinstance(filename, string_types) and filename is not None:
msg = 'Unable to add OTF material file to Material ID="{0}" with a ' \
'non-string name "{1}"'.format(self._id, filename)
msg = 'Unable to add OTF material file to Material ID="{}" with a ' \
'non-string name "{}"'.format(self._id, filename)
raise ValueError(msg)
self._distrib_otf_file = filename
@ -314,23 +327,23 @@ class Material(object):
"""
if self._macroscopic is not None:
msg = 'Unable to add a Nuclide to Material ID="{0}" as a ' \
msg = 'Unable to add a Nuclide to Material ID="{}" as a ' \
'macroscopic data-set has already been added'.format(self._id)
raise ValueError(msg)
if not isinstance(nuclide, string_types + (openmc.Nuclide,)):
msg = 'Unable to add a Nuclide to Material ID="{0}" with a ' \
'non-Nuclide value "{1}"'.format(self._id, nuclide)
msg = 'Unable to add a Nuclide to Material ID="{}" with a ' \
'non-Nuclide value "{}"'.format(self._id, nuclide)
raise ValueError(msg)
elif not isinstance(percent, Real):
msg = 'Unable to add a Nuclide to Material ID="{0}" with a ' \
'non-floating point value "{1}"'.format(self._id, percent)
msg = 'Unable to add a Nuclide to Material ID="{}" with a ' \
'non-floating point value "{}"'.format(self._id, percent)
raise ValueError(msg)
elif percent_type not in ['ao', 'wo', 'at/g-cm']:
msg = 'Unable to add a Nuclide to Material ID="{0}" with a ' \
'percent type "{1}"'.format(self._id, percent_type)
msg = 'Unable to add a Nuclide to Material ID="{}" with a ' \
'percent type "{}"'.format(self._id, percent_type)
raise ValueError(msg)
if isinstance(nuclide, openmc.Nuclide):
@ -353,7 +366,7 @@ class Material(object):
"""
if not isinstance(nuclide, openmc.Nuclide):
msg = 'Unable to remove a Nuclide "{0}" in Material ID="{1}" ' \
msg = 'Unable to remove a Nuclide "{}" in Material ID="{}" ' \
'since it is not a Nuclide'.format(self._id, nuclide)
raise ValueError(msg)
@ -377,15 +390,15 @@ class Material(object):
# Ensure no nuclides, elements, or sab are added since these would be
# incompatible with macroscopics
if self._nuclides or self._elements or self._sab:
msg = 'Unable to add a Macroscopic data set to Material ID="{0}" ' \
'with a macroscopic value "{1}" as an incompatible data ' \
msg = 'Unable to add a Macroscopic data set to Material ID="{}" ' \
'with a macroscopic value "{}" as an incompatible data ' \
'member (i.e., nuclide, element, or S(a,b) table) ' \
'has already been added'.format(self._id, macroscopic)
raise ValueError(msg)
if not isinstance(macroscopic, string_types + (openmc.Macroscopic,)):
msg = 'Unable to add a Macroscopic to Material ID="{0}" with a ' \
'non-Macroscopic value "{1}"'.format(self._id, macroscopic)
msg = 'Unable to add a Macroscopic to Material ID="{}" with a ' \
'non-Macroscopic value "{}"'.format(self._id, macroscopic)
raise ValueError(msg)
if isinstance(macroscopic, openmc.Macroscopic):
@ -398,7 +411,7 @@ class Material(object):
if self._macroscopic is None:
self._macroscopic = macroscopic
else:
msg = 'Unable to add a Macroscopic to Material ID="{0}". ' \
msg = 'Unable to add a Macroscopic to Material ID="{}". ' \
'Only one Macroscopic allowed per ' \
'Material.'.format(self._id)
raise ValueError(msg)
@ -422,7 +435,7 @@ class Material(object):
"""
if not isinstance(macroscopic, openmc.Macroscopic):
msg = 'Unable to remove a Macroscopic "{0}" in Material ID="{1}" ' \
msg = 'Unable to remove a Macroscopic "{}" in Material ID="{}" ' \
'since it is not a Macroscopic'.format(self._id, macroscopic)
raise ValueError(msg)
@ -450,23 +463,23 @@ class Material(object):
"""
if self._macroscopic is not None:
msg = 'Unable to add an Element to Material ID="{0}" as a ' \
msg = 'Unable to add an Element to Material ID="{}" as a ' \
'macroscopic data-set has already been added'.format(self._id)
raise ValueError(msg)
if not isinstance(element, string_types + (openmc.Element,)):
msg = 'Unable to add an Element to Material ID="{0}" with a ' \
'non-Element value "{1}"'.format(self._id, element)
msg = 'Unable to add an Element to Material ID="{}" with a ' \
'non-Element value "{}"'.format(self._id, element)
raise ValueError(msg)
if not isinstance(percent, Real):
msg = 'Unable to add an Element to Material ID="{0}" with a ' \
'non-floating point value "{1}"'.format(self._id, percent)
msg = 'Unable to add an Element to Material ID="{}" with a ' \
'non-floating point value "{}"'.format(self._id, percent)
raise ValueError(msg)
if percent_type not in ['ao', 'wo']:
msg = 'Unable to add an Element to Material ID="{0}" with a ' \
'percent type "{1}"'.format(self._id, percent_type)
msg = 'Unable to add an Element to Material ID="{}" with a ' \
'percent type "{}"'.format(self._id, percent_type)
raise ValueError(msg)
# Copy this Element to separate it from same Element in other Materials
@ -477,14 +490,14 @@ class Material(object):
if enrichment is not None:
if not isinstance(enrichment, Real):
msg = 'Unable to add an Element to Material ID="{0}" with a ' \
'non-floating point enrichment value "{1}"'\
msg = 'Unable to add an Element to Material ID="{}" with a ' \
'non-floating point enrichment value "{}"'\
.format(self._id, enrichment)
raise ValueError(msg)
elif element.name != 'U':
msg = 'Unable to use enrichment for element {0} which is not ' \
'uranium for Material ID="{1}"'.format(element.name,
msg = 'Unable to use enrichment for element {} which is not ' \
'uranium for Material ID="{}"'.format(element.name,
self._id)
raise ValueError(msg)
@ -493,8 +506,8 @@ class Material(object):
cv.check_greater_than('enrichment', enrichment, 0., equality=True)
if enrichment > 5.0:
msg = 'A uranium enrichment of {0} was given for Material ID='\
'"{1}". OpenMC assumes the U234/U235 mass ratio is '\
msg = 'A uranium enrichment of {} was given for Material ID='\
'"{}". OpenMC assumes the U234/U235 mass ratio is '\
'constant at 0.008, which is only valid at low ' \
'enrichments. Consider setting the isotopic ' \
'composition manually for enrichments over 5%.'.\
@ -514,7 +527,7 @@ class Material(object):
"""
if not isinstance(element, openmc.Element):
msg = 'Unable to remove "{0}" in Material ID="{1}" ' \
msg = 'Unable to remove "{}" in Material ID="{}" ' \
'since it is not an Element'.format(self.id, element)
raise ValueError(msg)
@ -534,13 +547,13 @@ class Material(object):
"""
if self._macroscopic is not None:
msg = 'Unable to add an S(a,b) table to Material ID="{0}" as a ' \
msg = 'Unable to add an S(a,b) table to Material ID="{}" as a ' \
'macroscopic data-set has already been added'.format(self._id)
raise ValueError(msg)
if not isinstance(name, string_types):
msg = 'Unable to add an S(a,b) table to Material ID="{0}" with a ' \
'non-string table name "{1}"'.format(self._id, name)
msg = 'Unable to add an S(a,b) table to Material ID="{}" with a ' \
'non-string table name "{}"'.format(self._id, name)
raise ValueError(msg)
new_name = openmc.data.get_thermal_name(name)
@ -758,6 +771,9 @@ class Material(object):
if len(self._name) > 0:
element.set("name", str(self._name))
if self._depletable:
element.set("depletable", "true")
# Create temperature XML subelement
if self.temperature is not None:
subelement = ET.SubElement(element, "temperature")

View file

@ -256,7 +256,7 @@ class MGXS(object):
clone._name = self.name
clone._rxn_type = self.rxn_type
clone._by_nuclide = self.by_nuclide
clone._nuclides = copy.deepcopy(self._nuclides)
clone._nuclides = copy.deepcopy(self._nuclides, memo)
clone._domain = self.domain
clone._domain_type = self.domain_type
clone._energy_groups = copy.deepcopy(self.energy_groups, memo)

View file

@ -1,4 +1,4 @@
from collections import Iterable
import copy
from numbers import Real, Integral
import os
@ -14,10 +14,17 @@ from openmc.checkvalue import check_type, check_value, check_greater_than, \
# Supported incoming particle MGXS angular treatment representations
_REPRESENTATIONS = ['isotropic', 'angle']
# Supported scattering angular distribution representations
_SCATTER_TYPES = ['tabular', 'legendre', 'histogram']
# List of MGXS indexing schemes
_XS_SHAPES = ["[G][G'][Order]", "[G]", "[G']", "[G][G']", "[DG]", "[DG][G]",
"[DG][G']", "[DG][G][G']"]
# Number of mu points for conversion between scattering formats
_NMU = 257
class XSdata(object):
"""A multi-group cross section data set providing all the
@ -185,6 +192,52 @@ class XSdata(object):
self._inverse_velocity = len(temperatures) * [None]
self._xs_shapes = None
def __deepcopy__(self, memo):
existing = memo.get(id(self))
# If this is the first time we have tried to copy this object, copy it
if existing is None:
clone = type(self).__new__(type(self))
clone._name = self.name
clone._energy_groups = copy.deepcopy(self.energy_groups, memo)
clone._num_delayed_groups = self.num_delayed_groups
clone._temperatures = copy.deepcopy(self.temperatures, memo)
clone._representation = self.representation
clone._atomic_weight_ratio = self._atomic_weight_ratio
clone._fissionable = self._fissionable
clone._scatter_format = self._scatter_format
clone._order = self._order
clone._num_polar = self._num_polar
clone._num_azimuthal = self._num_azimuthal
clone._total = copy.deepcopy(self._total, memo)
clone._absorption = copy.deepcopy(self._absorption, memo)
clone._scatter_matrix = copy.deepcopy(self._scatter_matrix, memo)
clone._multiplicity_matrix = \
copy.deepcopy(self._multiplicity_matrix, memo)
clone._fission = copy.deepcopy(self._fission, memo)
clone._nu_fission = copy.deepcopy(self._nu_fission, memo)
clone._prompt_nu_fission = \
copy.deepcopy(self._prompt_nu_fission, memo)
clone._delayed_nu_fission = \
copy.deepcopy(self._delayed_nu_fission, memo)
clone._kappa_fission = copy.deepcopy(self._kappa_fission, memo)
clone._chi = copy.deepcopy(self._chi, memo)
clone._chi_prompt = copy.deepcopy(self._chi_prompt, memo)
clone._chi_delayed = copy.deepcopy(self._chi_delayed, memo)
clone._beta = copy.deepcopy(self._beta, memo)
clone._decay_rate = copy.deepcopy(self._decay_rate, memo)
clone._inverse_velocity = \
copy.deepcopy(self._inverse_velocity, memo)
clone._xs_shapes = copy.deepcopy(self._xs_shapes, memo)
memo[id(self)] = clone
return clone
# If this object has been copied before, return the first copy made
else:
return existing
@property
def name(self):
return self._name
@ -318,15 +371,14 @@ class XSdata(object):
@name.setter
def name(self, name):
check_type('name for XSdata', name, string_types)
self._name = name
@energy_groups.setter
def energy_groups(self, energy_groups):
# Check validity of energy_groups
check_type('energy_groups', energy_groups, openmc.mgxs.EnergyGroups)
if energy_groups.group_edges is None:
msg = 'Unable to assign an EnergyGroups object ' \
'with uninitialized group edges'
@ -337,7 +389,6 @@ class XSdata(object):
@num_delayed_groups.setter
def num_delayed_groups(self, num_delayed_groups):
# Check validity of num_delayed_groups
check_type('num_delayed_groups', num_delayed_groups, Integral)
check_less_than('num_delayed_groups', num_delayed_groups,
openmc.mgxs.MAX_DELAYED_GROUPS, equality=True)
@ -348,14 +399,12 @@ class XSdata(object):
@representation.setter
def representation(self, representation):
# Check it is of valid type.
check_value('representation', representation, _REPRESENTATIONS)
self._representation = representation
@atomic_weight_ratio.setter
def atomic_weight_ratio(self, atomic_weight_ratio):
# Check validity of type and that the atomic_weight_ratio value is > 0
check_type('atomic_weight_ratio', atomic_weight_ratio, Real)
check_greater_than('atomic_weight_ratio', atomic_weight_ratio, 0.0)
self._atomic_weight_ratio = atomic_weight_ratio
@ -369,14 +418,12 @@ class XSdata(object):
@scatter_format.setter
def scatter_format(self, scatter_format):
# check to see it is of a valid type and value
check_value('scatter_format', scatter_format, _SCATTER_TYPES)
self._scatter_format = scatter_format
@order.setter
def order(self, order):
# Check type and value
check_type('order', order, Integral)
check_greater_than('order', order, 0, equality=True)
self._order = order
@ -384,7 +431,6 @@ class XSdata(object):
@num_polar.setter
def num_polar(self, num_polar):
# Make sure we have positive ints
check_type('num_polar', num_polar, Integral)
check_greater_than('num_polar', num_polar, 0)
self._num_polar = num_polar
@ -1622,7 +1668,8 @@ class XSdata(object):
"""
check_type('inverse_velocity', inverse_velocity, openmc.mgxs.InverseVelocity)
check_type('inverse_velocity', inverse_velocity,
openmc.mgxs.InverseVelocity)
check_value('energy_groups', inverse_velocity.energy_groups,
[self.energy_groups])
check_value('domain_type', inverse_velocity.domain_type,
@ -1634,6 +1681,269 @@ class XSdata(object):
self._inverse_velocity[i] = inverse_velocity.get_xs(
nuclides=nuclide, xs_type=xs_type, subdomains=subdomain)
def convert_representation(self, target_representation, num_polar=None,
num_azimuthal=None):
"""Produce a new XSdata object with the same data, but converted to the
new representation (isotropic or angle-dependent).
This method cannot be used to change the number of polar or
azimuthal bins of an XSdata object that already uses an angular
representation. Finally, this method simply uses an arithmetic mean to
convert from an angular to isotropic representation; no flux-weighting
is applied and therefore reaction rates will not be preserved.
Parameters
----------
target_representation : {'isotropic', 'angle'}
Representation of the MGXS (isotropic or angle-dependent flux
weighting).
num_polar : int, optional
Number of equal width angular bins that the polar angular
domain is subdivided into. This is required when
:param:`target_representation` is "angle".
num_azimuthal : int, optional
Number of equal width angular bins that the azimuthal angular
domain is subdivided into. This is required when
:param:`target_representation` is "angle".
Returns
-------
openmc.XSdata
Multi-group cross section data with the same data as self, but
represented as specified in :param:`target_representation`.
"""
check_value('target_representation', target_representation,
_REPRESENTATIONS)
if target_representation == 'angle':
check_type('num_polar', num_polar, Integral)
check_type('num_azimuthal', num_azimuthal, Integral)
check_greater_than('num_polar', num_polar, 0)
check_greater_than('num_azimuthal', num_azimuthal, 0)
xsdata = copy.deepcopy(self)
# First handle the case where the current and requested
# representations are the same
if target_representation == self.representation:
# Check to make sure the num_polar and num_azimuthal values match
if target_representation == 'angle':
if num_polar != self.num_polar or num_azimuthal != self.num_azimuthal:
raise ValueError("Cannot translate between `angle`"
" representations with different angle"
" bin structures")
# Nothing to do as the same structure was requested
return xsdata
xsdata.representation = target_representation
# We have different actions depending on the representation conversion
if target_representation == 'isotropic':
# This is not needed for the correct functionality, but these
# values are changed back to None for clarity
xsdata._num_polar = None
xsdata._num_azimuthal = None
elif target_representation == 'angle':
xsdata.num_polar = num_polar
xsdata.num_azimuthal = num_azimuthal
# Reset xs_shapes so it is recalculated the next time it is needed
xsdata._xs_shapes = None
for i, temp in enumerate(xsdata.temperatures):
for xs in ['total', 'absorption', 'fission', 'nu_fission',
'scatter_matrix', 'multiplicity_matrix',
'prompt_nu_fission', 'delayed_nu_fission',
'kappa_fission', 'chi', 'chi_prompt', 'chi_delayed',
'beta', 'decay_rate', 'inverse_velocity']:
# Get the original data
orig_data = getattr(self, '_' + xs)[i]
if orig_data is not None:
if target_representation == 'isotropic':
# Since we are going from angle to isotropic, the
# current data is just the average over the angle bins
new_data = orig_data.mean(axis=(0, 1))
elif target_representation == 'angle':
# Since we are going from isotropic to angle, the
# current data is just copied for every angle bin
new_shape = (num_polar, num_azimuthal) + \
orig_data.shape
new_data = np.resize(orig_data, new_shape)
setter = getattr(xsdata, 'set_' + xs)
setter(new_data, temp)
return xsdata
def convert_scatter_format(self, target_format, target_order=None):
"""Produce a new MGXSLibrary object with the same data, but converted
to the new scatter format and order
Parameters
----------
target_format : {'tabular', 'legendre', 'histogram'}
Representation of the scattering angle distribution
target_order : int
Either the Legendre target_order, number of bins, or number of
points used to describe the angular distribution associated with
each group-to-group transfer probability
Returns
-------
openmc.XSdata
Multi-group cross section data with the same data as in self, but
represented as specified in :param:`target_format`.
"""
from scipy.interpolate import interp1d
from scipy.integrate import simps
from scipy.special import eval_legendre
check_value('target_format', target_format, _SCATTER_TYPES)
check_type('target_order', target_order, Integral)
if target_format == 'legendre':
check_greater_than('target_order', target_order, 0, equality=True)
else:
check_greater_than('target_order', target_order, 0)
xsdata = copy.deepcopy(self)
xsdata.scatter_format = target_format
xsdata.order = target_order
# Reset and re-generate XSdata.xs_shapes with the new scattering format
xsdata._xs_shapes = None
for i, temp in enumerate(xsdata.temperatures):
orig_data = self._scatter_matrix[i]
new_shape = orig_data.shape[:-1] + (xsdata.num_orders,)
new_data = np.zeros(new_shape)
if self.scatter_format == 'legendre':
if target_format == 'legendre':
# Then we are changing orders and only need to change
# dimensionality of the mu data and pad/truncate as needed
order = min(xsdata.num_orders, self.num_orders)
new_data[..., :order] = orig_data[..., :order]
elif target_format == 'tabular':
mu = np.linspace(-1, 1, xsdata.num_orders)
# Evaluate the legendre on the mu grid
for imu in range(len(mu)):
new_data[..., imu] = \
np.sum((l + 0.5) * eval_legendre(l, mu[imu]) *
orig_data[..., l]
for l in range(self.num_orders))
elif target_format == 'histogram':
# This code uses the vectorized integration capabilities
# instead of having an isotropic and angle representation
# path.
# Set the histogram mu grid
mu = np.linspace(-1, 1, xsdata.num_orders + 1)
# For every bin perform simpson integration of a finely
# sampled orig_data
for h_bin in range(xsdata.num_orders):
mu_fine = np.linspace(mu[h_bin], mu[h_bin + 1], _NMU)
table_fine = np.zeros(new_data.shape[:-1] + (_NMU,))
for imu in range(len(mu_fine)):
table_fine[..., imu] = \
np.sum((l + 0.5) *
eval_legendre(l, mu_fine[imu]) *
orig_data[..., l]
for l in range(self.num_orders))
new_data[..., h_bin] = simps(table_fine, mu_fine)
elif self.scatter_format == 'tabular':
# Calculate the mu points of the current data
mu_self = np.linspace(-1, 1, self.num_orders)
if target_format == 'legendre':
# Find the Legendre coefficients via integration. To best
# use the vectorized integration capabilities of scipy,
# this is done with fixed sample integration routines.
mu_fine = np.linspace(-1, 1, _NMU)
y = [interp1d(mu_self, orig_data)(mu_fine) *
eval_legendre(l, mu_fine)
for l in range(xsdata.num_orders)]
for l in range(xsdata.num_orders):
new_data[..., l] = simps(y[l], mu_fine)
elif target_format == 'tabular':
# Simply use an interpolating function to get the new data
mu = np.linspace(-1, 1, xsdata.num_orders)
new_data[..., :] = interp1d(mu_self, orig_data)(mu)
elif target_format == 'histogram':
# Use an interpolating function to do the bin-wise
# integrals
mu = np.linspace(-1, 1, xsdata.num_orders + 1)
# Like the tabular -> legendre path above, this code will
# be written to utilize the vectorized integration
# capabilities instead of having an isotropic and
# angle representation path.
interp = interp1d(mu_self, orig_data)
for h_bin in range(xsdata.num_orders):
mu_fine = np.linspace(mu[h_bin], mu[h_bin + 1], _NMU)
new_data[..., h_bin] = simps(interp(mu_fine), mu_fine)
elif self.scatter_format == 'histogram':
# The histogram format does not have enough information to
# convert to the other forms without inducing some amount of
# error. We will make the assumption that the center of the bin
# has the value of the bin. The mu=-1 and 1 points will be
# extrapolated from the shape.
mu_midpoint = np.linspace(-1, 1, self.num_orders,
endpoint=False)
mu_midpoint += (mu_midpoint[1] - mu_midpoint[0]) * 0.5
interp = interp1d(mu_midpoint, orig_data,
fill_value='extrapolate')
# Now get the distribution normalization factor to take from
# an integral quantity to a point-wise quantity
norm = float(self.num_orders) / 2.0
# We now have a tabular distribution in tab_data on mu_self.
# We now proceed just like the tabular branch above.
if target_format == 'legendre':
# find the legendre coefficients via integration. To best
# use the vectorized integration capabilities of scipy,
# this will be done with fixed sample integration routines.
mu_fine = np.linspace(-1, 1, _NMU)
y = [interp(mu_fine) * norm * eval_legendre(l, mu_fine)
for l in range(xsdata.num_orders)]
for l in range(xsdata.num_orders):
new_data[..., l] = simps(y[l], mu_fine)
elif target_format == 'tabular':
# Simply use an interpolating function to get the new data
mu = np.linspace(-1, 1, xsdata.num_orders)
new_data[..., :] = interp(mu) * norm
elif target_format == 'histogram':
# Use an interpolating function to do the bin-wise
# integrals
mu = np.linspace(-1, 1, xsdata.num_orders + 1)
# Like the tabular -> legendre path above, this code will
# be written to utilize the vectorized integration
# capabilities instead of having an isotropic and
# angle representation path.
for h_bin in range(xsdata.num_orders):
mu_fine = np.linspace(mu[h_bin], mu[h_bin + 1], _NMU)
new_data[..., h_bin] = \
norm * simps(interp(mu_fine), mu_fine)
# Remove small values resulting from numerical precision issues
new_data[..., np.abs(new_data) < 1.E-10] = 0.
xsdata.set_scatter_matrix(new_data, temp)
return xsdata
def to_hdf5(self, file):
"""Write XSdata to an HDF5 file
@ -1757,7 +2067,7 @@ class XSdata(object):
elif self.representation == 'angle':
matrix = \
self._scatter_matrix[i][p, a, g_in, :, 0]
elif self.scatter_format == 'histogram':
else:
if self.representation == 'isotropic':
matrix = \
np.sum(self._scatter_matrix[i][g_in, :, :],
@ -1995,6 +2305,24 @@ class MGXSLibrary(object):
self.num_delayed_groups = num_delayed_groups
self._xsdatas = []
def __deepcopy__(self, memo):
existing = memo.get(id(self))
# If this is the first time we have tried to copy this object, copy it
if existing is None:
clone = type(self).__new__(type(self))
clone._energy_groups = copy.deepcopy(self.energy_groups, memo)
clone._num_delayed_groups = self.num_delayed_groups
clone._xsdatas = copy.deepcopy(self.xsdatas, memo)
memo[id(self)] = clone
return clone
# If this object has been copied before, return the first copy made
else:
return existing
@property
def energy_groups(self):
return self._energy_groups
@ -2099,6 +2427,75 @@ class MGXSLibrary(object):
result = xsdata
return result
def convert_representation(self, target_representation, num_polar=None,
num_azimuthal=None):
"""Produce a new XSdata object with the same data, but converted to the
new representation (isotropic or angle-dependent).
This method cannot be used to change the number of polar or
azimuthal bins of an XSdata object that already uses an angular
representation. Finally, this method simply uses an arithmetic mean to
convert from an angular to isotropic representation; no flux-weighting
is applied and therefore the reaction rates will not be preserved.
Parameters
----------
target_representation : {'isotropic', 'angle'}
Representation of the MGXS (isotropic or angle-dependent flux
weighting).
num_polar : int, optional
Number of equal width angular bins that the polar angular
domain is subdivided into. This is required when
:param:`target_representation` is "angle".
num_azimuthal : int, optional
Number of equal width angular bins that the azimuthal angular
domain is subdivided into. This is required when
:param:`target_representation` is "angle".
Returns
-------
openmc.MGXSLibrary
Multi-group Library with the same data as self, but represented as
specified in :param:`target_representation`.
"""
library = copy.deepcopy(self)
for i, xsdata in enumerate(self.xsdatas):
library.xsdatas[i] = \
xsdata.convert_representation(target_representation,
num_polar, num_azimuthal)
return library
def convert_scatter_format(self, target_format, target_order):
"""Produce a new MGXSLibrary object with the same data, but converted
to the new scatter format and order
Parameters
----------
target_format : {'tabular', 'legendre', 'histogram'}
Representation of the scattering angle distribution
target_order : int
Either the Legendre target_order, number of bins, or number of
points used to describe the angular distribution associated with
each group-to-group transfer probability
Returns
-------
openmc.MGXSLibrary
Multi-group Library with the same data as self, but with the
scatter format represented as specified in :param:`target_format`
and :param:`target_order`.
"""
library = copy.deepcopy(self)
for i, xsdata in enumerate(self.xsdatas):
library.xsdatas[i] = \
xsdata.convert_scatter_format(target_format, target_order)
return library
def export_to_hdf5(self, filename='mgxs.h5'):
"""Create an hdf5 file that can be used for a simulation.

View file

@ -11,6 +11,9 @@ from openmc.clean_xml import clean_xml_indentation
import openmc.checkvalue as cv
from openmc import Nuclide, VolumeCalculation, Source, Mesh
_RUN_MODES = ['eigenvalue', 'fixed source', 'plot', 'volume',
'particle restart']
class Settings(object):
"""Settings used for an OpenMC simulation.
@ -81,7 +84,7 @@ class Settings(object):
The elastic scattering model to use for resonant isotopes
run_cmfd : bool
Indicate if coarse mesh finite difference acceleration is to be used
run_mode : {'eigenvalue' or 'fixed source'}
run_mode : {'eigenvalue', 'fixed source', 'plot', 'volume', 'particle restart'}
The type of calculation to perform (default is 'eigenvalue')
seed : int
Seed for the linear congruential pseudorandom number generator
@ -388,10 +391,7 @@ class Settings(object):
@run_mode.setter
def run_mode(self, run_mode):
if run_mode not in ['eigenvalue', 'fixed source']:
msg = 'Unable to set run mode to "{0}". Only "eigenvalue" ' \
'and "fixed source" are supported."'.format(run_mode)
raise ValueError(msg)
cv.check_value('run mode', run_mode, _RUN_MODES)
self._run_mode = run_mode
@batches.setter
@ -794,18 +794,8 @@ class Settings(object):
self._create_fission_neutrons = create_fission_neutrons
def _create_run_mode_subelement(self, root):
if self.run_mode == 'eigenvalue':
elem = ET.SubElement(root, "eigenvalue")
self._create_particles_subelement(elem)
self._create_batches_subelement(elem)
self._create_inactive_subelement(elem)
self._create_generations_per_batch_subelement(elem)
self._create_keff_trigger_subelement(elem)
else:
elem = ET.SubElement(root, "fixed_source")
self._create_particles_subelement(elem)
self._create_batches_subelement(elem)
elem = ET.SubElement(root, "run_mode")
elem.text = self._run_mode
def _create_batches_subelement(self, run_mode_element):
if self._batches is not None:
@ -814,8 +804,7 @@ class Settings(object):
def _create_generations_per_batch_subelement(self, run_mode_element):
if self._generations_per_batch is not None:
element = ET.SubElement(run_mode_element,
"generations_per_batch")
element = ET.SubElement(run_mode_element, "generations_per_batch")
element.text = str(self._generations_per_batch)
def _create_inactive_subelement(self, run_mode_element):
@ -1081,6 +1070,11 @@ class Settings(object):
root_element = ET.Element("settings")
self._create_run_mode_subelement(root_element)
self._create_particles_subelement(root_element)
self._create_batches_subelement(root_element)
self._create_inactive_subelement(root_element)
self._create_generations_per_batch_subelement(root_element)
self._create_keff_trigger_subelement(root_element)
self._create_source_subelement(root_element)
self._create_output_subelement(root_element)
self._create_statepoint_subelement(root_element)

View file

@ -97,23 +97,25 @@ class Summary(object):
# Values - Material objects
self.materials = {}
for key in self._f['materials'].keys():
for key, group in self._f['materials'].items():
if key == 'n_materials':
continue
material_id = int(key.lstrip('material '))
index = self._f['materials'][key]['index'].value
name = self._f['materials'][key]['name'].value.decode()
density = self._f['materials'][key]['atom_density'].value
nuc_densities = self._f['materials'][key]['nuclide_densities'][...]
nuclides = self._f['materials'][key]['nuclides'].value
index = group['index'].value
name = group['name'].value.decode()
density = group['atom_density'].value
nuc_densities = group['nuclide_densities'][...]
nuclides = group['nuclides'].value
# Create the Material
material = openmc.Material(material_id=material_id, name=name)
material.depletable = bool(group.attrs['depletable'])
# Read the names of the S(a,b) tables for this Material and add them
if 'sab_names' in self._f['materials'][key]:
sab_tables = self._f['materials'][key]['sab_names'].value
if 'sab_names' in group:
sab_tables = group['sab_names'].value
for sab_table in sab_tables:
name = sab_table.decode()
material.add_s_alpha_beta(name)

View file

@ -22,6 +22,7 @@ contains
use cmfd_data, only: set_up_cmfd
use cmfd_solver, only: cmfd_solver_execute
use error, only: warning, fatal_error
use message_passing, only: master
! CMFD single processor on master
if (master) then
@ -90,13 +91,9 @@ contains
subroutine calc_fission_source()
use constants, only: CMFD_NOACCEL, ZERO, TWO
use global, only: cmfd, cmfd_coremap, master, entropy_on, current_batch
use string, only: to_str
#ifdef MPI
use global, only: mpi_err
use global, only: cmfd, cmfd_coremap, entropy_on, current_batch
use message_passing
#endif
use string, only: to_str
integer :: nx ! maximum number of cells in x direction
integer :: ny ! maximum number of cells in y direction
@ -202,7 +199,7 @@ contains
#ifdef MPI
! Broadcast full source to all procs
call MPI_BCAST(cmfd % cmfd_src, n, MPI_REAL8, 0, MPI_COMM_WORLD, mpi_err)
call MPI_BCAST(cmfd % cmfd_src, n, MPI_REAL8, 0, mpi_intracomm, mpi_err)
#endif
end subroutine calc_fission_source
@ -216,16 +213,11 @@ contains
use algorithm, only: binary_search
use constants, only: ZERO, ONE
use error, only: warning, fatal_error
use global, only: meshes, source_bank, work, n_user_meshes, cmfd, &
master
use global, only: meshes, source_bank, work, n_user_meshes, cmfd
use mesh_header, only: RegularMesh
use mesh, only: count_bank_sites, get_mesh_indices
use string, only: to_str
#ifdef MPI
use global, only: mpi_err
use message_passing
#endif
use string, only: to_str
logical, intent(in) :: new_weights ! calcualte new weights
@ -289,7 +281,7 @@ contains
! Broadcast weight factors to all procs
#ifdef MPI
call MPI_BCAST(cmfd % weightfactors, ng*nx*ny*nz, MPI_REAL8, 0, &
MPI_COMM_WORLD, mpi_err)
mpi_intracomm, mpi_err)
#endif
end if

View file

@ -15,6 +15,7 @@ contains
subroutine configure_cmfd()
use cmfd_header, only: allocate_cmfd
use message_passing, only: master
integer :: color ! color group of processor

View file

@ -301,10 +301,12 @@ contains
subroutine convergence(iter, innerits, iconv)
use constants, only: ONE, ZERO
use global, only: cmfd_power_monitor, master
use, intrinsic :: ISO_FORTRAN_ENV
use constants, only: ONE, ZERO
use global, only: cmfd_power_monitor
use message_passing, only: master
integer, intent(in) :: iter ! outer iteration number
integer, intent(in) :: innerits ! inner iteration nubmer
logical, intent(out) :: iconv ! convergence logical

View file

@ -424,7 +424,8 @@ module constants
MODE_FIXEDSOURCE = 1, & ! Fixed source mode
MODE_EIGENVALUE = 2, & ! K eigenvalue mode
MODE_PLOTTING = 3, & ! Plotting mode
MODE_PARTICLE = 4 ! Particle restart mode
MODE_PARTICLE = 4, & ! Particle restart mode
MODE_VOLUME = 5 ! Volume calculation mode
!=============================================================================
! CMFD CONSTANTS

View file

@ -1,8 +1,5 @@
module eigenvalue
#ifdef MPI
use message_passing
#endif
use algorithm, only: binary_search
use constants, only: ZERO
@ -11,6 +8,7 @@ module eigenvalue
use math, only: t_percentile
use mesh, only: count_bank_sites
use mesh_header, only: RegularMesh
use message_passing
use random_lcg, only: prn, set_particle_seed, advance_prn_seed
use string, only: to_str
@ -66,7 +64,7 @@ contains
#ifdef MPI
start = 0_8
call MPI_EXSCAN(n_bank, start, 1, MPI_INTEGER8, MPI_SUM, &
MPI_COMM_WORLD, mpi_err)
mpi_intracomm, mpi_err)
! While we would expect the value of start on rank 0 to be 0, the MPI
! standard says that the receive buffer on rank 0 is undefined and not
@ -76,7 +74,7 @@ contains
finish = start + n_bank
total = finish
call MPI_BCAST(total, 1, MPI_INTEGER8, n_procs - 1, &
MPI_COMM_WORLD, mpi_err)
mpi_intracomm, mpi_err)
#else
start = 0_8
@ -150,13 +148,13 @@ contains
! First do an exclusive scan to get the starting indices for
start = 0_8
call MPI_EXSCAN(index_temp, start, 1, MPI_INTEGER8, MPI_SUM, &
MPI_COMM_WORLD, mpi_err)
mpi_intracomm, mpi_err)
finish = start + index_temp
! Allocate space for bank_position if this hasn't been done yet
if (.not. allocated(bank_position)) allocate(bank_position(n_procs))
call MPI_ALLGATHER(start, 1, MPI_INTEGER8, bank_position, 1, &
MPI_INTEGER8, MPI_COMM_WORLD, mpi_err)
MPI_INTEGER8, mpi_intracomm, mpi_err)
#else
start = 0_8
finish = index_temp
@ -210,7 +208,7 @@ contains
if (neighbor /= rank) then
n_request = n_request + 1
call MPI_ISEND(temp_sites(index_local), int(n), MPI_BANK, neighbor, &
rank, MPI_COMM_WORLD, request(n_request), mpi_err)
rank, mpi_intracomm, request(n_request), mpi_err)
end if
! Increment all indices
@ -254,7 +252,7 @@ contains
n_request = n_request + 1
call MPI_IRECV(source_bank(index_local), int(n), MPI_BANK, &
neighbor, neighbor, MPI_COMM_WORLD, request(n_request), mpi_err)
neighbor, neighbor, mpi_intracomm, request(n_request), mpi_err)
else
! If the source sites are on this procesor, we can simply copy them
@ -379,7 +377,7 @@ contains
#ifdef MPI
! Combine values across all processors
call MPI_ALLREDUCE(keff_generation, k_generation(overall_gen), 1, &
MPI_REAL8, MPI_SUM, MPI_COMM_WORLD, mpi_err)
MPI_REAL8, MPI_SUM, mpi_intracomm, mpi_err)
#else
k_generation(overall_gen) = keff_generation
#endif
@ -565,7 +563,7 @@ contains
#ifdef MPI
! Send source fraction to all processors
n = product(ufs_mesh % dimension)
call MPI_BCAST(source_frac, n, MPI_REAL8, 0, MPI_COMM_WORLD, mpi_err)
call MPI_BCAST(source_frac, n, MPI_REAL8, 0, mpi_intracomm, mpi_err)
#endif
! Normalize to total weight to get fraction of source in each cell

View file

@ -3,9 +3,7 @@ module error
use, intrinsic :: ISO_FORTRAN_ENV
use constants
#ifdef MPI
use message_passing
#endif
implicit none
@ -139,7 +137,7 @@ contains
#ifdef MPI
! Abort MPI
call MPI_ABORT(MPI_COMM_WORLD, code, mpi_err)
call MPI_ABORT(mpi_intracomm, code, mpi_err)
#endif
! Abort program

View file

@ -1,17 +1,11 @@
module finalize
use global
use output, only: print_runtime, print_results, &
print_overlap_check, write_tallies
use tally, only: tally_statistics
#ifdef MPI
use message_passing
#endif
use hdf5_interface, only: hdf5_bank_t
use hdf5, only: h5tclose_f, h5close_f
use global
use hdf5_interface, only: hdf5_bank_t
use message_passing
implicit none
contains
@ -21,34 +15,10 @@ contains
! statistics and writing out tallies
!===============================================================================
subroutine finalize_run()
subroutine openmc_finalize()
integer :: hdf5_err
! Start finalization timer
call time_finalize%start()
if (run_mode /= MODE_PLOTTING .and. run_mode /= MODE_PARTICLE) then
! Calculate statistics for tallies and write to tallies.out
if (master) then
if (n_realizations > 1) call tally_statistics()
end if
if (output_tallies) then
if (master) call write_tallies()
end if
if (check_overlaps) call reduce_overlap_count()
end if
! Stop timers and show timing statistics
call time_finalize%stop()
call time_total%stop()
if (master .and. (run_mode /= MODE_PLOTTING .and. &
run_mode /= MODE_PARTICLE)) then
call print_runtime()
call print_results()
if (check_overlaps) call print_overlap_check()
end if
! Deallocate arrays
call free_memory()
@ -66,24 +36,6 @@ contains
call MPI_FINALIZE(mpi_err)
#endif
end subroutine finalize_run
!===============================================================================
! REDUCE_OVERLAP_COUNT accumulates cell overlap check counts to master
!===============================================================================
subroutine reduce_overlap_count()
#ifdef MPI
if (master) then
call MPI_REDUCE(MPI_IN_PLACE, overlap_check_cnt, n_cells, &
MPI_INTEGER8, MPI_SUM, 0, MPI_COMM_WORLD, mpi_err)
else
call MPI_REDUCE(overlap_check_cnt, overlap_check_cnt, n_cells, &
MPI_INTEGER8, MPI_SUM, 0, MPI_COMM_WORLD, mpi_err)
end if
#endif
end subroutine reduce_overlap_count
end subroutine openmc_finalize
end module finalize

View file

@ -267,21 +267,6 @@ module global
! ============================================================================
! PARALLEL PROCESSING VARIABLES
! The defaults set here for the number of processors, rank, and master and
! mpi_enabled flag are for when MPI is not being used at all, i.e. a serial
! run. In this case, these variables are still used at times.
integer :: n_procs = 1 ! number of processes
integer :: rank = 0 ! rank of process
logical :: master = .true. ! master process?
logical :: mpi_enabled = .false. ! is MPI in use and initialized?
integer :: mpi_err ! MPI error code
#ifdef MPIF08
type(MPI_Datatype) :: MPI_BANK
#else
integer :: MPI_BANK ! MPI datatype for fission bank
#endif
#ifdef _OPENMP
integer :: n_threads = NONE ! number of OpenMP threads
integer :: thread_id ! ID of a given thread

View file

@ -17,7 +17,7 @@ module hdf5_interface
use error, only: fatal_error
#ifdef PHDF5
use message_passing, only: MPI_COMM_WORLD, MPI_INFO_NULL
use message_passing, only: mpi_intracomm, MPI_INFO_NULL
#endif
implicit none
@ -124,10 +124,10 @@ contains
call h5pcreate_f(H5P_FILE_ACCESS_F, plist, hdf5_err)
#ifdef PHDF5
#ifdef MPIF08
call h5pset_fapl_mpio_f(plist, MPI_COMM_WORLD%MPI_VAL, &
call h5pset_fapl_mpio_f(plist, mpi_intracomm%MPI_VAL, &
MPI_INFO_NULL%MPI_VAL, hdf5_err)
#else
call h5pset_fapl_mpio_f(plist, MPI_COMM_WORLD, MPI_INFO_NULL, hdf5_err)
call h5pset_fapl_mpio_f(plist, mpi_intracomm, MPI_INFO_NULL, hdf5_err)
#endif
#endif
@ -174,10 +174,10 @@ contains
call h5pcreate_f(H5P_FILE_ACCESS_F, plist, hdf5_err)
#ifdef PHDF5
#ifdef MPIF08
call h5pset_fapl_mpio_f(plist, MPI_COMM_WORLD%MPI_VAL, &
call h5pset_fapl_mpio_f(plist, mpi_intracomm%MPI_VAL, &
MPI_INFO_NULL%MPI_VAL, hdf5_err)
#else
call h5pset_fapl_mpio_f(plist, MPI_COMM_WORLD, MPI_INFO_NULL, hdf5_err)
call h5pset_fapl_mpio_f(plist, mpi_intracomm, MPI_INFO_NULL, hdf5_err)
#endif
#endif

View file

@ -1,5 +1,12 @@
module initialize
use, intrinsic :: ISO_C_BINDING, only: c_loc
use hdf5
#ifdef _OPENMP
use omp_lib
#endif
use bank_header, only: Bank
use constants
use dict_header, only: DictIntInt, ElemKeyValueII
@ -15,6 +22,7 @@ module initialize
hdf5_integer8_t
use input_xml, only: read_input_xml, cells_in_univ_dict, read_plots_xml
use material_header, only: Material
use message_passing
use mgxs_data, only: read_mgxs, create_macro_xs
use output, only: title, header, print_version, write_message, &
print_usage, print_plot
@ -27,30 +35,23 @@ module initialize
use tally_filter
use tally, only: init_tally_routines
#ifdef MPI
use message_passing
#endif
#ifdef _OPENMP
use omp_lib
#endif
use hdf5
use, intrinsic :: ISO_C_BINDING, only: c_loc
implicit none
contains
!===============================================================================
! INITIALIZE_RUN takes care of all initialization tasks, i.e. reading
! OPENMC_INIT takes care of all initialization tasks, i.e. reading
! from command line, reading xml input files, initializing random
! number seeds, reading cross sections, initializing starting source,
! setting up timers, etc.
!===============================================================================
subroutine initialize_run()
subroutine openmc_init(intracomm)
#ifdef MPIF08
type(MPI_Comm), intent(in) :: intracomm ! MPI intracommunicator
#else
integer, intent(in), optional :: intracomm ! MPI intracommunicator
#endif
! Start total and initialization timer
call time_total%start()
@ -58,7 +59,7 @@ contains
#ifdef MPI
! Setup MPI
call initialize_mpi()
call initialize_mpi(intracomm)
#endif
! Initialize HDF5 interface
@ -155,7 +156,7 @@ contains
! Stop initialization timer
call time_initialize%stop()
end subroutine initialize_run
end subroutine openmc_init
#ifdef MPI
!===============================================================================
@ -164,7 +165,12 @@ contains
! each processor.
!===============================================================================
subroutine initialize_mpi()
subroutine initialize_mpi(intracomm)
#ifdef MPIF08
type(MPI_Comm), intent(in) :: intracomm ! MPI intracommunicator
#else
integer, intent(in) :: intracomm ! MPI intracommunicator
#endif
integer :: bank_blocks(5) ! Count for each datatype
#ifdef MPIF08
@ -182,8 +188,9 @@ contains
call MPI_INIT(mpi_err)
! Determine number of processors and rank of each processor
call MPI_COMM_SIZE(MPI_COMM_WORLD, n_procs, mpi_err)
call MPI_COMM_RANK(MPI_COMM_WORLD, rank, mpi_err)
mpi_intracomm = intracomm
call MPI_COMM_SIZE(mpi_intracomm, n_procs, mpi_err)
call MPI_COMM_RANK(mpi_intracomm, rank, mpi_err)
! Determine master
if (rank == 0) then

View file

@ -15,6 +15,7 @@ module input_xml
use hdf5_interface
use list_header, only: ListChar, ListInt, ListReal
use mesh_header, only: RegularMesh
use message_passing
use mgxs_data, only: create_macro_xs, read_mgxs
use multipole, only: multipole_read
use output, only: write_message
@ -78,7 +79,6 @@ contains
integer :: temp_int
integer :: temp_int_array3(3)
integer, allocatable :: temp_int_array(:)
integer(8) :: temp_long
real(8), allocatable :: temp_real(:)
integer :: n_tracks
logical :: file_exists
@ -99,7 +99,6 @@ contains
type(Node), pointer :: node_res_scat => null()
type(Node), pointer :: node_scatterer => null()
type(Node), pointer :: node_trigger => null()
type(Node), pointer :: node_keff_trigger => null()
type(Node), pointer :: node_vol => null()
type(Node), pointer :: node_tab_leg => null()
type(NodeList), pointer :: node_scat_list => null()
@ -223,119 +222,62 @@ contains
end if
end if
! Make sure that either eigenvalue or fixed source was specified
if (.not. check_for_node(doc, "eigenvalue") .and. &
.not. check_for_node(doc, "fixed_source")) then
call fatal_error("<eigenvalue> or <fixed_source> not specified.")
end if
! Check run mode if it hasn't been set from the command line
if (run_mode == NONE) then
if (check_for_node(doc, "run_mode")) then
call get_node_value(doc, "run_mode", temp_str)
select case (to_lower(temp_str))
case ("eigenvalue")
run_mode = MODE_EIGENVALUE
case ("fixed source")
run_mode = MODE_FIXEDSOURCE
case ("plot")
run_mode = MODE_PLOTTING
case ("particle restart")
run_mode = MODE_PARTICLE
case ("volume")
run_mode = MODE_VOLUME
end select
! Eigenvalue information
if (check_for_node(doc, "eigenvalue")) then
! Set run mode
if (run_mode == NONE) run_mode = MODE_EIGENVALUE
! Assume XML specifics <particles>, <batches>, etc. directly
node_mode => doc
else
call warning("<run_mode> should be specified.")
! Get pointer to eigenvalue XML block
call get_node_ptr(doc, "eigenvalue", node_mode)
! Check number of particles
if (.not. check_for_node(node_mode, "particles")) then
call fatal_error("Need to specify number of particles per generation.")
end if
! Get number of particles
call get_node_value(node_mode, "particles", temp_long)
! If the number of particles was specified as a command-line argument, we
! don't set it here
if (n_particles == 0) n_particles = temp_long
! Get number of basic batches
call get_node_value(node_mode, "batches", n_batches)
if (.not. trigger_on) then
n_max_batches = n_batches
end if
! Get number of inactive batches
call get_node_value(node_mode, "inactive", n_inactive)
n_active = n_batches - n_inactive
if (check_for_node(node_mode, "generations_per_batch")) then
call get_node_value(node_mode, "generations_per_batch", gen_per_batch)
end if
! Allocate array for batch keff and entropy
allocate(k_generation(n_max_batches*gen_per_batch))
allocate(entropy(n_max_batches*gen_per_batch))
entropy = ZERO
! Get the trigger information for keff
if (check_for_node(node_mode, "keff_trigger")) then
call get_node_ptr(node_mode, "keff_trigger", node_keff_trigger)
if (check_for_node(node_keff_trigger, "type")) then
call get_node_value(node_keff_trigger, "type", temp_str)
temp_str = trim(to_lower(temp_str))
select case (temp_str)
case ('std_dev')
keff_trigger % trigger_type = STANDARD_DEVIATION
case ('variance')
keff_trigger % trigger_type = VARIANCE
case ('rel_err')
keff_trigger % trigger_type = RELATIVE_ERROR
case default
call fatal_error("Unrecognized keff trigger type " // temp_str)
end select
else
call fatal_error("Specify keff trigger type in settings XML")
! Make sure that either eigenvalue or fixed source was specified
if (.not. check_for_node(doc, "eigenvalue") .and. &
.not. check_for_node(doc, "fixed_source")) then
call fatal_error("<eigenvalue> or <fixed_source> not specified.")
end if
if (check_for_node(node_keff_trigger, "threshold")) then
call get_node_value(node_keff_trigger, "threshold", &
keff_trigger % threshold)
else
call fatal_error("Specify keff trigger threshold in settings XML")
if (check_for_node(doc, "eigenvalue")) then
! Set run mode
if (run_mode == NONE) run_mode = MODE_EIGENVALUE
! Get pointer to eigenvalue XML block
call get_node_ptr(doc, "eigenvalue", node_mode)
elseif (check_for_node(doc, "fixed_source")) then
! Set run mode
if (run_mode == NONE) run_mode = MODE_FIXEDSOURCE
! Get pointer to fixed_source XML block
call get_node_ptr(doc, "fixed_source", node_mode)
end if
end if
end if
! Fixed source calculation information
if (check_for_node(doc, "fixed_source")) then
! Set run mode
if (run_mode == NONE) run_mode = MODE_FIXEDSOURCE
if (run_mode == MODE_EIGENVALUE .or. run_mode == MODE_FIXEDSOURCE) then
! Read run parameters
call get_run_parameters(node_mode)
! Get pointer to fixed_source XML block
call get_node_ptr(doc, "fixed_source", node_mode)
! Check number of particles
if (.not. check_for_node(node_mode, "particles")) then
call fatal_error("Need to specify number of particles per batch.")
! Check number of active batches, inactive batches, and particles
if (n_active <= 0) then
call fatal_error("Number of active batches must be greater than zero.")
elseif (n_inactive < 0) then
call fatal_error("Number of inactive batches must be non-negative.")
elseif (n_particles <= 0) then
call fatal_error("Number of particles must be greater than zero.")
end if
! Get number of particles
call get_node_value(node_mode, "particles", temp_long)
! If the number of particles was specified as a command-line argument, we
! don't set it here
if (n_particles == 0) n_particles = temp_long
! Copy batch information
call get_node_value(node_mode, "batches", n_batches)
if (.not. trigger_on) then
n_max_batches = n_batches
end if
n_active = n_batches
n_inactive = 0
gen_per_batch = 1
end if
! Check number of active batches, inactive batches, and particles
if (n_active <= 0) then
call fatal_error("Number of active batches must be greater than zero.")
elseif (n_inactive < 0) then
call fatal_error("Number of inactive batches must be non-negative.")
elseif (n_particles <= 0) then
call fatal_error("Number of particles must be greater than zero.")
end if
! Copy random number seed if specified
@ -379,7 +321,10 @@ contains
! Get point to list of <source> elements and make sure there is at least one
call get_node_list(doc, "source", node_source_list)
n = get_list_size(node_source_list)
if (n == 0) call fatal_error("No source specified in settings XML file.")
if (run_mode == MODE_EIGENVALUE .or. run_mode == MODE_FIXEDSOURCE) then
if (n == 0) call fatal_error("No source specified in settings XML file.")
end if
! Allocate array for sources
allocate(external_source(n))
@ -1092,6 +1037,86 @@ contains
end subroutine read_settings_xml
!===============================================================================
! GET_RUN_PARAMETERS
!===============================================================================
subroutine get_run_parameters(node_base)
type(Node), pointer :: node_base
integer(8) :: temp_long
character(MAX_LINE_LEN) :: temp_str
type(Node), pointer :: node_keff_trigger => null()
! Check number of particles
if (.not. check_for_node(node_base, "particles")) then
call fatal_error("Need to specify number of particles.")
end if
! Get number of particles
call get_node_value(node_base, "particles", temp_long)
! If the number of particles was specified as a command-line argument, we
! don't set it here
if (n_particles == 0) n_particles = temp_long
! Get number of basic batches
call get_node_value(node_base, "batches", n_batches)
if (.not. trigger_on) then
n_max_batches = n_batches
end if
n_inactive = 0
gen_per_batch = 1
! Get number of inactive batches
if (run_mode == MODE_EIGENVALUE) then
call get_node_value(node_base, "inactive", n_inactive)
if (check_for_node(node_base, "generations_per_batch")) then
call get_node_value(node_base, "generations_per_batch", gen_per_batch)
end if
! Allocate array for batch keff and entropy
allocate(k_generation(n_max_batches*gen_per_batch))
allocate(entropy(n_max_batches*gen_per_batch))
entropy = ZERO
! Get the trigger information for keff
if (check_for_node(node_base, "keff_trigger")) then
call get_node_ptr(node_base, "keff_trigger", node_keff_trigger)
if (check_for_node(node_keff_trigger, "type")) then
call get_node_value(node_keff_trigger, "type", temp_str)
temp_str = trim(to_lower(temp_str))
select case (temp_str)
case ('std_dev')
keff_trigger % trigger_type = STANDARD_DEVIATION
case ('variance')
keff_trigger % trigger_type = VARIANCE
case ('rel_err')
keff_trigger % trigger_type = RELATIVE_ERROR
case default
call fatal_error("Unrecognized keff trigger type " // temp_str)
end select
else
call fatal_error("Specify keff trigger type in settings XML")
end if
if (check_for_node(node_keff_trigger, "threshold")) then
call get_node_value(node_keff_trigger, "threshold", &
keff_trigger % threshold)
else
call fatal_error("Specify keff trigger threshold in settings XML")
end if
end if
end if
! Determine number of active batches
n_active = n_batches - n_inactive
end subroutine get_run_parameters
!===============================================================================
! READ_GEOMETRY_XML reads data from a geometry.xml file and parses it, checking
! for errors and placing properly-formatted data in the right data structures
@ -2226,6 +2251,13 @@ contains
call fatal_error("Must specify id of material in materials XML file")
end if
! Check if material is depletable
if (check_for_node(node_mat, "depletable")) then
call get_node_value(node_mat, "depletable", temp_str)
if (to_lower(temp_str) == "true" .or. temp_str == "1") &
mat % depletable = .true.
end if
! Check to make sure 'id' hasn't been used
if (material_dict % has_key(mat % id)) then
call fatal_error("Two or more materials use the same unique ID: " &

View file

@ -1,17 +1,23 @@
program main
use constants
use finalize, only: finalize_run
use finalize, only: openmc_finalize
use global
use initialize, only: initialize_run
use initialize, only: openmc_init
use message_passing
use particle_restart, only: run_particle_restart
use plot, only: run_plot
use simulation, only: run_simulation
use volume_calc, only: run_volume_calculations
implicit none
! set up problem
call initialize_run()
! Initialize run -- when run with MPI, pass communicator
#ifdef MPI
call openmc_init(MPI_COMM_WORLD)
#else
call openmc_init()
#endif
! start problem based on mode
select case (run_mode)
@ -21,9 +27,11 @@ program main
call run_plot()
case (MODE_PARTICLE)
if (master) call run_particle_restart()
case (MODE_VOLUME)
call run_volume_calculations()
end select
! finalize run
call finalize_run()
call openmc_finalize()
end program main

View file

@ -31,8 +31,9 @@ module material_header
character(20), allocatable :: names(:) ! isotope names
character(20), allocatable :: sab_names(:) ! name of S(a,b) table
! Does this material contain fissionable nuclides?
! Does this material contain fissionable nuclides? Is it depletable?
logical :: fissionable = .false.
logical :: depletable = .false.
! enforce isotropic scattering in lab
logical, allocatable :: p0(:)

View file

@ -1,13 +1,10 @@
module mesh
#ifdef MPI
use message_passing
#endif
use algorithm, only: binary_search
use constants
use global
use mesh_header
use message_passing
implicit none
@ -207,17 +204,17 @@ contains
! collect values from all processors
if (master) then
call MPI_REDUCE(MPI_IN_PLACE, cnt, n, MPI_REAL8, MPI_SUM, 0, &
MPI_COMM_WORLD, mpi_err)
mpi_intracomm, mpi_err)
else
! Receive buffer not significant at other processors
call MPI_REDUCE(cnt, dummy, n, MPI_REAL8, MPI_SUM, 0, &
MPI_COMM_WORLD, mpi_err)
mpi_intracomm, mpi_err)
end if
! Check if there were sites outside the mesh for any processor
if (present(sites_outside)) then
call MPI_REDUCE(outside, sites_outside, 1, MPI_LOGICAL, MPI_LOR, 0, &
MPI_COMM_WORLD, mpi_err)
mpi_intracomm, mpi_err)
end if
#else

View file

@ -8,4 +8,21 @@ module message_passing
#endif
#endif
! The defaults set here for the number of processors, rank, and master and
! mpi_enabled flag are for when MPI is not being used at all, i.e. a serial
! run. In this case, these variables are still used at times.
integer :: n_procs = 1 ! number of processes
integer :: rank = 0 ! rank of process
logical :: master = .true. ! master process?
logical :: mpi_enabled = .false. ! is MPI in use and initialized?
integer :: mpi_err ! MPI error code
#ifdef MPIF08
type(MPI_Datatype) :: MPI_BANK ! MPI datatype for fission bank
type(MPI_Comm) :: mpi_intracomm ! MPI intra-communicator
#else
integer :: MPI_BANK ! MPI datatype for fission bank
integer :: mpi_intracomm ! MPI intra-communicator
#endif
end module message_passing

View file

@ -11,6 +11,7 @@ module output
use math, only: t_percentile
use mesh_header, only: RegularMesh
use mesh, only: mesh_indices_to_bin, bin_to_mesh_indices
use message_passing, only: master, n_procs
use nuclide_header
use particle_header, only: LocalCoord, Particle
use plot_header

View file

@ -9,6 +9,7 @@ module physics
use material_header, only: Material
use math
use mesh, only: get_mesh_indices
use message_passing
use nuclide_header
use output, only: write_message
use particle_header, only: Particle

View file

@ -9,6 +9,7 @@ module physics_mg
use math, only: rotate_angle
use mgxs_header, only: Mgxs, MgxsContainer
use mesh, only: get_mesh_indices
use message_passing
use output, only: write_message
use particle_header, only: Particle
use particle_restart_write, only: write_particle_restart

View file

@ -522,7 +522,7 @@ contains
gout = this % gmin(gin)
prob = this % energy(gin) % data(gout)
do while (prob < xi)
do while ((prob < xi) .and. (gout < this % gmax(gin)))
gout = gout + 1
prob = prob + this % energy(gin) % data(gout)
end do
@ -568,7 +568,7 @@ contains
gout = this % gmin(gin)
prob = this % energy(gin) % data(gout)
do while (prob < xi)
do while ((prob < xi) .and. (gout < this % gmax(gin)))
gout = gout + 1
prob = prob + this % energy(gin) % data(gout)
end do
@ -605,7 +605,7 @@ contains
gout = this % gmin(gin)
prob = this % energy(gin) % data(gout)
do while (prob < xi)
do while ((prob < xi) .and. (gout < this % gmax(gin)))
gout = gout + 1
prob = prob + this % energy(gin) % data(gout)
end do

View file

@ -1,9 +1,5 @@
module simulation
#ifdef MPI
use message_passing
#endif
use cmfd_execute, only: cmfd_init_batch, execute_cmfd
use constants, only: ZERO
use eigenvalue, only: count_source_for_ufs, calculate_average_keff, &
@ -13,14 +9,17 @@ module simulation
use eigenvalue, only: join_bank_from_threads
#endif
use global
use message_passing
use output, only: write_message, header, print_columns, &
print_batch_keff, print_generation
print_batch_keff, print_generation, print_runtime, &
print_results, print_overlap_check, write_tallies
use particle_header, only: Particle
use random_lcg, only: set_particle_seed
use source, only: initialize_source, sample_external_source
use state_point, only: write_state_point, write_source_point
use string, only: to_str
use tally, only: synchronize_tallies, setup_active_usertallies
use tally, only: synchronize_tallies, setup_active_usertallies, &
tally_statistics
use trigger, only: check_triggers
use tracking, only: transport
use volume_calc, only: run_volume_calculations
@ -42,9 +41,6 @@ contains
type(Particle) :: p
integer(8) :: i_work
! Volume calculations
if (size(volume_calcs) > 0) call run_volume_calculations()
if (.not. restart_run) call initialize_source()
! Display header
@ -116,6 +112,8 @@ contains
if (master) call header("SIMULATION FINISHED", level=1)
call finalize_simulation()
! Clear particle
call p % clear()
@ -322,7 +320,7 @@ contains
if (master) call check_triggers()
#ifdef MPI
call MPI_BCAST(satisfy_triggers, 1, MPI_LOGICAL, 0, &
MPI_COMM_WORLD, mpi_err)
mpi_intracomm, mpi_err)
#endif
if (satisfy_triggers .or. &
(trigger_on .and. current_batch == n_max_batches)) then
@ -382,4 +380,52 @@ contains
end subroutine replay_batch_history
!===============================================================================
! FINALIZE_SIMULATION calculates tally statistics, writes tallies, and displays
! execution time and results
!===============================================================================
subroutine finalize_simulation
! Start finalization timer
call time_finalize%start()
! Calculate statistics for tallies and write to tallies.out
if (master) then
if (n_realizations > 1) call tally_statistics()
end if
if (output_tallies) then
if (master) call write_tallies()
end if
if (check_overlaps) call reduce_overlap_count()
! Stop timers and show timing statistics
call time_finalize%stop()
call time_total%stop()
if (master) then
call print_runtime()
call print_results()
if (check_overlaps) call print_overlap_check()
end if
end subroutine finalize_simulation
!===============================================================================
! REDUCE_OVERLAP_COUNT accumulates cell overlap check counts to master
!===============================================================================
subroutine reduce_overlap_count()
#ifdef MPI
if (master) then
call MPI_REDUCE(MPI_IN_PLACE, overlap_check_cnt, n_cells, &
MPI_INTEGER8, MPI_SUM, 0, mpi_intracomm, mpi_err)
else
call MPI_REDUCE(overlap_check_cnt, overlap_check_cnt, n_cells, &
MPI_INTEGER8, MPI_SUM, 0, mpi_intracomm, mpi_err)
end if
#endif
end subroutine reduce_overlap_count
end module simulation

View file

@ -15,6 +15,7 @@ module source
use geometry_header, only: BASE_UNIVERSE
use global
use hdf5_interface, only: file_create, file_open, file_close, read_dataset
use message_passing, only: rank
use output, only: write_message
use particle_header, only: Particle
use random_lcg, only: prn, set_particle_seed, prn_set_stream

View file

@ -11,26 +11,22 @@ module state_point
! intervals, using the <state_point ... /> tag.
!===============================================================================
use, intrinsic :: ISO_C_BINDING, only: c_loc, c_ptr
use hdf5
use constants
use dict_header, only: ElemKeyValueII, ElemKeyValueCI
use endf, only: reaction_name
use error, only: fatal_error, warning
use global
use hdf5_interface
use mesh_header, only: RegularMesh
use message_passing
use output, only: write_message, time_stamp
use random_lcg, only: seed
use string, only: to_str, count_digits, zero_padded
use tally_header, only: TallyObject
use mesh_header, only: RegularMesh
use dict_header, only: ElemKeyValueII, ElemKeyValueCI
use random_lcg, only: seed
#ifdef MPI
use message_passing
#endif
use hdf5
use, intrinsic :: ISO_C_BINDING, only: c_loc, c_ptr
implicit none
@ -553,7 +549,7 @@ contains
! receive buffer without having a temporary variable
#ifdef MPI
call MPI_REDUCE(MPI_IN_PLACE, global_temp, n_bins, MPI_REAL8, MPI_SUM, &
0, MPI_COMM_WORLD, mpi_err)
0, mpi_intracomm, mpi_err)
#endif
! Transfer values to value on master
@ -567,7 +563,7 @@ contains
! Receive buffer not significant at other processors
#ifdef MPI
call MPI_REDUCE(global_temp, dummy, n_bins, MPI_REAL8, MPI_SUM, &
0, MPI_COMM_WORLD, mpi_err)
0, mpi_intracomm, mpi_err)
#endif
end if
@ -616,7 +612,7 @@ contains
! a receive buffer without having a temporary variable
#ifdef MPI
call MPI_REDUCE(MPI_IN_PLACE, tally_temp, n_bins, MPI_REAL8, &
MPI_SUM, 0, MPI_COMM_WORLD, mpi_err)
MPI_SUM, 0, mpi_intracomm, mpi_err)
#endif
! At the end of the simulation, store the results back in the
@ -640,7 +636,7 @@ contains
! Receive buffer not significant at other processors
#ifdef MPI
call MPI_REDUCE(tally_temp, dummy, n_bins, MPI_REAL8, MPI_SUM, &
0, MPI_COMM_WORLD, mpi_err)
0, mpi_intracomm, mpi_err)
#endif
end if
@ -940,7 +936,7 @@ contains
! Receive source sites from other processes
if (i > 0) then
call MPI_RECV(source_bank, int(dims(1)), MPI_BANK, i, i, &
MPI_COMM_WORLD, MPI_STATUS_IGNORE, mpi_err)
mpi_intracomm, MPI_STATUS_IGNORE, mpi_err)
end if
#endif
@ -969,7 +965,7 @@ contains
else
#ifdef MPI
call MPI_SEND(source_bank, int(work), MPI_BANK, 0, rank, &
MPI_COMM_WORLD, mpi_err)
mpi_intracomm, mpi_err)
#endif
end if

View file

@ -8,6 +8,7 @@ module summary
use hdf5_interface
use material_header, only: Material
use mesh_header, only: RegularMesh
use message_passing
use nuclide_header
use output, only: time_stamp
use surface_header
@ -535,6 +536,12 @@ contains
material_group = create_group(materials_group, "material " // &
trim(to_str(m%id)))
if (m % depletable) then
call write_attribute(material_group, "depletable", 1)
else
call write_attribute(material_group, "depletable", 0)
end if
! Write internal OpenMC index for this material
call write_dataset(material_group, "index", i)

View file

@ -2,10 +2,6 @@ module tally
use, intrinsic :: ISO_C_BINDING
#ifdef MPI
use message_passing
#endif
use algorithm, only: binary_search
use constants
use cross_section, only: multipole_deriv_eval
@ -18,6 +14,7 @@ module tally
mesh_intersects_1d, mesh_intersects_2d, &
mesh_intersects_3d
use mesh_header, only: RegularMesh
use message_passing
use output, only: header
use particle_header, only: LocalCoord, Particle
use string, only: to_str
@ -4073,14 +4070,14 @@ contains
! The MPI_IN_PLACE specifier allows the master to copy values into
! a receive buffer without having a temporary variable
call MPI_REDUCE(MPI_IN_PLACE, tally_temp, n_bins, MPI_REAL8, &
MPI_SUM, 0, MPI_COMM_WORLD, mpi_err)
MPI_SUM, 0, mpi_intracomm, mpi_err)
! Transfer values to value on master
t % results(RESULT_VALUE,:,:) = tally_temp
else
! Receive buffer not significant at other processors
call MPI_REDUCE(tally_temp, dummy, n_bins, MPI_REAL8, &
MPI_SUM, 0, MPI_COMM_WORLD, mpi_err)
MPI_SUM, 0, mpi_intracomm, mpi_err)
! Reset value on other processors
t % results(RESULT_VALUE,:,:) = ZERO
@ -4094,14 +4091,14 @@ contains
if (master) then
call MPI_REDUCE(MPI_IN_PLACE, global_temp, N_GLOBAL_TALLIES, &
MPI_REAL8, MPI_SUM, 0, MPI_COMM_WORLD, mpi_err)
MPI_REAL8, MPI_SUM, 0, mpi_intracomm, mpi_err)
! Transfer values back to global_tallies on master
global_tallies(RESULT_VALUE, :) = global_temp
else
! Receive buffer not significant at other processors
call MPI_REDUCE(global_temp, dummy, N_GLOBAL_TALLIES, &
MPI_REAL8, MPI_SUM, 0, MPI_COMM_WORLD, mpi_err)
MPI_REAL8, MPI_SUM, 0, mpi_intracomm, mpi_err)
! Reset value on other processors
global_tallies(RESULT_VALUE, :) = ZERO
@ -4111,11 +4108,11 @@ contains
! last realization
if (master) then
call MPI_REDUCE(MPI_IN_PLACE, total_weight, 1, MPI_REAL8, MPI_SUM, &
0, MPI_COMM_WORLD, mpi_err)
0, mpi_intracomm, mpi_err)
else
! Receive buffer not significant at other processors
call MPI_REDUCE(total_weight, dummy, 1, MPI_REAL8, MPI_SUM, &
0, MPI_COMM_WORLD, mpi_err)
0, mpi_intracomm, mpi_err)
end if
end subroutine reduce_tally_results

View file

@ -42,11 +42,11 @@ contains
function timer_get_value(self) result(elapsed)
class(Timer), intent(in) :: self ! the timer
real(8) :: elapsed ! total elapsed time
real(8) :: elapsed ! total elapsed time
integer(8) :: end_counts ! current number of counts
integer(8) :: count_rate ! system-dependent counting rate
real :: elapsed_time ! elapsed time since last start
real(8) :: elapsed_time ! elapsed time since last start
if (self % running) then
call system_clock(end_counts, count_rate)

View file

@ -8,6 +8,7 @@ module tracking
use geometry_header, only: Universe, BASE_UNIVERSE
use global
use output, only: write_message
use message_passing
use particle_header, only: LocalCoord, Particle
use physics, only: collision
use physics_mg, only: collision_mg

View file

@ -10,6 +10,7 @@ module trigger
use output, only: warning, write_message
use mesh, only: bin_to_mesh_indices
use mesh_header, only: RegularMesh
use message_passing, only: master
use trigger_header, only: TriggerObject
use tally, only: TallyObject
use tally_filter, only: MeshFilter

View file

@ -272,11 +272,11 @@ contains
if (master) then
#ifdef MPI
do j = 1, n_procs - 1
call MPI_RECV(n, 1, MPI_INTEGER, j, 0, MPI_COMM_WORLD, &
call MPI_RECV(n, 1, MPI_INTEGER, j, 0, mpi_intracomm, &
MPI_STATUS_IGNORE, mpi_err)
allocate(data(2*n))
call MPI_RECV(data, 2*n, MPI_INTEGER, j, 1, MPI_COMM_WORLD, &
call MPI_RECV(data, 2*n, MPI_INTEGER, j, 1, mpi_intracomm, &
MPI_STATUS_IGNORE, mpi_err)
do k = 0, n - 1
do m = 1, master_indices(i_domain) % size()
@ -340,8 +340,8 @@ contains
data(2*k + 2) = master_hits(i_domain) % data(k + 1)
end do
call MPI_SEND(n, 1, MPI_INTEGER, 0, 0, MPI_COMM_WORLD, mpi_err)
call MPI_SEND(data, 2*n, MPI_INTEGER, 0, 1, MPI_COMM_WORLD, mpi_err)
call MPI_SEND(n, 1, MPI_INTEGER, 0, 0, mpi_intracomm, mpi_err)
call MPI_SEND(data, 2*n, MPI_INTEGER, 0, 1, mpi_intracomm, mpi_err)
deallocate(data)
#endif
end if

View file

@ -205,11 +205,10 @@
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<eigenvalue>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
<source strength="1.0">
<space type="fission">
<parameters>-32 -32 0 32 32 32</parameters>

View file

@ -2,11 +2,10 @@
<settings>
<!-- Parameters for criticality calculation -->
<eigenvalue>
<batches>20</batches>
<inactive>10</inactive>
<particles>1000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>20</batches>
<inactive>10</inactive>
<particles>1000</particles>
<!-- How verbose output should be -->
<verbosity value="7" />
@ -19,7 +18,7 @@
</space>
</source>
<!-- Shannon Entropy -->
<!-- Shannon Entropy -->
<entropy>
<dimension> 10 1 1 </dimension>
<lower_left> -10.0 -1.0 -1.0 </lower_left>

View file

@ -2,11 +2,10 @@
<settings>
<!-- Parameters for criticality calculation -->
<eigenvalue>
<batches>20</batches>
<inactive>10</inactive>
<particles>1000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>20</batches>
<inactive>10</inactive>
<particles>1000</particles>
<!-- How verbose output should be -->
<verbosity value="7" />
@ -19,7 +18,7 @@
</space>
</source>
<!-- Shannon Entropy -->
<!-- Shannon Entropy -->
<entropy>
<dimension> 10 1 1 </dimension>
<lower_left> -10.0 -1.0 -1.0 </lower_left>

View file

@ -1,11 +1,10 @@
<?xml version="1.0"?>
<settings>
<eigenvalue>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
<source>
<space type="box">

View file

@ -3,11 +3,10 @@
<confidence_intervals>true</confidence_intervals>
<eigenvalue>
<batches>10</batches>
<inactive>2</inactive>
<particles>100</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>10</batches>
<inactive>2</inactive>
<particles>100</particles>
<source>
<space type="box">

View file

@ -18,10 +18,9 @@
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<fixed_source>
<particles>100</particles>
<batches>10</batches>
</fixed_source>
<run_mode>fixed source</run_mode>
<particles>100</particles>
<batches>10</batches>
<source strength="1.0">
<space type="box">
<parameters>-1 -1 -1 1 1 1</parameters>

View file

@ -1,11 +1,10 @@
<?xml version="1.0"?>
<settings>
<eigenvalue>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
<source>
<space type="box">

View file

@ -297,11 +297,10 @@
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<eigenvalue>
<particles>100</particles>
<batches>3</batches>
<inactive>0</inactive>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<particles>100</particles>
<batches>3</batches>
<inactive>0</inactive>
<source strength="1.0">
<space type="box">
<parameters>-160 -160 -183 160 160 183</parameters>

View file

@ -37,11 +37,10 @@
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<eigenvalue>
<particles>1000</particles>
<batches>5</batches>
<inactive>0</inactive>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<particles>1000</particles>
<batches>5</batches>
<inactive>0</inactive>
<source strength="1.0">
<space type="box">
<parameters>-1 -1 -1 1 1 1</parameters>

View file

@ -1,12 +1,11 @@
<?xml version="1.0"?>
<settings>
<eigenvalue>
<batches>7</batches>
<inactive>3</inactive>
<particles>1000</particles>
<generations_per_batch>3</generations_per_batch>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>7</batches>
<inactive>3</inactive>
<particles>1000</particles>
<generations_per_batch>3</generations_per_batch>
<source>
<space type="box">

View file

@ -1,11 +1,10 @@
<?xml version="1.0"?>
<settings>
<eigenvalue>
<batches>10</batches>
<inactive>0</inactive>
<particles>1000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>10</batches>
<inactive>0</inactive>
<particles>1000</particles>
<source>
<space type="box">

View file

@ -17,10 +17,9 @@
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<fixed_source>
<particles>100</particles>
<batches>10</batches>
</fixed_source>
<run_mode>fixed source</run_mode>
<particles>100</particles>
<batches>10</batches>
<source strength="1.0">
<space type="box">
<parameters>-1 -1 -1 1 1 1</parameters>

View file

@ -3,11 +3,10 @@
<log_grid_bins>20000</log_grid_bins>
<eigenvalue>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
<source>
<space type="box">

View file

@ -1,10 +1,9 @@
<?xml version="1.0"?>
<settings>
<eigenvalue>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
<source>
<space type="point" parameters="0. 0. 0." />
</source>

View file

@ -1,11 +1,10 @@
<?xml version="1.0"?>
<settings>
<eigenvalue>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
<source>
<space type="box">

View file

@ -1,11 +1,10 @@
<?xml version="1.0"?>
<settings>
<eigenvalue>
<batches>1</batches>
<inactive>0</inactive>
<particles>1000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>1</batches>
<inactive>0</inactive>
<particles>1000</particles>
<source>
<space type="box">

View file

@ -1,11 +1,10 @@
<?xml version="1.0"?>
<settings>
<eigenvalue>
<batches>1</batches>
<inactive>0</inactive>
<particles>1000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>1</batches>
<inactive>0</inactive>
<particles>1000</particles>
<source>
<space type="box">

View file

@ -1,11 +1,10 @@
<?xml version="1.0"?>
<settings>
<eigenvalue>
<batches>3</batches>
<inactive>0</inactive>
<particles>100</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>3</batches>
<inactive>0</inactive>
<particles>100</particles>
<source>
<space type="box">

View file

@ -1,13 +1,12 @@
<?xml version='1.0' encoding='utf-8'?>
<settings>
<eigenvalue>
<particles>1000</particles>
<batches>1</batches>
<inactive>0</inactive>
</eigenvalue>
<source>
<space type="box">
<parameters>-1 -1 -1 1 1 1</parameters>
</space>
</source>
<run_mode>eigenvalue</run_mode>
<particles>1000</particles>
<batches>1</batches>
<inactive>0</inactive>
<source>
<space type="box">
<parameters>-1 -1 -1 1 1 1</parameters>
</space>
</source>
</settings>

View file

@ -298,11 +298,10 @@
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<eigenvalue>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
<source strength="1.0">
<space type="box">
<parameters>-160 -160 -183 160 160 183</parameters>

View file

@ -297,11 +297,10 @@
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<eigenvalue>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
<source strength="1.0">
<space type="box">
<parameters>-160 -160 -183 160 160 183</parameters>

View file

@ -1,10 +1,9 @@
<?xml version="1.0"?>
<settings>
<fixed_source>
<batches>10</batches>
<particles>100</particles>
</fixed_source>
<run_mode>fixed source</run_mode>
<batches>10</batches>
<particles>100</particles>
<temperature_default>294</temperature_default>

View file

@ -1,11 +1,10 @@
<?xml version="1.0"?>
<settings>
<eigenvalue>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
<source>
<space type="box">

View file

@ -297,11 +297,10 @@
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<eigenvalue>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
<source strength="1.0">
<space type="box">
<parameters>-160 -160 -183 160 160 183</parameters>

View file

@ -10,11 +10,10 @@
===============================================================
-->
<eigenvalue>
<batches>10</batches>
<inactive>5</inactive>
<particles>100</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>10</batches>
<inactive>5</inactive>
<particles>100</particles>
<source>
<space type="box">

View file

@ -1,10 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<settings>
<eigenvalue>
<batches>10</batches>
<inactive>5</inactive>
<particles>500</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>10</batches>
<inactive>5</inactive>
<particles>500</particles>
<source>
<space type="box">

View file

@ -1,10 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<settings>
<eigenvalue>
<batches>10</batches>
<inactive>5</inactive>
<particles>500</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>10</batches>
<inactive>5</inactive>
<particles>500</particles>
<source>
<space type="box">

View file

@ -1,11 +1,10 @@
<?xml version="1.0"?>
<settings>
<eigenvalue>
<batches>10</batches>
<inactive>5</inactive>
<particles>100</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>10</batches>
<inactive>5</inactive>
<particles>100</particles>
<source>
<space type="box">

View file

@ -84,11 +84,10 @@
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<eigenvalue>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
<source strength="1.0">
<space type="box">
<parameters>0.0 0.0 0.0 10.0 10.0 5.0</parameters>

View file

@ -0,0 +1,29 @@
<?xml version='1.0' encoding='utf-8'?>
<geometry>
<cell id="1" material="1" name="cell 1" region="4 -5 6 -7" universe="0" />
<surface boundary="reflective" coeffs="-5.0" id="4" name="left" type="x-plane" />
<surface boundary="vacuum" coeffs="5.0" id="5" name="right" type="x-plane" />
<surface boundary="reflective" coeffs="-5.0" id="6" name="bottom" type="y-plane" />
<surface boundary="reflective" coeffs="5.0" id="7" name="top" type="y-plane" />
</geometry>
<?xml version='1.0' encoding='utf-8'?>
<materials>
<cross_sections>./mgxs.h5</cross_sections>
<material id="1" name="UO2 fuel">
<density units="macro" value="1.0" />
<macroscopic name="UO2" />
</material>
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<run_mode>eigenvalue</run_mode>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
<source strength="1.0">
<space type="box">
<parameters>-5 -5 -5 5 5 5</parameters>
</space>
</source>
<energy_mode>multi-group</energy_mode>
</settings>

View file

@ -0,0 +1,24 @@
k-combined:
9.930873E-01 2.221904E-03
k-combined:
9.948148E-01 1.216270E-03
k-combined:
9.930873E-01 2.221904E-03
k-combined:
9.755034E-01 6.178296E-03
k-combined:
9.738059E-01 4.529068E-03
k-combined:
9.866847E-01 9.485912E-03
k-combined:
9.755024E-01 6.179047E-03
k-combined:
9.738061E-01 4.529462E-03
k-combined:
9.866835E-01 9.485832E-03
k-combined:
9.719024E-01 4.213166E-03
k-combined:
9.930873E-01 2.221904E-03
k-combined:
9.930873E-01 2.221904E-03

View file

@ -0,0 +1,206 @@
#!/usr/bin/env python
import os
import sys
import hashlib
sys.path.insert(0, os.pardir)
import numpy as np
from testing_harness import PyAPITestHarness
import openmc
# OpenMC simulation parameters
batches = 10
inactive = 5
particles = 100
def build_mgxs_library(convert):
# Instantiate the energy group data
groups = openmc.mgxs.EnergyGroups(group_edges=[1e-5, 0.625, 20.0e6])
# Instantiate the 7-group (C5G7) cross section data
uo2_xsdata = openmc.XSdata('UO2', groups)
uo2_xsdata.order = 2
uo2_xsdata.set_total([2., 2.])
uo2_xsdata.set_absorption([1., 1.])
scatter_matrix = np.array([[[0.75, 0.25],
[0.00, 1.00]],
[[0.75 / 3., 0.25 / 3.],
[0.00 / 3., 1.00 / 3.]],
[[0.75 / 4., 0.25 / 4.],
[0.00 / 4., 1.00 / 4.]]])
scatter_matrix = np.rollaxis(scatter_matrix, 0, 3)
uo2_xsdata.set_scatter_matrix(scatter_matrix)
uo2_xsdata.set_fission([0.5, 0.5])
uo2_xsdata.set_nu_fission([1., 1.])
uo2_xsdata.set_chi([1., 0.])
mg_cross_sections_file = openmc.MGXSLibrary(groups)
mg_cross_sections_file.add_xsdatas([uo2_xsdata])
if convert is not None:
if isinstance(convert[0], list):
for conv in convert:
if conv[0] in ['legendre', 'tabular', 'histogram']:
mg_cross_sections_file = \
mg_cross_sections_file.convert_scatter_format(
conv[0], conv[1])
elif conv[0] in ['angle', 'isotropic']:
mg_cross_sections_file = \
mg_cross_sections_file.convert_representation(
conv[0], conv[1], conv[1])
elif convert[0] in ['legendre', 'tabular', 'histogram']:
mg_cross_sections_file = \
mg_cross_sections_file.convert_scatter_format(
convert[0], convert[1])
elif convert[0] in ['angle', 'isotropic']:
mg_cross_sections_file = \
mg_cross_sections_file.convert_representation(
convert[0], convert[1], convert[1])
mg_cross_sections_file.export_to_hdf5()
class MGXSTestHarness(PyAPITestHarness):
def _build_inputs(self):
# Instantiate some Macroscopic Data
uo2_data = openmc.Macroscopic('UO2')
# Instantiate some Materials and register the appropriate objects
mat = openmc.Material(material_id=1, name='UO2 fuel')
mat.set_density('macro', 1.0)
mat.add_macroscopic(uo2_data)
# Instantiate a Materials collection and export to XML
materials_file = openmc.Materials([mat])
materials_file.cross_sections = "./mgxs.h5"
materials_file.export_to_xml()
# Instantiate ZCylinder surfaces
left = openmc.XPlane(surface_id=4, x0=-5., name='left')
right = openmc.XPlane(surface_id=5, x0=5., name='right')
bottom = openmc.YPlane(surface_id=6, y0=-5., name='bottom')
top = openmc.YPlane(surface_id=7, y0=5., name='top')
left.boundary_type = 'reflective'
right.boundary_type = 'vacuum'
top.boundary_type = 'reflective'
bottom.boundary_type = 'reflective'
# Instantiate Cells
fuel = openmc.Cell(cell_id=1, name='cell 1')
# Use surface half-spaces to define regions
fuel.region = +left & -right & +bottom & -top
# Register Materials with Cells
fuel.fill = mat
# Instantiate Universe
root = openmc.Universe(universe_id=0, name='root universe')
# Register Cells with Universe
root.add_cells([fuel])
# Instantiate a Geometry, register the root Universe, and export to XML
geometry = openmc.Geometry(root)
geometry.export_to_xml()
settings_file = openmc.Settings()
settings_file.energy_mode = "multi-group"
settings_file.batches = batches
settings_file.inactive = inactive
settings_file.particles = particles
# Create an initial uniform spatial source distribution
bounds = [-5, -5, -5, 5, 5, 5]
uniform_dist = openmc.stats.Box(bounds[:3], bounds[3:])
settings_file.source = openmc.source.Source(space=uniform_dist)
settings_file.export_to_xml()
def _run_openmc(self):
# Run multiple conversions to compare results
cases = [['legendre', 2], ['legendre', 0],
['tabular', 33], ['histogram', 32],
[['tabular', 33], ['legendre', 1]],
[['tabular', 33], ['tabular', 3]],
[['tabular', 33], ['histogram', 32]],
[['histogram', 32], ['legendre', 1]],
[['histogram', 32], ['tabular', 3]],
[['histogram', 32], ['histogram', 16]],
['angle', 2], [['angle', 2], ['isotropic', None]]]
outstr = ''
for case in cases:
build_mgxs_library(case)
if self._opts.mpi_exec is not None:
mpi_args = [self._opts.mpi_exec, '-n', self._opts.mpi_np]
returncode = openmc.run(openmc_exec=self._opts.exe,
mpi_args=mpi_args)
else:
returncode = openmc.run(openmc_exec=self._opts.exe)
assert returncode == 0, 'OpenMC did not exit successfully.'
sp = openmc.StatePoint('statepoint.' + str(batches) + '.h5')
# Write out k-combined.
outstr += 'k-combined:\n'
form = '{0:12.6E} {1:12.6E}\n'
outstr += form.format(sp.k_combined[0], sp.k_combined[1])
sp.close()
return outstr
def _get_results(self, outstr, hash_output=False):
# Hash the results if necessary.
if hash_output:
sha512 = hashlib.sha512()
sha512.update(outstr.encode('utf-8'))
outstr = sha512.hexdigest()
return outstr
def _cleanup(self):
super(MGXSTestHarness, self)._cleanup()
f = os.path.join(os.getcwd(), 'mgxs.h5')
if os.path.exists(f):
os.remove(f)
def execute_test(self):
"""Build input XMLs, run OpenMC, and verify correct results."""
try:
self._build_inputs()
inputs = self._get_inputs()
self._write_inputs(inputs)
self._compare_inputs()
outstr = self._run_openmc()
results = self._get_results(outstr)
self._write_results(results)
self._compare_results()
finally:
self._cleanup()
def update_results(self):
"""Update results_true.dat and inputs_true.dat"""
try:
self._build_inputs()
inputs = self._get_inputs()
self._write_inputs(inputs)
self._overwrite_inputs()
outstr = self._run_openmc()
results = self._get_results(outstr)
self._write_results(results)
self._overwrite_results()
finally:
self._cleanup()
if __name__ == '__main__':
harness = MGXSTestHarness('statepoint.10.*', False)
harness.main()

View file

@ -0,0 +1,46 @@
<?xml version='1.0' encoding='utf-8'?>
<geometry>
<cell id="10000" material="10000" region="10000 -10001 10002 -10003 10004 -10005" universe="0" />
<cell id="10001" material="10001" region="10000 -10001 10002 -10003 10005 -10006" universe="0" />
<cell id="10002" material="10002" region="10000 -10001 10002 -10003 10006 -10007" universe="0" />
<surface boundary="reflective" coeffs="0.0" id="10000" type="x-plane" />
<surface boundary="reflective" coeffs="10.0" id="10001" type="x-plane" />
<surface boundary="reflective" coeffs="0.0" id="10002" type="y-plane" />
<surface boundary="reflective" coeffs="10.0" id="10003" type="y-plane" />
<surface boundary="reflective" coeffs="0.0" id="10004" type="z-plane" />
<surface coeffs="1.6667" id="10005" type="z-plane" />
<surface coeffs="3.3334" id="10006" type="z-plane" />
<surface boundary="reflective" coeffs="5.0" id="10007" type="z-plane" />
</geometry>
<?xml version='1.0' encoding='utf-8'?>
<materials>
<cross_sections>../1d_mgxs.h5</cross_sections>
<material id="10000" name="1">
<density units="macro" value="1.0" />
<macroscopic name="uo2_iso" />
</material>
<material id="10001" name="2">
<density units="macro" value="1.0" />
<macroscopic name="clad_iso" />
</material>
<material id="10002" name="3">
<density units="macro" value="1.0" />
<macroscopic name="lwtr_iso" />
</material>
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<run_mode>eigenvalue</run_mode>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
<source strength="1.0">
<space type="box">
<parameters>0.0 0.0 0.0 10.0 10.0 5.0</parameters>
</space>
</source>
<energy_mode>multi-group</energy_mode>
<tabular_legendre>
<enable>false</enable>
</tabular_legendre>
</settings>

View file

@ -0,0 +1,2 @@
k-combined:
1.110122E+00 2.549637E-02

View file

@ -0,0 +1,28 @@
#!/usr/bin/env python
import os
import sys
sys.path.insert(0, os.pardir)
from testing_harness import PyAPITestHarness
from input_set import MGInputSet
class MGMaxOrderTestHarness(PyAPITestHarness):
def __init__(self, statepoint_name, tallies_present, mg=False):
PyAPITestHarness.__init__(self, statepoint_name, tallies_present)
self._input_set = MGInputSet()
def _build_inputs(self):
"""Write input XML files."""
reps = ['iso']
self._input_set.build_default_materials_and_geometry(reps=reps)
self._input_set.build_default_settings()
# Enforce Legendre scattering
self._input_set.settings.tabular_legendre = {'enable': False}
self._input_set.export()
if __name__ == '__main__':
harness = MGMaxOrderTestHarness('statepoint.10.*', False, mg=True)
harness.main()

View file

@ -30,11 +30,10 @@
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<eigenvalue>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
<source strength="1.0">
<space type="box">
<parameters>0.0 0.0 0.0 10.0 10.0 5.0</parameters>

View file

@ -84,11 +84,10 @@
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<eigenvalue>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
<source strength="1.0">
<space type="box">
<parameters>0.0 0.0 0.0 10.0 10.0 5.0</parameters>

View file

@ -84,11 +84,10 @@
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<eigenvalue>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
<source strength="1.0">
<space type="box">
<parameters>0.0 0.0 0.0 10.0 10.0 5.0</parameters>

View file

@ -38,11 +38,10 @@
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<eigenvalue>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
<source strength="1.0">
<space type="fission">
<parameters>-0.63 -0.63 -1 0.63 0.63 1</parameters>

View file

@ -41,10 +41,9 @@ class MGXSTestHarness(PyAPITestHarness):
def _run_openmc(self):
# Initial run
if self._opts.mpi_exec is not None:
returncode = openmc.run(mpi_procs=self._opts.mpi_np,
openmc_exec=self._opts.exe,
mpi_exec=self._opts.mpi_exec)
mpi_args = [self._opts.mpi_exec, '-n', self._opts.mpi_np]
returncode = openmc.run(openmc_exec=self._opts.exe,
mpi_args=mpi_args)
else:
returncode = openmc.run(openmc_exec=self._opts.exe)
@ -72,12 +71,14 @@ class MGXSTestHarness(PyAPITestHarness):
if os.path.exists('./tallies.xml'):
os.remove('./tallies.xml')
# Close the statepoint to allow writing
sp.close()
# Re-run MG mode.
if self._opts.mpi_exec is not None:
returncode = openmc.run(mpi_procs=self._opts.mpi_np,
openmc_exec=self._opts.exe,
mpi_exec=self._opts.mpi_exec)
mpi_args = [self._opts.mpi_exec, '-n', self._opts.mpi_np]
returncode = openmc.run(openmc_exec=self._opts.exe,
mpi_args=mpi_args)
else:
returncode = openmc.run(openmc_exec=self._opts.exe)

View file

@ -38,11 +38,10 @@
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<eigenvalue>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
<source strength="1.0">
<space type="fission">
<parameters>-0.63 -0.63 -1 0.63 0.63 1</parameters>

View file

@ -65,11 +65,10 @@
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<eigenvalue>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
<source strength="1.0">
<space type="fission">
<parameters>-10.71 -10.71 -1 10.71 10.71 1</parameters>

View file

@ -38,11 +38,10 @@
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<eigenvalue>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
<source strength="1.0">
<space type="fission">
<parameters>-0.63 -0.63 -1 0.63 0.63 1</parameters>

View file

@ -297,11 +297,10 @@
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<eigenvalue>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
<source strength="1.0">
<space type="box">
<parameters>-160 -160 -183 160 160 183</parameters>

View file

@ -38,11 +38,10 @@
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<eigenvalue>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
<source strength="1.0">
<space type="fission">
<parameters>-0.63 -0.63 -1 0.63 0.63 1</parameters>

View file

@ -38,11 +38,10 @@
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<eigenvalue>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<particles>100</particles>
<batches>10</batches>
<inactive>5</inactive>
<source strength="1.0">
<space type="fission">
<parameters>-0.63 -0.63 -1 0.63 0.63 1</parameters>

View file

@ -34,11 +34,10 @@
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<eigenvalue>
<particles>1000</particles>
<batches>5</batches>
<inactive>0</inactive>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<particles>1000</particles>
<batches>5</batches>
<inactive>0</inactive>
<source strength="1.0">
<space type="box">
<parameters>-1 -1 -1 1 1 1</parameters>

View file

@ -3,11 +3,10 @@
<output summary="true" />
<eigenvalue>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
<source>
<space type="box">

View file

@ -1,11 +1,10 @@
<?xml version="1.0"?>
<settings>
<eigenvalue>
<batches>12</batches>
<inactive>5</inactive>
<particles>1200</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>12</batches>
<inactive>5</inactive>
<particles>1200</particles>
<source>
<space type="box">

View file

@ -1,10 +1,9 @@
<?xml version="1.0"?>
<settings>
<fixed_source>
<batches>12</batches>
<particles>1000</particles>
</fixed_source>
<run_mode>fixed source</run_mode>
<batches>12</batches>
<particles>1000</particles>
<source>
<space type="box">

View file

@ -25,11 +25,10 @@
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<eigenvalue>
<particles>1000</particles>
<batches>4</batches>
<inactive>0</inactive>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<particles>1000</particles>
<batches>4</batches>
<inactive>0</inactive>
<source strength="1.0">
<space type="box">
<parameters>-5.0 -5.0 -5.0 5.0 5.0 5.0</parameters>

View file

@ -1,11 +1,10 @@
<?xml version="1.0"?>
<settings>
<eigenvalue>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
<source>
<space type="box">

View file

@ -3,11 +3,10 @@
<ptables>false</ptables>
<eigenvalue>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
<source>
<space type="box">

View file

@ -1,11 +1,10 @@
<?xml version="1.0"?>
<settings>
<eigenvalue>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
<source>
<space type="point" parameters="0. 0. 0." />

View file

@ -1,11 +1,10 @@
<?xml version="1.0"?>
<settings>
<eigenvalue>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
</eigenvalue>
<run_mode>eigenvalue</run_mode>
<batches>10</batches>
<inactive>5</inactive>
<particles>1000</particles>
<source>
<space type="box">

Some files were not shown because too many files have changed in this diff Show more