From d311e06029a04bb21176c250a25eb0668c0dfb99 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 13 Mar 2017 10:00:41 -0500 Subject: [PATCH 1/8] Add physical units in user's guide, TallyDerivative link --- docs/source/pythonapi/index.rst | 1 + docs/source/usersguide/input.rst | 16 ++++++++++++++++ openmc/tally_derivative.py | 8 ++++---- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/docs/source/pythonapi/index.rst b/docs/source/pythonapi/index.rst index e9762c4f6..e845641e1 100644 --- a/docs/source/pythonapi/index.rst +++ b/docs/source/pythonapi/index.rst @@ -135,6 +135,7 @@ Constructing Tallies openmc.EnergyFunctionFilter openmc.Mesh openmc.Trigger + openmc.TallyDerivative openmc.Tally openmc.Tallies diff --git a/docs/source/usersguide/input.rst b/docs/source/usersguide/input.rst index b8629f180..e1775d364 100644 --- a/docs/source/usersguide/input.rst +++ b/docs/source/usersguide/input.rst @@ -87,6 +87,22 @@ be validated using the following command: /opt/openmc/bin/openmc-validate-xml +-------------- +Physical Units +-------------- + +Unless specified otherwise, all length quantities are assumed to be in units of +centimeters, all energy quantities are assumed to be in electronvolts, and all +time quantities are assumed to be in seconds. + +======= ============ ====== +Measure Default unit Symbol +======= ============ ====== +length centimeter cm +energy electronvolt eV +time second s +======= ============ ====== + -------------------------------------- Settings Specification -- settings.xml -------------------------------------- diff --git a/openmc/tally_derivative.py b/openmc/tally_derivative.py index 1c8a316cf..24187df84 100644 --- a/openmc/tally_derivative.py +++ b/openmc/tally_derivative.py @@ -23,12 +23,12 @@ class TallyDerivative(EqualityMixin): Parameters ---------- - derivative_id : Integral, optional + derivative_id : int, optional Unique identifier for the tally derivative. If none is specified, an identifier will automatically be assigned variable : str, optional Accepted values are 'density', 'nuclide_density', and 'temperature' - material : Integral, optional + material : int, optional The perturubed material ID nuclide : str, optional The perturbed nuclide. Only needed for 'nuclide_density' derivatives. @@ -36,11 +36,11 @@ class TallyDerivative(EqualityMixin): Attributes ---------- - id : Integral + id : int Unique identifier for the tally derivative variable : str Accepted values are 'density', 'nuclide_density', and 'temperature' - material : Integral + material : int The perturubed material ID nuclide : str The perturbed nuclide. Only needed for 'nuclide_density' derivatives. From 6f854d2dee8b72750665bfb5436b2d7b74603391 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 13 Mar 2017 13:54:59 -0500 Subject: [PATCH 2/8] Update openmc-voxel-to-silovtk --- scripts/openmc-voxel-to-silovtk | 70 ++++++++++++--------------------- 1 file changed, 26 insertions(+), 44 deletions(-) diff --git a/scripts/openmc-voxel-to-silovtk b/scripts/openmc-voxel-to-silovtk index 471047127..9748cc3bb 100755 --- a/scripts/openmc-voxel-to-silovtk +++ b/scripts/openmc-voxel-to-silovtk @@ -3,30 +3,24 @@ from __future__ import division, print_function import struct import sys +from argparse import ArgumentParser import numpy as np import h5py -def parse_options(): - """Process command line arguments""" - from optparse import OptionParser - usage = r"""%prog [options] """ - p = OptionParser(usage=usage) - p.add_option('-o', '--output', action='store', dest='output', - default='plot', help='Path to output SILO or VTK file.') - p.add_option('-v', '--vtk', action='store_true', dest='vtk', - default=False, help='Flag to convert to VTK instead of SILO.') - parsed = p.parse_args() - if not parsed[1]: - p.print_help() - return parsed - return parsed +def main(): + # Process command line arguments + parser = ArgumentParser() + parser.add_argument('voxel_file', help='Path to voxel file') + parser.add_argument('-o', '--output', action='store', + default='plot', help='Path to output SILO or VTK file.') + parser.add_argument('-s', '--silo', action='store_true', + default=False, help='Flag to convert to SILO instead of VTK.') + args = parser.parse_args() - -def main(filename, o): # Read data from voxel file - fh = h5py.File(filename, 'r') + fh = h5py.File(args.voxel_file, 'r') dimension = fh.attrs['num_voxels'] width = fh.attrs['voxel_width'] lower_left = fh.attrs['lower_left'] @@ -35,14 +29,8 @@ def main(filename, o): nx, ny, nz = dimension upper_right = lower_left + width*dimension - if o.vtk: - try: - import vtk - except: - print('The vtk python bindings do not appear to be installed ' - 'properly.\nOn Ubuntu: sudo apt install python-vtk\n' - 'See: http://www.vtk.org/') - return + if not args.silo: + import vtk grid = vtk.vtkImageData() grid.SetDimensions(nx+1, ny+1, nz+1) @@ -53,12 +41,12 @@ def main(filename, o): data.SetName("id") data.SetNumberOfTuples(nx*ny*nz) for x in range(nx): - sys.stdout.write(" {0}%\r".format(int(x/nx*100))) + sys.stdout.write(" {}%\r".format(int(x/nx*100))) sys.stdout.flush() for y in range(ny): for z in range(nz): i = z*nx*ny + y*nx + x - data.SetValue(i, voxel_data[x,y,z]) + data.SetValue(i, voxel_data[x, y, z]) grid.GetCellData().AddArray(data) writer = vtk.vtkXMLImageDataWriter() @@ -66,31 +54,27 @@ def main(filename, o): writer.SetInputData(grid) else: writer.SetInput(grid) - if not o.output.endswith(".vti"): - o.output += ".vti" - writer.SetFileName(o.output) + if not args.output.endswith(".vti"): + args.output += ".vti" + writer.SetFileName(args.output) writer.Write() else: - try: - import silomesh - except: - print('The silomesh package does not appear to be installed ' - 'properly.\nSee: https://github.com/nhorelik/silomesh/') - return - if not o.output.endswith(".silo"): - o.output += ".silo" - silomesh.init_silo(o.output) + import silomesh + + if not args.output.endswith(".silo"): + args.output += ".silo" + silomesh.init_silo(args.output) meshparams = list(map(int, dimension)) + list(map(float, lower_left)) + \ list(map(float, upper_right)) silomesh.init_mesh('plot', *meshparams) silomesh.init_var("id") for x in range(nx): - sys.stdout.write(" {0}%\r".format(int(x/nx*100))) + sys.stdout.write(" {}%\r".format(int(x/nx*100))) sys.stdout.flush() for y in range(ny): for z in range(nz): - silomesh.set_value(float(voxel_data[x,y,z]), + silomesh.set_value(float(voxel_data[x, y, z]), x + 1, y + 1, z + 1) print() silomesh.finalize_var() @@ -99,6 +83,4 @@ def main(filename, o): if __name__ == '__main__': - (options, args) = parse_options() - if args: - main(args[0], options) + main() From d938fa0176329c5abf510b44040363dd0d90e18f Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 15 Mar 2017 11:25:24 -0400 Subject: [PATCH 3/8] Fix bugs discovered during CNL workshop --- openmc/cell.py | 7 ++++--- openmc/geometry.py | 25 ++++++++++++++++--------- openmc/stats/multivariate.py | 3 ++- openmc/tally_derivative.py | 2 +- openmc/volume.py | 6 +++--- 5 files changed, 26 insertions(+), 17 deletions(-) diff --git a/openmc/cell.py b/openmc/cell.py index b578702bb..9993175ef 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -289,9 +289,10 @@ class Cell(object): c3, s3 = cos(phi), sin(phi) c2, s2 = cos(theta), sin(theta) c1, s1 = cos(psi), sin(psi) - return np.array([[c1*c2, c1*s2*s3 - c3*s1, s1*s3 + c1*c3*s2], - [c2*s1, c1*c3 + s1*s2*s3, c3*s1*s2 - c1*s3], - [-s2, c2*s3, c2*c3]]) + self._rotation_matrix = np.array([ + [c1*c2, c1*s2*s3 - c3*s1, s1*s3 + c1*c3*s2], + [c2*s1, c1*c3 + s1*s2*s3, c3*s1*s2 - c1*s3], + [-s2, c2*s3, c2*c3]]) @translation.setter def translation(self, translation): diff --git a/openmc/geometry.py b/openmc/geometry.py index 02bcbe180..598aa4312 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -361,18 +361,25 @@ class Geometry(object): if not case_sensitive: name = name.lower() - all_cells = self.get_all_cells().values() cells = set() - for cell in all_cells: - cell_fill_name = cell.fill.name - if not case_sensitive: - cell_fill_name = cell_fill_name.lower() + for cell in self.get_all_cells().values(): + names = [] + if cell.fill_type in ('material', 'universe', 'lattice'): + names.append(cell.fill.name) + elif cell.fill_type == 'distribmat': + for mat in cell.fill: + if mat is not None: + names.append(mat.name) - if cell_fill_name == name: - cells.add(cell) - elif not matching and name in cell_fill_name: - cells.add(cell) + for fill_name in names: + if not case_sensitive: + fill_name = fill_name.lower() + + if fill_name == name: + cells.add(cell) + elif not matching and name in fill_name: + cells.add(cell) cells = list(cells) cells.sort(key=lambda x: x.id) diff --git a/openmc/stats/multivariate.py b/openmc/stats/multivariate.py index ca25cf5fb..0ab11b7c5 100644 --- a/openmc/stats/multivariate.py +++ b/openmc/stats/multivariate.py @@ -54,7 +54,8 @@ class PolarAzimuthal(UnitSphere): """Angular distribution represented by polar and azimuthal angles This distribution allows one to specify the distribution of the cosine of - the polar angle and the azimuthal angle independently of once another. + the polar angle and the azimuthal angle independently of one another. The + polar angle is measured relative to the reference angle. Parameters ---------- diff --git a/openmc/tally_derivative.py b/openmc/tally_derivative.py index 24187df84..185e7ab6a 100644 --- a/openmc/tally_derivative.py +++ b/openmc/tally_derivative.py @@ -29,7 +29,7 @@ class TallyDerivative(EqualityMixin): variable : str, optional Accepted values are 'density', 'nuclide_density', and 'temperature' material : int, optional - The perturubed material ID + The perturbed material ID nuclide : str, optional The perturbed nuclide. Only needed for 'nuclide_density' derivatives. Ex: 'Xe135' diff --git a/openmc/volume.py b/openmc/volume.py index c9e1a5afa..6c4b130f9 100644 --- a/openmc/volume.py +++ b/openmc/volume.py @@ -246,9 +246,9 @@ class VolumeCalculation(object): results = type(self).from_hdf5(filename) # Make sure properties match - assert self.domains == results.domains - assert self.lower_left == results.lower_left - assert self.upper_right == results.upper_right + assert self.ids == results.ids + assert np.all(self.lower_left == results.lower_left) + assert np.all(self.upper_right == results.upper_right) # Copy results self.volumes = results.volumes From b08d0eb51ca896071d10f97423d0c3a0f2828570 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 17 Mar 2017 06:47:10 -0400 Subject: [PATCH 4/8] Remove unnecessary import in __init__.py. Fix MG env var doc --- openmc/__init__.py | 2 -- openmc/material.py | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/openmc/__init__.py b/openmc/__init__.py index b35538558..53fbec3f2 100644 --- a/openmc/__init__.py +++ b/openmc/__init__.py @@ -1,5 +1,3 @@ -import warnings - from openmc.arithmetic import * from openmc.cell import * from openmc.mesh import * diff --git a/openmc/material.py b/openmc/material.py index 92d992a6f..357753fa9 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -980,7 +980,7 @@ class Materials(cv.CheckedList): :envvar:`OPENMC_CROSS_SECTIONS` environment variable will be used for continuous-energy calculations and :envvar:`OPENMC_MG_CROSS_SECTIONS` will be used for multi-group - calculations to find the path to the XML cross section file. + calculations to find the path to the HDF5 cross section file. multipole_library : str Indicates the path to a directory containing a windowed multipole cross section library. If it is not set, the From 48135a59ab62438e6e3666a0d653c2dc6c2128bc Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 17 Mar 2017 07:06:07 -0400 Subject: [PATCH 5/8] Documentation/test fixes --- docs/source/devguide/workflow.rst | 43 +++++++++++++++++-------------- tests/run_tests.py | 7 +++++ 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/docs/source/devguide/workflow.rst b/docs/source/devguide/workflow.rst index a53bd114b..7a303f45e 100644 --- a/docs/source/devguide/workflow.rst +++ b/docs/source/devguide/workflow.rst @@ -37,9 +37,8 @@ In order to be considered suitable for inclusion in the *develop* branch, the following criteria must be satisfied for all proposed changes: - Changes have a clear purpose and are useful. -- Compiles under all conditions (MPI, OpenMP, HDF5, etc.). This is checked as - part of the test suite. -- Passes the regression suite. +- Compiles and passes the regression suite with all configurations (This is + checked by Travis CI). - If appropriate, test cases are added to regression suite. - No memory leaks (checked with valgrind_). - Conforms to the OpenMC `style guide`_. @@ -81,8 +80,7 @@ features and bug fixes. The general steps for contributing are as follows: At a minimum, you should describe what the changes you've made are and why you are making them. If the changes are related to an oustanding issue, make - sure it is cross-referenced. A wise developer would also check whether their - changes do indeed pass the regression test suite. + sure it is cross-referenced. 5. A trusted developer will review your pull request based on the criteria above. Any issues with the pull request can be discussed directly on the pull @@ -104,7 +102,7 @@ full OpenMC code is executed. Results from simulations are compared with expected results. The test suite is comprised of many build configurations (e.g. debug, mpi, hdf5) and the actual tests which reside in sub-directories in the tests directory. We recommend to developers to test their branches -before submitting a formal pull request using gfortran and intel compilers +before submitting a formal pull request using gfortran and Intel compilers if available. The test suite is designed to integrate with cmake using ctest_. @@ -113,9 +111,9 @@ download these cross sections please do the following: .. code-block:: sh - cd ../data - python get_nndc_data.py - export CROSS_SECTIONS=/nndc/cross_sections.xml + cd ../scripts + ./openmc-get-nndc-data + export OPENMC_CROSS_SECTIONS=/nndc_hdf5/cross_sections.xml The test suite can be run on an already existing build using: @@ -137,21 +135,29 @@ more control over which tests are executed. Before running the test suite python script, the following environmental variables should be set if the default paths are incorrect: - * **FC** - The command of the Fortran compiler (e.g. gfotran, ifort). + * **FC** - The command for a Fortran compiler (e.g. gfotran, ifort). * Default - *gfortran* + * **CC** - The command for a C compiler (e.g. gcc, icc). + + * Default - *gcc* + + * **CXX** - The command for a C++ compiler (e.g. g++, icpc). + + * Default - *g++* + * **MPI_DIR** - The path to the MPI directory. - * Default - */opt/mpich/3.1.3-gnu* + * Default - */opt/mpich/3.2-gnu* * **HDF5_DIR** - The path to the HDF5 directory. - * Default - */opt/hdf5/1.8.14-gnu* + * Default - */opt/hdf5/1.8.16-gnu* * **PHDF5_DIR** - The path to the parallel HDF5 directory. - * Default - */opt/phdf5/1.8.14-gnu* + * Default - */opt/phdf5/1.8.16-gnu* To run the full test suite, the following command can be executed in the tests directory: @@ -192,15 +198,12 @@ a test you need to add the following files to your new test directory, *test_name* for example: * OpenMC input XML files - * **test_name.py** - python test driver script, please refer to other + * **test_name.py** - Python test driver script, please refer to other tests to see how to construct. Any output files that are generated during testing must be removed at the end of this script. - * **results.py** - python script that extracts results from statepoint - output files. By default it should look for a binary file, but can - take an argument to overwrite which statepoint file is processed, - whether it is at a different batch or with an HDF5 extension. This - script must output a results file that is named *results_test.dat*. - It is recommended that any real numbers reported use *12.6E* format. + * **inputs_true.dat** - ASCII file that contains Python API-generated XML + files concatenated together. When the test is run, inputs that are + generated are compared to this file. * **results_true.dat** - ASCII file that contains the expected results from the test. The file *results_test.dat* is compared to this file during the execution of the python test driver script. When the diff --git a/tests/run_tests.py b/tests/run_tests.py index 28bedab0d..f0ecd8291 100755 --- a/tests/run_tests.py +++ b/tests/run_tests.py @@ -43,6 +43,7 @@ parser.add_option("-s", "--script", action="store_true", dest="script", # Default compiler paths FC='gfortran' CC='gcc' +CXX='g++' MPI_DIR='/opt/mpich/3.2-gnu' HDF5_DIR='/opt/hdf5/1.8.16-gnu' PHDF5_DIR='/opt/phdf5/1.8.16-gnu' @@ -55,6 +56,8 @@ if 'FC' in os.environ: FC = os.environ['FC'] if 'CC' in os.environ: CC = os.environ['CC'] +if 'CXX' in os.environ: + CXX = os.environ['CXX'] if 'MPI_DIR' in os.environ: MPI_DIR = os.environ['MPI_DIR'] if 'HDF5_DIR' in os.environ: @@ -162,9 +165,11 @@ class Test(object): else: self.fc = os.path.join(MPI_DIR, 'bin', 'mpif90') self.cc = os.path.join(MPI_DIR, 'bin', 'mpicc') + self.cxx = os.path.join(MPI_DIR, 'bin', 'mpicxx') else: self.fc = FC self.cc = CC + self.cxx = CXX # Sets the build name that will show up on the CDash def get_build_name(self): @@ -195,6 +200,7 @@ class Test(object): def run_ctest_script(self): os.environ['FC'] = self.fc os.environ['CC'] = self.cc + os.environ['CXX'] = self.cxx if self.mpi: os.environ['MPI_DIR'] = MPI_DIR if self.phdf5: @@ -210,6 +216,7 @@ class Test(object): def run_cmake(self): os.environ['FC'] = self.fc os.environ['CC'] = self.cc + os.environ['CXX'] = self.cxx if self.mpi: os.environ['MPI_DIR'] = MPI_DIR if self.phdf5: From 5adc5f63faf498846dc69bd203fa1d378e3e8bb9 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 17 Mar 2017 08:26:40 -0500 Subject: [PATCH 6/8] Add OpenMOC compatiblity module in documentation --- docs/source/pythonapi/index.rst | 22 ++++++++++++++++++++ docs/source/pythonapi/openmoc_compatible.rst | 8 ------- 2 files changed, 22 insertions(+), 8 deletions(-) delete mode 100644 docs/source/pythonapi/openmoc_compatible.rst diff --git a/docs/source/pythonapi/index.rst b/docs/source/pythonapi/index.rst index e845641e1..c23bf1921 100644 --- a/docs/source/pythonapi/index.rst +++ b/docs/source/pythonapi/index.rst @@ -470,6 +470,28 @@ Functions openmc.data.endf.get_tab2_record openmc.data.endf.get_text_record +--------------------------------------------------------- +:mod:`openmc.openmoc_compatible` -- OpenMOC Compatibility +--------------------------------------------------------- + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myfunction.rst + + openmc.openmoc_compatible.get_openmoc_material + openmc.openmoc_compatible.get_openmc_material + openmc.openmoc_compatible.get_openmoc_surface + openmc.openmoc_compatible.get_openmc_surface + openmc.openmoc_compatible.get_openmoc_cell + openmc.openmoc_compatible.get_openmc_cell + openmc.openmoc_compatible.get_openmoc_universe + openmc.openmoc_compatible.get_openmc_universe + openmc.openmoc_compatible.get_openmoc_lattice + openmc.openmoc_compatible.get_openmc_lattice + openmc.openmoc_compatible.get_openmoc_geometry + openmc.openmoc_compatible.get_openmc_geometry + .. _Jupyter: https://jupyter.org/ .. _NumPy: http://www.numpy.org/ .. _Codecademy: https://www.codecademy.com/tracks/python diff --git a/docs/source/pythonapi/openmoc_compatible.rst b/docs/source/pythonapi/openmoc_compatible.rst deleted file mode 100644 index bf353b96e..000000000 --- a/docs/source/pythonapi/openmoc_compatible.rst +++ /dev/null @@ -1,8 +0,0 @@ -.. _pythonapi_openmoc_compatible: - -===================== -OpenMOC Compatibility -===================== - -.. automodule:: openmc.openmoc_compatible - :members: From 5a116aedb30284b91555ea86bae1995e5a07c381 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 20 Mar 2017 06:24:19 -0500 Subject: [PATCH 7/8] Update missing label in documentation --- docs/source/methods/cross_sections.rst | 52 +++++++++++++------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/docs/source/methods/cross_sections.rst b/docs/source/methods/cross_sections.rst index b9043a944..9f677bac4 100644 --- a/docs/source/methods/cross_sections.rst +++ b/docs/source/methods/cross_sections.rst @@ -183,45 +183,43 @@ Multi-Group Data The data governing the interaction of particles with various nuclei or materials are represented using a multi-group library format specific to the OpenMC code. -The format is described in the :ref:`mgxs_lib_spec`. -The data itself can be prepared via traditional paths or directly from a -continuous-energy OpenMC calculation by use of the Python API as is shown in the -:ref:`notebook_mgxs_part_iv` example notebook. This multi-group -library consists of meta-data (such as the energy group structure) and multiple -`xsdata` objects which contains the required microscopic or macroscopic -multi-group data. +The format is described in the :ref:`mgxs_lib_spec`. The data itself can be +prepared via traditional paths or directly from a continuous-energy OpenMC +calculation by use of the Python API as is shown in the +:ref:`notebook_mg_mode_part_i` example notebook. This multi-group library +consists of meta-data (such as the energy group structure) and multiple `xsdata` +objects which contains the required microscopic or macroscopic multi-group data. At a minimum, the library must contain the absorption cross section (:math:`\sigma_{a,g}`) and a scattering matrix. If the problem is an eigenvalue -problem then all fissionable materials must also contain either -a fission production matrix cross section -(:math:`\nu\sigma_{f,g\rightarrow g'}`), or -both the fission spectrum data (:math:`\chi_{g'}`) and a fission production -cross section (:math:`\nu\sigma_{f,g}`), or, . The library must also contain -the fission cross section (:math:`\sigma_{f,g}`) or the fission energy release -cross section (:math:`\kappa\sigma_{f,g}`) if the associated tallies are -required by the model using the library. +problem then all fissionable materials must also contain either a fission +production matrix cross section (:math:`\nu\sigma_{f,g\rightarrow g'}`), or both +the fission spectrum data (:math:`\chi_{g'}`) and a fission production cross +section (:math:`\nu\sigma_{f,g}`), or, . The library must also contain the +fission cross section (:math:`\sigma_{f,g}`) or the fission energy release cross +section (:math:`\kappa\sigma_{f,g}`) if the associated tallies are required by +the model using the library. After a scattering collision, the outgoing particle experiences a change in both energy and angle. The probability of a particle resulting in a given outgoing -energy group (`g'`) given a certain incoming energy group (`g`) is provided -by the scattering matrix data. The angular information can be expressed either -via Legendre expansion of the particle's change-in-angle (:math:`\mu`), a -tabular representation of the probability distribution function of :math:`\mu`, -or a histogram representation of the same PDF. The formats used to -represent these are described in the :ref:`mgxs_lib_spec`. +energy group (`g'`) given a certain incoming energy group (`g`) is provided by +the scattering matrix data. The angular information can be expressed either via +Legendre expansion of the particle's change-in-angle (:math:`\mu`), a tabular +representation of the probability distribution function of :math:`\mu`, or a +histogram representation of the same PDF. The formats used to represent these +are described in the :ref:`mgxs_lib_spec`. Unlike the continuous-energy mode, the multi-group mode does not explicitly track particles produced from scattering multiplication (i.e., :math:`(n,xn)`) reactions. These are instead accounted for by adjusting the weight of the particle after the collision such that the correct total weight is maintained. The weight adjustment factor is optionally provided by the `multiplicity` data -which is required to be provided in the form of a group-wise matrix. -This data is provided as a group-wise matrix since the probability of producing -multiple particles in a scattering reaction depends on both the incoming energy, -`g`, and the sampled outgoing energy, `g'`. This data represents the average -number of particles emitted from a scattering reaction, given a scattering -reaction has occurred: +which is required to be provided in the form of a group-wise matrix. This data +is provided as a group-wise matrix since the probability of producing multiple +particles in a scattering reaction depends on both the incoming energy, `g`, and +the sampled outgoing energy, `g'`. This data represents the average number of +particles emitted from a scattering reaction, given a scattering reaction has +occurred: .. math:: From 033197a091feff8e6e4e13258b43eae7c0e3160a Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 21 Mar 2017 06:48:21 -0500 Subject: [PATCH 8/8] Sort as they are written to plots.xml --- openmc/plots.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openmc/plots.py b/openmc/plots.py index 2ba5d9758..cc2fcc4b6 100644 --- a/openmc/plots.py +++ b/openmc/plots.py @@ -636,7 +636,8 @@ class Plot(object): subelement.text = ' '.join(str(x) for x in color) if self._colors: - for domain, color in self._colors.items(): + for domain, color in sorted(self._colors.items(), + key=lambda x: x[0].id): subelement = ET.SubElement(element, "color") subelement.set("id", str(domain.id)) if isinstance(color, string_types):