diff --git a/docs/source/_templates/myfunction.rst b/docs/source/_templates/myfunction.rst new file mode 100644 index 000000000..4d7ea38a1 --- /dev/null +++ b/docs/source/_templates/myfunction.rst @@ -0,0 +1,6 @@ +{{ fullname }} +{{ underline }} + +.. currentmodule:: {{ module }} + +.. autofunction:: {{ objname }} diff --git a/docs/source/index.rst b/docs/source/index.rst index 54ba825e5..413107c34 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -13,11 +13,14 @@ OpenMC was originally developed by members of the `Computational Reactor Physics Group`_ at the `Massachusetts Institute of Technology`_ starting in 2011. Various universities, laboratories, and other organizations now contribute to the development of OpenMC. For more information on OpenMC, feel -free to send a message to the User's Group `mailing list`_. +free to send a message to the User's Group `mailing list`_. Documentation for +the latest developmental version of the develop branch can be found on +`Read the Docs`_. .. _Computational Reactor Physics Group: http://crpg.mit.edu .. _Massachusetts Institute of Technology: http://web.mit.edu .. _mailing list: https://groups.google.com/forum/?fromgroups=#!forum/openmc-users +.. _Read the Docs: http://openmc.readthedocs.io/en/latest/ .. only:: html @@ -34,6 +37,7 @@ free to send a message to the User's Group `mailing list`_. usersguide/index devguide/index pythonapi/index + io_formats/index publications license developers diff --git a/docs/source/io_formats/data_wmp.rst b/docs/source/io_formats/data_wmp.rst new file mode 100644 index 000000000..1e791d6c5 --- /dev/null +++ b/docs/source/io_formats/data_wmp.rst @@ -0,0 +1,92 @@ +.. _io_data_wmp: + +========================================== +The Windowed Multipole Library Format v0.2 +========================================== + +**/nuclide/** + - **broaden_poly** (*int[]*) + If 1, Doppler broaden curve fit for window with corresponding index. + If 0, do not. + - **curvefit** (*double[][][]*) + Curve fit coefficients. Indexed by (reaction type, coefficient index, + window index). + - **data** (*complex[][]*) + Complex poles and residues. Each pole has a corresponding set of + residues. For example, the `i`th pole and corresponding residues are + stored as `data[:,i] = [pole, residue_1, residue_2, ...]`. The + residues are in the order: total, competitive if present, absorption, + fission. Complex numbers are stored by forming a type with `"r"` and + `"i"` identifiers, similar to how `h5py` does it. + - **start_E** (*double*) + Lowest energy the windowed multipole part of the library is valid for. + - **end_E** (*double*) + Highest energy the windowed multipole part of the library is valid for. + - **energy_points** (*double[]*) + Energy grid for the pointwise library in the reaction group. + - **fissionable** (*int*) + 1 if this nuclide has fission data. 0 if it does not. + - **fit_order** (*int*) + The order of the curve fit. + - **formalism** (*int*) + The formalism of the underlying data. Uses the `ENDF-6`_ format + formalism numbers. + + .. table:: Table of supported formalisms. + + +-------------+------------------+ + | Formalism | Formalism number | + +=============+==================+ + | MLBW | 2 | + +-------------+------------------+ + | Reich-Moore | 3 | + +-------------+------------------+ + + - **l_value** (*int[]*) + The index for a corresponding pole. Equivalent to the :math:`l` quantum + number of the resonance the pole comes from :math:`+1`. + - **length** (*int*) + Total count of poles in `data`. + - **max_w** (*int*) + Maximum number of poles in a window. + - **MT_count** (*int*) + Number of pointwise tables in the library. + - **MT_list** (*int[]*) + A list of available MT identifiers. See `ENDF-6`_ for meaning. + - **n_grid** (*int*) + Total length of the pointwise data. + - **num_l** (*int*) + Number of possible :math:`l` quantum states for this nuclide. + - **pseudo_K0RS** (*double[]*) + :math:`l` dependent value of + + .. math:: + \sqrt{\frac{2 m_n}{\hbar}}\frac{AWR}{AWR + 1} r_{s,l} + + Where :math:`m_n` is mass of neutron, :math:`AWR` is the atomic weight + ratio of the target to the neutron, and :math:`r_{s,l}` is the + scattering radius for a given :math:`l`. + - **spacing** (*double*) + .. math:: + \frac{\sqrt{E_{max}}- \sqrt{E_{min}}}{n_w} + + Where :math:`E_{max}` is the maximum energy the windows go up to. This + is not equivalent to the maximum energy for which the windowed multipole + data is valid for. It is slightly higher to ensure an integer number of + windows. :math:`E_{min}` is the minimum energy and equivalent to + `start_E`, and :math:`n_w` is the number of windows, given by `windows`. + - **sqrtAWR** (*double*) + Square root of the atomic weight ratio. + - **w_start** (*int[]*) + The pole to start from for each window. + - **w_end** (*int[]*) + The pole to end at for each window. + - **windows** (*int*) + Number of windows. + +**/nuclide/reactions/MT** + - **MT_sigma** (*double[]*) -- Cross section value for this reaction. + - **Q_value** (*double*) -- Energy released in this reaction, in eV. + - **threshold** (*int*) -- The first non-zero entry in `MT_sigma`. + +.. _ENDF-6: https://www.oecd-nea.org/dbdata/data/manual-endf/endf102.pdf diff --git a/docs/source/usersguide/output/index.rst b/docs/source/io_formats/index.rst similarity index 55% rename from docs/source/usersguide/output/index.rst rename to docs/source/io_formats/index.rst index 31bd1da91..33c43df08 100644 --- a/docs/source/usersguide/output/index.rst +++ b/docs/source/io_formats/index.rst @@ -1,13 +1,15 @@ -.. _usersguide_output: +.. _io_file_formats: -=================== -Output File Formats -=================== +=============== +IO File Formats +=============== .. toctree:: :numbered: :maxdepth: 3 + data_wmp + mgxs_library statepoint source summary diff --git a/docs/source/usersguide/mgxs_library.rst b/docs/source/io_formats/mgxs_library.rst similarity index 97% rename from docs/source/usersguide/mgxs_library.rst rename to docs/source/io_formats/mgxs_library.rst index a5d2ec0d0..35addf15e 100644 --- a/docs/source/usersguide/mgxs_library.rst +++ b/docs/source/io_formats/mgxs_library.rst @@ -1,4 +1,4 @@ -.. _usersguide_mgxs_library: +.. _io_mgxs_library: ======================================== Multi-Group Cross Section Library Format @@ -8,10 +8,10 @@ OpenMC can be run in continuous-energy mode or multi-group mode, provided the nuclear data is available. In continuous-energy mode, the ``cross_sections.xml`` file contains necessary meta-data for each data set, including the name and a file system location where the complete library -can be found. In multi-group mode, this ``cross_sections.xml`` file contains +can be found. In multi-group mode, this ``mgxs.xml`` file contains this same meta-data describing the nuclide or material, but also contains the group-wise nuclear data. This portion of the manual describes the format of -the multi-group data library required to be used in the ``cross_sections.xml`` +the multi-group data library required to be used in the ``mgxs.xml`` file. Similar to the other input file types, the multi-group library is provided in @@ -22,9 +22,9 @@ materials. .. _XML: http://www.w3.org/XML/ ------------------------------------------------- -MGXS Library Specification -- cross_sections.xml ------------------------------------------------- +-------------------------------------- +MGXS Library Specification -- mgxs.xml +-------------------------------------- The multi-group library meta-data is contained within the groups_, group_structure_, and inverse_velocities_ elements. @@ -33,7 +33,7 @@ The actual multi-group data itself is contained within the xsdata_ element. .. _groups: ```` Element ----------------------------------- +-------------------- The ```` element has no attributes and simply provides the number of energy groups contained within the library. diff --git a/docs/source/usersguide/output/particle_restart.rst b/docs/source/io_formats/particle_restart.rst similarity index 97% rename from docs/source/usersguide/output/particle_restart.rst rename to docs/source/io_formats/particle_restart.rst index 70f00a930..c30eda318 100644 --- a/docs/source/usersguide/output/particle_restart.rst +++ b/docs/source/io_formats/particle_restart.rst @@ -1,4 +1,4 @@ -.. _usersguide_particle_restart: +.. _io_particle_restart: ============================ Particle Restart File Format diff --git a/docs/source/usersguide/output/source.rst b/docs/source/io_formats/source.rst similarity index 96% rename from docs/source/usersguide/output/source.rst rename to docs/source/io_formats/source.rst index 53841a5eb..a0a62afca 100644 --- a/docs/source/usersguide/output/source.rst +++ b/docs/source/io_formats/source.rst @@ -1,4 +1,4 @@ -.. _usersguide_source: +.. _io_source: ================== Source File Format diff --git a/docs/source/usersguide/output/statepoint.rst b/docs/source/io_formats/statepoint.rst similarity index 99% rename from docs/source/usersguide/output/statepoint.rst rename to docs/source/io_formats/statepoint.rst index 4a51877f1..8452046b3 100644 --- a/docs/source/usersguide/output/statepoint.rst +++ b/docs/source/io_formats/statepoint.rst @@ -1,4 +1,4 @@ -.. _usersguide_statepoint: +.. _io_statepoint: ======================= State Point File Format diff --git a/docs/source/usersguide/output/summary.rst b/docs/source/io_formats/summary.rst similarity index 99% rename from docs/source/usersguide/output/summary.rst rename to docs/source/io_formats/summary.rst index cb9f725e8..8af4f2398 100644 --- a/docs/source/usersguide/output/summary.rst +++ b/docs/source/io_formats/summary.rst @@ -1,4 +1,4 @@ -.. _usersguide_summary: +.. _io_summary: =================== Summary File Format diff --git a/docs/source/usersguide/output/track.rst b/docs/source/io_formats/track.rst similarity index 96% rename from docs/source/usersguide/output/track.rst rename to docs/source/io_formats/track.rst index d3c7a27d8..e5cb5d46e 100644 --- a/docs/source/usersguide/output/track.rst +++ b/docs/source/io_formats/track.rst @@ -1,4 +1,4 @@ -.. _usersguide_track: +.. _io_track: ================= Track File Format diff --git a/docs/source/usersguide/output/voxel.rst b/docs/source/io_formats/voxel.rst similarity index 95% rename from docs/source/usersguide/output/voxel.rst rename to docs/source/io_formats/voxel.rst index 1da501fb5..6b73f2800 100644 --- a/docs/source/usersguide/output/voxel.rst +++ b/docs/source/io_formats/voxel.rst @@ -1,4 +1,4 @@ -.. _usersguide_voxel: +.. _io_voxel: ====================== Voxel Plot File Format diff --git a/docs/source/license.rst b/docs/source/license.rst index 73e329617..c51902d6f 100644 --- a/docs/source/license.rst +++ b/docs/source/license.rst @@ -4,7 +4,7 @@ License Agreement ================= -Copyright © 2011-2015 Massachusetts Institute of Technology +Copyright © 2011-2016 Massachusetts Institute of Technology Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/docs/source/methods/cross_sections.rst b/docs/source/methods/cross_sections.rst index 50a97d575..ec8f8fe45 100644 --- a/docs/source/methods/cross_sections.rst +++ b/docs/source/methods/cross_sections.rst @@ -136,6 +136,9 @@ Note that the implementation of WMP in OpenMC currently assumes that inelastic scattering does not occur in the resolved resonance region. This is usually, but not always the case. Future library versions may eliminate this issue. +The data format used by OpenMC to represent windowed multipole data is specified +in :ref:`io_data_wmp` + .. only:: html .. rubric:: References diff --git a/docs/source/pythonapi/examples/mgxs-part-i.ipynb b/docs/source/pythonapi/examples/mgxs-part-i.ipynb index de66cbb83..ea75bec72 100644 --- a/docs/source/pythonapi/examples/mgxs-part-i.ipynb +++ b/docs/source/pythonapi/examples/mgxs-part-i.ipynb @@ -201,7 +201,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "With our material, we can now create a `MaterialsFile` object that can be exported to an actual XML file." + "With our material, we can now create a `Materials` object that can be exported to an actual XML file." ] }, { @@ -212,10 +212,9 @@ }, "outputs": [], "source": [ - "# Instantiate a MaterialsFile, register all Materials, and export to XML\n", - "materials_file = openmc.MaterialsFile()\n", + "# Instantiate a Materials collection and export to XML\n", + "materials_file = openmc.Materials([inf_medium])\n", "materials_file.default_xs = '71c'\n", - "materials_file.add_material(inf_medium)\n", "materials_file.export_to_xml()" ] }, @@ -290,7 +289,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We now must create a geometry that is assigned a root universe, put the geometry into a `GeometryFile` object, and export it to XML." + "We now must create a geometry that is assigned a root universe and export it to XML." ] }, { @@ -305,12 +304,8 @@ "openmc_geometry = openmc.Geometry()\n", "openmc_geometry.root_universe = root_universe\n", "\n", - "# Instantiate a GeometryFile\n", - "geometry_file = openmc.GeometryFile()\n", - "geometry_file.geometry = openmc_geometry\n", - "\n", "# Export to \"geometry.xml\"\n", - "geometry_file.export_to_xml()" + "openmc_geometry.export_to_xml()" ] }, { @@ -333,8 +328,8 @@ "inactive = 10\n", "particles = 2500\n", "\n", - "# Instantiate a SettingsFile\n", - "settings_file = openmc.SettingsFile()\n", + "# Instantiate a Settings object\n", + "settings_file = openmc.Settings()\n", "settings_file.batches = batches\n", "settings_file.inactive = inactive\n", "settings_file.particles = particles\n", @@ -377,10 +372,12 @@ "\n", "* `TotalXS`\n", "* `TransportXS`\n", + "* `NuTransportXS`\n", "* `AbsorptionXS`\n", "* `CaptureXS`\n", "* `FissionXS`\n", "* `NuFissionXS`\n", + "* `KappaFissionXS`\n", "* `ScatterXS`\n", "* `NuScatterXS`\n", "* `ScatterMatrixXS`\n", @@ -399,9 +396,9 @@ "outputs": [], "source": [ "# Instantiate a few different sections\n", - "total = mgxs.TotalXS(domain=cell, domain_type='cell', groups=groups)\n", - "absorption = mgxs.AbsorptionXS(domain=cell, domain_type='cell', groups=groups)\n", - "scattering = mgxs.ScatterXS(domain=cell, domain_type='cell', groups=groups)" + "total = mgxs.TotalXS(domain=cell, groups=groups)\n", + "absorption = mgxs.AbsorptionXS(domain=cell, groups=groups)\n", + "scattering = mgxs.ScatterXS(domain=cell, groups=groups)" ] }, { @@ -455,7 +452,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The `Absorption` object includes tracklength tallies for the 'absorption' and 'flux' scores in the 2-group structure in cell 1. Now that each `MGXS` object contains the tallies that it needs, we must add these tallies to a `TalliesFile` object to generate the \"tallies.xml\" input file for OpenMC." + "The `Absorption` object includes tracklength tallies for the 'absorption' and 'flux' scores in the 2-group structure in cell 1. Now that each `MGXS` object contains the tallies that it needs, we must add these tallies to a `Tallies` object to generate the \"tallies.xml\" input file for OpenMC." ] }, { @@ -466,21 +463,18 @@ }, "outputs": [], "source": [ - "# Instantiate an empty TalliesFile\n", - "tallies_file = openmc.TalliesFile()\n", + "# Instantiate an empty Tallies object\n", + "tallies_file = openmc.Tallies()\n", "\n", "# Add total tallies to the tallies file\n", - "for tally in total.tallies.values():\n", - " tallies_file.add_tally(tally)\n", + "tallies_file += total.tallies.values()\n", "\n", "# Add absorption tallies to the tallies file\n", - "for tally in absorption.tallies.values():\n", - " tallies_file.add_tally(tally)\n", + "tallies_file += absorption.tallies.values()\n", "\n", "# Add scattering tallies to the tallies file\n", - "for tally in scattering.tallies.values():\n", - " tallies_file.add_tally(tally)\n", - " \n", + "tallies_file += scattering.tallies.values()\n", + "\n", "# Export to \"tallies.xml\"\n", "tallies_file.export_to_xml()" ] @@ -516,11 +510,11 @@ " 888\n", " 888\n", "\n", - " Copyright: 2011-2015 Massachusetts Institute of Technology\n", - " License: http://mit-crpg.github.io/openmc/license.html\n", + " Copyright: 2011-2016 Massachusetts Institute of Technology\n", + " License: http://openmc.readthedocs.io/en/latest/license.html\n", " Version: 0.7.1\n", - " Git SHA1: eeb5091ca3a34cc85df73a3318cae2b6c7097413\n", - " Date/Time: 2016-04-13 11:24:09\n", + " Git SHA1: 19feb55e6d5e8350398627f39fb55ee8e2e63011\n", + " Date/Time: 2016-05-13 10:19:16\n", " MPI Processes: 1\n", "\n", " ===========================================================================\n", @@ -606,20 +600,20 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 4.6300E-01 seconds\n", - " Reading cross sections = 1.2100E-01 seconds\n", - " Total time in simulation = 1.6504E+01 seconds\n", - " Time in transport only = 1.6479E+01 seconds\n", - " Time in inactive batches = 1.9620E+00 seconds\n", - " Time in active batches = 1.4542E+01 seconds\n", - " Time synchronizing fission bank = 1.0000E-02 seconds\n", - " Sampling source sites = 4.0000E-03 seconds\n", - " SEND/RECV source sites = 3.0000E-03 seconds\n", + " Total time for initialization = 4.2300E-01 seconds\n", + " Reading cross sections = 9.3000E-02 seconds\n", + " Total time in simulation = 1.6549E+01 seconds\n", + " Time in transport only = 1.6535E+01 seconds\n", + " Time in inactive batches = 2.3650E+00 seconds\n", + " Time in active batches = 1.4184E+01 seconds\n", + " Time synchronizing fission bank = 5.0000E-03 seconds\n", + " Sampling source sites = 3.0000E-03 seconds\n", + " SEND/RECV source sites = 0.0000E+00 seconds\n", " Time accumulating tallies = 0.0000E+00 seconds\n", " Total time for finalization = 0.0000E+00 seconds\n", - " Total time elapsed = 1.6977E+01 seconds\n", - " Calculation Rate (inactive) = 12742.1 neutrons/second\n", - " Calculation Rate (active) = 6876.63 neutrons/second\n", + " Total time elapsed = 1.6981E+01 seconds\n", + " Calculation Rate (inactive) = 10570.8 neutrons/second\n", + " Calculation Rate (active) = 7050.20 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", @@ -644,8 +638,7 @@ ], "source": [ "# Run OpenMC\n", - "executor = openmc.Executor()\n", - "executor.run_simulation()" + "openmc.run()" ] }, { @@ -678,20 +671,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "In addition to the statepoint file, our simulation also created a summary file which encapsulates information about the materials and geometry. This is necessary for the `openmc.mgxs` module to properly process the tally data. We first create a `Summary` object and link it with the statepoint." - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Load the summary file and link it with the statepoint\n", - "su = openmc.Summary('summary.h5')\n", - "sp.link_with_summary(su)" + "In addition to the statepoint file, our simulation also created a summary file which encapsulates information about the materials and geometry. By default, a `Summary` object is automatically linked when a `StatePoint` is loaded. This is necessary for the `openmc.mgxs` module to properly process the tally data." ] }, { @@ -703,7 +683,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 17, "metadata": { "collapsed": false }, @@ -738,7 +718,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 18, "metadata": { "collapsed": false }, @@ -773,7 +753,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 19, "metadata": { "collapsed": false }, @@ -820,7 +800,7 @@ "0 1 2 total 1.292013 0.007642" ] }, - "execution_count": 20, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -839,7 +819,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 20, "metadata": { "collapsed": true }, @@ -857,7 +837,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 21, "metadata": { "collapsed": false }, @@ -884,7 +864,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 22, "metadata": { "collapsed": false }, @@ -941,7 +921,7 @@ "1 (((total / flux) - (absorption / flux)) - (sca... 1.44e-15 2.57e-03 " ] }, - "execution_count": 23, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -963,7 +943,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 23, "metadata": { "collapsed": false }, @@ -1020,7 +1000,7 @@ "1 ((absorption / flux) / (total / flux)) 1.93e-02 9.46e-05 " ] }, - "execution_count": 24, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -1035,7 +1015,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 24, "metadata": { "collapsed": false }, @@ -1092,7 +1072,7 @@ "1 ((scatter / flux) / (total / flux)) 9.81e-01 3.74e-03 " ] }, - "execution_count": 25, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } @@ -1114,7 +1094,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 25, "metadata": { "collapsed": false }, @@ -1144,7 +1124,7 @@ " 6.250000e-07\n", " total\n", " (((absorption / flux) / (total / flux)) + ((sc...\n", - " 1\n", + " 1.0\n", " 0.007763\n", " \n", " \n", @@ -1154,7 +1134,7 @@ " 2.000000e+01\n", " total\n", " (((absorption / flux) / (total / flux)) + ((sc...\n", - " 1\n", + " 1.0\n", " 0.003739\n", " \n", " \n", @@ -1171,7 +1151,7 @@ "1 (((absorption / flux) / (total / flux)) + ((sc... 1.00e+00 3.74e-03 " ] }, - "execution_count": 26, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } diff --git a/docs/source/pythonapi/examples/mgxs-part-ii.ipynb b/docs/source/pythonapi/examples/mgxs-part-ii.ipynb index 6ed5cd38d..b882e949c 100644 --- a/docs/source/pythonapi/examples/mgxs-part-ii.ipynb +++ b/docs/source/pythonapi/examples/mgxs-part-ii.ipynb @@ -13,7 +13,7 @@ "* The use of **[PyNE](http://pyne.io/) to plot** continuous-energy vs. multi-group cross sections\n", "* **Validation** of multi-group cross sections with **[OpenMOC](https://mit-crpg.github.io/OpenMOC/)**\n", "\n", - "**Note:** This Notebook was created using [OpenMOC](https://mit-crpg.github.io/OpenMOC/) to verify the multi-group cross-sections generated by OpenMC. In order to run this Notebook in its entirety, you must have [OpenMOC](https://mit-crpg.github.io/OpenMOC/) installed on your system, along with OpenCG to convert the OpenMC geometries into OpenMOC geometries. In addition, this Notebook illustrates the use of [Pandas](http://pandas.pydata.org/) `DataFrames` to containerize multi-group cross section data. We recommend using [Pandas](http://pandas.pydata.org/) >v0.15.0 or later since OpenMC's Python API leverages the multi-indexing feature included in the most recent releases of [Pandas](http://pandas.pydata.org/)." + "**Note:** This Notebook was created using [OpenMOC](https://mit-crpg.github.io/OpenMOC/) to verify the multi-group cross-sections generated by OpenMC. In order to run this Notebook in its entirety, you must have [OpenMOC](https://mit-crpg.github.io/OpenMOC/) installed on your system, along with OpenCG to convert the OpenMC geometries into OpenMOC geometries. In addition, this Notebook illustrates the use of [Pandas](http://pandas.pydata.org/) `DataFrames` to containerize multi-group cross section data." ] }, { @@ -122,7 +122,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "With our materials, we can now create a `MaterialsFile` object that can be exported to an actual XML file." + "With our materials, we can now create a `Materials` object that can be exported to an actual XML file." ] }, { @@ -133,11 +133,8 @@ }, "outputs": [], "source": [ - "# Instantiate a MaterialsFile, add Materials\n", - "materials_file = openmc.MaterialsFile()\n", - "materials_file.add_material(fuel)\n", - "materials_file.add_material(water)\n", - "materials_file.add_material(zircaloy)\n", + "# Instantiate a Materials collection\n", + "materials_file = openmc.Materials((fuel, water, zircaloy))\n", "materials_file.default_xs = '71c'\n", "\n", "# Export to \"materials.xml\"\n", @@ -238,7 +235,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We now must create a geometry that is assigned a root universe, put the geometry into a `GeometryFile` object, and export it to XML." + "We now must create a geometry that is assigned a root universe and export it to XML." ] }, { @@ -253,12 +250,8 @@ "openmc_geometry = openmc.Geometry()\n", "openmc_geometry.root_universe = root_universe\n", "\n", - "# Instantiate a GeometryFile\n", - "geometry_file = openmc.GeometryFile()\n", - "geometry_file.geometry = openmc_geometry\n", - "\n", "# Export to \"geometry.xml\"\n", - "geometry_file.export_to_xml()" + "openmc_geometry.export_to_xml()" ] }, { @@ -281,8 +274,8 @@ "inactive = 10\n", "particles = 10000\n", "\n", - "# Instantiate a SettingsFile\n", - "settings_file = openmc.SettingsFile()\n", + "# Instantiate a Settings object\n", + "settings_file = openmc.Settings()\n", "settings_file.batches = batches\n", "settings_file.inactive = inactive\n", "settings_file.particles = particles\n", @@ -396,23 +389,22 @@ }, "outputs": [], "source": [ - "# Instantiate an empty TalliesFile\n", - "tallies_file = openmc.TalliesFile()\n", + "# Instantiate an empty Tallies object\n", + "tallies_file = openmc.Tallies()\n", "\n", "# Iterate over all cells and cross section types\n", "for cell in openmc_cells:\n", " for rxn_type in xs_library[cell.id]:\n", "\n", - " # Set the cross sections domain type to the cell\n", + " # Set the cross sections domain to the cell\n", " xs_library[cell.id][rxn_type].domain = cell\n", - " xs_library[cell.id][rxn_type].domain_type = 'cell'\n", " \n", " # Tally cross sections by nuclide\n", " xs_library[cell.id][rxn_type].by_nuclide = True\n", " \n", " # Add OpenMC tallies to the tallies file for XML generation\n", " for tally in xs_library[cell.id][rxn_type].tallies.values():\n", - " tallies_file.add_tally(tally, merge=True)\n", + " tallies_file.append(tally, merge=True)\n", "\n", "# Export to \"tallies.xml\"\n", "tallies_file.export_to_xml()" @@ -449,11 +441,11 @@ " 888\n", " 888\n", "\n", - " Copyright: 2011-2015 Massachusetts Institute of Technology\n", - " License: http://mit-crpg.github.io/openmc/license.html\n", + " Copyright: 2011-2016 Massachusetts Institute of Technology\n", + " License: http://openmc.readthedocs.io/en/latest/license.html\n", " Version: 0.7.1\n", - " Git SHA1: eeb5091ca3a34cc85df73a3318cae2b6c7097413\n", - " Date/Time: 2016-04-13 11:59:39\n", + " Git SHA1: 19feb55e6d5e8350398627f39fb55ee8e2e63011\n", + " Date/Time: 2016-05-13 10:13:48\n", " MPI Processes: 1\n", "\n", " ===========================================================================\n", @@ -530,7 +522,7 @@ " 48/1 1.21610 1.22612 +/- 0.00251\n", " 49/1 1.22199 1.22602 +/- 0.00245\n", " 50/1 1.20860 1.22558 +/- 0.00243\n", - " Triggers unsatisfied, max unc./thresh. is 1.25496 for flux in tally 10050\n", + " Triggers unsatisfied, max unc./thresh. is 1.25496 for flux in tally 10051\n", " The estimated number of batches is 73\n", " Creating state point statepoint.050.h5...\n", " 51/1 1.21850 1.22541 +/- 0.00237\n", @@ -556,7 +548,7 @@ " 71/1 1.19720 1.22444 +/- 0.00195\n", " 72/1 1.23770 1.22465 +/- 0.00193\n", " 73/1 1.23894 1.22488 +/- 0.00191\n", - " Triggers unsatisfied, max unc./thresh. is 1.00243 for flux in tally 10050\n", + " Triggers unsatisfied, max unc./thresh. is 1.00243 for flux in tally 10051\n", " The estimated number of batches is 74\n", " 74/1 1.22437 1.22487 +/- 0.00188\n", " Triggers satisfied for batch 74\n", @@ -569,20 +561,20 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 4.0100E-01 seconds\n", - " Reading cross sections = 8.8000E-02 seconds\n", - " Total time in simulation = 2.3897E+02 seconds\n", - " Time in transport only = 2.3892E+02 seconds\n", - " Time in inactive batches = 1.6456E+01 seconds\n", - " Time in active batches = 2.2251E+02 seconds\n", - " Time synchronizing fission bank = 1.8000E-02 seconds\n", - " Sampling source sites = 1.3000E-02 seconds\n", - " SEND/RECV source sites = 4.0000E-03 seconds\n", + " Total time for initialization = 5.7400E-01 seconds\n", + " Reading cross sections = 1.2600E-01 seconds\n", + " Total time in simulation = 2.6256E+02 seconds\n", + " Time in transport only = 2.6250E+02 seconds\n", + " Time in inactive batches = 2.2890E+01 seconds\n", + " Time in active batches = 2.3967E+02 seconds\n", + " Time synchronizing fission bank = 3.4000E-02 seconds\n", + " Sampling source sites = 2.1000E-02 seconds\n", + " SEND/RECV source sites = 1.3000E-02 seconds\n", " Time accumulating tallies = 0.0000E+00 seconds\n", - " Total time for finalization = 1.2000E-02 seconds\n", - " Total time elapsed = 2.3943E+02 seconds\n", - " Calculation Rate (inactive) = 6076.81 neutrons/second\n", - " Calculation Rate (active) = 1797.66 neutrons/second\n", + " Total time for finalization = 1.3000E-02 seconds\n", + " Total time elapsed = 2.6320E+02 seconds\n", + " Calculation Rate (inactive) = 4368.72 neutrons/second\n", + " Calculation Rate (active) = 1668.93 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", @@ -607,8 +599,7 @@ ], "source": [ "# Run OpenMC\n", - "executor = openmc.Executor()\n", - "executor.run_simulation(output=True)" + "openmc.run(output=True)" ] }, { @@ -637,26 +628,6 @@ "sp = openmc.StatePoint('statepoint.074.h5')" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In addition to the statepoint file, our simulation also created a summary file which encapsulates information about the materials and geometry. This is necessary for the `openmc.mgxs` module to properly process the tally data. We first create a `Summary` object and link it with the statepoint." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# Load the summary file and link it with the statepoint\n", - "su = openmc.Summary('summary.h5')\n", - "sp.link_with_summary(su)" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -666,7 +637,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 16, "metadata": { "collapsed": false }, @@ -701,7 +672,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 17, "metadata": { "collapsed": false }, @@ -755,7 +726,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 18, "metadata": { "collapsed": false }, @@ -797,7 +768,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 19, "metadata": { "collapsed": false }, @@ -927,7 +898,7 @@ "119 10002 1 5 O-16 0.000000 0.000000" ] }, - "execution_count": 20, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -947,7 +918,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 20, "metadata": { "collapsed": true }, @@ -969,7 +940,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 21, "metadata": { "collapsed": false }, @@ -1008,7 +979,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 22, "metadata": { "collapsed": false }, @@ -1091,7 +1062,7 @@ "2 10000 2 O-16 3.794859 0.011139" ] }, - "execution_count": 23, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -1117,14 +1088,14 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Create an OpenMOC Geometry from the OpenCG Geometry\n", - "openmoc_geometry = get_openmoc_geometry(su.opencg_geometry)" + "openmoc_geometry = get_openmoc_geometry(sp.summary.opencg_geometry)" ] }, { @@ -1136,7 +1107,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 24, "metadata": { "collapsed": false }, @@ -1181,7 +1152,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 25, "metadata": { "collapsed": false }, @@ -1200,167 +1171,167 @@ "[ NORMAL ] Iteration 5:\tk_eff = 0.625810\tres = 2.417E-02\n", "[ NORMAL ] Iteration 6:\tk_eff = 0.606678\tres = 2.675E-02\n", "[ NORMAL ] Iteration 7:\tk_eff = 0.587485\tres = 3.057E-02\n", - "[ NORMAL ] Iteration 8:\tk_eff = 0.569029\tres = 3.164E-02\n", + "[ NORMAL ] Iteration 8:\tk_eff = 0.569028\tres = 3.164E-02\n", "[ NORMAL ] Iteration 9:\tk_eff = 0.551707\tres = 3.142E-02\n", - "[ NORMAL ] Iteration 10:\tk_eff = 0.536035\tres = 3.044E-02\n", - "[ NORMAL ] Iteration 11:\tk_eff = 0.522275\tres = 2.841E-02\n", - "[ NORMAL ] Iteration 12:\tk_eff = 0.510610\tres = 2.567E-02\n", - "[ NORMAL ] Iteration 13:\tk_eff = 0.501106\tres = 2.234E-02\n", - "[ NORMAL ] Iteration 14:\tk_eff = 0.493832\tres = 1.861E-02\n", - "[ NORMAL ] Iteration 15:\tk_eff = 0.488781\tres = 1.452E-02\n", - "[ NORMAL ] Iteration 16:\tk_eff = 0.485924\tres = 1.023E-02\n", - "[ NORMAL ] Iteration 17:\tk_eff = 0.485211\tres = 5.846E-03\n", - "[ NORMAL ] Iteration 18:\tk_eff = 0.486571\tres = 1.467E-03\n", - "[ NORMAL ] Iteration 19:\tk_eff = 0.489905\tres = 2.802E-03\n", - "[ NORMAL ] Iteration 20:\tk_eff = 0.495105\tres = 6.853E-03\n", - "[ NORMAL ] Iteration 21:\tk_eff = 0.502056\tres = 1.061E-02\n", - "[ NORMAL ] Iteration 22:\tk_eff = 0.510630\tres = 1.404E-02\n", - "[ NORMAL ] Iteration 23:\tk_eff = 0.520696\tres = 1.708E-02\n", - "[ NORMAL ] Iteration 24:\tk_eff = 0.532120\tres = 1.971E-02\n", - "[ NORMAL ] Iteration 25:\tk_eff = 0.544768\tres = 2.194E-02\n", - "[ NORMAL ] Iteration 26:\tk_eff = 0.558505\tres = 2.377E-02\n", - "[ NORMAL ] Iteration 27:\tk_eff = 0.573200\tres = 2.522E-02\n", - "[ NORMAL ] Iteration 28:\tk_eff = 0.588723\tres = 2.631E-02\n", - "[ NORMAL ] Iteration 29:\tk_eff = 0.604951\tres = 2.708E-02\n", - "[ NORMAL ] Iteration 30:\tk_eff = 0.621765\tres = 2.756E-02\n", - "[ NORMAL ] Iteration 31:\tk_eff = 0.639053\tres = 2.779E-02\n", - "[ NORMAL ] Iteration 32:\tk_eff = 0.656709\tres = 2.780E-02\n", - "[ NORMAL ] Iteration 33:\tk_eff = 0.674632\tres = 2.763E-02\n", - "[ NORMAL ] Iteration 34:\tk_eff = 0.692730\tres = 2.729E-02\n", - "[ NORMAL ] Iteration 35:\tk_eff = 0.710919\tres = 2.683E-02\n", - "[ NORMAL ] Iteration 36:\tk_eff = 0.729118\tres = 2.626E-02\n", - "[ NORMAL ] Iteration 37:\tk_eff = 0.747258\tres = 2.560E-02\n", - "[ NORMAL ] Iteration 38:\tk_eff = 0.765273\tres = 2.488E-02\n", - "[ NORMAL ] Iteration 39:\tk_eff = 0.783104\tres = 2.411E-02\n", - "[ NORMAL ] Iteration 40:\tk_eff = 0.800701\tres = 2.330E-02\n", - "[ NORMAL ] Iteration 41:\tk_eff = 0.818017\tres = 2.247E-02\n", - "[ NORMAL ] Iteration 42:\tk_eff = 0.835012\tres = 2.163E-02\n", - "[ NORMAL ] Iteration 43:\tk_eff = 0.851651\tres = 2.078E-02\n", - "[ NORMAL ] Iteration 44:\tk_eff = 0.867906\tres = 1.993E-02\n", - "[ NORMAL ] Iteration 45:\tk_eff = 0.883750\tres = 1.909E-02\n", - "[ NORMAL ] Iteration 46:\tk_eff = 0.899164\tres = 1.826E-02\n", - "[ NORMAL ] Iteration 47:\tk_eff = 0.914131\tres = 1.744E-02\n", - "[ NORMAL ] Iteration 48:\tk_eff = 0.928638\tres = 1.665E-02\n", - "[ NORMAL ] Iteration 49:\tk_eff = 0.942676\tres = 1.587E-02\n", - "[ NORMAL ] Iteration 50:\tk_eff = 0.956239\tres = 1.512E-02\n", - "[ NORMAL ] Iteration 51:\tk_eff = 0.969323\tres = 1.439E-02\n", - "[ NORMAL ] Iteration 52:\tk_eff = 0.981927\tres = 1.368E-02\n", - "[ NORMAL ] Iteration 53:\tk_eff = 0.994054\tres = 1.300E-02\n", - "[ NORMAL ] Iteration 54:\tk_eff = 1.005705\tres = 1.235E-02\n", - "[ NORMAL ] Iteration 55:\tk_eff = 1.016886\tres = 1.172E-02\n", - "[ NORMAL ] Iteration 56:\tk_eff = 1.027604\tres = 1.112E-02\n", - "[ NORMAL ] Iteration 57:\tk_eff = 1.037866\tres = 1.054E-02\n", - "[ NORMAL ] Iteration 58:\tk_eff = 1.047682\tres = 9.987E-03\n", - "[ NORMAL ] Iteration 59:\tk_eff = 1.057062\tres = 9.458E-03\n", - "[ NORMAL ] Iteration 60:\tk_eff = 1.066016\tres = 8.953E-03\n", - "[ NORMAL ] Iteration 61:\tk_eff = 1.074556\tres = 8.471E-03\n", - "[ NORMAL ] Iteration 62:\tk_eff = 1.082693\tres = 8.011E-03\n", - "[ NORMAL ] Iteration 63:\tk_eff = 1.090442\tres = 7.573E-03\n", - "[ NORMAL ] Iteration 64:\tk_eff = 1.097813\tres = 7.156E-03\n", - "[ NORMAL ] Iteration 65:\tk_eff = 1.104820\tres = 6.760E-03\n", - "[ NORMAL ] Iteration 66:\tk_eff = 1.111477\tres = 6.383E-03\n", - "[ NORMAL ] Iteration 67:\tk_eff = 1.117795\tres = 6.025E-03\n", - "[ NORMAL ] Iteration 68:\tk_eff = 1.123789\tres = 5.685E-03\n", - "[ NORMAL ] Iteration 69:\tk_eff = 1.129470\tres = 5.362E-03\n", - "[ NORMAL ] Iteration 70:\tk_eff = 1.134853\tres = 5.056E-03\n", - "[ NORMAL ] Iteration 71:\tk_eff = 1.139950\tres = 4.766E-03\n", - "[ NORMAL ] Iteration 72:\tk_eff = 1.144772\tres = 4.491E-03\n", - "[ NORMAL ] Iteration 73:\tk_eff = 1.149333\tres = 4.230E-03\n", - "[ NORMAL ] Iteration 74:\tk_eff = 1.153643\tres = 3.984E-03\n", - "[ NORMAL ] Iteration 75:\tk_eff = 1.157716\tres = 3.751E-03\n", - "[ NORMAL ] Iteration 76:\tk_eff = 1.161561\tres = 3.530E-03\n", - "[ NORMAL ] Iteration 77:\tk_eff = 1.165190\tres = 3.321E-03\n", - "[ NORMAL ] Iteration 78:\tk_eff = 1.168613\tres = 3.124E-03\n", - "[ NORMAL ] Iteration 79:\tk_eff = 1.171841\tres = 2.938E-03\n", - "[ NORMAL ] Iteration 80:\tk_eff = 1.174883\tres = 2.762E-03\n", - "[ NORMAL ] Iteration 81:\tk_eff = 1.177749\tres = 2.596E-03\n", - "[ NORMAL ] Iteration 82:\tk_eff = 1.180447\tres = 2.439E-03\n", - "[ NORMAL ] Iteration 83:\tk_eff = 1.182988\tres = 2.291E-03\n", - "[ NORMAL ] Iteration 84:\tk_eff = 1.185378\tres = 2.152E-03\n", - "[ NORMAL ] Iteration 85:\tk_eff = 1.187627\tres = 2.021E-03\n", - "[ NORMAL ] Iteration 86:\tk_eff = 1.189741\tres = 1.897E-03\n", - "[ NORMAL ] Iteration 87:\tk_eff = 1.191728\tres = 1.780E-03\n", - "[ NORMAL ] Iteration 88:\tk_eff = 1.193595\tres = 1.670E-03\n", - "[ NORMAL ] Iteration 89:\tk_eff = 1.195349\tres = 1.567E-03\n", - "[ NORMAL ] Iteration 90:\tk_eff = 1.196996\tres = 1.469E-03\n", - "[ NORMAL ] Iteration 91:\tk_eff = 1.198543\tres = 1.378E-03\n", - "[ NORMAL ] Iteration 92:\tk_eff = 1.199994\tres = 1.292E-03\n", - "[ NORMAL ] Iteration 93:\tk_eff = 1.201355\tres = 1.211E-03\n", - "[ NORMAL ] Iteration 94:\tk_eff = 1.202632\tres = 1.134E-03\n", - "[ NORMAL ] Iteration 95:\tk_eff = 1.203829\tres = 1.063E-03\n", - "[ NORMAL ] Iteration 96:\tk_eff = 1.204952\tres = 9.956E-04\n", - "[ NORMAL ] Iteration 97:\tk_eff = 1.206004\tres = 9.324E-04\n", - "[ NORMAL ] Iteration 98:\tk_eff = 1.206989\tres = 8.730E-04\n", - "[ NORMAL ] Iteration 99:\tk_eff = 1.207913\tres = 8.173E-04\n", - "[ NORMAL ] Iteration 100:\tk_eff = 1.208777\tres = 7.650E-04\n", - "[ NORMAL ] Iteration 101:\tk_eff = 1.209587\tres = 7.159E-04\n", - "[ NORMAL ] Iteration 102:\tk_eff = 1.210345\tres = 6.698E-04\n", - "[ NORMAL ] Iteration 103:\tk_eff = 1.211054\tres = 6.266E-04\n", - "[ NORMAL ] Iteration 104:\tk_eff = 1.211718\tres = 5.861E-04\n", - "[ NORMAL ] Iteration 105:\tk_eff = 1.212339\tres = 5.481E-04\n", - "[ NORMAL ] Iteration 106:\tk_eff = 1.212920\tres = 5.125E-04\n", - "[ NORMAL ] Iteration 107:\tk_eff = 1.213463\tres = 4.792E-04\n", - "[ NORMAL ] Iteration 108:\tk_eff = 1.213971\tres = 4.479E-04\n", - "[ NORMAL ] Iteration 109:\tk_eff = 1.214446\tres = 4.186E-04\n", - "[ NORMAL ] Iteration 110:\tk_eff = 1.214890\tres = 3.912E-04\n", - "[ NORMAL ] Iteration 111:\tk_eff = 1.215305\tres = 3.655E-04\n", - "[ NORMAL ] Iteration 112:\tk_eff = 1.215692\tres = 3.414E-04\n", - "[ NORMAL ] Iteration 113:\tk_eff = 1.216055\tres = 3.189E-04\n", - "[ NORMAL ] Iteration 114:\tk_eff = 1.216393\tres = 2.979E-04\n", - "[ NORMAL ] Iteration 115:\tk_eff = 1.216709\tres = 2.782E-04\n", - "[ NORMAL ] Iteration 116:\tk_eff = 1.217004\tres = 2.597E-04\n", - "[ NORMAL ] Iteration 117:\tk_eff = 1.217279\tres = 2.425E-04\n", - "[ NORMAL ] Iteration 118:\tk_eff = 1.217536\tres = 2.263E-04\n", - "[ NORMAL ] Iteration 119:\tk_eff = 1.217776\tres = 2.113E-04\n", - "[ NORMAL ] Iteration 120:\tk_eff = 1.218000\tres = 1.971E-04\n", - "[ NORMAL ] Iteration 121:\tk_eff = 1.218209\tres = 1.840E-04\n", - "[ NORMAL ] Iteration 122:\tk_eff = 1.218404\tres = 1.716E-04\n", - "[ NORMAL ] Iteration 123:\tk_eff = 1.218587\tres = 1.601E-04\n", - "[ NORMAL ] Iteration 124:\tk_eff = 1.218756\tres = 1.494E-04\n", - "[ NORMAL ] Iteration 125:\tk_eff = 1.218915\tres = 1.393E-04\n", - "[ NORMAL ] Iteration 126:\tk_eff = 1.219062\tres = 1.299E-04\n", - "[ NORMAL ] Iteration 127:\tk_eff = 1.219200\tres = 1.212E-04\n", - "[ NORMAL ] Iteration 128:\tk_eff = 1.219329\tres = 1.130E-04\n", - "[ NORMAL ] Iteration 129:\tk_eff = 1.219448\tres = 1.054E-04\n", - "[ NORMAL ] Iteration 130:\tk_eff = 1.219560\tres = 9.822E-05\n", - "[ NORMAL ] Iteration 131:\tk_eff = 1.219664\tres = 9.156E-05\n", - "[ NORMAL ] Iteration 132:\tk_eff = 1.219761\tres = 8.534E-05\n", - "[ NORMAL ] Iteration 133:\tk_eff = 1.219851\tres = 7.954E-05\n", - "[ NORMAL ] Iteration 134:\tk_eff = 1.219936\tres = 7.413E-05\n", - "[ NORMAL ] Iteration 135:\tk_eff = 1.220014\tres = 6.908E-05\n", - "[ NORMAL ] Iteration 136:\tk_eff = 1.220087\tres = 6.437E-05\n", - "[ NORMAL ] Iteration 137:\tk_eff = 1.220156\tres = 5.997E-05\n", - "[ NORMAL ] Iteration 138:\tk_eff = 1.220219\tres = 5.587E-05\n", - "[ NORMAL ] Iteration 139:\tk_eff = 1.220278\tres = 5.205E-05\n", - "[ NORMAL ] Iteration 140:\tk_eff = 1.220333\tres = 4.848E-05\n", - "[ NORMAL ] Iteration 141:\tk_eff = 1.220385\tres = 4.516E-05\n", - "[ NORMAL ] Iteration 142:\tk_eff = 1.220433\tres = 4.206E-05\n", - "[ NORMAL ] Iteration 143:\tk_eff = 1.220477\tres = 3.917E-05\n", - "[ NORMAL ] Iteration 144:\tk_eff = 1.220518\tres = 3.648E-05\n", - "[ NORMAL ] Iteration 145:\tk_eff = 1.220557\tres = 3.397E-05\n", - "[ NORMAL ] Iteration 146:\tk_eff = 1.220593\tres = 3.163E-05\n", - "[ NORMAL ] Iteration 147:\tk_eff = 1.220627\tres = 2.945E-05\n", - "[ NORMAL ] Iteration 148:\tk_eff = 1.220658\tres = 2.742E-05\n", - "[ NORMAL ] Iteration 149:\tk_eff = 1.220687\tres = 2.552E-05\n", - "[ NORMAL ] Iteration 150:\tk_eff = 1.220714\tres = 2.376E-05\n", - "[ NORMAL ] Iteration 151:\tk_eff = 1.220739\tres = 2.212E-05\n", - "[ NORMAL ] Iteration 152:\tk_eff = 1.220762\tres = 2.059E-05\n", - "[ NORMAL ] Iteration 153:\tk_eff = 1.220784\tres = 1.916E-05\n", - "[ NORMAL ] Iteration 154:\tk_eff = 1.220804\tres = 1.783E-05\n", - "[ NORMAL ] Iteration 155:\tk_eff = 1.220823\tres = 1.660E-05\n", - "[ NORMAL ] Iteration 156:\tk_eff = 1.220841\tres = 1.545E-05\n", - "[ NORMAL ] Iteration 157:\tk_eff = 1.220857\tres = 1.437E-05\n", - "[ NORMAL ] Iteration 158:\tk_eff = 1.220872\tres = 1.338E-05\n", - "[ NORMAL ] Iteration 159:\tk_eff = 1.220886\tres = 1.245E-05\n", - "[ NORMAL ] Iteration 160:\tk_eff = 1.220899\tres = 1.158E-05\n", - "[ NORMAL ] Iteration 161:\tk_eff = 1.220912\tres = 1.077E-05\n", - "[ NORMAL ] Iteration 162:\tk_eff = 1.220923\tres = 1.002E-05\n" + "[ NORMAL ] Iteration 10:\tk_eff = 0.536034\tres = 3.044E-02\n", + "[ NORMAL ] Iteration 11:\tk_eff = 0.522274\tres = 2.841E-02\n", + "[ NORMAL ] Iteration 12:\tk_eff = 0.510609\tres = 2.567E-02\n", + "[ NORMAL ] Iteration 13:\tk_eff = 0.501105\tres = 2.234E-02\n", + "[ NORMAL ] Iteration 14:\tk_eff = 0.493831\tres = 1.861E-02\n", + "[ NORMAL ] Iteration 15:\tk_eff = 0.488780\tres = 1.452E-02\n", + "[ NORMAL ] Iteration 16:\tk_eff = 0.485922\tres = 1.023E-02\n", + "[ NORMAL ] Iteration 17:\tk_eff = 0.485209\tres = 5.846E-03\n", + "[ NORMAL ] Iteration 18:\tk_eff = 0.486569\tres = 1.467E-03\n", + "[ NORMAL ] Iteration 19:\tk_eff = 0.489903\tres = 2.801E-03\n", + "[ NORMAL ] Iteration 20:\tk_eff = 0.495102\tres = 6.853E-03\n", + "[ NORMAL ] Iteration 21:\tk_eff = 0.502053\tres = 1.061E-02\n", + "[ NORMAL ] Iteration 22:\tk_eff = 0.510627\tres = 1.404E-02\n", + "[ NORMAL ] Iteration 23:\tk_eff = 0.520692\tres = 1.708E-02\n", + "[ NORMAL ] Iteration 24:\tk_eff = 0.532116\tres = 1.971E-02\n", + "[ NORMAL ] Iteration 25:\tk_eff = 0.544763\tres = 2.194E-02\n", + "[ NORMAL ] Iteration 26:\tk_eff = 0.558500\tres = 2.377E-02\n", + "[ NORMAL ] Iteration 27:\tk_eff = 0.573195\tres = 2.522E-02\n", + "[ NORMAL ] Iteration 28:\tk_eff = 0.588717\tres = 2.631E-02\n", + "[ NORMAL ] Iteration 29:\tk_eff = 0.604945\tres = 2.708E-02\n", + "[ NORMAL ] Iteration 30:\tk_eff = 0.621759\tres = 2.756E-02\n", + "[ NORMAL ] Iteration 31:\tk_eff = 0.639046\tres = 2.779E-02\n", + "[ NORMAL ] Iteration 32:\tk_eff = 0.656701\tres = 2.780E-02\n", + "[ NORMAL ] Iteration 33:\tk_eff = 0.674624\tres = 2.763E-02\n", + "[ NORMAL ] Iteration 34:\tk_eff = 0.692722\tres = 2.729E-02\n", + "[ NORMAL ] Iteration 35:\tk_eff = 0.710909\tres = 2.683E-02\n", + "[ NORMAL ] Iteration 36:\tk_eff = 0.729109\tres = 2.626E-02\n", + "[ NORMAL ] Iteration 37:\tk_eff = 0.747248\tres = 2.560E-02\n", + "[ NORMAL ] Iteration 38:\tk_eff = 0.765262\tres = 2.488E-02\n", + "[ NORMAL ] Iteration 39:\tk_eff = 0.783093\tres = 2.411E-02\n", + "[ NORMAL ] Iteration 40:\tk_eff = 0.800689\tres = 2.330E-02\n", + "[ NORMAL ] Iteration 41:\tk_eff = 0.818004\tres = 2.247E-02\n", + "[ NORMAL ] Iteration 42:\tk_eff = 0.834999\tres = 2.163E-02\n", + "[ NORMAL ] Iteration 43:\tk_eff = 0.851638\tres = 2.078E-02\n", + "[ NORMAL ] Iteration 44:\tk_eff = 0.867891\tres = 1.993E-02\n", + "[ NORMAL ] Iteration 45:\tk_eff = 0.883735\tres = 1.909E-02\n", + "[ NORMAL ] Iteration 46:\tk_eff = 0.899148\tres = 1.826E-02\n", + "[ NORMAL ] Iteration 47:\tk_eff = 0.914114\tres = 1.744E-02\n", + "[ NORMAL ] Iteration 48:\tk_eff = 0.928621\tres = 1.664E-02\n", + "[ NORMAL ] Iteration 49:\tk_eff = 0.942659\tres = 1.587E-02\n", + "[ NORMAL ] Iteration 50:\tk_eff = 0.956221\tres = 1.512E-02\n", + "[ NORMAL ] Iteration 51:\tk_eff = 0.969305\tres = 1.439E-02\n", + "[ NORMAL ] Iteration 52:\tk_eff = 0.981909\tres = 1.368E-02\n", + "[ NORMAL ] Iteration 53:\tk_eff = 0.994034\tres = 1.300E-02\n", + "[ NORMAL ] Iteration 54:\tk_eff = 1.005685\tres = 1.235E-02\n", + "[ NORMAL ] Iteration 55:\tk_eff = 1.016866\tres = 1.172E-02\n", + "[ NORMAL ] Iteration 56:\tk_eff = 1.027583\tres = 1.112E-02\n", + "[ NORMAL ] Iteration 57:\tk_eff = 1.037845\tres = 1.054E-02\n", + "[ NORMAL ] Iteration 58:\tk_eff = 1.047661\tres = 9.986E-03\n", + "[ NORMAL ] Iteration 59:\tk_eff = 1.057040\tres = 9.458E-03\n", + "[ NORMAL ] Iteration 60:\tk_eff = 1.065993\tres = 8.952E-03\n", + "[ NORMAL ] Iteration 61:\tk_eff = 1.074533\tres = 8.470E-03\n", + "[ NORMAL ] Iteration 62:\tk_eff = 1.082670\tres = 8.011E-03\n", + "[ NORMAL ] Iteration 63:\tk_eff = 1.090418\tres = 7.573E-03\n", + "[ NORMAL ] Iteration 64:\tk_eff = 1.097789\tres = 7.156E-03\n", + "[ NORMAL ] Iteration 65:\tk_eff = 1.104796\tres = 6.760E-03\n", + "[ NORMAL ] Iteration 66:\tk_eff = 1.111452\tres = 6.383E-03\n", + "[ NORMAL ] Iteration 67:\tk_eff = 1.117770\tres = 6.025E-03\n", + "[ NORMAL ] Iteration 68:\tk_eff = 1.123764\tres = 5.685E-03\n", + "[ NORMAL ] Iteration 69:\tk_eff = 1.129445\tres = 5.362E-03\n", + "[ NORMAL ] Iteration 70:\tk_eff = 1.134828\tres = 5.056E-03\n", + "[ NORMAL ] Iteration 71:\tk_eff = 1.139924\tres = 4.766E-03\n", + "[ NORMAL ] Iteration 72:\tk_eff = 1.144746\tres = 4.491E-03\n", + "[ NORMAL ] Iteration 73:\tk_eff = 1.149306\tres = 4.230E-03\n", + "[ NORMAL ] Iteration 74:\tk_eff = 1.153617\tres = 3.984E-03\n", + "[ NORMAL ] Iteration 75:\tk_eff = 1.157689\tres = 3.750E-03\n", + "[ NORMAL ] Iteration 76:\tk_eff = 1.161534\tres = 3.530E-03\n", + "[ NORMAL ] Iteration 77:\tk_eff = 1.165163\tres = 3.321E-03\n", + "[ NORMAL ] Iteration 78:\tk_eff = 1.168586\tres = 3.124E-03\n", + "[ NORMAL ] Iteration 79:\tk_eff = 1.171813\tres = 2.938E-03\n", + "[ NORMAL ] Iteration 80:\tk_eff = 1.174855\tres = 2.762E-03\n", + "[ NORMAL ] Iteration 81:\tk_eff = 1.177721\tres = 2.596E-03\n", + "[ NORMAL ] Iteration 82:\tk_eff = 1.180419\tres = 2.439E-03\n", + "[ NORMAL ] Iteration 83:\tk_eff = 1.182960\tres = 2.291E-03\n", + "[ NORMAL ] Iteration 84:\tk_eff = 1.185350\tres = 2.152E-03\n", + "[ NORMAL ] Iteration 85:\tk_eff = 1.187598\tres = 2.021E-03\n", + "[ NORMAL ] Iteration 86:\tk_eff = 1.189712\tres = 1.897E-03\n", + "[ NORMAL ] Iteration 87:\tk_eff = 1.191699\tres = 1.780E-03\n", + "[ NORMAL ] Iteration 88:\tk_eff = 1.193567\tres = 1.670E-03\n", + "[ NORMAL ] Iteration 89:\tk_eff = 1.195320\tres = 1.567E-03\n", + "[ NORMAL ] Iteration 90:\tk_eff = 1.196967\tres = 1.469E-03\n", + "[ NORMAL ] Iteration 91:\tk_eff = 1.198513\tres = 1.378E-03\n", + "[ NORMAL ] Iteration 92:\tk_eff = 1.199964\tres = 1.292E-03\n", + "[ NORMAL ] Iteration 93:\tk_eff = 1.201326\tres = 1.211E-03\n", + "[ NORMAL ] Iteration 94:\tk_eff = 1.202602\tres = 1.134E-03\n", + "[ NORMAL ] Iteration 95:\tk_eff = 1.203800\tres = 1.063E-03\n", + "[ NORMAL ] Iteration 96:\tk_eff = 1.204922\tres = 9.955E-04\n", + "[ NORMAL ] Iteration 97:\tk_eff = 1.205974\tres = 9.323E-04\n", + "[ NORMAL ] Iteration 98:\tk_eff = 1.206959\tres = 8.730E-04\n", + "[ NORMAL ] Iteration 99:\tk_eff = 1.207883\tres = 8.173E-04\n", + "[ NORMAL ] Iteration 100:\tk_eff = 1.208747\tres = 7.649E-04\n", + "[ NORMAL ] Iteration 101:\tk_eff = 1.209557\tres = 7.159E-04\n", + "[ NORMAL ] Iteration 102:\tk_eff = 1.210315\tres = 6.698E-04\n", + "[ NORMAL ] Iteration 103:\tk_eff = 1.211024\tres = 6.266E-04\n", + "[ NORMAL ] Iteration 104:\tk_eff = 1.211688\tres = 5.861E-04\n", + "[ NORMAL ] Iteration 105:\tk_eff = 1.212309\tres = 5.481E-04\n", + "[ NORMAL ] Iteration 106:\tk_eff = 1.212890\tres = 5.125E-04\n", + "[ NORMAL ] Iteration 107:\tk_eff = 1.213433\tres = 4.791E-04\n", + "[ NORMAL ] Iteration 108:\tk_eff = 1.213941\tres = 4.479E-04\n", + "[ NORMAL ] Iteration 109:\tk_eff = 1.214416\tres = 4.186E-04\n", + "[ NORMAL ] Iteration 110:\tk_eff = 1.214860\tres = 3.912E-04\n", + "[ NORMAL ] Iteration 111:\tk_eff = 1.215275\tres = 3.655E-04\n", + "[ NORMAL ] Iteration 112:\tk_eff = 1.215662\tres = 3.414E-04\n", + "[ NORMAL ] Iteration 113:\tk_eff = 1.216024\tres = 3.189E-04\n", + "[ NORMAL ] Iteration 114:\tk_eff = 1.216362\tres = 2.979E-04\n", + "[ NORMAL ] Iteration 115:\tk_eff = 1.216678\tres = 2.781E-04\n", + "[ NORMAL ] Iteration 116:\tk_eff = 1.216973\tres = 2.597E-04\n", + "[ NORMAL ] Iteration 117:\tk_eff = 1.217249\tres = 2.425E-04\n", + "[ NORMAL ] Iteration 118:\tk_eff = 1.217506\tres = 2.263E-04\n", + "[ NORMAL ] Iteration 119:\tk_eff = 1.217746\tres = 2.112E-04\n", + "[ NORMAL ] Iteration 120:\tk_eff = 1.217970\tres = 1.971E-04\n", + "[ NORMAL ] Iteration 121:\tk_eff = 1.218179\tres = 1.840E-04\n", + "[ NORMAL ] Iteration 122:\tk_eff = 1.218374\tres = 1.716E-04\n", + "[ NORMAL ] Iteration 123:\tk_eff = 1.218556\tres = 1.601E-04\n", + "[ NORMAL ] Iteration 124:\tk_eff = 1.218726\tres = 1.494E-04\n", + "[ NORMAL ] Iteration 125:\tk_eff = 1.218884\tres = 1.393E-04\n", + "[ NORMAL ] Iteration 126:\tk_eff = 1.219032\tres = 1.299E-04\n", + "[ NORMAL ] Iteration 127:\tk_eff = 1.219170\tres = 1.212E-04\n", + "[ NORMAL ] Iteration 128:\tk_eff = 1.219298\tres = 1.130E-04\n", + "[ NORMAL ] Iteration 129:\tk_eff = 1.219418\tres = 1.053E-04\n", + "[ NORMAL ] Iteration 130:\tk_eff = 1.219529\tres = 9.821E-05\n", + "[ NORMAL ] Iteration 131:\tk_eff = 1.219633\tres = 9.155E-05\n", + "[ NORMAL ] Iteration 132:\tk_eff = 1.219730\tres = 8.534E-05\n", + "[ NORMAL ] Iteration 133:\tk_eff = 1.219821\tres = 7.954E-05\n", + "[ NORMAL ] Iteration 134:\tk_eff = 1.219905\tres = 7.412E-05\n", + "[ NORMAL ] Iteration 135:\tk_eff = 1.219984\tres = 6.907E-05\n", + "[ NORMAL ] Iteration 136:\tk_eff = 1.220057\tres = 6.436E-05\n", + "[ NORMAL ] Iteration 137:\tk_eff = 1.220125\tres = 5.997E-05\n", + "[ NORMAL ] Iteration 138:\tk_eff = 1.220188\tres = 5.587E-05\n", + "[ NORMAL ] Iteration 139:\tk_eff = 1.220248\tres = 5.205E-05\n", + "[ NORMAL ] Iteration 140:\tk_eff = 1.220303\tres = 4.848E-05\n", + "[ NORMAL ] Iteration 141:\tk_eff = 1.220354\tres = 4.516E-05\n", + "[ NORMAL ] Iteration 142:\tk_eff = 1.220402\tres = 4.206E-05\n", + "[ NORMAL ] Iteration 143:\tk_eff = 1.220446\tres = 3.917E-05\n", + "[ NORMAL ] Iteration 144:\tk_eff = 1.220488\tres = 3.648E-05\n", + "[ NORMAL ] Iteration 145:\tk_eff = 1.220526\tres = 3.397E-05\n", + "[ NORMAL ] Iteration 146:\tk_eff = 1.220562\tres = 3.163E-05\n", + "[ NORMAL ] Iteration 147:\tk_eff = 1.220596\tres = 2.945E-05\n", + "[ NORMAL ] Iteration 148:\tk_eff = 1.220627\tres = 2.742E-05\n", + "[ NORMAL ] Iteration 149:\tk_eff = 1.220656\tres = 2.552E-05\n", + "[ NORMAL ] Iteration 150:\tk_eff = 1.220683\tres = 2.376E-05\n", + "[ NORMAL ] Iteration 151:\tk_eff = 1.220708\tres = 2.212E-05\n", + "[ NORMAL ] Iteration 152:\tk_eff = 1.220732\tres = 2.059E-05\n", + "[ NORMAL ] Iteration 153:\tk_eff = 1.220753\tres = 1.916E-05\n", + "[ NORMAL ] Iteration 154:\tk_eff = 1.220774\tres = 1.783E-05\n", + "[ NORMAL ] Iteration 155:\tk_eff = 1.220792\tres = 1.660E-05\n", + "[ NORMAL ] Iteration 156:\tk_eff = 1.220810\tres = 1.545E-05\n", + "[ NORMAL ] Iteration 157:\tk_eff = 1.220826\tres = 1.437E-05\n", + "[ NORMAL ] Iteration 158:\tk_eff = 1.220841\tres = 1.337E-05\n", + "[ NORMAL ] Iteration 159:\tk_eff = 1.220856\tres = 1.244E-05\n", + "[ NORMAL ] Iteration 160:\tk_eff = 1.220869\tres = 1.158E-05\n", + "[ NORMAL ] Iteration 161:\tk_eff = 1.220881\tres = 1.077E-05\n", + "[ NORMAL ] Iteration 162:\tk_eff = 1.220892\tres = 1.002E-05\n" ] } ], "source": [ "# Generate tracks for OpenMOC\n", - "track_generator = openmoc.TrackGenerator(openmoc_geometry, num_azim=128, spacing=0.1)\n", + "track_generator = openmoc.TrackGenerator(openmoc_geometry, num_azim=128, azim_spacing=0.1)\n", "track_generator.generateTracks()\n", "\n", "# Run OpenMOC\n", @@ -1377,7 +1348,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 26, "metadata": { "collapsed": false }, @@ -1387,8 +1358,8 @@ "output_type": "stream", "text": [ "openmc keff = 1.223474\n", - "openmoc keff = 1.220923\n", - "bias [pcm]: -255.0\n" + "openmoc keff = 1.220892\n", + "bias [pcm]: -258.1\n" ] } ], @@ -1412,13 +1383,13 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 27, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "openmoc_geometry = get_openmoc_geometry(su.opencg_geometry)\n", + "openmoc_geometry = get_openmoc_geometry(sp.summary.opencg_geometry)\n", "openmoc_cells = openmoc_geometry.getRootUniverse().getAllCells()\n", "\n", "# Inject multi-group cross sections into OpenMOC Materials\n", @@ -1452,7 +1423,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 28, "metadata": { "collapsed": false }, @@ -1465,241 +1436,241 @@ "[ NORMAL ] Computing the eigenvalue...\n", "[ NORMAL ] Iteration 0:\tk_eff = 0.495816\tres = 0.000E+00\n", "[ NORMAL ] Iteration 1:\tk_eff = 0.557477\tres = 5.042E-01\n", - "[ NORMAL ] Iteration 2:\tk_eff = 0.518301\tres = 1.244E-01\n", - "[ NORMAL ] Iteration 3:\tk_eff = 0.509212\tres = 7.027E-02\n", + "[ NORMAL ] Iteration 2:\tk_eff = 0.518300\tres = 1.244E-01\n", + "[ NORMAL ] Iteration 3:\tk_eff = 0.509211\tres = 7.027E-02\n", "[ NORMAL ] Iteration 4:\tk_eff = 0.496489\tres = 1.754E-02\n", "[ NORMAL ] Iteration 5:\tk_eff = 0.488581\tres = 2.498E-02\n", "[ NORMAL ] Iteration 6:\tk_eff = 0.482897\tres = 1.593E-02\n", "[ NORMAL ] Iteration 7:\tk_eff = 0.479775\tres = 1.163E-02\n", - "[ NORMAL ] Iteration 8:\tk_eff = 0.478835\tres = 6.464E-03\n", - "[ NORMAL ] Iteration 9:\tk_eff = 0.479872\tres = 1.960E-03\n", - "[ NORMAL ] Iteration 10:\tk_eff = 0.482685\tres = 2.166E-03\n", - "[ NORMAL ] Iteration 11:\tk_eff = 0.487085\tres = 5.861E-03\n", - "[ NORMAL ] Iteration 12:\tk_eff = 0.492901\tres = 9.116E-03\n", - "[ NORMAL ] Iteration 13:\tk_eff = 0.499973\tres = 1.194E-02\n", - "[ NORMAL ] Iteration 14:\tk_eff = 0.508155\tres = 1.435E-02\n", - "[ NORMAL ] Iteration 15:\tk_eff = 0.517314\tres = 1.637E-02\n", - "[ NORMAL ] Iteration 16:\tk_eff = 0.527327\tres = 1.802E-02\n", - "[ NORMAL ] Iteration 17:\tk_eff = 0.538081\tres = 1.936E-02\n", - "[ NORMAL ] Iteration 18:\tk_eff = 0.549475\tres = 2.039E-02\n", - "[ NORMAL ] Iteration 19:\tk_eff = 0.561413\tres = 2.117E-02\n", - "[ NORMAL ] Iteration 20:\tk_eff = 0.573810\tres = 2.173E-02\n", - "[ NORMAL ] Iteration 21:\tk_eff = 0.586589\tres = 2.208E-02\n", - "[ NORMAL ] Iteration 22:\tk_eff = 0.599678\tres = 2.227E-02\n", - "[ NORMAL ] Iteration 23:\tk_eff = 0.613012\tres = 2.231E-02\n", - "[ NORMAL ] Iteration 24:\tk_eff = 0.626532\tres = 2.224E-02\n", - "[ NORMAL ] Iteration 25:\tk_eff = 0.640186\tres = 2.206E-02\n", - "[ NORMAL ] Iteration 26:\tk_eff = 0.653925\tres = 2.179E-02\n", - "[ NORMAL ] Iteration 27:\tk_eff = 0.667706\tres = 2.146E-02\n", - "[ NORMAL ] Iteration 28:\tk_eff = 0.681489\tres = 2.107E-02\n", - "[ NORMAL ] Iteration 29:\tk_eff = 0.695240\tres = 2.064E-02\n", - "[ NORMAL ] Iteration 30:\tk_eff = 0.708927\tres = 2.018E-02\n", - "[ NORMAL ] Iteration 31:\tk_eff = 0.722522\tres = 1.969E-02\n", - "[ NORMAL ] Iteration 32:\tk_eff = 0.736000\tres = 1.918E-02\n", - "[ NORMAL ] Iteration 33:\tk_eff = 0.749339\tres = 1.865E-02\n", - "[ NORMAL ] Iteration 34:\tk_eff = 0.762519\tres = 1.812E-02\n", - "[ NORMAL ] Iteration 35:\tk_eff = 0.775522\tres = 1.759E-02\n", - "[ NORMAL ] Iteration 36:\tk_eff = 0.788335\tres = 1.705E-02\n", - "[ NORMAL ] Iteration 37:\tk_eff = 0.800944\tres = 1.652E-02\n", - "[ NORMAL ] Iteration 38:\tk_eff = 0.813338\tres = 1.599E-02\n", - "[ NORMAL ] Iteration 39:\tk_eff = 0.825507\tres = 1.547E-02\n", - "[ NORMAL ] Iteration 40:\tk_eff = 0.837444\tres = 1.496E-02\n", - "[ NORMAL ] Iteration 41:\tk_eff = 0.849142\tres = 1.446E-02\n", - "[ NORMAL ] Iteration 42:\tk_eff = 0.860595\tres = 1.397E-02\n", - "[ NORMAL ] Iteration 43:\tk_eff = 0.871801\tres = 1.349E-02\n", - "[ NORMAL ] Iteration 44:\tk_eff = 0.882755\tres = 1.302E-02\n", - "[ NORMAL ] Iteration 45:\tk_eff = 0.893455\tres = 1.256E-02\n", - "[ NORMAL ] Iteration 46:\tk_eff = 0.903901\tres = 1.212E-02\n", - "[ NORMAL ] Iteration 47:\tk_eff = 0.914091\tres = 1.169E-02\n", - "[ NORMAL ] Iteration 48:\tk_eff = 0.924027\tres = 1.127E-02\n", - "[ NORMAL ] Iteration 49:\tk_eff = 0.933708\tres = 1.087E-02\n", - "[ NORMAL ] Iteration 50:\tk_eff = 0.943137\tres = 1.048E-02\n", - "[ NORMAL ] Iteration 51:\tk_eff = 0.952314\tres = 1.010E-02\n", - "[ NORMAL ] Iteration 52:\tk_eff = 0.961243\tres = 9.731E-03\n", - "[ NORMAL ] Iteration 53:\tk_eff = 0.969927\tres = 9.376E-03\n", - "[ NORMAL ] Iteration 54:\tk_eff = 0.978367\tres = 9.033E-03\n", - "[ NORMAL ] Iteration 55:\tk_eff = 0.986568\tres = 8.702E-03\n", - "[ NORMAL ] Iteration 56:\tk_eff = 0.994534\tres = 8.382E-03\n", - "[ NORMAL ] Iteration 57:\tk_eff = 1.002267\tres = 8.074E-03\n", - "[ NORMAL ] Iteration 58:\tk_eff = 1.009773\tres = 7.776E-03\n", - "[ NORMAL ] Iteration 59:\tk_eff = 1.017055\tres = 7.489E-03\n", - "[ NORMAL ] Iteration 60:\tk_eff = 1.024118\tres = 7.212E-03\n", - "[ NORMAL ] Iteration 61:\tk_eff = 1.030966\tres = 6.944E-03\n", - "[ NORMAL ] Iteration 62:\tk_eff = 1.037603\tres = 6.687E-03\n", - "[ NORMAL ] Iteration 63:\tk_eff = 1.044036\tres = 6.438E-03\n", - "[ NORMAL ] Iteration 64:\tk_eff = 1.050267\tres = 6.199E-03\n", - "[ NORMAL ] Iteration 65:\tk_eff = 1.056302\tres = 5.968E-03\n", - "[ NORMAL ] Iteration 66:\tk_eff = 1.062145\tres = 5.746E-03\n", - "[ NORMAL ] Iteration 67:\tk_eff = 1.067802\tres = 5.532E-03\n", - "[ NORMAL ] Iteration 68:\tk_eff = 1.073276\tres = 5.326E-03\n", - "[ NORMAL ] Iteration 69:\tk_eff = 1.078573\tres = 5.127E-03\n", - "[ NORMAL ] Iteration 70:\tk_eff = 1.083698\tres = 4.935E-03\n", - "[ NORMAL ] Iteration 71:\tk_eff = 1.088654\tres = 4.751E-03\n", - "[ NORMAL ] Iteration 72:\tk_eff = 1.093447\tres = 4.573E-03\n", - "[ NORMAL ] Iteration 73:\tk_eff = 1.098080\tres = 4.402E-03\n", - "[ NORMAL ] Iteration 74:\tk_eff = 1.102560\tres = 4.238E-03\n", - "[ NORMAL ] Iteration 75:\tk_eff = 1.106889\tres = 4.079E-03\n", - "[ NORMAL ] Iteration 76:\tk_eff = 1.111072\tres = 3.926E-03\n", - "[ NORMAL ] Iteration 77:\tk_eff = 1.115114\tres = 3.779E-03\n", - "[ NORMAL ] Iteration 78:\tk_eff = 1.119018\tres = 3.638E-03\n", - "[ NORMAL ] Iteration 79:\tk_eff = 1.122790\tres = 3.501E-03\n", - "[ NORMAL ] Iteration 80:\tk_eff = 1.126432\tres = 3.370E-03\n", - "[ NORMAL ] Iteration 81:\tk_eff = 1.129949\tres = 3.244E-03\n", - "[ NORMAL ] Iteration 82:\tk_eff = 1.133344\tres = 3.122E-03\n", - "[ NORMAL ] Iteration 83:\tk_eff = 1.136622\tres = 3.005E-03\n", - "[ NORMAL ] Iteration 84:\tk_eff = 1.139786\tres = 2.892E-03\n", - "[ NORMAL ] Iteration 85:\tk_eff = 1.142840\tres = 2.784E-03\n", - "[ NORMAL ] Iteration 86:\tk_eff = 1.145786\tres = 2.679E-03\n", - "[ NORMAL ] Iteration 87:\tk_eff = 1.148630\tres = 2.579E-03\n", - "[ NORMAL ] Iteration 88:\tk_eff = 1.151373\tres = 2.482E-03\n", - "[ NORMAL ] Iteration 89:\tk_eff = 1.154020\tres = 2.388E-03\n", - "[ NORMAL ] Iteration 90:\tk_eff = 1.156573\tres = 2.299E-03\n", - "[ NORMAL ] Iteration 91:\tk_eff = 1.159035\tres = 2.212E-03\n", - "[ NORMAL ] Iteration 92:\tk_eff = 1.161410\tres = 2.129E-03\n", - "[ NORMAL ] Iteration 93:\tk_eff = 1.163700\tres = 2.049E-03\n", - "[ NORMAL ] Iteration 94:\tk_eff = 1.165909\tres = 1.972E-03\n", - "[ NORMAL ] Iteration 95:\tk_eff = 1.168038\tres = 1.898E-03\n", - "[ NORMAL ] Iteration 96:\tk_eff = 1.170091\tres = 1.826E-03\n", - "[ NORMAL ] Iteration 97:\tk_eff = 1.172070\tres = 1.758E-03\n", - "[ NORMAL ] Iteration 98:\tk_eff = 1.173977\tres = 1.691E-03\n", - "[ NORMAL ] Iteration 99:\tk_eff = 1.175816\tres = 1.628E-03\n", - "[ NORMAL ] Iteration 100:\tk_eff = 1.177589\tres = 1.566E-03\n", - "[ NORMAL ] Iteration 101:\tk_eff = 1.179297\tres = 1.507E-03\n", - "[ NORMAL ] Iteration 102:\tk_eff = 1.180943\tres = 1.451E-03\n", - "[ NORMAL ] Iteration 103:\tk_eff = 1.182529\tres = 1.396E-03\n", - "[ NORMAL ] Iteration 104:\tk_eff = 1.184058\tres = 1.343E-03\n", - "[ NORMAL ] Iteration 105:\tk_eff = 1.185530\tres = 1.293E-03\n", - "[ NORMAL ] Iteration 106:\tk_eff = 1.186949\tres = 1.244E-03\n", - "[ NORMAL ] Iteration 107:\tk_eff = 1.188316\tres = 1.197E-03\n", - "[ NORMAL ] Iteration 108:\tk_eff = 1.189633\tres = 1.152E-03\n", - "[ NORMAL ] Iteration 109:\tk_eff = 1.190902\tres = 1.108E-03\n", - "[ NORMAL ] Iteration 110:\tk_eff = 1.192124\tres = 1.066E-03\n", - "[ NORMAL ] Iteration 111:\tk_eff = 1.193301\tres = 1.026E-03\n", - "[ NORMAL ] Iteration 112:\tk_eff = 1.194435\tres = 9.874E-04\n", - "[ NORMAL ] Iteration 113:\tk_eff = 1.195527\tres = 9.501E-04\n", - "[ NORMAL ] Iteration 114:\tk_eff = 1.196578\tres = 9.142E-04\n", - "[ NORMAL ] Iteration 115:\tk_eff = 1.197591\tres = 8.797E-04\n", - "[ NORMAL ] Iteration 116:\tk_eff = 1.198566\tres = 8.464E-04\n", - "[ NORMAL ] Iteration 117:\tk_eff = 1.199506\tres = 8.144E-04\n", - "[ NORMAL ] Iteration 118:\tk_eff = 1.200410\tres = 7.836E-04\n", - "[ NORMAL ] Iteration 119:\tk_eff = 1.201281\tres = 7.540E-04\n", - "[ NORMAL ] Iteration 120:\tk_eff = 1.202119\tres = 7.255E-04\n", - "[ NORMAL ] Iteration 121:\tk_eff = 1.202927\tres = 6.980E-04\n", - "[ NORMAL ] Iteration 122:\tk_eff = 1.203704\tres = 6.716E-04\n", - "[ NORMAL ] Iteration 123:\tk_eff = 1.204452\tres = 6.462E-04\n", - "[ NORMAL ] Iteration 124:\tk_eff = 1.205173\tres = 6.217E-04\n", - "[ NORMAL ] Iteration 125:\tk_eff = 1.205867\tres = 5.982E-04\n", - "[ NORMAL ] Iteration 126:\tk_eff = 1.206534\tres = 5.755E-04\n", - "[ NORMAL ] Iteration 127:\tk_eff = 1.207177\tres = 5.537E-04\n", - "[ NORMAL ] Iteration 128:\tk_eff = 1.207796\tres = 5.327E-04\n", - "[ NORMAL ] Iteration 129:\tk_eff = 1.208391\tres = 5.126E-04\n", - "[ NORMAL ] Iteration 130:\tk_eff = 1.208965\tres = 4.931E-04\n", - "[ NORMAL ] Iteration 131:\tk_eff = 1.209517\tres = 4.744E-04\n", - "[ NORMAL ] Iteration 132:\tk_eff = 1.210048\tres = 4.565E-04\n", - "[ NORMAL ] Iteration 133:\tk_eff = 1.210559\tres = 4.391E-04\n", - "[ NORMAL ] Iteration 134:\tk_eff = 1.211051\tres = 4.225E-04\n", - "[ NORMAL ] Iteration 135:\tk_eff = 1.211525\tres = 4.065E-04\n", - "[ NORMAL ] Iteration 136:\tk_eff = 1.211980\tres = 3.910E-04\n", - "[ NORMAL ] Iteration 137:\tk_eff = 1.212419\tres = 3.762E-04\n", - "[ NORMAL ] Iteration 138:\tk_eff = 1.212841\tres = 3.619E-04\n", - "[ NORMAL ] Iteration 139:\tk_eff = 1.213247\tres = 3.482E-04\n", - "[ NORMAL ] Iteration 140:\tk_eff = 1.213638\tres = 3.350E-04\n", - "[ NORMAL ] Iteration 141:\tk_eff = 1.214015\tres = 3.222E-04\n", - "[ NORMAL ] Iteration 142:\tk_eff = 1.214377\tres = 3.100E-04\n", - "[ NORMAL ] Iteration 143:\tk_eff = 1.214725\tres = 2.982E-04\n", - "[ NORMAL ] Iteration 144:\tk_eff = 1.215060\tres = 2.869E-04\n", - "[ NORMAL ] Iteration 145:\tk_eff = 1.215383\tres = 2.760E-04\n", - "[ NORMAL ] Iteration 146:\tk_eff = 1.215693\tres = 2.655E-04\n", - "[ NORMAL ] Iteration 147:\tk_eff = 1.215992\tres = 2.554E-04\n", - "[ NORMAL ] Iteration 148:\tk_eff = 1.216280\tres = 2.457E-04\n", - "[ NORMAL ] Iteration 149:\tk_eff = 1.216556\tres = 2.364E-04\n", - "[ NORMAL ] Iteration 150:\tk_eff = 1.216822\tres = 2.274E-04\n", - "[ NORMAL ] Iteration 151:\tk_eff = 1.217078\tres = 2.187E-04\n", - "[ NORMAL ] Iteration 152:\tk_eff = 1.217325\tres = 2.104E-04\n", - "[ NORMAL ] Iteration 153:\tk_eff = 1.217562\tres = 2.024E-04\n", - "[ NORMAL ] Iteration 154:\tk_eff = 1.217790\tres = 1.947E-04\n", - "[ NORMAL ] Iteration 155:\tk_eff = 1.218009\tres = 1.873E-04\n", - "[ NORMAL ] Iteration 156:\tk_eff = 1.218220\tres = 1.802E-04\n", - "[ NORMAL ] Iteration 157:\tk_eff = 1.218423\tres = 1.733E-04\n", - "[ NORMAL ] Iteration 158:\tk_eff = 1.218619\tres = 1.667E-04\n", - "[ NORMAL ] Iteration 159:\tk_eff = 1.218807\tres = 1.604E-04\n", - "[ NORMAL ] Iteration 160:\tk_eff = 1.218988\tres = 1.543E-04\n", - "[ NORMAL ] Iteration 161:\tk_eff = 1.219162\tres = 1.484E-04\n", - "[ NORMAL ] Iteration 162:\tk_eff = 1.219329\tres = 1.428E-04\n", - "[ NORMAL ] Iteration 163:\tk_eff = 1.219490\tres = 1.373E-04\n", - "[ NORMAL ] Iteration 164:\tk_eff = 1.219645\tres = 1.321E-04\n", - "[ NORMAL ] Iteration 165:\tk_eff = 1.219794\tres = 1.271E-04\n", - "[ NORMAL ] Iteration 166:\tk_eff = 1.219938\tres = 1.222E-04\n", - "[ NORMAL ] Iteration 167:\tk_eff = 1.220076\tres = 1.176E-04\n", - "[ NORMAL ] Iteration 168:\tk_eff = 1.220208\tres = 1.131E-04\n", - "[ NORMAL ] Iteration 169:\tk_eff = 1.220336\tres = 1.088E-04\n", - "[ NORMAL ] Iteration 170:\tk_eff = 1.220459\tres = 1.046E-04\n", - "[ NORMAL ] Iteration 171:\tk_eff = 1.220577\tres = 1.006E-04\n", - "[ NORMAL ] Iteration 172:\tk_eff = 1.220691\tres = 9.681E-05\n", - "[ NORMAL ] Iteration 173:\tk_eff = 1.220800\tres = 9.312E-05\n", - "[ NORMAL ] Iteration 174:\tk_eff = 1.220905\tres = 8.957E-05\n", - "[ NORMAL ] Iteration 175:\tk_eff = 1.221006\tres = 8.615E-05\n", - "[ NORMAL ] Iteration 176:\tk_eff = 1.221104\tres = 8.287E-05\n", - "[ NORMAL ] Iteration 177:\tk_eff = 1.221197\tres = 7.971E-05\n", - "[ NORMAL ] Iteration 178:\tk_eff = 1.221287\tres = 7.667E-05\n", - "[ NORMAL ] Iteration 179:\tk_eff = 1.221374\tres = 7.374E-05\n", - "[ NORMAL ] Iteration 180:\tk_eff = 1.221457\tres = 7.093E-05\n", - "[ NORMAL ] Iteration 181:\tk_eff = 1.221537\tres = 6.823E-05\n", - "[ NORMAL ] Iteration 182:\tk_eff = 1.221615\tres = 6.562E-05\n", - "[ NORMAL ] Iteration 183:\tk_eff = 1.221689\tres = 6.312E-05\n", - "[ NORMAL ] Iteration 184:\tk_eff = 1.221760\tres = 6.071E-05\n", - "[ NORMAL ] Iteration 185:\tk_eff = 1.221829\tres = 5.840E-05\n", - "[ NORMAL ] Iteration 186:\tk_eff = 1.221895\tres = 5.617E-05\n", - "[ NORMAL ] Iteration 187:\tk_eff = 1.221958\tres = 5.402E-05\n", - "[ NORMAL ] Iteration 188:\tk_eff = 1.222019\tres = 5.196E-05\n", - "[ NORMAL ] Iteration 189:\tk_eff = 1.222078\tres = 4.998E-05\n", - "[ NORMAL ] Iteration 190:\tk_eff = 1.222134\tres = 4.807E-05\n", - "[ NORMAL ] Iteration 191:\tk_eff = 1.222189\tres = 4.624E-05\n", - "[ NORMAL ] Iteration 192:\tk_eff = 1.222241\tres = 4.447E-05\n", - "[ NORMAL ] Iteration 193:\tk_eff = 1.222291\tres = 4.277E-05\n", - "[ NORMAL ] Iteration 194:\tk_eff = 1.222340\tres = 4.114E-05\n", - "[ NORMAL ] Iteration 195:\tk_eff = 1.222386\tres = 3.957E-05\n", - "[ NORMAL ] Iteration 196:\tk_eff = 1.222431\tres = 3.806E-05\n", - "[ NORMAL ] Iteration 197:\tk_eff = 1.222474\tres = 3.661E-05\n", - "[ NORMAL ] Iteration 198:\tk_eff = 1.222515\tres = 3.521E-05\n", - "[ NORMAL ] Iteration 199:\tk_eff = 1.222555\tres = 3.386E-05\n", - "[ NORMAL ] Iteration 200:\tk_eff = 1.222594\tres = 3.257E-05\n", - "[ NORMAL ] Iteration 201:\tk_eff = 1.222630\tres = 3.133E-05\n", - "[ NORMAL ] Iteration 202:\tk_eff = 1.222666\tres = 3.013E-05\n", - "[ NORMAL ] Iteration 203:\tk_eff = 1.222700\tres = 2.898E-05\n", - "[ NORMAL ] Iteration 204:\tk_eff = 1.222733\tres = 2.787E-05\n", - "[ NORMAL ] Iteration 205:\tk_eff = 1.222764\tres = 2.681E-05\n", - "[ NORMAL ] Iteration 206:\tk_eff = 1.222795\tres = 2.578E-05\n", - "[ NORMAL ] Iteration 207:\tk_eff = 1.222824\tres = 2.480E-05\n", - "[ NORMAL ] Iteration 208:\tk_eff = 1.222852\tres = 2.385E-05\n", - "[ NORMAL ] Iteration 209:\tk_eff = 1.222879\tres = 2.294E-05\n", - "[ NORMAL ] Iteration 210:\tk_eff = 1.222905\tres = 2.206E-05\n", - "[ NORMAL ] Iteration 211:\tk_eff = 1.222930\tres = 2.122E-05\n", - "[ NORMAL ] Iteration 212:\tk_eff = 1.222954\tres = 2.041E-05\n", - "[ NORMAL ] Iteration 213:\tk_eff = 1.222977\tres = 1.963E-05\n", - "[ NORMAL ] Iteration 214:\tk_eff = 1.222999\tres = 1.888E-05\n", - "[ NORMAL ] Iteration 215:\tk_eff = 1.223020\tres = 1.816E-05\n", - "[ NORMAL ] Iteration 216:\tk_eff = 1.223041\tres = 1.747E-05\n", - "[ NORMAL ] Iteration 217:\tk_eff = 1.223061\tres = 1.680E-05\n", - "[ NORMAL ] Iteration 218:\tk_eff = 1.223080\tres = 1.616E-05\n", - "[ NORMAL ] Iteration 219:\tk_eff = 1.223098\tres = 1.554E-05\n", - "[ NORMAL ] Iteration 220:\tk_eff = 1.223116\tres = 1.495E-05\n", - "[ NORMAL ] Iteration 221:\tk_eff = 1.223132\tres = 1.437E-05\n", - "[ NORMAL ] Iteration 222:\tk_eff = 1.223149\tres = 1.382E-05\n", - "[ NORMAL ] Iteration 223:\tk_eff = 1.223164\tres = 1.330E-05\n", - "[ NORMAL ] Iteration 224:\tk_eff = 1.223179\tres = 1.279E-05\n", - "[ NORMAL ] Iteration 225:\tk_eff = 1.223194\tres = 1.230E-05\n", - "[ NORMAL ] Iteration 226:\tk_eff = 1.223208\tres = 1.183E-05\n", - "[ NORMAL ] Iteration 227:\tk_eff = 1.223221\tres = 1.138E-05\n", - "[ NORMAL ] Iteration 228:\tk_eff = 1.223234\tres = 1.094E-05\n", - "[ NORMAL ] Iteration 229:\tk_eff = 1.223246\tres = 1.052E-05\n", - "[ NORMAL ] Iteration 230:\tk_eff = 1.223258\tres = 1.012E-05\n" + "[ NORMAL ] Iteration 8:\tk_eff = 0.478834\tres = 6.465E-03\n", + "[ NORMAL ] Iteration 9:\tk_eff = 0.479871\tres = 1.960E-03\n", + "[ NORMAL ] Iteration 10:\tk_eff = 0.482684\tres = 2.166E-03\n", + "[ NORMAL ] Iteration 11:\tk_eff = 0.487084\tres = 5.861E-03\n", + "[ NORMAL ] Iteration 12:\tk_eff = 0.492900\tres = 9.116E-03\n", + "[ NORMAL ] Iteration 13:\tk_eff = 0.499971\tres = 1.194E-02\n", + "[ NORMAL ] Iteration 14:\tk_eff = 0.508153\tres = 1.435E-02\n", + "[ NORMAL ] Iteration 15:\tk_eff = 0.517312\tres = 1.637E-02\n", + "[ NORMAL ] Iteration 16:\tk_eff = 0.527324\tres = 1.802E-02\n", + "[ NORMAL ] Iteration 17:\tk_eff = 0.538079\tres = 1.935E-02\n", + "[ NORMAL ] Iteration 18:\tk_eff = 0.549472\tres = 2.039E-02\n", + "[ NORMAL ] Iteration 19:\tk_eff = 0.561410\tres = 2.117E-02\n", + "[ NORMAL ] Iteration 20:\tk_eff = 0.573807\tres = 2.173E-02\n", + "[ NORMAL ] Iteration 21:\tk_eff = 0.586585\tres = 2.208E-02\n", + "[ NORMAL ] Iteration 22:\tk_eff = 0.599674\tres = 2.227E-02\n", + "[ NORMAL ] Iteration 23:\tk_eff = 0.613007\tres = 2.231E-02\n", + "[ NORMAL ] Iteration 24:\tk_eff = 0.626528\tres = 2.223E-02\n", + "[ NORMAL ] Iteration 25:\tk_eff = 0.640181\tres = 2.206E-02\n", + "[ NORMAL ] Iteration 26:\tk_eff = 0.653920\tres = 2.179E-02\n", + "[ NORMAL ] Iteration 27:\tk_eff = 0.667700\tres = 2.146E-02\n", + "[ NORMAL ] Iteration 28:\tk_eff = 0.681483\tres = 2.107E-02\n", + "[ NORMAL ] Iteration 29:\tk_eff = 0.695234\tres = 2.064E-02\n", + "[ NORMAL ] Iteration 30:\tk_eff = 0.708921\tres = 2.018E-02\n", + "[ NORMAL ] Iteration 31:\tk_eff = 0.722515\tres = 1.969E-02\n", + "[ NORMAL ] Iteration 32:\tk_eff = 0.735993\tres = 1.918E-02\n", + "[ NORMAL ] Iteration 33:\tk_eff = 0.749331\tres = 1.865E-02\n", + "[ NORMAL ] Iteration 34:\tk_eff = 0.762510\tres = 1.812E-02\n", + "[ NORMAL ] Iteration 35:\tk_eff = 0.775514\tres = 1.759E-02\n", + "[ NORMAL ] Iteration 36:\tk_eff = 0.788326\tres = 1.705E-02\n", + "[ NORMAL ] Iteration 37:\tk_eff = 0.800934\tres = 1.652E-02\n", + "[ NORMAL ] Iteration 38:\tk_eff = 0.813328\tres = 1.599E-02\n", + "[ NORMAL ] Iteration 39:\tk_eff = 0.825497\tres = 1.547E-02\n", + "[ NORMAL ] Iteration 40:\tk_eff = 0.837433\tres = 1.496E-02\n", + "[ NORMAL ] Iteration 41:\tk_eff = 0.849131\tres = 1.446E-02\n", + "[ NORMAL ] Iteration 42:\tk_eff = 0.860584\tres = 1.397E-02\n", + "[ NORMAL ] Iteration 43:\tk_eff = 0.871789\tres = 1.349E-02\n", + "[ NORMAL ] Iteration 44:\tk_eff = 0.882742\tres = 1.302E-02\n", + "[ NORMAL ] Iteration 45:\tk_eff = 0.893442\tres = 1.256E-02\n", + "[ NORMAL ] Iteration 46:\tk_eff = 0.903888\tres = 1.212E-02\n", + "[ NORMAL ] Iteration 47:\tk_eff = 0.914078\tres = 1.169E-02\n", + "[ NORMAL ] Iteration 48:\tk_eff = 0.924013\tres = 1.127E-02\n", + "[ NORMAL ] Iteration 49:\tk_eff = 0.933694\tres = 1.087E-02\n", + "[ NORMAL ] Iteration 50:\tk_eff = 0.943122\tres = 1.048E-02\n", + "[ NORMAL ] Iteration 51:\tk_eff = 0.952299\tres = 1.010E-02\n", + "[ NORMAL ] Iteration 52:\tk_eff = 0.961228\tres = 9.731E-03\n", + "[ NORMAL ] Iteration 53:\tk_eff = 0.969911\tres = 9.376E-03\n", + "[ NORMAL ] Iteration 54:\tk_eff = 0.978351\tres = 9.033E-03\n", + "[ NORMAL ] Iteration 55:\tk_eff = 0.986552\tres = 8.702E-03\n", + "[ NORMAL ] Iteration 56:\tk_eff = 0.994517\tres = 8.382E-03\n", + "[ NORMAL ] Iteration 57:\tk_eff = 1.002250\tres = 8.074E-03\n", + "[ NORMAL ] Iteration 58:\tk_eff = 1.009756\tres = 7.776E-03\n", + "[ NORMAL ] Iteration 59:\tk_eff = 1.017037\tres = 7.488E-03\n", + "[ NORMAL ] Iteration 60:\tk_eff = 1.024100\tres = 7.211E-03\n", + "[ NORMAL ] Iteration 61:\tk_eff = 1.030948\tres = 6.944E-03\n", + "[ NORMAL ] Iteration 62:\tk_eff = 1.037585\tres = 6.687E-03\n", + "[ NORMAL ] Iteration 63:\tk_eff = 1.044017\tres = 6.438E-03\n", + "[ NORMAL ] Iteration 64:\tk_eff = 1.050248\tres = 6.199E-03\n", + "[ NORMAL ] Iteration 65:\tk_eff = 1.056282\tres = 5.968E-03\n", + "[ NORMAL ] Iteration 66:\tk_eff = 1.062125\tres = 5.746E-03\n", + "[ NORMAL ] Iteration 67:\tk_eff = 1.067782\tres = 5.532E-03\n", + "[ NORMAL ] Iteration 68:\tk_eff = 1.073256\tres = 5.325E-03\n", + "[ NORMAL ] Iteration 69:\tk_eff = 1.078553\tres = 5.127E-03\n", + "[ NORMAL ] Iteration 70:\tk_eff = 1.083677\tres = 4.935E-03\n", + "[ NORMAL ] Iteration 71:\tk_eff = 1.088633\tres = 4.751E-03\n", + "[ NORMAL ] Iteration 72:\tk_eff = 1.093425\tres = 4.573E-03\n", + "[ NORMAL ] Iteration 73:\tk_eff = 1.098059\tres = 4.402E-03\n", + "[ NORMAL ] Iteration 74:\tk_eff = 1.102538\tres = 4.238E-03\n", + "[ NORMAL ] Iteration 75:\tk_eff = 1.106867\tres = 4.079E-03\n", + "[ NORMAL ] Iteration 76:\tk_eff = 1.111050\tres = 3.926E-03\n", + "[ NORMAL ] Iteration 77:\tk_eff = 1.115091\tres = 3.779E-03\n", + "[ NORMAL ] Iteration 78:\tk_eff = 1.118996\tres = 3.638E-03\n", + "[ NORMAL ] Iteration 79:\tk_eff = 1.122767\tres = 3.501E-03\n", + "[ NORMAL ] Iteration 80:\tk_eff = 1.126408\tres = 3.370E-03\n", + "[ NORMAL ] Iteration 81:\tk_eff = 1.129925\tres = 3.244E-03\n", + "[ NORMAL ] Iteration 82:\tk_eff = 1.133320\tres = 3.122E-03\n", + "[ NORMAL ] Iteration 83:\tk_eff = 1.136598\tres = 3.005E-03\n", + "[ NORMAL ] Iteration 84:\tk_eff = 1.139762\tres = 2.892E-03\n", + "[ NORMAL ] Iteration 85:\tk_eff = 1.142815\tres = 2.784E-03\n", + "[ NORMAL ] Iteration 86:\tk_eff = 1.145762\tres = 2.679E-03\n", + "[ NORMAL ] Iteration 87:\tk_eff = 1.148605\tres = 2.578E-03\n", + "[ NORMAL ] Iteration 88:\tk_eff = 1.151348\tres = 2.482E-03\n", + "[ NORMAL ] Iteration 89:\tk_eff = 1.153995\tres = 2.388E-03\n", + "[ NORMAL ] Iteration 90:\tk_eff = 1.156548\tres = 2.299E-03\n", + "[ NORMAL ] Iteration 91:\tk_eff = 1.159010\tres = 2.212E-03\n", + "[ NORMAL ] Iteration 92:\tk_eff = 1.161384\tres = 2.129E-03\n", + "[ NORMAL ] Iteration 93:\tk_eff = 1.163674\tres = 2.049E-03\n", + "[ NORMAL ] Iteration 94:\tk_eff = 1.165883\tres = 1.972E-03\n", + "[ NORMAL ] Iteration 95:\tk_eff = 1.168012\tres = 1.898E-03\n", + "[ NORMAL ] Iteration 96:\tk_eff = 1.170064\tres = 1.826E-03\n", + "[ NORMAL ] Iteration 97:\tk_eff = 1.172043\tres = 1.757E-03\n", + "[ NORMAL ] Iteration 98:\tk_eff = 1.173951\tres = 1.691E-03\n", + "[ NORMAL ] Iteration 99:\tk_eff = 1.175790\tres = 1.628E-03\n", + "[ NORMAL ] Iteration 100:\tk_eff = 1.177562\tres = 1.566E-03\n", + "[ NORMAL ] Iteration 101:\tk_eff = 1.179270\tres = 1.507E-03\n", + "[ NORMAL ] Iteration 102:\tk_eff = 1.180916\tres = 1.450E-03\n", + "[ NORMAL ] Iteration 103:\tk_eff = 1.182502\tres = 1.396E-03\n", + "[ NORMAL ] Iteration 104:\tk_eff = 1.184030\tres = 1.343E-03\n", + "[ NORMAL ] Iteration 105:\tk_eff = 1.185503\tres = 1.292E-03\n", + "[ NORMAL ] Iteration 106:\tk_eff = 1.186922\tres = 1.244E-03\n", + "[ NORMAL ] Iteration 107:\tk_eff = 1.188289\tres = 1.197E-03\n", + "[ NORMAL ] Iteration 108:\tk_eff = 1.189605\tres = 1.152E-03\n", + "[ NORMAL ] Iteration 109:\tk_eff = 1.190874\tres = 1.108E-03\n", + "[ NORMAL ] Iteration 110:\tk_eff = 1.192096\tres = 1.066E-03\n", + "[ NORMAL ] Iteration 111:\tk_eff = 1.193273\tres = 1.026E-03\n", + "[ NORMAL ] Iteration 112:\tk_eff = 1.194407\tres = 9.873E-04\n", + "[ NORMAL ] Iteration 113:\tk_eff = 1.195498\tres = 9.500E-04\n", + "[ NORMAL ] Iteration 114:\tk_eff = 1.196550\tres = 9.141E-04\n", + "[ NORMAL ] Iteration 115:\tk_eff = 1.197563\tres = 8.796E-04\n", + "[ NORMAL ] Iteration 116:\tk_eff = 1.198538\tres = 8.464E-04\n", + "[ NORMAL ] Iteration 117:\tk_eff = 1.199477\tres = 8.144E-04\n", + "[ NORMAL ] Iteration 118:\tk_eff = 1.200381\tres = 7.836E-04\n", + "[ NORMAL ] Iteration 119:\tk_eff = 1.201252\tres = 7.539E-04\n", + "[ NORMAL ] Iteration 120:\tk_eff = 1.202091\tres = 7.254E-04\n", + "[ NORMAL ] Iteration 121:\tk_eff = 1.202898\tres = 6.980E-04\n", + "[ NORMAL ] Iteration 122:\tk_eff = 1.203675\tres = 6.715E-04\n", + "[ NORMAL ] Iteration 123:\tk_eff = 1.204423\tres = 6.461E-04\n", + "[ NORMAL ] Iteration 124:\tk_eff = 1.205144\tres = 6.217E-04\n", + "[ NORMAL ] Iteration 125:\tk_eff = 1.205837\tres = 5.981E-04\n", + "[ NORMAL ] Iteration 126:\tk_eff = 1.206505\tres = 5.755E-04\n", + "[ NORMAL ] Iteration 127:\tk_eff = 1.207148\tres = 5.537E-04\n", + "[ NORMAL ] Iteration 128:\tk_eff = 1.207766\tres = 5.327E-04\n", + "[ NORMAL ] Iteration 129:\tk_eff = 1.208362\tres = 5.125E-04\n", + "[ NORMAL ] Iteration 130:\tk_eff = 1.208935\tres = 4.931E-04\n", + "[ NORMAL ] Iteration 131:\tk_eff = 1.209487\tres = 4.744E-04\n", + "[ NORMAL ] Iteration 132:\tk_eff = 1.210018\tres = 4.564E-04\n", + "[ NORMAL ] Iteration 133:\tk_eff = 1.210529\tres = 4.391E-04\n", + "[ NORMAL ] Iteration 134:\tk_eff = 1.211021\tres = 4.225E-04\n", + "[ NORMAL ] Iteration 135:\tk_eff = 1.211495\tres = 4.064E-04\n", + "[ NORMAL ] Iteration 136:\tk_eff = 1.211950\tres = 3.910E-04\n", + "[ NORMAL ] Iteration 137:\tk_eff = 1.212389\tres = 3.762E-04\n", + "[ NORMAL ] Iteration 138:\tk_eff = 1.212811\tres = 3.619E-04\n", + "[ NORMAL ] Iteration 139:\tk_eff = 1.213217\tres = 3.482E-04\n", + "[ NORMAL ] Iteration 140:\tk_eff = 1.213608\tres = 3.349E-04\n", + "[ NORMAL ] Iteration 141:\tk_eff = 1.213984\tres = 3.222E-04\n", + "[ NORMAL ] Iteration 142:\tk_eff = 1.214346\tres = 3.100E-04\n", + "[ NORMAL ] Iteration 143:\tk_eff = 1.214695\tres = 2.982E-04\n", + "[ NORMAL ] Iteration 144:\tk_eff = 1.215030\tres = 2.869E-04\n", + "[ NORMAL ] Iteration 145:\tk_eff = 1.215353\tres = 2.760E-04\n", + "[ NORMAL ] Iteration 146:\tk_eff = 1.215663\tres = 2.655E-04\n", + "[ NORMAL ] Iteration 147:\tk_eff = 1.215962\tres = 2.554E-04\n", + "[ NORMAL ] Iteration 148:\tk_eff = 1.216249\tres = 2.457E-04\n", + "[ NORMAL ] Iteration 149:\tk_eff = 1.216526\tres = 2.364E-04\n", + "[ NORMAL ] Iteration 150:\tk_eff = 1.216792\tres = 2.274E-04\n", + "[ NORMAL ] Iteration 151:\tk_eff = 1.217048\tres = 2.187E-04\n", + "[ NORMAL ] Iteration 152:\tk_eff = 1.217294\tres = 2.104E-04\n", + "[ NORMAL ] Iteration 153:\tk_eff = 1.217531\tres = 2.024E-04\n", + "[ NORMAL ] Iteration 154:\tk_eff = 1.217759\tres = 1.947E-04\n", + "[ NORMAL ] Iteration 155:\tk_eff = 1.217979\tres = 1.873E-04\n", + "[ NORMAL ] Iteration 156:\tk_eff = 1.218190\tres = 1.802E-04\n", + "[ NORMAL ] Iteration 157:\tk_eff = 1.218393\tres = 1.733E-04\n", + "[ NORMAL ] Iteration 158:\tk_eff = 1.218588\tres = 1.667E-04\n", + "[ NORMAL ] Iteration 159:\tk_eff = 1.218776\tres = 1.604E-04\n", + "[ NORMAL ] Iteration 160:\tk_eff = 1.218957\tres = 1.543E-04\n", + "[ NORMAL ] Iteration 161:\tk_eff = 1.219131\tres = 1.484E-04\n", + "[ NORMAL ] Iteration 162:\tk_eff = 1.219298\tres = 1.427E-04\n", + "[ NORMAL ] Iteration 163:\tk_eff = 1.219459\tres = 1.373E-04\n", + "[ NORMAL ] Iteration 164:\tk_eff = 1.219614\tres = 1.321E-04\n", + "[ NORMAL ] Iteration 165:\tk_eff = 1.219763\tres = 1.270E-04\n", + "[ NORMAL ] Iteration 166:\tk_eff = 1.219907\tres = 1.222E-04\n", + "[ NORMAL ] Iteration 167:\tk_eff = 1.220045\tres = 1.176E-04\n", + "[ NORMAL ] Iteration 168:\tk_eff = 1.220177\tres = 1.131E-04\n", + "[ NORMAL ] Iteration 169:\tk_eff = 1.220305\tres = 1.088E-04\n", + "[ NORMAL ] Iteration 170:\tk_eff = 1.220428\tres = 1.046E-04\n", + "[ NORMAL ] Iteration 171:\tk_eff = 1.220546\tres = 1.006E-04\n", + "[ NORMAL ] Iteration 172:\tk_eff = 1.220660\tres = 9.680E-05\n", + "[ NORMAL ] Iteration 173:\tk_eff = 1.220769\tres = 9.311E-05\n", + "[ NORMAL ] Iteration 174:\tk_eff = 1.220874\tres = 8.956E-05\n", + "[ NORMAL ] Iteration 175:\tk_eff = 1.220975\tres = 8.614E-05\n", + "[ NORMAL ] Iteration 176:\tk_eff = 1.221073\tres = 8.286E-05\n", + "[ NORMAL ] Iteration 177:\tk_eff = 1.221166\tres = 7.970E-05\n", + "[ NORMAL ] Iteration 178:\tk_eff = 1.221256\tres = 7.666E-05\n", + "[ NORMAL ] Iteration 179:\tk_eff = 1.221343\tres = 7.373E-05\n", + "[ NORMAL ] Iteration 180:\tk_eff = 1.221426\tres = 7.092E-05\n", + "[ NORMAL ] Iteration 181:\tk_eff = 1.221506\tres = 6.822E-05\n", + "[ NORMAL ] Iteration 182:\tk_eff = 1.221583\tres = 6.562E-05\n", + "[ NORMAL ] Iteration 183:\tk_eff = 1.221658\tres = 6.311E-05\n", + "[ NORMAL ] Iteration 184:\tk_eff = 1.221729\tres = 6.070E-05\n", + "[ NORMAL ] Iteration 185:\tk_eff = 1.221797\tres = 5.839E-05\n", + "[ NORMAL ] Iteration 186:\tk_eff = 1.221863\tres = 5.616E-05\n", + "[ NORMAL ] Iteration 187:\tk_eff = 1.221927\tres = 5.402E-05\n", + "[ NORMAL ] Iteration 188:\tk_eff = 1.221988\tres = 5.196E-05\n", + "[ NORMAL ] Iteration 189:\tk_eff = 1.222047\tres = 4.997E-05\n", + "[ NORMAL ] Iteration 190:\tk_eff = 1.222103\tres = 4.807E-05\n", + "[ NORMAL ] Iteration 191:\tk_eff = 1.222158\tres = 4.623E-05\n", + "[ NORMAL ] Iteration 192:\tk_eff = 1.222210\tres = 4.447E-05\n", + "[ NORMAL ] Iteration 193:\tk_eff = 1.222260\tres = 4.277E-05\n", + "[ NORMAL ] Iteration 194:\tk_eff = 1.222308\tres = 4.114E-05\n", + "[ NORMAL ] Iteration 195:\tk_eff = 1.222355\tres = 3.957E-05\n", + "[ NORMAL ] Iteration 196:\tk_eff = 1.222400\tres = 3.805E-05\n", + "[ NORMAL ] Iteration 197:\tk_eff = 1.222443\tres = 3.660E-05\n", + "[ NORMAL ] Iteration 198:\tk_eff = 1.222484\tres = 3.520E-05\n", + "[ NORMAL ] Iteration 199:\tk_eff = 1.222524\tres = 3.386E-05\n", + "[ NORMAL ] Iteration 200:\tk_eff = 1.222562\tres = 3.257E-05\n", + "[ NORMAL ] Iteration 201:\tk_eff = 1.222599\tres = 3.132E-05\n", + "[ NORMAL ] Iteration 202:\tk_eff = 1.222635\tres = 3.013E-05\n", + "[ NORMAL ] Iteration 203:\tk_eff = 1.222669\tres = 2.898E-05\n", + "[ NORMAL ] Iteration 204:\tk_eff = 1.222701\tres = 2.787E-05\n", + "[ NORMAL ] Iteration 205:\tk_eff = 1.222733\tres = 2.680E-05\n", + "[ NORMAL ] Iteration 206:\tk_eff = 1.222763\tres = 2.578E-05\n", + "[ NORMAL ] Iteration 207:\tk_eff = 1.222792\tres = 2.480E-05\n", + "[ NORMAL ] Iteration 208:\tk_eff = 1.222820\tres = 2.385E-05\n", + "[ NORMAL ] Iteration 209:\tk_eff = 1.222847\tres = 2.294E-05\n", + "[ NORMAL ] Iteration 210:\tk_eff = 1.222873\tres = 2.206E-05\n", + "[ NORMAL ] Iteration 211:\tk_eff = 1.222898\tres = 2.122E-05\n", + "[ NORMAL ] Iteration 212:\tk_eff = 1.222922\tres = 2.041E-05\n", + "[ NORMAL ] Iteration 213:\tk_eff = 1.222945\tres = 1.963E-05\n", + "[ NORMAL ] Iteration 214:\tk_eff = 1.222968\tres = 1.888E-05\n", + "[ NORMAL ] Iteration 215:\tk_eff = 1.222989\tres = 1.816E-05\n", + "[ NORMAL ] Iteration 216:\tk_eff = 1.223009\tres = 1.746E-05\n", + "[ NORMAL ] Iteration 217:\tk_eff = 1.223029\tres = 1.680E-05\n", + "[ NORMAL ] Iteration 218:\tk_eff = 1.223048\tres = 1.615E-05\n", + "[ NORMAL ] Iteration 219:\tk_eff = 1.223067\tres = 1.554E-05\n", + "[ NORMAL ] Iteration 220:\tk_eff = 1.223084\tres = 1.494E-05\n", + "[ NORMAL ] Iteration 221:\tk_eff = 1.223101\tres = 1.437E-05\n", + "[ NORMAL ] Iteration 222:\tk_eff = 1.223117\tres = 1.382E-05\n", + "[ NORMAL ] Iteration 223:\tk_eff = 1.223133\tres = 1.329E-05\n", + "[ NORMAL ] Iteration 224:\tk_eff = 1.223148\tres = 1.279E-05\n", + "[ NORMAL ] Iteration 225:\tk_eff = 1.223162\tres = 1.230E-05\n", + "[ NORMAL ] Iteration 226:\tk_eff = 1.223176\tres = 1.183E-05\n", + "[ NORMAL ] Iteration 227:\tk_eff = 1.223190\tres = 1.137E-05\n", + "[ NORMAL ] Iteration 228:\tk_eff = 1.223203\tres = 1.094E-05\n", + "[ NORMAL ] Iteration 229:\tk_eff = 1.223215\tres = 1.052E-05\n", + "[ NORMAL ] Iteration 230:\tk_eff = 1.223227\tres = 1.012E-05\n" ] } ], "source": [ "# Generate tracks for OpenMOC\n", - "track_generator = openmoc.TrackGenerator(openmoc_geometry, num_azim=128, spacing=0.1)\n", + "track_generator = openmoc.TrackGenerator(openmoc_geometry, num_azim=128, azim_spacing=0.1)\n", "track_generator.generateTracks()\n", "\n", "# Run OpenMOC\n", @@ -1709,7 +1680,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 29, "metadata": { "collapsed": false }, @@ -1719,8 +1690,8 @@ "output_type": "stream", "text": [ "openmc keff = 1.223474\n", - "openmoc keff = 1.223258\n", - "bias [pcm]: -21.5\n" + "openmoc keff = 1.223227\n", + "bias [pcm]: -24.7\n" ] } ], @@ -1766,7 +1737,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 30, "metadata": { "collapsed": false }, @@ -1792,7 +1763,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 31, "metadata": { "collapsed": false }, @@ -1803,7 +1774,7 @@ "(9.9999999999999994e-12, 20.0)" ] }, - "execution_count": 32, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" }, @@ -1811,7 +1782,7 @@ "data": { "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1853,7 +1824,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 32, "metadata": { "collapsed": false }, @@ -1885,7 +1856,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 33, "metadata": { "collapsed": false }, @@ -1894,7 +1865,7 @@ "data": { "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, diff --git a/docs/source/pythonapi/examples/mgxs-part-iii.ipynb b/docs/source/pythonapi/examples/mgxs-part-iii.ipynb index 5fccc4f03..bc2f96414 100644 --- a/docs/source/pythonapi/examples/mgxs-part-iii.ipynb +++ b/docs/source/pythonapi/examples/mgxs-part-iii.ipynb @@ -11,7 +11,7 @@ "* **Validation** of multi-group cross sections with **[OpenMOC](https://mit-crpg.github.io/OpenMOC/)**\n", "* Steady-state pin-by-pin **fission rates comparison** between OpenMC and [OpenMOC](https://mit-crpg.github.io/OpenMOC/)\n", "\n", - "**Note:** This Notebook was created using [OpenMOC](https://mit-crpg.github.io/OpenMOC/) to verify the multi-group cross-sections generated by OpenMC. In order to run this Notebook in its entirety, you must have [OpenMOC](https://mit-crpg.github.io/OpenMOC/) installed on your system, along with OpenCG to convert the OpenMC geometries into OpenMOC geometries. In addition, this Notebook illustrates the use of [Pandas](http://pandas.pydata.org/) `DataFrames` to containerize multi-group cross section data. We recommend using [Pandas](http://pandas.pydata.org/) >v0.15.0 or later since OpenMC's Python API leverages the multi-indexing feature included in the most recent releases of [Pandas](http://pandas.pydata.org/)." + "**Note:** This Notebook was created using [OpenMOC](https://mit-crpg.github.io/OpenMOC/) to verify the multi-group cross-sections generated by OpenMC. In order to run this Notebook in its entirety, you must have [OpenMOC](https://mit-crpg.github.io/OpenMOC/) installed on your system, along with OpenCG to convert the OpenMC geometries into OpenMOC geometries. In addition, this Notebook illustrates the use of [Pandas](http://pandas.pydata.org/) `DataFrames` to containerize multi-group cross section data." ] }, { @@ -32,7 +32,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/usr/local/lib/python2.7/dist-packages/matplotlib-1.5.1+1178.ga40c9ec-py2.7-linux-x86_64.egg/matplotlib/__init__.py:1362: UserWarning: This call to matplotlib.use() has no effect\n", + "/home/wboyd/anaconda2/lib/python2.7/site-packages/matplotlib/__init__.py:1350: UserWarning: This call to matplotlib.use() has no effect\n", "because the backend has already been chosen;\n", "matplotlib.use() must be called *before* pylab, matplotlib.pyplot,\n", "or matplotlib.backends is imported for the first time.\n", @@ -122,7 +122,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "With our three materials, we can now create a `MaterialsFile` object that can be exported to an actual XML file." + "With our three materials, we can now create a `Materials` object that can be exported to an actual XML file." ] }, { @@ -133,11 +133,8 @@ }, "outputs": [], "source": [ - "# Instantiate a MaterialsFile, add Materials\n", - "materials_file = openmc.MaterialsFile()\n", - "materials_file.add_material(fuel)\n", - "materials_file.add_material(water)\n", - "materials_file.add_material(zircaloy)\n", + "# Instantiate a Materials object\n", + "materials_file = openmc.Materials((fuel, water, zircaloy))\n", "materials_file.default_xs = '71c'\n", "\n", "# Export to \"materials.xml\"\n", @@ -331,7 +328,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We now must create a geometry that is assigned a root universe, put the geometry into a `GeometryFile` object, and export it to XML." + "We now must create a geometry that is assigned a root universe and export it to XML." ] }, { @@ -355,12 +352,8 @@ }, "outputs": [], "source": [ - "# Instantiate a GeometryFile\n", - "geometry_file = openmc.GeometryFile()\n", - "geometry_file.geometry = geometry\n", - "\n", "# Export to \"geometry.xml\"\n", - "geometry_file.export_to_xml()" + "geometry.export_to_xml()" ] }, { @@ -383,8 +376,8 @@ "inactive = 10\n", "particles = 2500\n", "\n", - "# Instantiate a SettingsFile\n", - "settings_file = openmc.SettingsFile()\n", + "# Instantiate a Settings object\n", + "settings_file = openmc.Settings()\n", "settings_file.batches = batches\n", "settings_file.inactive = inactive\n", "settings_file.particles = particles\n", @@ -403,7 +396,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Let us also create a `PlotsFile` that we can use to verify that our fuel assembly geometry was created successfully." + "Let us also create a `Plots` file that we can use to verify that our fuel assembly geometry was created successfully." ] }, { @@ -422,9 +415,8 @@ "plot.width = [-10.71*2, -10.71*2]\n", "plot.color = 'mat'\n", "\n", - "# Instantiate a PlotsFile, add Plot, and export to \"plots.xml\"\n", - "plot_file = openmc.PlotsFile()\n", - "plot_file.add_plot(plot)\n", + "# Instantiate a Plots object, add Plot, and export to \"plots.xml\"\n", + "plot_file = openmc.Plots([plot])\n", "plot_file.export_to_xml()" ] }, @@ -455,8 +447,7 @@ ], "source": [ "# Run openmc in plotting mode\n", - "executor = openmc.Executor()\n", - "executor.plot_geometry(output=False)" + "openmc.plot_geometry(output=False)" ] }, { @@ -468,7 +459,7 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6AgMAAAD1grKuAAAABGdBTUEAALGPC/xhBQAAAAFzUkdC\nAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAxQTFRF\n////chIS6YCRTb/E6kGE+wAAAAFiS0dEAIgFHUgAAAAJcEhZcwAAAEgAAABIAEbJaz4AAAWFSURB\nVGje7Zs7cttADIZ9CSvXcrP0iCxUqbBc8Ag6xR6BhV2EvYvwFD4CCx1ABT1jMdgndpegRQnOrCbj\npPlGESISC4A/gd27e8H583CX3b4+iKJrRHkS4vkghMPBonRYWGwtfgD2YN+dRDUOoh6lACw0Noi9\nw2fESuEoAR/uVuMolX039oXGT7F3eFL2iEfhUX1f4cPdL/ishs+68ai+udE4xPhexbjX2FfjGNoP\nj/DPNX4Tsd+EODr8FvsVdf1Hd9P2VvCi4+s/aXvrf+upAD+1/9GV1mkOH5X9vV6THtfvACslcaUC\nbESL61drBPtdI8SrFMWrELsXCkuFDYW75gbiP7d9Cf7bAYI/aCwUShrBvh30+lWQkzVgZ/HD4Oix\nNCgcQpJ3BxU/Ln91elKoM5VEE38QtJ+Yv6cQ9xjKNYayyl8TypP8DfJnQ2H/b/N3ye9P83cT33SQ\nv/sQh9gV7zZ/0dNj5HQaC5vVzv9+/WFN2w8KVaZ2BwL1+pv4g0x1QRfjq0dB4Q3kT277oP6VNL6g\nKxNU9a8zK+WLbi/WwpdihbboKqyxFOulHMj6v4W/AXbmUeAxrv9J/CqEBXaRKsXaodD4nsYvkT/G\n6H1D4SR/iPy1Roj9JsQ5e18/7EUHv1+Fvx/Xj5V9Ugb5K8TW4TZEEdcvoz/up0VTe9qsVIppKVX6\na7D6y9ZvwEKjrtQxPtv6fXII9vCxKOGaIeAIfEF8IvAG8ie3vRK9rRQl+PPpSctbhfpTUCpviH+k\nxsZgpT91+snoX1l49KK3iUQvICRy5aUw6l8leoVwoo3Uv1rKreF/UFLY6d9QP4L9Wf2r7EP9GOSf\ncsjZ56f60kz+XmVPXv+RuP49ff0T/53Rv6n/7m2lvXT9Wqd/VUz8hvh5M/ED6ILmt4mfHYZSaePn\nTWpsf/SvqV9O6dLYYClLEetnoH/LBLFoBvrX189uTv8++kot5vTvQD4/9jP690g9P/4z/bvo/XVG\n/xYoZZx+8fr3MxAtsf7tUOkG2JqsTtCIpgCt/qX1226KqZS7gfzJbe+c9jLrtIZ8lXD+s4umlW6A\nKIVrlML2/cXjgPFjlJqIRC+Fj0bVJe+vSh56pSdR6YkQ1ygF10Wqf0FeLta/iKn9Mv1L24ti2e+7\nW4n1b3T/W+L+t9H9T/SvVboUmqJJon1/hZq8LnzRDlDrX1u0xRT1+6vEpomMmyYkqi95vIH8yW1P\nN+122KkLcNLKi/WTF01z/cNASrWE/l3ev6T17zX909z9X27/euK/Rf3zWP+Waf9eEv37KkWJ+rfD\nl6ZglNDa+cEBhwYDvkoNP/rX69814NaI3imq0l7OYDy/qSdDGwr7r+Y3VbzoKZr6XX2lfxfOb87q\nXzr+b1j/Xlp/nP6dn98McdH7cn7zjPObKsYWS3Eb9w8n85smHtqQuPuZ30T2dlIT6F9xFl+n8xsl\negL9a4c2KRr9W4rp/GYqumiM9Nec/j2v/yj9u1h//hv9e93vc++f63/u+rPjL3f+5Lbn1j9m/eXW\nf+7zh/v8+2b9e/Hzn6s/uPqHrb8g71n6L3f+5Lbnvn8w33+4718/+5d47//c/gO7/5E7/nPbc/tv\n3P4fs//I7X9y+6/fqH+v6j9z+9/c/ju3/8+eP+TOn9z23PkXc/7Gnf9x5483q38Xzn+582fu/Js9\nfy8kb/6fO39y23P3n3S8/S/c/Tfc/T83uX/pgv1XE/9duP+Lu/+Mvf8td/znti8kb/8ld/9nx9t/\nSjw/Ltr/yt1/+337f6/bf0zoB3nJ/ucVc/81d/83e/957vzJbc89/8A8f8E9/5HE78XnT/4H/cs5\nf8Q9/8Q9f8U+/5U7f3Lbc88fdrzzjyvm+cuf/Uu887/c88fs88954/8vO4SjPC+2QRIAAAAldEVY\ndGRhdGU6Y3JlYXRlADIwMTYtMDQtMTNUMTE6NTc6NDAtMDQ6MDBB7YJkAAAAJXRFWHRkYXRlOm1v\nZGlmeQAyMDE2LTA0LTEzVDExOjU3OjQwLTA0OjAwMLA62AAAAABJRU5ErkJggg==\n", + "image/png": "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\n", "text/plain": [ "" ] @@ -548,10 +539,12 @@ "\n", "* `TotalXS` (`\"total\"`)\n", "* `TransportXS` (`\"transport\"`)\n", + "* `NuTransportXS` (`\"nu-transport\"`)\n", "* `AbsorptionXS` (`\"absorption\"`)\n", "* `CaptureXS` (`\"capture\"`)\n", "* `FissionXS` (`\"fission\"`)\n", "* `NuFissionXS` (`\"nu-fission\"`)\n", + "* `KappaFissionXS` (`\"kappa-fission\"`)\n", "* `ScatterXS` (`\"scatter\"`)\n", "* `NuScatterXS` (`\"nu-scatter\"`)\n", "* `ScatterMatrixXS` (`\"scatter matrix\"`)\n", @@ -593,7 +586,7 @@ "outputs": [], "source": [ "# Specify a \"cell\" domain type for the cross section tally filters\n", - "mgxs_lib.domain_type = \"cell\"\n", + "mgxs_lib.domain_type = 'cell'\n", "\n", "# Specify the cell domains over which to compute multi-group cross sections\n", "mgxs_lib.domains = geometry.get_all_material_cells()" @@ -643,7 +636,7 @@ "source": [ "The tallies can now be export to a \"tallies.xml\" input file for OpenMC. \n", "\n", - "**NOTE**: At this point the `Library` has constructed nearly 100 distinct `Tally` objects. The overhead to tally in OpenMC scales as $O(N)$ for $N$ tallies, which can become a bottleneck for large tally datasets. To compensate for this, the Python API's `Tally`, `Filter` and `TalliesFile` classes allow for the smart *merging* of tallies when possible. The `Library` class supports this runtime optimization with the use of the optional `merge` paramter (`False` by default) for the `Library.add_to_tallies_file(...)` method, as shown below." + "**NOTE**: At this point the `Library` has constructed nearly 100 distinct `Tally` objects. The overhead to tally in OpenMC scales as $O(N)$ for $N$ tallies, which can become a bottleneck for large tally datasets. To compensate for this, the Python API's `Tally`, `Filter` and `Tallies` classes allow for the smart *merging* of tallies when possible. The `Library` class supports this runtime optimization with the use of the optional `merge` paramter (`False` by default) for the `Library.add_to_tallies_file(...)` method, as shown below." ] }, { @@ -655,7 +648,7 @@ "outputs": [], "source": [ "# Create a \"tallies.xml\" file for the MGXS Library\n", - "tallies_file = openmc.TalliesFile()\n", + "tallies_file = openmc.Tallies()\n", "mgxs_lib.add_to_tallies_file(tallies_file, merge=True)" ] }, @@ -690,9 +683,8 @@ "tally.filters = [mesh_filter]\n", "tally.scores = ['fission', 'nu-fission']\n", "\n", - "# Add mesh and Tally to TalliesFile\n", - "tallies_file.add_mesh(mesh)\n", - "tallies_file.add_tally(tally)" + "# Add tally to collection\n", + "tallies_file.append(tally)" ] }, { @@ -731,11 +723,11 @@ " 888\n", " 888\n", "\n", - " Copyright: 2011-2015 Massachusetts Institute of Technology\n", - " License: http://mit-crpg.github.io/openmc/license.html\n", + " Copyright: 2011-2016 Massachusetts Institute of Technology\n", + " License: http://openmc.readthedocs.io/en/latest/license.html\n", " Version: 0.7.1\n", - " Git SHA1: eeb5091ca3a34cc85df73a3318cae2b6c7097413\n", - " Date/Time: 2016-04-13 11:57:40\n", + " Git SHA1: 47ef320ad517612376e181ec6a6bc42ca0db98ce\n", + " Date/Time: 2016-05-14 12:29:07\n", " MPI Processes: 1\n", "\n", " ===========================================================================\n", @@ -822,20 +814,20 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 4.3700E-01 seconds\n", - " Reading cross sections = 8.2000E-02 seconds\n", - " Total time in simulation = 4.7745E+01 seconds\n", - " Time in transport only = 4.7726E+01 seconds\n", - " Time in inactive batches = 3.8220E+00 seconds\n", - " Time in active batches = 4.3923E+01 seconds\n", - " Time synchronizing fission bank = 3.0000E-03 seconds\n", + " Total time for initialization = 5.7700E-01 seconds\n", + " Reading cross sections = 1.3400E-01 seconds\n", + " Total time in simulation = 8.0461E+01 seconds\n", + " Time in transport only = 8.0422E+01 seconds\n", + " Time in inactive batches = 6.4060E+00 seconds\n", + " Time in active batches = 7.4055E+01 seconds\n", + " Time synchronizing fission bank = 6.0000E-03 seconds\n", " Sampling source sites = 2.0000E-03 seconds\n", - " SEND/RECV source sites = 0.0000E+00 seconds\n", - " Time accumulating tallies = 1.0000E-03 seconds\n", + " SEND/RECV source sites = 3.0000E-03 seconds\n", + " Time accumulating tallies = 0.0000E+00 seconds\n", " Total time for finalization = 0.0000E+00 seconds\n", - " Total time elapsed = 4.8198E+01 seconds\n", - " Calculation Rate (inactive) = 6541.08 neutrons/second\n", - " Calculation Rate (active) = 2276.71 neutrons/second\n", + " Total time elapsed = 8.1067E+01 seconds\n", + " Calculation Rate (inactive) = 3902.59 neutrons/second\n", + " Calculation Rate (active) = 1350.35 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", @@ -860,7 +852,7 @@ ], "source": [ "# Run OpenMC\n", - "executor.run_simulation()" + "openmc.run()" ] }, { @@ -889,25 +881,6 @@ "sp = openmc.StatePoint('statepoint.50.h5')" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In addition to the statepoint file, our simulation also created a summary file which encapsulates information about the materials and geometry. This is necessary for the `openmc.mgxs` module to properly process the tally data. We first create a `Summary` object and link it with the statepoint." - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "su = openmc.Summary('summary.h5')\n", - "sp.link_with_summary(su)" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -917,7 +890,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 28, "metadata": { "collapsed": false }, @@ -952,7 +925,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 29, "metadata": { "collapsed": false }, @@ -971,7 +944,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 30, "metadata": { "collapsed": false }, @@ -980,7 +953,8 @@ "name": "stderr", "output_type": "stream", "text": [ - "/usr/local/lib/python2.7/dist-packages/openmc-0.7.1-py2.7.egg/openmc/tallies.py:1996: RuntimeWarning: invalid value encountered in true_divide\n" + "/home/wboyd/Documents/NSE-CRPG-Codes/openmc/openmc/tallies.py:1988: RuntimeWarning: invalid value encountered in true_divide\n", + " self_rel_err = data['self']['std. dev.'] / data['self']['mean']\n" ] }, { @@ -1061,7 +1035,7 @@ "2 10000 2 O-16 0.000000e+00 0.000000e+00" ] }, - "execution_count": 31, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } @@ -1080,7 +1054,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 31, "metadata": { "collapsed": false }, @@ -1126,9 +1100,9 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 32, "metadata": { - "collapsed": true + "collapsed": false }, "outputs": [], "source": [ @@ -1145,7 +1119,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 33, "metadata": { "collapsed": true }, @@ -1157,7 +1131,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 34, "metadata": { "collapsed": true }, @@ -1176,7 +1150,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 35, "metadata": { "collapsed": true }, @@ -1191,7 +1165,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 36, "metadata": { "collapsed": false }, @@ -1247,7 +1221,7 @@ "2 10000 1 O-16 0.000000 0.000000" ] }, - "execution_count": 37, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" } @@ -1276,7 +1250,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 37, "metadata": { "collapsed": false }, @@ -1295,7 +1269,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 38, "metadata": { "collapsed": false }, @@ -1314,7 +1288,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 39, "metadata": { "collapsed": false, "scrolled": true @@ -1328,128 +1302,128 @@ "[ NORMAL ] Computing the eigenvalue...\n", "[ NORMAL ] Iteration 0:\tk_eff = 0.854370\tres = 0.000E+00\n", "[ NORMAL ] Iteration 1:\tk_eff = 0.801922\tres = 1.521E-01\n", - "[ NORMAL ] Iteration 2:\tk_eff = 0.761746\tres = 6.349E-02\n", - "[ NORMAL ] Iteration 3:\tk_eff = 0.732367\tres = 5.029E-02\n", - "[ NORMAL ] Iteration 4:\tk_eff = 0.711075\tres = 3.869E-02\n", - "[ NORMAL ] Iteration 5:\tk_eff = 0.696557\tres = 2.912E-02\n", - "[ NORMAL ] Iteration 6:\tk_eff = 0.687673\tres = 2.044E-02\n", - "[ NORMAL ] Iteration 7:\tk_eff = 0.683470\tres = 1.277E-02\n", - "[ NORMAL ] Iteration 8:\tk_eff = 0.683129\tres = 6.141E-03\n", - "[ NORMAL ] Iteration 9:\tk_eff = 0.685949\tres = 7.889E-04\n", - "[ NORMAL ] Iteration 10:\tk_eff = 0.691329\tres = 4.181E-03\n", - "[ NORMAL ] Iteration 11:\tk_eff = 0.698755\tres = 7.875E-03\n", - "[ NORMAL ] Iteration 12:\tk_eff = 0.707786\tres = 1.077E-02\n", - "[ NORMAL ] Iteration 13:\tk_eff = 0.718050\tres = 1.295E-02\n", - "[ NORMAL ] Iteration 14:\tk_eff = 0.729230\tres = 1.452E-02\n", - "[ NORMAL ] Iteration 15:\tk_eff = 0.741058\tres = 1.559E-02\n", - "[ NORMAL ] Iteration 16:\tk_eff = 0.753310\tres = 1.624E-02\n", - "[ NORMAL ] Iteration 17:\tk_eff = 0.765800\tres = 1.655E-02\n", - "[ NORMAL ] Iteration 18:\tk_eff = 0.778371\tres = 1.660E-02\n", - "[ NORMAL ] Iteration 19:\tk_eff = 0.790897\tres = 1.643E-02\n", - "[ NORMAL ] Iteration 20:\tk_eff = 0.803273\tres = 1.611E-02\n", - "[ NORMAL ] Iteration 21:\tk_eff = 0.815415\tres = 1.566E-02\n", - "[ NORMAL ] Iteration 22:\tk_eff = 0.827256\tres = 1.513E-02\n", - "[ NORMAL ] Iteration 23:\tk_eff = 0.838747\tres = 1.453E-02\n", - "[ NORMAL ] Iteration 24:\tk_eff = 0.849847\tres = 1.390E-02\n", - "[ NORMAL ] Iteration 25:\tk_eff = 0.860527\tres = 1.324E-02\n", - "[ NORMAL ] Iteration 26:\tk_eff = 0.870770\tres = 1.258E-02\n", - "[ NORMAL ] Iteration 27:\tk_eff = 0.880562\tres = 1.191E-02\n", - "[ NORMAL ] Iteration 28:\tk_eff = 0.889897\tres = 1.125E-02\n", - "[ NORMAL ] Iteration 29:\tk_eff = 0.898776\tres = 1.061E-02\n", - "[ NORMAL ] Iteration 30:\tk_eff = 0.907202\tres = 9.986E-03\n", - "[ NORMAL ] Iteration 31:\tk_eff = 0.915181\tres = 9.382E-03\n", - "[ NORMAL ] Iteration 32:\tk_eff = 0.922724\tres = 8.803E-03\n", - "[ NORMAL ] Iteration 33:\tk_eff = 0.929843\tres = 8.249E-03\n", - "[ NORMAL ] Iteration 34:\tk_eff = 0.936550\tres = 7.721E-03\n", - "[ NORMAL ] Iteration 35:\tk_eff = 0.942861\tres = 7.220E-03\n", - "[ NORMAL ] Iteration 36:\tk_eff = 0.948791\tres = 6.744E-03\n", - "[ NORMAL ] Iteration 37:\tk_eff = 0.954357\tres = 6.295E-03\n", - "[ NORMAL ] Iteration 38:\tk_eff = 0.959575\tres = 5.871E-03\n", - "[ NORMAL ] Iteration 39:\tk_eff = 0.964461\tres = 5.472E-03\n", - "[ NORMAL ] Iteration 40:\tk_eff = 0.969033\tres = 5.097E-03\n", - "[ NORMAL ] Iteration 41:\tk_eff = 0.973306\tres = 4.744E-03\n", - "[ NORMAL ] Iteration 42:\tk_eff = 0.977297\tres = 4.414E-03\n", - "[ NORMAL ] Iteration 43:\tk_eff = 0.981021\tres = 4.104E-03\n", - "[ NORMAL ] Iteration 44:\tk_eff = 0.984493\tres = 3.814E-03\n", - "[ NORMAL ] Iteration 45:\tk_eff = 0.987729\tres = 3.543E-03\n", - "[ NORMAL ] Iteration 46:\tk_eff = 0.990742\tres = 3.290E-03\n", - "[ NORMAL ] Iteration 47:\tk_eff = 0.993546\tres = 3.053E-03\n", - "[ NORMAL ] Iteration 48:\tk_eff = 0.996153\tres = 2.833E-03\n", - "[ NORMAL ] Iteration 49:\tk_eff = 0.998577\tres = 2.627E-03\n", - "[ NORMAL ] Iteration 50:\tk_eff = 1.000829\tres = 2.436E-03\n", - "[ NORMAL ] Iteration 51:\tk_eff = 1.002920\tres = 2.257E-03\n", - "[ NORMAL ] Iteration 52:\tk_eff = 1.004860\tres = 2.091E-03\n", - "[ NORMAL ] Iteration 53:\tk_eff = 1.006661\tres = 1.937E-03\n", - "[ NORMAL ] Iteration 54:\tk_eff = 1.008330\tres = 1.793E-03\n", - "[ NORMAL ] Iteration 55:\tk_eff = 1.009877\tres = 1.660E-03\n", - "[ NORMAL ] Iteration 56:\tk_eff = 1.011311\tres = 1.536E-03\n", - "[ NORMAL ] Iteration 57:\tk_eff = 1.012639\tres = 1.421E-03\n", - "[ NORMAL ] Iteration 58:\tk_eff = 1.013868\tres = 1.314E-03\n", - "[ NORMAL ] Iteration 59:\tk_eff = 1.015006\tres = 1.215E-03\n", - "[ NORMAL ] Iteration 60:\tk_eff = 1.016059\tres = 1.124E-03\n", - "[ NORMAL ] Iteration 61:\tk_eff = 1.017033\tres = 1.039E-03\n", - "[ NORMAL ] Iteration 62:\tk_eff = 1.017933\tres = 9.596E-04\n", - "[ NORMAL ] Iteration 63:\tk_eff = 1.018766\tres = 8.865E-04\n", - "[ NORMAL ] Iteration 64:\tk_eff = 1.019535\tres = 8.188E-04\n", - "[ NORMAL ] Iteration 65:\tk_eff = 1.020246\tres = 7.562E-04\n", - "[ NORMAL ] Iteration 66:\tk_eff = 1.020903\tres = 6.981E-04\n", - "[ NORMAL ] Iteration 67:\tk_eff = 1.021509\tres = 6.445E-04\n", - "[ NORMAL ] Iteration 68:\tk_eff = 1.022069\tres = 5.948E-04\n", - "[ NORMAL ] Iteration 69:\tk_eff = 1.022586\tres = 5.489E-04\n", - "[ NORMAL ] Iteration 70:\tk_eff = 1.023063\tres = 5.064E-04\n", - "[ NORMAL ] Iteration 71:\tk_eff = 1.023503\tres = 4.671E-04\n", - "[ NORMAL ] Iteration 72:\tk_eff = 1.023909\tres = 4.308E-04\n", - "[ NORMAL ] Iteration 73:\tk_eff = 1.024284\tres = 3.973E-04\n", - "[ NORMAL ] Iteration 74:\tk_eff = 1.024629\tres = 3.663E-04\n", - "[ NORMAL ] Iteration 75:\tk_eff = 1.024948\tres = 3.377E-04\n", - "[ NORMAL ] Iteration 76:\tk_eff = 1.025241\tres = 3.113E-04\n", - "[ NORMAL ] Iteration 77:\tk_eff = 1.025512\tres = 2.869E-04\n", - "[ NORMAL ] Iteration 78:\tk_eff = 1.025761\tres = 2.644E-04\n", - "[ NORMAL ] Iteration 79:\tk_eff = 1.025991\tres = 2.436E-04\n", - "[ NORMAL ] Iteration 80:\tk_eff = 1.026203\tres = 2.244E-04\n", - "[ NORMAL ] Iteration 81:\tk_eff = 1.026398\tres = 2.067E-04\n", - "[ NORMAL ] Iteration 82:\tk_eff = 1.026578\tres = 1.904E-04\n", - "[ NORMAL ] Iteration 83:\tk_eff = 1.026743\tres = 1.754E-04\n", - "[ NORMAL ] Iteration 84:\tk_eff = 1.026895\tres = 1.615E-04\n", - "[ NORMAL ] Iteration 85:\tk_eff = 1.027036\tres = 1.487E-04\n", - "[ NORMAL ] Iteration 86:\tk_eff = 1.027165\tres = 1.369E-04\n", - "[ NORMAL ] Iteration 87:\tk_eff = 1.027284\tres = 1.260E-04\n", - "[ NORMAL ] Iteration 88:\tk_eff = 1.027393\tres = 1.160E-04\n", - "[ NORMAL ] Iteration 89:\tk_eff = 1.027494\tres = 1.068E-04\n", - "[ NORMAL ] Iteration 90:\tk_eff = 1.027587\tres = 9.825E-05\n", - "[ NORMAL ] Iteration 91:\tk_eff = 1.027672\tres = 9.041E-05\n", - "[ NORMAL ] Iteration 92:\tk_eff = 1.027751\tres = 8.319E-05\n", - "[ NORMAL ] Iteration 93:\tk_eff = 1.027823\tres = 7.654E-05\n", - "[ NORMAL ] Iteration 94:\tk_eff = 1.027889\tres = 7.042E-05\n", - "[ NORMAL ] Iteration 95:\tk_eff = 1.027950\tres = 6.478E-05\n", - "[ NORMAL ] Iteration 96:\tk_eff = 1.028007\tres = 5.959E-05\n", - "[ NORMAL ] Iteration 97:\tk_eff = 1.028058\tres = 5.481E-05\n", - "[ NORMAL ] Iteration 98:\tk_eff = 1.028106\tres = 5.041E-05\n", - "[ NORMAL ] Iteration 99:\tk_eff = 1.028150\tres = 4.636E-05\n", - "[ NORMAL ] Iteration 100:\tk_eff = 1.028190\tres = 4.263E-05\n", - "[ NORMAL ] Iteration 101:\tk_eff = 1.028227\tres = 3.920E-05\n", - "[ NORMAL ] Iteration 102:\tk_eff = 1.028261\tres = 3.604E-05\n", - "[ NORMAL ] Iteration 103:\tk_eff = 1.028292\tres = 3.314E-05\n", - "[ NORMAL ] Iteration 104:\tk_eff = 1.028321\tres = 3.047E-05\n", - "[ NORMAL ] Iteration 105:\tk_eff = 1.028347\tres = 2.801E-05\n", - "[ NORMAL ] Iteration 106:\tk_eff = 1.028371\tres = 2.575E-05\n", - "[ NORMAL ] Iteration 107:\tk_eff = 1.028394\tres = 2.367E-05\n", - "[ NORMAL ] Iteration 108:\tk_eff = 1.028414\tres = 2.175E-05\n", - "[ NORMAL ] Iteration 109:\tk_eff = 1.028433\tres = 1.999E-05\n", - "[ NORMAL ] Iteration 110:\tk_eff = 1.028450\tres = 1.838E-05\n", - "[ NORMAL ] Iteration 111:\tk_eff = 1.028466\tres = 1.689E-05\n", - "[ NORMAL ] Iteration 112:\tk_eff = 1.028481\tres = 1.552E-05\n", - "[ NORMAL ] Iteration 113:\tk_eff = 1.028494\tres = 1.426E-05\n", - "[ NORMAL ] Iteration 114:\tk_eff = 1.028507\tres = 1.310E-05\n", - "[ NORMAL ] Iteration 115:\tk_eff = 1.028518\tres = 1.204E-05\n", - "[ NORMAL ] Iteration 116:\tk_eff = 1.028528\tres = 1.106E-05\n", - "[ NORMAL ] Iteration 117:\tk_eff = 1.028538\tres = 1.017E-05\n" + "[ NORMAL ] Iteration 2:\tk_eff = 0.761745\tres = 6.349E-02\n", + "[ NORMAL ] Iteration 3:\tk_eff = 0.732366\tres = 5.029E-02\n", + "[ NORMAL ] Iteration 4:\tk_eff = 0.711073\tres = 3.869E-02\n", + "[ NORMAL ] Iteration 5:\tk_eff = 0.696554\tres = 2.912E-02\n", + "[ NORMAL ] Iteration 6:\tk_eff = 0.687670\tres = 2.044E-02\n", + "[ NORMAL ] Iteration 7:\tk_eff = 0.683465\tres = 1.277E-02\n", + "[ NORMAL ] Iteration 8:\tk_eff = 0.683124\tres = 6.142E-03\n", + "[ NORMAL ] Iteration 9:\tk_eff = 0.685943\tres = 7.897E-04\n", + "[ NORMAL ] Iteration 10:\tk_eff = 0.691322\tres = 4.180E-03\n", + "[ NORMAL ] Iteration 11:\tk_eff = 0.698747\tres = 7.873E-03\n", + "[ NORMAL ] Iteration 12:\tk_eff = 0.707777\tres = 1.076E-02\n", + "[ NORMAL ] Iteration 13:\tk_eff = 0.718040\tres = 1.295E-02\n", + "[ NORMAL ] Iteration 14:\tk_eff = 0.729218\tres = 1.452E-02\n", + "[ NORMAL ] Iteration 15:\tk_eff = 0.741045\tres = 1.559E-02\n", + "[ NORMAL ] Iteration 16:\tk_eff = 0.753296\tres = 1.624E-02\n", + "[ NORMAL ] Iteration 17:\tk_eff = 0.765785\tres = 1.655E-02\n", + "[ NORMAL ] Iteration 18:\tk_eff = 0.778355\tres = 1.659E-02\n", + "[ NORMAL ] Iteration 19:\tk_eff = 0.790879\tres = 1.643E-02\n", + "[ NORMAL ] Iteration 20:\tk_eff = 0.803254\tres = 1.610E-02\n", + "[ NORMAL ] Iteration 21:\tk_eff = 0.815394\tres = 1.566E-02\n", + "[ NORMAL ] Iteration 22:\tk_eff = 0.827235\tres = 1.513E-02\n", + "[ NORMAL ] Iteration 23:\tk_eff = 0.838724\tres = 1.453E-02\n", + "[ NORMAL ] Iteration 24:\tk_eff = 0.849823\tres = 1.390E-02\n", + "[ NORMAL ] Iteration 25:\tk_eff = 0.860503\tres = 1.324E-02\n", + "[ NORMAL ] Iteration 26:\tk_eff = 0.870744\tres = 1.258E-02\n", + "[ NORMAL ] Iteration 27:\tk_eff = 0.880535\tres = 1.191E-02\n", + "[ NORMAL ] Iteration 28:\tk_eff = 0.889870\tres = 1.125E-02\n", + "[ NORMAL ] Iteration 29:\tk_eff = 0.898748\tres = 1.061E-02\n", + "[ NORMAL ] Iteration 30:\tk_eff = 0.907172\tres = 9.985E-03\n", + "[ NORMAL ] Iteration 31:\tk_eff = 0.915151\tres = 9.382E-03\n", + "[ NORMAL ] Iteration 32:\tk_eff = 0.922693\tres = 8.802E-03\n", + "[ NORMAL ] Iteration 33:\tk_eff = 0.929811\tres = 8.248E-03\n", + "[ NORMAL ] Iteration 34:\tk_eff = 0.936517\tres = 7.720E-03\n", + "[ NORMAL ] Iteration 35:\tk_eff = 0.942827\tres = 7.219E-03\n", + "[ NORMAL ] Iteration 36:\tk_eff = 0.948757\tres = 6.744E-03\n", + "[ NORMAL ] Iteration 37:\tk_eff = 0.954322\tres = 6.295E-03\n", + "[ NORMAL ] Iteration 38:\tk_eff = 0.959539\tres = 5.871E-03\n", + "[ NORMAL ] Iteration 39:\tk_eff = 0.964425\tres = 5.472E-03\n", + "[ NORMAL ] Iteration 40:\tk_eff = 0.968996\tres = 5.096E-03\n", + "[ NORMAL ] Iteration 41:\tk_eff = 0.973268\tres = 4.744E-03\n", + "[ NORMAL ] Iteration 42:\tk_eff = 0.977259\tres = 4.413E-03\n", + "[ NORMAL ] Iteration 43:\tk_eff = 0.980982\tres = 4.104E-03\n", + "[ NORMAL ] Iteration 44:\tk_eff = 0.984454\tres = 3.814E-03\n", + "[ NORMAL ] Iteration 45:\tk_eff = 0.987689\tres = 3.543E-03\n", + "[ NORMAL ] Iteration 46:\tk_eff = 0.990702\tres = 3.289E-03\n", + "[ NORMAL ] Iteration 47:\tk_eff = 0.993505\tres = 3.053E-03\n", + "[ NORMAL ] Iteration 48:\tk_eff = 0.996112\tres = 2.832E-03\n", + "[ NORMAL ] Iteration 49:\tk_eff = 0.998536\tres = 2.627E-03\n", + "[ NORMAL ] Iteration 50:\tk_eff = 1.000787\tres = 2.435E-03\n", + "[ NORMAL ] Iteration 51:\tk_eff = 1.002878\tres = 2.257E-03\n", + "[ NORMAL ] Iteration 52:\tk_eff = 1.004818\tres = 2.091E-03\n", + "[ NORMAL ] Iteration 53:\tk_eff = 1.006618\tres = 1.937E-03\n", + "[ NORMAL ] Iteration 54:\tk_eff = 1.008287\tres = 1.793E-03\n", + "[ NORMAL ] Iteration 55:\tk_eff = 1.009834\tres = 1.660E-03\n", + "[ NORMAL ] Iteration 56:\tk_eff = 1.011268\tres = 1.536E-03\n", + "[ NORMAL ] Iteration 57:\tk_eff = 1.012595\tres = 1.421E-03\n", + "[ NORMAL ] Iteration 58:\tk_eff = 1.013824\tres = 1.314E-03\n", + "[ NORMAL ] Iteration 59:\tk_eff = 1.014962\tres = 1.215E-03\n", + "[ NORMAL ] Iteration 60:\tk_eff = 1.016015\tres = 1.123E-03\n", + "[ NORMAL ] Iteration 61:\tk_eff = 1.016988\tres = 1.038E-03\n", + "[ NORMAL ] Iteration 62:\tk_eff = 1.017889\tres = 9.595E-04\n", + "[ NORMAL ] Iteration 63:\tk_eff = 1.018721\tres = 8.864E-04\n", + "[ NORMAL ] Iteration 64:\tk_eff = 1.019490\tres = 8.187E-04\n", + "[ NORMAL ] Iteration 65:\tk_eff = 1.020201\tres = 7.560E-04\n", + "[ NORMAL ] Iteration 66:\tk_eff = 1.020858\tres = 6.980E-04\n", + "[ NORMAL ] Iteration 67:\tk_eff = 1.021464\tres = 6.444E-04\n", + "[ NORMAL ] Iteration 68:\tk_eff = 1.022024\tres = 5.947E-04\n", + "[ NORMAL ] Iteration 69:\tk_eff = 1.022541\tres = 5.488E-04\n", + "[ NORMAL ] Iteration 70:\tk_eff = 1.023017\tres = 5.063E-04\n", + "[ NORMAL ] Iteration 71:\tk_eff = 1.023458\tres = 4.670E-04\n", + "[ NORMAL ] Iteration 72:\tk_eff = 1.023863\tres = 4.308E-04\n", + "[ NORMAL ] Iteration 73:\tk_eff = 1.024238\tres = 3.972E-04\n", + "[ NORMAL ] Iteration 74:\tk_eff = 1.024583\tres = 3.663E-04\n", + "[ NORMAL ] Iteration 75:\tk_eff = 1.024902\tres = 3.376E-04\n", + "[ NORMAL ] Iteration 76:\tk_eff = 1.025195\tres = 3.112E-04\n", + "[ NORMAL ] Iteration 77:\tk_eff = 1.025466\tres = 2.868E-04\n", + "[ NORMAL ] Iteration 78:\tk_eff = 1.025715\tres = 2.643E-04\n", + "[ NORMAL ] Iteration 79:\tk_eff = 1.025945\tres = 2.435E-04\n", + "[ NORMAL ] Iteration 80:\tk_eff = 1.026157\tres = 2.244E-04\n", + "[ NORMAL ] Iteration 81:\tk_eff = 1.026352\tres = 2.067E-04\n", + "[ NORMAL ] Iteration 82:\tk_eff = 1.026531\tres = 1.904E-04\n", + "[ NORMAL ] Iteration 83:\tk_eff = 1.026697\tres = 1.753E-04\n", + "[ NORMAL ] Iteration 84:\tk_eff = 1.026849\tres = 1.614E-04\n", + "[ NORMAL ] Iteration 85:\tk_eff = 1.026989\tres = 1.487E-04\n", + "[ NORMAL ] Iteration 86:\tk_eff = 1.027118\tres = 1.369E-04\n", + "[ NORMAL ] Iteration 87:\tk_eff = 1.027237\tres = 1.260E-04\n", + "[ NORMAL ] Iteration 88:\tk_eff = 1.027347\tres = 1.160E-04\n", + "[ NORMAL ] Iteration 89:\tk_eff = 1.027447\tres = 1.067E-04\n", + "[ NORMAL ] Iteration 90:\tk_eff = 1.027540\tres = 9.823E-05\n", + "[ NORMAL ] Iteration 91:\tk_eff = 1.027625\tres = 9.039E-05\n", + "[ NORMAL ] Iteration 92:\tk_eff = 1.027704\tres = 8.317E-05\n", + "[ NORMAL ] Iteration 93:\tk_eff = 1.027776\tres = 7.652E-05\n", + "[ NORMAL ] Iteration 94:\tk_eff = 1.027843\tres = 7.040E-05\n", + "[ NORMAL ] Iteration 95:\tk_eff = 1.027904\tres = 6.476E-05\n", + "[ NORMAL ] Iteration 96:\tk_eff = 1.027960\tres = 5.957E-05\n", + "[ NORMAL ] Iteration 97:\tk_eff = 1.028012\tres = 5.479E-05\n", + "[ NORMAL ] Iteration 98:\tk_eff = 1.028059\tres = 5.039E-05\n", + "[ NORMAL ] Iteration 99:\tk_eff = 1.028103\tres = 4.635E-05\n", + "[ NORMAL ] Iteration 100:\tk_eff = 1.028143\tres = 4.262E-05\n", + "[ NORMAL ] Iteration 101:\tk_eff = 1.028180\tres = 3.919E-05\n", + "[ NORMAL ] Iteration 102:\tk_eff = 1.028214\tres = 3.603E-05\n", + "[ NORMAL ] Iteration 103:\tk_eff = 1.028245\tres = 3.313E-05\n", + "[ NORMAL ] Iteration 104:\tk_eff = 1.028274\tres = 3.046E-05\n", + "[ NORMAL ] Iteration 105:\tk_eff = 1.028300\tres = 2.800E-05\n", + "[ NORMAL ] Iteration 106:\tk_eff = 1.028324\tres = 2.574E-05\n", + "[ NORMAL ] Iteration 107:\tk_eff = 1.028347\tres = 2.366E-05\n", + "[ NORMAL ] Iteration 108:\tk_eff = 1.028367\tres = 2.175E-05\n", + "[ NORMAL ] Iteration 109:\tk_eff = 1.028386\tres = 1.999E-05\n", + "[ NORMAL ] Iteration 110:\tk_eff = 1.028403\tres = 1.837E-05\n", + "[ NORMAL ] Iteration 111:\tk_eff = 1.028419\tres = 1.688E-05\n", + "[ NORMAL ] Iteration 112:\tk_eff = 1.028434\tres = 1.551E-05\n", + "[ NORMAL ] Iteration 113:\tk_eff = 1.028447\tres = 1.426E-05\n", + "[ NORMAL ] Iteration 114:\tk_eff = 1.028460\tres = 1.310E-05\n", + "[ NORMAL ] Iteration 115:\tk_eff = 1.028471\tres = 1.204E-05\n", + "[ NORMAL ] Iteration 116:\tk_eff = 1.028481\tres = 1.106E-05\n", + "[ NORMAL ] Iteration 117:\tk_eff = 1.028491\tres = 1.016E-05\n" ] } ], "source": [ "# Generate tracks for OpenMOC\n", - "track_generator = openmoc.TrackGenerator(openmoc_geometry, num_azim=32, spacing=0.1)\n", + "track_generator = openmoc.TrackGenerator(openmoc_geometry, num_azim=32, azim_spacing=0.1)\n", "track_generator.generateTracks()\n", "\n", "# Run OpenMOC\n", @@ -1466,7 +1440,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 40, "metadata": { "collapsed": false }, @@ -1476,8 +1450,8 @@ "output_type": "stream", "text": [ "openmc keff = 1.028263\n", - "openmoc keff = 1.028538\n", - "bias [pcm]: 27.5\n" + "openmoc keff = 1.028491\n", + "bias [pcm]: 22.8\n" ] } ], @@ -1519,7 +1493,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 41, "metadata": { "collapsed": false }, @@ -1545,7 +1519,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 42, "metadata": { "collapsed": false }, @@ -1577,7 +1551,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 43, "metadata": { "collapsed": false }, @@ -1585,18 +1559,18 @@ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 44, + "execution_count": 43, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\nZOT/APiw99Nd94jXAAAAAElFTkSuQmCC\n", + "image/png": "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\n2ajR7Q6wgAAAAABJRU5ErkJggg==\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1604,6 +1578,10 @@ } ], "source": [ + "# Ignore zero fission rates in guide tubes with Matplotlib color scheme\n", + "openmc_fission_rates[openmc_fission_rates == 0] = np.nan\n", + "openmoc_fission_rates[openmoc_fission_rates == 0] = np.nan\n", + "\n", "# Plot OpenMC's fission rates in the left subplot\n", "fig = plt.subplot(121)\n", "plt.imshow(openmc_fission_rates, interpolation='none', cmap='jet')\n", @@ -1614,15 +1592,6 @@ "plt.imshow(openmoc_fission_rates, interpolation='none', cmap='jet')\n", "plt.title('OpenMOC Fission Rates')" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [] } ], "metadata": { @@ -1641,7 +1610,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.6" + "version": "2.7.11" } }, "nbformat": 4, diff --git a/docs/source/pythonapi/examples/mgxs-part-iv.ipynb b/docs/source/pythonapi/examples/mgxs-part-iv.ipynb new file mode 100644 index 000000000..4b73cf3ca --- /dev/null +++ b/docs/source/pythonapi/examples/mgxs-part-iv.ipynb @@ -0,0 +1,1461 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This Notebook illustrates the use of the openmc.mgxs.Library class specifically for application in OpenMC's multi-group mode. This example notebook follows the same process as was done in MGXS Part III, but instead uses OpenMC as the multi-group solver. This Notebook illustrates the following features:\n", + "\n", + " - Calculation of multi-group cross sections for a fuel assembly\n", + " - Automated creation and storage of MGXS with openmc.mgxs.Library\n", + " - Steady-state pin-by-pin fission rates comparison between continuous-energy and multi-group OpenMC.\n", + "\n", + "Note: This Notebook illustrates the use of Pandas DataFrames to containerize multi-group cross section data. We recommend using Pandas >v0.15.0 or later since OpenMC's Python API leverages the multi-indexing feature included in the most recent releases of Pandas.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Generate Input Files" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import math\n", + "import pickle\n", + "\n", + "from IPython.display import Image\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import os\n", + "\n", + "import openmc\n", + "import openmc.mgxs\n", + "\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "First we need to define materials that will be used in the problem. Before defining a material, we must create nuclides that are used in the material." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Instantiate some Nuclides\n", + "h1 = openmc.Nuclide('H-1')\n", + "b10 = openmc.Nuclide('B-10')\n", + "o16 = openmc.Nuclide('O-16')\n", + "u235 = openmc.Nuclide('U-235')\n", + "u238 = openmc.Nuclide('U-238')\n", + "zr90 = openmc.Nuclide('Zr-90')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With the nuclides we defined, we will now create three materials for the fuel, water, and cladding of the fuel pins." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# 1.6 enriched fuel\n", + "fuel = openmc.Material(name='1.6% Fuel')\n", + "fuel.set_density('g/cm3', 10.31341)\n", + "fuel.add_nuclide(u235, 3.7503e-4)\n", + "fuel.add_nuclide(u238, 2.2625e-2)\n", + "fuel.add_nuclide(o16, 4.6007e-2)\n", + "\n", + "# zircaloy\n", + "zircaloy = openmc.Material(name='Zircaloy')\n", + "zircaloy.set_density('g/cm3', 6.55)\n", + "zircaloy.add_nuclide(zr90, 7.2758e-3)\n", + "\n", + "# borated water\n", + "water = openmc.Material(name='Borated Water')\n", + "water.set_density('g/cm3', 0.740582)\n", + "water.add_nuclide(h1, 4.9457e-2)\n", + "water.add_nuclide(o16, 2.4732e-2)\n", + "water.add_nuclide(b10, 8.0042e-6)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With our three materials, we can now create a Materials object that can be exported to an actual XML file." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Instantiate a Materials object\n", + "materials_file = openmc.Materials((fuel, zircaloy, water))\n", + "materials_file.default_xs = '71c'\n", + "\n", + "# Export to \"materials.xml\"\n", + "materials_file.export_to_xml()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's move on to the geometry. This problem will be a square array of fuel pins and control rod guide tubes for which we can use OpenMC's lattice/universe feature. The basic universe will have three regions for the fuel, the clad, and the surrounding coolant. The first step is to create the bounding surfaces for fuel and clad, as well as the outer bounding surfaces of the problem." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Create cylinders for the fuel and clad\n", + "fuel_outer_radius = openmc.ZCylinder(x0=0.0, y0=0.0, R=0.39218)\n", + "clad_outer_radius = openmc.ZCylinder(x0=0.0, y0=0.0, R=0.45720)\n", + "\n", + "# Create boundary planes to surround the geometry\n", + "min_x = openmc.XPlane(x0=-10.71, boundary_type='reflective')\n", + "max_x = openmc.XPlane(x0=+10.71, boundary_type='reflective')\n", + "min_y = openmc.YPlane(y0=-10.71, boundary_type='reflective')\n", + "max_y = openmc.YPlane(y0=+10.71, boundary_type='reflective')\n", + "min_z = openmc.ZPlane(z0=-10., boundary_type='reflective')\n", + "max_z = openmc.ZPlane(z0=+10., boundary_type='reflective')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With the surfaces defined, we can now construct a fuel pin cell from cells that are defined by intersections of half-spaces created by the surfaces." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Create a Universe to encapsulate a fuel pin\n", + "fuel_pin_universe = openmc.Universe(name='1.6% Fuel Pin')\n", + "\n", + "# Create fuel Cell\n", + "fuel_cell = openmc.Cell(name='1.6% Fuel')\n", + "fuel_cell.fill = fuel\n", + "fuel_cell.region = -fuel_outer_radius\n", + "fuel_pin_universe.add_cell(fuel_cell)\n", + "\n", + "# Create a clad Cell\n", + "clad_cell = openmc.Cell(name='1.6% Clad')\n", + "clad_cell.fill = zircaloy\n", + "clad_cell.region = +fuel_outer_radius & -clad_outer_radius\n", + "fuel_pin_universe.add_cell(clad_cell)\n", + "\n", + "# Create a moderator Cell\n", + "moderator_cell = openmc.Cell(name='1.6% Moderator')\n", + "moderator_cell.fill = water\n", + "moderator_cell.region = +clad_outer_radius\n", + "fuel_pin_universe.add_cell(moderator_cell)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Likewise, we can construct a control rod guide tube with the same surfaces." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Create a Universe to encapsulate a control rod guide tube\n", + "guide_tube_universe = openmc.Universe(name='Guide Tube')\n", + "\n", + "# Create guide tube Cell\n", + "guide_tube_cell = openmc.Cell(name='Guide Tube Water')\n", + "guide_tube_cell.fill = water\n", + "guide_tube_cell.region = -fuel_outer_radius\n", + "guide_tube_universe.add_cell(guide_tube_cell)\n", + "\n", + "# Create a clad Cell\n", + "clad_cell = openmc.Cell(name='Guide Clad')\n", + "clad_cell.fill = zircaloy\n", + "clad_cell.region = +fuel_outer_radius & -clad_outer_radius\n", + "guide_tube_universe.add_cell(clad_cell)\n", + "\n", + "# Create a moderator Cell\n", + "moderator_cell = openmc.Cell(name='Guide Tube Moderator')\n", + "moderator_cell.fill = water\n", + "moderator_cell.region = +clad_outer_radius\n", + "guide_tube_universe.add_cell(moderator_cell)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Using the pin cell universe, we can construct a 17x17 rectangular lattice with a 1.26 cm pitch." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Create fuel assembly Lattice\n", + "assembly = openmc.RectLattice(name='1.6% Fuel Assembly')\n", + "assembly.dimension = (17, 17)\n", + "assembly.pitch = (1.26, 1.26)\n", + "assembly.lower_left = [-1.26 * 17. / 2.0] * 2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we create a NumPy array of fuel pin and guide tube universes for the lattice." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Create array indices for guide tube locations in lattice\n", + "template_x = np.array([5, 8, 11, 3, 13, 2, 5, 8, 11, 14, 2, 5, 8,\n", + " 11, 14, 2, 5, 8, 11, 14, 3, 13, 5, 8, 11])\n", + "template_y = np.array([2, 2, 2, 3, 3, 5, 5, 5, 5, 5, 8, 8, 8, 8,\n", + " 8, 11, 11, 11, 11, 11, 13, 13, 14, 14, 14])\n", + "\n", + "# Initialize an empty 17x17 array of the lattice universes\n", + "universes = np.empty((17, 17), dtype=openmc.Universe)\n", + "\n", + "# Fill the array with the fuel pin and guide tube universes\n", + "universes[:,:] = fuel_pin_universe\n", + "universes[template_x, template_y] = guide_tube_universe\n", + "\n", + "# Store the array of universes in the lattice\n", + "assembly.universes = universes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "OpenMC requires that there is a \"root\" universe. Let us create a root cell that is filled by the pin cell universe and then assign it to the root universe." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Create root Cell\n", + "root_cell = openmc.Cell(name='root cell')\n", + "root_cell.fill = assembly\n", + "\n", + "# Add boundary planes\n", + "root_cell.region = +min_x & -max_x & +min_y & -max_y & +min_z & -max_z\n", + "\n", + "# Create root Universe\n", + "root_universe = openmc.Universe(name='root universe', universe_id=0)\n", + "root_universe.add_cell(root_cell)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We now must create a geometry that is assigned a root universe and export it to XML." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Create Geometry and set root Universe\n", + "geometry = openmc.Geometry()\n", + "geometry.root_universe = root_universe\n", + "# Export to \"geometry.xml\"\n", + "geometry.export_to_xml()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With the geometry and materials finished, we now just need to define simulation parameters. In this case, we will use 10 inactive batches and 40 active batches each with 2500 particles." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# OpenMC simulation parameters\n", + "batches = 50\n", + "inactive = 10\n", + "particles = 5000\n", + "\n", + "# Instantiate a Settings object\n", + "settings_file = openmc.Settings()\n", + "settings_file.batches = batches\n", + "settings_file.inactive = inactive\n", + "settings_file.particles = particles\n", + "settings_file.output = {'tallies': False}\n", + "\n", + "# Create an initial uniform spatial source distribution over fissionable zones\n", + "bounds = [-10.71, -10.71, -10, 10.71, 10.71, 10.]\n", + "uniform_dist = openmc.stats.Box(bounds[:3], bounds[3:], only_fissionable=True)\n", + "settings_file.source = openmc.source.Source(space=uniform_dist)\n", + "\n", + "# Export to \"settings.xml\"\n", + "settings_file.export_to_xml()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let us also create a Plots file that we can use to verify that our fuel assembly geometry was created successfully." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Instantiate a Plot\n", + "plot = openmc.Plot()\n", + "plot.filename = 'materials-xy'\n", + "plot.origin = [0, 0, 0]\n", + "plot.pixels = [250, 250]\n", + "plot.width = [-10.71*2, -10.71*2]\n", + "plot.color = 'mat'\n", + "\n", + "# Instantiate a Plots object, add Plot, and export to \"plots.xml\"\n", + "plot_file = openmc.Plots([plot])\n", + "plot_file.export_to_xml()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With the plots.xml file, we can now generate and view the plot. OpenMC outputs plots in .ppm format, which can be converted into a compressed format like .png with the convert utility." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Run openmc in plotting mode\n", + "openmc.plot_geometry(output=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6AgMAAAD1grKuAAAABGdBTUEAALGPC/xhBQAAACBjSFJN\nAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAADFBMVEX////pgJFyEhJNv8RV\nUZDeAAAAAWJLR0QAiAUdSAAAAAd0SU1FB+AFERUOBQ7RtjIAAAWFSURBVGje7Zs7cttADIZ9CSvX\ncrP0iCxUqbBc8Ag6xR6BhV2EvYvwFD4CCx1ABT1jMdgndpegRQnOrCbjpPlGESISC4A/gd27e8H5\n83CX3b4+iKJrRHkS4vkghMPBonRYWGwtfgD2YN+dRDUOoh6lACw0Noi9w2fESuEoAR/uVuMolX03\n9oXGT7F3eFL2iEfhUX1f4cPdL/ishs+68ai+udE4xPhexbjX2FfjGNoPj/DPNX4Tsd+EODr8FvsV\ndf1Hd9P2VvCi4+s/aXvrf+upAD+1/9GV1mkOH5X9vV6THtfvACslcaUCbESL61drBPtdI8SrFMWr\nELsXCkuFDYW75gbiP7d9Cf7bAYI/aCwUShrBvh30+lWQkzVgZ/HD4OixNCgcQpJ3BxU/Ln91elKo\nM5VEE38QtJ+Yv6cQ9xjKNYayyl8TypP8DfJnQ2H/b/N3ye9P83cT33SQv/sQh9gV7zZ/0dNj5HQa\nC5vVzv9+/WFN2w8KVaZ2BwL1+pv4g0x1QRfjq0dB4Q3kT277oP6VNL6gKxNU9a8zK+WLbi/Wwpdi\nhbboKqyxFOulHMj6v4W/AXbmUeAxrv9J/CqEBXaRKsXaodD4nsYvkT/G6H1D4SR/iPy1Roj9JsQ5\ne18/7EUHv1+Fvx/Xj5V9Ugb5K8TW4TZEEdcvoz/up0VTe9qsVIppKVX6a7D6y9ZvwEKjrtQxPtv6\nfXII9vCxKOGaIeAIfEF8IvAG8ie3vRK9rRQl+PPpSctbhfpTUCpviH+kxsZgpT91+snoX1l49KK3\niUQvICRy5aUw6l8leoVwoo3Uv1rKreF/UFLY6d9QP4L9Wf2r7EP9GOSfcsjZ56f60kz+XmVPXv+R\nuP49ff0T/53Rv6n/7m2lvXT9Wqd/VUz8hvh5M/ED6ILmt4mfHYZSaePnTWpsf/SvqV9O6dLYYClL\nEetnoH/LBLFoBvrX189uTv8++kot5vTvQD4/9jP690g9P/4z/bvo/XVG/xYoZZx+8fr3MxAtsf7t\nUOkG2JqsTtCIpgCt/qX1226KqZS7gfzJbe+c9jLrtIZ8lXD+s4umlW6AKIVrlML2/cXjgPFjlJqI\nRC+Fj0bVJe+vSh56pSdR6YkQ1ygF10Wqf0FeLta/iKn9Mv1L24ti2e+7W4n1b3T/W+L+t9H9T/Sv\nVboUmqJJon1/hZq8LnzRDlDrX1u0xRT1+6vEpomMmyYkqi95vIH8yW1PN+122KkLcNLKi/WTF01z\n/cNASrWE/l3ev6T17zX909z9X27/euK/Rf3zWP+Waf9eEv37KkWJ+rfDl6ZglNDa+cEBhwYDvkoN\nP/rX69814NaI3imq0l7OYDy/qSdDGwr7r+Y3VbzoKZr6XX2lfxfOb87qXzr+b1j/Xlp/nP6dn98M\ncdH7cn7zjPObKsYWS3Eb9w8n85smHtqQuPuZ30T2dlIT6F9xFl+n8xslegL9a4c2KRr9W4rp/GYq\numiM9Nec/j2v/yj9u1h//hv9e93vc++f63/u+rPjL3f+5Lbn1j9m/eXWf+7zh/v8+2b9e/Hzn6s/\nuPqHrb8g71n6L3f+5Lbnvn8w33+4718/+5d47//c/gO7/5E7/nPbc/tv3P4fs//I7X9y+6/fqH+v\n6j9z+9/c/ju3/8+eP+TOn9z23PkXc/7Gnf9x5483q38Xzn+582fu/Js9fy8kb/6fO39y23P3n3S8\n/S/c/Tfc/T83uX/pgv1XE/9duP+Lu/+Mvf8td/znti8kb/8ld/9nx9t/Sjw/Ltr/yt1/+337f6/b\nf0zoB3nJ/ucVc/81d/83e/957vzJbc89/8A8f8E9/5HE78XnT/4H/cs5f8Q9/8Q9f8U+/5U7f3Lb\nc88fdrzzjyvm+cuf/Uu887/c88fs88954/8vO4SjPC+2QRIAAAAldEVYdGRhdGU6Y3JlYXRlADIw\nMTYtMDUtMTdUMjE6MTQ6MDUtMDQ6MDCzw4K8AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE2LTA1LTE3\nVDIxOjE0OjA1LTA0OjAwwp46AAAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Convert OpenMC's funky ppm to png\n", + "!convert materials-xy.ppm materials-xy.png\n", + "\n", + "# Display the materials plot inline\n", + "Image(filename='materials-xy.png')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As we can see from the plot, we have a nice array of fuel and guide tube pin cells with fuel, cladding, and water!\n", + "\n", + "# Create an MGXS Library\n", + "\n", + "Now we are ready to generate multi-group cross sections! First, let's define a 2-group structure using the built-in EnergyGroups class." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Instantiate a 2-group EnergyGroups object\n", + "groups = openmc.mgxs.EnergyGroups()\n", + "groups.group_edges = np.array([0., 0.625e-6, 20.])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we will instantiate an openmc.mgxs.Library for the energy groups with our the fuel assembly geometry." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Initialize an 2-group MGXS Library for OpenMOC\n", + "mgxs_lib = openmc.mgxs.Library(geometry)\n", + "mgxs_lib.energy_groups = groups" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, we must specify to the Library which types of cross sections to compute. OpenMC's multi-group mode can accept isotropic flux-weighted cross sections or angle-dependent cross sections, as well as supporting anisotropic scattering represented by either Legendre polynomials, histogram, or tabular angular distributions. At this time the MGXS Library class only supports the generation of isotropic flux-weighted cross sections and P0 scattering, so that is what will be used for this example. Therefore, we will create the following multi-group cross sections needed to run an OpenMC simulation to verify the accuracy of our cross sections: \"transport\", \"absorption\", \"nu-fission\", '\"fission\", \"nu-scatter matrix\", \"scatter matrix\", and \"chi\".\n", + "\"scatter matrix\" is needed in addition to \"nu-scatter matrix\" because OpenMC's multi-group mode can treat scattering multiplication (i.e., (n,xn) reactions)) explicitly instead of adjusting the absorption cross section to maintain neutron balance, and using this explicit treatment would require tallying of both types of scattering matrices." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Specify multi-group cross section types to compute\n", + "mgxs_lib.mgxs_types = ['total', 'absorption', 'nu-fission', 'fission',\n", + " 'nu-scatter matrix', 'scatter matrix', 'chi']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we must specify the type of domain over which we would like the `Library` to compute multi-group cross sections. The domain type corresponds to the type of tally filter to be used in the tallies created to compute multi-group cross sections. At the present time, the `Library` supports \"material,\" \"cell,\" and \"universe\" domain types. In this simple example, we wish to compute multi-group cross sections only for each material andtherefore will use a \"material\" domain type.\n", + "\n", + "**Note:** By default, the `Library` class will instantiate `MGXS` objects for each and every domain (material, cell or universe) in the geometry of interest. However, one may specify a subset of these domains to the `Library.domains` property." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Specify a \"cell\" domain type for the cross section tally filters\n", + "mgxs_lib.domain_type = \"material\"\n", + "\n", + "# Specify the cell domains over which to compute multi-group cross sections\n", + "mgxs_lib.domains = geometry.get_all_materials()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will instruct the library to not compute cross sections on a nuclide-by-nuclide basis, and instead to focus on generating material-specific macroscopic cross sections.\n", + "\n", + "**NOTE:** The default value of the `by_nuclide` parameter is `False`, so the following step is not necessary but is included for illustrative purposes." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Do not compute cross sections on a nuclide-by-nuclide basis\n", + "mgxs_lib.by_nuclide = False" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we will set the scattering order that we wish to use. For this problem we will use P3 scattering." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/nelsonag/git/openmc/openmc/mgxs/library.py:320: RuntimeWarning: The P0 correction will be ignored since the scattering order 0 is greater than zero\n", + " warnings.warn(msg, RuntimeWarning)\n" + ] + } + ], + "source": [ + "# Set the Legendre order to 3 for P3 scattering\n", + "mgxs_lib.legendre_order = 3" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that the `Library` has been setup, lets make sure it contains the types of cross sections which meet the needs of OpenMC's multi-group solver. Note that this step is done automatically when writing the Multi-Group Library file later in the process (as part of the `mgxs_lib.write_mg_library()`), but it is a good practice to also run this before spending all the time running OpenMC to generate the cross sections." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Check the library - if no errors are raised, then the library is satisfactory.\n", + "mgxs_lib.check_library_for_openmc_mgxs()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Lastly, we use the `Library` to construct the tallies needed to compute all of the requested multi-group cross sections in each domain and nuclide." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Construct all tallies needed for the multi-group cross section library\n", + "mgxs_lib.build_library()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The tallies can now be export to a \"tallies.xml\" input file for OpenMC.\n", + "\n", + "**NOTE:** At this point the `Library` has constructed nearly 100 distinct Tally objects. The overhead to tally in OpenMC scales as O(N) for N tallies, which can become a bottleneck for large tally datasets. To compensate for this, the Python API's `Tally`, `Filter` and `Tallies` classes allow for the smart merging of tallies when possible. The `Library` class supports this runtime optimization with the use of the optional `merge` parameter (`False` by default) for the `Library.add_to_tallies_file(...)` method, as shown below." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Create a \"tallies.xml\" file for the MGXS Library\n", + "tallies_file = openmc.Tallies()\n", + "mgxs_lib.add_to_tallies_file(tallies_file, merge=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In addition, we instantiate a fission rate mesh tally to compare with the multi-group result." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Instantiate a tally Mesh\n", + "mesh = openmc.Mesh()\n", + "mesh.type = 'regular'\n", + "mesh.dimension = [17, 17]\n", + "mesh.lower_left = [-10.71, -10.71]\n", + "mesh.upper_right = [+10.71, +10.71]\n", + "\n", + "# Instantiate tally Filter\n", + "mesh_filter = openmc.Filter()\n", + "mesh_filter.mesh = mesh\n", + "\n", + "# Instantiate the Tally\n", + "tally = openmc.Tally(name='mesh tally')\n", + "tally.filters = [mesh_filter]\n", + "tally.scores = ['fission']\n", + "\n", + "# Add tally to collection\n", + "tallies_file.append(tally)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Export all tallies to a \"tallies.xml\" file\n", + "tallies_file.export_to_xml()" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + " .d88888b. 888b d888 .d8888b.\n", + " d88P\" \"Y88b 8888b d8888 d88P Y88b\n", + " 888 888 88888b.d88888 888 888\n", + " 888 888 88888b. .d88b. 88888b. 888Y88888P888 888 \n", + " 888 888 888 \"88b d8P Y8b 888 \"88b 888 Y888P 888 888 \n", + " 888 888 888 888 88888888 888 888 888 Y8P 888 888 888\n", + " Y88b. .d88P 888 d88P Y8b. 888 888 888 \" 888 Y88b d88P\n", + " \"Y88888P\" 88888P\" \"Y8888 888 888 888 888 \"Y8888P\"\n", + "__________________888______________________________________________________\n", + " 888\n", + " 888\n", + "\n", + " Copyright: 2011-2016 Massachusetts Institute of Technology\n", + " License: http://openmc.readthedocs.io/en/latest/license.html\n", + " Version: 0.7.1\n", + " Git SHA1: 058ba68895a2f880402fda3d58cfb14b162931d9\n", + " Date/Time: 2016-05-17 21:14:05\n", + " OpenMP Threads: 4\n", + "\n", + " ===========================================================================\n", + " ========================> INITIALIZATION <=========================\n", + " ===========================================================================\n", + "\n", + " Reading settings XML file...\n", + " Reading cross sections XML file...\n", + " Reading geometry XML file...\n", + " Reading materials XML file...\n", + " Reading tallies XML file...\n", + " Building neighboring cells lists for each surface...\n", + " Loading ACE cross section table: 92235.71c\n", + " Loading ACE cross section table: 92238.71c\n", + " Loading ACE cross section table: 8016.71c\n", + " Loading ACE cross section table: 40090.71c\n", + " Loading ACE cross section table: 1001.71c\n", + " Loading ACE cross section table: 5010.71c\n", + " Maximum neutron transport energy: 20.0000 MeV for 92235.71c\n", + " Initializing source particles...\n", + "\n", + " ===========================================================================\n", + " ====================> K EIGENVALUE SIMULATION <====================\n", + " ===========================================================================\n", + "\n", + " Bat./Gen. k Average k \n", + " ========= ======== ==================== \n", + " 1/1 1.05201 \n", + " 2/1 1.02017 \n", + " 3/1 1.02398 \n", + " 4/1 1.02677 \n", + " 5/1 1.01070 \n", + " 6/1 1.02964 \n", + " 7/1 1.02163 \n", + " 8/1 1.04524 \n", + " 9/1 1.00773 \n", + " 10/1 1.01536 \n", + " 11/1 1.02992 \n", + " 12/1 1.03248 1.03120 +/- 0.00128\n", + " 13/1 0.99044 1.01761 +/- 0.01361\n", + " 14/1 1.01484 1.01692 +/- 0.00965\n", + " 15/1 1.01491 1.01652 +/- 0.00748\n", + " 16/1 1.03809 1.02011 +/- 0.00709\n", + " 17/1 1.02536 1.02086 +/- 0.00604\n", + " 18/1 1.03663 1.02283 +/- 0.00559\n", + " 19/1 1.03902 1.02463 +/- 0.00525\n", + " 20/1 1.01557 1.02373 +/- 0.00478\n", + " 21/1 1.01286 1.02274 +/- 0.00443\n", + " 22/1 1.01392 1.02200 +/- 0.00411\n", + " 23/1 1.04439 1.02372 +/- 0.00416\n", + " 24/1 1.04034 1.02491 +/- 0.00403\n", + " 25/1 0.99433 1.02287 +/- 0.00427\n", + " 26/1 1.02720 1.02314 +/- 0.00400\n", + " 27/1 1.03545 1.02387 +/- 0.00383\n", + " 28/1 1.03853 1.02468 +/- 0.00370\n", + " 29/1 1.02735 1.02482 +/- 0.00350\n", + " 30/1 1.02429 1.02480 +/- 0.00332\n", + " 31/1 1.02901 1.02500 +/- 0.00317\n", + " 32/1 1.03296 1.02536 +/- 0.00304\n", + " 33/1 1.03605 1.02582 +/- 0.00294\n", + " 34/1 1.04247 1.02652 +/- 0.00290\n", + " 35/1 1.02088 1.02629 +/- 0.00279\n", + " 36/1 1.03017 1.02644 +/- 0.00269\n", + " 37/1 1.03216 1.02665 +/- 0.00259\n", + " 38/1 1.01459 1.02622 +/- 0.00254\n", + " 39/1 1.03706 1.02659 +/- 0.00248\n", + " 40/1 1.01383 1.02617 +/- 0.00243\n", + " 41/1 0.99043 1.02502 +/- 0.00262\n", + " 42/1 1.02891 1.02514 +/- 0.00254\n", + " 43/1 1.02100 1.02501 +/- 0.00246\n", + " 44/1 0.99546 1.02414 +/- 0.00254\n", + " 45/1 1.01562 1.02390 +/- 0.00248\n", + " 46/1 1.03025 1.02408 +/- 0.00242\n", + " 47/1 0.99409 1.02327 +/- 0.00249\n", + " 48/1 1.04355 1.02380 +/- 0.00248\n", + " 49/1 1.02763 1.02390 +/- 0.00242\n", + " 50/1 0.99426 1.02316 +/- 0.00247\n", + " Creating state point statepoint.50.h5...\n", + "\n", + " ===========================================================================\n", + " ======================> SIMULATION FINISHED <======================\n", + " ===========================================================================\n", + "\n", + "\n", + " =======================> TIMING STATISTICS <=======================\n", + "\n", + " Total time for initialization = 1.4530E+00 seconds\n", + " Reading cross sections = 1.1470E+00 seconds\n", + " Total time in simulation = 1.8747E+01 seconds\n", + " Time in transport only = 1.8639E+01 seconds\n", + " Time in inactive batches = 2.1690E+00 seconds\n", + " Time in active batches = 1.6578E+01 seconds\n", + " Time synchronizing fission bank = 6.0000E-03 seconds\n", + " Sampling source sites = 4.0000E-03 seconds\n", + " SEND/RECV source sites = 2.0000E-03 seconds\n", + " Time accumulating tallies = 0.0000E+00 seconds\n", + " Total time for finalization = 0.0000E+00 seconds\n", + " Total time elapsed = 2.0209E+01 seconds\n", + " Calculation Rate (inactive) = 23052.1 neutrons/second\n", + " Calculation Rate (active) = 12064.2 neutrons/second\n", + "\n", + " ============================> RESULTS <============================\n", + "\n", + " k-effective (Collision) = 1.02389 +/- 0.00235\n", + " k-effective (Track-length) = 1.02316 +/- 0.00247\n", + " k-effective (Absorption) = 1.02494 +/- 0.00180\n", + " Combined k-effective = 1.02429 +/- 0.00140\n", + " Leakage Fraction = 0.00000 +/- 0.00000\n", + "\n" + ] + }, + { + "data": { + "text/plain": [ + "0" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Run OpenMC\n", + "openmc.run()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To make the files available and not be over-written when running the multi-group calculation, we will now rename the statepoint and summary files." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Move the StatePoint File\n", + "ce_spfile = './ce_statepoint.h5'\n", + "os.rename('statepoint.' + str(batches) + '.h5', ce_spfile)\n", + "# Move the Summary file\n", + "ce_sumfile = './ce_summary.h5'\n", + "os.rename('summary.h5', ce_sumfile)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Tally Data Processing\n", + "\n", + "Our simulation ran successfully and created statepoint and summary output files. Let's begin by loading the StatePoint file, but not automatically linking the summary file." + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Load the statepoint file, but not the summary file, as it is a different filename than expected.\n", + "sp = openmc.StatePoint(ce_spfile, autolink=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In addition to the statepoint file, our simulation also created a summary file which encapsulates information about the materials and geometry. This is necessary for the `openmc.mgxs` module to properly process the tally data. We first create a `Summary` object and link it with the statepoint. Normally this would not need to be performed, but since we have renamed our summary file to avoid conflicts with the Multi-Group calculation's summary file, we will load this in explicitly." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "su = openmc.Summary(ce_sumfile)\n", + "sp.link_with_summary(su)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The statepoint is now ready to be analyzed by the `Library`. We simply have to load the tallies from the statepoint into the `Library` and our `MGXS` objects will compute the cross sections for us under-the-hood." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Initialize MGXS Library with OpenMC statepoint data\n", + "mgxs_lib.load_from_statepoint(sp)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The next step will be to prepare the input for OpenMC to use our newly created multi-group data." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Multi-Group OpenMC Calculation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will now use the `Library` to produce a multi-group cross section data set for use by the OpenMC multi-group solver. " + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/nelsonag/git/openmc/openmc/tallies.py:1988: RuntimeWarning: invalid value encountered in true_divide\n", + " self_rel_err = data['self']['std. dev.'] / data['self']['mean']\n", + "/home/nelsonag/git/openmc/openmc/tallies.py:1989: RuntimeWarning: invalid value encountered in true_divide\n", + " other_rel_err = data['other']['std. dev.'] / data['other']['mean']\n", + "/home/nelsonag/git/openmc/openmc/tallies.py:1990: RuntimeWarning: invalid value encountered in true_divide\n", + " new_tally._mean = data['self']['mean'] / data['other']['mean']\n" + ] + } + ], + "source": [ + "# Create a MGXS File which can then be written to disk\n", + "mgxs_file = mgxs_lib.create_mg_library(xs_type='macro', xsdata_names=['fuel', 'zircaloy', 'water'],\n", + " xs_ids='2m')\n", + "\n", + "# Write the file to disk using the default filename of `mgxs.xml`\n", + "mgxs_file.export_to_xml()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "OpenMC's multi-group mode uses the same input files as does the continuous-energy mode (materials, geometry, settings, plots ,and tallies file). Differences would include the use of a flag to tell the code to use multi-group transport, a location of the multi-group library file, and any changes needed in the materials.xml and geometry.xml files to re-define materials as necessary (for example, if using a macroscopic cross section library instead of individual microscopic nuclide cross sections as is done in continuous-energy, or if multiple cross sections exist for the same material due to the material existing in varied spectral regions).\n", + "\n", + "Since this example is using material-wise macroscopic cross sections without considering that the neutron energy spectra and thus cross sections may be changing in space, we only need to modify the materials.xml and settings.xml files. If the material names and ids are not otherwise changed, then the geometry.xml file does not need to be modified from its continuous-energy form. The tallies.xml file will be left untouched as it currently contains the tally types that we will need to perform our comparison. \n", + "\n", + "First we will create the new materials.xml file. Continuous-energy cross section nuclidic data sets are named with the nuclide name followed by a cross section identifier. For example, the data for hydrogen is accessed in OpenMC by the name `H-1.71c`. The cross-section identifier (in this case, `71c`) can be used to distinguish between different variants of `H-1` data, such as for different evaluations or temperatures. OpenMC multi-group libraries use the same convention of a name followed by a xs identifier. We will use a cross section identifier here of `2m`. Similar to how continuous-energy cross section libraries are named, the `openmc.Macroscopic` quantities below can either have their `xs_id` included (i.e., `'fuel.2m'`). An alternative is to leave this extension off and simply change the `default_xs` parameter to `.2m`." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Instantiate our Macroscopic Data\n", + "fuel_macro = openmc.Macroscopic('fuel')\n", + "zircaloy_macro = openmc.Macroscopic('zircaloy')\n", + "water_macro = openmc.Macroscopic('water')\n", + "\n", + "# Now re-define our materials to use the Multi-Group macroscopic data\n", + "# instead of the continuous-energy data.\n", + "# 1.6 enriched fuel UO2\n", + "fuel = openmc.Material(name='UO2')\n", + "fuel.add_macroscopic(fuel_macro)\n", + "\n", + "# cladding\n", + "zircaloy = openmc.Material(name='Clad')\n", + "zircaloy.add_macroscopic(zircaloy_macro)\n", + "\n", + "# moderator\n", + "water = openmc.Material(name='Water')\n", + "water.add_macroscopic(water_macro)\n", + "\n", + "# Finally, instantiate our Materials object\n", + "materials_file = openmc.Materials((fuel, zircaloy, water))\n", + "materials_file.default_xs = '2m'\n", + "\n", + "# Export to \"materials.xml\"\n", + "materials_file.export_to_xml()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "No geometry file neeeds to be written as the continuous-energy file is correctly defined for the multi-group case as well." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we can make the changes we need to the settings file.\n", + "These changes are limited to telling OpenMC we will be running a multi-group calculation and pointing to the location of our multi-group cross section file." + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Set the location of the cross sections file\n", + "settings_file.cross_sections = './mgxs.xml'\n", + "settings_file.energy_mode = 'multi-group'\n", + "\n", + "# Export to \"settings.xml\"\n", + "settings_file.export_to_xml()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, since we want similar tally data in the end, we will leave our pre-existing `tallies.xml` file for this calculation.\n", + "\n", + "At this point, the problem is set up and we can run the multi-group calculation." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false, + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + " .d88888b. 888b d888 .d8888b.\n", + " d88P\" \"Y88b 8888b d8888 d88P Y88b\n", + " 888 888 88888b.d88888 888 888\n", + " 888 888 88888b. .d88b. 88888b. 888Y88888P888 888 \n", + " 888 888 888 \"88b d8P Y8b 888 \"88b 888 Y888P 888 888 \n", + " 888 888 888 888 88888888 888 888 888 Y8P 888 888 888\n", + " Y88b. .d88P 888 d88P Y8b. 888 888 888 \" 888 Y88b d88P\n", + " \"Y88888P\" 88888P\" \"Y8888 888 888 888 888 \"Y8888P\"\n", + "__________________888______________________________________________________\n", + " 888\n", + " 888\n", + "\n", + " Copyright: 2011-2016 Massachusetts Institute of Technology\n", + " License: http://openmc.readthedocs.io/en/latest/license.html\n", + " Version: 0.7.1\n", + " Git SHA1: 058ba68895a2f880402fda3d58cfb14b162931d9\n", + " Date/Time: 2016-05-17 21:14:26\n", + " OpenMP Threads: 4\n", + "\n", + " ===========================================================================\n", + " ========================> INITIALIZATION <=========================\n", + " ===========================================================================\n", + "\n", + " Reading settings XML file...\n", + " Reading cross sections XML file...\n", + " Reading geometry XML file...\n", + " Reading materials XML file...\n", + " Reading tallies XML file...\n", + " Building neighboring cells lists for each surface...\n", + " Loading Cross Section Data...\n", + " Loading fuel.2m Data...\n", + " Loading zircaloy.2m Data...\n", + " Loading water.2m Data...\n", + " Initializing source particles...\n", + "\n", + " ===========================================================================\n", + " ====================> K EIGENVALUE SIMULATION <====================\n", + " ===========================================================================\n", + "\n", + " Bat./Gen. k Average k \n", + " ========= ======== ==================== \n", + " 1/1 1.06913 \n", + " 2/1 1.04067 \n", + " 3/1 1.01854 \n", + " 4/1 1.00203 \n", + " 5/1 1.03243 \n", + " 6/1 1.02688 \n", + " 7/1 1.06855 \n", + " 8/1 1.03420 \n", + " 9/1 1.01657 \n", + " 10/1 1.02795 \n", + " 11/1 1.01796 \n", + " 12/1 1.03372 1.02584 +/- 0.00788\n", + " 13/1 1.02433 1.02534 +/- 0.00458\n", + " 14/1 1.01147 1.02187 +/- 0.00474\n", + " 15/1 1.01215 1.01993 +/- 0.00416\n", + " 16/1 1.04088 1.02342 +/- 0.00487\n", + " 17/1 1.04033 1.02583 +/- 0.00477\n", + " 18/1 1.04483 1.02821 +/- 0.00477\n", + " 19/1 1.02870 1.02826 +/- 0.00420\n", + " 20/1 1.01339 1.02678 +/- 0.00404\n", + " 21/1 1.03389 1.02742 +/- 0.00371\n", + " 22/1 1.02535 1.02725 +/- 0.00340\n", + " 23/1 1.00225 1.02533 +/- 0.00367\n", + " 24/1 0.99938 1.02347 +/- 0.00387\n", + " 25/1 1.01620 1.02299 +/- 0.00363\n", + " 26/1 1.03393 1.02367 +/- 0.00347\n", + " 27/1 1.01875 1.02338 +/- 0.00327\n", + " 28/1 1.00305 1.02225 +/- 0.00328\n", + " 29/1 1.01453 1.02185 +/- 0.00313\n", + " 30/1 1.02891 1.02220 +/- 0.00299\n", + " 31/1 0.99612 1.02096 +/- 0.00311\n", + " 32/1 1.04911 1.02224 +/- 0.00323\n", + " 33/1 1.01410 1.02188 +/- 0.00310\n", + " 34/1 0.98979 1.02055 +/- 0.00326\n", + " 35/1 1.00938 1.02010 +/- 0.00316\n", + " 36/1 1.02857 1.02043 +/- 0.00305\n", + " 37/1 1.04095 1.02119 +/- 0.00303\n", + " 38/1 1.02033 1.02115 +/- 0.00292\n", + " 39/1 1.02104 1.02115 +/- 0.00282\n", + " 40/1 1.00854 1.02073 +/- 0.00276\n", + " 41/1 1.00932 1.02036 +/- 0.00269\n", + " 42/1 1.00284 1.01982 +/- 0.00266\n", + " 43/1 1.02489 1.01997 +/- 0.00258\n", + " 44/1 1.03981 1.02055 +/- 0.00257\n", + " 45/1 1.02630 1.02072 +/- 0.00251\n", + " 46/1 1.00133 1.02018 +/- 0.00249\n", + " 47/1 1.02409 1.02028 +/- 0.00243\n", + " 48/1 1.03928 1.02078 +/- 0.00241\n", + " 49/1 1.01226 1.02057 +/- 0.00236\n", + " 50/1 1.03536 1.02094 +/- 0.00233\n", + " Creating state point statepoint.50.h5...\n", + "\n", + " ===========================================================================\n", + " ======================> SIMULATION FINISHED <======================\n", + " ===========================================================================\n", + "\n", + "\n", + " =======================> TIMING STATISTICS <=======================\n", + "\n", + " Total time for initialization = 4.6000E-02 seconds\n", + " Reading cross sections = 8.0000E-03 seconds\n", + " Total time in simulation = 1.4524E+01 seconds\n", + " Time in transport only = 1.4457E+01 seconds\n", + " Time in inactive batches = 1.3350E+00 seconds\n", + " Time in active batches = 1.3189E+01 seconds\n", + " Time synchronizing fission bank = 7.0000E-03 seconds\n", + " Sampling source sites = 5.0000E-03 seconds\n", + " SEND/RECV source sites = 2.0000E-03 seconds\n", + " Time accumulating tallies = 0.0000E+00 seconds\n", + " Total time for finalization = 0.0000E+00 seconds\n", + " Total time elapsed = 1.4579E+01 seconds\n", + " Calculation Rate (inactive) = 37453.2 neutrons/second\n", + " Calculation Rate (active) = 15164.2 neutrons/second\n", + "\n", + " ============================> RESULTS <============================\n", + "\n", + " k-effective (Collision) = 1.02358 +/- 0.00231\n", + " k-effective (Track-length) = 1.02094 +/- 0.00233\n", + " k-effective (Absorption) = 1.02682 +/- 0.00152\n", + " Combined k-effective = 1.02527 +/- 0.00153\n", + " Leakage Fraction = 0.00000 +/- 0.00000\n", + "\n" + ] + }, + { + "data": { + "text/plain": [ + "0" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Run the Multi-Group OpenMC Simulation\n", + "openmc.run()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Results Comparison\n", + "Now we can compare the multi-group and continuous-energy results.\n", + "\n", + "We will begin by loading the multi-group statepoint file we just finished writing and extracting the calculated keff.\n", + "Since we did not rename the summary file, we do not need to load it separately this time." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Load the last statepoint file and keff value\n", + "mgsp = openmc.StatePoint('statepoint.' + str(batches) + '.h5')\n", + "mg_keff = mgsp.k_combined" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we can load the continuous-energy eigenvalue for comparison." + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "ce_keff = sp.k_combined" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Lets compare the two eigenvalues, including their bias" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Continuous-Energy keff = 1.024295\n", + "Multi-Group keff = 1.025274\n", + "bias [pcm]: -97.9\n" + ] + } + ], + "source": [ + "bias = 1.0E5 * (ce_keff[0] - mg_keff[0])\n", + "\n", + "print('Continuous-Energy keff = {0:1.6f}'.format(ce_keff[0]))\n", + "print('Multi-Group keff = {0:1.6f}'.format(mg_keff[0]))\n", + "print('bias [pcm]: {0:1.1f}'.format(bias))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This shows a nontrivial pcm bias between the two methods. Some degree of mismatch is expected simply to the very few histories being used in these example problems. An additional mismatch is always inherent in the practical application of multi-group theory due to the high degree of approximations inherent in that method." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Flux and Pin Power Visualizations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next we will visualize the mesh tally results obtained from both the Continuous-Energy and Multi-Group OpenMC calculations.\n", + "\n", + "First, we extract volume-integrated fission rates from the Multi-Group calculation's mesh fission rate tally for each pin cell in the fuel assembly." + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Get the OpenMC fission rate mesh tally data\n", + "mg_mesh_tally = mgsp.get_tally(name='mesh tally')\n", + "mg_fission_rates = mg_mesh_tally.get_values(scores=['fission'])\n", + "\n", + "# Reshape array to 2D for plotting\n", + "mg_fission_rates.shape = (17,17)\n", + "\n", + "# Normalize to the average pin power\n", + "mg_fission_rates /= np.mean(mg_fission_rates)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can do the same for the Continuous-Energy results." + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Get the OpenMC fission rate mesh tally data\n", + "ce_mesh_tally = sp.get_tally(name='mesh tally')\n", + "ce_fission_rates = ce_mesh_tally.get_values(scores=['fission'])\n", + "\n", + "# Reshape array to 2D for plotting\n", + "ce_fission_rates.shape = (17,17)\n", + "\n", + "# Normalize to the average pin power\n", + "ce_fission_rates /= np.mean(ce_fission_rates)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can easily use Matplotlib to visualize the two fission rates side-by-side." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Force zeros to be NaNs so their values are not included when matplotlib calculates\n", + "# the color scale\n", + "ce_fission_rates[ce_fission_rates == 0.] = np.nan\n", + "mg_fission_rates[mg_fission_rates == 0.] = np.nan\n", + "\n", + "# Plot the CE fission rates in the left subplot\n", + "fig = plt.subplot(121)\n", + "plt.imshow(ce_fission_rates, interpolation='none', cmap='jet')\n", + "plt.title('Continuous-Energy Fission Rates')\n", + "\n", + "# Plot the MG fission rates in the right subplot\n", + "fig2 = plt.subplot(122)\n", + "plt.imshow(mg_fission_rates, interpolation='none', cmap='jet')\n", + "plt.title('Multi-Group Fission Rates')\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "We also see very good agreement between the fission rate distributions, though these should converge closer together with an increasing number of particle histories in both the continuous-energy run to generate the multi-group cross sections, and in the multi-group calculation itself." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.1" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/docs/source/pythonapi/examples/mgxs-part-iv.rst b/docs/source/pythonapi/examples/mgxs-part-iv.rst new file mode 100644 index 000000000..e24325521 --- /dev/null +++ b/docs/source/pythonapi/examples/mgxs-part-iv.rst @@ -0,0 +1,13 @@ +.. _notebook_mgxs_part_iv: + +==================================================== +MGXS Part IV: Multi-Group Mode Cross-Section Library +==================================================== + +.. only:: html + + .. notebook:: mgxs-part-iv.ipynb + +.. only:: latex + + IPython notebooks must be viewed in the online HTML documentation. diff --git a/docs/source/pythonapi/examples/pandas-dataframes.ipynb b/docs/source/pythonapi/examples/pandas-dataframes.ipynb index 388e4aaa6..b88cf9949 100644 --- a/docs/source/pythonapi/examples/pandas-dataframes.ipynb +++ b/docs/source/pythonapi/examples/pandas-dataframes.ipynb @@ -20,7 +20,7 @@ "%matplotlib inline\n", "import glob\n", "from IPython.display import Image\n", - "import matplotlib.pylab as pylab\n", + "import matplotlib.pyplot as plt\n", "import scipy.stats\n", "import numpy as np\n", "\n", @@ -108,11 +108,8 @@ }, "outputs": [], "source": [ - "# Instantiate a MaterialsFile, add Materials\n", - "materials_file = openmc.MaterialsFile()\n", - "materials_file.add_material(fuel)\n", - "materials_file.add_material(water)\n", - "materials_file.add_material(zircaloy)\n", + "# Instantiate a Materials collection\n", + "materials_file = openmc.Materials((fuel, water, zircaloy))\n", "materials_file.default_xs = '71c'\n", "\n", "# Export to \"materials.xml\"\n", @@ -239,7 +236,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We now must create a geometry that is assigned a root universe, put the geometry into a `GeometryFile` object, and export it to XML." + "We now must create a geometry that is assigned a root universe and export it to XML." ] }, { @@ -263,12 +260,8 @@ }, "outputs": [], "source": [ - "# Instantiate a GeometryFile\n", - "geometry_file = openmc.GeometryFile()\n", - "geometry_file.geometry = geometry\n", - "\n", "# Export to \"geometry.xml\"\n", - "geometry_file.export_to_xml()" + "geometry.export_to_xml()" ] }, { @@ -292,8 +285,8 @@ "inactive = 5\n", "particles = 2500\n", "\n", - "# Instantiate a SettingsFile\n", - "settings_file = openmc.SettingsFile()\n", + "# Instantiate a Settings object\n", + "settings_file = openmc.Settings()\n", "settings_file.batches = min_batches\n", "settings_file.inactive = inactive\n", "settings_file.particles = particles\n", @@ -333,9 +326,8 @@ "plot.pixels = [250, 250]\n", "plot.color = 'mat'\n", "\n", - "# Instantiate a PlotsFile, add Plot, and export to \"plots.xml\"\n", - "plot_file = openmc.PlotsFile()\n", - "plot_file.add_plot(plot)\n", + "# Instantiate a Plots collection and export to \"plots.xml\"\n", + "plot_file = openmc.Plots([plot])\n", "plot_file.export_to_xml()" ] }, @@ -366,8 +358,7 @@ ], "source": [ "# Run openmc in plotting mode\n", - "executor = openmc.Executor()\n", - "executor.plot_geometry(output=False)" + "openmc.plot_geometry(output=False)" ] }, { @@ -379,7 +370,7 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6AgMAAAD1grKuAAAABGdBTUEAALGPC/xhBQAAAAFzUkdC\nAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAxQTFRF\n////chIS6YCRTb/E6kGE+wAAAAFiS0dEAIgFHUgAAAAJcEhZcwAAAEgAAABIAEbJaz4AAAPZSURB\nVGje7Zs7buMwEIZ9iey50gyNjQpXKTYudIScgkdQYTfut1idwkdQkQNsYQO2Qj0sPiVK+mlQDmwg\nwIcgg8Cc4fCTSK5W4OeFkM8rHv+2I/rgxPZEPZgR7XtQxKdXYuUXJSUnBQ/9WCgo4vOSJ+WFUvF7\nE08mlia+rn7VcKXP8sRszFX8b2MdX2y6v1Tw6MZUw4H4ojfIjD8mvn/qRL5p4+vvlMqvp2EhR8WB\nzfiz20hXORmP9fi/bM9EeUFvV5H/0yRkeSbiGRfFJErxD9ENdz7Mbhig/h89fvtFdMiI/ePUIXV4\nlXju8K3DKv9NThOZ3q2KmUy6grxFES8rjeyic+FFQav+ncg3fXjH+Ts+/iibztFqOiZuZP/Z3Oaf\nPX40NGgST2r+uvQkXXp6cKvmr+r0e1Eef5um3+JHP3IFF1D/seNZJgaDmvY0Gav1s+2f1fqpIcub\nlfKGt6apotG/NVx3SInWtLX+7Vg/Pv1YqOsnun6JSVdOXT/X7vk75f938QP+8OmSBs0fXtymMhJb\nf8qlPynYmpKCh7OB1fzNalOj1sl0ZAruHLiA+RM73pDe/VjMVP89+aTXwjyc/x5n+u991895/utr\nJTy8/06TXh0r/5JOa2JmYmqi4r/vUm/H4wLmT+z4anhr05X+q6KUXhtzr/9qSff5L5uMT//V/NdU\n4YuBTPa/8P67l/6r44ds+hYuoP5jx9ciy6XTWlibBrmx8V/TdMfjkP+6pOsu/lvM9N90sf7r+f6m\n/65n+S8p/itN15v0UkW3/+48+PRfJX6S9Joo4g+G/1qYG9KroqP/WypcuvyXPf13wH89/hHef7MB\n6R3Cqn55U4rv4kfH3zaSgQuYP7HjVf89tXrbO+hfLdr+Ozv/SP1dgtQ/Ov8C+i/3+q/Zf2D/HWi6\nbjT6rym9I/v/03/b+LHS4cTg/utTsV7/net/Afzz4f0XGX84/2j9xZ4/sePR/of2X7D/o+vPo/sv\n6h9B/Bfxr9j1Hz2eN/hO8/wfff4A848+f/1A/530/I0+/8PvH9D3H9HnT+R49P0b+v4PfP/4E/wX\nfP8Mvf9G37/D/ovuP8SeP7Hj0f0vdP8tqP9O339cyv7p3P1fdP8Z3v9G999j13/seMax8x/o+ZN7\n+O+E8zdP/8XOf8Hnz9Dzb7HnT+x49PxlCp7/BM+fOv13wvnXBfivt2lMvD8TyH/Hnb+Gz3+j589j\nz5/Y8ej9h4D+W7qQmf57efqv239n3T+C7z+h969i13/seMax+3/o/cMcu/8Y2H9n3p+J6r98pv8m\n4fwXuH+M3n+OO3++AX9clR+4PhbRAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE2LTA0LTEzVDExOjQw\nOjAxLTA0OjAwQIJDkwAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNi0wNC0xM1QxMTo0MDowMS0wNDow\nMDHf+y8AAAAASUVORK5CYII=\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6AgMAAAD1grKuAAAABGdBTUEAALGPC/xhBQAAAAFzUkdC\nAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAxQTFRF\n////chIS6YCRTb/E6kGE+wAAAAFiS0dEAIgFHUgAAAAJcEhZcwAAAEgAAABIAEbJaz4AAAPZSURB\nVGje7Zs7buMwEIZ9iey50gyNjQpXKTYudIScgkdQYTfut1idwkdQkQNsYQO2Qj0sPiVK+mlQDmwg\nwIcgg8Cc4fCTSK5W4OeFkM8rHv+2I/rgxPZEPZgR7XtQxKdXYuUXJSUnBQ/9WCgo4vOSJ+WFUvF7\nE08mlia+rn7VcKXP8sRszFX8b2MdX2y6v1Tw6MZUw4H4ojfIjD8mvn/qRL5p4+vvlMqvp2EhR8WB\nzfiz20hXORmP9fi/bM9EeUFvV5H/0yRkeSbiGRfFJErxD9ENdz7Mbhig/h89fvtFdMiI/ePUIXV4\nlXju8K3DKv9NThOZ3q2KmUy6grxFES8rjeyic+FFQav+ncg3fXjH+Ts+/iibztFqOiZuZP/Z3Oaf\nPX40NGgST2r+uvQkXXp6cKvmr+r0e1Eef5um3+JHP3IFF1D/seNZJgaDmvY0Gav1s+2f1fqpIcub\nlfKGt6apotG/NVx3SInWtLX+7Vg/Pv1YqOsnun6JSVdOXT/X7vk75f938QP+8OmSBs0fXtymMhJb\nf8qlPynYmpKCh7OB1fzNalOj1sl0ZAruHLiA+RM73pDe/VjMVP89+aTXwjyc/x5n+u991895/utr\nJTy8/06TXh0r/5JOa2JmYmqi4r/vUm/H4wLmT+z4anhr05X+q6KUXhtzr/9qSff5L5uMT//V/NdU\n4YuBTPa/8P67l/6r44ds+hYuoP5jx9ciy6XTWlibBrmx8V/TdMfjkP+6pOsu/lvM9N90sf7r+f6m\n/65n+S8p/itN15v0UkW3/+48+PRfJX6S9Joo4g+G/1qYG9KroqP/WypcuvyXPf13wH89/hHef7MB\n6R3Cqn55U4rv4kfH3zaSgQuYP7HjVf89tXrbO+hfLdr+Ozv/SP1dgtQ/Ov8C+i/3+q/Zf2D/HWi6\nbjT6rym9I/v/03/b+LHS4cTg/utTsV7/net/Afzz4f0XGX84/2j9xZ4/sePR/of2X7D/o+vPo/sv\n6h9B/Bfxr9j1Hz2eN/hO8/wfff4A848+f/1A/530/I0+/8PvH9D3H9HnT+R49P0b+v4PfP/4E/wX\nfP8Mvf9G37/D/ovuP8SeP7Hj0f0vdP8tqP9O339cyv7p3P1fdP8Z3v9G999j13/seMax8x/o+ZN7\n+O+E8zdP/8XOf8Hnz9Dzb7HnT+x49PxlCp7/BM+fOv13wvnXBfivt2lMvD8TyH/Hnb+Gz3+j589j\nz5/Y8ej9h4D+W7qQmf57efqv239n3T+C7z+h969i13/seMax+3/o/cMcu/8Y2H9n3p+J6r98pv8m\n4fwXuH+M3n+OO3++AX9clR+4PhbRAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE2LTA1LTA5VDIzOjAx\nOjE4LTA0OjAw/mF/xQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNi0wNS0wOVQyMzowMToxOC0wNDow\nMI88x3kAAAAASUVORK5CYII=\n", "text/plain": [ "" ] @@ -412,8 +403,8 @@ }, "outputs": [], "source": [ - "# Instantiate an empty TalliesFile\n", - "tallies_file = openmc.TalliesFile()\n", + "# Instantiate an empty Tallies object\n", + "tallies_file = openmc.Tallies()\n", "tallies_file._tallies = []" ] }, @@ -453,9 +444,8 @@ "tally.filters = [mesh_filter, energy_filter]\n", "tally.scores = ['fission', 'nu-fission']\n", "\n", - "# Add mesh and Tally to TalliesFile\n", - "tallies_file.add_mesh(mesh)\n", - "tallies_file.add_tally(tally)" + "# Add mesh and Tally to Tallies\n", + "tallies_file.append(tally)" ] }, { @@ -482,8 +472,8 @@ "tally.scores = ['scatter-y2']\n", "tally.nuclides = [u235, u238]\n", "\n", - "# Add mesh and tally to TalliesFile\n", - "tallies_file.add_tally(tally)" + "# Add mesh and tally to Tallies\n", + "tallies_file.append(tally)" ] }, { @@ -514,8 +504,8 @@ "tally.scores = ['absorption', 'scatter']\n", "tally.triggers = [trigger]\n", "\n", - "# Add mesh and tally to TalliesFile\n", - "tallies_file.add_tally(tally)" + "# Add mesh and tally to Tallies\n", + "tallies_file.append(tally)" ] }, { @@ -561,11 +551,11 @@ " 888\n", " 888\n", "\n", - " Copyright: 2011-2015 Massachusetts Institute of Technology\n", - " License: http://mit-crpg.github.io/openmc/license.html\n", + " Copyright: 2011-2016 Massachusetts Institute of Technology\n", + " License: http://openmc.readthedocs.io/en/latest/license.html\n", " Version: 0.7.1\n", - " Git SHA1: eeb5091ca3a34cc85df73a3318cae2b6c7097413\n", - " Date/Time: 2016-04-13 11:40:02\n", + " Git SHA1: ae588276014a905ecc6e0967bf08288ecec5b550\n", + " Date/Time: 2016-05-09 23:01:18\n", " MPI Processes: 1\n", "\n", " ===========================================================================\n", @@ -629,20 +619,20 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 3.7900E-01 seconds\n", + " Total time for initialization = 3.9000E-01 seconds\n", " Reading cross sections = 8.6000E-02 seconds\n", - " Total time in simulation = 8.7310E+00 seconds\n", - " Time in transport only = 8.7200E+00 seconds\n", - " Time in inactive batches = 1.3230E+00 seconds\n", - " Time in active batches = 7.4080E+00 seconds\n", - " Time synchronizing fission bank = 2.0000E-03 seconds\n", - " Sampling source sites = 1.0000E-03 seconds\n", - " SEND/RECV source sites = 0.0000E+00 seconds\n", + " Total time in simulation = 1.0830E+01 seconds\n", + " Time in transport only = 1.0818E+01 seconds\n", + " Time in inactive batches = 1.3590E+00 seconds\n", + " Time in active batches = 9.4710E+00 seconds\n", + " Time synchronizing fission bank = 3.0000E-03 seconds\n", + " Sampling source sites = 2.0000E-03 seconds\n", + " SEND/RECV source sites = 1.0000E-03 seconds\n", " Time accumulating tallies = 0.0000E+00 seconds\n", " Total time for finalization = 0.0000E+00 seconds\n", - " Total time elapsed = 9.1240E+00 seconds\n", - " Calculation Rate (inactive) = 9448.22 neutrons/second\n", - " Calculation Rate (active) = 5062.10 neutrons/second\n", + " Total time elapsed = 1.1234E+01 seconds\n", + " Calculation Rate (inactive) = 9197.94 neutrons/second\n", + " Calculation Rate (active) = 3959.46 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", @@ -669,8 +659,8 @@ "# Remove old HDF5 (summary, statepoint) files\n", "!rm statepoint.*\n", "\n", - "# Run OpenMC with MPI!\n", - "executor.run_simulation()" + "# Run OpenMC!\n", + "openmc.run()" ] }, { @@ -696,20 +686,6 @@ "sp = openmc.StatePoint(statepoints[-1])" ] }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": { - "collapsed": false, - "scrolled": true - }, - "outputs": [], - "source": [ - "# Load the summary file and link with statepoint\n", - "su = openmc.Summary('summary.h5')\n", - "sp.link_with_summary(su)" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -719,7 +695,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 22, "metadata": { "collapsed": false }, @@ -758,7 +734,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 23, "metadata": { "collapsed": false }, @@ -788,7 +764,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 24, "metadata": { "collapsed": false }, @@ -1093,7 +1069,7 @@ "19 2.67e-05 " ] }, - "execution_count": 25, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } @@ -1112,16 +1088,16 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 25, "metadata": { "collapsed": false }, "outputs": [ { "data": { - "image/png": "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\nD03l9kElNMu/AAAAAElFTkSuQmCC\n", + "image/png": "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\nSWry/wHxFqsYpaO7aQAAAABJRU5ErkJggg==\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1136,7 +1112,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 26, "metadata": { "collapsed": false }, @@ -1144,10 +1120,10 @@ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 27, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" }, @@ -1155,7 +1131,7 @@ "data": { "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1170,11 +1146,11 @@ "# Extract mean and reshape as 2D NumPy arrays\n", "mean = fiss['mean'].reshape((17,17))\n", "\n", - "pylab.imshow(mean, interpolation='nearest')\n", - "pylab.title('fission rate')\n", - "pylab.xlabel('x')\n", - "pylab.ylabel('y')\n", - "pylab.colorbar()" + "plt.imshow(mean, interpolation='nearest')\n", + "plt.title('fission rate')\n", + "plt.xlabel('x')\n", + "plt.ylabel('y')\n", + "plt.colorbar()" ] }, { @@ -1186,7 +1162,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 27, "metadata": { "collapsed": false }, @@ -1217,7 +1193,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 28, "metadata": { "collapsed": false }, @@ -1408,7 +1384,7 @@ "17 10000 U-238 scatter-Y2,2 2.07e-03 1.60e-03" ] }, - "execution_count": 29, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -1430,7 +1406,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 29, "metadata": { "collapsed": false }, @@ -1461,7 +1437,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 30, "metadata": { "collapsed": false }, @@ -1499,7 +1475,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 31, "metadata": { "collapsed": false }, @@ -1524,222 +1500,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Print the distribcell tally dataframe **without** OpenCG info" + "Print the distribcell tally dataframe" ] }, { "cell_type": "code", - "execution_count": 33, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
distribcellscoremeanstd. dev.
558279absorption8.19e-057.82e-06
559279scatter1.33e-026.19e-04
560280absorption1.00e-047.93e-06
561280scatter1.40e-025.61e-04
562281absorption9.52e-057.08e-06
563281scatter1.51e-026.50e-04
564282absorption9.85e-059.47e-06
565282scatter1.53e-024.63e-04
566283absorption1.08e-041.34e-05
567283scatter1.65e-027.04e-04
568284absorption1.13e-047.91e-06
569284scatter1.67e-025.51e-04
570285absorption1.23e-049.53e-06
571285scatter1.88e-027.25e-04
572286absorption1.44e-041.34e-05
573286scatter1.90e-027.07e-04
574287absorption1.26e-048.66e-06
575287scatter1.97e-027.23e-04
576288absorption1.25e-049.59e-06
577288scatter2.01e-026.75e-04
\n", - "
" - ], - "text/plain": [ - " distribcell score mean std. dev.\n", - "558 279 absorption 8.19e-05 7.82e-06\n", - "559 279 scatter 1.33e-02 6.19e-04\n", - "560 280 absorption 1.00e-04 7.93e-06\n", - "561 280 scatter 1.40e-02 5.61e-04\n", - "562 281 absorption 9.52e-05 7.08e-06\n", - "563 281 scatter 1.51e-02 6.50e-04\n", - "564 282 absorption 9.85e-05 9.47e-06\n", - "565 282 scatter 1.53e-02 4.63e-04\n", - "566 283 absorption 1.08e-04 1.34e-05\n", - "567 283 scatter 1.65e-02 7.04e-04\n", - "568 284 absorption 1.13e-04 7.91e-06\n", - "569 284 scatter 1.67e-02 5.51e-04\n", - "570 285 absorption 1.23e-04 9.53e-06\n", - "571 285 scatter 1.88e-02 7.25e-04\n", - "572 286 absorption 1.44e-04 1.34e-05\n", - "573 286 scatter 1.90e-02 7.07e-04\n", - "574 287 absorption 1.26e-04 8.66e-06\n", - "575 287 scatter 1.97e-02 7.23e-04\n", - "576 288 absorption 1.25e-04 9.59e-06\n", - "577 288 scatter 2.01e-02 6.75e-04" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Get a pandas dataframe for the distribcell tally data\n", - "df = tally.get_pandas_dataframe(nuclides=False)\n", - "\n", - "# Print the last twenty rows in the dataframe\n", - "df.tail(20)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Print the distribcell tally dataframe **with** OpenCG info" - ] - }, - { - "cell_type": "code", - "execution_count": 34, + "execution_count": 32, "metadata": { "collapsed": false }, @@ -1762,11 +1528,11 @@ " \n", " \n", " \n", - " cell\n", " univ\n", + " cell\n", " lat\n", - " cell\n", " univ\n", + " cell\n", " \n", " \n", " \n", @@ -1791,14 +1557,14 @@ " \n", " \n", " 558\n", - " 10003\n", " 0\n", + " 10003\n", " 10001\n", " 16\n", - " 9\n", + " 7\n", " 0\n", - " 10002\n", " 10000\n", + " 10002\n", " 279\n", " absorption\n", " 8.19e-05\n", @@ -1806,14 +1572,14 @@ " \n", " \n", " 559\n", - " 10003\n", " 0\n", + " 10003\n", " 10001\n", " 16\n", - " 9\n", + " 7\n", " 0\n", - " 10002\n", " 10000\n", + " 10002\n", " 279\n", " scatter\n", " 1.33e-02\n", @@ -1821,14 +1587,14 @@ " \n", " \n", " 560\n", - " 10003\n", " 0\n", + " 10003\n", " 10001\n", " 16\n", " 8\n", " 0\n", - " 10002\n", " 10000\n", + " 10002\n", " 280\n", " absorption\n", " 1.00e-04\n", @@ -1836,14 +1602,14 @@ " \n", " \n", " 561\n", - " 10003\n", " 0\n", + " 10003\n", " 10001\n", " 16\n", " 8\n", " 0\n", - " 10002\n", " 10000\n", + " 10002\n", " 280\n", " scatter\n", " 1.40e-02\n", @@ -1851,14 +1617,14 @@ " \n", " \n", " 562\n", - " 10003\n", " 0\n", + " 10003\n", " 10001\n", " 16\n", - " 7\n", + " 9\n", " 0\n", - " 10002\n", " 10000\n", + " 10002\n", " 281\n", " absorption\n", " 9.52e-05\n", @@ -1866,14 +1632,14 @@ " \n", " \n", " 563\n", - " 10003\n", " 0\n", + " 10003\n", " 10001\n", " 16\n", - " 7\n", + " 9\n", " 0\n", - " 10002\n", " 10000\n", + " 10002\n", " 281\n", " scatter\n", " 1.51e-02\n", @@ -1881,14 +1647,14 @@ " \n", " \n", " 564\n", - " 10003\n", " 0\n", + " 10003\n", " 10001\n", " 16\n", - " 6\n", + " 10\n", " 0\n", - " 10002\n", " 10000\n", + " 10002\n", " 282\n", " absorption\n", " 9.85e-05\n", @@ -1896,14 +1662,14 @@ " \n", " \n", " 565\n", - " 10003\n", " 0\n", + " 10003\n", " 10001\n", " 16\n", - " 6\n", + " 10\n", " 0\n", - " 10002\n", " 10000\n", + " 10002\n", " 282\n", " scatter\n", " 1.53e-02\n", @@ -1911,14 +1677,14 @@ " \n", " \n", " 566\n", - " 10003\n", " 0\n", + " 10003\n", " 10001\n", " 16\n", - " 5\n", + " 11\n", " 0\n", - " 10002\n", " 10000\n", + " 10002\n", " 283\n", " absorption\n", " 1.08e-04\n", @@ -1926,14 +1692,14 @@ " \n", " \n", " 567\n", - " 10003\n", " 0\n", + " 10003\n", " 10001\n", " 16\n", - " 5\n", + " 11\n", " 0\n", - " 10002\n", " 10000\n", + " 10002\n", " 283\n", " scatter\n", " 1.65e-02\n", @@ -1941,14 +1707,14 @@ " \n", " \n", " 568\n", - " 10003\n", " 0\n", + " 10003\n", " 10001\n", " 16\n", - " 4\n", + " 12\n", " 0\n", - " 10002\n", " 10000\n", + " 10002\n", " 284\n", " absorption\n", " 1.13e-04\n", @@ -1956,14 +1722,14 @@ " \n", " \n", " 569\n", - " 10003\n", " 0\n", + " 10003\n", " 10001\n", " 16\n", - " 4\n", + " 12\n", " 0\n", - " 10002\n", " 10000\n", + " 10002\n", " 284\n", " scatter\n", " 1.67e-02\n", @@ -1971,14 +1737,14 @@ " \n", " \n", " 570\n", - " 10003\n", " 0\n", + " 10003\n", " 10001\n", " 16\n", - " 3\n", + " 13\n", " 0\n", - " 10002\n", " 10000\n", + " 10002\n", " 285\n", " absorption\n", " 1.23e-04\n", @@ -1986,14 +1752,14 @@ " \n", " \n", " 571\n", - " 10003\n", " 0\n", + " 10003\n", " 10001\n", " 16\n", - " 3\n", + " 13\n", " 0\n", - " 10002\n", " 10000\n", + " 10002\n", " 285\n", " scatter\n", " 1.88e-02\n", @@ -2001,14 +1767,14 @@ " \n", " \n", " 572\n", - " 10003\n", " 0\n", + " 10003\n", " 10001\n", " 16\n", - " 2\n", + " 14\n", " 0\n", - " 10002\n", " 10000\n", + " 10002\n", " 286\n", " absorption\n", " 1.44e-04\n", @@ -2016,14 +1782,14 @@ " \n", " \n", " 573\n", - " 10003\n", " 0\n", + " 10003\n", " 10001\n", " 16\n", - " 2\n", + " 14\n", " 0\n", - " 10002\n", " 10000\n", + " 10002\n", " 286\n", " scatter\n", " 1.90e-02\n", @@ -2031,14 +1797,14 @@ " \n", " \n", " 574\n", - " 10003\n", " 0\n", + " 10003\n", " 10001\n", " 16\n", - " 1\n", + " 15\n", " 0\n", - " 10002\n", " 10000\n", + " 10002\n", " 287\n", " absorption\n", " 1.26e-04\n", @@ -2046,14 +1812,14 @@ " \n", " \n", " 575\n", - " 10003\n", " 0\n", + " 10003\n", " 10001\n", " 16\n", - " 1\n", + " 15\n", " 0\n", - " 10002\n", " 10000\n", + " 10002\n", " 287\n", " scatter\n", " 1.97e-02\n", @@ -2061,14 +1827,14 @@ " \n", " \n", " 576\n", - " 10003\n", " 0\n", + " 10003\n", " 10001\n", " 16\n", + " 16\n", " 0\n", - " 0\n", - " 10002\n", " 10000\n", + " 10002\n", " 288\n", " absorption\n", " 1.25e-04\n", @@ -2076,14 +1842,14 @@ " \n", " \n", " 577\n", - " 10003\n", " 0\n", + " 10003\n", " 10001\n", " 16\n", + " 16\n", " 0\n", - " 0\n", - " 10002\n", " 10000\n", + " 10002\n", " 288\n", " scatter\n", " 2.01e-02\n", @@ -2094,29 +1860,29 @@ "" ], "text/plain": [ - " level 1 level 2 level 3 distribcell score \\\n", - " cell univ lat cell univ \n", - " id id id x y z id id \n", - "558 10003 0 10001 16 9 0 10002 10000 279 absorption \n", - "559 10003 0 10001 16 9 0 10002 10000 279 scatter \n", - "560 10003 0 10001 16 8 0 10002 10000 280 absorption \n", - "561 10003 0 10001 16 8 0 10002 10000 280 scatter \n", - "562 10003 0 10001 16 7 0 10002 10000 281 absorption \n", - "563 10003 0 10001 16 7 0 10002 10000 281 scatter \n", - "564 10003 0 10001 16 6 0 10002 10000 282 absorption \n", - "565 10003 0 10001 16 6 0 10002 10000 282 scatter \n", - "566 10003 0 10001 16 5 0 10002 10000 283 absorption \n", - "567 10003 0 10001 16 5 0 10002 10000 283 scatter \n", - "568 10003 0 10001 16 4 0 10002 10000 284 absorption \n", - "569 10003 0 10001 16 4 0 10002 10000 284 scatter \n", - "570 10003 0 10001 16 3 0 10002 10000 285 absorption \n", - "571 10003 0 10001 16 3 0 10002 10000 285 scatter \n", - "572 10003 0 10001 16 2 0 10002 10000 286 absorption \n", - "573 10003 0 10001 16 2 0 10002 10000 286 scatter \n", - "574 10003 0 10001 16 1 0 10002 10000 287 absorption \n", - "575 10003 0 10001 16 1 0 10002 10000 287 scatter \n", - "576 10003 0 10001 16 0 0 10002 10000 288 absorption \n", - "577 10003 0 10001 16 0 0 10002 10000 288 scatter \n", + " level 1 level 2 level 3 distribcell score \\\n", + " univ cell lat univ cell \n", + " id id id x y z id id \n", + "558 0 10003 10001 16 7 0 10000 10002 279 absorption \n", + "559 0 10003 10001 16 7 0 10000 10002 279 scatter \n", + "560 0 10003 10001 16 8 0 10000 10002 280 absorption \n", + "561 0 10003 10001 16 8 0 10000 10002 280 scatter \n", + "562 0 10003 10001 16 9 0 10000 10002 281 absorption \n", + "563 0 10003 10001 16 9 0 10000 10002 281 scatter \n", + "564 0 10003 10001 16 10 0 10000 10002 282 absorption \n", + "565 0 10003 10001 16 10 0 10000 10002 282 scatter \n", + "566 0 10003 10001 16 11 0 10000 10002 283 absorption \n", + "567 0 10003 10001 16 11 0 10000 10002 283 scatter \n", + "568 0 10003 10001 16 12 0 10000 10002 284 absorption \n", + "569 0 10003 10001 16 12 0 10000 10002 284 scatter \n", + "570 0 10003 10001 16 13 0 10000 10002 285 absorption \n", + "571 0 10003 10001 16 13 0 10000 10002 285 scatter \n", + "572 0 10003 10001 16 14 0 10000 10002 286 absorption \n", + "573 0 10003 10001 16 14 0 10000 10002 286 scatter \n", + "574 0 10003 10001 16 15 0 10000 10002 287 absorption \n", + "575 0 10003 10001 16 15 0 10000 10002 287 scatter \n", + "576 0 10003 10001 16 16 0 10000 10002 288 absorption \n", + "577 0 10003 10001 16 16 0 10000 10002 288 scatter \n", "\n", " mean std. dev. \n", " \n", @@ -2143,14 +1909,14 @@ "577 2.01e-02 6.75e-04 " ] }, - "execution_count": 34, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Get a pandas dataframe for the distribcell tally data\n", - "df = tally.get_pandas_dataframe(summary=su, nuclides=False)\n", + "df = tally.get_pandas_dataframe(nuclides=False)\n", "\n", "# Print the last twenty rows in the dataframe\n", "df.tail(20)" @@ -2158,7 +1924,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 33, "metadata": { "collapsed": false }, @@ -2244,7 +2010,7 @@ "max 9.19e-04 4.95e-05" ] }, - "execution_count": 35, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } @@ -2267,7 +2033,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 34, "metadata": { "collapsed": false }, @@ -2280,44 +2046,6 @@ ] } ], - "source": [ - "# Extract tally data from pins in the pins divided along y=-x diagonal\n", - "multi_index = ('level 2', 'lat',)\n", - "lower = df[df[multi_index + ('x',)] > df[multi_index + ('y',)]]\n", - "upper = df[df[multi_index + ('x',)] < df[multi_index + ('y',)]]\n", - "lower = lower[lower['score'] == 'absorption']\n", - "upper = upper[upper['score'] == 'absorption']\n", - "\n", - "# Perform non-parametric Mann-Whitney U Test to see if the \n", - "# absorption rates (may) come from same sampling distribution\n", - "u, p = scipy.stats.mannwhitneyu(lower['mean'], upper['mean'])\n", - "print('Mann-Whitney Test p-value: {0}'.format(p))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Note that the symmetry implied by the y=x diagonal ensures that the two sampling distributions are identical. Indeed, as illustrated by the test above, for any reasonable significance level (*e.g.*, $\\alpha$=0.05) one would **not reject** the null hypothesis that the two sampling distributions are identical.\n", - "\n", - "Next, perform the same test but with two groupings of pins which are not symmetrically identical to one another." - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Mann-Whitney Test p-value: 6.038663783e-42\n" - ] - } - ], "source": [ "# Extract tally data from pins in the pins divided along y=x diagonal \n", "multi_index = ('level 2', 'lat',)\n", @@ -2332,6 +2060,44 @@ "print('Mann-Whitney Test p-value: {0}'.format(p))" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that the symmetry implied by the y=x diagonal ensures that the two sampling distributions are identical. Indeed, as illustrated by the test above, for any reasonable significance level (*e.g.*, $\\alpha$=0.05) one would **not reject** the null hypothesis that the two sampling distributions are identical.\n", + "\n", + "Next, perform the same test but with two groupings of pins which are not symmetrically identical to one another." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Mann-Whitney Test p-value: 6.038663783e-42\n" + ] + } + ], + "source": [ + "# Extract tally data from pins in the pins divided along y=-x diagonal\n", + "multi_index = ('level 2', 'lat',)\n", + "lower = df[df[multi_index + ('x',)] > df[multi_index + ('y',)]]\n", + "upper = df[df[multi_index + ('x',)] < df[multi_index + ('y',)]]\n", + "lower = lower[lower['score'] == 'absorption']\n", + "upper = upper[upper['score'] == 'absorption']\n", + "\n", + "# Perform non-parametric Mann-Whitney U Test to see if the \n", + "# absorption rates (may) come from same sampling distribution\n", + "u, p = scipy.stats.mannwhitneyu(lower['mean'], upper['mean'])\n", + "print('Mann-Whitney Test p-value: {0}'.format(p))" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -2341,7 +2107,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 36, "metadata": { "collapsed": false }, @@ -2360,10 +2126,10 @@ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 38, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" }, @@ -2371,7 +2137,7 @@ "data": { "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -2390,7 +2156,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 37, "metadata": { "collapsed": false }, @@ -2398,10 +2164,10 @@ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 39, + "execution_count": 37, "metadata": {}, "output_type": "execute_result" }, @@ -2409,7 +2175,7 @@ "data": { "image/png": "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\n9OnTh2bNmtGmTRsuu+wyioqKSt/PzLjvvvvYdddd2W677fjDH/7A3Llz6dOnD02bNmXo0KEbrZ8J\nSggi0mBcccUVXHHFFaxatYq5c+dy8sknA/Dmm28CsGLFClavXk2fPn0YOXIkI0eO5LXXXuOrr75i\n9erVXHbZZQB89tlnXHLJJTz++OMsXryYlStXlna8s97YsWMZMmQIK1as4LTTTiMej3PXXXexfPly\npkyZwqRJk7jvvvs22ubll1/mo48+4t133+WOO+7gvPPO4/HHH+ebb75hxowZjBo1KqPlo4QgIvXe\n4MGDadasWelwySWXlLteTk4Oc+bMYfny5eTn57P//vtv8T0ff/xxrr76ajp37kx+fj5/+ctfGD16\nNCUlJTz11FMce+yx9OvXj9zcXG6++ebNemnr06cPgwcPJhaL0bhxY/bee2/2339/EokEHTt25MIL\nL+SNN97YaJvrrruOJk2a0K1bN7p3786RRx5J586dadq0KYMGDWLatGnVL6wKKCGISL337LPPsmLF\nitJh01/e640YMYJZs2bRpUsX9tlnH55//vktvueiRYvo0KFD6XSHDh0oKSlhyZIlLFq0iPbt25cu\n22abbWjRosVG25ddDjBr1iyOOeYYWrduTZMmTbjxxhtZvnz5Ruu0atWqdLxx48abTa9evbqCUqg+\nJQQRaTB22203Ro0axdKlS7n++usZMmQIa9asKbcP5rZt2zJ//vzS6W+++YZEIkGrVq1o06YNCxYs\nKF22bt06vv/++4223/Q9L774Yrp06cLs2bNZtWoVf/7zn+tcHxNKCCLSYDz22GMsW7aMWCxGs2bN\nAIjFYuy4447EYjG++uqr0nVPPfVU7rrrLr7++mtWr17NjTfeyNChQ0kkEgwZMoRx48YxefJkioqK\nKCgoqPTL/aeffqJJkybk5+fzxRdfVNjvc1Qa7g23IlIt9fG5kPHjx3P11Vezdu1aOnTowOjRo2nc\nuDEAw4YNo2/fvhQXFzN+/HjOPfdcFi1aRP/+/fn555854ogjuOeee4DgYbd77rmHU045hTVr1nDl\nlVfSsmVL8vLytrjvO++8kwsuuIA77riDnj17MnToUF599dVaOe50qQtNybiqPmimB9PqHnWhWbHV\nq1fTrFkzZs+eTadOnSKLQ11oiohEYNy4caxdu5Y1a9ZwzTXX0KNHDzp27Bh1WNWiKiOpEZluxkCk\n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\nSUVORK5CYII=\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -2420,9 +2186,9 @@ "# Plot a histogram and kernel density estimate for the scattering rates\n", "scatter['mean'].plot(kind='hist', bins=25)\n", "scatter['mean'].plot(kind='kde')\n", - "pylab.title('Scattering Rates')\n", - "pylab.xlabel('Mean')\n", - "pylab.legend(['KDE', 'Histogram'])" + "plt.title('Scattering Rates')\n", + "plt.xlabel('Mean')\n", + "plt.legend(['KDE', 'Histogram'])" ] } ], diff --git a/docs/source/pythonapi/examples/post-processing.ipynb b/docs/source/pythonapi/examples/post-processing.ipynb index 0dc18d5a2..de92c2bcb 100644 --- a/docs/source/pythonapi/examples/post-processing.ipynb +++ b/docs/source/pythonapi/examples/post-processing.ipynb @@ -104,11 +104,8 @@ }, "outputs": [], "source": [ - "# Instantiate a MaterialsFile, add Materials\n", - "materials_file = openmc.MaterialsFile()\n", - "materials_file.add_material(fuel)\n", - "materials_file.add_material(water)\n", - "materials_file.add_material(zircaloy)\n", + "# Instantiate a Materials collection\n", + "materials_file = openmc.Materials((fuel, water, zircaloy))\n", "materials_file.default_xs = '71c'\n", "\n", "# Export to \"materials.xml\"\n", @@ -236,12 +233,8 @@ }, "outputs": [], "source": [ - "# Instantiate a GeometryFile\n", - "geometry_file = openmc.GeometryFile()\n", - "geometry_file.geometry = geometry\n", - "\n", "# Export to \"geometry.xml\"\n", - "geometry_file.export_to_xml()" + "geometry.export_to_xml()" ] }, { @@ -264,8 +257,8 @@ "inactive = 10\n", "particles = 5000\n", "\n", - "# Instantiate a SettingsFile\n", - "settings_file = openmc.SettingsFile()\n", + "# Instantiate a Settings object\n", + "settings_file = openmc.Settings()\n", "settings_file.batches = batches\n", "settings_file.inactive = inactive\n", "settings_file.particles = particles\n", @@ -302,9 +295,8 @@ "plot.pixels = [250, 250]\n", "plot.color = 'mat'\n", "\n", - "# Instantiate a PlotsFile, add Plot, and export to \"plots.xml\"\n", - "plot_file = openmc.PlotsFile()\n", - "plot_file.add_plot(plot)\n", + "# Instantiate a Plots collection and export to \"plots.xml\"\n", + "plot_file = openmc.Plots([plot])\n", "plot_file.export_to_xml()" ] }, @@ -335,8 +327,7 @@ ], "source": [ "# Run openmc in plotting mode\n", - "executor = openmc.Executor()\n", - "executor.plot_geometry(output=False)" + "openmc.plot_geometry(output=False)" ] }, { @@ -348,7 +339,7 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6AgMAAAD1grKuAAAABGdBTUEAALGPC/xhBQAAAAFzUkdC\nAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAxQTFRF\n////chIS6YCRTb/E6kGE+wAAAAFiS0dEAIgFHUgAAAAJcEhZcwAAAEgAAABIAEbJaz4AAALKSURB\nVGje7dpLcqQwDAbgHHE2YeEj+D4cwQucBUfo+3CEXoSp8OhuhF70T4qpKXmdr21LogK2Pj7A8QmN\nP+HDhw8fPnz48Kf6VH9G+66vy+je8k19jnf8C5dXIPv86ms56lPdjvaYbyodx3ze+XLE76cXFiD4\nzPji99z0/AJ4n1lfvJ6fnl0A6x+578efMSg1wPr172/jPO5yFXM+Ef78gdblM+WPHyguP//t1/g6\npA0wfln+ho/fwgYYn19C/xwDvwHGc9OvC+hs37DTrwuwfWanXxdQTC9Mvyygs3wjTL8uwPJpn/tN\nDbSGz7T0SBEWw4vLXzbQ6b6RoveIoO6TvPxlA63qs7z8ZQPF9F+SH22vbX8OQKf5Rtv+EgDNJ3X5\n8wZaxWd1+fMGiuFvir8bvjp8J/tGy/6jAmRvhW8fwL3vVT+o3grfPoB7r/IpALI3tz8FoJN84/NV\n873hB8UnM3xzANtf8nb4dwmg3grfFEDJO8JPE0i9Ff4pAYL3pI8mkHor/HMCeO9JH00g9SafEsh7\nT/ppARBvp48UwJnelT5SACd7O31TAlnvKx9SQCd7B58KgPO+8iMFuPWe9E8F8BveWX7bAjzX9y4/\n/Jve+fhsH6Ctv7n8PTzjvY/v9gEOHz58+PBX+6v/f/wPvnd54f3j6venE/yl769Xv7+j3x/o98/V\n32/o9+fl389Xnx+g5x/o+Qt6/oOeP6HnX+j5G3z+h54/ouefV5/foufP6Pk3ev4On/+j9w/o/Qd6\n/4Le/6D3T/D9V67Y/ZsVQBq+s+8f0ftP+P41axXguP9NWgDuu/Cdfv+N3r/D9/9TAID+A7T/Ae2/\ngPs/0P4TtP8F7r9J3AIO9P+g/Udw/9Oygbf7r9D+L7j/DO1/Q/vv4P4/tP8Q7n9E+y/h/k+0/xTu\nf4X7b+H+X7T/+BPuf3aM8OHDhw8fPnz4w/4vzcvgeY10sY0AAAAldEVYdGRhdGU6Y3JlYXRlADIw\nMTYtMDQtMTNUMTE6MzI6NTUtMDQ6MDDR46xaAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE2LTA0LTEz\nVDExOjMyOjU1LTA0OjAwoL4U5gAAAABJRU5ErkJggg==\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6AgMAAAD1grKuAAAABGdBTUEAALGPC/xhBQAAACBjSFJN\nAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAADFBMVEX///9yEhLpgJFNv8Tq\nQYT7AAAAAWJLR0QAiAUdSAAAAAd0SU1FB+AFBRQpN8J6/ygAAALKSURBVGje7dpLcqQwDAbgHHE2\nYeEj+D4cwQucBUfo+3CEXoSp8OhuhF70T4qpKXmdr21LogK2Pj7A8QmNP+HDhw8fPnz48Kf6VH9G\n+66vy+je8k19jnf8C5dXIPv86ms56lPdjvaYbyodx3ze+XLE76cXFiD4zPji99z0/AJ4n1lfvJ6f\nnl0A6x+578efMSg1wPr172/jPO5yFXM+Ef78gdblM+WPHyguP//t1/g6pA0wfln+ho/fwgYYn19C\n/xwDvwHGc9OvC+hs37DTrwuwfWanXxdQTC9Mvyygs3wjTL8uwPJpn/tNDbSGz7T0SBEWw4vLXzbQ\n6b6RoveIoO6TvPxlA63qs7z8ZQPF9F+SH22vbX8OQKf5Rtv+EgDNJ3X58wZaxWd1+fMGiuFvir8b\nvjp8J/tGy/6jAmRvhW8fwL3vVT+o3grfPoB7r/IpALI3tz8FoJN84/NV873hB8UnM3xzANtf8nb4\ndwmg3grfFEDJO8JPE0i9Ff4pAYL3pI8mkHor/HMCeO9JH00g9SafEsh7T/ppARBvp48UwJnelT5S\nACd7O31TAlnvKx9SQCd7B58KgPO+8iMFuPWe9E8F8BveWX7bAjzX9y4//Jve+fhsH6Ctv7n8PTzj\nvY/v9gEOHz58+PBX+6v/f/wPvnd54f3j6venE/yl769Xv7+j3x/o98/V32/o9+fl389Xnx+g5x/o\n+Qt6/oOeP6HnX+j5G3z+h54/ouefV5/foufP6Pk3ev4On/+j9w/o/Qd6/4Le/6D3T/D9V67Y/ZsV\nQBq+s+8f0ftP+P41axXguP9NWgDuu/Cdfv+N3r/D9/9TAID+A7T/Ae2/gPs/0P4TtP8F7r9J3AIO\n9P+g/Udw/9Oygbf7r9D+L7j/DO1/Q/vv4P4/tP8Q7n9E+y/h/k+0/xTuf4X7b+H+X7T/+BPuf3aM\n8OHDhw8fPnz4w/4vzcvgeY10sY0AAAAldEVYdGRhdGU6Y3JlYXRlADIwMTYtMDUtMDVUMTQ6NDE6\nNTUtMDY6MDCnHFu9AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE2LTA1LTA1VDE0OjQxOjU1LTA2OjAw\n1kHjAQAAAABJRU5ErkJggg==\n", "text/plain": [ "" ] @@ -381,8 +372,8 @@ }, "outputs": [], "source": [ - "# Instantiate an empty TalliesFile\n", - "tallies_file = openmc.TalliesFile()" + "# Instantiate an empty Tallies object\n", + "tallies_file = openmc.Tallies()" ] }, { @@ -398,17 +389,16 @@ "mesh.dimension = [100, 100]\n", "mesh.lower_left = [-0.63, -0.63]\n", "mesh.upper_right = [0.63, 0.63]\n", - "tallies_file.add_mesh(mesh)\n", "\n", "# Create mesh filter for tally\n", - "mesh_filter = openmc.Filter(type='mesh', bins=[1])\n", + "mesh_filter = openmc.Filter(type='mesh')\n", "mesh_filter.mesh = mesh\n", "\n", "# Create mesh tally to score flux and fission rate\n", "tally = openmc.Tally(name='flux')\n", "tally.filters = [mesh_filter]\n", "tally.scores = ['flux', 'fission']\n", - "tallies_file.add_tally(tally)" + "tallies_file.append(tally)" ] }, { @@ -455,12 +445,11 @@ " 888\n", " 888\n", "\n", - " Copyright: 2011-2015 Massachusetts Institute of Technology\n", - " License: http://mit-crpg.github.io/openmc/license.html\n", + " Copyright: 2011-2016 Massachusetts Institute of Technology\n", + " License: http://openmc.readthedocs.org/en/latest/license.html\n", " Version: 0.7.1\n", - " Git SHA1: eeb5091ca3a34cc85df73a3318cae2b6c7097413\n", - " Date/Time: 2016-04-13 11:32:56\n", - " MPI Processes: 1\n", + " Git SHA1: df280b60eb1c6d7b7f842e05ede734a4883a0fc8\n", + " Date/Time: 2016-05-05 14:41:55\n", "\n", " ===========================================================================\n", " ========================> INITIALIZATION <=========================\n", @@ -596,20 +585,20 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 3.8100E-01 seconds\n", - " Reading cross sections = 8.6000E-02 seconds\n", - " Total time in simulation = 2.4400E+02 seconds\n", - " Time in transport only = 2.4395E+02 seconds\n", - " Time in inactive batches = 8.3260E+00 seconds\n", - " Time in active batches = 2.3567E+02 seconds\n", - " Time synchronizing fission bank = 1.6000E-02 seconds\n", - " Sampling source sites = 6.0000E-03 seconds\n", - " SEND/RECV source sites = 7.0000E-03 seconds\n", + " Total time for initialization = 4.4900E-01 seconds\n", + " Reading cross sections = 1.2100E-01 seconds\n", + " Total time in simulation = 3.4132E+02 seconds\n", + " Time in transport only = 3.4128E+02 seconds\n", + " Time in inactive batches = 1.0748E+01 seconds\n", + " Time in active batches = 3.3057E+02 seconds\n", + " Time synchronizing fission bank = 1.1000E-02 seconds\n", + " Sampling source sites = 1.1000E-02 seconds\n", + " SEND/RECV source sites = 0.0000E+00 seconds\n", " Time accumulating tallies = 1.9000E-02 seconds\n", - " Total time for finalization = 1.7400E-01 seconds\n", - " Total time elapsed = 2.4458E+02 seconds\n", - " Calculation Rate (inactive) = 6005.28 neutrons/second\n", - " Calculation Rate (active) = 1909.46 neutrons/second\n", + " Total time for finalization = 1.5600E-01 seconds\n", + " Total time elapsed = 3.4196E+02 seconds\n", + " Calculation Rate (inactive) = 4652.03 neutrons/second\n", + " Calculation Rate (active) = 1361.27 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", @@ -634,7 +623,7 @@ ], "source": [ "# Run OpenMC!\n", - "executor.run_simulation()" + "openmc.run()" ] }, { @@ -684,11 +673,11 @@ "text": [ "Tally\n", "\tID =\t10000\n", - "\tName =\t\n", + "\tName =\tflux\n", "\tFilters =\t\n", " \t\tmesh\t[10000]\n", "\tNuclides =\ttotal \n", - "\tScores =\t[u'flux', u'fission']\n", + "\tScores =\t['flux', 'fission']\n", "\tEstimator =\ttracklength\n", "\n" ] @@ -819,11 +808,11 @@ "text": [ "Tally\n", "\tID =\t10001\n", - "\tName =\t\n", + "\tName =\tflux\n", "\tFilters =\t\n", " \t\tmesh\t[10000]\n", "\tNuclides =\ttotal \n", - "\tScores =\t[u'flux']\n", + "\tScores =\t['flux']\n", "\tEstimator =\ttracklength\n", "\n" ] @@ -866,7 +855,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 24, @@ -875,9 +864,9 @@ }, { "data": { - "image/png": "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\nRK5CYII=\n", + "image/png": "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\nAElFTkSuQmCC\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -907,9 +896,9 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYwAAAEACAYAAACgS0HpAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAEupJREFUeJzt3X+IZWd9x/H3N5sfatQ1WnZuuxszsSFxprSVgNHWlhZc\ntkkKmzQLQXegSVNoIf5CRczaUrEUNgpiLXYFq7WrZBo2Lm0CtSaEFKELNmp+aWaMY3U3m9G5sRoC\nUZruut/+cc/u3p25M/Ps/X1m3y+45Mxzz7nnO8/ezWef8+M5kZlIkrSe80ZdgCSpHgwMSVIRA0OS\nVMTAkCQVMTAkSUUMDElSkXUDIyI+FxHNiHiire2SiHggIp6KiPsjYnPbe3siYiEi5iNiR1v71RHx\nRER8NyL+tv+/iiRpkEpGGJ8H/mBZ2x3Ag5l5FfAQsAcgIqaBm4Ep4DpgX0REtc2ngT/NzCuBKyNi\n+WdKksbYuoGRmf8JPLes+QZgf7W8H7ixWt4J3J2ZxzPzMLAAXBMRDeAVmfn1ar0vtG0jSaqBbs9h\nbMnMJkBmLgFbqvatwNG29Rartq3AM23tz1RtkqSa6NdJb+cXkaQN7vwut2tGxERmNqvDTc9W7YvA\npW3rbavaVmvvKCIMIEnqQmbG+mt1p3SEEdXrpPuAW6vlW4B729rfFhEXRsTlwBXAw9Vhq+cj4prq\nJPgft23TUWbW9nXTTTeNvIZzsXbrH/3L+kf7GrR1RxgRMQv8PvCaiHga+DBwJ3BPRNwGHKF1ZRSZ\nORcRB4A54Bhwe57+Ld4B/BPwEuDLmfmV/v4qkqRBWjcwMnP3Km9tX2X9vcDeDu3fBH79rKqTJI0N\n7/QegKmpqVGX0LU61w7WP2rWv7EZGAMwPT096hK6VufawfpHzfo3NgNDklTEwJAkFTEwJElFDAxJ\nUhEDQ5JUxMBQsUZjkohY8Wo0JkddmqQhMDBUrNk8QmueyTNfzeaSQSKdA7qdfFBq8yKdJixuNgc2\nB5qkEXCEIUkqYmBIkooYGJKkIgaGJKmIgSFJKmJgSJKKGBiSpCIGhjrqdFe3pHObN+6po9N3dbcz\nNKRzmSMMSVIRA0OSVMTAkCQVMTAkSUUMDElSEQNDklTEwJAkFTEwJElFDAxJUhEDQ5JUxMCQJBUx\nMCRJRQwMSVIRA0OSVMTAkCQVMTAkSUUMDA3QRSue2tdoTI66KEld6ikwIuK9EfHtiHgiIu6KiAsj\n4pKIeCAinoqI+yNic9v6eyJiISLmI2JH7+VrvL1I66l9p1+tJ/lJqqOuAyMifgV4F3B1Zv4Grce9\nvh24A3gwM68CHgL2VOtPAzcDU8B1wL7wQdGSVBu9HpLaBFwcEecDLwUWgRuA/dX7+4Ebq+WdwN2Z\neTwzDwMLwDU97l+SNCRdB0Zm/hD4OPA0raB4PjMfBCYys1mtswRsqTbZChxt+4jFqk0j1GhMnnGO\nYWZmBgd+kjo5v9sNI+JVtEYTlwHPA/dExAytg9Xtlv9cZNeuXaeWp6ammJ6e7rLS4Tt06NCoSyjW\nOqfQ6Y9ocKExOzs7sM+uU993Yv2jVbf65+bmmJ+fH9r+ug4MYDvw/cz8KUBE/Avw20AzIiYysxkR\nDeDZav1F4NK27bdVbR0dPHiwh9JGb/fu3aMuocjMzMzQ9znovqlL36/G+kerzvUP+uhAL+cwngbe\nHBEvqU5evxWYA+4Dbq3WuQW4t1q+D3hbdSXV5cAVwMM97F+SNERdjzAy8+GI+BLwKHCs+u9ngFcA\nByLiNuAIrSujyMy5iDhAK1SOAbdnZleHqyRJw9fLISky8yPAR5Y1/5TW4apO6+8F9vayT0nSaHin\ntySpiIEhSSpiYEiSihgYkqQiBoYkqYiBIUkqYmCcQ5bPG+WcUZLORk/3YaheOs8bZWhIKuMIQ5JU\nxMCQJBUxMCRJRQwMSVIRA0OSVMTAkCQVMTAkSUUMDElSEQNDklTEwJAkFTEwJElFDAwN2UUrJkCM\nCBqNyVEXJmkdTj6oIXuRlRMgQrPpJIjSuHOEIUkqYmBIkooYGJKkIgaGJKmIgSFJKmJgSJKKGBiS\npCIGhiSpiIEhSSpiYEiSihgYkqQiBoYkqYiBIUkqYmBIkor0FBgRsTki7omI+Yh4MiLeFBGXRMQD\nEfFURNwfEZvb1t8TEQvV+jt6L1+SNCy9jjA+CXw5M6eA3wS+A9wBPJiZVwEPAXsAImIauBmYAq4D\n9kWED0GQpJroOjAi4pXA72bm5wEy83hmPg/cAOyvVtsP3Fgt7wTurtY7DCwA13S7f0nScPUywrgc\n+J+I+HxEPBIRn4mIlwETmdkEyMwlYEu1/lbgaNv2i1WbJKkGegmM84Grgb/PzKuBn9E6HLX8+Zsr\nn8cpSaqdXp7p/QxwNDO/Uf18kFZgNCNiIjObEdEAnq3eXwQubdt+W9XW0a5du04tT01NMT093UOp\nw3Xo0KFRl1BLs7OzPX9G3fve+kerbvXPzc0xPz8/tP11HRhVIByNiCsz87vAW4Enq9etwEeBW4B7\nq03uA+6KiE/QOhR1BfDwap9/8ODBbksbC7t37x51CSvMzMyMuoQ19avPxrHvz4b1j1ad6x/0dUS9\njDAA3k0rBC4Avg/8CbAJOBARtwFHaF0ZRWbORcQBYA44BtyemR6uUuWiFV/2iYnLWFo6PJpyJK3Q\nU2Bk5uPAGzu8tX2V9fcCe3vZpzaqF1l+uqvZ9KpraZx4p7ckqYiBIUkqYmBIkooYGJKkIgaGJKmI\ngSFJKmJgSJKKGBiSpCIGxgbUaEwSEStektSLXqcG0RhqNo/QeZJgQ0NS9xxhSJKKGBiSpCIGhiSp\niIEhSSpiYEiSihgYkqQiBoYkqYiBIUkqYmBIkooYGJKkIgaGJKmIgSFJKmJgaIxd1HHW3UZjctSF\nSeckZ6vVGHuRTrPuNpvOuiuNgiMMSVIRA0OSVMTAkCQVMTAkSUUMDElSEQNDklTEwJAkFTEwJElF\nDAxJUhEDQ5JUxMCQJBUxMGqu0ZhcMTmfJA1Cz4EREedFxCMRcV/18yUR8UBEPBUR90fE5rZ190TE\nQkTMR8SOXvctaDaP0Jqgr/0lSf3XjxHGe4C5tp/vAB7MzKuAh4A9ABExDdwMTAHXAfvCfw5LUm30\nFBgRsQ24HvhsW/MNwP5qeT9wY7W8E7g7M49n5mFgAbiml/1Lkoan1xHGJ4APcOZxkInMbAJk5hKw\npWrfChxtW2+xapMk1UDXgRERfwg0M/MxYK1DSx5Ul6QNoJcn7r0F2BkR1wMvBV4REV8EliJiIjOb\nEdEAnq3WXwQubdt+W9XW0a5du04tT01NMT093UOpw3Xo0KFRl7Dhzc7Odmyve99b/2jVrf65uTnm\n5+eHt8PM7PkF/B5wX7X8MeCD1fIHgTur5WngUeBC4HLge0Cs8nlZZ3fdddfQ9gUk5LJXp7ZhrzvY\n/Y1D3w+C9Y9W3euv/m705f/rnV6DeKb3ncCBiLgNOELryigycy4iDtC6ouoYcHv1C0qSaqAvgZGZ\nXwW+Wi3/FNi+ynp7gb392Kckabi801uSVMTAkCQVMTAkSUUMDElSEQNDNXTRihl6G43JURclbXiD\nuKxWGrAXWT6BQLPpPJbSoDnCkCQVMTAkSUUMDElSEQNDklTEwJAkFTEwJElFDAxJUhEDQ5JUxMCQ\nJBUxMCRJRQwMSVIRA0OSVMTAkCQVMTAkSUUMDElSEQNDklTEwKiJRmNyxVPmInxokKTh8Yl7NdFs\nHmH5U+ZaDA1Jw+EIQ5JUxMDQBnEREcHMzMwZh+wajclRFyZtGB6S0gbxIp0O2TWbHrKT+sURhiSp\niIEhSSpiYEiSihgYkqQiBoYkqYiBIUkqYmBog7toxXQq3pshdcf7MLTBrbw/w3szpO44wpAkFek6\nMCJiW0Q8FBFPRsS3IuLdVfslEfFARDwVEfdHxOa2bfZExEJEzEfEjn78ApKk4ehlhHEceF9m/hrw\nW8A7IuL1wB3Ag5l5FfAQsAcgIqaBm4Ep4DpgXzg/tyTVRteBkZlLmflYtfwCMA9sA24A9ler7Qdu\nrJZ3Andn5vHMPAwsANd0u39J0nD15RxGREwCbwC+BkxkZhNaoQJsqVbbChxt22yxatMynR6WJEmj\n1vNVUhHxcuBLwHsy84WIWD5laKen/qxr165dp5anpqaYnp7uvsghO3ToUE/bd35YkqHRT7Ozs6Mu\noaNevzujZv3DNTc3x/z8/ND211NgRMT5tMLii5l5b9XcjIiJzGxGRAN4tmpfBC5t23xb1dbRwYMH\neylt5Hbv3t31tjMzM32sRJ308uczaONcWwnrH51BH43o9ZDUPwJzmfnJtrb7gFur5VuAe9va3xYR\nF0bE5cAVwMM97l+SNCRdjzAi4i3ADPCtiHiU1jGUDwEfBQ5ExG3AEVpXRpGZcxFxAJgDjgG3Z2ZX\nh6skScPXdWBk5iFg0ypvb19lm73A3m73KUkaHe/0liQVMTAkSUUMDElSEQNDklTEwJAkFTEwJElF\nDAydg1Y+hc8n8Unr84l7OgetfAof+CQ+aT2OMCRJRQwMSVIRA0OSVMTAkCQVMTAkSUUMjBHq9ChW\nH8cqaVx5We0IdX4UK/g4VknjyBGGJKmIgSFJKmJgSJKKGBiSpCIGhnTKykkJnZBQOs2rpKRTVk5K\n6ISE0mmOMCRJRQwMSVIRA0OSVMTAGAKnAKkzn84nneRJ7yFwCpA68+l80kmOMCRJRQwMSVIRA0OS\nVMTAkCQVMTCkrnS+emrTpou9okoblldJSV3pfPXUiROxot0rqrRROMLos0ZjkpmZGe+3kLThOMLo\ns873XBgakurPEYYkqcjQAyMiro2I70TEdyPig8Pef7843YfKOb2INoahHpKKiPOATwFvBX4IfD0i\n7s3M7wyzjn5wug+VW216kZes+EfGxRe/ht27dw+prv6bm5sbdQk9qXv9gzbsEcY1wEJmHsnMY8Dd\nwA1DrkEaEyeD5PTrZz97odajkfn5+VGX0JO61z9owz7pvRU42vbzM7RCZOSWlpbYvv2PeOGFn5/R\nfsEFm3juuWf5yU8WR1SZzi3lo5GJictYWjo8nLIkvErqlMXFRebnv8mmTY0z2n/xix9z4sT/4pVP\nGq1Oj49dGSIA5533Mk6c+Pm6bWu1G0bqZNiBsQi8tu3nbVXbCqM6gXzixNFV3ulUz2o19rrusPfn\n79G/dUexvzN1CoBObWu1N5tHuv47WPeLP+pe/yBFZqcTtwPaWcQm4ClaJ71/BDwMvD0zPXAoSWNu\nqCOMzPxFRLwTeIDWCffPGRaSVA9DHWFIkuprIJfVltycFxF/FxELEfFYRLxhvW0j4mMRMV+tfzAi\nXtn23p7qs+YjYked6o+IyyLi5xHxSPXaN4a1/3VEPB4Rj0bEVyKi0fZeHfq+Y/397vtB1d/2/vsj\n4kREvLqtbez7f7X669L/EfHhiHimrc5r294b+/5frf6u+j8z+/qiFULfAy4DLgAeA16/bJ3rgH+r\nlt8EfG29bYHtwHnV8p3A3mp5GniU1uG1yWr7qFH9lwFPjHnfv7xt+3cBn65Z369Wf9/6fpD1V+9v\nA74C/AB4ddU2VYf+X6P+WvQ/8GHgfR32V4v+X6P+s+7/QYwwSm7OuwH4AkBm/hewOSIm1to2Mx/M\nzBPV9l+j9QUE2AncnZnHM/MwsEBv93YMu37o3zW6g6r9hbbtLwZO/h516fvV6of+Xh89kPornwA+\n0OGzxr7/16gf6tP/neqsU//3duldZRCB0enmvK2F65RsC3Ab8OVVPmtxlW1KDav+f2/7ebIaEv5H\nRPxOt4UX7r+r2iPibyLiaWA38FerfNbY9v0q9UP/+n5g9UfETuBoZn5rnc8ay/5fo36oQf9X3lkd\nAvpsRGxe5bPGsv8r7fW/qq39rPp/XGarLU65iPgL4Fhm/vMA6zlb3dQ/WzX9EHhtZl4NvB+YjYiX\nD6DGVUsqWSkz/zIzXwvcReuwzrjopf4fMdq+h3Xqj4iXAh+idVhhHHVT/8ltRv3db69lLfuA12Xm\nG4Al4OODLems9FL/WX//BxEYJTfnLQKXdlhnzW0j4lbgelr/Slzvs7o11Poz81hmPlctPwL8N3Dl\nuNXeZha4aZ3P6taw6t8FkJn/18e+H1T9v0rr+PjjEfGDqv2RiNhSuL9xrP+bEbGlz9/9QdVPZv44\nq4P+wD9w+rBTLb7/Hep/Y9V+9t//bk/QrHHiZhOnT75cSOvky9Syda7n9ImbN3P6xM2q2wLXAk8C\nr1n2WSdPvF4IXE7vJ56GXf8vcfpk+OtoDStfNWa1X9G2/buAAzXr+9Xq71vfD7L+Zdv/ALikTv2/\nRv216H+g0bb9e4HZOvX/GvWfdf939YsV/OLX0rqjewG4o2r7c+DP2tb5VPULPg5cvda2VfsCcAR4\npHrta3tvT/VZ88COOtVP61/r367avgFcP4a1fwl4ovoS3gv8cs36vmP9/e77QdW/7PO/T3WVUV36\nf7X669L/tE4yn/z+/CswUaf+X63+bvrfG/ckSUXG5aS3JGnMGRiSpCIGhiSpiIEhSSpiYEiSihgY\nkqQiBoYkqYiBIUkq8v85hnCHzxMbMwAAAABJRU5ErkJggg==\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1023,7 +1012,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 28, @@ -1032,9 +1021,9 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAY4AAAEWCAYAAABxMXBSAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAGt5JREFUeJzt3X20ZFV55/Hvj24DaIs9uiamA+1AtKPpvIiMQByzjIZR\nAaOdFUkaX+KCmESypM3rmmgmGZqYSTRvo6CBNoKKOja+JiSrEzQddZIJIK/B0GBoMQ6QNsQQpRVR\nOz7zR50rxe1bt87pe8+9Vfd+P2vVunXO3qfqqd2n66lzzj57p6qQJKmtw5Y7AEnSdDFxSJI6MXFI\nkjoxcUiSOjFxSJI6MXFIkjpZkYkjyfbljmHa2YYLZxsuDttx4Ra7DbMS7+NIUlWV5Y5jmtmGC2cb\nLg7bceEWuw1X5BFH3w41e3fZbr66XcvarFvqX3ULeb+2246rN6q87fq2bd2nvvfFQ23DUWXui93K\nJ7UNPeJYwtfvst18dbuWtVk3bnmxLeT12247rt6o8rbrx7XrUvxS7ntfPNQ2HFXmvtitfFLbcMUm\njuWOQZKmTdvksrbvQJbLSkyIktSXpP0Bidc4JEmdmDgkSZ2YOCRJnZg4JEmdmDgkSZ2YOCRJnZg4\nJEmdrNj7OCStbjfd+QUu3H07X/rqgYPK1h2+lm2nbOL4jeuXIbLpZ+KQtCJduPt2dt92z7x1Ljnr\nxCWKZmUxcUhakWaONB55xFo2bzjqm+v37LuP/Q8cmPNIRO2YOCStaJs3HMXlr3jaN5e37riKaz5z\n7zJGNP28OC5J6sTEIUnqxFNVkqbWfD2n9uy7bxkiWh1MHJKmVpueU+sOn/trbs+++9i646o569tV\nd34mDkkTrc1RxeyeUzPWHb6WV52y6aB1APsfODDyIvnu2+7h5OMePefrmVRMHJImXJujipOOfXTr\nezK2NYlkrkQ0nEjm63m12u//MHFImmij7seYMddRxXyO37h+5Bf/uKMb7/8YMHFImgqz78fow3xJ\nxfs/HmR3XElSJyYOSVInJg5JUicmDklSJyYOSVInJg5JUicmDklSJyYOSVInvSeOJKcm+VSSvUle\nPUd5klzQlN+c5IShstck2ZPk75O8J8kRfccrSZpfr4kjyRrgzcBpwGbgRUk2z6p2GrCpefwMcFGz\n7bHN8n+uqu8B1gBn9hmvJGm8vo84TgL2VtUdVfU1YCewZVadLcBlNXA1sD7JBuA+4OvAkUnWAg8H\n/qnneCVJY/Q9VtXRwJ1Dy3cBJ7eoc3RVXZfk94D/B3wF+HBVfbjPYCUtn1EDDDoh0+SZ2EEOkzwe\n+AXgOOALwPuSvLSq3jVH3e3AeUsboaTFNG749FETMmnxJKmhxfOravtc9fr+l7gb2Di0fEyzrk2d\nZwB/W1X/ApDkg8B/AQ5KHM2H2z6zPOvDS5oC8w2f3nXodB2aqkqben0njmuBTUmOY5AMzgRePKvO\nFcC5SXYyOI31xaral+RTwP9I8nAGp6pOAa7rOV5Jy2wphk/XwvSaOKrqQJJzgSsZ9Iq6tKpuSXJO\nU34xsAs4HdgL3A+c3ZTdlOQyBsniG8CNwFv6jFeSNF7vJw2raheD5DC87uKh5wW8csS2rwde32uA\nkqROvHNcktSJiUOS1ImJQ5LUiYlDktSJiUOS1ImJQ5LUiYlDktSJiUOS1ImJQ5LUiYlDktSJiUOS\n1ImJQ5LUiYlDktSJiUOS1ImJQ5LUiYlDktSJiUOS1ImJQ5LUiYlDktSJiUOS1ImJQ5LUiYlDktSJ\niUOS1ImJQ5LUiYlDktSJiUOS1ImJQ5LUiYlDktSJiUOS1Mna5Q5AkqbJnn33sXXHVQ9Zt+7wtWw7\nZRPHb1y/TFEtLROHJLWw7vDB1+X+Bw5wzWfunbPOJWeduJQhLRsThyS1sO2UTQB86asHHrJ+z777\n2P/AgYPWr2QmDklq4fiN6+c8oti646qRRyArlRfHJUmdmDgkSZ30njiSnJrkU0n2Jnn1HOVJckFT\nfnOSE4bK1id5f5Lbktya5Gl9xytJml+viSPJGuDNwGnAZuBFSTbPqnYasKl5/Axw0VDZG4G/qKon\nAU8Gbu0zXknSePMmjiR7kvxakscf4uufBOytqjuq6mvATmDLrDpbgMtq4GpgfZINSR4FPAO4BKCq\nvlZVXzjEOCRJi2TcEceLgEcAH07yiSS/kOTbO7z+0cCdQ8t3Neva1DkO+BfgbUluTPLWJI/o8N6S\npB7Mmziq6u+q6jVV9XjgVcDjgKuTfDTJT/cc21rgBOCiqnoK8GXgoGskkqSl1foaR1VdXVW/ALwM\nWA+8qcVmdwMbh5aPada1qXMXcFdVXdOsfz+DRHKQJNuT1MyjRVySpFmGv0eTbB9Vr1XiSHJikj9I\n8llgO7ADaHPK6lpgU5LjknwLcCZwxaw6VwAva3pXfT/wxaraV1WfA+5M8sSm3inAnrnepKq2V1Vm\n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\n1LFE4vGQAAAAAElFTkSuQmCC\n", + "image/png": "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\nrkJggg==\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1083,9 +1072,9 @@ }, { "data": { - "image/png": "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\nbZVKpTqB/D+F7yW5gV7LfQAAAABJRU5ErkJggg==\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1104,21 +1093,21 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 2", + "display_name": "Python 3", "language": "python", - "name": "python2" + "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", - "version": 2 + "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.6" + "pygments_lexer": "ipython3", + "version": "3.5.1" } }, "nbformat": 4, diff --git a/docs/source/pythonapi/examples/tally-arithmetic.ipynb b/docs/source/pythonapi/examples/tally-arithmetic.ipynb index 094842895..56b3cb45c 100644 --- a/docs/source/pythonapi/examples/tally-arithmetic.ipynb +++ b/docs/source/pythonapi/examples/tally-arithmetic.ipynb @@ -4,9 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "This notebook shows the how tallies can be combined (added, subtracted, multiplied, etc.) using the Python API in order to create derived tallies. Since no covariance information is obtained, it is assumed that tallies are completely independent of one another when propagating uncertainties. The target problem is a simple pin cell.\n", - "\n", - "**Note:** that this Notebook was created using the latest Pandas v0.16.1. Everything in the Notebook will wun with older versions of Pandas, but the multi-indexing option in >v0.15.0 makes the tables look prettier." + "This notebook shows the how tallies can be combined (added, subtracted, multiplied, etc.) using the Python API in order to create derived tallies. Since no covariance information is obtained, it is assumed that tallies are completely independent of one another when propagating uncertainties. The target problem is a simple pin cell." ] }, { @@ -15,27 +13,6 @@ "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The autoreload extension is already loaded. To reload it, use:\n", - " %reload_ext autoreload\n" - ] - } - ], - "source": [ - "%load_ext autoreload\n", - "%autoreload 2" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": false - }, "outputs": [], "source": [ "import glob\n", @@ -61,7 +38,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "metadata": { "collapsed": true }, @@ -85,7 +62,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "metadata": { "collapsed": false }, @@ -120,17 +97,14 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "# Instantiate a MaterialsFile, add Materials\n", - "materials_file = openmc.MaterialsFile()\n", - "materials_file.add_material(fuel)\n", - "materials_file.add_material(water)\n", - "materials_file.add_material(zircaloy)\n", + "# Instantiate a Materials collection\n", + "materials_file = openmc.Materials((fuel, water, zircaloy))\n", "materials_file.default_xs = '71c'\n", "\n", "# Export to \"materials.xml\"\n", @@ -146,7 +120,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "metadata": { "collapsed": false }, @@ -175,7 +149,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "metadata": { "collapsed": false }, @@ -212,7 +186,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "metadata": { "collapsed": false }, @@ -239,7 +213,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "metadata": { "collapsed": false }, @@ -252,18 +226,14 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "# Instantiate a GeometryFile\n", - "geometry_file = openmc.GeometryFile()\n", - "geometry_file.geometry = geometry\n", - "\n", "# Export to \"geometry.xml\"\n", - "geometry_file.export_to_xml()" + "geometry.export_to_xml()" ] }, { @@ -275,7 +245,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 10, "metadata": { "collapsed": true }, @@ -286,8 +256,8 @@ "inactive = 5\n", "particles = 2500\n", "\n", - "# Instantiate a SettingsFile\n", - "settings_file = openmc.SettingsFile()\n", + "# Instantiate a Settings object\n", + "settings_file = openmc.Settings()\n", "settings_file.batches = batches\n", "settings_file.inactive = inactive\n", "settings_file.particles = particles\n", @@ -311,7 +281,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 11, "metadata": { "collapsed": false }, @@ -325,9 +295,8 @@ "plot.pixels = [250, 250]\n", "plot.color = 'mat'\n", "\n", - "# Instantiate a PlotsFile, add Plot, and export to \"plots.xml\"\n", - "plot_file = openmc.PlotsFile()\n", - "plot_file.add_plot(plot)\n", + "# Instantiate a Plots collection and export to \"plots.xml\"\n", + "plot_file = openmc.Plots([plot])\n", "plot_file.export_to_xml()" ] }, @@ -340,7 +309,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 12, "metadata": { "collapsed": false }, @@ -351,32 +320,31 @@ "0" ] }, - "execution_count": 13, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Run openmc in plotting mode\n", - "executor = openmc.Executor()\n", - "executor.plot_geometry(output=False)" + "openmc.plot_geometry(output=False)" ] }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6AgMAAAD1grKuAAAABGdBTUEAALGPC/xhBQAAAAFzUkdC\nAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAxQTFRF\n////chIS6YCRTb/E6kGE+wAAAAFiS0dEAIgFHUgAAAAJcEhZcwAAAEgAAABIAEbJaz4AAALKSURB\nVGje7dpLcqQwDAbgHHE2YeEj+D4cwQucBUfo+3CEXoSp8OhuhF70T4qpKXmdr21LogK2Pj7A8QmN\nP+HDhw8fPnz48Kf6VH9G+66vy+je8k19jnf8C5dXIPv86ms56lPdjvaYbyodx3ze+XLE76cXFiD4\nzPji99z0/AJ4n1lfvJ6fnl0A6x+578efMSg1wPr172/jPO5yFXM+Ef78gdblM+WPHyguP//t1/g6\npA0wfln+ho/fwgYYn19C/xwDvwHGc9OvC+hs37DTrwuwfWanXxdQTC9Mvyygs3wjTL8uwPJpn/tN\nDbSGz7T0SBEWw4vLXzbQ6b6RoveIoO6TvPxlA63qs7z8ZQPF9F+SH22vbX8OQKf5Rtv+EgDNJ3X5\n8wZaxWd1+fMGiuFvir8bvjp8J/tGy/6jAmRvhW8fwL3vVT+o3grfPoB7r/IpALI3tz8FoJN84/NV\n873hB8UnM3xzANtf8nb4dwmg3grfFEDJO8JPE0i9Ff4pAYL3pI8mkHor/HMCeO9JH00g9SafEsh7\nT/ppARBvp48UwJnelT5SACd7O31TAlnvKx9SQCd7B58KgPO+8iMFuPWe9E8F8BveWX7bAjzX9y4/\n/Jve+fhsH6Ctv7n8PTzjvY/v9gEOHz58+PBX+6v/f/wPvnd54f3j6venE/yl769Xv7+j3x/o98/V\n32/o9+fl389Xnx+g5x/o+Qt6/oOeP6HnX+j5G3z+h54/ouefV5/foufP6Pk3ev4On/+j9w/o/Qd6\n/4Le/6D3T/D9V67Y/ZsVQBq+s+8f0ftP+P41axXguP9NWgDuu/Cdfv+N3r/D9/9TAID+A7T/Ae2/\ngPs/0P4TtP8F7r9J3AIO9P+g/Udw/9Oygbf7r9D+L7j/DO1/Q/vv4P4/tP8Q7n9E+y/h/k+0/xTu\nf4X7b+H+X7T/+BPuf3aM8OHDhw8fPnz4w/4vzcvgeY10sY0AAAAldEVYdGRhdGU6Y3JlYXRlADIw\nMTYtMDQtMTNUMTE6Mzk6MTQtMDQ6MDALPlLjAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE2LTA0LTEz\nVDExOjM5OjE0LTA0OjAwemPqXwAAAABJRU5ErkJggg==\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6AgMAAAD1grKuAAAABGdBTUEAALGPC/xhBQAAACBjSFJN\nAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAADFBMVEX///9yEhLpgJFNv8Tq\nQYT7AAAAAWJLR0QAiAUdSAAAAAd0SU1FB+AFBRQzLY81/IkAAALKSURBVGje7dpLcqQwDAbgHHE2\nYeEj+D4cwQucBUfo+3CEXoSp8OhuhF70T4qpKXmdr21LogK2Pj7A8QmNP+HDhw8fPnz48Kf6VH9G\n+66vy+je8k19jnf8C5dXIPv86ms56lPdjvaYbyodx3ze+XLE76cXFiD4zPji99z0/AJ4n1lfvJ6f\nnl0A6x+578efMSg1wPr172/jPO5yFXM+Ef78gdblM+WPHyguP//t1/g6pA0wfln+ho/fwgYYn19C\n/xwDvwHGc9OvC+hs37DTrwuwfWanXxdQTC9Mvyygs3wjTL8uwPJpn/tNDbSGz7T0SBEWw4vLXzbQ\n6b6RoveIoO6TvPxlA63qs7z8ZQPF9F+SH22vbX8OQKf5Rtv+EgDNJ3X58wZaxWd1+fMGiuFvir8b\nvjp8J/tGy/6jAmRvhW8fwL3vVT+o3grfPoB7r/IpALI3tz8FoJN84/NV873hB8UnM3xzANtf8nb4\ndwmg3grfFEDJO8JPE0i9Ff4pAYL3pI8mkHor/HMCeO9JH00g9SafEsh7T/ppARBvp48UwJnelT5S\nACd7O31TAlnvKx9SQCd7B58KgPO+8iMFuPWe9E8F8BveWX7bAjzX9y4//Jve+fhsH6Ctv7n8PTzj\nvY/v9gEOHz58+PBX+6v/f/wPvnd54f3j6venE/yl769Xv7+j3x/o98/V32/o9+fl389Xnx+g5x/o\n+Qt6/oOeP6HnX+j5G3z+h54/ouefV5/foufP6Pk3ev4On/+j9w/o/Qd6/4Le/6D3T/D9V67Y/ZsV\nQBq+s+8f0ftP+P41axXguP9NWgDuu/Cdfv+N3r/D9/9TAID+A7T/Ae2/gPs/0P4TtP8F7r9J3AIO\n9P+g/Udw/9Oygbf7r9D+L7j/DO1/Q/vv4P4/tP8Q7n9E+y/h/k+0/xTuf4X7b+H+X7T/+BPuf3aM\n8OHDhw8fPnz4w/4vzcvgeY10sY0AAAAldEVYdGRhdGU6Y3JlYXRlADIwMTYtMDUtMDVUMTQ6NTE6\nNDUtMDY6MDCqOITjAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE2LTA1LTA1VDE0OjUxOjQ1LTA2OjAw\n22U8XwAAAABJRU5ErkJggg==\n", "text/plain": [ "" ] }, - "execution_count": 14, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -398,19 +366,19 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "# Instantiate an empty TalliesFile\n", - "tallies_file = openmc.TalliesFile()" + "# Instantiate an empty Tallies object\n", + "tallies_file = openmc.Tallies()" ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 15, "metadata": { "collapsed": false }, @@ -426,7 +394,7 @@ "tally.filters = [openmc.Filter(type='cell', bins=[fuel_cell.id, moderator_cell.id])]\n", "tally.filters.append(energy_filter)\n", "tally.scores = ['flux']\n", - "tallies_file.add_tally(tally)\n", + "tallies_file.append(tally)\n", "\n", "# Instantiate reaction rate Tally in fuel\n", "tally = openmc.Tally(name='fuel rxn rates')\n", @@ -434,7 +402,7 @@ "tally.filters.append(energy_filter)\n", "tally.scores = ['nu-fission', 'scatter']\n", "tally.nuclides = [u238, u235]\n", - "tallies_file.add_tally(tally)\n", + "tallies_file.append(tally)\n", "\n", "# Instantiate reaction rate Tally in moderator\n", "tally = openmc.Tally(name='moderator rxn rates')\n", @@ -442,12 +410,12 @@ "tally.filters.append(energy_filter)\n", "tally.scores = ['absorption', 'total']\n", "tally.nuclides = [o16, h1]\n", - "tallies_file.add_tally(tally)" + "tallies_file.append(tally)" ] }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 16, "metadata": { "collapsed": true }, @@ -458,8 +426,22 @@ "abs_rate = openmc.Tally(name='abs. rate')\n", "fiss_rate.scores = ['nu-fission']\n", "abs_rate.scores = ['absorption']\n", - "tallies_file.add_tally(fiss_rate)\n", - "tallies_file.add_tally(abs_rate)" + "tallies_file += (fiss_rate, abs_rate)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# Resonance Escape Probability tallies\n", + "therm_abs_rate = openmc.Tally(name='therm. abs. rate')\n", + "therm_abs_rate.scores = ['absorption']\n", + "therm_abs_rate.filters = [openmc.Filter(type='energy', bins=[0., 0.625e-6])]\n", + "tallies_file.append(therm_abs_rate)" ] }, { @@ -469,33 +451,18 @@ "collapsed": false }, "outputs": [], - "source": [ - "# Resonance Escape Probability tallies\n", - "therm_abs_rate = openmc.Tally(name='therm. abs. rate')\n", - "therm_abs_rate.scores = ['absorption']\n", - "therm_abs_rate.filters = [openmc.Filter(type='energy', bins=[0., 0.625e-6])]\n", - "tallies_file.add_tally(therm_abs_rate)" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": { - "collapsed": false - }, - "outputs": [], "source": [ "# Thermal Flux Utilization tallies\n", "fuel_therm_abs_rate = openmc.Tally(name='fuel therm. abs. rate')\n", "fuel_therm_abs_rate.scores = ['absorption']\n", "fuel_therm_abs_rate.filters = [openmc.Filter(type='energy', bins=[0., 0.625e-6]),\n", " openmc.Filter(type='cell', bins=[fuel_cell.id])]\n", - "tallies_file.add_tally(fuel_therm_abs_rate)" + "tallies_file.append(fuel_therm_abs_rate)" ] }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 19, "metadata": { "collapsed": true }, @@ -505,12 +472,12 @@ "therm_fiss_rate = openmc.Tally(name='therm. fiss. rate')\n", "therm_fiss_rate.scores = ['nu-fission']\n", "therm_fiss_rate.filters = [openmc.Filter(type='energy', bins=[0., 0.625e-6])]\n", - "tallies_file.add_tally(therm_fiss_rate)" + "tallies_file.append(therm_fiss_rate)" ] }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 20, "metadata": { "collapsed": true }, @@ -525,12 +492,12 @@ "tally.filters.append(energy_filter)\n", "tally.scores = ['nu-fission', 'scatter']\n", "tally.nuclides = [h1, u238]\n", - "tallies_file.add_tally(tally)" + "tallies_file.append(tally)" ] }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 21, "metadata": { "collapsed": false }, @@ -549,7 +516,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 22, "metadata": { "collapsed": false, "scrolled": true @@ -572,12 +539,11 @@ " 888\n", " 888\n", "\n", - " Copyright: 2011-2015 Massachusetts Institute of Technology\n", - " License: http://mit-crpg.github.io/openmc/license.html\n", + " Copyright: 2011-2016 Massachusetts Institute of Technology\n", + " License: http://openmc.readthedocs.org/en/latest/license.html\n", " Version: 0.7.1\n", - " Git SHA1: eeb5091ca3a34cc85df73a3318cae2b6c7097413\n", - " Date/Time: 2016-04-13 11:39:14\n", - " MPI Processes: 1\n", + " Git SHA1: df280b60eb1c6d7b7f842e05ede734a4883a0fc8\n", + " Date/Time: 2016-05-05 14:51:45\n", "\n", " ===========================================================================\n", " ========================> INITIALIZATION <=========================\n", @@ -633,20 +599,20 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 4.0300E-01 seconds\n", - " Reading cross sections = 8.6000E-02 seconds\n", - " Total time in simulation = 1.4439E+01 seconds\n", - " Time in transport only = 1.4430E+01 seconds\n", - " Time in inactive batches = 2.2790E+00 seconds\n", - " Time in active batches = 1.2160E+01 seconds\n", - " Time synchronizing fission bank = 2.0000E-03 seconds\n", - " Sampling source sites = 1.0000E-03 seconds\n", - " SEND/RECV source sites = 1.0000E-03 seconds\n", - " Time accumulating tallies = 0.0000E+00 seconds\n", - " Total time for finalization = 1.0000E-03 seconds\n", - " Total time elapsed = 1.4856E+01 seconds\n", - " Calculation Rate (inactive) = 5484.86 neutrons/second\n", - " Calculation Rate (active) = 3083.88 neutrons/second\n", + " Total time for initialization = 7.2500E-01 seconds\n", + " Reading cross sections = 4.4400E-01 seconds\n", + " Total time in simulation = 1.5547E+01 seconds\n", + " Time in transport only = 1.5527E+01 seconds\n", + " Time in inactive batches = 2.2880E+00 seconds\n", + " Time in active batches = 1.3259E+01 seconds\n", + " Time synchronizing fission bank = 1.0000E-03 seconds\n", + " Sampling source sites = 0.0000E+00 seconds\n", + " SEND/RECV source sites = 0.0000E+00 seconds\n", + " Time accumulating tallies = 1.0000E-03 seconds\n", + " Total time for finalization = 2.0000E-03 seconds\n", + " Total time elapsed = 1.6291E+01 seconds\n", + " Calculation Rate (inactive) = 5463.29 neutrons/second\n", + " Calculation Rate (active) = 2828.27 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", @@ -664,7 +630,7 @@ "0" ] }, - "execution_count": 23, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -673,8 +639,8 @@ "# Remove old HDF5 (summary, statepoint) files\n", "!rm statepoint.*\n", "\n", - "# Run OpenMC with MPI!\n", - "executor.run_simulation()" + "# Run OpenMC!\n", + "openmc.run()" ] }, { @@ -693,7 +659,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 23, "metadata": { "collapsed": false, "scrolled": true @@ -704,27 +670,6 @@ "sp = openmc.StatePoint('statepoint.20.h5')" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You may have also noticed we instructed OpenMC to create a summary file with lots of geometry information in it. This can help to produce more sensible output from the Python API, so we will use the summary file to link against." - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": { - "collapsed": false, - "scrolled": true - }, - "outputs": [], - "source": [ - "# Load the summary file and link with statepoint\n", - "su = openmc.Summary('summary.h5')\n", - "sp.link_with_summary(su)" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -736,7 +681,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 24, "metadata": { "collapsed": false }, @@ -772,7 +717,7 @@ "0 total (nu-fission / absorption) 1.04e+00 6.14e-03" ] }, - "execution_count": 26, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } @@ -796,7 +741,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 25, "metadata": { "collapsed": false }, @@ -820,7 +765,7 @@ " \n", " \n", " 0\n", - " 0\n", + " 0.0\n", " 6.250000e-07\n", " total\n", " absorption\n", @@ -836,7 +781,7 @@ "0 0.00e+00 6.25e-07 total absorption 6.93e-01 4.11e-03" ] }, - "execution_count": 27, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -858,7 +803,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 26, "metadata": { "collapsed": false }, @@ -882,7 +827,7 @@ " \n", " \n", " 0\n", - " 0\n", + " 0.0\n", " 6.250000e-07\n", " total\n", " nu-fission\n", @@ -898,7 +843,7 @@ "0 0.00e+00 6.25e-07 total nu-fission 1.20e+00 7.60e-03" ] }, - "execution_count": 28, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -919,6 +864,137 @@ "where the superscript $F$ denotes fuel." ] }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
energy low [MeV]energy high [MeV]cellnuclidescoremeanstd. dev.
00.06.250000e-0710000totalabsorption0.7484130.004723
\n", + "
" + ], + "text/plain": [ + " energy low [MeV] energy high [MeV] cell nuclide score mean \\\n", + "0 0.00e+00 6.25e-07 10000 total absorption 7.48e-01 \n", + "\n", + " std. dev. \n", + "0 4.72e-03 " + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Compute thermal flux utilization factor using tally arithmetic\n", + "fuel_therm_abs_rate = sp.get_tally(name='fuel therm. abs. rate')\n", + "therm_util = fuel_therm_abs_rate / therm_abs_rate\n", + "therm_util.get_pandas_dataframe()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The final factor is the number of fission neutrons produced per absorption in fuel, calculated as $$\\eta = \\frac{\\langle \\nu\\Sigma_f\\phi \\rangle_T}{\\langle \\Sigma_a \\phi \\rangle^F_T}$$" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
energy low [MeV]energy high [MeV]cellnuclidescoremeanstd. dev.
00.06.250000e-0710000total(nu-fission / absorption)1.6633850.011253
\n", + "
" + ], + "text/plain": [ + " energy low [MeV] energy high [MeV] cell nuclide \\\n", + "0 0.00e+00 6.25e-07 10000 total \n", + "\n", + " score mean std. dev. \n", + "0 (nu-fission / absorption) 1.66e+00 1.13e-02 " + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Compute neutrons produced per absorption (eta) using tally arithmetic\n", + "eta = therm_fiss_rate / fuel_therm_abs_rate\n", + "eta.get_pandas_dataframe()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can calculate $k_\\infty$ using the product of the factors form the four-factor formula." + ] + }, { "cell_type": "code", "execution_count": 29, @@ -946,138 +1022,7 @@ " \n", " \n", " 0\n", - " 0\n", - " 6.250000e-07\n", - " 10000\n", - " total\n", - " absorption\n", - " 0.748413\n", - " 0.004723\n", - " \n", - " \n", - "\n", - "" - ], - "text/plain": [ - " energy low [MeV] energy high [MeV] cell nuclide score mean \\\n", - "0 0.00e+00 6.25e-07 10000 total absorption 7.48e-01 \n", - "\n", - " std. dev. \n", - "0 4.72e-03 " - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Compute thermal flux utilization factor using tally arithmetic\n", - "fuel_therm_abs_rate = sp.get_tally(name='fuel therm. abs. rate')\n", - "therm_util = fuel_therm_abs_rate / therm_abs_rate\n", - "therm_util.get_pandas_dataframe()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The final factor is the number of fission neutrons produced per absorption in fuel, calculated as $$\\eta = \\frac{\\langle \\nu\\Sigma_f\\phi \\rangle_T}{\\langle \\Sigma_a \\phi \\rangle^F_T}$$" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
energy low [MeV]energy high [MeV]cellnuclidescoremeanstd. dev.
006.250000e-0710000total(nu-fission / absorption)1.6633850.011253
\n", - "
" - ], - "text/plain": [ - " energy low [MeV] energy high [MeV] cell nuclide \\\n", - "0 0.00e+00 6.25e-07 10000 total \n", - "\n", - " score mean std. dev. \n", - "0 (nu-fission / absorption) 1.66e+00 1.13e-02 " - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Compute neutrons produced per absorption (eta) using tally arithmetic\n", - "eta = therm_fiss_rate / fuel_therm_abs_rate\n", - "eta.get_pandas_dataframe()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we can calculate $k_\\infty$ using the product of the factors form the four-factor formula." - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", " \n", " \n", " \n", @@ -1097,7 +1042,7 @@ "0 (((absorption * nu-fission) * absorption) * (n... 1.04e+00 1.32e-02 " ] }, - "execution_count": 31, + "execution_count": 29, "metadata": {}, "output_type": "execute_result" } @@ -1118,7 +1063,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 30, "metadata": { "collapsed": false, "scrolled": true @@ -1134,7 +1079,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 31, "metadata": { "collapsed": false }, @@ -1263,7 +1208,7 @@ "7 (scatter / flux) 3.37e-03 1.44e-05 " ] }, - "execution_count": 33, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -1282,7 +1227,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 32, "metadata": { "collapsed": false }, @@ -1314,7 +1259,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 33, "metadata": { "collapsed": false }, @@ -1338,7 +1283,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 34, "metadata": { "collapsed": false }, @@ -1369,7 +1314,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 35, "metadata": { "collapsed": false }, @@ -1450,7 +1395,7 @@ "3 7.32e-04 " ] }, - "execution_count": 37, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } @@ -1463,7 +1408,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 36, "metadata": { "collapsed": false }, @@ -1604,7 +1549,7 @@ "8 3.20e-03 " ] }, - "execution_count": 38, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" } @@ -1620,21 +1565,21 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 2", + "display_name": "Python 3", "language": "python", - "name": "python2" + "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", - "version": 2 + "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.6" + "pygments_lexer": "ipython3", + "version": "3.5.1" } }, "nbformat": 4, diff --git a/docs/source/pythonapi/index.rst b/docs/source/pythonapi/index.rst index 9fd70cb5a..bf35e7587 100644 --- a/docs/source/pythonapi/index.rst +++ b/docs/source/pythonapi/index.rst @@ -13,6 +13,21 @@ online. We recommend going through the modules from Codecademy_ and/or the `Scipy lectures`_. The full API documentation serves to provide more information on a given module or class. +------------------------- +Example Jupyter Notebooks +------------------------- + +.. toctree:: + :maxdepth: 1 + + examples/post-processing + examples/pandas-dataframes + examples/tally-arithmetic + examples/mgxs-part-i + examples/mgxs-part-ii + examples/mgxs-part-iii + examples/mgxs-part-iv + ------------------------------------ :mod:`openmc` -- Basic Functionality ------------------------------------ @@ -29,7 +44,7 @@ Classes :template: myclass.rst openmc.XSdata - openmc.MGXSLibraryFile + openmc.MGXSLibrary Functions +++++++++ @@ -50,7 +65,7 @@ Simulation Settings openmc.Source openmc.ResonanceScattering - openmc.SettingsFile + openmc.Settings Material Specification ---------------------- @@ -64,7 +79,7 @@ Material Specification openmc.Element openmc.Macroscopic openmc.Material - openmc.MaterialsFile + openmc.Materials Building geometry ----------------- @@ -96,7 +111,6 @@ Building geometry openmc.RectLattice openmc.HexLattice openmc.Geometry - openmc.GeometryFile Many of the above classes are derived from several abstract classes: @@ -109,6 +123,16 @@ Many of the above classes are derived from several abstract classes: openmc.Region openmc.Lattice +One function is also available to create a hexagonal region defined by the +intersection of six surface half-spaces. + +.. autosummary:: + :toctree: generated + :nosignatures: + :template: myfunction.rst + + openmc.make_hexagon_region + Constructing Tallies -------------------- @@ -121,7 +145,7 @@ Constructing Tallies openmc.Mesh openmc.Trigger openmc.Tally - openmc.TalliesFile + openmc.Tallies Coarse Mesh Finite Difference Acceleration ------------------------------------------ @@ -132,7 +156,7 @@ Coarse Mesh Finite Difference Acceleration :template: myclass.rst openmc.CMFDMesh - openmc.CMFDFile + openmc.CMFD Plotting -------- @@ -143,7 +167,7 @@ Plotting :template: myclass.rst openmc.Plot - openmc.PlotsFile + openmc.Plots Running OpenMC -------------- @@ -151,9 +175,10 @@ Running OpenMC .. autosummary:: :toctree: generated :nosignatures: - :template: myclass.rst + :template: myfunction.rst - openmc.Executor + openmc.run + openmc.plot_geometry Post-processing --------------- @@ -271,20 +296,6 @@ Multi-group Cross Section Libraries openmc.mgxs.Library -------------------------- -Example Jupyter Notebooks -------------------------- - -.. toctree:: - :maxdepth: 1 - - examples/post-processing - examples/pandas-dataframes - examples/tally-arithmetic - examples/mgxs-part-i - examples/mgxs-part-ii - examples/mgxs-part-iii - .. _Jupyter: https://jupyter.org/ .. _NumPy: http://www.numpy.org/ .. _Codecademy: https://www.codecademy.com/tracks/python diff --git a/docs/source/usersguide/index.rst b/docs/source/usersguide/index.rst index 0338c5cef..f8b4e64fa 100644 --- a/docs/source/usersguide/index.rst +++ b/docs/source/usersguide/index.rst @@ -14,7 +14,5 @@ essential aspects of using OpenMC to perform simulations. beginners install input - mgxs_library - output/index processing troubleshoot diff --git a/docs/source/usersguide/input.rst b/docs/source/usersguide/input.rst index a3e3228e4..1b6c412ac 100644 --- a/docs/source/usersguide/input.rst +++ b/docs/source/usersguide/input.rst @@ -1066,6 +1066,20 @@ Each ```` element can have the following attributes or sub-elements: + The rotation applied is an intrinsic rotation whose Tait-Bryan angles are + given as those specified about the x, y, and z axes respectively. That is to + say, if the angles are :math:`(\phi, \theta, \psi)`, then the rotation + matrix applied is :math:`R_z(\psi) R_y(\theta) R_x(\phi)` or + + .. math:: + + \left [ \begin{array}{ccc} \cos\theta \cos\psi & -\cos\theta \sin\psi + + \sin\phi \sin\theta \cos\psi & \sin\phi \sin\psi + \cos\phi \sin\theta + \cos\psi \\ \cos\theta \sin\psi & \cos\phi \cos\psi + \sin\phi \sin\theta + \sin\psi & -\sin\phi \cos\psi + \cos\phi \sin\theta \sin\psi \\ + -\sin\theta & \sin\phi \cos\theta & \cos\phi \cos\theta \end{array} + \right ] + *Default*: None :translation: @@ -1248,11 +1262,10 @@ Each ``material`` element can have the following attributes or sub-elements: An element with attributes/sub-elements called ``value`` and ``units``. The ``value`` attribute is the numeric value of the density while the ``units`` can be "g/cm3", "kg/m3", "atom/b-cm", "atom/cm3", or "sum". The "sum" unit - indicates that values appearing in ``ao`` attributes for ```` and - ```` sub-elements are to be interpreted as nuclide/element - densities in atom/b-cm, and the total density of the material is taken as - the sum of all nuclides/elements. The "sum" option cannot be used in - conjunction with weight percents. The "macro" unit is used with + indicates that values appearing in ``ao`` or ``wo`` attributes for ```` + and ```` sub-elements are to be interpreted as absolute nuclide/element + densities in atom/b-cm or g/cm3, and the total density of the material is + taken as the sum of all nuclides/elements. The "macro" unit is used with a ``macroscopic`` quantity to indicate that the density is already included in the library and thus not needed here. However, if a value is provided for the ``value``, then this is treated as a number density multiplier on @@ -1976,7 +1989,7 @@ sub-elements: datafiles can be processed into 3D SILO files using the ``openmc-voxel-to-silovtk`` utility provided with the OpenMC source, and subsequently viewed with a 3D viewer such as VISIT or Paraview. See the - :ref:`usersguide_voxel` for information about the datafile structure. + :ref:`io_voxel` for information about the datafile structure. .. note:: Since the PPM format is saved without any kind of compression, the resulting file sizes can be quite large. Saving the image in diff --git a/docs/source/usersguide/processing.rst b/docs/source/usersguide/processing.rst index 059659dbc..93a17a7b8 100644 --- a/docs/source/usersguide/processing.rst +++ b/docs/source/usersguide/processing.rst @@ -161,7 +161,7 @@ or * `VTK `_ with python bindings. On debian derivatives, these are easily obtained with ``sudo apt-get install python-vtk`` -For the HDF5 file structure, see :ref:`usersguide_voxel`. +For the HDF5 file structure, see :ref:`io_voxel`. Once processed into a standard 3D file format, colors and masks can be defined using the stored id numbers to better explore the geometry. The process for @@ -195,7 +195,7 @@ Data Extraction --------------- A great deal of information is available in statepoint files (See -:ref:`usersguide_statepoint`), all of which is accessible through the Python +:ref:`io_statepoint`), all of which is accessible through the Python API. The :class:`openmc.StatePoint` class can load statepoints and access data as requested; it is used in many of the provided plotting utilities, OpenMC's regression test suite, and can be used in user-created scripts to carry out diff --git a/examples/python/basic/build-xml.py b/examples/python/basic/build-xml.py index fbe683661..ffff03720 100644 --- a/examples/python/basic/build-xml.py +++ b/examples/python/basic/build-xml.py @@ -12,7 +12,7 @@ particles = 10000 ############################################################################### -# Exporting to OpenMC materials.xml File +# Exporting to OpenMC materials.xml file ############################################################################### # Instantiate some Nuclides @@ -31,15 +31,14 @@ fuel = openmc.Material(material_id=40, name='fuel') fuel.set_density('g/cc', 4.5) fuel.add_nuclide(u235, 1.) -# Instantiate a MaterialsFile, register all Materials, and export to XML -materials_file = openmc.MaterialsFile() +# Instantiate a Materials collection and export to XML +materials_file = openmc.Materials([moderator, fuel]) materials_file.default_xs = '71c' -materials_file.add_materials([moderator, fuel]) materials_file.export_to_xml() ############################################################################### -# Exporting to OpenMC geometry.xml File +# Exporting to OpenMC geometry.xml file ############################################################################### # Instantiate ZCylinder surfaces @@ -74,22 +73,18 @@ cell1.fill = universe1 universe1.add_cells([cell2, cell3]) root.add_cells([cell1, cell4]) -# Instantiate a Geometry and register the root Universe +# Instantiate a Geometry, register the root Universe, and export to XML geometry = openmc.Geometry() geometry.root_universe = root - -# Instantiate a GeometryFile, register Geometry, and export to XML -geometry_file = openmc.GeometryFile() -geometry_file.geometry = geometry -geometry_file.export_to_xml() +geometry.export_to_xml() ############################################################################### -# Exporting to OpenMC settings.xml File +# Exporting to OpenMC settings.xml file ############################################################################### -# Instantiate a SettingsFile, set all runtime parameters, and export to XML -settings_file = openmc.SettingsFile() +# Instantiate a Settings object, set all runtime parameters, and export to XML +settings_file = openmc.Settings() settings_file.batches = batches settings_file.inactive = inactive settings_file.particles = particles @@ -103,7 +98,7 @@ settings_file.export_to_xml() ############################################################################### -# Exporting to OpenMC tallies.xml File +# Exporting to OpenMC tallies.xml file ############################################################################### # Instantiate some tally Filters @@ -128,9 +123,6 @@ third_tally = openmc.Tally(tally_id=3, name='third tally') third_tally.filters = [cell_filter, energy_filter, energyout_filter] third_tally.scores = ['scatter', 'nu-scatter', 'nu-fission'] -# Instantiate a TalliesFile, register all Tallies, and export to XML -tallies_file = openmc.TalliesFile() -tallies_file.add_tally(first_tally) -tallies_file.add_tally(second_tally) -tallies_file.add_tally(third_tally) +# Instantiate a Tallies collection and export to XML +tallies_file = openmc.Tallies((first_tally, second_tally, third_tally)) tallies_file.export_to_xml() diff --git a/examples/python/boxes/build-xml.py b/examples/python/boxes/build-xml.py index ea3e81d17..814f60beb 100644 --- a/examples/python/boxes/build-xml.py +++ b/examples/python/boxes/build-xml.py @@ -36,15 +36,14 @@ moderator.add_nuclide(h1, 2.) moderator.add_nuclide(o16, 1.) moderator.add_s_alpha_beta('HH2O', '71t') -# Instantiate a MaterialsFile, register all Materials, and export to XML -materials_file = openmc.MaterialsFile() +# Instantiate a Materials collection and export to XML +materials_file = openmc.Materials([fuel1, fuel2, moderator]) materials_file.default_xs = '71c' -materials_file.add_materials([fuel1, fuel2, moderator]) materials_file.export_to_xml() ############################################################################### -# Exporting to OpenMC geometry.xml File +# Exporting to OpenMC geometry.xml file ############################################################################### # Instantiate planar surfaces @@ -97,22 +96,18 @@ outer_box.fill = moderator root = openmc.Universe(universe_id=0, name='root universe') root.add_cells([inner_box, middle_box, outer_box]) -# Instantiate a Geometry and register the root Universe +# Instantiate a Geometry, register the root Universe, and export to XML geometry = openmc.Geometry() geometry.root_universe = root - -# Instantiate a GeometryFile, register Geometry, and export to XML -geometry_file = openmc.GeometryFile() -geometry_file.geometry = geometry -geometry_file.export_to_xml() +geometry.export_to_xml() ############################################################################### # Exporting to OpenMC settings.xml File ############################################################################### -# Instantiate a SettingsFile, set all runtime parameters, and export to XML -settings_file = openmc.SettingsFile() +# Instantiate a Settings object, set all runtime parameters, and export to XML +settings_file = openmc.Settings() settings_file.batches = batches settings_file.inactive = inactive settings_file.particles = particles @@ -133,7 +128,6 @@ plot.width = [20, 20] plot.pixels = [200, 200] plot.color = 'cell' -# Instantiate a PlotsFile, add Plot, and export to XML -plot_file = openmc.PlotsFile() -plot_file.add_plot(plot) +# Instantiate a Plots collection and export to XML +plot_file = openmc.Plots([plot]) plot_file.export_to_xml() diff --git a/examples/python/lattice/hexagonal/build-xml.py b/examples/python/lattice/hexagonal/build-xml.py index 7f92e6602..ef3a12847 100644 --- a/examples/python/lattice/hexagonal/build-xml.py +++ b/examples/python/lattice/hexagonal/build-xml.py @@ -35,15 +35,14 @@ iron = openmc.Material(material_id=3, name='iron') iron.set_density('g/cc', 7.9) iron.add_nuclide(fe56, 1.) -# Instantiate a MaterialsFile, register all Materials, and export to XML -materials_file = openmc.MaterialsFile() +# Instantiate a Materials collection and export to XML +materials_file = openmc.Materials([moderator, fuel, iron]) materials_file.default_xs = '71c' -materials_file.add_materials([moderator, fuel, iron]) materials_file.export_to_xml() ############################################################################### -# Exporting to OpenMC geometry.xml File +# Exporting to OpenMC geometry.xml file ############################################################################### # Instantiate Surfaces @@ -105,22 +104,18 @@ lattice.outer = univ2 # Fill Cell with the Lattice cell1.fill = lattice -# Instantiate a Geometry and register the root Universe +# Instantiate a Geometry, register the root Universe, and export to XML geometry = openmc.Geometry() geometry.root_universe = root - -# Instantiate a GeometryFile, register Geometry, and export to XML -geometry_file = openmc.GeometryFile() -geometry_file.geometry = geometry -geometry_file.export_to_xml() +geometry.export_to_xml() ############################################################################### -# Exporting to OpenMC settings.xml File +# Exporting to OpenMC settings.xml file ############################################################################### -# Instantiate a SettingsFile, set all runtime parameters, and export to XML -settings_file = openmc.SettingsFile() +# Instantiate a Settings object, set all runtime parameters, and export to XML +settings_file = openmc.Settings() settings_file.batches = batches settings_file.inactive = inactive settings_file.particles = particles @@ -137,7 +132,7 @@ settings_file.export_to_xml() ############################################################################### -# Exporting to OpenMC plots.xml File +# Exporting to OpenMC plots.xml file ############################################################################### plot_xy = openmc.Plot(plot_id=1) @@ -155,10 +150,8 @@ plot_yz.width = [8, 8] plot_yz.pixels = [400, 400] plot_yz.color = 'mat' -# Instantiate a PlotsFile, add Plot, and export to XML -plot_file = openmc.PlotsFile() -plot_file.add_plot(plot_xy) -plot_file.add_plot(plot_yz) +# Instantiate a Plots collection, add plots, and export to XML +plot_file = openmc.Plots((plot_xy, plot_yz)) plot_file.export_to_xml() @@ -171,7 +164,6 @@ tally = openmc.Tally(tally_id=1) tally.filters = [openmc.Filter(type='distribcell', bins=[cell2.id])] tally.scores = ['total'] -# Instantiate a TalliesFile, register Tally/Mesh, and export to XML -tallies_file = openmc.TalliesFile() -tallies_file.add_tally(tally) +# Instantiate a Tallies collection and export to XML +tallies_file = openmc.Tallies([tally]) tallies_file.export_to_xml() diff --git a/examples/python/lattice/nested/build-xml.py b/examples/python/lattice/nested/build-xml.py index f54f06453..b2d611d34 100644 --- a/examples/python/lattice/nested/build-xml.py +++ b/examples/python/lattice/nested/build-xml.py @@ -11,7 +11,7 @@ particles = 10000 ############################################################################### -# Exporting to OpenMC materials.xml File +# Exporting to OpenMC materials.xml file ############################################################################### # Instantiate some Nuclides @@ -30,15 +30,14 @@ moderator.add_nuclide(h1, 2.) moderator.add_nuclide(o16, 1.) moderator.add_s_alpha_beta('HH2O', '71t') -# Instantiate a MaterialsFile, register all Materials, and export to XML -materials_file = openmc.MaterialsFile() +# Instantiate a Materials collection and export to XML +materials_file = openmc.Materials((moderator, fuel)) materials_file.default_xs = '71c' -materials_file.add_materials([moderator, fuel]) materials_file.export_to_xml() ############################################################################### -# Exporting to OpenMC geometry.xml File +# Exporting to OpenMC geometry.xml file ############################################################################### # Instantiate Surfaces @@ -116,22 +115,18 @@ lattice2.universes = [[univ4, univ4], cell1.fill = lattice2 cell2.fill = lattice1 -# Instantiate a Geometry and register the root Universe +# Instantiate a Geometry, register the root Universe, and export to XML geometry = openmc.Geometry() geometry.root_universe = root - -# Instantiate a GeometryFile, register Geometry, and export to XML -geometry_file = openmc.GeometryFile() -geometry_file.geometry = geometry -geometry_file.export_to_xml() +geometry.export_to_xml() ############################################################################### -# Exporting to OpenMC settings.xml File +# Exporting to OpenMC settings.xml file ############################################################################### -# Instantiate a SettingsFile, set all runtime parameters, and export to XML -settings_file = openmc.SettingsFile() +# Instantiate a Settings object, set all runtime parameters, and export to XML +settings_file = openmc.Settings() settings_file.batches = batches settings_file.inactive = inactive settings_file.particles = particles @@ -145,7 +140,7 @@ settings_file.export_to_xml() ############################################################################### -# Exporting to OpenMC plots.xml File +# Exporting to OpenMC plots.xml file ############################################################################### plot = openmc.Plot(plot_id=1) @@ -154,14 +149,13 @@ plot.width = [4, 4] plot.pixels = [400, 400] plot.color = 'mat' -# Instantiate a PlotsFile, add Plot, and export to XML -plot_file = openmc.PlotsFile() -plot_file.add_plot(plot) +# Instantiate a Plots object and export to XML +plot_file = openmc.Plots([plot]) plot_file.export_to_xml() ############################################################################### -# Exporting to OpenMC tallies.xml File +# Exporting to OpenMC tallies.xml file ############################################################################### # Instantiate a tally mesh @@ -180,8 +174,6 @@ tally = openmc.Tally(tally_id=1) tally.filters = [mesh_filter] tally.scores = ['total'] -# Instantiate a TalliesFile, register Tally/Mesh, and export to XML -tallies_file = openmc.TalliesFile() -tallies_file.add_mesh(mesh) -tallies_file.add_tally(tally) +# Instantiate a Tallies collection, register Tally/Mesh, and export to XML +tallies_file = openmc.Tallies([tally]) tallies_file.export_to_xml() diff --git a/examples/python/lattice/simple/build-xml.py b/examples/python/lattice/simple/build-xml.py index f633fa96f..65c355479 100644 --- a/examples/python/lattice/simple/build-xml.py +++ b/examples/python/lattice/simple/build-xml.py @@ -11,7 +11,7 @@ particles = 10000 ############################################################################### -# Exporting to OpenMC materials.xml File +# Exporting to OpenMC materials.xml file ############################################################################### # Instantiate some Nuclides @@ -30,15 +30,14 @@ moderator.add_nuclide(h1, 2.) moderator.add_nuclide(o16, 1.) moderator.add_s_alpha_beta('HH2O', '71t') -# Instantiate a MaterialsFile, register all Materials, and export to XML -materials_file = openmc.MaterialsFile() +# Instantiate a Materials collection and export to XML +materials_file = openmc.Materials([moderator, fuel]) materials_file.default_xs = '71c' -materials_file.add_materials([moderator, fuel]) materials_file.export_to_xml() ############################################################################### -# Exporting to OpenMC geometry.xml File +# Exporting to OpenMC geometry.xml file ############################################################################### # Instantiate Surfaces @@ -106,22 +105,18 @@ lattice.universes = [[univ1, univ2, univ1, univ2], # Fill Cell with the Lattice cell1.fill = lattice -# Instantiate a Geometry and register the root Universe +# Instantiate a Geometry, register the root Universe, and export to XML geometry = openmc.Geometry() geometry.root_universe = root - -# Instantiate a GeometryFile, register Geometry, and export to XML -geometry_file = openmc.GeometryFile() -geometry_file.geometry = geometry -geometry_file.export_to_xml() +geometry.export_to_xml() ############################################################################### -# Exporting to OpenMC settings.xml File +# Exporting to OpenMC settings.xml file ############################################################################### -# Instantiate a SettingsFile, set all runtime parameters, and export to XML -settings_file = openmc.SettingsFile() +# Instantiate a Settings object, set all runtime parameters, and export to XML +settings_file = openmc.Settings() settings_file.batches = batches settings_file.inactive = inactive settings_file.particles = particles @@ -137,7 +132,7 @@ settings_file.export_to_xml() ############################################################################### -# Exporting to OpenMC plots.xml File +# Exporting to OpenMC plots.xml file ############################################################################### plot = openmc.Plot(plot_id=1) @@ -146,14 +141,13 @@ plot.width = [4, 4] plot.pixels = [400, 400] plot.color = 'mat' -# Instantiate a PlotsFile, add Plot, and export to XML -plot_file = openmc.PlotsFile() -plot_file.add_plot(plot) +# Instantiate a Plots collection and export to XML +plot_file = openmc.Plots([plot]) plot_file.export_to_xml() ############################################################################### -# Exporting to OpenMC tallies.xml File +# Exporting to OpenMC tallies.xml file ############################################################################### # Instantiate a tally mesh @@ -177,8 +171,6 @@ tally.filters = [mesh_filter] tally.scores = ['total'] tally.triggers = [trigger] -# Instantiate a TalliesFile, register Tally/Mesh, and export to XML -tallies_file = openmc.TalliesFile() -tallies_file.add_mesh(mesh) -tallies_file.add_tally(tally) +# Instantiate a Tallies collection and export to XML +tallies_file = openmc.Tallies([tally]) tallies_file.export_to_xml() diff --git a/examples/python/pincell/build-xml.py b/examples/python/pincell/build-xml.py index 2e72d82ab..a3be3e97e 100644 --- a/examples/python/pincell/build-xml.py +++ b/examples/python/pincell/build-xml.py @@ -11,7 +11,7 @@ particles = 1000 ############################################################################### -# Exporting to OpenMC materials.xml File +# Exporting to OpenMC materials.xml file ############################################################################### # Instantiate some Nuclides @@ -100,15 +100,14 @@ borated_water.add_nuclide(o16, 2.4672e-2) borated_water.add_nuclide(o17, 6.0099e-5) borated_water.add_s_alpha_beta('HH2O', '71t') -# Instantiate a MaterialsFile, register all Materials, and export to XML -materials_file = openmc.MaterialsFile() +# Instantiate a Materials collection and export to XML +materials_file = openmc.Materials([uo2, helium, zircaloy, borated_water]) materials_file.default_xs = '71c' -materials_file.add_materials([uo2, helium, zircaloy, borated_water]) materials_file.export_to_xml() ############################################################################### -# Exporting to OpenMC geometry.xml File +# Exporting to OpenMC geometry.xml file ############################################################################### # Instantiate ZCylinder surfaces @@ -149,22 +148,18 @@ root = openmc.Universe(universe_id=0, name='root universe') # Register Cells with Universe root.add_cells([fuel, gap, clad, water]) -# Instantiate a Geometry and register the root Universe +# Instantiate a Geometry, register the root Universe, and export to XML geometry = openmc.Geometry() geometry.root_universe = root - -# Instantiate a GeometryFile, register Geometry, and export to XML -geometry_file = openmc.GeometryFile() -geometry_file.geometry = geometry -geometry_file.export_to_xml() +geometry.export_to_xml() ############################################################################### -# Exporting to OpenMC settings.xml File +# Exporting to OpenMC settings.xml file ############################################################################### -# Instantiate a SettingsFile, set all runtime parameters, and export to XML -settings_file = openmc.SettingsFile() +# Instantiate a Settings object, set all runtime parameters, and export to XML +settings_file = openmc.Settings() settings_file.batches = batches settings_file.inactive = inactive settings_file.particles = particles @@ -181,7 +176,7 @@ settings_file.export_to_xml() ############################################################################### -# Exporting to OpenMC tallies.xml File +# Exporting to OpenMC tallies.xml file ############################################################################### # Instantiate a tally mesh @@ -201,8 +196,6 @@ tally = openmc.Tally(tally_id=1, name='tally 1') tally.filters = [energy_filter, mesh_filter] tally.scores = ['flux', 'fission', 'nu-fission'] -# Instantiate a TalliesFile, register all Tallies, and export to XML -tallies_file = openmc.TalliesFile() -tallies_file.add_mesh(mesh) -tallies_file.add_tally(tally) +# Instantiate a Tallies collection and export to XML +tallies_file = openmc.Tallies([tally]) tallies_file.export_to_xml() diff --git a/examples/python/pincell_multigroup/build-xml.py b/examples/python/pincell_multigroup/build-xml.py index 60026c089..5ac5b376a 100644 --- a/examples/python/pincell_multigroup/build-xml.py +++ b/examples/python/pincell_multigroup/build-xml.py @@ -1,4 +1,3 @@ -import numpy as np import openmc import openmc.mgxs @@ -12,7 +11,7 @@ inactive = 10 particles = 1000 ############################################################################### -# Exporting to OpenMC mg_cross_sections.xml File +# Exporting to OpenMC mgxs.xml file ############################################################################### # Instantiate the energy group data @@ -22,50 +21,48 @@ groups = openmc.mgxs.EnergyGroups(group_edges=[1E-11, 0.0635E-6, 10.0E-6, # Instantiate the 7-group (C5G7) cross section data uo2_xsdata = openmc.XSdata('UO2.300K', groups) uo2_xsdata.order = 0 -uo2_xsdata.total = np.array([0.1779492, 0.3298048, 0.4803882, 0.5543674, - 0.3118013, 0.3951678, 0.5644058]) -uo2_xsdata.absorption = np.array([8.0248E-03, 3.7174E-03, 2.6769E-02, 9.6236E-02, - 3.0020E-02, 1.1126E-01, 2.8278E-01]) -scatter = [[[0.1275370, 0.0423780, 0.0000094, 0.0000000, 0.0000000, 0.0000000, 0.0000000], - [0.0000000, 0.3244560, 0.0016314, 0.0000000, 0.0000000, 0.0000000, 0.0000000], - [0.0000000, 0.0000000, 0.4509400, 0.0026792, 0.0000000, 0.0000000, 0.0000000], - [0.0000000, 0.0000000, 0.0000000, 0.4525650, 0.0055664, 0.0000000, 0.0000000], - [0.0000000, 0.0000000, 0.0000000, 0.0001253, 0.2714010, 0.0102550, 0.0000000], - [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0012968, 0.2658020, 0.0168090], - [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0085458, 0.2730800]]] -uo2_xsdata.scatter = np.array(scatter[:][:]) -uo2_xsdata.fission = np.array([7.21206E-03, 8.19301E-04, 6.45320E-03, - 1.85648E-02, 1.78084E-02, 8.30348E-02, - 2.16004E-01]) -uo2_xsdata.nu_fission = np.array([2.005998E-02, 2.027303E-03, 1.570599E-02, - 4.518301E-02, 4.334208E-02, 2.020901E-01, - 5.257105E-01]) -uo2_xsdata.chi = np.array([5.8791E-01, 4.1176E-01, 3.3906E-04, 1.1761E-07, - 0.0000E+00, 0.0000E+00, 0.0000E+00]) +uo2_xsdata.total = [0.1779492, 0.3298048, 0.4803882, 0.5543674, + 0.3118013, 0.3951678, 0.5644058] +uo2_xsdata.absorption = [8.0248E-03, 3.7174E-03, 2.6769E-02, 9.6236E-02, + 3.0020E-02, 1.1126E-01, 2.8278E-01] +uo2_xsdata.scatter = [[[0.1275370, 0.0423780, 0.0000094, 0.0000000, 0.0000000, 0.0000000, 0.0000000], + [0.0000000, 0.3244560, 0.0016314, 0.0000000, 0.0000000, 0.0000000, 0.0000000], + [0.0000000, 0.0000000, 0.4509400, 0.0026792, 0.0000000, 0.0000000, 0.0000000], + [0.0000000, 0.0000000, 0.0000000, 0.4525650, 0.0055664, 0.0000000, 0.0000000], + [0.0000000, 0.0000000, 0.0000000, 0.0001253, 0.2714010, 0.0102550, 0.0000000], + [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0012968, 0.2658020, 0.0168090], + [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0085458, 0.2730800]]] +uo2_xsdata.fission = [7.21206E-03, 8.19301E-04, 6.45320E-03, + 1.85648E-02, 1.78084E-02, 8.30348E-02, + 2.16004E-01] +uo2_xsdata.nu_fission = [2.005998E-02, 2.027303E-03, 1.570599E-02, + 4.518301E-02, 4.334208E-02, 2.020901E-01, + 5.257105E-01] +uo2_xsdata.chi = [5.8791E-01, 4.1176E-01, 3.3906E-04, 1.1761E-07, + 0.0000E+00, 0.0000E+00, 0.0000E+00] h2o_xsdata = openmc.XSdata('LWTR.300K', groups) h2o_xsdata.order = 0 -h2o_xsdata.total = np.array([0.15920605, 0.412969593, 0.59030986, 0.58435, - 0.718, 1.2544497, 2.650379]) -h2o_xsdata.absorption = np.array([6.0105E-04, 1.5793E-05, 3.3716E-04, - 1.9406E-03, 5.7416E-03, 1.5001E-02, - 3.7239E-02]) -scatter = [[[0.0444777, 0.1134000, 0.0007235, 0.0000037, 0.0000001, 0.0000000, 0.0000000], - [0.0000000, 0.2823340, 0.1299400, 0.0006234, 0.0000480, 0.0000074, 0.0000010], - [0.0000000, 0.0000000, 0.3452560, 0.2245700, 0.0169990, 0.0026443, 0.0005034], - [0.0000000, 0.0000000, 0.0000000, 0.0910284, 0.4155100, 0.0637320, 0.0121390], - [0.0000000, 0.0000000, 0.0000000, 0.0000714, 0.1391380, 0.5118200, 0.0612290], - [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0022157, 0.6999130, 0.5373200], - [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.1324400, 2.4807000]]] -h2o_xsdata.scatter = np.array(scatter) +h2o_xsdata.total = [0.15920605, 0.412969593, 0.59030986, 0.58435, + 0.718, 1.2544497, 2.650379] +h2o_xsdata.absorption = [6.0105E-04, 1.5793E-05, 3.3716E-04, + 1.9406E-03, 5.7416E-03, 1.5001E-02, + 3.7239E-02] +h2o_xsdata.scatter = [[[0.0444777, 0.1134000, 0.0007235, 0.0000037, 0.0000001, 0.0000000, 0.0000000], + [0.0000000, 0.2823340, 0.1299400, 0.0006234, 0.0000480, 0.0000074, 0.0000010], + [0.0000000, 0.0000000, 0.3452560, 0.2245700, 0.0169990, 0.0026443, 0.0005034], + [0.0000000, 0.0000000, 0.0000000, 0.0910284, 0.4155100, 0.0637320, 0.0121390], + [0.0000000, 0.0000000, 0.0000000, 0.0000714, 0.1391380, 0.5118200, 0.0612290], + [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0022157, 0.6999130, 0.5373200], + [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.1324400, 2.4807000]]] -mg_cross_sections_file = openmc.MGXSLibraryFile(groups) -mg_cross_sections_file.add_xsdatas([uo2_xsdata,h2o_xsdata]) +mg_cross_sections_file = openmc.MGXSLibrary(groups) +mg_cross_sections_file.add_xsdatas([uo2_xsdata, h2o_xsdata]) mg_cross_sections_file.export_to_xml() ############################################################################### -# Exporting to OpenMC materials.xml File +# Exporting to OpenMC materials.xml file ############################################################################### # Instantiate some Macroscopic Data @@ -81,15 +78,14 @@ water = openmc.Material(material_id=2, name='Water') water.set_density('macro', 1.0) water.add_macroscopic(h2o_data) -# Instantiate a MaterialsFile, register all Materials, and export to XML -materials_file = openmc.MaterialsFile() +# Instantiate a Materials collection and export to XML +materials_file = openmc.Materials([uo2, water]) materials_file.default_xs = '300K' -materials_file.add_materials([uo2, water]) materials_file.export_to_xml() ############################################################################### -# Exporting to OpenMC geometry.xml File +# Exporting to OpenMC geometry.xml file ############################################################################### # Instantiate ZCylinder surfaces @@ -122,24 +118,20 @@ root = openmc.Universe(universe_id=0, name='root universe') # Register Cells with Universe root.add_cells([fuel, moderator]) -# Instantiate a Geometry and register the root Universe +# Instantiate a Geometry, register the root Universe, and export to XML geometry = openmc.Geometry() geometry.root_universe = root - -# Instantiate a GeometryFile, register Geometry, and export to XML -geometry_file = openmc.GeometryFile() -geometry_file.geometry = geometry -geometry_file.export_to_xml() +geometry.export_to_xml() ############################################################################### -# Exporting to OpenMC settings.xml File +# Exporting to OpenMC settings.xml file ############################################################################### -# Instantiate a SettingsFile, set all runtime parameters, and export to XML -settings_file = openmc.SettingsFile() +# Instantiate a Settings object, set all runtime parameters, and export to XML +settings_file = openmc.Settings() settings_file.energy_mode = "multi-group" -settings_file.cross_sections = "./mg_cross_sections.xml" +settings_file.cross_sections = "./mgxs.xml" settings_file.batches = batches settings_file.inactive = inactive settings_file.particles = particles @@ -152,7 +144,7 @@ settings_file.source = openmc.source.Source(space=uniform_dist) settings_file.export_to_xml() ############################################################################### -# Exporting to OpenMC tallies.xml File +# Exporting to OpenMC tallies.xml file ############################################################################### # Instantiate a tally mesh @@ -171,14 +163,9 @@ mesh_filter.mesh = mesh # Instantiate the Tally tally = openmc.Tally(tally_id=1, name='tally 1') -tally.add_filter(energy_filter) -tally.add_filter(mesh_filter) -tally.add_score('flux') -tally.add_score('fission') -tally.add_score('nu-fission') +tally.filters = [energy_filter, mesh_filter] +tally.scores = ['flux', 'fission', 'nu-fission'] -# Instantiate a TalliesFile, register all Tallies, and export to XML -tallies_file = openmc.TalliesFile() -tallies_file.add_mesh(mesh) -tallies_file.add_tally(tally) +# Instantiate a Tallies collection, register all Tallies, and export to XML +tallies_file = openmc.Tallies([tally]) tallies_file.export_to_xml() diff --git a/examples/python/reflective/build-xml.py b/examples/python/reflective/build-xml.py index 01a5c7815..4ecd0351f 100644 --- a/examples/python/reflective/build-xml.py +++ b/examples/python/reflective/build-xml.py @@ -12,7 +12,7 @@ particles = 10000 ############################################################################### -# Exporting to OpenMC materials.xml File +# Exporting to OpenMC materials.xml file ############################################################################### # Instantiate a Nuclides @@ -23,15 +23,14 @@ fuel = openmc.Material(material_id=1, name='fuel') fuel.set_density('g/cc', 4.5) fuel.add_nuclide(u235, 1.) -# Instantiate a MaterialsFile, register Material, and export to XML -materials_file = openmc.MaterialsFile() +# Instantiate a Materials collection and export to XML +materials_file = openmc.Materials([fuel]) materials_file.default_xs = '71c' -materials_file.add_material(fuel) materials_file.export_to_xml() ############################################################################### -# Exporting to OpenMC geometry.xml File +# Exporting to OpenMC geometry.xml file ############################################################################### # Instantiate Surfaces @@ -64,22 +63,18 @@ root = openmc.Universe(universe_id=0, name='root universe') # Register Cell with Universe root.add_cell(cell) -# Instantiate a Geometry and register the root Universe +# Instantiate a Geometry, register the root Universe, and export to XML geometry = openmc.Geometry() geometry.root_universe = root - -# Instantiate a GeometryFile, register Geometry, and export to XML -geometry_file = openmc.GeometryFile() -geometry_file.geometry = geometry -geometry_file.export_to_xml() +geometry.export_to_xml() ############################################################################### -# Exporting to OpenMC settings.xml File +# Exporting to OpenMC settings.xml file ############################################################################### -# Instantiate a SettingsFile, set all runtime parameters, and export to XML -settings_file = openmc.SettingsFile() +# Instantiate a Settings object, set all runtime parameters, and export to XML +settings_file = openmc.Settings() settings_file.batches = batches settings_file.inactive = inactive settings_file.particles = particles diff --git a/openmc/cell.py b/openmc/cell.py index 2554df2d2..c6cfc4513 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -23,7 +23,7 @@ def reset_auto_cell_id(): class Cell(object): - """A region of space defined as the intersection of half-space created by + r"""A region of space defined as the intersection of half-space created by quadric surfaces. Parameters @@ -33,6 +33,10 @@ class Cell(object): automatically be assigned. name : str, optional Name of the cell. If not specified, the name is the empty string. + fill : openmc.Material or openmc.Universe or openmc.Lattice or 'void' or iterable of openmc.Material, optional + Indicates what the region of space is filled with + region : openmc.Region, optional + Region of space that is assigned to the cell. Attributes ---------- @@ -44,14 +48,25 @@ class Cell(object): Indicates what the region of space is filled with region : openmc.Region Region of space that is assigned to the cell. - rotation : numpy.ndarray + rotation : Iterable of float If the cell is filled with a universe, this array specifies the angles in degrees about the x, y, and z axes that the filled universe should be - rotated. + Tait-Bryan angles. That is to say, if the angles are :math:`(\phi, + \theta, \psi)`, then the rotation matrix applied is :math:`R_z(\psi) + R_y(\theta) R_x(\phi)` or + + .. math:: + + \left [ \begin{array}{ccc} \cos\theta \cos\psi & -\cos\theta \sin\psi + + \sin\phi \sin\theta \cos\psi & \sin\phi \sin\psi + \cos\phi + \sin\theta \cos\psi \\ \cos\theta \sin\psi & \cos\phi \cos\psi + + \sin\phi \sin\theta \sin\psi & -\sin\phi \cos\psi + \cos\phi + \sin\theta \sin\psi \\ -\sin\theta & \sin\phi \cos\theta & \cos\phi + \cos\theta \end{array} \right ] temperature : float or iterable of float Temperature of the cell in Kelvin. Multiple temperatures can be given to give each distributed cell instance a unique temperature. - translation : numpy.ndarray + translation : Iterable of float If the cell is filled with a universe, this array specifies a vector that is used to translate (shift) the universe. offsets : ndarray @@ -61,7 +76,7 @@ class Cell(object): """ - def __init__(self, cell_id=None, name=''): + def __init__(self, cell_id=None, name='', fill=None, region=None): # Initialize Cell class attributes self.id = cell_id self.name = name @@ -74,6 +89,11 @@ class Cell(object): self._offsets = None self._distribcell_index = None + if fill is not None: + self.fill = fill + if region is not None: + self.region = region + def __eq__(self, other): if not isinstance(other, Cell): return False @@ -234,6 +254,10 @@ class Cell(object): @rotation.setter def rotation(self, rotation): + if not isinstance(self.fill, openmc.Universe): + raise RuntimeError('Cell rotation can only be applied if the cell ' + 'is filled with a Universe') + cv.check_type('cell rotation', rotation, Iterable, Real) cv.check_length('cell rotation', rotation, 3) self._rotation = rotation diff --git a/openmc/checkvalue.py b/openmc/checkvalue.py index 53f4b8368..62b843a3a 100644 --- a/openmc/checkvalue.py +++ b/openmc/checkvalue.py @@ -1,3 +1,4 @@ +import copy from collections import Iterable from numbers import Integral, Real @@ -57,7 +58,7 @@ def check_type(name, value, expected_type, expected_iter_type=None): else: msg = 'Unable to set "{0}" to "{1}" which is not of type "{2}"'.format( name, value, expected_type.__name__) - raise ValueError(msg) + raise TypeError(msg) if expected_iter_type: for item in value: @@ -71,7 +72,7 @@ def check_type(name, value, expected_type, expected_iter_type=None): msg = 'Unable to set "{0}" to "{1}" since each item must be ' \ 'of type "{2}"'.format(name, value, expected_iter_type.__name__) - raise ValueError(msg) + raise TypeError(msg) def check_iterable_type(name, value, expected_type, min_depth=1, max_depth=1): @@ -122,7 +123,7 @@ def check_iterable_type(name, value, expected_type, min_depth=1, max_depth=1): if len(tree) < min_depth: msg = 'Error setting "{0}": The item at {1} does not meet the '\ 'minimum depth of {2}'.format(name, ind_str, min_depth) - raise ValueError(msg) + raise TypeError(msg) # This item is okay. Move on to the next item. index[-1] += 1 @@ -140,7 +141,7 @@ def check_iterable_type(name, value, expected_type, min_depth=1, max_depth=1): msg = 'Error setting {0}: Found an iterable at {1}, items '\ 'in that iterable exceed the maximum depth of {2}' \ .format(name, ind_str, max_depth) - raise ValueError(msg) + raise TypeError(msg) else: # This item is completely unexpected. @@ -148,7 +149,7 @@ def check_iterable_type(name, value, expected_type, min_depth=1, max_depth=1): "item at {2} is of type '{3}'"\ .format(name, expected_type.__name__, ind_str, type(current_item).__name__) - raise ValueError(msg) + raise TypeError(msg) def check_length(name, value, length_min, length_max=None): @@ -278,6 +279,21 @@ class CheckedList(list): for item in items: self.append(item) + def __add__(self, other): + new_instance = copy.copy(self) + new_instance += other + return new_instance + + def __radd__(self, other): + return self + other + + def __iadd__(self, other): + check_type('CheckedList add operand', other, Iterable, + self.expected_type) + for item in other: + self.append(item) + return self + def append(self, item): """Append item to list diff --git a/openmc/cmfd.py b/openmc/cmfd.py index b9977a288..d4cce2af5 100644 --- a/openmc/cmfd.py +++ b/openmc/cmfd.py @@ -187,7 +187,7 @@ class CMFDMesh(object): return element -class CMFDFile(object): +class CMFD(object): """Parameters that control the use of coarse-mesh finite difference acceleration in OpenMC. This corresponds directly to the cmfd.xml input file. diff --git a/openmc/data/__init__.py b/openmc/data/__init__.py new file mode 100644 index 000000000..df22d8bbb --- /dev/null +++ b/openmc/data/__init__.py @@ -0,0 +1 @@ +from .data import * diff --git a/openmc/data/data.py b/openmc/data/data.py new file mode 100644 index 000000000..c6dd81ba6 --- /dev/null +++ b/openmc/data/data.py @@ -0,0 +1,101 @@ +# Isotopic abundances from M. Berglund and M. E. Wieser, "Isotopic compositions +# of the elements 2009 (IUPAC Technical Report)", Pure. Appl. Chem. 83 (2), +# pp. 397--410 (2011). +natural_abundance = { + 'H-1': 0.999885, 'H-2': 0.000115, 'He-3': 1.34e-06, + 'He-4': 0.99999866, 'Li-6': 0.0759, 'Li-7': 0.9241, + 'Be-9': 1.0, 'B-10': 0.199, 'B-11': 0.801, + 'C-12': 0.9893, 'C-13': 0.0107, 'N-14': 0.99636, + 'N-15': 0.00364, 'O-16': 0.99757, 'O-17': 0.00038, + 'O-18': 0.00205, 'F-19': 1.0, 'Ne-20': 0.9048, + 'Ne-21': 0.0027, 'Ne-22': 0.0925, 'Na-23': 1.0, + 'Mg-24': 0.7899, 'Mg-25': 0.1, 'Mg-26': 0.1101, + 'Al-27': 1.0, 'Si-28': 0.92223, 'Si-29': 0.04685, + 'Si-30': 0.03092, 'P-31': 1.0, 'S-32': 0.9499, + 'S-33': 0.0075, 'S-34': 0.0425, 'S-36': 0.0001, + 'Cl-35': 0.7576, 'Cl-37': 0.2424, 'Ar-36': 0.003336, + 'Ar-38': 0.000629, 'Ar-40': 0.996035, 'K-39': 0.932581, + 'K-40': 0.000117, 'K-41': 0.067302, 'Ca-40': 0.96941, + 'Ca-42': 0.00647, 'Ca-43': 0.00135, 'Ca-44': 0.02086, + 'Ca-46': 4e-05, 'Ca-48': 0.00187, 'Sc-45': 1.0, + 'Ti-46': 0.0825, 'Ti-47': 0.0744, 'Ti-48': 0.7372, + 'Ti-49': 0.0541, 'Ti-50': 0.0518, 'V-50': 0.0025, + 'V-51': 0.9975, 'Cr-50': 0.04345, 'Cr-52': 0.83789, + 'Cr-53': 0.09501, 'Cr-54': 0.02365, 'Mn-55': 1.0, + 'Fe-54': 0.05845, 'Fe-56': 0.91754, 'Fe-57': 0.02119, + 'Fe-58': 0.00282, 'Co-59': 1.0, 'Ni-58': 0.68077, + 'Ni-60': 0.26223, 'Ni-61': 0.011399, 'Ni-62': 0.036346, + 'Ni-64': 0.009255, 'Cu-63': 0.6915, 'Cu-65': 0.3085, + 'Zn-64': 0.4917, 'Zn-66': 0.2773, 'Zn-67': 0.0404, + 'Zn-68': 0.1845, 'Zn-70': 0.0061, 'Ga-69': 0.60108, + 'Ga-71': 0.39892, 'Ge-70': 0.2057, 'Ge-72': 0.2745, + 'Ge-73': 0.0775, 'Ge-74': 0.365, 'Ge-76': 0.0773, + 'As-75': 1.0, 'Se-74': 0.0089, 'Se-76': 0.0937, + 'Se-77': 0.0763, 'Se-78': 0.2377, 'Se-80': 0.4961, + 'Se-82': 0.0873, 'Br-79': 0.5069, 'Br-81': 0.4931, + 'Kr-78': 0.00355, 'Kr-80': 0.02286, 'Kr-82': 0.11593, + 'Kr-83': 0.115, 'Kr-84': 0.56987, 'Kr-86': 0.17279, + 'Rb-85': 0.7217, 'Rb-87': 0.2783, 'Sr-84': 0.0056, + 'Sr-86': 0.0986, 'Sr-87': 0.07, 'Sr-88': 0.8258, + 'Y-89': 1.0, 'Zr-90': 0.5145, 'Zr-91': 0.1122, + 'Zr-92': 0.1715, 'Zr-94': 0.1738, 'Zr-96': 0.028, + 'Nb-93': 1.0, 'Mo-92': 0.1453, 'Mo-94': 0.0915, + 'Mo-95': 0.1584, 'Mo-96': 0.1667, 'Mo-97': 0.096, + 'Mo-98': 0.2439, 'Mo-100': 0.0982, 'Ru-96': 0.0554, + 'Ru-98': 0.0187, 'Ru-99': 0.1276, 'Ru-100': 0.126, + 'Ru-101': 0.1706, 'Ru-102': 0.3155, 'Ru-104': 0.1862, + 'Rh-103': 1.0, 'Pd-102': 0.0102, 'Pd-104': 0.1114, + 'Pd-105': 0.2233, 'Pd-106': 0.2733, 'Pd-108': 0.2646, + 'Pd-110': 0.1172, 'Ag-107': 0.51839, 'Ag-109': 0.48161, + 'Cd-106': 0.0125, 'Cd-108': 0.0089, 'Cd-110': 0.1249, + 'Cd-111': 0.128, 'Cd-112': 0.2413, 'Cd-113': 0.1222, + 'Cd-114': 0.2873, 'Cd-116': 0.0749, 'In-113': 0.0429, + 'In-115': 0.9571, 'Sn-112': 0.0097, 'Sn-114': 0.0066, + 'Sn-115': 0.0034, 'Sn-116': 0.1454, 'Sn-117': 0.0768, + 'Sn-118': 0.2422, 'Sn-119': 0.0859, 'Sn-120': 0.3258, + 'Sn-122': 0.0463, 'Sn-124': 0.0579, 'Sb-121': 0.5721, + 'Sb-123': 0.4279, 'Te-120': 0.0009, 'Te-122': 0.0255, + 'Te-123': 0.0089, 'Te-124': 0.0474, 'Te-125': 0.0707, + 'Te-126': 0.1884, 'Te-128': 0.3174, 'Te-130': 0.3408, + 'I-127': 1.0, 'Xe-124': 0.000952, 'Xe-126': 0.00089, + 'Xe-128': 0.019102, 'Xe-129': 0.264006, 'Xe-130': 0.04071, + 'Xe-131': 0.212324, 'Xe-132': 0.269086, 'Xe-134': 0.104357, + 'Xe-136': 0.088573, 'Cs-133': 1.0, 'Ba-130': 0.00106, + 'Ba-132': 0.00101, 'Ba-134': 0.02417, 'Ba-135': 0.06592, + 'Ba-136': 0.07854, 'Ba-137': 0.11232, 'Ba-138': 0.71698, + 'La-138': 0.0008881, 'La-139': 0.9991119, 'Ce-136': 0.00185, + 'Ce-138': 0.00251, 'Ce-140': 0.8845, 'Ce-142': 0.11114, + 'Pr-141': 1.0, 'Nd-142': 0.27152, 'Nd-143': 0.12174, + 'Nd-144': 0.23798, 'Nd-145': 0.08293, 'Nd-146': 0.17189, + 'Nd-148': 0.05756, 'Nd-150': 0.05638, 'Sm-144': 0.0307, + 'Sm-147': 0.1499, 'Sm-148': 0.1124, 'Sm-149': 0.1382, + 'Sm-150': 0.0738, 'Sm-152': 0.2675, 'Sm-154': 0.2275, + 'Eu-151': 0.4781, 'Eu-153': 0.5219, 'Gd-152': 0.002, + 'Gd-154': 0.0218, 'Gd-155': 0.148, 'Gd-156': 0.2047, + 'Gd-157': 0.1565, 'Gd-158': 0.2484, 'Gd-160': 0.2186, + 'Tb-159': 1.0, 'Dy-156': 0.00056, 'Dy-158': 0.00095, + 'Dy-160': 0.02329, 'Dy-161': 0.18889, 'Dy-162': 0.25475, + 'Dy-163': 0.24896, 'Dy-164': 0.2826, 'Ho-165': 1.0, + 'Er-162': 0.00139, 'Er-164': 0.01601, 'Er-166': 0.33503, + 'Er-167': 0.22869, 'Er-168': 0.26978, 'Er-170': 0.1491, + 'Tm-169': 1.0, 'Yb-168': 0.00123, 'Yb-170': 0.02982, + 'Yb-171': 0.1409, 'Yb-172': 0.2168, 'Yb-173': 0.16103, + 'Yb-174': 0.32026, 'Yb-176': 0.12996, 'Lu-175': 0.97401, + 'Lu-176': 0.02599, 'Hf-174': 0.0016, 'Hf-176': 0.0526, + 'Hf-177': 0.186, 'Hf-178': 0.2728, 'Hf-179': 0.1362, + 'Hf-180': 0.3508, 'Ta-180': 0.0001201, 'Ta-181': 0.9998799, + 'W-180': 0.0012, 'W-182': 0.265, 'W-183': 0.1431, + 'W-184': 0.3064, 'W-186': 0.2843, 'Re-185': 0.374, + 'Re-187': 0.626, 'Os-184': 0.0002, 'Os-186': 0.0159, + 'Os-187': 0.0196, 'Os-188': 0.1324, 'Os-189': 0.1615, + 'Os-190': 0.2626, 'Os-192': 0.4078, 'Ir-191': 0.373, + 'Ir-193': 0.627, 'Pt-190': 0.00012, 'Pt-192': 0.00782, + 'Pt-194': 0.3286, 'Pt-195': 0.3378, 'Pt-196': 0.2521, + 'Pt-198': 0.07356, 'Au-197': 1.0, 'Hg-196': 0.0015, + 'Hg-198': 0.0997, 'Hg-199': 0.1687, 'Hg-200': 0.231, + 'Hg-201': 0.1318, 'Hg-202': 0.2986, 'Hg-204': 0.0687, + 'Tl-203': 0.2952, 'Tl-205': 0.7048, 'Pb-204': 0.014, + 'Pb-206': 0.241, 'Pb-207': 0.221, 'Pb-208': 0.524, + 'Bi-209': 1.0, 'Th-232': 1.0, 'Pa-231': 1.0, + 'U-234': 5.4e-05, 'U-235': 0.007204, 'U-238': 0.992742 +} diff --git a/openmc/element.py b/openmc/element.py index 219aafbdf..66371aba9 100644 --- a/openmc/element.py +++ b/openmc/element.py @@ -1,6 +1,8 @@ import sys -from openmc.checkvalue import check_type +import openmc +from openmc.checkvalue import check_type, check_length +from openmc.data import natural_abundance if sys.version_info[0] >= 3: basestring = str @@ -97,7 +99,8 @@ class Element(object): @name.setter def name(self, name): - check_type('name', name, basestring) + check_type('element name', name, basestring) + check_length('element name', name, 1, 2) self._name = name @scattering.setter @@ -109,3 +112,22 @@ class Element(object): raise ValueError(msg) self._scattering = scattering + + def expand(self): + """Expand natural element into its naturally-occurring isotopes. + + Returns + ------- + isotopes : list + Naturally-occurring isotopes of the element. Each item of the list + is a tuple consisting of an openmc.Nuclide instance and the natural + abundance of the isotope. + + """ + + isotopes = [] + for isotope, abundance in natural_abundance.items(): + if isotope.startswith(self.name): + nuc = openmc.Nuclide(isotope, self.xs) + isotopes.append((nuc, abundance)) + return isotopes diff --git a/openmc/executor.py b/openmc/executor.py index 214517d6e..fbd9e5d82 100644 --- a/openmc/executor.py +++ b/openmc/executor.py @@ -1,131 +1,103 @@ from __future__ import print_function import subprocess from numbers import Integral -import os import sys -from openmc.checkvalue import check_type - if sys.version_info[0] >= 3: basestring = str -class Executor(object): - """Control execution of OpenMC +def _run(command, output, cwd): + # Launch a subprocess + p = subprocess.Popen(command, shell=True, cwd=cwd, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, universal_newlines=True) - Attributes + # Capture and re-print OpenMC output in real-time + while True: + # If OpenMC is finished, break loop + line = p.stdout.readline() + if not line and p.poll() != None: + break + + # If user requested output, print to screen + if output: + print(line, end='') + + # Return the returncode (integer, zero if no problems encountered) + return p.returncode + + +def plot_geometry(output=True, openmc_exec='openmc', cwd='.'): + """Run OpenMC in plotting mode + + Parameters ---------- - working_directory : str - Path to working directory to run in + output : bool + Capture OpenMC output from standard out + openmc_exec : str + Path to OpenMC executable + cwd : str, optional + Path to working directory to run in. Defaults to the current working directory. """ - def __init__(self): - self._working_directory = '.' + return _run(openmc_exec + ' -p', output, cwd) - def _run_openmc(self, command, output): - # Launch a subprocess to run OpenMC - p = subprocess.Popen(command, shell=True, - cwd=self._working_directory, - stdout=subprocess.PIPE, - universal_newlines=True) - # Capture and re-print OpenMC output in real-time - while True: - # If OpenMC is finished, break loop - line = p.stdout.readline() - if not line and p.poll() != None: - break +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='.'): + """Run an OpenMC simulation. - # If user requested output, print to screen - if output: - print(line, end='') + Parameters + ---------- + particles : int, optional + Number of particles to simulate per generation. + threads : int, optional + 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). + 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. + 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. - # Return the returncode (integer, zero if no problems encountered) - return p.returncode + """ - @property - def working_directory(self): - return self._working_directory + post_args = ' ' + pre_args = '' - @working_directory.setter - def working_directory(self, working_directory): - check_type("Executor's working directory", working_directory, - basestring) - if not os.path.isdir(working_directory): - msg = 'Unable to set Executor\'s working directory to "{0}" ' \ - 'which does not exist'.format(working_directory) - raise ValueError(msg) + if isinstance(particles, Integral) and particles > 0: + post_args += '-n {0} '.format(particles) - self._working_directory = working_directory + if isinstance(threads, Integral) and threads > 0: + post_args += '-s {0} '.format(threads) - def plot_geometry(self, output=True, openmc_exec='openmc'): - """Run OpenMC in plotting mode""" + if geometry_debug: + post_args += '-g ' - return self._run_openmc(openmc_exec + ' -p', output) + if isinstance(restart_file, basestring): + post_args += '-r {0} '.format(restart_file) - def run_simulation(self, particles=None, threads=None, - geometry_debug=False, restart_file=None, - tracks=False, mpi_procs=1, output=True, - openmc_exec='openmc', mpi_exec=None): - """Run an OpenMC simulation. + if tracks: + post_args += '-t' - Parameters - ---------- - particles : int - Number of particles to simulate per generation - threads : int - Number of OpenMP threads - geometry_debug : bool - Turn on geometry debugging during simulation - restart_file : str - Path to restart file to use - tracks : bool - Write tracks for all particles - mpi_procs : int - Number of MPI processes - output : bool - Capture OpenMC output from standard out - openmc_exec : str - Path to OpenMC executable + if isinstance(mpi_procs, Integral) and mpi_procs > 1: + pre_args += '{} -n {} '.format(mpi_exec, mpi_procs) - """ + command = pre_args + openmc_exec + ' ' + post_args - post_args = ' ' - pre_args = '' - - if isinstance(particles, Integral) and particles > 0: - post_args += '-n {0} '.format(particles) - - if isinstance(threads, Integral) and threads > 0: - post_args += '-s {0} '.format(threads) - - if geometry_debug: - post_args += '-g ' - - if isinstance(restart_file, basestring): - post_args += '-r {0} '.format(restart_file) - - if tracks: - post_args += '-t' - - if isinstance(mpi_procs, Integral) and mpi_procs > 1: - np_present = True - else: - np_present = False - - if mpi_exec is not None and isinstance(mpi_exec, basestring): - mpi_exec_present = True - else: - mpi_exec_present = False - - if np_present or mpi_exec_present: - if mpi_exec_present: - pre_args += mpi_exec + ' ' - else: - pre_args += 'mpirun ' - pre_args += '-n {0} '.format(mpi_procs) - - command = pre_args + openmc_exec + ' ' + post_args - - return self._run_openmc(command, output) + return _run(command, output, cwd) diff --git a/openmc/filter.py b/openmc/filter.py index 249bdcc02..52560a193 100644 --- a/openmc/filter.py +++ b/openmc/filter.py @@ -1,4 +1,4 @@ -from collections import Iterable +from collections import Iterable, OrderedDict import copy from numbers import Real, Integral import sys @@ -27,7 +27,8 @@ class Filter(object): type : str The type of the tally filter. Acceptable values are "universe", "material", "cell", "cellborn", "surface", "mesh", "energy", - "energyout", and "distribcell". + "energyout", "distribcell", "mu", "polar", "azimuthal", and + "delayedgroup". bins : Integral or Iterable of Integral or Iterable of Real The bins for the filter. This takes on different meaning for different filters. See the OpenMC online documentation for more details. @@ -515,7 +516,7 @@ class Filter(object): return filter_bin - def get_pandas_dataframe(self, data_size, summary=None): + def get_pandas_dataframe(self, data_size, distribcell_paths=True): """Builds a Pandas DataFrame for the Filter's bins. This method constructs a Pandas DataFrame object for the filter with @@ -530,12 +531,13 @@ class Filter(object): ---------- data_size : Integral The total number of bins in the tally corresponding to this filter - summary : None or openmc.Summary - An optional Summary object to be used to construct columns for - distribcell tally filters (default is None). The geometric - information in the Summary object is embedded into a Multi-index - column with a geometric "path" to each distribcell instance. - NOTE: This option requires the OpenCG Python package. + distribcell_paths : bool, optional + Construct columns for distribcell tally filters (default is True). + The geometric information in the Summary object is embedded into a + Multi-index column with a geometric "path" to each distribcell + instance. NOTE: This option assumes that all distribcell paths are + of the same length and do not have the same universes and cells but + different lattice cell indices. Returns ------- @@ -553,7 +555,7 @@ class Filter(object): 1. a single column with the cell instance IDs (without summary info) 2. separate columns for the cell IDs, universe IDs, and lattice IDs - and x,y,z cell indices corresponding to each (with summary info). + and x,y,z cell indices corresponding to each (distribcell paths). For 'energy' and 'energyout' filters, the DataFrame includes one column for the lower energy bound and one column for the upper @@ -565,8 +567,7 @@ class Filter(object): Raises ------ ImportError - When Pandas is not installed, or summary info is requested but - OpenCG is not installed. + When Pandas is not installed See also -------- @@ -625,106 +626,117 @@ class Filter(object): elif self.type == 'distribcell': level_df = None - if isinstance(summary, Summary): - # Attempt to import the OpenCG package - try: - import opencg - except ImportError: - msg = 'The OpenCG package must be installed ' \ - 'to use a Summary for distribcell dataframes' - raise ImportError(msg) + # Create Pandas Multi-index columns for each level in CSG tree + if distribcell_paths: - # Extract the OpenCG geometry from the Summary - opencg_geometry = summary.opencg_geometry - openmc_geometry = summary.openmc_geometry + # Distribcell paths require linked metadata from the Summary + if self.distribcell_paths is None: + msg = 'Unable to construct distribcell paths since ' \ + 'the Summary is not linked to the StatePoint' + raise ValueError(msg) - # Use OpenCG to compute the number of regions - opencg_geometry.initialize_cell_offsets() - num_regions = opencg_geometry.num_regions + # Make copy of array of distribcell paths to use in + # Pandas Multi-index column construction + distribcell_paths = copy.deepcopy(self.distribcell_paths) + num_offsets = len(distribcell_paths) - # Initialize a dictionary mapping OpenMC distribcell - # offsets to OpenCG LocalCoords linked lists - offsets_to_coords = {} - - for offset, path in enumerate(self.distribcell_paths): - region = opencg_geometry.get_region_from_path(path) - coords = opencg_geometry.find_region(region) - offsets_to_coords[offset] = coords - - # Each distribcell offset is a DataFrame bin - # Unravel the paths into DataFrame columns - num_offsets = len(offsets_to_coords) - - # Initialize termination condition for while loop + # Loop over CSG levels in the distribcell paths + level_counter = 0 levels_remain = True - counter = 0 - - # Iterate over each level in the CSG tree hierarchy while levels_remain: - levels_remain = False - # Initialize dictionary to build Pandas Multi-index - # column for this level in the CSG tree hierarchy - level_dict = {} + # Use level key as first index in Pandas Multi-index column + level_counter += 1 + level_key = 'level {}'.format(level_counter) - # Initialize prefix Multi-index keys - counter += 1 - level_key = 'level {0}'.format(counter) - univ_key = (level_key, 'univ', 'id') - cell_key = (level_key, 'cell', 'id') - lat_id_key = (level_key, 'lat', 'id') - lat_x_key = (level_key, 'lat', 'x') - lat_y_key = (level_key, 'lat', 'y') - lat_z_key = (level_key, 'lat', 'z') + # Use the first distribcell path to determine if level + # is a universe/cell or lattice level + first_path = distribcell_paths[0] + next_index = first_path.index('-') + level = first_path[:next_index] - # Allocate NumPy arrays for each CSG level and - # each Multi-index column in the DataFrame - level_dict[univ_key] = np.empty(num_offsets) - level_dict[cell_key] = np.empty(num_offsets) - level_dict[lat_id_key] = np.empty(num_offsets) - level_dict[lat_x_key] = np.empty(num_offsets) - level_dict[lat_y_key] = np.empty(num_offsets) - level_dict[lat_z_key] = np.empty(num_offsets) + # Trim universe/lattice info from path + first_path = first_path[next_index+2:] - # Initialize Multi-index columns to NaN - this is - # necessary since some distribcell instances may - # have very different LocalCoords linked lists - level_dict[univ_key][:] = np.NAN - level_dict[cell_key][:] = np.NAN - level_dict[lat_id_key][:] = np.NAN - level_dict[lat_x_key][:] = np.NAN - level_dict[lat_y_key][:] = np.NAN - level_dict[lat_z_key][:] = np.NAN + # Create a dictionary for this level for Pandas Multi-index + level_dict = OrderedDict() - # Iterate over all regions (distribcell instances) - for offset in range(num_offsets): - coords = offsets_to_coords[offset] + # This level is a lattice (e.g., ID(x,y,z)) + if '(' in level: + level_type = 'lattice' - # If entire LocalCoords has been unraveled into - # Multi-index columns already, continue - if coords is None: - continue + # Initialize prefix Multi-index keys + lat_id_key = (level_key, 'lat', 'id') + lat_x_key = (level_key, 'lat', 'x') + lat_y_key = (level_key, 'lat', 'y') + lat_z_key = (level_key, 'lat', 'z') - # Assign entry to Universe Multi-index column - if coords._type == 'universe': - level_dict[univ_key][offset] = coords._universe._id - level_dict[cell_key][offset] = coords._cell._id + # Allocate NumPy arrays for each CSG level and + # each Multi-index column in the DataFrame + level_dict[lat_id_key] = np.empty(num_offsets) + level_dict[lat_x_key] = np.empty(num_offsets) + level_dict[lat_y_key] = np.empty(num_offsets) + level_dict[lat_z_key] = np.empty(num_offsets) + + # This level is a universe / cell (e.g., ID->ID) + else: + level_type = 'universe' + + # Initialize prefix Multi-index keys + univ_key = (level_key, 'univ', 'id') + cell_key = (level_key, 'cell', 'id') + + # Allocate NumPy arrays for each CSG level and + # each Multi-index column in the DataFrame + level_dict[univ_key] = np.empty(num_offsets) + level_dict[cell_key] = np.empty(num_offsets) + + # Determine any levels remain in path + if '-' not in first_path: + levels_remain = False + + # Populate Multi-index arrays with all distribcell paths + for i, path in enumerate(distribcell_paths): + + if level_type == 'lattice': + # Extract lattice ID, indices from path + next_index = path.index('-') + lat_id_indices = path[:next_index] + + # Trim lattice info from distribcell path + distribcell_paths[i] = path[next_index+2:] + + # Extract the lattice cell indices from the path + i1 = lat_id_indices.index('(') + i2 = lat_id_indices.index(')') + i3 = lat_id_indices[i1+1:i2] + + # Assign entry to Lattice Multi-index column + level_dict[lat_id_key][i] = path[:i1] + level_dict[lat_x_key][i] = int(i3.split(',')[0]) - 1 + level_dict[lat_y_key][i] = int(i3.split(',')[1]) - 1 + level_dict[lat_z_key][i] = int(i3.split(',')[2]) - 1 - # Assign entry to Lattice Multi-index column else: - # Reverse y index per lattice ordering in OpenCG - level_dict[lat_id_key][offset] = coords._lattice._id - level_dict[lat_x_key][offset] = coords._lat_x - level_dict[lat_y_key][offset] = \ - coords._lattice.dimension[1] - coords._lat_y - 1 - level_dict[lat_z_key][offset] = coords._lat_z + # Extract universe ID from path + next_index = path.index('-') + universe_id = int(path[:next_index]) - # Move to next node in LocalCoords linked list - if coords._next is None: - offsets_to_coords[offset] = None - else: - offsets_to_coords[offset] = coords._next - levels_remain = True + # Trim universe info from distribcell path + path = path[next_index+2:] + + # Extract cell ID from path + if '-' in path: + next_index = path.index('-') + cell_id = int(path[:next_index]) + distribcell_paths[i] = path[next_index+2:] + else: + cell_id = int(path) + distribcell_paths[i] = '' + + # Assign entry to Universe, Cell Multi-index columns + level_dict[univ_key][i] = universe_id + level_dict[cell_key][i] = cell_id # Tile the Multi-index columns for level_key, level_bins in level_dict.items(): @@ -739,7 +751,7 @@ class Filter(object): else: level_df = pd.concat([level_df, pd.DataFrame(level_dict)], axis=1) - # Create DataFrame column for distribcell instances IDs + # Create DataFrame column for distribcell instance IDs # NOTE: This is performed regardless of whether the user # requests Summary geometric information filter_bins = np.arange(self.num_bins) diff --git a/openmc/geometry.py b/openmc/geometry.py index f5dfe97e4..ed437f6e1 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -23,7 +23,6 @@ class Geometry(object): """ def __init__(self): - # Initialize Geometry class attributes self._root_universe = None self._offsets = {} @@ -42,6 +41,27 @@ class Geometry(object): self._root_universe = root_universe + def export_to_xml(self): + """Create a geometry.xml file that can be used for a simulation. + + """ + + # Clear OpenMC written IDs used to optimize XML generation + openmc.universe.WRITTEN_IDS = {} + + # Create XML representation + geometry_file = ET.Element("geometry") + self.root_universe.create_xml_subelement(geometry_file) + + # Clean the indentation in the file to be user-readable + sort_xml_elements(geometry_file) + clean_xml_indentation(geometry_file) + + # Write the XML Tree to the geometry.xml file + tree = ET.ElementTree(geometry_file) + tree.write("geometry.xml", xml_declaration=True, encoding='utf-8', + method="xml") + def get_cell_instance(self, path): """Return the instance number for the final cell in a geometry path. @@ -436,52 +456,3 @@ class Geometry(object): lattices = list(lattices) lattices.sort(key=lambda x: x.id) return lattices - - -class GeometryFile(object): - """Geometry file used for an OpenMC simulation. Corresponds directly to the - geometry.xml input file. - - Attributes - ---------- - geometry : openmc.Geometry - The geometry to be used - - """ - - def __init__(self): - # Initialize GeometryFile class attributes - self._geometry = None - self._geometry_file = ET.Element("geometry") - - @property - def geometry(self): - return self._geometry - - @geometry.setter - def geometry(self, geometry): - check_type('the geometry', geometry, Geometry) - self._geometry = geometry - - def export_to_xml(self): - """Create a geometry.xml file that can be used for a simulation. - - """ - - # Clear OpenMC written IDs used to optimize XML generation - openmc.universe.WRITTEN_IDS = {} - - # Reset xml element tree - self._geometry_file.clear() - - root_universe = self.geometry.root_universe - root_universe.create_xml_subelement(self._geometry_file) - - # Clean the indentation in the file to be user-readable - sort_xml_elements(self._geometry_file) - clean_xml_indentation(self._geometry_file) - - # Write the XML Tree to the geometry.xml file - tree = ET.ElementTree(self._geometry_file) - tree.write("geometry.xml", xml_declaration=True, - encoding='utf-8', method="xml") diff --git a/openmc/lattice.py b/openmc/lattice.py index 7e78abf06..af6c14a6a 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -7,7 +7,7 @@ import sys import numpy as np import openmc.checkvalue as cv -from openmc.universe import Universe, AUTO_UNIVERSE_ID +import openmc if sys.version_info[0] >= 3: basestring = str @@ -30,13 +30,13 @@ class Lattice(object): Unique identifier for the lattice name : str Name of the lattice - pitch : float - Pitch of the lattice in cm - outer : int - The unique identifier of a universe to fill all space outside the - lattice - universes : numpy.ndarray of openmc.Universe - An array of universes filling each element of the lattice + pitch : Iterable of float + Pitch of the lattice in each direction in cm + outer : openmc.Universe + A universe to fill all space outside the lattice + universes : Iterable of Iterable of openmc.Universe + A two- or three-dimensional list/array of universes filling each element + of the lattice """ @@ -93,9 +93,8 @@ class Lattice(object): @id.setter def id(self, lattice_id): if lattice_id is None: - global AUTO_UNIVERSE_ID - self._id = AUTO_UNIVERSE_ID - AUTO_UNIVERSE_ID += 1 + self._id = openmc.universe.AUTO_UNIVERSE_ID + openmc.universe.AUTO_UNIVERSE_ID += 1 else: cv.check_type('lattice ID', lattice_id, Integral) cv.check_greater_than('lattice ID', lattice_id, 0, equality=True) @@ -111,12 +110,12 @@ class Lattice(object): @outer.setter def outer(self, outer): - cv.check_type('outer universe', outer, Universe) + cv.check_type('outer universe', outer, openmc.Universe) self._outer = outer @universes.setter def universes(self, universes): - cv.check_iterable_type('lattice universes', universes, Universe, + cv.check_iterable_type('lattice universes', universes, openmc.Universe, min_depth=2, max_depth=3) self._universes = np.asarray(universes) @@ -127,20 +126,20 @@ class Lattice(object): ------- universes : collections.OrderedDict Dictionary whose keys are universe IDs and values are - :class:`Universe` instances + :class:`openmc.Universe` instances """ univs = OrderedDict() for k in range(len(self._universes)): for j in range(len(self._universes[k])): - if isinstance(self._universes[k][j], Universe): + if isinstance(self._universes[k][j], openmc.Universe): u = self._universes[k][j] univs[u._id] = u else: for i in range(len(self._universes[k][j])): u = self._universes[k][j][i] - assert isinstance(u, Universe) + assert isinstance(u, openmc.Universe) univs[u._id] = u if self.outer is not None: @@ -260,6 +259,14 @@ class RectLattice(Lattice): lower_left : Iterable of float The coordinates of the lower-left corner of the lattice. If the lattice is two-dimensional, only the x- and y-coordinates are specified. + pitch : Iterable of float + Pitch of the lattice in the x, y, and (if applicable) z directions in + cm. + outer : openmc.Universe + A universe to fill all space outside the lattice + universes : Iterable of Iterable of openmc.Universe + A two- or three-dimensional list/array of universes filling each element + of the lattice """ @@ -506,6 +513,19 @@ class HexLattice(Lattice): center : Iterable of float Coordinates of the center of the lattice. If the lattice does not have axial sections then only the x- and y-coordinates are specified + pitch : Iterable of float + Pitch of the lattice in cm. The first item in the iterable specifies the + pitch in the radial direction and, if the lattice is 3D, the second item + in the iterable specifies the pitch in the axial direction. + outer : openmc.Universe + A universe to fill all space outside the lattice + universes : Iterable of Iterable of openmc.Universe + A two- or three-dimensional list/array of universes filling each element + of the lattice. Each sub-list corresponds to one ring of universes and + should be ordered from outermost ring to innermost ring. The universes + within each sub-list are ordered from the "top" and proceed in a + clockwise fashion. The :meth:`HexLattice.show_indices` method can be + used to help figure out indices for this property. """ @@ -615,10 +635,10 @@ class HexLattice(Lattice): # clockwise fashion. # Check to see if the given universes look like a 2D or a 3D array. - if isinstance(self._universes[0][0], Universe): + if isinstance(self._universes[0][0], openmc.Universe): n_dims = 2 - elif isinstance(self._universes[0][0][0], Universe): + elif isinstance(self._universes[0][0][0], openmc.Universe): n_dims = 3 else: @@ -636,7 +656,7 @@ class HexLattice(Lattice): # Set the number of rings and make sure this number is consistent for # all axial positions. if n_dims == 3: - self.num_rings = len(self._universes) + self.num_rings = len(self._universes[0]) for rings in self._universes: if len(rings) != self._num_rings: msg = 'HexLattice ID={0:d} has an inconsistent number of ' \ @@ -869,3 +889,107 @@ class HexLattice(Lattice): # Join the rows together and return the string. universe_ids = '\n'.join(rows) return universe_ids + + @staticmethod + def show_indices(num_rings): + """Return a diagram of the hexagonal lattice layout with indices. + + This method can be used to show the proper indices to be used when + setting the :attr:`HexLattice.universes` property. For example, running + this method with num_rings=3 will return the following diagram:: + + (0, 0) + (0,11) (0, 1) + (0,10) (1, 0) (0, 2) + (1, 5) (1, 1) + (0, 9) (2, 0) (0, 3) + (1, 4) (1, 2) + (0, 8) (1, 3) (0, 4) + (0, 7) (0, 5) + (0, 6) + + Parameters + ---------- + num_rings : int + Number of rings in the hexagonal lattice + + Returns + ------- + str + Diagram of the hexagonal lattice showing indices + + """ + + # Find the largest string and count the number of digits so we can + # properly pad the output string later + largest_index = 6*(num_rings - 1) + n_digits_index = len(str(largest_index)) + n_digits_ring = len(str(num_rings - 1)) + str_form = '({{:{}}},{{:{}}})'.format(n_digits_ring, n_digits_index) + pad = ' '*(n_digits_index + n_digits_ring + 3) + + # Initialize the list for each row. + rows = [[] for i in range(1 + 4 * (num_rings-1))] + middle = 2 * (num_rings - 1) + + # Start with the degenerate first ring. + rows[middle] = [str_form.format(num_rings - 1, 0)] + + # Add universes one ring at a time. + for r in range(1, num_rings): + # r_prime increments down while r increments up. + r_prime = num_rings - 1 - r + theta = 0 + y = middle + 2*r + + for i in range(r): + # Climb down the top-right. + rows[y].append(str_form.format(r_prime, theta)) + y -= 1 + theta += 1 + + for i in range(r): + # Climb down the right. + rows[y].append(str_form.format(r_prime, theta)) + y -= 2 + theta += 1 + + for i in range(r): + # Climb down the bottom-right. + rows[y].append(str_form.format(r_prime, theta)) + y -= 1 + theta += 1 + + for i in range(r): + # Climb up the bottom-left. + rows[y].insert(0, str_form.format(r_prime, theta)) + y += 1 + theta += 1 + + for i in range(r): + # Climb up the left. + rows[y].insert(0, str_form.format(r_prime, theta)) + y += 2 + theta += 1 + + for i in range(r): + # Climb up the top-left. + rows[y].insert(0, str_form.format(r_prime, theta)) + y += 1 + theta += 1 + + # Flip the rows and join each row into a single string. + rows = [pad.join(x) for x in rows[::-1]] + + # Pad the beginning of the rows so they line up properly. + for y in range(num_rings - 1): + rows[y] = (num_rings - 1 - y)*pad + rows[y] + rows[-1 - y] = (num_rings - 1 - y)*pad + rows[-1 - y] + + for y in range(num_rings % 2, num_rings, 2): + rows[middle + y] = pad + rows[middle + y] + if y != 0: + rows[middle - y] = pad + rows[middle - y] + + # Join the rows together and return the string. + return '\n'.join(rows) diff --git a/openmc/material.py b/openmc/material.py index 2c04a9ecf..6b2b07f2d 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -8,8 +8,9 @@ if sys.version_info[0] >= 3: basestring = str import openmc -from openmc.checkvalue import check_type, check_value, check_greater_than +import openmc.checkvalue as cv from openmc.clean_xml import * +from openmc.data import natural_abundance # A static variable for auto-generated Material IDs @@ -25,9 +26,6 @@ def reset_auto_material_id(): DENSITY_UNITS = ['g/cm3', 'g/cc', 'kg/cm3', 'atom/b-cm', 'atom/cm3', 'sum', 'macro'] -# Constant for density when not needed -NO_DENSITY = 99999. - class Material(object): """A material composed of a collection of nuclides/elements that can be @@ -52,6 +50,14 @@ 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. + elements : collections.OrderedDict + Dictionary whose keys are element names and values are 3-tuples + consisting of an :class:`openmc.Element` instance, the percent density, + and the percent type (atom or weight fraction). + nuclides : collections.OrderedDict + Dictionary whose keys are nuclide names and values are 3-tuples + consisting of an :class:`openmc.Nuclide` instance, the percent density, + and the percent type (atom or weight fraction). """ @@ -141,9 +147,9 @@ class Material(object): string += '{0: <16}\n'.format('\tElements') for element in self._elements: - percent = self._nuclides[element][1] - percent_type = self._nuclides[element][2] - string += '{0: >16}'.format('\t{0}'.format(element)) + percent = self._elements[element][1] + percent_type = self._elements[element][2] + string += '{0: <16}'.format('\t{0}'.format(element)) string += '=\t{0: <12} [{1}]\n'.format(percent, percent_type) return string @@ -189,6 +195,14 @@ class Material(object): def density_units(self): return self._density_units + @property + def elements(self): + return self._elements + + @property + def nuclides(self): + return self._nuclides + @property def convert_to_distrib_comps(self): return self._convert_to_distrib_comps @@ -205,45 +219,51 @@ class Material(object): self._id = AUTO_MATERIAL_ID AUTO_MATERIAL_ID += 1 else: - check_type('material ID', material_id, Integral) - check_greater_than('material ID', material_id, 0, equality=True) + cv.check_type('material ID', material_id, Integral) + cv.check_greater_than('material ID', material_id, 0, equality=True) self._id = material_id @name.setter def name(self, name): if name is not None: - check_type('name for Material ID="{0}"'.format(self._id), - name, basestring) + cv.check_type('name for Material ID="{0}"'.format(self._id), + name, basestring) self._name = name else: self._name = '' - def set_density(self, units, density=NO_DENSITY): + def set_density(self, units, density=None): """Set the density of the material Parameters ---------- - units : str - Physical units of density + units : {'g/cm3', 'g/cc', 'km/cm3', 'atom/b-cm', 'atom/cm3', 'sum', 'macro'} + Physical units of density. density : float, optional Value of the density. Must be specified unless units is given as 'sum'. """ - check_type('the density for Material ID="{0}"'.format(self._id), - density, Real) - check_value('density units', units, DENSITY_UNITS) - - if density == NO_DENSITY and units is not 'sum': - msg = 'Unable to set the density Material ID="{0}" ' \ - 'because a density must be set when not using ' \ - 'sum unit'.format(self._id) - raise ValueError(msg) - - self._density = density + cv.check_value('density units', units, DENSITY_UNITS) self._density_units = units + if units is 'sum': + if density is not None: + msg = 'Density "{0}" for Material ID="{1}" 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}" ' \ + '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), + density, Real) + self._density = density + @distrib_otf_file.setter def distrib_otf_file(self, filename): # TODO: remove this when distributed materials are merged @@ -274,7 +294,7 @@ class Material(object): Nuclide to add percent : float Atom or weight percent - percent_type : str + percent_type : {'ao', 'wo'} 'ao' for atom percent and 'wo' for weight percent """ @@ -284,7 +304,7 @@ class Material(object): 'macroscopic data-set has already been added'.format(self._id) raise ValueError(msg) - if not isinstance(nuclide, (openmc.Nuclide, str)): + if not isinstance(nuclide, (openmc.Nuclide, basestring)): msg = 'Unable to add a Nuclide to Material ID="{0}" with a ' \ 'non-Nuclide value "{1}"'.format(self._id, nuclide) raise ValueError(msg) @@ -328,7 +348,9 @@ class Material(object): del self._nuclides[nuclide._name] def add_macroscopic(self, macroscopic): - """Add a macroscopic to the material + """Add a macroscopic to the material. This will also set the + density of the material to 1.0, unless it has been otherwise set, + as a default for Macroscopic cross sections. Parameters ---------- @@ -366,6 +388,14 @@ class Material(object): 'Material!'.format(self._id, macroscopic) raise ValueError(msg) + # Generally speaking, the density for a macroscopic object will + # be 1.0. Therefore, lets set density to 1.0 so that the user + # doesnt need to set it unless its needed. + # Of course, if the user has already set a value of density, + # then we will not override it. + if self._density is None: + self.set_density('macro', 1.0) + def remove_macroscopic(self, macroscopic): """Remove a macroscopic from the material @@ -385,17 +415,21 @@ class Material(object): if macroscopic._name == self._macroscopic.name: self._macroscopic = None - def add_element(self, element, percent, percent_type='ao'): + def add_element(self, element, percent, percent_type='ao', expand=False): """Add a natural element to the material Parameters ---------- - element : openmc.Element + element : openmc.Element or str Element to add percent : float Atom or weight percent - percent_type : str - 'ao' for atom percent and 'wo' for weight percent + percent_type : {'ao', 'wo'}, optional + 'ao' for atom percent and 'wo' for weight percent. Defaults to atom + percent. + expand : bool, optional + Whether to expand the natural element into its naturally-occurring + isotopes. Defaults to False. """ @@ -404,7 +438,7 @@ class Material(object): 'macroscopic data-set has already been added'.format(self._id) raise ValueError(msg) - if not isinstance(element, openmc.Element): + if not isinstance(element, (openmc.Element, basestring)): msg = 'Unable to add an Element to Material ID="{0}" with a ' \ 'non-Element value "{1}"'.format(self._id, element) raise ValueError(msg) @@ -420,9 +454,20 @@ class Material(object): raise ValueError(msg) # Copy this Element to separate it from same Element in other Materials - element = deepcopy(element) + if isinstance(element, openmc.Element): + element = deepcopy(element) + else: + element = openmc.Element(element) - self._elements[element._name] = (element, percent, percent_type) + if expand: + if percent_type == 'wo': + raise NotImplementedError('Expanding natural element based on ' + 'weight percent is not yet supported.') + for isotope, abundance in element.expand(): + self._nuclides[isotope.name] = ( + isotope, percent*abundance, percent_type) + else: + self._elements[element.name] = (element, percent, percent_type) def remove_element(self, element): """Remove a natural element from the material @@ -471,7 +516,7 @@ class Material(object): for nuclide_name in self._nuclides: self._nuclides[nuclide_name][0].scattering = 'iso-in-lab' for element_name in self._elements: - self._element[element_name][0].scattering = 'iso-in-lab' + self._elements[element_name][0].scattering = 'iso-in-lab' def get_all_nuclides(self): """Returns all nuclides in the material @@ -491,6 +536,14 @@ class Material(object): density = nuclide_tuple[1] nuclides[nuclide._name] = (nuclide, density) + for element_name, element_tuple in self._elements.items(): + element = element_tuple[0] + density = element_tuple[1] + + # Expand natural element into isotopes + for isotope, abundance in element.expand(): + nuclides[isotope.name] = (isotope, density*abundance) + return nuclides def _get_nuclide_xml(self, nuclide, distrib=False): @@ -498,7 +551,7 @@ class Material(object): xml_element.set("name", nuclide[0]._name) if not distrib: - if nuclide[2] is 'ao': + if nuclide[2] == 'ao': xml_element.set("ao", str(nuclide[1])) else: xml_element.set("wo", str(nuclide[1])) @@ -525,11 +578,14 @@ class Material(object): xml_element.set("name", str(element[0]._name)) if not distrib: - if element[2] is 'ao': + if element[2] == 'ao': xml_element.set("ao", str(element[1])) else: xml_element.set("wo", str(element[1])) + if element[0].xs is not None: + xml_element.set("xs", element[0].xs) + if not element[0].scattering is None: xml_element.set("scattering", element[0].scattering) @@ -639,9 +695,25 @@ class Material(object): return element -class MaterialsFile(object): - """Materials file used for an OpenMC simulation. Corresponds directly to the - materials.xml input file. +class Materials(cv.CheckedList): + """Collection of Materials used for an OpenMC simulation. + + This class corresponds directly to the materials.xml input file. It can be + thought of as a normal Python list where each member is a + :class:`Material`. It behaves like a list as the following example + demonstrates: + + >>> fuel = openmc.Material() + >>> clad = openmc.Material() + >>> water = openmc.Material() + >>> m = openmc.Materials([fuel]) + >>> m.append(water) + >>> m += [clad] + + Parameters + ---------- + materials : Iterable of openmc.Material + Materials to add to the collection Attributes ---------- @@ -651,11 +723,12 @@ class MaterialsFile(object): """ - def __init__(self): - # Initialize MaterialsFile class attributes - self._materials = [] + def __init__(self, materials=None): + super(Materials, self).__init__(Material, 'materials collection') self._default_xs = None self._materials_file = ET.Element("materials") + if materials is not None: + self += materials @property def default_xs(self): @@ -663,11 +736,14 @@ class MaterialsFile(object): @default_xs.setter def default_xs(self, xs): - check_type('default xs', xs, basestring) + cv.check_type('default xs', xs, basestring) self._default_xs = xs def add_material(self, material): - """Add a material to the file. + """Append material to collection + + .. deprecated:: 0.8 + Use :meth:`Materials.append` instead. Parameters ---------- @@ -675,51 +751,72 @@ class MaterialsFile(object): Material to add """ - - if not isinstance(material, Material): - msg = 'Unable to add a non-Material "{0}" to the ' \ - 'MaterialsFile'.format(material) - raise ValueError(msg) - - self._materials.append(material) + warnings.warn("Materials.add_material(...) has been deprecated and may be " + "removed in a future version. Use Material.append(...) " + "instead.", DeprecationWarning) + self.append(material) def add_materials(self, materials): - """Add multiple materials to the file. + """Add multiple materials to the collection + + .. deprecated:: 0.8 + Use compound assignment instead. Parameters ---------- - materials : tuple or list of openmc.Material + materials : Iterable of openmc.Material Materials to add """ - - if not isinstance(materials, Iterable): - msg = 'Unable to create OpenMC materials.xml file from "{0}" which ' \ - 'is not iterable'.format(materials) - raise ValueError(msg) - + warnings.warn("Materials.add_materials(...) has been deprecated and may be " + "removed in a future version. Use compound assignment " + "instead.", DeprecationWarning) for material in materials: - self.add_material(material) + self.append(material) + + def append(self, material): + """Append material to collection + + Parameters + ---------- + material : openmc.Material + Material to append + + """ + super(Materials, self).append(material) + + def insert(self, index, material): + """Insert material before index + + Parameters + ---------- + index : int + Index in list + material : openmc.Material + Material to insert + + """ + super(Materials, self).insert(index, material) def remove_material(self, material): """Remove a material from the file + .. deprecated:: 0.8 + Use :meth:`Materials.remove` instead. + Parameters ---------- material : openmc.Material Material to remove """ - - if not isinstance(material, Material): - msg = 'Unable to remove a non-Material "{0}" from the ' \ - 'MaterialsFile'.format(material) - raise ValueError(msg) - - self._materials.remove(material) + warnings.warn("Materials.remove_material(...) has been deprecated and " + "may be removed in a future version. Use " + "Materials.remove(...) instead.", DeprecationWarning) + self.remove(material) def make_isotropic_in_lab(self): - for material in self._materials: + for material in self: material.make_isotropic_in_lab() def _create_material_subelements(self): @@ -727,7 +824,7 @@ class MaterialsFile(object): subelement = ET.SubElement(self._materials_file, "default_xs") subelement.text = self._default_xs - for material in self._materials: + for material in self: xml_element = material.get_material_xml() self._materials_file.append(xml_element) diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index 4de4bb48a..20302b624 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -2,8 +2,12 @@ import sys import os import copy import pickle +import warnings from numbers import Integral from collections import OrderedDict +from warnings import warn + +import numpy as np import openmc import openmc.mgxs @@ -57,6 +61,8 @@ class Library(object): The spatial domain(s) for which MGXS in the Library are computed correction : {'P0', None} Apply the P0 correction to scattering matrices if set to 'P0' + legendre_order : int + The highest legendre moment in the scattering matrices (default is 0) energy_groups : openmc.mgxs.EnergyGroups Energy group structure for energy condensation tally_trigger : openmc.Trigger @@ -89,8 +95,9 @@ class Library(object): self._mgxs_types = [] self._domain_type = None self._domains = 'all' - self._correction = 'P0' self._energy_groups = None + self._correction = 'P0' + self._legendre_order = 0 self._tally_trigger = None self._all_mgxs = OrderedDict() self._sp_filename = None @@ -118,6 +125,7 @@ class Library(object): clone._domain_type = self.domain_type clone._domains = copy.deepcopy(self.domains) clone._correction = self.correction + clone._legendre_order = self.legendre_order clone._energy_groups = copy.deepcopy(self.energy_groups, memo) clone._tally_trigger = copy.deepcopy(self.tally_trigger, memo) clone._all_mgxs = copy.deepcopy(self.all_mgxs) @@ -185,13 +193,17 @@ class Library(object): else: return self._domains + @property + def energy_groups(self): + return self._energy_groups + @property def correction(self): return self._correction @property - def energy_groups(self): - return self._energy_groups + def legendre_order(self): + return self._legendre_order @property def tally_trigger(self): @@ -245,7 +257,7 @@ class Library(object): @domain_type.setter def domain_type(self, domain_type): - cv.check_value('domain type', domain_type, tuple(openmc.mgxs.DOMAIN_TYPES)) + cv.check_value('domain type', domain_type, openmc.mgxs.DOMAIN_TYPES) self._domain_type = domain_type @domains.setter @@ -280,16 +292,36 @@ class Library(object): self._domains = domains - @correction.setter - def correction(self, correction): - cv.check_value('correction', correction, ('P0', None)) - self._correction = correction - @energy_groups.setter def energy_groups(self, energy_groups): cv.check_type('energy groups', energy_groups, openmc.mgxs.EnergyGroups) self._energy_groups = energy_groups + @correction.setter + def correction(self, correction): + cv.check_value('correction', correction, ('P0', None)) + + if correction == 'P0' and self.legendre_order > 0: + msg = 'The P0 correction will be ignored since the scattering ' \ + 'order {} is greater than zero'.format(self.legendre_order) + warnings.warn(msg) + + self._correction = correction + + @legendre_order.setter + def legendre_order(self, legendre_order): + cv.check_type('legendre_order', legendre_order, Integral) + cv.check_greater_than('legendre_order', legendre_order, 0, equality=True) + cv.check_less_than('legendre_order', legendre_order, 10, equality=True) + + if self.correction == 'P0' and legendre_order > 0: + msg = 'The P0 correction will be ignored since the scattering ' \ + 'order {} is greater than zero'.format(self.legendre_order) + warnings.warn(msg, RuntimeWarning) + self.correction = None + + self._legendre_order = legendre_order + @tally_trigger.setter def tally_trigger(self, tally_trigger): cv.check_type('tally trigger', tally_trigger, openmc.Trigger) @@ -344,6 +376,7 @@ class Library(object): # Specify whether to use a transport ('P0') correction if isinstance(mgxs, openmc.mgxs.ScatterMatrixXS): mgxs.correction = self.correction + mgxs.legendre_order = self.legendre_order self.all_mgxs[domain.id][mgxs_type] = mgxs @@ -354,23 +387,23 @@ class Library(object): Parameters ---------- - tallies_file : openmc.TalliesFile - A TalliesFile object to add each MGXS' tallies to generate a - "tallies.xml" input file for OpenMC + tallies_file : openmc.Tallies + A Tallies collection to add each MGXS' tallies to generate a + 'tallies.xml' input file for OpenMC merge : bool Indicate whether tallies should be merged when possible. Defaults to True. """ - cv.check_type('tallies_file', tallies_file, openmc.TalliesFile) + cv.check_type('tallies_file', tallies_file, openmc.Tallies) # Add tallies from each MGXS for each domain and mgxs type for domain in self.domains: for mgxs_type in self.mgxs_types: mgxs = self.get_mgxs(domain, mgxs_type) for tally_id, tally in mgxs.tallies.items(): - tallies_file.add_tally(tally, merge=merge) + tallies_file.append(tally, merge=merge) def load_from_statepoint(self, statepoint): """Extracts tallies in an OpenMC StatePoint with the data needed to @@ -403,6 +436,7 @@ class Library(object): self._sp_filename = statepoint._f.filename self._openmc_geometry = statepoint.summary.openmc_geometry + self._nuclides = statepoint.summary.nuclides if statepoint.run_mode == 'k-eigenvalue': self._keff = statepoint.k_combined[0] @@ -426,7 +460,7 @@ class Library(object): ---------- domain : Material or Cell or Universe or Integral The material, cell, or universe object of interest (or its ID) - mgxs_type : {'total', 'transport', 'absorption', 'capture', 'fission', 'nu-fission', 'kappa-fission', 'scatter', 'nu-scatter', 'scatter matrix', 'nu-scatter matrix', 'chi'} + mgxs_type : {'total', 'transport', 'nu-transport', 'absorption', 'capture', 'fission', 'nu-fission', 'kappa-fission', 'scatter', 'nu-scatter', 'scatter matrix', 'nu-scatter matrix', 'chi'} The type of multi-group cross section object to return Returns @@ -456,7 +490,7 @@ class Library(object): if domain_id == domain.id: break else: - msg = 'Unable to find MGXS for {0} "{1}" in ' \ + msg = 'Unable to find MGXS for "{0}" "{1}" in ' \ 'library'.format(self.domain_type, domain_id) raise ValueError(msg) else: @@ -575,7 +609,8 @@ class Library(object): return subdomain_avg_library def build_hdf5_store(self, filename='mgxs.h5', directory='mgxs', - subdomains='all', nuclides='all', xs_type='macro'): + subdomains='all', nuclides='all', xs_type='macro', + row_column='inout'): """Export the multi-group cross section library to an HDF5 binary file. This method constructs an HDF5 file which stores the library's @@ -605,6 +640,10 @@ class Library(object): xs_type: {'macro', 'micro'} Store the macro or micro cross section in units of cm^-1 or barns. Defaults to 'macro'. + row_column: {'inout', 'outin'} + Store scattering matrices indexed first by incoming group and + second by outgoing group ('inout'), or vice versa ('outin'). + Defaults to 'inout'. Raises ------ @@ -635,7 +674,7 @@ class Library(object): full_filename = os.path.join(directory, filename) full_filename = full_filename.replace(' ', '-') f = h5py.File(full_filename, 'w') - f.attrs["# groups"] = self.num_groups + f.attrs['# groups'] = self.num_groups f.close() # Export MGXS for each domain and mgxs type to an HDF5 file @@ -646,8 +685,8 @@ class Library(object): if subdomains == 'avg': mgxs = mgxs.get_subdomain_avg_xs() - mgxs.build_hdf5_store(filename, directory, - xs_type=xs_type, nuclides=nuclides) + mgxs.build_hdf5_store(filename, directory, xs_type=xs_type, + nuclides=nuclides, row_column=row_column) def dump_to_file(self, filename='mgxs', directory='mgxs'): """Store this Library object in a pickle binary file. @@ -712,3 +751,395 @@ class Library(object): # Load and return pickled Library object return pickle.load(open(full_filename, 'rb')) + + def get_xsdata(self, domain, xsdata_name, nuclide='total', xs_type='macro', + xs_id='1m', order=None): + """Generates an openmc.XSdata object describing a multi-group cross section + data set for eventual combination in to an openmc.MGXSLibrary object + (i.e., the library). + + Parameters + ---------- + domain : openmc.Material or openmc.Cell or openmc.Universe + The domain for spatial homogenization + xsdata_name : str + Name to apply to the "xsdata" entry produced by this method + nuclide : str + A nuclide name string (e.g., 'U-235'). Defaults to 'total' to + obtain a material-wise macroscopic cross section. + xs_type: {'macro', 'micro'} + Provide the macro or micro cross section in units of cm^-1 or + barns. Defaults to 'macro'. If the Library object is not tallied by + nuclide this will be set to 'macro' regardless. + xs_ids : str + Cross section set identifier. Defaults to '1m'. + order : Scattering order for this data entry. Default is None, + which will set the XSdata object to use the order of the + Library. + + Returns + ------- + xsdata : openmc.XSdata + Multi-Group Cross Section data set object. + + Raises + ------ + ValueError + When the Library object is initialized with insufficient types of + cross sections for the Library. + + See also + -------- + Library.create_mg_library() + + """ + + cv.check_type('domain', domain, (openmc.Material, openmc.Cell, + openmc.Cell)) + cv.check_type('xsdata_name', xsdata_name, basestring) + cv.check_type('nuclide', nuclide, basestring) + cv.check_value('xs_type', xs_type, ['macro', 'micro']) + cv.check_type('xs_id', xs_id, basestring) + cv.check_type('order', order, (type(None), Integral)) + if order is not None: + cv.check_greater_than('order', order, 0, equality=True) + cv.check_less_than('order', order, 10, equality=True) + + # Make sure statepoint has been loaded + if self._sp_filename is None: + msg = 'A StatePoint must be loaded before calling ' \ + 'the create_mg_library() function' + raise ValueError(msg) + + # If gathering material-specific data, set the xs_type to macro + if not self.by_nuclide: + xs_type = 'macro' + + # Build & add metadata to XSdata object + name = xsdata_name + if nuclide is not 'total': + name += '_' + nuclide + name += '.' + xs_id + xsdata = openmc.XSdata(name, self.energy_groups) + + if order is None: + # Set the order to the Library's order (the defualt behavior) + xsdata.order = self.legendre_order + else: + # Set the order of the xsdata object to the minimum of + # the provided order or the Library's order. + xsdata.order = min(order, self.legendre_order) + + if nuclide is not 'total': + xsdata.zaid = self._nuclides[nuclide][0] + xsdata.awr = self._nuclides[nuclide][1] + + # Now get xs data itself + if 'nu-transport' in self.mgxs_types and self.correction == 'P0': + mymgxs = self.get_mgxs(domain, 'nu-transport') + xsdata.set_total_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide]) + elif 'total' in self.mgxs_types: + mymgxs = self.get_mgxs(domain, 'total') + xsdata.set_total_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide]) + if 'absorption' in self.mgxs_types: + mymgxs = self.get_mgxs(domain, 'absorption') + xsdata.set_absorption_mgxs(mymgxs, xs_type=xs_type, + nuclide=[nuclide]) + if 'fission' in self.mgxs_types: + mymgxs = self.get_mgxs(domain, 'fission') + xsdata.set_fission_mgxs(mymgxs, xs_type=xs_type, + nuclide=[nuclide]) + if 'kappa-fission' in self.mgxs_types: + mymgxs = self.get_mgxs(domain, 'kappa-fission') + xsdata.set_kappa_fission_mgxs(mymgxs, xs_type=xs_type, + nuclide=[nuclide]) + if 'chi' in self.mgxs_types: + mymgxs = self.get_mgxs(domain, 'chi') + xsdata.set_chi_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide]) + if 'nu-fission' in self.mgxs_types: + mymgxs = self.get_mgxs(domain, 'nu-fission') + xsdata.set_nu_fission_mgxs(mymgxs, xs_type=xs_type, + nuclide=[nuclide]) + # multiplicity requires scatter and nu-scatter + if ((('scatter matrix' in self.mgxs_types) and + ('nu-scatter matrix' in self.mgxs_types))): + scatt_mgxs = self.get_mgxs(domain, 'scatter matrix') + nuscatt_mgxs = self.get_mgxs(domain, 'nu-scatter matrix') + xsdata.set_multiplicity_mgxs(nuscatt_mgxs, scatt_mgxs, + xs_type=xs_type, nuclide=[nuclide]) + using_multiplicity = True + else: + using_multiplicity = False + + if using_multiplicity: + nuscatt_mgxs = self.get_mgxs(domain, 'nu-scatter matrix') + xsdata.set_scatter_mgxs(nuscatt_mgxs, xs_type=xs_type, + nuclide=[nuclide]) + else: + if 'nu-scatter matrix' in self.mgxs_types: + nuscatt_mgxs = self.get_mgxs(domain, 'nu-scatter matrix') + xsdata.set_scatter_mgxs(nuscatt_mgxs, xs_type=xs_type, + nuclide=[nuclide]) + + # Since we are not using multiplicity, then + # scattering multiplication (nu-scatter) must be + # accounted for approximately by using an adjusted + # absorption cross section. + if 'total' in self.mgxs_types: + xsdata._absorption = \ + np.subtract(xsdata.total, + np.sum(xsdata.scatter[0, :, :], axis=1)) + + return xsdata + + def create_mg_library(self, xs_type='macro', xsdata_names=None, + xs_ids=None): + """Creates an openmc.MGXSLibrary object to contain the MGXS data for the + Multi-Group mode of OpenMC. + + Parameters + ---------- + xs_type: {'macro', 'micro'} + Provide the macro or micro cross section in units of cm^-1 or + barns. Defaults to 'macro'. If the Library object is not tallied by + nuclide this will be set to 'macro' regardless. + xsdata_names : Iterable of str + List of names to apply to the "xsdata" entries in the + resultant mgxs data file. Defaults to 'set1', 'set2', ... + xs_ids : str or Iterable of str + Cross section set identifier (i.e., '71c') for all + data sets (if only str) or for each individual one + (if iterable of str). Defaults to '1m'. + + Returns + ------- + mgxs_file : openmc.MGXSLibrary + Multi-Group Cross Section File that is ready to be printed to the + file of choice by the user. + + Raises + ------ + ValueError + When the Library object is initialized with insufficient types of + cross sections for the Library. + + See also + -------- + Library.dump_to_file() + + """ + + # Check to ensure the Library contains the correct + # multi-group cross section types + self.check_library_for_openmc_mgxs() + + cv.check_value('xs_type', xs_type, ['macro', 'micro']) + if xsdata_names is not None: + cv.check_iterable_type('xsdata_names', xsdata_names, basestring) + if xs_ids is not None: + if isinstance(xs_ids, basestring): + # If we only have a string lets convert it now to a list + # of strings. + xs_ids = [xs_ids for i in range(len(self.domains))] + else: + cv.check_iterable_type('xs_ids', xs_ids, basestring) + else: + xs_ids = ['1m' for i in range(len(self.domains))] + + # If gathering material-specific data, set the xs_type to macro + if not self.by_nuclide: + xs_type = 'macro' + + # Initialize file + mgxs_file = openmc.MGXSLibrary(self.energy_groups) + + # Create the xsdata object and add it to the mgxs_file + for i, domain in enumerate(self.domains): + if self.by_nuclide: + nuclides = list(domain.get_all_nuclides().keys()) + else: + nuclides = ['total'] + for nuclide in nuclides: + # Build & add metadata to XSdata object + if xsdata_names is None: + xsdata_name = 'set' + str(i + 1) + else: + xsdata_name = xsdata_names[i] + if nuclide is not 'total': + xsdata_name += '_' + nuclide + + xsdata = self.get_xsdata(domain, xsdata_name, nuclide=nuclide, + xs_type=xs_type, xs_id=xs_ids[i]) + + mgxs_file.add_xsdata(xsdata) + + return mgxs_file + + def create_mg_library_and_materials(self, xsdata_names=None, xs_ids=None, + material_ids=None): + """Creates an openmc.MGXSLibrary object to contain the MGXS data for the + Multi-Group mode of OpenMC as well as the associated openmc.Materials + objects. This method cannot be used for Library objects with + `Library.by_nuclide == True` since the materials to output would be + problem dependent and thus any Materials object produced by this method + would not be useful. + + Parameters + ---------- + xsdata_names : Iterable of str + List of names to apply to the "xsdata" entries in the + resultant mgxs data file. Defaults to 'set1', 'set2', ... + xs_ids : str or Iterable of str + Cross section set identifier (i.e., '71c') for all + data sets (if only str) or for each individual one + (if iterable of str). Defaults to '1m'. + material_ids : None or Iterable of Integral + An optional list of material IDs to pass to the materials in + materials_file. Defaults to `None` implying the materials will be + given an ID number which matches the index of the domain in + `self.domains` + + Returns + ------- + mgxs_file : openmc.MGXSLibrary + Multi-Group Cross Section File that is ready to be printed to the + file of choice by the user. + materials_file : openmc.Materials + Materials file ready to be printed with all the macroscopic data + present within this Library. + + Raises + ------ + ValueError + When the Library object is initialized with insufficient types of + cross sections for the Library. + + See also + -------- + Library.create_mg_library() + Library.dump_to_file() + + """ + + # Check to ensure the Library contains the correct + # multi-group cross section types + self.check_library_for_openmc_mgxs() + + if xsdata_names is not None: + cv.check_iterable_type('xsdata_names', xsdata_names, basestring) + if xs_ids is not None: + if isinstance(xs_ids, basestring): + # If we only have a string lets convert it now to a list + # of strings. + xs_ids = [xs_ids for i in range(len(self.domains))] + else: + cv.check_iterable_type('xs_ids', xs_ids, basestring) + else: + xs_ids = ['1m' for i in range(len(self.domains))] + if material_ids is not None: + cv.check_iterable_type('material_ids', material_ids, Integral) + xs_type = 'macro' + + # Initialize files + mgxs_file = openmc.MGXSLibrary(self.energy_groups) + + materials = [] + macroscopics = [] + nuclide = 'total' + # Create the xsdata object and add it to the mgxs_file + for i, domain in enumerate(self.domains): + # Build & add metadata to XSdata object + if xsdata_names is None: + xsdata_name = 'set' + str(i + 1) + else: + xsdata_name = xsdata_names[i] + + xsdata = self.get_xsdata(domain, xsdata_name, nuclide=nuclide, + xs_type=xs_type, xs_id=xs_ids[i]) + + mgxs_file.add_xsdata(xsdata) + + macroscopics.append(openmc.Macroscopic(name=xsdata_name, + xs=xs_ids[i])) + if material_ids is not None: + mat_id = material_ids[i] + else: + mat_id = i + materials.append(openmc.Material(name=xsdata_name + '.' + + xs_ids[i], material_id=mat_id)) + materials[-1].add_macroscopic(macroscopics[-1]) + + materials_file = openmc.Materials(materials) + + return (mgxs_file, materials_file) + + def check_library_for_openmc_mgxs(self): + """This routine will check the MGXS Types within a Library + to ensure the MGXS types provided can be used to create + a MGXS Library for OpenMC's Multi-Group mode. + + The rules to check include: + + - Either total or transport should be present. + + - Both can be available if one wants, but we should + use whatever corresponds to Library.correction (if P0: transport) + + - Absorption and total (or transport) are required. + - A nu-fission cross section and chi values are not required as a + fixed source problem could be the target. + - Fission and kappa-fission are not required as they are only + needed to support tallies the user may wish to request. + - A nu-scatter matrix is required. + + - Having both nu-scatter (of any order) and scatter + (at least isotropic) matrices is preferred + - If only nu-scatter, need total (not transport), to + be used in adjusting absorption + (i.e., reduced_abs = tot - nuscatt) + + See also + -------- + Library.create_mg_library() + + """ + + error_flag = False + # Ensure absorption is present + if 'absorption' not in self.mgxs_types: + error_flag = True + msg = '"absorption" MGXS type is required but not provided.' + warn(msg) + # Ensure nu-scattering matrix is required + if 'nu-scatter matrix' not in self.mgxs_types: + error_flag = True + msg = '"nu-scatter matrix" MGXS type is required but not provided.' + warn(msg) + else: + # Ok, now see the status of scatter + if 'scatter matrix' not in self.mgxs_types: + # We dont have both nu-scatter and scatter, therefore + # we need total, and not transport. + if 'total' not in self.mgxs_types: + error_flag = True + msg = '"total" MGXS type is required if a ' \ + 'scattering matrix is not provided.' + warn(msg) + # Total or transport can be present, but if using + # self.correction=="P0", then we should use transport. + if (((self.correction is "P0") and + ('nu-transport' not in self.mgxs_types))): + error_flag = True + msg = 'A "nu-transport" MGXS type is required since a "P0" ' \ + 'correction is applied, but a "nu-transport" MGXS is ' \ + 'not provided.' + warn(msg) + elif (((self.correction is None) and + ('total' not in self.mgxs_types))): + error_flag = True + msg = '"total" MGXS type is required, but not provided.' + warn(msg) + + if error_flag: + msg = 'Invalid MGXS configuration encountered.' + raise ValueError(msg) diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index 0c3612e9f..5be84bb2c 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -2,6 +2,7 @@ from __future__ import division from collections import Iterable, OrderedDict from numbers import Integral +import warnings import os import sys import copy @@ -21,6 +22,7 @@ if sys.version_info[0] >= 3: # Supported cross section types MGXS_TYPES = ['total', 'transport', + 'nu-transport', 'absorption', 'capture', 'fission', @@ -88,6 +90,15 @@ class MGXS(object): tally_trigger : openmc.Trigger An (optional) tally precision trigger given to each tally used to compute the cross section + scores : list of str + The scores in each tally used to compute the multi-group cross section + filters : list of openmc.Filter + The filters in each tally used to compute the multi-group cross section + tally_keys : list of str + The keys into the tallies dictionary for each tally used to compute + the multi-group cross section + estimator : {'tracklength', 'analog'} + The tally estimator used to compute the multi-group cross section tallies : collections.OrderedDict OpenMC tallies needed to compute the multi-group cross section rxn_rate_tally : openmc.Tally @@ -113,8 +124,12 @@ class MGXS(object): sparse : bool Whether or not the MGXS' tallies use SciPy's LIL sparse matrix format for compressed data storage + loaded_sp : bool + Whether or not a statepoint file has been loaded with tally data derived : bool Whether or not the MGXS is merged from one or more other MGXS + hdf5_key : str + The key used to index multi-group cross sections in an HDF5 data store """ @@ -136,7 +151,9 @@ class MGXS(object): self._rxn_rate_tally = None self._xs_tally = None self._sparse = False + self._loaded_sp = False self._derived = False + self._hdf5_key = None self.name = name self.by_nuclide = by_nuclide @@ -211,18 +228,74 @@ class MGXS(object): def num_groups(self): return self.energy_groups.num_groups + @property + def scores(self): + return ['flux', self.rxn_type] + + @property + def filters(self): + group_edges = self.energy_groups.group_edges + energy_filter = openmc.Filter('energy', group_edges) + return [[energy_filter]] * len(self.scores) + + @property + def tally_keys(self): + return self.scores + + @property + def estimator(self): + return 'tracklength' + @property def tallies(self): + + # Instantiate tallies if they do not exist + if self._tallies is None: + + # Initialize a collection of Tallies + self._tallies = OrderedDict() + + # Create a domain Filter object + domain_filter = openmc.Filter(self.domain_type, self.domain.id) + + # Create each Tally needed to compute the multi group cross section + tally_metadata = zip(self.scores, self.tally_keys, self.filters) + for score, key, filters in tally_metadata: + self._tallies[key] = openmc.Tally(name=self.name) + self._tallies[key].scores = [score] + self._tallies[key].estimator = self.estimator + self._tallies[key].filters = [domain_filter] + + # If a tally trigger was specified, add it to each tally + if self.tally_trigger: + trigger_clone = copy.deepcopy(self.tally_trigger) + trigger_clone.scores = [score] + self._tallies[key].triggers.append(trigger_clone) + + # Add non-domain specific Filters (e.g., 'energy') to the Tally + for add_filter in filters: + self._tallies[key].filters.append(add_filter) + + # If this is a by-nuclide cross-section, add nuclides to Tally + if self.by_nuclide and score != 'flux': + all_nuclides = self.get_all_nuclides() + for nuclide in all_nuclides: + self._tallies[key].nuclides.append(nuclide) + else: + self._tallies[key].nuclides.append('total') + return self._tallies @property def rxn_rate_tally(self): + if self._rxn_rate_tally is None: + self._rxn_rate_tally = self.tallies[self.rxn_type] + self._rxn_rate_tally.sparse = self.sparse + return self._rxn_rate_tally @property def xs_tally(self): - """Computes multi-group cross section using OpenMC tally arithmetic.""" - if self._xs_tally is None: if self.tallies is None: msg = 'Unable to get xs_tally since tallies have ' \ @@ -257,10 +330,21 @@ class MGXS(object): else: return 'sum' + @property + def loaded_sp(self): + return self._loaded_sp + @property def derived(self): return self._derived + @property + def hdf5_key(self): + if self._hdf5_key is not None: + return self._hdf5_key + else: + return self._rxn_type + @name.setter def name(self, name): cv.check_type('name', name, basestring) @@ -281,9 +365,18 @@ class MGXS(object): cv.check_type('domain', domain, tuple(_DOMAINS)) self._domain = domain + # Assign a domain type + if self.domain_type is None: + if isinstance(domain, openmc.Material): + self._domain_type = 'material' + elif isinstance(domain, openmc.Cell): + self._domain_type = 'cell' + elif isinstance(domain, openmc.Universe): + self._domain_type = 'universe' + @domain_type.setter def domain_type(self, domain_type): - cv.check_value('domain type', domain_type, tuple(DOMAIN_TYPES)) + cv.check_value('domain type', domain_type, DOMAIN_TYPES) self._domain_type = domain_type @energy_groups.setter @@ -332,7 +425,7 @@ class MGXS(object): Parameters ---------- - mgxs_type : {'total', 'transport', 'absorption', 'capture', 'fission', 'nu-fission', 'kappa-fission', 'scatter', 'nu-scatter', 'scatter matrix', 'nu-scatter matrix', 'chi'} + mgxs_type : {'total', 'transport', 'nu-transport', 'absorption', 'capture', 'fission', 'nu-fission', 'kappa-fission', 'scatter', 'nu-scatter', 'scatter matrix', 'nu-scatter matrix', 'chi'} The type of multi-group cross section object to return domain : openmc.Material or openmc.Cell or openmc.Universe The domain for spatial homogenization @@ -361,6 +454,8 @@ class MGXS(object): mgxs = TotalXS(domain, domain_type, energy_groups) elif mgxs_type == 'transport': mgxs = TransportXS(domain, domain_type, energy_groups) + elif mgxs_type == 'nu-transport': + mgxs = NuTransportXS(domain, domain_type, energy_groups) elif mgxs_type == 'absorption': mgxs = AbsorptionXS(domain, domain_type, energy_groups) elif mgxs_type == 'capture': @@ -412,7 +507,7 @@ class MGXS(object): # Otherwise, return all nuclides in the spatial domain else: nuclides = self.domain.get_all_nuclides() - return nuclides.keys() + return list(nuclides.keys()) def get_nuclide_density(self, nuclide): """Get the atomic number density in units of atoms/b-cm for a nuclide @@ -500,63 +595,6 @@ class MGXS(object): return densities - def _create_tallies(self, scores, all_filters, keys, estimator): - """Instantiates tallies needed to compute the multi-group cross section. - - This is a helper method for MGXS subclasses to create tallies - for input file generation. The tallies are stored in the tallies dict. - This method is called by each subclass' tallies property getter - which define the parameters given to this parent class method. - - Parameters - ---------- - scores : Iterable of str - Scores for each tally - all_filters : Iterable of tuple of openmc.Filter - Tuples of non-spatial domain filters for each tally - keys : Iterable of str - Key string used to store each tally in the tallies dictionary - estimator : {'analog', 'tracklength'} - Type of estimator to use for each tally - - """ - - cv.check_iterable_type('scores', scores, basestring) - cv.check_length('scores', scores, len(keys)) - cv.check_iterable_type('filters', all_filters, openmc.Filter, 1, 2) - cv.check_type('keys', keys, Iterable, basestring) - cv.check_value('estimator', estimator, ['analog', 'tracklength']) - - self._tallies = OrderedDict() - - # Create a domain Filter object - domain_filter = openmc.Filter(self.domain_type, self.domain.id) - - # Create each Tally needed to compute the multi group cross section - for score, key, filters in zip(scores, keys, all_filters): - self.tallies[key] = openmc.Tally(name=self.name) - self.tallies[key].scores = [score] - self.tallies[key].estimator = estimator - self.tallies[key].filters = [domain_filter] - - # If a tally trigger was specified, add it to each tally - if self.tally_trigger: - trigger_clone = copy.deepcopy(self.tally_trigger) - trigger_clone.scores = [score] - self.tallies[key].triggers.append(trigger_clone) - - # Add all non-domain specific Filters (e.g., 'energy') to the Tally - for add_filter in filters: - self.tallies[key].filters.append(add_filter) - - # If this is a by-nuclide cross-section, add all nuclides to Tally - if self.by_nuclide and score != 'flux': - all_nuclides = self.get_all_nuclides() - for nuclide in all_nuclides: - self.tallies[key].nuclides.append(nuclide) - else: - self.tallies[key].nuclides.append('total') - def _compute_xs(self): """Performs generic cleanup after a subclass' uses tally arithmetic to compute a multi-group cross section as a derived tally. @@ -638,9 +676,11 @@ class MGXS(object): filter_bins = [] # Clear any tallies previously loaded from a statepoint - self._tallies = None - self._xs_tally = None - self._rxn_rate_tally = None + if self.loaded_sp: + self._tallies = None + self._xs_tally = None + self._rxn_rate_tally = None + self._loaded_sp = False # Find, slice and store Tallies from StatePoint # The tally slicing is needed if tally merging was used @@ -653,8 +693,11 @@ class MGXS(object): sp_tally.sparse = self.sparse self.tallies[tally_type] = sp_tally + self._loaded_sp = True + def get_xs(self, groups='all', subdomains='all', nuclides='all', - xs_type='macro', order_groups='increasing', value='mean'): + xs_type='macro', order_groups='increasing', + value='mean', **kwargs): """Returns an array of multi-group cross sections. This method constructs a 2D NumPy array for the requested multi-group @@ -1143,7 +1186,7 @@ class MGXS(object): def build_hdf5_store(self, filename='mgxs.h5', directory='mgxs', subdomains='all', nuclides='all', - xs_type='macro', append=True): + xs_type='macro', row_column='inout', append=True): """Export the multi-group cross section data to an HDF5 binary file. This method constructs an HDF5 file which stores the multi-group @@ -1172,6 +1215,10 @@ class MGXS(object): xs_type: {'macro', 'micro'} Store the macro or micro cross section in units of cm^-1 or barns. Defaults to 'macro'. + row_column: {'inout', 'outin'} + Store scattering matrices indexed first by incoming group and + second by outgoing group ('inout'), or vice versa ('outin'). + Defaults to 'inout'. append : bool If true, appends to an existing HDF5 file with the same filename directory (if one exists). Defaults to True. @@ -1242,8 +1289,8 @@ class MGXS(object): else: subdomain_group = domain_group - # Create a separate HDF5 group for the rxn type - rxn_group = subdomain_group.require_group(self.rxn_type) + # Create a separate HDF5 group for this cross section + rxn_group = subdomain_group.require_group(self.hdf5_key) # Create a separate HDF5 group for each nuclide for j, nuclide in enumerate(nuclides): @@ -1258,9 +1305,9 @@ class MGXS(object): # Extract the cross section for this subdomain and nuclide average = self.get_xs(subdomains=[subdomain], nuclides=[nuclide], - xs_type=xs_type, value='mean') + xs_type=xs_type, value='mean', row_column=row_column) std_dev = self.get_xs(subdomains=[subdomain], nuclides=[nuclide], - xs_type=xs_type, value='std_dev') + xs_type=xs_type, value='std_dev', row_column=row_column) average = average.squeeze() std_dev = std_dev.squeeze() @@ -1346,7 +1393,7 @@ class MGXS(object): modified.write('\n\\end{document}') def get_pandas_dataframe(self, groups='all', nuclides='all', - xs_type='macro', summary=None): + xs_type='macro', distribcell_paths=True): """Build a Pandas DataFrame for the MGXS data. This method leverages :meth:`openmc.Tally.get_pandas_dataframe`, but @@ -1366,12 +1413,11 @@ class MGXS(object): xs_type: {'macro', 'micro'} Return macro or micro cross section in units of cm^-1 or barns. Defaults to 'macro'. - summary : None or openmc.Summary - An optional Summary object to be used to construct columns for - distribcell tally filters (default is None). The geometric - information in the Summary object is embedded into a multi-index - column with a geometric "path" to each distribcell intance. - NOTE: This option requires the OpenCG Python package. + distribcell_paths : bool, optional + Construct columns for distribcell tally filters (default is True). + The geometric information in the Summary object is embedded into + a Multi-index column with a geometric "path" to each distribcell + instance. Returns ------- @@ -1398,7 +1444,8 @@ class MGXS(object): # Use tally summation to sum across all nuclides query_nuclides = self.get_all_nuclides() xs_tally = self.xs_tally.summation(nuclides=query_nuclides) - df = xs_tally.get_pandas_dataframe(summary=summary) + df = xs_tally.get_pandas_dataframe( + distribcell_paths=distribcell_paths) # Remove nuclide column since it is homogeneous and redundant df.drop('nuclide', axis=1, inplace=True) @@ -1406,17 +1453,16 @@ class MGXS(object): # If the user requested a specific set of nuclides elif self.by_nuclide and nuclides != 'all': xs_tally = self.xs_tally.get_slice(nuclides=nuclides) - df = xs_tally.get_pandas_dataframe(summary=summary) + df = xs_tally.get_pandas_dataframe( + distribcell_paths=distribcell_paths) # If the user requested all nuclides, keep nuclide column in dataframe else: - df = self.xs_tally.get_pandas_dataframe(summary=summary) + df = self.xs_tally.get_pandas_dataframe( + distribcell_paths=distribcell_paths) # Remove the score column since it is homogeneous and redundant - if summary and 'distribcell' in self.domain_type: - df = df.drop('score', level=0, axis=1) - else: - df = df.drop('score', axis=1) + df = df.drop('score', axis=1) # Override energy groups bounds with indices all_groups = np.arange(self.num_groups, 0, -1, dtype=np.int) @@ -1431,7 +1477,8 @@ class MGXS(object): df.rename(columns={'energyout low [MeV]': 'group out'}, inplace=True) - out_groups = np.tile(all_groups, df.shape[0] / all_groups.size) + out_groups = np.repeat(all_groups, self.xs_tally.num_scores) + out_groups = np.tile(out_groups, df.shape[0] / out_groups.size) df['group out'] = out_groups del df['energyout high [MeV]'] columns = ['group in', 'group out'] @@ -1475,7 +1522,85 @@ class MGXS(object): class TotalXS(MGXS): - """A total multi-group cross section.""" + """A total multi-group cross section. + + This class can be used for both OpenMC input generation and tally data + post-processing to compute spatially-homogenized and energy-integrated + multi-group cross sections for deterministic neutronics calculations. + + Parameters + ---------- + domain : openmc.Material or openmc.Cell or openmc.Universe + The domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + The domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + The energy group structure for energy condensation + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + name : str, optional + Name of the multi-group cross section. Used as a label to identify + tallies in OpenMC 'tallies.xml' file. + + Attributes + ---------- + name : str, optional + Name of the multi-group cross section + rxn_type : str + Reaction type (e.g., 'total', 'nu-fission', etc.) + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + domain : Material or Cell or Universe + Domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + Domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + Energy group structure for energy condensation + tally_trigger : openmc.Trigger + An (optional) tally precision trigger given to each tally used to + compute the cross section + scores : list of str + The scores in each tally used to compute the multi-group cross section + filters : list of openmc.Filter + The filters in each tally used to compute the multi-group cross section + tally_keys : list of str + The keys into the tallies dictionary for each tally used to compute + the multi-group cross section + estimator : {'tracklength', 'analog'} + The tally estimator used to compute the multi-group cross section + tallies : collections.OrderedDict + OpenMC tallies needed to compute the multi-group cross section + rxn_rate_tally : openmc.Tally + Derived tally for the reaction rate tally used in the numerator to + compute the multi-group cross section. This attribute is None + unless the multi-group cross section has been computed. + xs_tally : openmc.Tally + Derived tally for the multi-group cross section. This attribute + is None unless the multi-group cross section has been computed. + num_subdomains : int + The number of subdomains is unity for 'material', 'cell' and 'universe' + domain types. When the This is equal to the number of cell instances + for 'distribcell' domain types (it is equal to unity prior to loading + tally data from a statepoint file). + num_nuclides : int + The number of nuclides for which the multi-group cross section is + being tracked. This is unity if the by_nuclide attribute is False. + nuclides : Iterable of str or 'sum' + The optional user-specified nuclides for which to compute cross + sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides + are not specified by the user, all nuclides in the spatial domain + are included. This attribute is 'sum' if by_nuclide is false. + sparse : bool + Whether or not the MGXS' tallies use SciPy's LIL sparse matrix format + for compressed data storage + loaded_sp : bool + Whether or not a statepoint file has been loaded with tally data + derived : bool + Whether or not the MGXS is merged from one or more other MGXS + hdf5_key : str + The key used to index multi-group cross sections in an HDF5 data store + + """ def __init__(self, domain=None, domain_type=None, groups=None, by_nuclide=False, name=''): @@ -1483,44 +1608,87 @@ class TotalXS(MGXS): groups, by_nuclide, name) self._rxn_type = 'total' - @property - def tallies(self): - """Construct the OpenMC tallies needed to compute this cross section. - - This method constructs two tracklength tallies to compute the 'flux' - and 'total' reaction rates in the spatial domain and energy groups - of interest. - - """ - - # Instantiate tallies if they do not exist - if self._tallies is None: - - # Create a list of scores for each Tally to be created - scores = ['flux', 'total'] - estimator = 'tracklength' - keys = scores - - # Create the non-domain specific Filters for the Tallies - group_edges = self.energy_groups.group_edges - energy_filter = openmc.Filter('energy', group_edges) - filters = [[energy_filter], [energy_filter]] - - # Initialize the Tallies - self._create_tallies(scores, filters, keys, estimator) - - return self._tallies - - @property - def rxn_rate_tally(self): - if self._rxn_rate_tally is None : - self._rxn_rate_tally = self.tallies['total'] - self._rxn_rate_tally.sparse = self.sparse - return self._rxn_rate_tally - class TransportXS(MGXS): - """A transport-corrected total multi-group cross section.""" + """A transport-corrected total multi-group cross section. + + This class can be used for both OpenMC input generation and tally data + post-processing to compute spatially-homogenized and energy-integrated + multi-group cross sections for deterministic neutronics calculations. + + Parameters + ---------- + domain : openmc.Material or openmc.Cell or openmc.Universe + The domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + The domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + The energy group structure for energy condensation + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + name : str, optional + Name of the multi-group cross section. Used as a label to identify + tallies in OpenMC 'tallies.xml' file. + + Attributes + ---------- + name : str, optional + Name of the multi-group cross section + rxn_type : str + Reaction type (e.g., 'total', 'nu-fission', etc.) + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + domain : Material or Cell or Universe + Domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + Domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + Energy group structure for energy condensation + tally_trigger : openmc.Trigger + An (optional) tally precision trigger given to each tally used to + compute the cross section + scores : list of str + The scores in each tally used to compute the multi-group cross section + filters : list of openmc.Filter + The filters in each tally used to compute the multi-group cross section + tally_keys : list of str + The keys into the tallies dictionary for each tally used to compute + the multi-group cross section + estimator : {'tracklength', 'analog'} + The tally estimator used to compute the multi-group cross section + tallies : collections.OrderedDict + OpenMC tallies needed to compute the multi-group cross section + rxn_rate_tally : openmc.Tally + Derived tally for the reaction rate tally used in the numerator to + compute the multi-group cross section. This attribute is None + unless the multi-group cross section has been computed. + xs_tally : openmc.Tally + Derived tally for the multi-group cross section. This attribute + is None unless the multi-group cross section has been computed. + num_subdomains : int + The number of subdomains is unity for 'material', 'cell' and 'universe' + domain types. When the This is equal to the number of cell instances + for 'distribcell' domain types (it is equal to unity prior to loading + tally data from a statepoint file). + num_nuclides : int + The number of nuclides for which the multi-group cross section is + being tracked. This is unity if the by_nuclide attribute is False. + nuclides : Iterable of str or 'sum' + The optional user-specified nuclides for which to compute cross + sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides + are not specified by the user, all nuclides in the spatial domain + are included. This attribute is 'sum' if by_nuclide is false. + sparse : bool + Whether or not the MGXS' tallies use SciPy's LIL sparse matrix format + for compressed data storage + loaded_sp : bool + Whether or not a statepoint file has been loaded with tally data + derived : bool + Whether or not the MGXS is merged from one or more other MGXS + hdf5_key : str + The key used to index multi-group cross sections in an HDF5 data store + + """ def __init__(self, domain=None, domain_type=None, groups=None, by_nuclide=False, name=''): @@ -1529,53 +1697,208 @@ class TransportXS(MGXS): self._rxn_type = 'transport' @property - def tallies(self): - """Construct the OpenMC tallies needed to compute this cross section. + def scores(self): + return ['flux', 'total', 'scatter-1'] - This method constructs three analog tallies to compute the 'flux', - 'total' and 'scatter-P1' reaction rates in the spatial domain and - energy groups of interest. + @property + def filters(self): + group_edges = self.energy_groups.group_edges + energy_filter = openmc.Filter('energy', group_edges) + energyout_filter = openmc.Filter('energyout', group_edges) + return [[energy_filter], [energy_filter], [energyout_filter]] - """ - - # Instantiate tallies if they do not exist - if self._tallies is None: - - # Create a list of scores for each Tally to be created - scores = ['flux', 'total', 'scatter-P1'] - estimator = 'analog' - keys = scores - - # Create the non-domain specific Filters for the Tallies - group_edges = self.energy_groups.group_edges - energy_filter = openmc.Filter('energy', group_edges) - energyout_filter = openmc.Filter('energyout', group_edges) - filters = [[energy_filter], [energy_filter], [energyout_filter]] - - # Initialize the Tallies - self._create_tallies(scores, filters, keys, estimator) - - return self._tallies + @property + def estimator(self): + return 'analog' @property def rxn_rate_tally(self): if self._rxn_rate_tally is None: - scatter_p1 = copy.deepcopy(self.tallies['scatter-P1']) - - # Use tally slicing to remove scatter-P0 data from scatter-P1 tally - self.tallies['scatter-P1'] = \ - scatter_p1.get_slice(scores=['scatter-P1']) - - self.tallies['scatter-P1'].filters[-1].type = 'energy' + self.tallies['scatter-1'].filters[-1].type = 'energy' self._rxn_rate_tally = \ - self.tallies['total'] - self.tallies['scatter-P1'] + self.tallies['total'] - self.tallies['scatter-1'] self._rxn_rate_tally.sparse = self.sparse return self._rxn_rate_tally +class NuTransportXS(TransportXS): + """A transport-corrected total multi-group cross section which + accounts for neutron multiplicity in scattering reactions. + + This class can be used for both OpenMC input generation and tally data + post-processing to compute spatially-homogenized and energy-integrated + multi-group cross sections for deterministic neutronics calculations. + + Parameters + ---------- + domain : openmc.Material or openmc.Cell or openmc.Universe + The domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + The domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + The energy group structure for energy condensation + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + name : str, optional + Name of the multi-group cross section. Used as a label to identify + tallies in OpenMC 'tallies.xml' file. + + Attributes + ---------- + name : str, optional + Name of the multi-group cross section + rxn_type : str + Reaction type (e.g., 'total', 'nu-fission', etc.) + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + domain : Material or Cell or Universe + Domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + Domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + Energy group structure for energy condensation + tally_trigger : openmc.Trigger + An (optional) tally precision trigger given to each tally used to + compute the cross section + scores : list of str + The scores in each tally used to compute the multi-group cross section + filters : list of openmc.Filter + The filters in each tally used to compute the multi-group cross section + tally_keys : list of str + The keys into the tallies dictionary for each tally used to compute + the multi-group cross section + estimator : {'tracklength', 'analog'} + The tally estimator used to compute the multi-group cross section + tallies : collections.OrderedDict + OpenMC tallies needed to compute the multi-group cross section + rxn_rate_tally : openmc.Tally + Derived tally for the reaction rate tally used in the numerator to + compute the multi-group cross section. This attribute is None + unless the multi-group cross section has been computed. + xs_tally : openmc.Tally + Derived tally for the multi-group cross section. This attribute + is None unless the multi-group cross section has been computed. + num_subdomains : int + The number of subdomains is unity for 'material', 'cell' and 'universe' + domain types. When the This is equal to the number of cell instances + for 'distribcell' domain types (it is equal to unity prior to loading + tally data from a statepoint file). + num_nuclides : int + The number of nuclides for which the multi-group cross section is + being tracked. This is unity if the by_nuclide attribute is False. + nuclides : Iterable of str or 'sum' + The optional user-specified nuclides for which to compute cross + sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides + are not specified by the user, all nuclides in the spatial domain + are included. This attribute is 'sum' if by_nuclide is false. + sparse : bool + Whether or not the MGXS' tallies use SciPy's LIL sparse matrix format + for compressed data storage + loaded_sp : bool + Whether or not a statepoint file has been loaded with tally data + derived : bool + Whether or not the MGXS is merged from one or more other MGXS + hdf5_key : str + The key used to index multi-group cross sections in an HDF5 data store + + """ + + def __init__(self, domain=None, domain_type=None, + groups=None, by_nuclide=False, name=''): + super(NuTransportXS, self).__init__(domain, domain_type, + groups, by_nuclide, name) + self._rxn_type = 'nu-transport' + + @property + def scores(self): + return ['flux', 'total', 'nu-scatter-1'] + + @property + def tally_keys(self): + return ['flux', 'total', 'scatter-1'] + + class AbsorptionXS(MGXS): - """An absorption multi-group cross section.""" + """An absorption multi-group cross section. + + This class can be used for both OpenMC input generation and tally data + post-processing to compute spatially-homogenized and energy-integrated + multi-group cross sections for deterministic neutronics calculations. + + Parameters + ---------- + domain : openmc.Material or openmc.Cell or openmc.Universe + The domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + The domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + The energy group structure for energy condensation + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + name : str, optional + Name of the multi-group cross section. Used as a label to identify + tallies in OpenMC 'tallies.xml' file. + + Attributes + ---------- + name : str, optional + Name of the multi-group cross section + rxn_type : str + Reaction type (e.g., 'total', 'nu-fission', etc.) + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + domain : Material or Cell or Universe + Domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + Domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + Energy group structure for energy condensation + tally_trigger : openmc.Trigger + An (optional) tally precision trigger given to each tally used to + compute the cross section + scores : list of str + The scores in each tally used to compute the multi-group cross section + filters : list of openmc.Filter + The filters in each tally used to compute the multi-group cross section + tally_keys : list of str + The keys into the tallies dictionary for each tally used to compute + the multi-group cross section + estimator : {'tracklength', 'analog'} + The tally estimator used to compute the multi-group cross section + tallies : collections.OrderedDict + OpenMC tallies needed to compute the multi-group cross section + rxn_rate_tally : openmc.Tally + Derived tally for the reaction rate tally used in the numerator to + compute the multi-group cross section. This attribute is None + unless the multi-group cross section has been computed. + xs_tally : openmc.Tally + Derived tally for the multi-group cross section. This attribute + is None unless the multi-group cross section has been computed. + num_subdomains : int + The number of subdomains is unity for 'material', 'cell' and 'universe' + domain types. When the This is equal to the number of cell instances + for 'distribcell' domain types (it is equal to unity prior to loading + tally data from a statepoint file). + num_nuclides : int + The number of nuclides for which the multi-group cross section is + being tracked. This is unity if the by_nuclide attribute is False. + nuclides : Iterable of str or 'sum' + The optional user-specified nuclides for which to compute cross + sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides + are not specified by the user, all nuclides in the spatial domain + are included. This attribute is 'sum' if by_nuclide is false. + sparse : bool + Whether or not the MGXS' tallies use SciPy's LIL sparse matrix format + for compressed data storage + loaded_sp : bool + Whether or not a statepoint file has been loaded with tally data + derived : bool + Whether or not the MGXS is merged from one or more other MGXS + hdf5_key : str + The key used to index multi-group cross sections in an HDF5 data store + + """ def __init__(self, domain=None, domain_type=None, groups=None, by_nuclide=False, name=''): @@ -1583,41 +1906,6 @@ class AbsorptionXS(MGXS): groups, by_nuclide, name) self._rxn_type = 'absorption' - @property - def tallies(self): - """Construct the OpenMC tallies needed to compute this cross section. - - This method constructs two tracklength tallies to compute the 'flux' - and 'absorption' reaction rates in the spatial domain and energy - groups of interest. - - """ - - # Instantiate tallies if they do not exist - if self._tallies is None: - - # Create a list of scores for each Tally to be created - scores = ['flux', 'absorption'] - estimator = 'tracklength' - keys = scores - - # Create the non-domain specific Filters for the Tallies - group_edges = self.energy_groups.group_edges - energy_filter = openmc.Filter('energy', group_edges) - filters = [[energy_filter], [energy_filter]] - - # Initialize the Tallies - self._create_tallies(scores, filters, keys, estimator) - - return self._tallies - - @property - def rxn_rate_tally(self): - if self._rxn_rate_tally is None: - self._rxn_rate_tally = self.tallies['absorption'] - self._rxn_rate_tally.sparse = self.sparse - return self._rxn_rate_tally - class CaptureXS(MGXS): """A capture multi-group cross section. @@ -1627,6 +1915,82 @@ class CaptureXS(MGXS): not only radiative capture, but all forms of neutron disappearance aside from fission (e.g., MT > 100). + This class can be used for both OpenMC input generation and tally data + post-processing to compute spatially-homogenized and energy-integrated + multi-group cross sections for deterministic neutronics calculations. + + Parameters + ---------- + domain : openmc.Material or openmc.Cell or openmc.Universe + The domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + The domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + The energy group structure for energy condensation + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + name : str, optional + Name of the multi-group cross section. Used as a label to identify + tallies in OpenMC 'tallies.xml' file. + + Attributes + ---------- + name : str, optional + Name of the multi-group cross section + rxn_type : str + Reaction type (e.g., 'total', 'nu-fission', etc.) + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + domain : Material or Cell or Universe + Domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + Domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + Energy group structure for energy condensation + tally_trigger : openmc.Trigger + An (optional) tally precision trigger given to each tally used to + compute the cross section + scores : list of str + The scores in each tally used to compute the multi-group cross section + filters : list of openmc.Filter + The filters in each tally used to compute the multi-group cross section + tally_keys : list of str + The keys into the tallies dictionary for each tally used to compute + the multi-group cross section + estimator : {'tracklength', 'analog'} + The tally estimator used to compute the multi-group cross section + tallies : collections.OrderedDict + OpenMC tallies needed to compute the multi-group cross section + rxn_rate_tally : openmc.Tally + Derived tally for the reaction rate tally used in the numerator to + compute the multi-group cross section. This attribute is None + unless the multi-group cross section has been computed. + xs_tally : openmc.Tally + Derived tally for the multi-group cross section. This attribute + is None unless the multi-group cross section has been computed. + num_subdomains : int + The number of subdomains is unity for 'material', 'cell' and 'universe' + domain types. When the This is equal to the number of cell instances + for 'distribcell' domain types (it is equal to unity prior to loading + tally data from a statepoint file). + num_nuclides : int + The number of nuclides for which the multi-group cross section is + being tracked. This is unity if the by_nuclide attribute is False. + nuclides : Iterable of str or 'sum' + The optional user-specified nuclides for which to compute cross + sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides + are not specified by the user, all nuclides in the spatial domain + are included. This attribute is 'sum' if by_nuclide is false. + sparse : bool + Whether or not the MGXS' tallies use SciPy's LIL sparse matrix format + for compressed data storage + loaded_sp : bool + Whether or not a statepoint file has been loaded with tally data + derived : bool + Whether or not the MGXS is merged from one or more other MGXS + hdf5_key : str + The key used to index multi-group cross sections in an HDF5 data store + """ def __init__(self, domain=None, domain_type=None, @@ -1636,32 +2000,8 @@ class CaptureXS(MGXS): self._rxn_type = 'capture' @property - def tallies(self): - """Construct the OpenMC tallies needed to compute this cross section. - - This method constructs two tracklength tallies to compute the 'flux' - and 'capture' reaction rates in the spatial domain and energy - groups of interest. - - """ - - # Instantiate tallies if they do not exist - if self._tallies is None: - - # Create a list of scores for each Tally to be created - scores = ['flux', 'absorption', 'fission'] - estimator = 'tracklength' - keys = scores - - # Create the non-domain specific Filters for the Tallies - group_edges = self.energy_groups.group_edges - energy_filter = openmc.Filter('energy', group_edges) - filters = [[energy_filter], [energy_filter], [energy_filter]] - - # Initialize the Tallies - self._create_tallies(scores, filters, keys, estimator) - - return self._tallies + def scores(self): + return ['flux', 'absorption', 'fission'] @property def rxn_rate_tally(self): @@ -1671,83 +2011,351 @@ class CaptureXS(MGXS): self._rxn_rate_tally.sparse = self.sparse return self._rxn_rate_tally -class FissionXSBase(MGXS): - """A fission production multi-group cross section base class - for NuFission and KappaFission + +class FissionXS(MGXS): + """A fission multi-group cross section. + + This class can be used for both OpenMC input generation and tally data + post-processing to compute spatially-homogenized and energy-integrated + multi-group cross sections for deterministic neutronics calculations. + + Parameters + ---------- + domain : openmc.Material or openmc.Cell or openmc.Universe + The domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + The domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + The energy group structure for energy condensation + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + name : str, optional + Name of the multi-group cross section. Used as a label to identify + tallies in OpenMC 'tallies.xml' file. + + Attributes + ---------- + name : str, optional + Name of the multi-group cross section + rxn_type : str + Reaction type (e.g., 'total', 'nu-fission', etc.) + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + domain : Material or Cell or Universe + Domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + Domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + Energy group structure for energy condensation + tally_trigger : openmc.Trigger + An (optional) tally precision trigger given to each tally used to + compute the cross section + scores : list of str + The scores in each tally used to compute the multi-group cross section + filters : list of openmc.Filter + The filters in each tally used to compute the multi-group cross section + tally_keys : list of str + The keys into the tallies dictionary for each tally used to compute + the multi-group cross section + estimator : {'tracklength', 'analog'} + The tally estimator used to compute the multi-group cross section + tallies : collections.OrderedDict + OpenMC tallies needed to compute the multi-group cross section + rxn_rate_tally : openmc.Tally + Derived tally for the reaction rate tally used in the numerator to + compute the multi-group cross section. This attribute is None + unless the multi-group cross section has been computed. + xs_tally : openmc.Tally + Derived tally for the multi-group cross section. This attribute + is None unless the multi-group cross section has been computed. + num_subdomains : int + The number of subdomains is unity for 'material', 'cell' and 'universe' + domain types. When the This is equal to the number of cell instances + for 'distribcell' domain types (it is equal to unity prior to loading + tally data from a statepoint file). + num_nuclides : int + The number of nuclides for which the multi-group cross section is + being tracked. This is unity if the by_nuclide attribute is False. + nuclides : Iterable of str or 'sum' + The optional user-specified nuclides for which to compute cross + sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides + are not specified by the user, all nuclides in the spatial domain + are included. This attribute is 'sum' if by_nuclide is false. + sparse : bool + Whether or not the MGXS' tallies use SciPy's LIL sparse matrix format + for compressed data storage + loaded_sp : bool + Whether or not a statepoint file has been loaded with tally data + derived : bool + Whether or not the MGXS is merged from one or more other MGXS + hdf5_key : str + The key used to index multi-group cross sections in an HDF5 data store + """ - # This is an abstract class which cannot be instantiated - __metaclass__ = abc.ABCMeta - - def __init__(self, rxn_type, domain=None, domain_type=None, - groups=None, by_nuclide=False, name=''): - super(FissionXSBase, self).__init__(domain, domain_type, - groups, by_nuclide, name) - self._rxn_type = rxn_type - - @property - def tallies(self): - """Construct the OpenMC tallies needed to compute this cross section. - - This method constructs two tracklength tallies to compute the 'flux' - and 'rxn_type' reaction rates in the spatial domain and energy - groups of interest. - - """ - - # Instantiate tallies if they do not exist - if self._tallies is None: - - # Create a list of scores for each Tally to be created - scores = ['flux', self._rxn_type] - estimator = 'tracklength' - keys = scores - - # Create the non-domain specific Filters for the Tallies - group_edges = self.energy_groups.group_edges - energy_filter = openmc.Filter('energy', group_edges) - filters = [[energy_filter], [energy_filter]] - - # Initialize the Tallies - self._create_tallies(scores, filters, keys, estimator) - - return self._tallies - - @property - def rxn_rate_tally(self): - if self._rxn_rate_tally is None: - self._rxn_rate_tally = self.tallies[self._rxn_type] - self._rxn_rate_tally.sparse = self.sparse - return self._rxn_rate_tally - - -class FissionXS(FissionXSBase): - """A fission multi-group cross section.""" - def __init__(self, domain=None, domain_type=None, groups=None, by_nuclide=False, name=''): - super(FissionXS, self).__init__('fission', domain, domain_type, + super(FissionXS, self).__init__(domain, domain_type, groups, by_nuclide, name) + self._rxn_type = 'fission' -class NuFissionXS(FissionXSBase): - """A fission production multi-group cross section.""" +class NuFissionXS(MGXS): + """A fission production multi-group cross section. + + This class can be used for both OpenMC input generation and tally data + post-processing to compute spatially-homogenized and energy-integrated + multi-group cross sections for deterministic neutronics calculations. + + Parameters + ---------- + domain : openmc.Material or openmc.Cell or openmc.Universe + The domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + The domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + The energy group structure for energy condensation + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + name : str, optional + Name of the multi-group cross section. Used as a label to identify + tallies in OpenMC 'tallies.xml' file. + + Attributes + ---------- + name : str, optional + Name of the multi-group cross section + rxn_type : str + Reaction type (e.g., 'total', 'nu-fission', etc.) + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + domain : Material or Cell or Universe + Domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + Domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + Energy group structure for energy condensation + tally_trigger : openmc.Trigger + An (optional) tally precision trigger given to each tally used to + compute the cross section + scores : list of str + The scores in each tally used to compute the multi-group cross section + filters : list of openmc.Filter + The filters in each tally used to compute the multi-group cross section + tally_keys : list of str + The keys into the tallies dictionary for each tally used to compute + the multi-group cross section + estimator : {'tracklength', 'analog'} + The tally estimator used to compute the multi-group cross section + tallies : collections.OrderedDict + OpenMC tallies needed to compute the multi-group cross section + rxn_rate_tally : openmc.Tally + Derived tally for the reaction rate tally used in the numerator to + compute the multi-group cross section. This attribute is None + unless the multi-group cross section has been computed. + xs_tally : openmc.Tally + Derived tally for the multi-group cross section. This attribute + is None unless the multi-group cross section has been computed. + num_subdomains : int + The number of subdomains is unity for 'material', 'cell' and 'universe' + domain types. When the This is equal to the number of cell instances + for 'distribcell' domain types (it is equal to unity prior to loading + tally data from a statepoint file). + num_nuclides : int + The number of nuclides for which the multi-group cross section is + being tracked. This is unity if the by_nuclide attribute is False. + nuclides : Iterable of str or 'sum' + The optional user-specified nuclides for which to compute cross + sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides + are not specified by the user, all nuclides in the spatial domain + are included. This attribute is 'sum' if by_nuclide is false. + sparse : bool + Whether or not the MGXS' tallies use SciPy's LIL sparse matrix format + for compressed data storage + loaded_sp : bool + Whether or not a statepoint file has been loaded with tally data + derived : bool + Whether or not the MGXS is merged from one or more other MGXS + hdf5_key : str + The key used to index multi-group cross sections in an HDF5 data store + + """ def __init__(self, domain=None, domain_type=None, groups=None, by_nuclide=False, name=''): - super(NuFissionXS, self).__init__('nu-fission', domain, domain_type, + super(NuFissionXS, self).__init__(domain, domain_type, groups, by_nuclide, name) + self._rxn_type = 'nu-fission' -class KappaFissionXS(FissionXSBase): - """A recoverable fission energy production rate multi-group cross section.""" + +class KappaFissionXS(MGXS): + """A recoverable fission energy production rate multi-group cross section. + + This class can be used for both OpenMC input generation and tally data + post-processing to compute spatially-homogenized and energy-integrated + multi-group cross sections for deterministic neutronics calculations. + + Parameters + ---------- + domain : openmc.Material or openmc.Cell or openmc.Universe + The domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + The domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + The energy group structure for energy condensation + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + name : str, optional + Name of the multi-group cross section. Used as a label to identify + tallies in OpenMC 'tallies.xml' file. + + Attributes + ---------- + name : str, optional + Name of the multi-group cross section + rxn_type : str + Reaction type (e.g., 'total', 'nu-fission', etc.) + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + domain : Material or Cell or Universe + Domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + Domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + Energy group structure for energy condensation + tally_trigger : openmc.Trigger + An (optional) tally precision trigger given to each tally used to + compute the cross section + scores : list of str + The scores in each tally used to compute the multi-group cross section + filters : list of openmc.Filter + The filters in each tally used to compute the multi-group cross section + tally_keys : list of str + The keys into the tallies dictionary for each tally used to compute + the multi-group cross section + estimator : {'tracklength', 'analog'} + The tally estimator used to compute the multi-group cross section + tallies : collections.OrderedDict + OpenMC tallies needed to compute the multi-group cross section + rxn_rate_tally : openmc.Tally + Derived tally for the reaction rate tally used in the numerator to + compute the multi-group cross section. This attribute is None + unless the multi-group cross section has been computed. + xs_tally : openmc.Tally + Derived tally for the multi-group cross section. This attribute + is None unless the multi-group cross section has been computed. + num_subdomains : int + The number of subdomains is unity for 'material', 'cell' and 'universe' + domain types. When the This is equal to the number of cell instances + for 'distribcell' domain types (it is equal to unity prior to loading + tally data from a statepoint file). + num_nuclides : int + The number of nuclides for which the multi-group cross section is + being tracked. This is unity if the by_nuclide attribute is False. + nuclides : Iterable of str or 'sum' + The optional user-specified nuclides for which to compute cross + sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides + are not specified by the user, all nuclides in the spatial domain + are included. This attribute is 'sum' if by_nuclide is false. + sparse : bool + Whether or not the MGXS' tallies use SciPy's LIL sparse matrix format + for compressed data storage + loaded_sp : bool + Whether or not a statepoint file has been loaded with tally data + derived : bool + Whether or not the MGXS is merged from one or more other MGXS + hdf5_key : str + The key used to index multi-group cross sections in an HDF5 data store + + """ def __init__(self, domain=None, domain_type=None, groups=None, by_nuclide=False, name=''): - super(KappaFissionXS, self).__init__('kappa-fission', domain, domain_type, + super(KappaFissionXS, self).__init__(domain, domain_type, groups, by_nuclide, name) + self._rxn_type = 'kappa-fission' + class ScatterXS(MGXS): - """A scatter multi-group cross section.""" + """A scatter multi-group cross section. + + This class can be used for both OpenMC input generation and tally data + post-processing to compute spatially-homogenized and energy-integrated + multi-group cross sections for deterministic neutronics calculations. + + Parameters + ---------- + domain : openmc.Material or openmc.Cell or openmc.Universe + The domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + The domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + The energy group structure for energy condensation + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + name : str, optional + Name of the multi-group cross section. Used as a label to identify + tallies in OpenMC 'tallies.xml' file. + + Attributes + ---------- + name : str, optional + Name of the multi-group cross section + rxn_type : str + Reaction type (e.g., 'total', 'nu-fission', etc.) + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + domain : Material or Cell or Universe + Domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + Domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + Energy group structure for energy condensation + tally_trigger : openmc.Trigger + An (optional) tally precision trigger given to each tally used to + compute the cross section + scores : list of str + The scores in each tally used to compute the multi-group cross section + filters : list of openmc.Filter + The filters in each tally used to compute the multi-group cross section + tally_keys : list of str + The keys into the tallies dictionary for each tally used to compute + the multi-group cross section + estimator : {'tracklength', 'analog'} + The tally estimator used to compute the multi-group cross section + tallies : collections.OrderedDict + OpenMC tallies needed to compute the multi-group cross section + rxn_rate_tally : openmc.Tally + Derived tally for the reaction rate tally used in the numerator to + compute the multi-group cross section. This attribute is None + unless the multi-group cross section has been computed. + xs_tally : openmc.Tally + Derived tally for the multi-group cross section. This attribute + is None unless the multi-group cross section has been computed. + num_subdomains : int + The number of subdomains is unity for 'material', 'cell' and 'universe' + domain types. When the This is equal to the number of cell instances + for 'distribcell' domain types (it is equal to unity prior to loading + tally data from a statepoint file). + num_nuclides : int + The number of nuclides for which the multi-group cross section is + being tracked. This is unity if the by_nuclide attribute is False. + nuclides : Iterable of str or 'sum' + The optional user-specified nuclides for which to compute cross + sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides + are not specified by the user, all nuclides in the spatial domain + are included. This attribute is 'sum' if by_nuclide is false. + sparse : bool + Whether or not the MGXS' tallies use SciPy's LIL sparse matrix format + for compressed data storage + loaded_sp : bool + Whether or not a statepoint file has been loaded with tally data + derived : bool + Whether or not the MGXS is merged from one or more other MGXS + hdf5_key : str + The key used to index multi-group cross sections in an HDF5 data store + + """ def __init__(self, domain=None, domain_type=None, groups=None, by_nuclide=False, name=''): @@ -1755,44 +2363,87 @@ class ScatterXS(MGXS): groups, by_nuclide, name) self._rxn_type = 'scatter' - @property - def tallies(self): - """Construct the OpenMC tallies needed to compute this cross section. - - This method constructs two tracklength tallies to compute the 'flux' - and 'scatter' reaction rates in the spatial domain and energy - groups of interest. - - """ - - # Instantiate tallies if they do not exist - if self._tallies is None: - - # Create a list of scores for each Tally to be created - scores = ['flux', 'scatter'] - estimator = 'tracklength' - keys = scores - - # Create the non-domain specific Filters for the Tallies - group_edges = self.energy_groups.group_edges - energy_filter = openmc.Filter('energy', group_edges) - filters = [[energy_filter], [energy_filter]] - - # Intialize the Tallies - self._create_tallies(scores, filters, keys, estimator) - - return self._tallies - - @property - def rxn_rate_tally(self): - if self._rxn_rate_tally is None: - self._rxn_rate_tally = self.tallies['scatter'] - self._rxn_rate_tally.sparse = self.sparse - return self._rxn_rate_tally - class NuScatterXS(MGXS): - """A nu-scatter multi-group cross section.""" + """A nu-scatter multi-group cross section. + + This class can be used for both OpenMC input generation and tally data + post-processing to compute spatially-homogenized and energy-integrated + multi-group cross sections for deterministic neutronics calculations. + + Parameters + ---------- + domain : openmc.Material or openmc.Cell or openmc.Universe + The domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + The domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + The energy group structure for energy condensation + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + name : str, optional + Name of the multi-group cross section. Used as a label to identify + tallies in OpenMC 'tallies.xml' file. + + Attributes + ---------- + name : str, optional + Name of the multi-group cross section + rxn_type : str + Reaction type (e.g., 'total', 'nu-fission', etc.) + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + domain : Material or Cell or Universe + Domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + Domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + Energy group structure for energy condensation + tally_trigger : openmc.Trigger + An (optional) tally precision trigger given to each tally used to + compute the cross section + scores : list of str + The scores in each tally used to compute the multi-group cross section + filters : list of openmc.Filter + The filters in each tally used to compute the multi-group cross section + tally_keys : list of str + The keys into the tallies dictionary for each tally used to compute + the multi-group cross section + estimator : {'tracklength', 'analog'} + The tally estimator used to compute the multi-group cross section + tallies : collections.OrderedDict + OpenMC tallies needed to compute the multi-group cross section + rxn_rate_tally : openmc.Tally + Derived tally for the reaction rate tally used in the numerator to + compute the multi-group cross section. This attribute is None + unless the multi-group cross section has been computed. + xs_tally : openmc.Tally + Derived tally for the multi-group cross section. This attribute + is None unless the multi-group cross section has been computed. + num_subdomains : int + The number of subdomains is unity for 'material', 'cell' and 'universe' + domain types. When the This is equal to the number of cell instances + for 'distribcell' domain types (it is equal to unity prior to loading + tally data from a statepoint file). + num_nuclides : int + The number of nuclides for which the multi-group cross section is + being tracked. This is unity if the by_nuclide attribute is False. + nuclides : Iterable of str or 'sum' + The optional user-specified nuclides for which to compute cross + sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides + are not specified by the user, all nuclides in the spatial domain + are included. This attribute is 'sum' if by_nuclide is false. + sparse : bool + Whether or not the MGXS' tallies use SciPy's LIL sparse matrix format + for compressed data storage + loaded_sp : bool + Whether or not a statepoint file has been loaded with tally data + derived : bool + Whether or not the MGXS is merged from one or more other MGXS + hdf5_key : str + The key used to index multi-group cross sections in an HDF5 data store + + """ def __init__(self, domain=None, domain_type=None, groups=None, by_nuclide=False, name=''): @@ -1800,49 +2451,90 @@ class NuScatterXS(MGXS): groups, by_nuclide, name) self._rxn_type = 'nu-scatter' - @property - def tallies(self): - """Construct the OpenMC tallies needed to compute this cross section. - - This method constructs two analog tallies to compute the 'flux' - and 'nu-scatter' reaction rates in the spatial domain and energy - groups of interest. - - """ - - # Instantiate tallies if they do not exist - if self._tallies is None: - - # Create a list of scores for each Tally to be created - scores = ['flux', 'nu-scatter'] - estimator = 'analog' - keys = scores - - # Create the non-domain specific Filters for the Tallies - group_edges = self.energy_groups.group_edges - energy_filter = openmc.Filter('energy', group_edges) - filters = [[energy_filter], [energy_filter]] - - # Initialize the Tallies - self._create_tallies(scores, filters, keys, estimator) - - return self._tallies - - @property - def rxn_rate_tally(self): - if self._rxn_rate_tally is None: - self._rxn_rate_tally = self.tallies['nu-scatter'] - self._rxn_rate_tally.sparse = self.sparse - return self._rxn_rate_tally - class ScatterMatrixXS(MGXS): - """A scattering matrix multi-group cross section. + """A scattering matrix multi-group cross section for one or more Legendre + moments. + + This class can be used for both OpenMC input generation and tally data + post-processing to compute spatially-homogenized and energy-integrated + multi-group cross sections for deterministic neutronics calculations. + + Parameters + ---------- + domain : openmc.Material or openmc.Cell or openmc.Universe + The domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + The domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + The energy group structure for energy condensation + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + name : str, optional + Name of the multi-group cross section. Used as a label to identify + tallies in OpenMC 'tallies.xml' file. Attributes ---------- correction : 'P0' or None Apply the P0 correction to scattering matrices if set to 'P0' + legendre_order : int + The highest legendre moment in the scattering matrix (default is 0) + name : str, optional + Name of the multi-group cross section + rxn_type : str + Reaction type (e.g., 'total', 'nu-fission', etc.) + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + domain : Material or Cell or Universe + Domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + Domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + Energy group structure for energy condensation + tally_trigger : openmc.Trigger + An (optional) tally precision trigger given to each tally used to + compute the cross section + scores : list of str + The scores in each tally used to compute the multi-group cross section + filters : list of openmc.Filter + The filters in each tally used to compute the multi-group cross section + tally_keys : list of str + The keys into the tallies dictionary for each tally used to compute + the multi-group cross section + estimator : {'tracklength', 'analog'} + The tally estimator used to compute the multi-group cross section + tallies : collections.OrderedDict + OpenMC tallies needed to compute the multi-group cross section + rxn_rate_tally : openmc.Tally + Derived tally for the reaction rate tally used in the numerator to + compute the multi-group cross section. This attribute is None + unless the multi-group cross section has been computed. + xs_tally : openmc.Tally + Derived tally for the multi-group cross section. This attribute + is None unless the multi-group cross section has been computed. + num_subdomains : int + The number of subdomains is unity for 'material', 'cell' and 'universe' + domain types. When the This is equal to the number of cell instances + for 'distribcell' domain types (it is equal to unity prior to loading + tally data from a statepoint file). + num_nuclides : int + The number of nuclides for which the multi-group cross section is + being tracked. This is unity if the by_nuclide attribute is False. + nuclides : Iterable of str or 'sum' + The optional user-specified nuclides for which to compute cross + sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides + are not specified by the user, all nuclides in the spatial domain + are included. This attribute is 'sum' if by_nuclide is false. + sparse : bool + Whether or not the MGXS' tallies use SciPy's LIL sparse matrix format + for compressed data storage + loaded_sp : bool + Whether or not a statepoint file has been loaded with tally data + derived : bool + Whether or not the MGXS is merged from one or more other MGXS + hdf5_key : str + The key used to index multi-group cross sections in an HDF5 data store """ @@ -1850,12 +2542,15 @@ class ScatterMatrixXS(MGXS): groups=None, by_nuclide=False, name=''): super(ScatterMatrixXS, self).__init__(domain, domain_type, groups, by_nuclide, name) - self._rxn_type = 'scatter matrix' + self._rxn_type = 'scatter' self._correction = 'P0' + self._legendre_order = 0 + self._hdf5_key = 'scatter matrix' def __deepcopy__(self, memo): clone = super(ScatterMatrixXS, self).__deepcopy__(memo) clone._correction = self.correction + clone._legendre_order = self.legendre_order return clone @property @@ -1863,52 +2558,56 @@ class ScatterMatrixXS(MGXS): return self._correction @property - def tallies(self): - """Construct the OpenMC tallies needed to compute this cross section. + def legendre_order(self): + return self._legendre_order - This method constructs three analog tallies to compute the 'flux', - 'scatter' and 'scatter-P1' reaction rates in the spatial domain and - energy groups of interest. + @property + def scores(self): + scores = ['flux'] - """ + if self.correction == 'P0' and self.legendre_order == 0: + scores += ['{}-0'.format(self.rxn_type), + '{}-1'.format(self.rxn_type)] + else: + scores += ['{}-P{}'.format(self.rxn_type, self.legendre_order)] - # Instantiate tallies if they do not exist - if self._tallies is None: + return scores - group_edges = self.energy_groups.group_edges - energy = openmc.Filter('energy', group_edges) - energyout = openmc.Filter('energyout', group_edges) + @property + def filters(self): + group_edges = self.energy_groups.group_edges + energy = openmc.Filter('energy', group_edges) + energyout = openmc.Filter('energyout', group_edges) - # Create a list of scores for each Tally to be created - if self.correction == 'P0': - scores = ['flux', 'scatter', 'scatter-P1'] - filters = [[energy], [energy, energyout], [energyout]] - else: - scores = ['flux', 'scatter'] - filters = [[energy], [energy, energyout]] + if self.correction == 'P0' and self.legendre_order == 0: + filters = [[energy], [energy, energyout], [energyout]] + else: + filters = [[energy], [energy, energyout]] - estimator = 'analog' - keys = scores + return filters - # Initialize the Tallies - self._create_tallies(scores, filters, keys, estimator) - - return self._tallies + @property + def estimator(self): + return 'analog' @property def rxn_rate_tally(self): if self._rxn_rate_tally is None: - # If using P0 correction subtract scatter-P1 from the diagonal - if self.correction == 'P0': - scatter_p1 = self.tallies['scatter-P1'] - scatter_p1 = scatter_p1.get_slice(scores=['scatter-P1']) - energy_filter = self.tallies['scatter'].find_filter('energy') + + # If using P0 correction subtract scatter-1 from the diagonal + if self.correction == 'P0' and self.legendre_order == 0: + scatter_p0 = self.tallies['{}-0'.format(self.rxn_type)] + scatter_p1 = self.tallies['{}-1'.format(self.rxn_type)] + energy_filter = scatter_p0.find_filter('energy') energy_filter = copy.deepcopy(energy_filter) scatter_p1 = scatter_p1.diagonalize_filter(energy_filter) - self._rxn_rate_tally = self.tallies['scatter'] - scatter_p1 + self._rxn_rate_tally = scatter_p0 - scatter_p1 + + # Extract scattering moment reaction rate Tally else: - self._rxn_rate_tally = self.tallies['scatter'] + tally_key = '{}-P{}'.format(self.rxn_type, self.legendre_order) + self._rxn_rate_tally = self.tallies[tally_key] self._rxn_rate_tally.sparse = self.sparse @@ -1917,9 +2616,68 @@ class ScatterMatrixXS(MGXS): @correction.setter def correction(self, correction): cv.check_value('correction', correction, ('P0', None)) + + if correction == 'P0' and self.legendre_order > 0: + msg = 'The P0 correction will be ignored since the scattering ' \ + 'order {} is greater than zero'.format(self.legendre_order) + warnings.warn(msg) + self._correction = correction - def get_slice(self, nuclides=[], in_groups=[], out_groups=[]): + @legendre_order.setter + def legendre_order(self, legendre_order): + cv.check_type('legendre_order', legendre_order, Integral) + cv.check_greater_than('legendre_order', legendre_order, 0, equality=True) + cv.check_less_than('legendre_order', legendre_order, 10, equality=True) + + if self.correction == 'P0' and legendre_order > 0: + msg = 'The P0 correction will be ignored since the scattering ' \ + 'order {} is greater than zero'.format(self.legendre_order) + warnings.warn(msg, RuntimeWarning) + self.correction = None + + self._legendre_order = legendre_order + + def load_from_statepoint(self, statepoint): + """Extracts tallies in an OpenMC StatePoint with the data needed to + compute multi-group cross sections. + + This method is needed to compute cross section data from tallies + in an OpenMC StatePoint object. + + NOTE: The statepoint must first be linked with an OpenMC Summary object. + + Parameters + ---------- + statepoint : openmc.StatePoint + An OpenMC StatePoint object with tally data + + Raises + ------ + ValueError + When this method is called with a statepoint that has not been + linked with a summary object. + + """ + + # Clear any tallies previously loaded from a statepoint + if self.loaded_sp: + self._tallies = None + self._xs_tally = None + self._rxn_rate_tally = None + self._loaded_sp = False + + # Expand scores to match the format in the statepoint + # e.g., "scatter-P2" -> "scatter-0", "scatter-1", "scatter-2" + if self.correction != 'P0' or self.legendre_order != 0: + tally_key = '{}-P{}'.format(self.rxn_type, self.legendre_order) + self.tallies[tally_key].scores = \ + [self.rxn_type + '-{}'.format(i) for i in range(self.legendre_order+1)] + + super(ScatterMatrixXS, self).load_from_statepoint(statepoint) + + def get_slice(self, nuclides=[], in_groups=[], out_groups=[], + legendre_order='same'): """Build a sliced ScatterMatrix for the specified nuclides and energy groups. @@ -1939,6 +2697,12 @@ class ScatterMatrixXS(MGXS): out_groups : list of int A list of outgoing energy group indices starting at 1 for the high energies (e.g., [1, 2, 3]; default is []) + legendre_order : int or 'same' + The highest Legendre moment in the sliced MGXS. If order is 'same' + then the sliced MGXS will have the same Legendre moments as the + original MGXS (default). If order is an integer less than the + original MGXS' order, then only those Legendre moments up to that + order will be included in the sliced MGXS. Returns ------- @@ -1953,6 +2717,20 @@ class ScatterMatrixXS(MGXS): slice_xs._rxn_rate_tally = None slice_xs._xs_tally = None + # Slice the Legendre order if needed + if legendre_order != 'same': + cv.check_type('legendre_order', legendre_order, Integral) + cv.check_less_than('legendre_order', legendre_order, + self.legendre_order, equality=True) + slice_xs.legendre_order = legendre_order + + # Slice the scattering tally + tally_key = '{}-P{}'.format(self.rxn_type, self.legendre_order) + expand_scores = \ + [self.rxn_type + '-{}'.format(i) for i in range(self.legendre_order+1)] + slice_xs.tallies[tally_key] = \ + slice_xs.tallies[tally_key].get_slice(scores=expand_scores) + # Slice outgoing energy groups if needed if len(out_groups) != 0: filter_bins = [] @@ -1972,13 +2750,18 @@ class ScatterMatrixXS(MGXS): return slice_xs def get_xs(self, in_groups='all', out_groups='all', - subdomains='all', nuclides='all', xs_type='macro', - order_groups='increasing', value='mean'): - """Returns an array of multi-group cross sections. + subdomains='all', nuclides='all', moment='all', + xs_type='macro', order_groups='increasing', + row_column='inout', value='mean', **kwargs): + r"""Returns an array of multi-group cross sections. This method constructs a 2D NumPy array for the requested scattering matrix data data for one or more energy groups and subdomains. + NOTE: The scattering moments are not multiplied by the :math:`(2l+1)/2` + prefactor in the expansion of the scattering source into Legendre + moments in the neutron transport equation. + Parameters ---------- in_groups : Iterable of Integral or 'all' @@ -1992,6 +2775,10 @@ class ScatterMatrixXS(MGXS): special string 'all' will return the cross sections for all nuclides in the spatial domain. The special string 'sum' will return the cross section summed over all nuclides. Defaults to 'all'. + moment : int or 'all' + The scattering matrix moment to return. All moments will be + returned if the moment is 'all' (default); otherwise, a specific + moment will be returned. xs_type: {'macro', 'micro'} Return the macro or micro cross section in units of cm^-1 or barns. Defaults to 'macro'. @@ -1999,6 +2786,10 @@ class ScatterMatrixXS(MGXS): Return the cross section indexed according to increasing or decreasing energy groups (decreasing or increasing energies). Defaults to 'increasing'. + row_column: {'inout', 'outin'} + Return the cross section indexed first by incoming group and + second by outgoing group ('inout'), or vice versa ('outin'). + Defaults to 'inout'. value : str A string for the type of value to return - 'mean', 'std_dev', or 'rel_err' are accepted. Defaults to the empty string. @@ -2044,6 +2835,16 @@ class ScatterMatrixXS(MGXS): filters.append('energyout') filter_bins.append((self.energy_groups.get_group_bounds(group),)) + # Construct CrossScore for requested scattering moment + if moment != 'all': + cv.check_type('moment', moment, Integral) + cv.check_greater_than('moment', moment, 0, equality=True) + cv.check_less_than( + 'moment', moment, self.legendre_order, equality=True) + scores = [self.xs_tally.scores[moment]] + else: + scores = [] + # Construct a collection of the nuclides to retrieve from the xs tally if self.by_nuclide: if nuclides == 'all' or nuclides == 'sum' or nuclides == ['sum']: @@ -2056,10 +2857,10 @@ class ScatterMatrixXS(MGXS): # Use tally summation if user requested the sum for all nuclides if nuclides == 'sum' or nuclides == ['sum']: xs_tally = self.xs_tally.summation(nuclides=query_nuclides) - xs = xs_tally.get_values(filters=filters, + xs = xs_tally.get_values(scores=scores, filters=filters, filter_bins=filter_bins, value=value) else: - xs = self.xs_tally.get_values(filters=filters, + xs = self.xs_tally.get_values(scores=scores, filters=filters, filter_bins=filter_bins, nuclides=query_nuclides, value=value) @@ -2092,6 +2893,10 @@ class ScatterMatrixXS(MGXS): new_shape += xs.shape[1:] xs = np.reshape(xs, new_shape) + # Transpose the scattering matrix if requested by user + if row_column == 'outin': + xs = np.swapaxes(xs, 1, 2) + # Reverse energies to align with increasing energy groups xs = xs[:, ::-1, ::-1, :] @@ -2101,7 +2906,77 @@ class ScatterMatrixXS(MGXS): return xs - def print_xs(self, subdomains='all', nuclides='all', xs_type='macro'): + def get_pandas_dataframe(self, groups='all', nuclides='all', moment='all', + xs_type='macro', distribcell_paths=True): + """Build a Pandas DataFrame for the MGXS data. + + This method leverages :meth:`openmc.Tally.get_pandas_dataframe`, but + renames the columns with terminology appropriate for cross section data. + + Parameters + ---------- + groups : Iterable of Integral or 'all' + Energy groups of interest. Defaults to 'all'. + nuclides : Iterable of str or 'all' or 'sum' + The nuclides of the cross-sections to include in the dataframe. This + may be a list of nuclide name strings (e.g., ['U-235', 'U-238']). + The special string 'all' will include the cross sections for all + nuclides in the spatial domain. The special string 'sum' will + include the cross sections summed over all nuclides. Defaults + to 'all'. + moment : int or 'all' + The scattering matrix moment to return. All moments will be + returned if the moment is 'all' (default); otherwise, a specific + moment will be returned. + xs_type: {'macro', 'micro'} + Return macro or micro cross section in units of cm^-1 or barns. + Defaults to 'macro'. + distribcell_paths : bool, optional + Construct columns for distribcell tally filters (default is True). + The geometric information in the Summary object is embedded into a + Multi-index column with a geometric "path" to each distribcell + instance. + + Returns + ------- + pandas.DataFrame + A Pandas DataFrame for the cross section data. + + Raises + ------ + ValueError + When this method is called before the multi-group cross section is + computed from tally data. + + """ + + df = super(ScatterMatrixXS, self).get_pandas_dataframe( + groups, nuclides, xs_type, distribcell_paths) + + # Add a moment column to dataframe + if self.legendre_order > 0: + # Insert a column corresponding to the Legendre moments + moments = ['P{}'.format(i) for i in range(self.legendre_order+1)] + moments = np.tile(moments, df.shape[0] / len(moments)) + df['moment'] = moments + + # Place the moment column before the mean column + mean_index = df.columns.get_loc('mean') + columns = df.columns.tolist() + df = df[columns[:mean_index] + ['moment'] + columns[mean_index:-1]] + + # Select rows corresponding to requested scattering moment + if moment != 'all': + cv.check_type('moment', moment, Integral) + cv.check_greater_than('moment', moment, 0, equality=True) + cv.check_less_than( + 'moment', moment, self.legendre_order, equality=True) + df = df[df['moment'] == 'P{}'.format(moment)] + + return df + + def print_xs(self, subdomains='all', nuclides='all', + xs_type='macro', moment=0): """Prints a string representation for the multi-group cross section. Parameters @@ -2118,6 +2993,8 @@ class ScatterMatrixXS(MGXS): xs_type: {'macro', 'micro'} Return the macro or micro cross section in units of cm^-1 or barns. Defaults to 'macro'. + moment : int + The scattering moment to print (default is 0) """ @@ -2142,9 +3019,14 @@ class ScatterMatrixXS(MGXS): cv.check_value('xs_type', xs_type, ['macro', 'micro']) + if self.correction != 'P0': + rxn_type= '{0} (P{1})'.format(self.rxn_type, moment) + else: + rxn_type = self.rxn_type + # Build header for string with type and domain info string = 'Multi-Group XS\n' - string += '{0: <16}=\t{1}\n'.format('\tReaction Type', self.rxn_type) + string += '{0: <16}=\t{1}\n'.format('\tReaction Type', rxn_type) string += '{0: <16}=\t{1}\n'.format('\tDomain Type', self.domain_type) string += '{0: <16}=\t{1}\n'.format('\tDomain ID', self.domain.id) @@ -2189,11 +3071,11 @@ class ScatterMatrixXS(MGXS): string += template.format('', in_group, out_group) average = \ self.get_xs([in_group], [out_group], - [subdomain], [nuclide], + [subdomain], [nuclide], moment=moment, xs_type=xs_type, value='mean') rel_err = \ self.get_xs([in_group], [out_group], - [subdomain], [nuclide], + [subdomain], [nuclide], moment=moment, xs_type=xs_type, value='rel_err') average = average.flatten()[0] rel_err = rel_err.flatten()[0] * 100. @@ -2207,51 +3089,179 @@ class ScatterMatrixXS(MGXS): class NuScatterMatrixXS(ScatterMatrixXS): - """A scattering production matrix multi-group cross section.""" + """A scattering production matrix multi-group cross section for one or + more Legendre moments. + + This class can be used for both OpenMC input generation and tally data + post-processing to compute spatially-homogenized and energy-integrated + multi-group cross sections for deterministic neutronics calculations. + + Parameters + ---------- + domain : openmc.Material or openmc.Cell or openmc.Universe + The domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + The domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + The energy group structure for energy condensation + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + name : str, optional + Name of the multi-group cross section. Used as a label to identify + tallies in OpenMC 'tallies.xml' file. + + Attributes + ---------- + correction : 'P0' or None + Apply the P0 correction to scattering matrices if set to 'P0' + legendre_order : int + The highest legendre moment in the scattering matrix (default is 0) + name : str, optional + Name of the multi-group cross section + rxn_type : str + Reaction type (e.g., 'total', 'nu-fission', etc.) + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + domain : Material or Cell or Universe + Domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + Domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + Energy group structure for energy condensation + tally_trigger : openmc.Trigger + An (optional) tally precision trigger given to each tally used to + compute the cross section + scores : list of str + The scores in each tally used to compute the multi-group cross section + filters : list of openmc.Filter + The filters in each tally used to compute the multi-group cross section + tally_keys : list of str + The keys into the tallies dictionary for each tally used to compute + the multi-group cross section + estimator : {'tracklength', 'analog'} + The tally estimator used to compute the multi-group cross section + tallies : collections.OrderedDict + OpenMC tallies needed to compute the multi-group cross section + rxn_rate_tally : openmc.Tally + Derived tally for the reaction rate tally used in the numerator to + compute the multi-group cross section. This attribute is None + unless the multi-group cross section has been computed. + xs_tally : openmc.Tally + Derived tally for the multi-group cross section. This attribute + is None unless the multi-group cross section has been computed. + num_subdomains : int + The number of subdomains is unity for 'material', 'cell' and 'universe' + domain types. When the This is equal to the number of cell instances + for 'distribcell' domain types (it is equal to unity prior to loading + tally data from a statepoint file). + num_nuclides : int + The number of nuclides for which the multi-group cross section is + being tracked. This is unity if the by_nuclide attribute is False. + nuclides : Iterable of str or 'sum' + The optional user-specified nuclides for which to compute cross + sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides + are not specified by the user, all nuclides in the spatial domain + are included. This attribute is 'sum' if by_nuclide is false. + sparse : bool + Whether or not the MGXS' tallies use SciPy's LIL sparse matrix format + for compressed data storage + loaded_sp : bool + Whether or not a statepoint file has been loaded with tally data + derived : bool + Whether or not the MGXS is merged from one or more other MGXS + hdf5_key : str + The key used to index multi-group cross sections in an HDF5 data store + + """ def __init__(self, domain=None, domain_type=None, groups=None, by_nuclide=False, name=''): super(NuScatterMatrixXS, self).__init__(domain, domain_type, groups, by_nuclide, name) - self._rxn_type = 'nu-scatter matrix' + self._rxn_type = 'nu-scatter' + self._hdf5_key = 'nu-scatter matrix' - @property - def tallies(self): - """Construct the OpenMC tallies needed to compute this cross section. - - This method constructs three analog tallies to compute the 'flux', - 'nu-scatter' and 'scatter-P1' reaction rates in the spatial domain and - energy groups of interest. - - """ - - # Instantiate tallies if they do not exist - if self._tallies is None: - - # Create the non-domain specific Filters for the Tallies - group_edges = self.energy_groups.group_edges - energy = openmc.Filter('energy', group_edges) - energyout = openmc.Filter('energyout', group_edges) - - # Create a list of scores for each Tally to be created - if self.correction == 'P0': - scores = ['flux', 'nu-scatter', 'scatter-P1'] - estimator = 'analog' - keys = ['flux', 'scatter', 'scatter-P1'] - filters = [[energy], [energy, energyout], [energyout]] - else: - scores = ['flux', 'nu-scatter'] - estimator = 'analog' - keys = ['flux', 'scatter'] - filters = [[energy], [energy, energyout]] - - # Intialize the Tallies - self._create_tallies(scores, filters, keys, estimator) - - return self._tallies class Chi(MGXS): - """The fission spectrum.""" + """The fission spectrum. + + This class can be used for both OpenMC input generation and tally data + post-processing to compute spatially-homogenized and energy-integrated + multi-group cross sections for deterministic neutronics calculations. + + Parameters + ---------- + domain : openmc.Material or openmc.Cell or openmc.Universe + The domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + The domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + The energy group structure for energy condensation + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + name : str, optional + Name of the multi-group cross section. Used as a label to identify + tallies in OpenMC 'tallies.xml' file. + + Attributes + ---------- + name : str, optional + Name of the multi-group cross section + rxn_type : str + Reaction type (e.g., 'total', 'nu-fission', etc.) + by_nuclide : bool + If true, computes cross sections for each nuclide in domain + domain : Material or Cell or Universe + Domain for spatial homogenization + domain_type : {'material', 'cell', 'distribcell', 'universe'} + Domain type for spatial homogenization + energy_groups : openmc.mgxs.EnergyGroups + Energy group structure for energy condensation + tally_trigger : openmc.Trigger + An (optional) tally precision trigger given to each tally used to + compute the cross section + scores : list of str + The scores in each tally used to compute the multi-group cross section + filters : list of openmc.Filter + The filters in each tally used to compute the multi-group cross section + tally_keys : list of str + The keys into the tallies dictionary for each tally used to compute + the multi-group cross section + estimator : {'tracklength', 'analog'} + The tally estimator used to compute the multi-group cross section + tallies : collections.OrderedDict + OpenMC tallies needed to compute the multi-group cross section + rxn_rate_tally : openmc.Tally + Derived tally for the reaction rate tally used in the numerator to + compute the multi-group cross section. This attribute is None + unless the multi-group cross section has been computed. + xs_tally : openmc.Tally + Derived tally for the multi-group cross section. This attribute + is None unless the multi-group cross section has been computed. + num_subdomains : int + The number of subdomains is unity for 'material', 'cell' and 'universe' + domain types. When the This is equal to the number of cell instances + for 'distribcell' domain types (it is equal to unity prior to loading + tally data from a statepoint file). + num_nuclides : int + The number of nuclides for which the multi-group cross section is + being tracked. This is unity if the by_nuclide attribute is False. + nuclides : Iterable of str or 'sum' + The optional user-specified nuclides for which to compute cross + sections (e.g., 'U-238', 'O-16'). If by_nuclide is True but nuclides + are not specified by the user, all nuclides in the spatial domain + are included. This attribute is 'sum' if by_nuclide is false. + sparse : bool + Whether or not the MGXS' tallies use SciPy's LIL sparse matrix format + for compressed data storage + loaded_sp : bool + Whether or not a statepoint file has been loaded with tally data + derived : bool + Whether or not the MGXS is merged from one or more other MGXS + hdf5_key : str + The key used to index multi-group cross sections in an HDF5 data store + + """ def __init__(self, domain=None, domain_type=None, groups=None, by_nuclide=False, name=''): @@ -2259,33 +3269,24 @@ class Chi(MGXS): self._rxn_type = 'chi' @property - def tallies(self): - """Construct the OpenMC tallies needed to compute this cross section. + def scores(self): + return ['nu-fission', 'nu-fission'] - This method constructs two analog tallies to compute 'nu-fission' - reaction rates with 'energy' and 'energyout' filters in the spatial - domain and energy groups of interest. + @property + def filters(self): + # Create the non-domain specific Filters for the Tallies + group_edges = self.energy_groups.group_edges + energyout = openmc.Filter('energyout', group_edges) + energyin = openmc.Filter('energy', [group_edges[0], group_edges[-1]]) + return [[energyin], [energyout]] - """ + @property + def tally_keys(self): + return ['nu-fission-in', 'nu-fission-out'] - # Instantiate tallies if they do not exist - if self._tallies is None: - - # Create a list of scores for each Tally to be created - scores = ['nu-fission', 'nu-fission'] - estimator = 'analog' - keys = ['nu-fission-in', 'nu-fission-out'] - - # Create the non-domain specific Filters for the Tallies - group_edges = self.energy_groups.group_edges - energyout = openmc.Filter('energyout', group_edges) - energyin = openmc.Filter('energy', [group_edges[0], group_edges[-1]]) - filters = [[energyin], [energyout]] - - # Intialize the Tallies - self._create_tallies(scores, filters, keys, estimator) - - return self._tallies + @property + def estimator(self): + return 'analog' @property def rxn_rate_tally(self): @@ -2296,7 +3297,6 @@ class Chi(MGXS): @property def xs_tally(self): - """Computes chi fission spectrum using OpenMC tally arithmetic.""" if self._xs_tally is None: nu_fission_in = self.tallies['nu-fission-in'] @@ -2422,7 +3422,8 @@ class Chi(MGXS): return merged_mgxs def get_xs(self, groups='all', subdomains='all', nuclides='all', - xs_type='macro', order_groups='increasing', value='mean'): + xs_type='macro', order_groups='increasing', + value='mean', **kwargs): """Returns an array of the fission spectrum. This method constructs a 2D NumPy array for the requested multi-group @@ -2557,7 +3558,7 @@ class Chi(MGXS): return xs def get_pandas_dataframe(self, groups='all', nuclides='all', - xs_type='macro', summary=None): + xs_type='macro', distribcell_paths=False): """Build a Pandas DataFrame for the MGXS data. This method leverages :meth:`openmc.Tally.get_pandas_dataframe`, but @@ -2577,12 +3578,11 @@ class Chi(MGXS): xs_type: {'macro', 'micro'} Return macro or micro cross section in units of cm^-1 or barns. Defaults to 'macro'. - summary : None or openmc.Summary - An optional Summary object to be used to construct columns for - distribcell tally filters (default is None). The geometric - information in the Summary object is embedded into a multi-index - column with a geometric "path" to each distribcell intance. - NOTE: This option requires the OpenCG Python package. + distribcell_paths : bool, optional + Construct columns for distribcell tally filters (default is True). + The geometric information in the Summary object is embedded into + a Multi-index column with a geometric "path" to each distribcell + instance. Returns ------- @@ -2598,8 +3598,8 @@ class Chi(MGXS): """ # Build the dataframe using the parent class method - df = super(Chi, self).get_pandas_dataframe(groups, nuclides, - xs_type, summary) + df = super(Chi, self).get_pandas_dataframe( + groups, nuclides, xs_type, distribcell_paths=distribcell_paths) # If user requested micro cross sections, multiply by the atom # densities to cancel out division made by the parent class method diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index c0b04fed1..88ae05808 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -1,19 +1,19 @@ from collections import Iterable from numbers import Real, Integral from xml.etree import ElementTree as ET -import warnings import sys -if sys.version_info[0] >= 3: - basestring = str import numpy as np import openmc -from openmc.mgxs import EnergyGroups +import openmc.mgxs from openmc.checkvalue import check_type, check_value, check_greater_than, \ - check_iterable_type + check_iterable_type from openmc.clean_xml import * +if sys.version_info[0] >= 3: + basestring = str + # Supported incoming particle MGXS angular treatment representations _REPRESENTATIONS = ['isotropic', 'angle'] @@ -99,6 +99,12 @@ class XSdata(object): Unique identifier for the xsdata object alias : str Separate unique identifier for the xsdata object + zaid : int + 1000*(atomic number) + mass number. As an example, the zaid of U-235 + would be 92235. + awr : float + Atomic weight ratio of an isotope. That is, the ratio of the mass + of the isotope to the mass of a single neutron. kT : float Temperature (in units of MeV). energy_groups : openmc.mgxs.EnergyGroups @@ -116,12 +122,27 @@ class XSdata(object): Legendre polynomial form). Dict contains two keys: 'enable' and 'num_points'. 'enable' is a boolean and 'num_points' is the number of points to use, if 'enable' is True. + representation : {'isotropic', 'angle'} + Method used in generating the MGXS (isotropic or angle-dependent flux + weighting). num_azimuthal : int Number of equal width angular bins that the azimuthal angular domain is subdivided into. This only applies when ``representation`` is "angle". num_polar : int Number of equal width angular bins that the polar angular domain is subdivided into. This only applies when ``representation`` is "angle". + vector_shape : iterable of int + Dimensionality of vector multi-group cross sections (e.g., the total + cross section). The return result depends on the value of + ``representation``. + matrix_shape : iterable of int + Dimensionality of matrix multi-group cross sections (e.g., the + fission matrix cross section). The return result depends on the + value of ``representation``. + pn_matrix_shape : iterable of int + Dimensionality of scattering matrix data (e.g., the + scattering matrix cross section). The return result depends on the + value of ``representation``. total : numpy.ndarray Group-wise total cross section ordered by increasing group index (i.e., fast to thermal). If ``representation`` is "isotropic", then the length @@ -133,9 +154,9 @@ class XSdata(object): angles and outer-dimension being the polar angles. absorption : numpy.ndarray Group-wise absorption cross section ordered by increasing group index - (i.e., fast to thermal). If ``representation`` is "isotropic", then the + (i.e., fast to thermal). If ``representation`` is "isotropic", then the length of this list should equal the number of groups described in the - ``groups`` attribute. If ``representation`` is "angle", then the length + ``groups`` attribute. If ``representation`` is "angle", then the length of this list should equal the number of groups times the number of azimuthal angles times the number of polar angles, with the inner-dimension being groups, intermediate-dimension being azimuthal @@ -152,7 +173,7 @@ class XSdata(object): multiplicity : numpy.ndarray Ratio of neutrons produced in scattering collisions to the neutrons which undergo scattering collisions; that is, the multiplicity provides - the code with a scaling factor to account for neutrons being produced in + the code with a scaling factor to account for neutrons produced in (n,xn) reactions. This information is assumed isotropic and therefore does not need to be repeated for every Legendre moment or histogram/tabular bin. This matrix follows the same arrangement as @@ -160,30 +181,30 @@ class XSdata(object): needed to provide the scattering type information. fission : numpy.ndarray Group-wise fission cross section ordered by increasing group index - (i.e., fast to thermal). If ``representation`` is "isotropic", then the + (i.e., fast to thermal). If ``representation`` is "isotropic", then the length of this list should equal the number of groups described in the - ``groups`` attribute. If ``representation`` is "angle", then the length + ``groups`` attribute. If ``representation`` is "angle", then the length of this list should equal the number of groups times the number of azimuthal angles times the number of polar angles, with the inner-dimension being groups, intermediate-dimension being azimuthal angles and outer-dimension being the polar angles. - k_fission : numpy.ndarray - Group-wise kappa-fission cross section ordered by increasing group index - (i.e., fast to thermal). If ``representation`` is "isotropic", then the - length of this list should equal the number of groups described in the - ``groups`` attribute. If ``representation`` is "angle", then the length + kappa_fission : numpy.ndarray + Group-wise kappa-fission cross section ordered by increasing group + index (i.e., fast to thermal). If ``representation`` is "isotropic", + then the length of this list should equal the number of groups in the + ``groups`` attribute. If ``representation`` is "angle", then the length of this list should equal the number of groups times the number of azimuthal angles times the number of polar angles, with the inner-dimension being groups, intermediate-dimension being azimuthal angles and outer-dimension being the polar angles. chi : numpy.ndarray - Group-wise fission spectra ordered by increasing group index (i.e., fast - to thermal). This attribute should be used if making the common + Group-wise fission spectra ordered by increasing group index (i.e., + fast to thermal). This attribute should be used if making the common approximation that the fission spectra does not depend on incoming - energy. If the user does not wish to make this approximation, then this - should not be provided and this information included in the + energy. If the user does not wish to make this approximation, then + this should not be provided and this information included in the ``nu_fission`` element instead. If ``representation`` is "isotropic", - then the length of this list should equal the number of groups described + then the length of this list should equal the number of groups in the ``groups`` element. If ``representation`` is "angle", then the length of this list should equal the number of groups times the number of azimuthal angles times the number of polar angles, with the @@ -191,18 +212,21 @@ class XSdata(object): angles and outer-dimension being the polar angles. nu_fission : numpy.ndarray Group-wise fission production cross section vector (i.e., if ``chi`` is - provided), or is the group-wise fission production matrix. If providing + provided), or is the group-wise fission production matrix. If providing the vector, it should be ordered the same as the ``fission`` data. If providing the matrix, it should be ordered the same as the ``multiplicity`` matrix. """ - def __init__(self, name, energy_groups, representation="isotropic"): + + def __init__(self, name, energy_groups, representation='isotropic'): # Initialize class attributes self._name = name self._energy_groups = energy_groups self._representation = representation self._alias = None + self._zaid = None + self._awr = None self._kT = None self._fissionable = False self._scatt_type = 'legendre' @@ -216,7 +240,7 @@ class XSdata(object): self._multiplicity = None self._fission = None self._nu_fission = None - self._k_fission = None + self._kappa_fission = None self._chi = None self._use_chi = None @@ -236,6 +260,14 @@ class XSdata(object): def alias(self): return self._alias + @property + def zaid(self): + return self._zaid + + @property + def awr(self): + return self._awr + @property def kT(self): return self._kT @@ -285,8 +317,8 @@ class XSdata(object): return self._nu_fission @property - def k_fission(self): - return self._k_fission + def kappa_fission(self): + return self._kappa_fission @property def chi(self): @@ -300,6 +332,34 @@ class XSdata(object): else: return self._order + @property + def vector_shape(self): + if self.representation is 'isotropic': + return (self.energy_groups.num_groups,) + elif self.representation is 'angle': + return (self.num_polar, self.num_azimuthal, + self.energy_groups.num_groups) + + @property + def matrix_shape(self): + if self.representation is 'isotropic': + return (self.energy_groups.num_groups, + self.energy_groups.num_groups) + elif self.representation is 'angle': + return (self.num_polar, self.num_azimuthal, + self.energy_groups.num_groups, + self.energy_groups.num_groups) + + @property + def pn_matrix_shape(self): + if self.representation is 'isotropic': + return (self.num_orders, self.energy_groups.num_groups, + self.energy_groups.num_groups) + elif self.representation is 'angle': + return (self.num_polar, self.num_azimuthal, self.num_orders, + self.energy_groups.num_groups, + self.energy_groups.num_groups) + @name.setter def name(self, name): check_type('name for XSdata', name, basestring) @@ -308,15 +368,12 @@ class XSdata(object): @energy_groups.setter def energy_groups(self, energy_groups): # Check validity of energy_groups - check_type("energy_groups", energy_groups, EnergyGroups) + check_type('energy_groups', energy_groups, openmc.mgxs.EnergyGroups) - # Check that there is one or more groups - if ((energy_groups.num_groups is None) or - (energy_groups.num_groups < 1)): - - msg = 'energy_groups object incorrectly initialized.' + if energy_group.group_edges is None: + msg = 'Unable to assign an EnergyGroups object ' \ + 'with uninitialized group edges' raise ValueError(msg) - self._energy_groups = energy_groups @representation.setter @@ -333,37 +390,52 @@ class XSdata(object): else: self._alias = self._name + @zaid.setter + def zaid(self, zaid): + # Check type and value + check_type('zaid', zaid, Integral) + check_greater_than('zaid', zaid, 0) + self._zaid = zaid + + @awr.setter + def awr(self, awr): + # Check validity of type and that the awr value is > 0 + check_type('awr', awr, Real) + check_greater_than('awr', awr, 0.0) + self._awr = awr + @kT.setter def kT(self, kT): # Check validity of type and that the kT value is >= 0 - check_type("kT", kT, Real) - check_greater_than("kT", kT, 0.0, equality=True) + check_type('kT', kT, Real) + check_greater_than('kT', kT, 0.0, equality=True) self._kT = kT @scatt_type.setter def scatt_type(self, scatt_type): # check to see it is of a valid type and value - check_value("scatt_type", scatt_type, ['legendre', 'histogram', + check_value('scatt_type', scatt_type, ['legendre', 'histogram', 'tabular']) self._scatt_type = scatt_type @order.setter def order(self, order): # Check type and value - check_type("order", order, Integral) - check_greater_than("order", order, 0, equality=True) + check_type('order', order, Integral) + check_greater_than('order', order, 0, equality=True) self._order = order @tabular_legendre.setter def tabular_legendre(self, tabular_legendre): # Check to make sure this is a dict and it has our keys with the # right values. - check_type("tabular_legendre", tabular_legendre, dict) + check_type('tabular_legendre', tabular_legendre, dict) if 'enable' in tabular_legendre: enable = tabular_legendre['enable'] check_type('enable', enable, bool) else: - msg = "enable must be provided in tabular_legendre" + msg = 'The tabular_legendre dict must include a value keyed by ' \ + '"enable"' raise ValueError(msg) if 'num_points' in tabular_legendre: num_points = tabular_legendre['num_points'] @@ -379,200 +451,503 @@ class XSdata(object): @num_polar.setter def num_polar(self, num_polar): # Make sure we have positive ints - check_value("num_polar", num_polar, Integral) - check_greater_than("num_polar", num_polar, 0) + check_value('num_polar', num_polar, Integral) + check_greater_than('num_polar', num_polar, 0) self._num_polar = num_polar @num_azimuthal.setter def num_azimuthal(self, num_azimuthal): - check_value("num_azimuthal", num_azimuthal, Integral) - check_greater_than("num_azimuthal", num_azimuthal, 0) + check_value('num_azimuthal', num_azimuthal, Integral) + check_greater_than('num_azimuthal', num_azimuthal, 0) self._num_azimuthal = num_azimuthal @total.setter def total(self, total): - if self._representation is 'isotropic': - shape = (self._energy_groups.num_groups,) - elif self._representation is 'angle': - shape = (self._num_polar, self._num_azimuthal, - self._energy_groups.num_groups) - # check we have a numpy list - check_type("total", total, np.ndarray, expected_iter_type=Real) - if total.shape == shape: - self._total = np.copy(total) - else: - msg = 'Shape of provided total "{0}" does not match shape ' \ - 'required, "{1}"'.format(total.shape, shape) - raise ValueError(msg) + check_type('total', total, Iterable, expected_iter_type=Real) + # Convert to a numpy array so we can easily get the shape for + # checking + nptotal = np.asarray(total) + check_value('total shape', nptotal.shape, [self.vector_shape]) + + self._total = nptotal @absorption.setter def absorption(self, absorption): - if self._representation is 'isotropic': - shape = (self._energy_groups.num_groups,) - elif self._representation is 'angle': - shape = (self._num_polar, self._num_azimuthal, - self._energy_groups.num_groups) - # check we have a numpy list - check_type("absorption", absorption, np.ndarray, expected_iter_type=Real) - if absorption.shape == shape: - self._absorption = np.copy(absorption) - else: - msg = 'Shape of provided absorption "{0}" does not match shape ' \ - 'required, "{1}"'.format(absorption.shape, shape) - raise ValueError(msg) + check_type('absorption', absorption, Iterable, expected_iter_type=Real) + # Convert to a numpy array so we can easily get the shape for + # checking + npabsorption = np.asarray(absorption) + check_value('absorption shape', npabsorption.shape, + [self.vector_shape]) + + self._absorption = npabsorption @fission.setter def fission(self, fission): - if self._representation is 'isotropic': - shape = (self._energy_groups.num_groups,) - elif self._representation is 'angle': - shape = (self._num_polar, self._num_azimuthal, - self._energy_groups.num_groups) - # check we have a numpy list - check_type("fission", fission, np.ndarray, expected_iter_type=Real) - if fission.shape == shape: - self._fission = np.copy(fission) - if np.sum(self._fission) > 0.0: - self._fissionable = True - else: - msg = 'Shape of provided fission "{0}" does not match shape ' \ - 'required, "{1}"'.format(fission.shape, shape) - raise ValueError(msg) + check_type('fission', fission, Iterable, expected_iter_type=Real) + # Convert to a numpy array so we can easily get the shape for + # checking + npfission = np.asarray(fission) + check_value('fission shape', npfission.shape, [self.vector_shape]) - @k_fission.setter - def k_fission(self, k_fission): - if self._representation is 'isotropic': - shape = (self._energy_groups.num_groups,) - elif self._representation is 'angle': - shape = (self._num_polar, self._num_azimuthal, - self._energy_groups.num_groups) - # check we have a numpy list - check_type("k_fission", k_fission, np.ndarray, expected_iter_type=Real) - if k_fission.shape == shape: - self._k_fission = np.copy(k_fission) - if np.sum(self._k_fission) > 0.0: - self._fissionable = True - else: - msg = 'Shape of provided k_fission "{0}" does not match shape ' \ - 'required, "{1}"'.format(k_fission.shape, shape) - raise ValueError(msg) + self._fission = npfission + + if np.sum(self._fission) > 0.0: + self._fissionable = True + + @kappa_fission.setter + def kappa_fission(self, kappa_fission): + check_type('kappa_fission', kappa_fission, Iterable, + expected_iter_type=Real) + # Convert to a numpy array so we can easily get the shape for + # checking + npkappa_fission = np.asarray(kappa_fission) + check_value('kappa fission shape', npkappa_fission.shape, + [self.vector_shape]) + + self._kappa_fission = npkappa_fission + + if np.sum(self._kappa_fission) > 0.0: + self._fissionable = True @chi.setter def chi(self, chi): - if not self._use_chi: - msg = 'Providing chi when nu_fission already provided as matrix!' - raise ValueError(msg) - if self._representation is 'isotropic': - shape = (self._energy_groups.num_groups,) - elif self._representation is 'angle': - shape = (self._num_polar, self._num_azimuthal, - self._energy_groups.num_groups) - # check we have a numpy list - check_type("chi", chi, np.ndarray, expected_iter_type=Real) - if chi.shape == shape: - self._chi = np.copy(chi) - else: - msg = 'Shape of provided chi "{0}" does not match shape ' \ - 'required, "{1}"'.format(chi.shape, shape) + if self._use_chi is not None: + if not self._use_chi: + msg = 'Providing chi when nu_fission already provided as a' \ + 'matrix' + raise ValueError(msg) + + check_type('chi', chi, Iterable, expected_iter_type=Real) + # Convert to a numpy array so we can easily get the shape for + # checking + npchi = np.asarray(chi) + # Check the shape + if npchi.shape != self.vector_shape: + msg = 'Provided chi iterable does not have the expected shape.' raise ValueError(msg) + + self._chi = npchi + if self._use_chi is not None: self._use_chi = True @scatter.setter def scatter(self, scatter): - if self._representation is 'isotropic': - shape = (self.num_orders, self._energy_groups.num_groups, - self._energy_groups.num_groups) - max_depth = 3 - elif self._representation is 'angle': - shape = (self._num_polar, self._num_azimuthal, self.num_orders, - self._energy_groups.num_groups, - self._energy_groups.num_groups) - max_depth = 5 - # check we have a numpy list - check_iterable_type("scatter", scatter, expected_type=Real, - max_depth=max_depth) - if scatter.shape == shape: - self._scatter = np.copy(scatter) - else: - msg = 'Shape of provided scatter "{0}" does not match shape ' \ - 'required, "{1}"'.format(scatter.shape, shape) - raise ValueError(msg) + # Convert to a numpy array so we can easily get the shape for + # checking + npscatter = np.asarray(scatter) + check_iterable_type('scatter', npscatter, Real, + max_depth=len(npscatter.shape)) + check_value('scatter shape', npscatter.shape, [self.pn_matrix_shape]) + + self._scatter = npscatter @multiplicity.setter def multiplicity(self, multiplicity): - if self._representation is 'isotropic': - shape = (self._energy_groups.num_groups, - self._energy_groups.num_groups) - max_depth = 2 - elif self._representation is 'angle': - shape = (self._num_polar, self._num_azimuthal, - self._energy_groups.num_groups, - self._energy_groups.num_groups) - max_depth = 4 - # check we have a numpy list - check_iterable_type("multiplicity", multiplicity, expected_type=Real, - max_depth=max_depth) - if multiplicity.shape == shape: - self._multiplicity = np.copy(multiplicity) - else: - msg = 'Shape of provided multiplicity "{0}" does not match shape ' \ - 'required, "{1}"'.format(multiplicity.shape, shape) - raise ValueError(msg) + # Convert to a numpy array so we can easily get the shape for + # checking + npmultiplicity = np.asarray(multiplicity) + check_iterable_type('multiplicity', npmultiplicity, Real, + max_depth=len(npmultiplicity.shape)) + check_value('multiplicity shape', npmultiplicity.shape, + [self.matrix_shape]) + + self._multiplicity = npmultiplicity @nu_fission.setter def nu_fission(self, nu_fission): + # The NuFissionXS class does not have the capability to produce + # a fission matrix and therefore if this path is pursued, we know + # chi must be used. # nu_fission can be given as a vector or a matrix # Vector is used when chi also exists. # Matrix is used when chi does not exist. # We have to check that the correct form is given, but only if # chi already has been set. If not, we just check that this is OK - # and set the use_chi flag. + # and set the use_chi flag accordingly - # First lets set our dimensions here since they get used repeatedly - # throughout this code. - if self._representation is 'isotropic': - shape_vec = (self._energy_groups.num_groups,) - shape_mat = (self._energy_groups.num_groups, - self._energy_groups.num_groups) - elif self._representation is 'angle': - shape_vec = (self._num_polar, self._num_azimuthal, - self._energy_groups.num_groups) - shape_mat = (self._num_polar, self._num_azimuthal, - self._energy_groups.num_groups, - self._energy_groups.num_groups) + # Convert to a numpy array so we can easily get the shape for + # checking + npnu_fission = np.asarray(nu_fission) + + check_iterable_type('nu_fission', npnu_fission, Real, + max_depth=len(npnu_fission.shape)) - # Begin by checking the case when chi has already been given and thus - # the rules for filling in nu_fission are set. if self._use_chi is not None: if self._use_chi: - shape = shape_vec + check_value('nu_fission shape', npnu_fission.shape, + [self.vector_shape]) else: - shape = shape_mat - if nu_fission.shape != shape: - msg = "Invalid Shape of Nu_fission!" - raise ValueError(msg) + check_value('nu_fission shape', npnu_fission.shape, + [self.matrix_shape]) else: - # Get shape of nu_fission so we can figure if we need chi or not - if nu_fission.shape == shape_vec: + check_value('nu_fission shape', npnu_fission.shape, + [self.vector_shape, self.matrix_shape]) + # Find out if we have a nu-fission matrix or vector + # and set a flag to allow other methods to check this later. + if npnu_fission.shape == self.vector_shape: self._use_chi = True - shape = shape_vec - elif nu_fission.shape == shape_mat: - self._use_chi = False - shape = shape_mat else: - msg = "Invalid Shape of Nu_fission!" - raise ValueError(msg) + self._use_chi = False - # check we have a numpy list - check_type("nu_fission", nu_fission, np.ndarray, expected_iter_type=Real) - self._nu_fission = np.copy(nu_fission) + self._nu_fission = npnu_fission if np.sum(self._nu_fission) > 0.0: self._fissionable = True + def set_total_mgxs(self, total, nuclide='total', xs_type='macro'): + """This method allows for an openmc.mgxs.TotalXS or + openmc.mgxs.TransportXS to be used to set the total cross section + for this XSdata object. + + Parameters + ---------- + total: openmc.mgxs.TotalXS or openmc.mgxs.TransportXS + MGXS Object containing the total or transport cross section + for the domain of interest. + nuclide : str + Individual nuclide (or 'total' if obtaining material-wise data) + to gather data for. Defaults to 'total'. + xs_type: {'macro', 'micro'} + Provide the macro or micro cross section in units of cm^-1 or + barns. Defaults to 'macro'. + + See also + -------- + openmc.mgxs.Library.create_mg_library() + openmc.mgxs.Library.get_xsdata + + """ + + check_type('total', total, (openmc.mgxs.TotalXS, + openmc.mgxs.TransportXS)) + check_value('energy_groups', total.energy_groups, [self.energy_groups]) + check_value('domain_type', total.domain_type, + ['universe', 'cell', 'material']) + + if self.representation is 'isotropic': + self._total = total.get_xs(nuclides=nuclide, xs_type=xs_type) + elif self.representation is 'angle': + msg = 'Angular-Dependent MGXS have not yet been implemented' + raise ValueError(msg) + + def set_absorption_mgxs(self, absorption, nuclide='total', + xs_type='macro'): + """This method allows for an openmc.mgxs.AbsorptionXS + to be used to set the absorption cross section for this XSdata object. + + Parameters + ---------- + absorption: openmc.mgxs.AbsorptionXS + MGXS Object containing the absorption cross section + for the domain of interest. + nuclide : str + Individual nuclide (or 'total' if obtaining material-wise data) + to gather data for. Defaults to 'total'. + xs_type: {'macro', 'micro'} + Provide the macro or micro cross section in units of cm^-1 or + barns. Defaults to 'macro'. + + See also + -------- + openmc.mgxs.Library.create_mg_library() + openmc.mgxs.Library.get_xsdata + + """ + + check_type('absorption', absorption, openmc.mgxs.AbsorptionXS) + check_value('energy_groups', absorption.energy_groups, + [self.energy_groups]) + check_value('domain_type', absorption.domain_type, + ['universe', 'cell', 'material']) + + if self.representation is 'isotropic': + self._absorption = absorption.get_xs(nuclides=nuclide, + xs_type=xs_type) + elif self.representation is 'angle': + msg = 'Angular-Dependent MGXS have not yet been implemented' + raise ValueError(msg) + + def set_fission_mgxs(self, fission, nuclide='total', xs_type='macro'): + """This method allows for an openmc.mgxs.FissionXS + to be used to set the fission cross section for this XSdata object. + + Parameters + ---------- + fission: openmc.mgxs.FissionXS + MGXS Object containing the fission cross section + for the domain of interest. + nuclide : str + Individual nuclide (or 'total' if obtaining material-wise data) + to gather data for. Defaults to 'total'. + xs_type: {'macro', 'micro'} + Provide the macro or micro cross section in units of cm^-1 or + barns. Defaults to 'macro'. + + See also + -------- + openmc.mgxs.Library.create_mg_library() + openmc.mgxs.Library.get_xsdata + + """ + + check_type('fission', fission, openmc.mgxs.FissionXS) + check_value('energy_groups', fission.energy_groups, + [self.energy_groups]) + check_value('domain_type', fission.domain_type, + ['universe', 'cell', 'material']) + + if self.representation is 'isotropic': + self._fission = fission.get_xs(nuclides=nuclide, + xs_type=xs_type) + elif self.representation is 'angle': + msg = 'Angular-Dependent MGXS have not yet been implemented' + raise ValueError(msg) + + def set_nu_fission_mgxs(self, nu_fission, nuclide='total', + xs_type='macro'): + """This method allows for an openmc.mgxs.NuFissionXS + to be used to set the nu-fission cross section for this XSdata object. + + Parameters + ---------- + nu_fission: openmc.mgxs.NuFissionXS + MGXS Object containing the nu-fission cross section + for the domain of interest. + nuclide : str + Individual nuclide (or 'total' if obtaining material-wise data) + to gather data for. Defaults to 'total'. + xs_type: {'macro', 'micro'} + Provide the macro or micro cross section in units of cm^-1 or + barns. Defaults to 'macro'. + + See also + -------- + openmc.mgxs.Library.create_mg_library() + openmc.mgxs.Library.get_xsdata + + """ + + # The NuFissionXS class does not have the capability to produce + # a fission matrix and therefore if this path is pursued, we know + # chi must be used. + check_type('nu_fission', nu_fission, openmc.mgxs.NuFissionXS) + check_value('energy_groups', nu_fission.energy_groups, + [self.energy_groups]) + check_value('domain_type', nu_fission.domain_type, + ['universe', 'cell', 'material']) + + if self.representation is 'isotropic': + self._nu_fission = nu_fission.get_xs(nuclides=nuclide, + xs_type=xs_type) + elif self.representation is 'angle': + msg = 'Angular-Dependent MGXS have not yet been implemented' + raise ValueError(msg) + + self._use_chi = True + + if np.sum(self._nu_fission) > 0.0: + self._fissionable = True + + def set_kappa_fission_mgxs(self, k_fission, nuclide='total', + xs_type='macro'): + """This method allows for an openmc.mgxs.KappaFissionXS + to be used to set the kappa-fission cross section for this XSdata + object. + + Parameters + ---------- + kappa_fission: openmc.mgxs.KappaFissionXS + MGXS Object containing the kappa-fission cross section + for the domain of interest. + nuclide : str + Individual nuclide (or 'total' if obtaining material-wise data) + to gather data for. Defaults to 'total'. + xs_type: {'macro', 'micro'} + Provide the macro or micro cross section in units of cm^-1 or + barns. Defaults to 'macro'. + + See also + -------- + openmc.mgxs.Library.create_mg_library() + openmc.mgxs.Library.get_xsdata + + """ + + check_type('k_fission', k_fission, openmc.mgxs.KappaFissionXS) + check_value('energy_groups', k_fission.energy_groups, + [self.energy_groups]) + check_value('domain_type', k_fission.domain_type, + ['universe', 'cell', 'material']) + + if self.representation is 'isotropic': + self._kappa_fission = k_fission.get_xs(nuclides=nuclide, + xs_type=xs_type) + elif self.representation is 'angle': + msg = 'Angular-Dependent MGXS have not yet been implemented' + raise ValueError(msg) + + def set_chi_mgxs(self, chi, nuclide='total', xs_type='macro'): + """This method allows for an openmc.mgxs.Chi + to be used to set chi for this XSdata object. + + Parameters + ---------- + chi: openmc.mgxs.Chi + MGXS Object containing chi for the domain of interest. + nuclide : str + Individual nuclide (or 'total' if obtaining material-wise data) + to gather data for. Defaults to 'total'. + xs_type: {'macro', 'micro'} + Provide the macro or micro cross section in units of cm^-1 or + barns. Defaults to 'macro'. + + See also + -------- + openmc.mgxs.Library.create_mg_library() + openmc.mgxs.Library.get_xsdata + + """ + + if self._use_chi is not None: + if not self._use_chi: + msg = 'Providing chi when nu_fission already provided as a ' \ + 'matrix!' + raise ValueError(msg) + + check_type('chi', chi, openmc.mgxs.Chi) + check_value('energy_groups', chi.energy_groups, [self.energy_groups]) + check_value('domain_type', chi.domain_type, + ['universe', 'cell', 'material']) + + if self.representation is 'isotropic': + self._chi = chi.get_xs(nuclides=nuclide, + xs_type=xs_type) + elif self.representation is 'angle': + msg = 'Angular-Dependent MGXS have not yet been implemented' + raise ValueError(msg) + + if self._use_chi is not None: + self._use_chi = True + + def set_scatter_mgxs(self, scatter, nuclide='total', xs_type='macro'): + """This method allows for an openmc.mgxs.ScatterMatrixXS + to be used to set the scatter matrix cross section for this XSdata + object. If the XSdata.order attribute has not yet been set, then + it will be set based on the properties of scatter. + + Parameters + ---------- + scatter: openmc.mgxs.ScatterMatrixXS + MGXS Object containing the scatter matrix cross section + for the domain of interest. + nuclide : str + Individual nuclide (or 'total' if obtaining material-wise data) + to gather data for. Defaults to 'total'. + xs_type: {'macro', 'micro'} + Provide the macro or micro cross section in units of cm^-1 or + barns. Defaults to 'macro'. + + See also + -------- + openmc.mgxs.Library.create_mg_library() + openmc.mgxs.Library.get_xsdata + + """ + + check_type('scatter', scatter, openmc.mgxs.ScatterMatrixXS) + check_value('energy_groups', scatter.energy_groups, + [self.energy_groups]) + check_value('domain_type', scatter.domain_type, + ['universe', 'cell', 'material']) + + if (self.scatt_type != 'legendre'): + msg = 'Anisotropic scattering representations other than ' \ + 'Legendre expansions have not yet been implemented in ' \ + 'openmc.mgxs.' + raise ValueError(msg) + + # If the user has not defined XSdata.order, then we will set + # the order based on the data within scatter. + # Otherwise, we will check to see that XSdata.order to match + # the order of scatter + if self.order is None: + self.order = scatter.legendre_order + else: + check_value('legendre_order', scatter.legendre_order, + [self.order]) + + if self.representation is 'isotropic': + # Get the scattering orders in the outermost dimension + self._scatter = np.zeros((self.num_orders, + self.energy_groups.num_groups, + self.energy_groups.num_groups)) + for moment in range(self.num_orders): + self._scatter[moment, :, :] = scatter.get_xs(nuclides=nuclide, + xs_type=xs_type, + moment=moment) + + elif self.representation is 'angle': + msg = 'Angular-Dependent MGXS have not yet been implemented' + raise ValueError(msg) + + def set_multiplicity_mgxs(self, nuscatter, scatter, nuclide='total', + xs_type='macro'): + """This method allows for an openmc.mgxs.NuScatterMatrixXS and + openmc.mgxs.ScatterMatrixXS to be used to set the scattering + multiplicity for this XSdata object. Multiplicity, + in OpenMC parlance, is a factor used to account for the production + of neutrons introduced by scattering multiplication reactions, i.e., + (n,xn) events. In this sense, the multiplication matrix is simply + defined as the ratio of the nu-scatter and scatter matrices. + + Parameters + ---------- + nuscatter: openmc.mgxs.NuScatterMatrixXS + MGXS Object containing the nu-scattering matrix cross section + for the domain of interest. + scatter: openmc.mgxs.ScatterMatrixXS + MGXS Object containing the scattering matrix cross section + for the domain of interest. + nuclide : str + Individual nuclide (or 'total' if obtaining material-wise data) + to gather data for. Defaults to 'total'. + xs_type: {'macro', 'micro'} + Provide the macro or micro cross section in units of cm^-1 or + barns. Defaults to 'macro'. + + See also + -------- + openmc.mgxs.Library.create_mg_library() + openmc.mgxs.Library.get_xsdata + + """ + + check_type('nuscatter', nuscatter, openmc.mgxs.NuScatterMatrixXS) + check_type('scatter', scatter, openmc.mgxs.ScatterMatrixXS) + check_value('energy_groups', nuscatter.energy_groups, + [self.energy_groups]) + check_value('energy_groups', scatter.energy_groups, + [self.energy_groups]) + check_value('domain_type', nuscatter.domain_type, + ['universe', 'cell', 'material']) + check_value('domain_type', scatter.domain_type, + ['universe', 'cell', 'material']) + + if self.representation is 'isotropic': + nuscatt = nuscatter.get_xs(nuclides=nuclide, + xs_type=xs_type, moment=0) + scatt = scatter.get_xs(nuclides=nuclide, + xs_type=xs_type, moment=0) + self._multiplicity = np.divide(nuscatt, scatt) + elif self.representation is 'angle': + msg = 'Angular-Dependent MGXS have not yet been implemented' + raise ValueError(msg) + self._multiplicity = np.nan_to_num(self._multiplicity) + def _get_xsdata_xml(self): - element = ET.Element("xsdata") - element.set("name", self._name) + element = ET.Element('xsdata') + element.set('name', self._name) if self._alias is not None: subelement = ET.SubElement(element, 'alias') @@ -582,6 +957,18 @@ class XSdata(object): subelement = ET.SubElement(element, 'kT') subelement.text = str(self._kT) + if self._zaid is not None: + subelement = ET.SubElement(element, 'zaid') + subelement.text = str(self._zaid) + + if self._awr is not None: + subelement = ET.SubElement(element, 'awr') + subelement.text = str(self._awr) + + if self._kT is not None: + subelement = ET.SubElement(element, 'kT') + subelement.text = str(self._kT) + if self._fissionable is not None: subelement = ET.SubElement(element, 'fissionable') subelement.text = str(self._fissionable) @@ -609,7 +996,8 @@ class XSdata(object): if self._tabular_legendre is not None: subelement = ET.SubElement(element, 'tabular_legendre') subelement.set('enable', str(self._tabular_legendre['enable'])) - subelement.set('num_points', str(self._tabular_legendre['num_points'])) + subelement.set('num_points', + str(self._tabular_legendre['num_points'])) if self._total is not None: subelement = ET.SubElement(element, 'total') @@ -632,9 +1020,9 @@ class XSdata(object): subelement = ET.SubElement(element, 'fission') subelement.text = ndarray_to_string(self._fission) - if self._k_fission is not None: + if self._kappa_fission is not None: subelement = ET.SubElement(element, 'k_fission') - subelement.text = ndarray_to_string(self._k_fission) + subelement.text = ndarray_to_string(self._kappa_fission) if self._nu_fission is not None: subelement = ET.SubElement(element, 'nu_fission') @@ -647,9 +1035,10 @@ class XSdata(object): return element -class MGXSLibraryFile(object): +class MGXSLibrary(object): """Multi-Group Cross Sections file used for an OpenMC simulation. - Corresponds directly to the MG version of the cross_sections.xml input file. + Corresponds directly to the MG version of the cross_sections.xml input + file. Attributes ---------- @@ -662,11 +1051,10 @@ class MGXSLibraryFile(object): """ def __init__(self, energy_groups): - # Initialize MGXSLibraryFile class attributes self._xsdatas = [] self._energy_groups = energy_groups self._inverse_velocities = None - self._cross_sections_file = ET.Element("cross_sections") + self._cross_sections_file = ET.Element('cross_sections') @property def inverse_velocities(self): @@ -685,7 +1073,7 @@ class MGXSLibraryFile(object): @energy_groups.setter def energy_groups(self, energy_groups): - check_type("energy groups", energy_groups, EnergyGroups) + check_type('energy groups', energy_groups, openmc.mgxs.EnergyGroups) self._energy_groups = energy_groups def add_xsdata(self, xsdata): @@ -697,16 +1085,12 @@ class MGXSLibraryFile(object): MGXS information to add """ - - # Check the type if not isinstance(xsdata, XSdata): msg = 'Unable to add a non-XSdata "{0}" to the ' \ - 'MGXSLibraryFile'.format(xsdata) + 'MGXSLibrary instance'.format(xsdata) raise ValueError(msg) - - # Make sure energy groups match. if xsdata.energy_groups != self._energy_groups: - msg = 'Energy groups of XSdata do not match that of MGXSLibraryFile!' + msg = 'Energy groups of XSdata do not match that of MGXSLibrary.' raise ValueError(msg) self._xsdatas.append(xsdata) @@ -720,11 +1104,7 @@ class MGXSLibraryFile(object): XSdatas to add """ - - if not isinstance(xsdatas, Iterable): - msg = 'Unable to create OpenMC xsdatas.xml file from "{0}" which ' \ - 'is not iterable'.format(xsdatas) - raise ValueError(msg) + check_iterable_type('xsdatas', xsdatas, XSdata) for xsdata in xsdatas: self.add_xsdata(xsdata) @@ -741,26 +1121,26 @@ class MGXSLibraryFile(object): if not isinstance(xsdata, XSdata): msg = 'Unable to remove a non-XSdata "{0}" from the ' \ - 'XSdatasFile'.format(xsdata) + 'MGXSLibrary instance'.format(xsdata) raise ValueError(msg) self._xsdatas.remove(xsdata) def _create_groups_subelement(self): if self._energy_groups is not None: - element = ET.SubElement(self._cross_sections_file, "groups") + element = ET.SubElement(self._cross_sections_file, 'groups') element.text = str(self._energy_groups.num_groups) def _create_group_structure_subelement(self): if self._energy_groups is not None: element = ET.SubElement(self._cross_sections_file, - "group_structure") + 'group_structure') element.text = ' '.join(map(str, self._energy_groups.group_edges)) def _create_inverse_velocities_subelement(self): if self._inverse_velocities is not None: element = ET.SubElement(self._cross_sections_file, - "inverse_velocities") + 'inverse_velocities') element.text = ' '.join(map(str, self._inverse_velocities)) def _create_xsdata_subelements(self): @@ -768,14 +1148,14 @@ class MGXSLibraryFile(object): xml_element = xsdata._get_xsdata_xml() self._cross_sections_file.append(xml_element) - def export_to_xml(self, filename='mg_cross_sections.xml'): - """Create an mg_cross_sections.xml file that can be used for a + def export_to_xml(self, filename='mgxs.xml'): + """Create an mgxs.xml file that can be used for a simulation. Parameters ---------- filename : str, optional - filename of file, default is mg_cross_sections.xml + filename of file, default is mgxs.xml """ @@ -794,4 +1174,4 @@ class MGXSLibraryFile(object): # Write the XML Tree to the xsdatas.xml file tree = ET.ElementTree(self._cross_sections_file) tree.write(filename, xml_declaration=True, - encoding='utf-8', method="xml") + encoding='utf-8', method='xml') diff --git a/openmc/opencg_compatible.py b/openmc/opencg_compatible.py index d690c2c6a..562fe9cad 100644 --- a/openmc/opencg_compatible.py +++ b/openmc/opencg_compatible.py @@ -393,9 +393,9 @@ def get_compatible_opencg_surfaces(opencg_surface): surfaces = [left, right, bottom, top] elif opencg_surface.type == 'z-squareprism': - x0 = opencg_surface.x0['x0'] - y0 = opencg_surface.y0['y0'] - R = opencg_surface.r['R'] + x0 = opencg_surface.x0 + y0 = opencg_surface.y0 + R = opencg_surface.r # Create a list of the four planes we need left = opencg.XPlane(name=name, boundary=boundary, x0=x0-R) @@ -528,7 +528,7 @@ def get_compatible_opencg_cells(opencg_cell, opencg_surface, halfspace): # Get the compatible Surfaces (XPlanes and YPlanes) compatible_surfaces = get_compatible_opencg_surfaces(opencg_surface) - opencg_cell.removeSurface(opencg_surface) + opencg_cell.remove_surface(opencg_surface) # If Cell is inside SquarePrism, add "inside" of Surface halfspaces if halfspace == -1: @@ -595,7 +595,7 @@ def get_compatible_opencg_cells(opencg_cell, opencg_surface, halfspace): # Remove redundant Surfaces from the Cells for cell in compatible_cells: - cell.removeRedundantSurfaces() + cell.remove_redundant_surfaces() # Return the list of OpenMC compatible OpenCG Cells return compatible_cells @@ -639,7 +639,7 @@ def make_opencg_cells_compatible(opencg_universe): surface, halfspace) # Remove the non-compatible OpenCG Cell from the Universe - opencg_universe.removeCell(opencg_cell) + opencg_universe.remove_cell(opencg_cell) # Add the compatible OpenCG Cells to the Universe opencg_universe.add_cells(cells) diff --git a/openmc/plots.py b/openmc/plots.py index 6e78995f4..9167e55d5 100644 --- a/openmc/plots.py +++ b/openmc/plots.py @@ -2,6 +2,7 @@ from collections import Iterable from numbers import Real, Integral from xml.etree import ElementTree as ET import sys +import warnings import numpy as np @@ -125,7 +126,7 @@ class Plot(object): return self._background @property - def mask_componenets(self): + def mask_components(self): return self._mask_components @property @@ -227,7 +228,7 @@ class Plot(object): self._col_spec = col_spec - @mask_componenets.setter + @mask_components.setter def mask_components(self, mask_components): cv.check_type('plot mask_components', mask_components, Iterable, Integral) for component in mask_components: @@ -401,44 +402,90 @@ class Plot(object): return element -class PlotsFile(object): - """Plots file used for an OpenMC simulation. Corresponds directly to the - plots.xml input file. +class Plots(cv.CheckedList): + """Collection of Plots used for an OpenMC simulation. + + This class corresponds directly to the plots.xml input file. It can be + thought of as a normal Python list where each member is a :class:`Plot`. It + behaves like a list as the following example demonstrates: + + >>> xz_plot = openmc.Plot() + >>> big_plot = openmc.Plot() + >>> small_plot = openmc.Plot() + >>> p = openmc.Plots((xz_plot, big_plot)) + >>> p.append(small_plot) + >>> small_plot = p.pop() + + Parameters + ---------- + plots : Iterable of openmc.Plot + Plots to add to the collection """ - def __init__(self): - # Initialize PlotsFile class attributes - self._plots = [] + def __init__(self, plots=None): + super(Plots, self).__init__(Plot, 'plots collection') self._plots_file = ET.Element("plots") + if plots is not None: + self += plots def add_plot(self, plot): """Add a plot to the file. + .. deprecated:: 0.8 + Use :meth:`Plots.append` instead. + Parameters ---------- plot : openmc.Plot Plot to add """ + warnings.warn("Plots.add_plot(...) has been deprecated and may be " + "removed in a future version. Use Plots.append(...) " + "instead.", DeprecationWarning) + self.append(plot) - if not isinstance(plot, Plot): - msg = 'Unable to add a non-Plot "{0}" to the PlotsFile'.format(plot) - raise ValueError(msg) + def append(self, plot): + """Append plot to collection - self._plots.append(plot) + Parameters + ---------- + plot : openmc.Plot + Plot to append + + """ + super(Plots, self).append(plot) + + def insert(self, index, plot): + """Insert plot before index + + Parameters + ---------- + index : int + Index in list + plot : openmc.Plot + Plot to insert + + """ + super(Plots, self).insert(index, plot) def remove_plot(self, plot): """Remove a plot from the file. + .. deprecated:: 0.8 + Use :meth:`Plots.remove` instead. + Parameters ---------- plot : openmc.Plot Plot to remove """ - - self._plots.remove(plot) + warnings.warn("Plots.remove_plot(...) has been deprecated and may be " + "removed in a future version. Use Plots.remove(...) " + "instead.", DeprecationWarning) + self.remove(plot) def colorize(self, geometry, seed=1): """Generate a consistent color scheme for each domain in each plot. @@ -456,7 +503,7 @@ class PlotsFile(object): """ - for plot in self._plots: + for plot in self: plot.colorize(geometry, seed) @@ -482,11 +529,11 @@ class PlotsFile(object): """ - for plot in self._plots: + for plot in self: plot.highlight_domains(geometry, domains, seed, alpha, background) def _create_plot_subelements(self): - for plot in self._plots: + for plot in self: xml_element = plot.get_plot_xml() if len(plot._name) > 0: diff --git a/openmc/settings.py b/openmc/settings.py index c01f2afd7..bb38ca797 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -16,7 +16,7 @@ if sys.version_info[0] >= 3: basestring = str -class SettingsFile(object): +class Settings(object): """Settings file used for an OpenMC simulation. Corresponds directly to the settings.xml input file. @@ -70,9 +70,10 @@ class SettingsFile(object): deviation. cross_sections : str Indicates the path to an XML cross section listing file (usually named - cross_sections.xml). If it is not set, the :envvar:`CROSS_SECTIONS` - environment variable will be used for continuous-energy calculations - and :envvar:`MG_CROSS_SECTIONS` will be used for multi-group + cross_sections.xml). If it is not set, the + :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. multipole_library : str Indicates the path to a directory containing a windowed multipole diff --git a/openmc/statepoint.py b/openmc/statepoint.py index e11b1c096..beba3ff6b 100644 --- a/openmc/statepoint.py +++ b/openmc/statepoint.py @@ -1,5 +1,8 @@ import sys import re +import os +import warnings + import numpy as np import openmc @@ -14,6 +17,14 @@ class StatePoint(object): of a given batch). Statepoints can be used to analyze tally results as well as restart a simulation. + Parameters + ---------- + filename : str + Path to file to load + autolink : bool, optional + Whether to automatically link in metadata from a summary.h5 + file. Defaults to True. + Attributes ---------- cmfd_on : bool @@ -96,7 +107,7 @@ class StatePoint(object): """ - def __init__(self, filename): + def __init__(self, filename, autolink=True): import h5py self._f = h5py.File(filename, 'r') @@ -119,11 +130,18 @@ class StatePoint(object): # Set flags for what data has been read self._meshes_read = False self._tallies_read = False - self._summary = False + self._summary = None self._global_tallies = None self._sparse = False self._derivs_read = False + # Automatically link in a summary file if one exists + if autolink: + path_summary = os.path.join(os.path.dirname(filename), 'summary.h5') + if os.path.exists(path_summary): + su = openmc.Summary(path_summary) + self.link_with_summary(su) + def close(self): self._f.close() @@ -659,6 +677,11 @@ class StatePoint(object): """ + if self.summary is not None: + warnings.warn('A Summary object has already been linked.', + RuntimeWarning) + return + if not isinstance(summary, openmc.summary.Summary): msg = 'Unable to link statepoint with "{0}" which ' \ 'is not a Summary object'.format(summary) diff --git a/openmc/stats/multivariate.py b/openmc/stats/multivariate.py index 4ce34a071..e4eadd7aa 100644 --- a/openmc/stats/multivariate.py +++ b/openmc/stats/multivariate.py @@ -328,8 +328,8 @@ class Point(Spatial): Parameters ---------- - xyz : Iterable of float - Cartesian coordinates of location + xyz : Iterable of float, optional + Cartesian coordinates of location. Defaults to (0., 0., 0.). Attributes ---------- @@ -338,7 +338,7 @@ class Point(Spatial): """ - def __init__(self, xyz): + def __init__(self, xyz=(0., 0., 0.)): super(Point, self).__init__() self.xyz = xyz diff --git a/openmc/summary.py b/openmc/summary.py index fbe3f90c8..04c37f82d 100644 --- a/openmc/summary.py +++ b/openmc/summary.py @@ -38,8 +38,10 @@ class Summary(object): self._opencg_geometry = None self._read_metadata() + self._read_nuclides() self._read_geometry() self._read_tallies() + self._f.close() @property def openmc_geometry(self): @@ -55,8 +57,8 @@ class Summary(object): def _read_metadata(self): # Read OpenMC version self.version = [self._f['version_major'].value, - self._f['version_minor'].value, - self._f['version_release'].value] + self._f['version_minor'].value, + self._f['version_release'].value] # Read date and time self.date_and_time = self._f['date_and_time'][...] @@ -65,11 +67,23 @@ class Summary(object): self.n_batches = self._f['n_batches'].value self.n_particles = self._f['n_particles'].value - self.n_active = self._f['n_active'].value - self.n_inactive = self._f['n_inactive'].value - self.gen_per_batch = self._f['gen_per_batch'].value + if 'n_inactive' in self._f: + self.n_active = self._f['n_active'].value + self.n_inactive = self._f['n_inactive'].value + self.gen_per_batch = self._f['gen_per_batch'].value self.n_procs = self._f['n_procs'].value + def _read_nuclides(self): + self.nuclides = {} + n_nuclides = self._f['nuclides/n_nuclides_total'].value + names = self._f['nuclides/names'].value + awrs = self._f['nuclides/awrs'].value + zaids = self._f['nuclides/zaids'].value + for n in range(n_nuclides): + name = names[n].decode() + name = name[:name.find('.')] + self.nuclides[name] = (zaids[n], awrs[n]) + def _read_geometry(self): # Read in and initialize the Materials and Geometry self._read_materials() @@ -266,7 +280,8 @@ class Summary(object): rotation = \ self._f['geometry/cells'][key]['rotation'][...] rotation = np.asarray(rotation, dtype=np.int) - cell.rotation = rotation + cell._rotation = rotation + elif fill_type == 'normal': cell.temperature = \ self._f['geometry/cells'][key]['temperature'][...] @@ -381,11 +396,11 @@ class Summary(object): self.lattices[index] = lattice if lattice_type == 'hexagonal': - n_rings = self._f['geometry/lattices'][key]['n_rings'][0] - n_axial = self._f['geometry/lattices'][key]['n_axial'][0] + n_rings = self._f['geometry/lattices'][key]['n_rings'].value + n_axial = self._f['geometry/lattices'][key]['n_axial'].value center = self._f['geometry/lattices'][key]['center'][...] pitch = self._f['geometry/lattices'][key]['pitch'][...] - outer = self._f['geometry/lattices'][key]['outer'][0] + outer = self._f['geometry/lattices'][key]['outer'].value universe_ids = self._f[ 'geometry/lattices'][key]['universes'][...] diff --git a/openmc/surface.py b/openmc/surface.py index 5c8b20856..52f0955f0 100644 --- a/openmc/surface.py +++ b/openmc/surface.py @@ -2,11 +2,12 @@ from abc import ABCMeta from numbers import Real, Integral from xml.etree import ElementTree as ET import sys +from math import sqrt import numpy as np from openmc.checkvalue import check_type, check_value, check_greater_than -from openmc.region import Region +from openmc.region import Region, Intersection if sys.version_info[0] >= 3: basestring = str @@ -23,8 +24,11 @@ def reset_auto_surface_id(): class Surface(object): - """A two-dimensional surface that can be used define regions of space with an - associated boundary condition. + """An implicit surface with an associated boundary condition. + + An implicit surface is defined as the set of zeros of a function of the + three Cartesian coordinates. Surfaces in OpenMC are limited to a set of + algebraic surfaces, i.e., surfaces that are polynomial in x, y, and z. Parameters ---------- @@ -44,19 +48,18 @@ class Surface(object): boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} Boundary condition that defines the behavior for particles hitting the surface. - coeffs : dict + coefficients : dict Dictionary of surface coefficients id : int Unique identifier for the surface name : str Name of the surface type : str - Type of the surface, e.g. 'x-plane' + Type of the surface """ def __init__(self, surface_id=None, boundary_type='transmission', name=''): - # Initialize class attributes self.id = surface_id self.name = name self._type = '' @@ -65,7 +68,7 @@ class Surface(object): # A dictionary of the quadratic surface coefficients # Key - coefficeint name # Value - coefficient value - self._coeffs = {} + self._coefficients = {} # An ordered list of the coefficient names to export to XML in the # proper order @@ -84,12 +87,13 @@ class Surface(object): string += '{0: <16}{1}{2}\n'.format('\tType', '=\t', self._type) string += '{0: <16}{1}{2}\n'.format('\tBoundary', '=\t', self._boundary_type) - coeffs = '{0: <16}'.format('\tCoefficients') + '\n' + coefficients = '{0: <16}'.format('\tCoefficients') + '\n' - for coeff in self._coeffs: - coeffs += '{0: <16}{1}{2}\n'.format(coeff, '=\t', self._coeffs[coeff]) + for coeff in self._coefficients: + coefficients += '{0: <16}{1}{2}\n'.format( + coeff, '=\t', self._coefficients[coeff]) - string += coeffs + string += coefficients return string @@ -110,8 +114,8 @@ class Surface(object): return self._boundary_type @property - def coeffs(self): - return self._coeffs + def coefficients(self): + return self._coefficients @id.setter def id(self, surface_id): @@ -173,8 +177,9 @@ class Surface(object): element.set("name", str(self._name)) element.set("type", self._type) - element.set("boundary", self._boundary_type) - element.set("coeffs", ' '.join([str(self._coeffs.setdefault(key, 0.0)) + if self.boundary_type != 'transmission': + element.set("boundary", self.boundary_type) + element.set("coeffs", ' '.join([str(self._coefficients.setdefault(key, 0.0)) for key in self._coeff_keys])) return element @@ -185,22 +190,22 @@ class Plane(Surface): Parameters ---------- - surface_id : int + surface_id : int, optional Unique identifier for the surface. If not specified, an identifier will automatically be assigned. - boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'}, optional Boundary condition that defines the behavior for particles hitting the surface. Defaults to transmissive boundary condition where particles freely pass through the surface. - A : float - The 'A' parameter for the plane - B : float - The 'B' parameter for the plane - C : float - The 'C' parameter for the plane - D : float - The 'D' parameter for the plane - name : str + A : float, optional + The 'A' parameter for the plane. Defaults to 1. + B : float, optional + The 'B' parameter for the plane. Defaults to 0. + C : float, optional + The 'C' parameter for the plane. Defaults to 0. + D : float, optional + The 'D' parameter for the plane. Defaults to 0. + name : str, optional Name of the plane. If not specified, the name will be the empty string. Attributes @@ -213,68 +218,66 @@ class Plane(Surface): The 'C' parameter for the plane d : float The 'D' parameter for the plane + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + Boundary condition that defines the behavior for particles hitting the + surface. + coefficients : dict + Dictionary of surface coefficients + id : int + Unique identifier for the surface + name : str + Name of the surface + type : str + Type of the surface """ def __init__(self, surface_id=None, boundary_type='transmission', - A=None, B=None, C=None, D=None, name=''): - # Initialize Plane class attributes + A=1., B=0., C=0., D=0., name=''): super(Plane, self).__init__(surface_id, boundary_type, name=name) self._type = 'plane' self._coeff_keys = ['A', 'B', 'C', 'D'] - self._coeffs['A'] = 1. - self._coeffs['B'] = 0. - self._coeffs['C'] = 0. - self._coeffs['D'] = 0. - - if A is not None: - self.a = A - - if B is not None: - self.b = B - - if C is not None: - self.c = C - - if D is not None: - self.d = D + self.a = A + self.b = B + self.c = C + self.d = D @property def a(self): - return self.coeffs['A'] + return self.coefficients['A'] @property def b(self): - return self.coeffs['B'] + return self.coefficients['B'] @property def c(self): - return self.coeffs['C'] + return self.coefficients['C'] @property def d(self): - return self.coeffs['D'] + return self.coefficients['D'] @a.setter def a(self, A): check_type('A coefficient', A, Real) - self._coeffs['A'] = A + self._coefficients['A'] = A @b.setter def b(self, B): check_type('B coefficient', B, Real) - self._coeffs['B'] = B + self._coefficients['B'] = B @c.setter def c(self, C): check_type('C coefficient', C, Real) - self._coeffs['C'] = C + self._coefficients['C'] = C @d.setter def d(self, D): check_type('D coefficient', D, Real) - self._coeffs['D'] = D + self._coefficients['D'] = D class XPlane(Plane): @@ -282,45 +285,52 @@ class XPlane(Plane): Parameters ---------- - surface_id : int + surface_id : int, optional Unique identifier for the surface. If not specified, an identifier will automatically be assigned. - boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'}, optional Boundary condition that defines the behavior for particles hitting the surface. Defaults to transmissive boundary condition where particles freely pass through the surface. - x0 : float - Location of the plane - name : str + x0 : float, optional + Location of the plane. Defaults to 0. + name : str, optional Name of the plane. If not specified, the name will be the empty string. Attributes ---------- x0 : float Location of the plane + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + Boundary condition that defines the behavior for particles hitting the + surface. + coefficients : dict + Dictionary of surface coefficients + id : int + Unique identifier for the surface + name : str + Name of the surface + type : str + Type of the surface """ def __init__(self, surface_id=None, boundary_type='transmission', - x0=None, name=''): - # Initialize XPlane class attributes + x0=0., name=''): super(XPlane, self).__init__(surface_id, boundary_type, name=name) self._type = 'x-plane' self._coeff_keys = ['x0'] - self._coeffs['x0'] = 0. - - if x0 is not None: - self.x0 = x0 + self.x0 = x0 @property def x0(self): - return self.coeffs['x0'] + return self.coefficients['x0'] @x0.setter def x0(self, x0): check_type('x0 coefficient', x0, Real) - self._coeffs['x0'] = x0 + self._coefficients['x0'] = x0 def bounding_box(self, side): """Determine an axis-aligned bounding box. @@ -359,45 +369,53 @@ class YPlane(Plane): Parameters ---------- - surface_id : int + surface_id : int, optional Unique identifier for the surface. If not specified, an identifier will automatically be assigned. - boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'}, optional Boundary condition that defines the behavior for particles hitting the surface. Defaults to transmissive boundary condition where particles freely pass through the surface. - y0 : float + y0 : float, optional Location of the plane - name : str + name : str, optional Name of the plane. If not specified, the name will be the empty string. Attributes ---------- y0 : float Location of the plane + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + Boundary condition that defines the behavior for particles hitting the + surface. + coefficients : dict + Dictionary of surface coefficients + id : int + Unique identifier for the surface + name : str + Name of the surface + type : str + Type of the surface """ def __init__(self, surface_id=None, boundary_type='transmission', - y0=None, name=''): + y0=0., name=''): # Initialize YPlane class attributes super(YPlane, self).__init__(surface_id, boundary_type, name=name) self._type = 'y-plane' self._coeff_keys = ['y0'] - self._coeffs['y0'] = 0. - - if y0 is not None: - self.y0 = y0 + self.y0 = y0 @property def y0(self): - return self.coeffs['y0'] + return self.coefficients['y0'] @y0.setter def y0(self, y0): check_type('y0 coefficient', y0, Real) - self._coeffs['y0'] = y0 + self._coefficients['y0'] = y0 def bounding_box(self, side): """Determine an axis-aligned bounding box. @@ -436,45 +454,53 @@ class ZPlane(Plane): Parameters ---------- - surface_id : int + surface_id : int, optional Unique identifier for the surface. If not specified, an identifier will automatically be assigned. - boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'}, optional Boundary condition that defines the behavior for particles hitting the surface. Defaults to transmissive boundary condition where particles freely pass through the surface. - z0 : float - Location of the plane - name : str + z0 : float, optional + Location of the plane. Defaults to 0. + name : str, optional Name of the plane. If not specified, the name will be the empty string. Attributes ---------- z0 : float Location of the plane + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + Boundary condition that defines the behavior for particles hitting the + surface. + coefficients : dict + Dictionary of surface coefficients + id : int + Unique identifier for the surface + name : str + Name of the surface + type : str + Type of the surface """ def __init__(self, surface_id=None, boundary_type='transmission', - z0=None, name=''): + z0=0., name=''): # Initialize ZPlane class attributes super(ZPlane, self).__init__(surface_id, boundary_type, name=name) self._type = 'z-plane' self._coeff_keys = ['z0'] - self._coeffs['z0'] = 0. - - if z0 is not None: - self.z0 = z0 + self.z0 = z0 @property def z0(self): - return self.coeffs['z0'] + return self.coefficients['z0'] @z0.setter def z0(self, z0): check_type('z0 coefficient', z0, Real) - self._coeffs['z0'] = z0 + self._coefficients['z0'] = z0 def bounding_box(self, side): """Determine an axis-aligned bounding box. @@ -513,16 +539,16 @@ class Cylinder(Surface): Parameters ---------- - surface_id : int + surface_id : int, optional Unique identifier for the surface. If not specified, an identifier will automatically be assigned. - boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'}, optional Boundary condition that defines the behavior for particles hitting the surface. Defaults to transmissive boundary condition where particles freely pass through the surface. - R : float - Radius of the cylinder - name : str + R : float, optional + Radius of the cylinder. Defaults to 1. + name : str, optional Name of the cylinder. If not specified, the name will be the empty string. @@ -530,52 +556,59 @@ class Cylinder(Surface): ---------- r : float Radius of the cylinder + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + Boundary condition that defines the behavior for particles hitting the + surface. + coefficients : dict + Dictionary of surface coefficients + id : int + Unique identifier for the surface + name : str + Name of the surface + type : str + Type of the surface """ __metaclass__ = ABCMeta def __init__(self, surface_id=None, boundary_type='transmission', - R=None, name=''): - # Initialize Cylinder class attributes + R=1., name=''): super(Cylinder, self).__init__(surface_id, boundary_type, name=name) self._coeff_keys = ['R'] - self._coeffs['R'] = 1. - - if R is not None: - self.r = R + self.r = R @property def r(self): - return self.coeffs['R'] + return self.coefficients['R'] @r.setter def r(self, R): check_type('R coefficient', R, Real) - self._coeffs['R'] = R + self._coefficients['R'] = R class XCylinder(Cylinder): - """An infinite cylinder whose length is parallel to the x-axis. This is a - quadratic surface of the form :math:`(y - y_0)^2 + (z - z_0)^2 = R^2`. + """An infinite cylinder whose length is parallel to the x-axis of the form + :math:`(y - y_0)^2 + (z - z_0)^2 = R^2`. Parameters ---------- - surface_id : int + surface_id : int, optional Unique identifier for the surface. If not specified, an identifier will automatically be assigned. - boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'}, optional Boundary condition that defines the behavior for particles hitting the surface. Defaults to transmissive boundary condition where particles freely pass through the surface. - y0 : float - y-coordinate of the center of the cylinder - z0 : float - z-coordinate of the center of the cylinder - R : float - Radius of the cylinder - name : str + y0 : float, optional + y-coordinate of the center of the cylinder. Defaults to 0. + z0 : float, optional + z-coordinate of the center of the cylinder. Defaults to 0. + R : float, optional + Radius of the cylinder. Defaults to 0. + name : str, optional Name of the cylinder. If not specified, the name will be the empty string. @@ -585,42 +618,46 @@ class XCylinder(Cylinder): y-coordinate of the center of the cylinder z0 : float z-coordinate of the center of the cylinder + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + Boundary condition that defines the behavior for particles hitting the + surface. + coefficients : dict + Dictionary of surface coefficients + id : int + Unique identifier for the surface + name : str + Name of the surface + type : str + Type of the surface """ def __init__(self, surface_id=None, boundary_type='transmission', - y0=None, z0=None, R=None, name=''): - # Initialize XCylinder class attributes + y0=0., z0=0., R=1., name=''): super(XCylinder, self).__init__(surface_id, boundary_type, R, name=name) self._type = 'x-cylinder' self._coeff_keys = ['y0', 'z0', 'R'] - self._coeffs['y0'] = 0. - self._coeffs['z0'] = 0. - - if y0 is not None: - self.y0 = y0 - - if z0 is not None: - self.z0 = z0 + self.y0 = y0 + self.z0 = z0 @property def y0(self): - return self.coeffs['y0'] + return self.coefficients['y0'] @property def z0(self): - return self.coeffs['z0'] + return self.coefficients['z0'] @y0.setter def y0(self, y0): check_type('y0 coefficient', y0, Real) - self._coeffs['y0'] = y0 + self._coefficients['y0'] = y0 @z0.setter def z0(self, z0): check_type('z0 coefficient', z0, Real) - self._coeffs['z0'] = z0 + self._coefficients['z0'] = z0 def bounding_box(self, side): """Determine an axis-aligned bounding box. @@ -656,25 +693,25 @@ class XCylinder(Cylinder): class YCylinder(Cylinder): - """An infinite cylinder whose length is parallel to the y-axis. This is a - quadratic surface of the form :math:`(x - x_0)^2 + (z - z_0)^2 = R^2`. + """An infinite cylinder whose length is parallel to the y-axis of the form + :math:`(x - x_0)^2 + (z - z_0)^2 = R^2`. Parameters ---------- - surface_id : int + surface_id : int, optional Unique identifier for the surface. If not specified, an identifier will automatically be assigned. - boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'}, optional Boundary condition that defines the behavior for particles hitting the surface. Defaults to transmissive boundary condition where particles freely pass through the surface. - x0 : float - x-coordinate of the center of the cylinder - z0 : float - z-coordinate of the center of the cylinder - R : float - Radius of the cylinder - name : str + x0 : float, optional + x-coordinate of the center of the cylinder. Defaults to 0. + z0 : float, optional + z-coordinate of the center of the cylinder. Defaults to 0. + R : float, optional + Radius of the cylinder. Defaults to 1. + name : str, optional Name of the cylinder. If not specified, the name will be the empty string. @@ -684,42 +721,46 @@ class YCylinder(Cylinder): x-coordinate of the center of the cylinder z0 : float z-coordinate of the center of the cylinder + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + Boundary condition that defines the behavior for particles hitting the + surface. + coefficients : dict + Dictionary of surface coefficients + id : int + Unique identifier for the surface + name : str + Name of the surface + type : str + Type of the surface """ def __init__(self, surface_id=None, boundary_type='transmission', - x0=None, z0=None, R=None, name=''): - # Initialize YCylinder class attributes + x0=0., z0=0., R=1., name=''): super(YCylinder, self).__init__(surface_id, boundary_type, R, name=name) self._type = 'y-cylinder' self._coeff_keys = ['x0', 'z0', 'R'] - self._coeffs['x0'] = 0. - self._coeffs['z0'] = 0. - - if x0 is not None: - self.x0 = x0 - - if z0 is not None: - self.z0 = z0 + self.x0 = x0 + self.z0 = z0 @property def x0(self): - return self.coeffs['x0'] + return self.coefficients['x0'] @property def z0(self): - return self.coeffs['z0'] + return self.coefficients['z0'] @x0.setter def x0(self, x0): check_type('x0 coefficient', x0, Real) - self._coeffs['x0'] = x0 + self._coefficients['x0'] = x0 @z0.setter def z0(self, z0): check_type('z0 coefficient', z0, Real) - self._coeffs['z0'] = z0 + self._coefficients['z0'] = z0 def bounding_box(self, side): """Determine an axis-aligned bounding box. @@ -755,25 +796,25 @@ class YCylinder(Cylinder): class ZCylinder(Cylinder): - """An infinite cylinder whose length is parallel to the z-axis. This is a - quadratic surface of the form :math:`(x - x_0)^2 + (y - y_0)^2 = R^2`. + """An infinite cylinder whose length is parallel to the z-axis of the form + :math:`(x - x_0)^2 + (y - y_0)^2 = R^2`. Parameters ---------- - surface_id : int + surface_id : int, optional Unique identifier for the surface. If not specified, an identifier will automatically be assigned. - boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'}, optional Boundary condition that defines the behavior for particles hitting the surface. Defaults to transmissive boundary condition where particles freely pass through the surface. - x0 : float - x-coordinate of the center of the cylinder - y0 : float - y-coordinate of the center of the cylinder - R : float - Radius of the cylinder - name : str + x0 : float, optional + x-coordinate of the center of the cylinder. Defaults to 0. + y0 : float, optional + y-coordinate of the center of the cylinder. Defaults to 0. + R : float, optional + Radius of the cylinder. Defaults to 1. + name : str, optional Name of the cylinder. If not specified, the name will be the empty string. @@ -783,42 +824,46 @@ class ZCylinder(Cylinder): x-coordinate of the center of the cylinder y0 : float y-coordinate of the center of the cylinder + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + Boundary condition that defines the behavior for particles hitting the + surface. + coefficients : dict + Dictionary of surface coefficients + id : int + Unique identifier for the surface + name : str + Name of the surface + type : str + Type of the surface """ def __init__(self, surface_id=None, boundary_type='transmission', - x0=None, y0=None, R=None, name=''): - # Initialize ZCylinder class attributes + x0=0., y0=0., R=1., name=''): super(ZCylinder, self).__init__(surface_id, boundary_type, R, name=name) self._type = 'z-cylinder' self._coeff_keys = ['x0', 'y0', 'R'] - self._coeffs['x0'] = 0. - self._coeffs['y0'] = 0. - - if x0 is not None: - self.x0 = x0 - - if y0 is not None: - self.y0 = y0 + self.x0 = x0 + self.y0 = y0 @property def x0(self): - return self.coeffs['x0'] + return self.coefficients['x0'] @property def y0(self): - return self.coeffs['y0'] + return self.coefficients['y0'] @x0.setter def x0(self, x0): check_type('x0 coefficient', x0, Real) - self._coeffs['x0'] = x0 + self._coefficients['x0'] = x0 @y0.setter def y0(self, y0): check_type('y0 coefficient', y0, Real) - self._coeffs['y0'] = y0 + self._coefficients['y0'] = y0 def bounding_box(self, side): """Determine an axis-aligned bounding box. @@ -858,22 +903,22 @@ class Sphere(Surface): Parameters ---------- - surface_id : int + surface_id : int, optional Unique identifier for the surface. If not specified, an identifier will automatically be assigned. - boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'}, optional Boundary condition that defines the behavior for particles hitting the surface. Defaults to transmissive boundary condition where particles freely pass through the surface. - x0 : float - x-coordinate of the center of the sphere - y0 : float - y-coordinate of the center of the sphere - z0 : float - z-coordinate of the center of the sphere - R : float - Radius of the sphere - name : str + x0 : float, optional + x-coordinate of the center of the sphere. Defaults to 0. + y0 : float, optional + y-coordinate of the center of the sphere. Defaults to 0. + z0 : float, optional + z-coordinate of the center of the sphere. Defaults to 0. + R : float, optional + Radius of the sphere. Defaults to 1. + name : str, optional Name of the sphere. If not specified, the name will be the empty string. Attributes @@ -886,68 +931,66 @@ class Sphere(Surface): z-coordinate of the center of the sphere R : float Radius of the sphere + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + Boundary condition that defines the behavior for particles hitting the + surface. + coefficients : dict + Dictionary of surface coefficients + id : int + Unique identifier for the surface + name : str + Name of the surface + type : str + Type of the surface """ def __init__(self, surface_id=None, boundary_type='transmission', - x0=None, y0=None, z0=None, R=None, name=''): - # Initialize Sphere class attributes + x0=0., y0=0., z0=0., R=1., name=''): super(Sphere, self).__init__(surface_id, boundary_type, name=name) self._type = 'sphere' self._coeff_keys = ['x0', 'y0', 'z0', 'R'] - self._coeffs['x0'] = 0. - self._coeffs['y0'] = 0. - self._coeffs['z0'] = 0. - self._coeffs['R'] = 1. - - if x0 is not None: - self.x0 = x0 - - if y0 is not None: - self.y0 = y0 - - if z0 is not None: - self.z0 = z0 - - if R is not None: - self.r = R + self.x0 = x0 + self.y0 = y0 + self.z0 = z0 + self.r = R @property def x0(self): - return self.coeffs['x0'] + return self.coefficients['x0'] @property def y0(self): - return self.coeffs['y0'] + return self.coefficients['y0'] @property def z0(self): - return self.coeffs['z0'] + return self.coefficients['z0'] @property def r(self): - return self.coeffs['R'] + return self.coefficients['R'] @x0.setter def x0(self, x0): check_type('x0 coefficient', x0, Real) - self._coeffs['x0'] = x0 + self._coefficients['x0'] = x0 @y0.setter def y0(self, y0): check_type('y0 coefficient', y0, Real) - self._coeffs['y0'] = y0 + self._coefficients['y0'] = y0 @z0.setter def z0(self, z0): check_type('z0 coefficient', z0, Real) - self._coeffs['z0'] = z0 + self._coefficients['z0'] = z0 @r.setter def r(self, R): check_type('R coefficient', R, Real) - self._coeffs['R'] = R + self._coefficients['R'] = R def bounding_box(self, side): """Determine an axis-aligned bounding box. @@ -988,21 +1031,21 @@ class Cone(Surface): Parameters ---------- - surface_id : int + surface_id : int, optional Unique identifier for the surface. If not specified, an identifier will automatically be assigned. - boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'}, optional Boundary condition that defines the behavior for particles hitting the surface. Defaults to transmissive boundary condition where particles freely pass through the surface. - x0 : float - x-coordinate of the apex + x0 : float, optional + x-coordinate of the apex. Defaults to 0. y0 : float - y-coordinate of the apex + y-coordinate of the apex. Defaults to 0. z0 : float - z-coordinate of the apex + z-coordinate of the apex. Defaults to 0. R2 : float - Parameter related to the aperature + Parameter related to the aperature. Defaults to 1. name : str Name of the cone. If not specified, the name will be the empty string. @@ -1016,69 +1059,67 @@ class Cone(Surface): z-coordinate of the apex R2 : float Parameter related to the aperature + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + Boundary condition that defines the behavior for particles hitting the + surface. + coefficients : dict + Dictionary of surface coefficients + id : int + Unique identifier for the surface + name : str + Name of the surface + type : str + Type of the surface """ __metaclass__ = ABCMeta def __init__(self, surface_id=None, boundary_type='transmission', - x0=None, y0=None, z0=None, R2=None, name=''): - # Initialize Cone class attributes + x0=0., y0=0., z0=0., R2=1., name=''): super(Cone, self).__init__(surface_id, boundary_type, name=name) self._coeff_keys = ['x0', 'y0', 'z0', 'R2'] - self._coeffs['x0'] = 0. - self._coeffs['y0'] = 0. - self._coeffs['z0'] = 0. - self._coeffs['R2'] = 1. - - if x0 is not None: - self.x0 = x0 - - if y0 is not None: - self.y0 = y0 - - if z0 is not None: - self.z0 = z0 - - if R2 is not None: - self.r2 = R2 + self.x0 = x0 + self.y0 = y0 + self.z0 = z0 + self.r2 = R2 @property def x0(self): - return self.coeffs['x0'] + return self.coefficients['x0'] @property def y0(self): - return self.coeffs['y0'] + return self.coefficients['y0'] @property def z0(self): - return self.coeffs['z0'] + return self.coefficients['z0'] @property def r2(self): - return self.coeffs['r2'] + return self.coefficients['r2'] @x0.setter def x0(self, x0): check_type('x0 coefficient', x0, Real) - self._coeffs['x0'] = x0 + self._coefficients['x0'] = x0 @y0.setter def y0(self, y0): check_type('y0 coefficient', y0, Real) - self._coeffs['y0'] = y0 + self._coefficients['y0'] = y0 @z0.setter def z0(self, z0): check_type('z0 coefficient', z0, Real) - self._coeffs['z0'] = z0 + self._coefficients['z0'] = z0 @r2.setter def r2(self, R2): check_type('R^2 coefficient', R2, Real) - self._coeffs['R2'] = R2 + self._coefficients['R2'] = R2 class XCone(Cone): @@ -1087,22 +1128,22 @@ class XCone(Cone): Parameters ---------- - surface_id : int + surface_id : int, optional Unique identifier for the surface. If not specified, an identifier will automatically be assigned. - boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'}, optional Boundary condition that defines the behavior for particles hitting the surface. Defaults to transmissive boundary condition where particles freely pass through the surface. - x0 : float - x-coordinate of the apex - y0 : float - y-coordinate of the apex - z0 : float - z-coordinate of the apex - R2 : float - Parameter related to the aperature - name : str + x0 : float, optional + x-coordinate of the apex. Defaults to 0. + y0 : float, optional + y-coordinate of the apex. Defaults to 0. + z0 : float, optional + z-coordinate of the apex. Defaults to 0. + R2 : float, optional + Parameter related to the aperature. Defaults to 1. + name : str, optional Name of the cone. If not specified, the name will be the empty string. Attributes @@ -1115,12 +1156,22 @@ class XCone(Cone): z-coordinate of the apex R2 : float Parameter related to the aperature + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + Boundary condition that defines the behavior for particles hitting the + surface. + coefficients : dict + Dictionary of surface coefficients + id : int + Unique identifier for the surface + name : str + Name of the surface + type : str + Type of the surface """ def __init__(self, surface_id=None, boundary_type='transmission', - x0=None, y0=None, z0=None, R2=None, name=''): - # Initialize XCone class attributes + x0=0., y0=0., z0=0., R2=1., name=''): super(XCone, self).__init__(surface_id, boundary_type, x0, y0, z0, R2, name=name) @@ -1133,22 +1184,22 @@ class YCone(Cone): Parameters ---------- - surface_id : int + surface_id : int, optional Unique identifier for the surface. If not specified, an identifier will automatically be assigned. - boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'}, optional Boundary condition that defines the behavior for particles hitting the surface. Defaults to transmissive boundary condition where particles freely pass through the surface. - x0 : float - x-coordinate of the apex - y0 : float - y-coordinate of the apex - z0 : float - z-coordinate of the apex - R2 : float - Parameter related to the aperature - name : str + x0 : float, optional + x-coordinate of the apex. Defaults to 0. + y0 : float, optional + y-coordinate of the apex. Defaults to 0. + z0 : float, optional + z-coordinate of the apex. Defaults to 0. + R2 : float, optional + Parameter related to the aperature. Defaults to 1. + name : str, optional Name of the cone. If not specified, the name will be the empty string. Attributes @@ -1161,12 +1212,22 @@ class YCone(Cone): z-coordinate of the apex R2 : float Parameter related to the aperature + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + Boundary condition that defines the behavior for particles hitting the + surface. + coefficients : dict + Dictionary of surface coefficients + id : int + Unique identifier for the surface + name : str + Name of the surface + type : str + Type of the surface """ def __init__(self, surface_id=None, boundary_type='transmission', - x0=None, y0=None, z0=None, R2=None, name=''): - # Initialize YCone class attributes + x0=0., y0=0., z0=0., R2=1., name=''): super(YCone, self).__init__(surface_id, boundary_type, x0, y0, z0, R2, name=name) @@ -1179,22 +1240,22 @@ class ZCone(Cone): Parameters ---------- - surface_id : int + surface_id : int, optional Unique identifier for the surface. If not specified, an identifier will automatically be assigned. - boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'}, optional Boundary condition that defines the behavior for particles hitting the surface. Defaults to transmissive boundary condition where particles freely pass through the surface. - x0 : float - x-coordinate of the apex - y0 : float - y-coordinate of the apex - z0 : float - z-coordinate of the apex - R2 : float - Parameter related to the aperature - name : str + x0 : float, optional + x-coordinate of the apex. Defaults to 0. + y0 : float, optional + y-coordinate of the apex. Defaults to 0. + z0 : float, optional + z-coordinate of the apex. Defaults to 0. + R2 : float, optional + Parameter related to the aperature. Defaults to 1. + name : str, optional Name of the cone. If not specified, the name will be the empty string. Attributes @@ -1207,12 +1268,22 @@ class ZCone(Cone): z-coordinate of the apex R2 : float Parameter related to the aperature + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + Boundary condition that defines the behavior for particles hitting the + surface. + coefficients : dict + Dictionary of surface coefficients + id : int + Unique identifier for the surface + name : str + Name of the surface + type : str + Type of the surface """ def __init__(self, surface_id=None, boundary_type='transmission', - x0=None, y0=None, z0=None, R2=None, name=''): - # Initialize ZCone class attributes + x0=0., y0=0., z0=0., R2=1., name=''): super(ZCone, self).__init__(surface_id, boundary_type, x0, y0, z0, R2, name=name) @@ -1220,151 +1291,148 @@ class ZCone(Cone): class Quadric(Surface): - """A sphere of the form :math:`Ax^2 + By^2 + Cz^2 + Dxy + Eyz + Fxz + Gx + Hy + - Jz + K`. + """A surface of the form :math:`Ax^2 + By^2 + Cz^2 + Dxy + Eyz + Fxz + Gx + Hy + + Jz + K = 0`. Parameters ---------- - surface_id : int + surface_id : int, optional Unique identifier for the surface. If not specified, an identifier will automatically be assigned. - boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'}, optional Boundary condition that defines the behavior for particles hitting the surface. Defaults to transmissive boundary condition where particles freely pass through the surface. - a, b, c, d, e, f, g, h, j, k : float - coefficients for the surface - name : str + a, b, c, d, e, f, g, h, j, k : float, optional + coefficients for the surface. All default to 0. + name : str, optional Name of the sphere. If not specified, the name will be the empty string. Attributes ---------- a, b, c, d, e, f, g, h, j, k : float coefficients for the surface + boundary_type : {'transmission, 'vacuum', 'reflective', 'periodic'} + Boundary condition that defines the behavior for particles hitting the + surface. + coefficients : dict + Dictionary of surface coefficients + id : int + Unique identifier for the surface + name : str + Name of the surface + type : str + Type of the surface """ def __init__(self, surface_id=None, boundary_type='transmission', - a=None, b=None, c=None, d=None, e=None, f=None, g=None, - h=None, j=None, k=None, name=''): - # Initialize Quadric class attributes + a=0., b=0., c=0., d=0., e=0., f=0., g=0., + h=0., j=0., k=0., name=''): super(Quadric, self).__init__(surface_id, boundary_type, name=name) self._type = 'quadric' self._coeff_keys = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k'] - for key in self._coeff_keys: - self._coeffs[key] = 0. - - if a is not None: - self.a = a - if b is not None: - self.b = b - if c is not None: - self.c = c - if d is not None: - self.d = d - if e is not None: - self.e = e - if f is not None: - self.f = f - if g is not None: - self.g = g - if h is not None: - self.h = h - if j is not None: - self.j = j - if k is not None: - self.k = k + self.a = a + self.b = b + self.c = c + self.d = d + self.e = e + self.f = f + self.g = g + self.h = h + self.j = j + self.k = k @property def a(self): - return self.coeffs['a'] + return self.coefficients['a'] @property def b(self): - return self.coeffs['b'] + return self.coefficients['b'] @property def c(self): - return self.coeffs['c'] + return self.coefficients['c'] @property def d(self): - return self.coeffs['d'] + return self.coefficients['d'] @property def e(self): - return self.coeffs['e'] + return self.coefficients['e'] @property def f(self): - return self.coeffs['f'] + return self.coefficients['f'] @property def g(self): - return self.coeffs['g'] + return self.coefficients['g'] @property def h(self): - return self.coeffs['h'] + return self.coefficients['h'] @property def j(self): - return self.coeffs['j'] + return self.coefficients['j'] @property def k(self): - return self.coeffs['k'] + return self.coefficients['k'] @a.setter def a(self, a): check_type('a coefficient', a, Real) - self._coeffs['a'] = a + self._coefficients['a'] = a @b.setter def b(self, b): check_type('b coefficient', b, Real) - self._coeffs['b'] = b + self._coefficients['b'] = b @c.setter def c(self, c): check_type('c coefficient', c, Real) - self._coeffs['c'] = c + self._coefficients['c'] = c @d.setter def d(self, d): check_type('d coefficient', d, Real) - self._coeffs['d'] = d + self._coefficients['d'] = d @e.setter def e(self, e): check_type('e coefficient', e, Real) - self._coeffs['e'] = e + self._coefficients['e'] = e @f.setter def f(self, f): check_type('f coefficient', f, Real) - self._coeffs['f'] = f + self._coefficients['f'] = f @g.setter def g(self, g): check_type('g coefficient', g, Real) - self._coeffs['g'] = g + self._coefficients['g'] = g @h.setter def h(self, h): check_type('h coefficient', h, Real) - self._coeffs['h'] = h + self._coefficients['h'] = h @j.setter def j(self, j): check_type('j coefficient', j, Real) - self._coeffs['j'] = j + self._coefficients['j'] = j @k.setter def k(self, k): check_type('k coefficient', k, Real) - self._coeffs['k'] = k + self._coefficients['k'] = k class Halfspace(Region): @@ -1436,3 +1504,45 @@ class Halfspace(Region): def __str__(self): return '-' + str(self.surface.id) if self.side == '-' \ else str(self.surface.id) + + +def make_hexagon_region(edge_length=1., orientation='y'): + """Create a hexagon region from six surface planes. + + Parameters + ---------- + edge_length : float + Length of a side of the hexagon in cm + orientation : {'x', 'y'} + An 'x' orientation means that two sides of the hexagon are parallel to + the x-axis and a 'y' orientation means that two sides of the hexagon are + parallel to the y-axis. + + Returns + ------- + openmc.Region + The inside of a hexagonal prism + + """ + + l = edge_length + + if orientation == 'y': + right = XPlane(x0=sqrt(3.)/2.*l) + left = XPlane(x0=-sqrt(3.)/2.*l) + c = sqrt(3.)/3. + ur = Plane(A=c, B=1., D=l) # y = -x/sqrt(3) + a + ul = Plane(A=-c, B=1., D=l) # y = x/sqrt(3) + a + lr = Plane(A=-c, B=1., D=-l) # y = x/sqrt(3) - a + ll = Plane(A=c, B=1., D=-l) # y = -x/sqrt(3) - a + return Intersection(-right, +left, -ur, -ul, +lr, +ll) + + elif orientation == 'x': + top = YPlane(y0=sqrt(3.)/2.*l) + bottom = YPlane(y0=-sqrt(3.)/2.*l) + c = sqrt(3.) + ur = Plane(A=c, B=1., D=c*l) # y = -sqrt(3)*(x - a) + lr = Plane(A=-c, B=1., D=-c*l) # y = sqrt(3)*(x + a) + ll = Plane(A=c, B=1., D=-c*l) # y = -sqrt(3)*(x + a) + ul = Plane(A=-c, B=1., D=c*l) # y = sqrt(3)*(x + a) + return Intersection(-top, +bottom, -ur, +lr, +ll, -ul) diff --git a/openmc/tallies.py b/openmc/tallies.py index 5a857d4e1..97b04c093 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -1566,7 +1566,7 @@ class Tally(object): return data def get_pandas_dataframe(self, filters=True, nuclides=True, scores=True, - derivative=True, summary=None, + derivative=True, distribcell_paths=True, float_format='{:.2e}'): """Build a Pandas DataFrame for the Tally data. @@ -1587,12 +1587,11 @@ class Tally(object): Include columns with score bin information (default is True). derivative : bool Include columns with differential tally info (default is True). - summary : None or openmc.Summary - An optional Summary object to be used to construct columns for - distribcell tally filters (default is None). The geometric - information in the Summary object is embedded into a Multi-index - column with a geometric "path" to each distribcell intance. - NOTE: This option requires the OpenCG Python package. + distribcell_paths : bool, optional + Construct columns for distribcell tally filters (default is True). + The geometric information in the Summary object is embedded into a + Multi-index column with a geometric "path" to each distribcell + instance. float_format : str All floats in the DataFrame will be formatted using the given format string before printing. @@ -1618,14 +1617,6 @@ class Tally(object): msg = 'The Tally ID="{0}" has no data to return'.format(self.id) raise KeyError(msg) - # If using Summary, ensure StatePoint.link_with_summary(...) was called - if summary and not self.with_summary: - msg = 'The Tally ID="{0}" has not been linked with the Summary. ' \ - 'Call the StatePoint.link_with_summary(...) method ' \ - 'before using Tally.get_pandas_dataframe(...) with ' \ - 'Summary info'.format(self.id) - raise KeyError(msg) - # Initialize a pandas dataframe for the tally data import pandas as pd df = pd.DataFrame() @@ -1638,7 +1629,8 @@ class Tally(object): # Append each Filter's DataFrame to the overall DataFrame for self_filter in self.filters: - filter_df = self_filter.get_pandas_dataframe(data_size, summary) + filter_df = self_filter.get_pandas_dataframe( + data_size, distribcell_paths) df = pd.concat([df, filter_df], axis=1) # Include DataFrame column for nuclides if user requested it @@ -1667,7 +1659,7 @@ class Tally(object): for score in self.scores: if isinstance(score, (basestring, CrossScore)): - scores.append(score) + scores.append(str(score)) elif isinstance(score, AggregateScore): scores.append(score.name) column_name = '{0}(score)'.format(score.aggregate_op) @@ -3457,66 +3449,108 @@ class Tally(object): return new_tally -class TalliesFile(object): - """Tallies file used for an OpenMC simulation. Corresponds directly to the - tallies.xml input file. +class Tallies(cv.CheckedList): + """Collection of Tallies used for an OpenMC simulation. + + This class corresponds directly to the tallies.xml input file. It can be + thought of as a normal Python list where each member is a :class:`Tally`. It + behaves like a list as the following example demonstrates: + + >>> t1 = openmc.Tally() + >>> t2 = openmc.Tally() + >>> t3 = openmc.Tally() + >>> tallies = openmc.Tallies([t1]) + >>> tallies.append(t2) + >>> tallies += [t3] + + Parameters + ---------- + tallies : Iterable of openmc.Tally + Tallies to add to the collection """ - def __init__(self): - # Initialize TalliesFile class attributes - self._tallies = [] - self._meshes = [] + def __init__(self, tallies=None): + super(Tallies, self).__init__(Tally, 'tallies collection') self._tallies_file = ET.Element("tallies") - - @property - def tallies(self): - return self._tallies - - @property - def meshes(self): - return self._meshes + if tallies is not None: + self += tallies def add_tally(self, tally, merge=False): - """Add a tally to the file + """Append tally to collection + + .. deprecated:: 0.8 + Use :meth:`Tallies.append` instead. Parameters ---------- tally : openmc.Tally - Tally to add to file + Tally to add merge : bool Indicate whether the tally should be merged with an existing tally, if possible. Defaults to False. """ + warnings.warn("Tallies.add_tally(...) has been deprecated and may be " + "removed in a future version. Use Tallies.append(...) " + "instead.", DeprecationWarning) + self.append(tally, merge) + def append(self, tally, merge=False): + """Append tally to collection + + Parameters + ---------- + tally : openmc.Tally + Tally to append + merge : bool + Indicate whether the tally should be merged with an existing tally, + if possible. Defaults to False. + + """ if not isinstance(tally, Tally): - msg = 'Unable to add a non-Tally "{0}" to the TalliesFile'.format(tally) - raise ValueError(msg) + msg = 'Unable to add a non-Tally "{0}" to the Tallies instance'.format(tally) + raise TypeError(msg) if merge: merged = False # Look for a tally to merge with this one - for i, tally2 in enumerate(self._tallies): + for i, tally2 in enumerate(self): # If a mergeable tally is found if tally2.can_merge(tally): # Replace tally 2 with the merged tally merged_tally = tally2.merge(tally) - self._tallies[i] = merged_tally + self[i] = merged_tally merged = True break # If not mergeable tally was found, simply add this tally if not merged: - self._tallies.append(tally) + super(Tallies, self).append(tally) else: - self._tallies.append(tally) + super(Tallies, self).append(tally) + + def insert(self, index, item): + """Insert tally before index + + Parameters + ---------- + index : int + Index in list + item : openmc.Tally + Tally to insert + + """ + super(Tallies, self).insert(index, item) def remove_tally(self, tally): - """Remove a tally from the file + """Remove a tally from the collection + + .. deprecated:: 0.8 + Use :meth:`Tallies.remove` instead. Parameters ---------- @@ -3524,8 +3558,11 @@ class TalliesFile(object): Tally to remove """ + warnings.warn("Tallies.remove_tally(...) has been deprecated and may " + "be removed in a future version. Use Tallies.remove(...) " + "instead.", DeprecationWarning) - self._tallies.remove(tally) + self.remove(tally) def merge_tallies(self): """Merge any mergeable tallies together. Note that n-way merges are @@ -3533,8 +3570,8 @@ class TalliesFile(object): """ - for i, tally1 in enumerate(self._tallies): - for j, tally2 in enumerate(self._tallies): + for i, tally1 in enumerate(self): + for j, tally2 in enumerate(self): # Do not merge the same tally with itself if i == j: continue @@ -3543,10 +3580,10 @@ class TalliesFile(object): if tally1.can_merge(tally2): # Replace tally 1 with the merged tally merged_tally = tally1.merge(tally2) - self._tallies[i] = merged_tally + self[i] = merged_tally # Remove tally 2 since it is no longer needed - self._tallies.pop(j) + self.pop(j) # Continue iterating from the first loop break @@ -3554,6 +3591,10 @@ class TalliesFile(object): def add_mesh(self, mesh): """Add a mesh to the file + .. deprecated:: 0.8 + Meshes that appear in a tally are automatically added to the + collection. + Parameters ---------- mesh : openmc.Mesh @@ -3561,41 +3602,48 @@ class TalliesFile(object): """ - if not isinstance(mesh, Mesh): - msg = 'Unable to add a non-Mesh "{0}" to the TalliesFile'.format(mesh) - raise ValueError(msg) - - self._meshes.append(mesh) + warnings.warn("Tallies.add_mesh(...) has been deprecated and may be " + "removed in a future version. Meshes that appear in a " + "tally are automatically added to the collection.", + DeprecationWarning) def remove_mesh(self, mesh): """Remove a mesh from the file + .. deprecated:: 0.8 + Meshes do not need to be managed explicitly. + Parameters ---------- mesh : openmc.Mesh Mesh to remove from the file """ - - self._meshes.remove(mesh) + warnings.warn("Tallies.remove_mesh(...) has been deprecated and may be " + "removed in a future version. Meshes do not need to be " + "managed explicitly.", DeprecationWarning) def _create_tally_subelements(self): - for tally in self._tallies: + for tally in self: xml_element = tally.get_tally_xml() self._tallies_file.append(xml_element) def _create_mesh_subelements(self): - for mesh in self._meshes: - if len(mesh._name) > 0: - self._tallies_file.append(ET.Comment(mesh._name)) + already_written = set() + for tally in self: + for f in tally.filters: + if f.type == 'mesh' and f.mesh not in already_written: + if len(f.mesh.name) > 0: + self._tallies_file.append(ET.Comment(f.mesh.name)) - xml_element = mesh.get_mesh_xml() - self._tallies_file.append(xml_element) + xml_element = f.mesh.get_mesh_xml() + self._tallies_file.append(xml_element) + already_written.add(f.mesh) def _create_derivative_subelements(self): # Get a list of all derivatives referenced in a tally. derivs = [] - for tally in self._tallies: + for tally in self: deriv = tally.derivative if deriv is not None and deriv not in derivs: derivs.append(deriv) diff --git a/openmc/universe.py b/openmc/universe.py index eb6d13233..770e789da 100644 --- a/openmc/universe.py +++ b/openmc/universe.py @@ -36,6 +36,8 @@ class Universe(object): automatically be assigned name : str, optional Name of the universe. If not specified, the name is the empty string. + cells : Iterable of openmc.Cell, optional + Cells to add to the universe. By default no cells are added. Attributes ---------- @@ -49,7 +51,7 @@ class Universe(object): """ - def __init__(self, universe_id=None, name=''): + def __init__(self, universe_id=None, name='', cells=None): # Initialize Cell class attributes self.id = universe_id self.name = name @@ -61,7 +63,9 @@ class Universe(object): # Keys - Cell IDs # Values - Offsets self._cell_offsets = OrderedDict() - self._num_regions = 0 + + if cells is not None: + self.add_cells(cells) def __eq__(self, other): if not isinstance(other, Universe): @@ -87,8 +91,6 @@ class Universe(object): string += '{0: <16}{1}{2}\n'.format('\tName', '=\t', self._name) string += '{0: <16}{1}{2}\n'.format('\tCells', '=\t', list(self._cells.keys())) - string += '{0: <16}{1}{2}\n'.format('\t# Regions', '=\t', - self._num_regions) return string @property diff --git a/setup.py b/setup.py index e66b0b7a0..770f280ad 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ except ImportError: kwargs = {'name': 'openmc', 'version': '0.7.1', - 'packages': ['openmc', 'openmc.mgxs', 'openmc.stats'], + 'packages': ['openmc', 'openmc.data', 'openmc.mgxs', 'openmc.stats'], 'scripts': glob.glob('scripts/openmc-*'), # Metadata diff --git a/src/ace.F90 b/src/ace.F90 index b401caca8..cbe14b6ae 100644 --- a/src/ace.F90 +++ b/src/ace.F90 @@ -57,7 +57,7 @@ contains character(12) :: alias ! alias of nuclide, e.g. U-235.03c logical :: mp_found ! if windowed multipole libraries were found type(Material), pointer :: mat - type(NuclideCE), pointer :: nuc + type(Nuclide), pointer :: nuc type(SAlphaBeta), pointer :: sab type(SetChar) :: already_read @@ -286,7 +286,7 @@ contains character(10) :: mat ! material identifier character(70) :: comment ! comment for ACE table character(MAX_FILE_LEN) :: filename ! path to ACE cross section library - type(NuclideCE), pointer :: nuc + type(Nuclide), pointer :: nuc type(SAlphaBeta), pointer :: sab type(XsListing), pointer :: listing @@ -492,7 +492,7 @@ contains !=============================================================================== subroutine read_esz(nuc, data_0K) - type(NuclideCE), intent(inout) :: nuc + type(Nuclide), intent(inout) :: nuc logical, intent(in) :: data_0K ! are we reading 0K data? integer :: NE ! number of energy points for total and elastic cross sections @@ -580,7 +580,7 @@ contains !=============================================================================== subroutine read_nu_data(nuc) - type(NuclideCE), intent(inout) :: nuc + type(Nuclide), intent(inout) :: nuc integer :: i, j ! loop index integer :: idx ! index in XSS @@ -795,7 +795,7 @@ contains !=============================================================================== subroutine read_reactions(nuc) - type(NuclideCE), intent(inout) :: nuc + type(Nuclide), intent(inout) :: nuc integer :: i ! loop indices integer :: i_fission ! index in nuc % index_fission @@ -971,7 +971,7 @@ contains !=============================================================================== subroutine read_angular_dist(nuc) - type(NuclideCE), intent(inout) :: nuc + type(Nuclide), intent(inout) :: nuc integer :: LOCB ! location of angular distribution for given MT integer :: NE ! number of incoming energies @@ -1075,7 +1075,7 @@ contains !=============================================================================== subroutine read_energy_dist(nuc) - type(NuclideCE), intent(inout) :: nuc + type(Nuclide), intent(inout) :: nuc integer :: i ! loop index integer :: n @@ -1464,7 +1464,7 @@ contains !=============================================================================== subroutine read_unr_res(nuc) - type(NuclideCE), intent(inout) :: nuc + type(Nuclide), intent(inout) :: nuc integer :: JXS23 ! location of URR data integer :: lc ! locator @@ -1551,7 +1551,7 @@ contains !=============================================================================== subroutine generate_nu_fission(nuc) - type(NuclideCE), intent(inout) :: nuc + type(Nuclide), intent(inout) :: nuc integer :: i ! index on nuclide energy grid diff --git a/src/constants.F90 b/src/constants.F90 index 0998a87c1..33e74e1d9 100644 --- a/src/constants.F90 +++ b/src/constants.F90 @@ -37,7 +37,7 @@ module constants real(8), parameter :: FP_COINCIDENT = 1e-12_8 ! Maximum number of collisions/crossings - integer, parameter :: MAX_EVENTS = 10000 + integer, parameter :: MAX_EVENTS = 1000000 integer, parameter :: MAX_SAMPLE = 100000 ! Maximum number of secondary particles created diff --git a/src/cross_section.F90 b/src/cross_section.F90 index 8d1eb6898..9e725186c 100644 --- a/src/cross_section.F90 +++ b/src/cross_section.F90 @@ -156,8 +156,8 @@ contains integer :: i_high ! upper logarithmic mapping index real(8) :: f ! interp factor on nuclide energy grid real(8) :: sigT, sigA, sigF ! Intermediate multipole variables - type(NuclideCE), pointer :: nuc - type(Material), pointer :: mat + type(Nuclide), pointer :: nuc + type(Material), pointer :: mat ! Set pointer to nuclide and material nuc => nuclides(i_nuclide) @@ -845,9 +845,9 @@ contains !=============================================================================== pure function elastic_xs_0K(E, nuc) result(xs_out) - real(8), intent(in) :: E ! trial energy - type(NuclideCE), intent(in) :: nuc ! target nuclide at temperature - real(8) :: xs_out ! 0K xs at trial energy + real(8), intent(in) :: E ! trial energy + type(Nuclide), intent(in) :: nuc ! target nuclide at temperature + real(8) :: xs_out ! 0K xs at trial energy integer :: i_grid ! index on nuclide energy grid real(8) :: f ! interp factor on nuclide energy grid diff --git a/src/energy_grid.F90 b/src/energy_grid.F90 index 248462f70..66419f83c 100644 --- a/src/energy_grid.F90 +++ b/src/energy_grid.F90 @@ -27,7 +27,7 @@ contains integer :: i ! index in nuclides array integer :: j ! index in materials array type(ListReal) :: list - type(NuclideCE), pointer :: nuc + type(Nuclide), pointer :: nuc type(Material), pointer :: mat call write_message("Creating unionized energy grid...", 5) @@ -70,7 +70,7 @@ contains real(8) :: E_max ! Maximum energy in MeV real(8) :: E_min ! Minimum energy in MeV real(8), allocatable :: umesh(:) ! Equally log-spaced energy grid - type(NuclideCE), pointer :: nuc + type(Nuclide), pointer :: nuc ! Set minimum/maximum energies E_max = energy_max_neutron @@ -179,7 +179,7 @@ contains integer :: index_e ! index on union energy grid real(8) :: union_energy ! energy on union grid real(8) :: energy ! energy on nuclide grid - type(NuclideCE), pointer :: nuc + type(Nuclide), pointer :: nuc type(Material), pointer :: mat do k = 1, n_materials diff --git a/src/global.F90 b/src/global.F90 index bfd993bc5..8d520e2ad 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -5,9 +5,9 @@ module global use constants use dict_header, only: DictCharInt, DictIntInt use geometry_header, only: Cell, Universe, Lattice, LatticeContainer - use macroxs_header, only: MacroXSContainer use material_header, only: Material use mesh_header, only: RegularMesh + use mgxs_header, only: Mgxs, MgxsContainer use nuclide_header use plot_header, only: ObjectPlot use sab_header, only: SAlphaBeta @@ -87,7 +87,7 @@ module global ! CONTINUOUS-ENERGY CROSS SECTION RELATED VARIABLES ! Cross section arrays - type(NuclideCE), allocatable, target :: nuclides(:) ! Nuclide cross-sections + type(Nuclide), allocatable, target :: nuclides(:) ! Nuclide cross-sections type(SAlphaBeta), allocatable, target :: sab_tables(:) ! S(a,b) tables integer :: n_sab_tables ! Number of S(a,b) thermal scattering tables @@ -116,10 +116,10 @@ module global ! MULTI-GROUP CROSS SECTION RELATED VARIABLES ! Cross section arrays - type(NuclideMGContainer), allocatable, target :: nuclides_MG(:) + type(MgxsContainer), allocatable, target :: nuclides_MG(:) ! Cross section caches - type(MacroXSContainer), target, allocatable :: macro_xs(:) + type(MgxsContainer), target, allocatable :: macro_xs(:) ! Number of energy groups integer :: energy_groups diff --git a/src/hdf5_interface.F90 b/src/hdf5_interface.F90 index 14c9b9eb1..0bfe04051 100644 --- a/src/hdf5_interface.F90 +++ b/src/hdf5_interface.F90 @@ -65,14 +65,28 @@ module hdf5_interface module procedure read_complex_2D end interface read_dataset + interface read_attribute + module procedure read_attribute_double + module procedure read_attribute_double_1D + module procedure read_attribute_double_2D + module procedure read_attribute_integer + module procedure read_attribute_integer_1D + module procedure read_attribute_integer_2D + module procedure read_attribute_string + end interface read_attribute + public :: write_dataset public :: read_dataset + public :: read_attribute public :: file_create public :: file_open public :: file_close public :: create_group public :: open_group public :: close_group + public :: open_dataset + public :: close_dataset + public :: get_shape public :: write_attribute_string contains @@ -244,6 +258,44 @@ contains end if end subroutine close_group +!=============================================================================== +! OPEN_DATASET opens an existing HDF5 dataset +!=============================================================================== + + function open_dataset(group_id, name) result(dataset_id) + integer(HID_T), intent(in) :: group_id + character(*), intent(in) :: name ! name of dataset + integer(HID_T) :: dataset_id + + logical :: exists ! does the dataset exist + integer :: hdf5_err ! HDF5 error code + + ! Check if group exists + call h5ltpath_valid_f(group_id, trim(name), .true., exists, hdf5_err) + + ! open group if it exists + if (exists) then + call h5dopen_f(group_id, trim(name), dataset_id, hdf5_err) + else + call fatal_error("The dataset '" // trim(name) // "' does not exist.") + end if + end function open_dataset + +!=============================================================================== +! CLOSE_GROUP closes HDF5 temp_group +!=============================================================================== + + subroutine close_dataset(dataset_id) + integer(HID_T), intent(inout) :: dataset_id + + integer :: hdf5_err ! HDF5 error code + + call h5dclose_f(dataset_id, hdf5_err) + if (hdf5_err < 0) then + call fatal_error("Unable to close HDF5 dataset.") + end if + end subroutine close_dataset + !=============================================================================== ! WRITE_DOUBLE writes double precision scalar data !=============================================================================== @@ -294,19 +346,27 @@ contains ! READ_DOUBLE reads double precision scalar data !=============================================================================== - subroutine read_double(group_id, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - character(*), intent(in) :: name ! name for data - real(8), intent(inout), target :: buffer ! read data to here - logical, intent(in), optional :: indep ! independent I/O + subroutine read_double(buffer, obj_id, name, indep) + real(8), target, intent(inout) :: buffer + integer(HID_T), intent(in) :: obj_id + character(*), optional, intent(in) :: name + logical, optional, intent(in) :: indep ! independent I/O - integer :: hdf5_err - integer :: data_xfer_mode + integer :: hdf5_err + integer :: data_xfer_mode #ifdef PHDF5 integer(HID_T) :: plist ! property list #endif - integer(HID_T) :: dset ! data set handle - type(c_ptr) :: f_ptr + integer(HID_T) :: dset_id + type(c_ptr) :: f_ptr + + ! If 'name' argument is passed, obj_id is interpreted to be a group and + ! 'name' is the name of the dataset we should read from + if (present(name)) then + call h5dopen_f(obj_id, trim(name), dset_id, hdf5_err) + else + dset_id = obj_id + end if ! Set up collective vs. independent I/O data_xfer_mode = H5FD_MPIO_COLLECTIVE_F @@ -314,21 +374,20 @@ contains if (indep) data_xfer_mode = H5FD_MPIO_INDEPENDENT_F end if - call h5dopen_f(group_id, trim(name), dset, hdf5_err) f_ptr = c_loc(buffer) - if (using_mpio_device(group_id)) then + if (using_mpio_device(dset_id)) then #ifdef PHDF5 call h5pcreate_f(H5P_DATASET_XFER_F, plist, hdf5_err) call h5pset_dxpl_mpio_f(plist, data_xfer_mode, hdf5_err) - call h5dread_f(dset, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err, xfer_prp=plist) + call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err, xfer_prp=plist) call h5pclose_f(plist, hdf5_err) #endif else - call h5dread_f(dset, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err) + call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err) end if - call h5dclose_f(dset, hdf5_err) + if (present(name)) call h5dclose_f(dset_id, hdf5_err) end subroutine read_double !=============================================================================== @@ -397,35 +456,46 @@ contains ! READ_DOUBLE_1D reads double precision 1-D array data !=============================================================================== - subroutine read_double_1D(group_id, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - character(*), intent(in) :: name ! name of data - real(8), intent(inout), target :: buffer(:) ! data to write - logical, intent(in), optional :: indep ! independent I/O + subroutine read_double_1D(buffer, obj_id, name, indep) + real(8), target, intent(inout) :: buffer(:) + integer(HID_T), intent(in) :: obj_id + character(*), optional, intent(in) :: name + logical, optional, intent(in) :: indep ! independent I/O + integer :: hdf5_err + integer(HID_T) :: dset_id integer(HSIZE_T) :: dims(1) - dims(:) = shape(buffer) - if (present(indep)) then - call read_double_1D_explicit(group_id, dims, name, buffer, indep) + ! If 'name' argument is passed, obj_id is interpreted to be a group and + ! 'name' is the name of the dataset we should read from + if (present(name)) then + call h5dopen_f(obj_id, trim(name), dset_id, hdf5_err) else - call read_double_1D_explicit(group_id, dims, name, buffer) + dset_id = obj_id end if + + dims(:) = shape(buffer) + + if (present(indep)) then + call read_double_1D_explicit(dset_id, dims, buffer, indep) + else + call read_double_1D_explicit(dset_id, dims, buffer) + end if + + if (present(name)) call h5dclose_f(dset_id, hdf5_err) end subroutine read_double_1D - subroutine read_double_1D_explicit(group_id, dims, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - integer(HSIZE_T), intent(in) :: dims(1) - character(*), intent(in) :: name ! name of data - real(8), intent(inout), target :: buffer(dims(1)) ! data to write - logical, intent(in), optional :: indep ! independent I/O + subroutine read_double_1D_explicit(dset_id, dims, buffer, indep) + integer(HID_T), intent(in) :: dset_id + integer(HSIZE_T), intent(in) :: dims(1) + real(8), target, intent(inout) :: buffer(dims(1)) + logical, optional, intent(in) :: indep ! independent I/O integer :: hdf5_err integer :: data_xfer_mode #ifdef PHDF5 integer(HID_T) :: plist ! property list #endif - integer(HID_T) :: dset ! data set handle type(c_ptr) :: f_ptr ! Set up collective vs. independent I/O @@ -434,21 +504,18 @@ contains if (indep) data_xfer_mode = H5FD_MPIO_INDEPENDENT_F end if - call h5dopen_f(group_id, trim(name), dset, hdf5_err) f_ptr = c_loc(buffer) - if (using_mpio_device(group_id)) then + if (using_mpio_device(dset_id)) then #ifdef PHDF5 call h5pcreate_f(H5P_DATASET_XFER_F, plist, hdf5_err) call h5pset_dxpl_mpio_f(plist, data_xfer_mode, hdf5_err) - call h5dread_f(dset, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err, xfer_prp=plist) + call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err, xfer_prp=plist) call h5pclose_f(plist, hdf5_err) #endif else - call h5dread_f(dset, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err) + call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err) end if - - call h5dclose_f(dset, hdf5_err) end subroutine read_double_1D_explicit !=============================================================================== @@ -517,35 +584,46 @@ contains ! READ_DOUBLE_2D reads double precision 2-D array data !=============================================================================== - subroutine read_double_2D(group_id, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - character(*), intent(in) :: name ! name of data - real(8), intent(inout), target :: buffer(:,:) ! data to write - logical, intent(in), optional :: indep ! independent I/O + subroutine read_double_2D(buffer, obj_id, name, indep) + real(8), target, intent(inout) :: buffer(:,:) + integer(HID_T), intent(in) :: obj_id + character(*), optional, intent(in) :: name + logical, optional, intent(in) :: indep ! independent I/O + integer :: hdf5_err + integer(HID_T) :: dset_id integer(HSIZE_T) :: dims(2) - dims(:) = shape(buffer) - if (present(indep)) then - call read_double_2D_explicit(group_id, dims, name, buffer, indep) + ! If 'name' argument is passed, obj_id is interpreted to be a group and + ! 'name' is the name of the dataset we should read from + if (present(name)) then + call h5dopen_f(obj_id, trim(name), dset_id, hdf5_err) else - call read_double_2D_explicit(group_id, dims, name, buffer) + dset_id = obj_id end if + + dims(:) = shape(buffer) + + if (present(indep)) then + call read_double_2D_explicit(dset_id, dims, buffer, indep) + else + call read_double_2D_explicit(dset_id, dims, buffer) + end if + + if (present(name)) call h5dclose_f(dset_id, hdf5_err) end subroutine read_double_2D - subroutine read_double_2D_explicit(group_id, dims, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - integer(HSIZE_T), intent(in) :: dims(2) - character(*), intent(in) :: name ! name of data - real(8), intent(inout), target :: buffer(dims(1),dims(2)) - logical, intent(in), optional :: indep ! independent I/O + subroutine read_double_2D_explicit(dset_id, dims, buffer, indep) + integer(HID_T), intent(in) :: dset_id + integer(HSIZE_T), intent(in) :: dims(2) + real(8), target, intent(inout) :: buffer(dims(1),dims(2)) + logical, optional, intent(in) :: indep ! independent I/O integer :: hdf5_err integer :: data_xfer_mode #ifdef PHDF5 integer(HID_T) :: plist ! property list #endif - integer(HID_T) :: dset ! data set handle type(c_ptr) :: f_ptr ! Set up collective vs. independent I/O @@ -554,21 +632,18 @@ contains if (indep) data_xfer_mode = H5FD_MPIO_INDEPENDENT_F end if - call h5dopen_f(group_id, trim(name), dset, hdf5_err) f_ptr = c_loc(buffer) - if (using_mpio_device(group_id)) then + if (using_mpio_device(dset_id)) then #ifdef PHDF5 call h5pcreate_f(H5P_DATASET_XFER_F, plist, hdf5_err) call h5pset_dxpl_mpio_f(plist, data_xfer_mode, hdf5_err) - call h5dread_f(dset, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err, xfer_prp=plist) + call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err, xfer_prp=plist) call h5pclose_f(plist, hdf5_err) #endif else - call h5dread_f(dset, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err) + call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err) end if - - call h5dclose_f(dset, hdf5_err) end subroutine read_double_2D_explicit !=============================================================================== @@ -637,35 +712,46 @@ contains ! READ_DOUBLE_3D reads double precision 3-D array data !=============================================================================== - subroutine read_double_3D(group_id, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - character(*), intent(in) :: name ! name of data - real(8), intent(inout), target :: buffer(:,:,:) ! data to write - logical, intent(in), optional :: indep ! independent I/O + subroutine read_double_3D(buffer, obj_id, name, indep) + real(8), target, intent(inout) :: buffer(:,:,:) + integer(HID_T), intent(in) :: obj_id + character(*), optional, intent(in) :: name + logical, optional, intent(in) :: indep ! independent I/O + integer :: hdf5_err + integer(HID_T) :: dset_id integer(HSIZE_T) :: dims(3) - dims(:) = shape(buffer) - if (present(indep)) then - call read_double_3D_explicit(group_id, dims, name, buffer, indep) + ! If 'name' argument is passed, obj_id is interpreted to be a group and + ! 'name' is the name of the dataset we should read from + if (present(name)) then + call h5dopen_f(obj_id, trim(name), dset_id, hdf5_err) else - call read_double_3D_explicit(group_id, dims, name, buffer) + dset_id = obj_id end if + + dims(:) = shape(buffer) + + if (present(indep)) then + call read_double_3D_explicit(dset_id, dims, buffer, indep) + else + call read_double_3D_explicit(dset_id, dims, buffer) + end if + + if (present(name)) call h5dclose_f(dset_id, hdf5_err) end subroutine read_double_3D - subroutine read_double_3D_explicit(group_id, dims, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - integer(HSIZE_T), intent(in) :: dims(3) - character(*), intent(in) :: name ! name of data - real(8), intent(inout), target :: buffer(dims(1),dims(2),dims(3)) - logical, intent(in), optional :: indep ! independent I/O + subroutine read_double_3D_explicit(dset_id, dims, buffer, indep) + integer(HID_T), intent(in) :: dset_id + integer(HSIZE_T), intent(in) :: dims(3) + real(8), target, intent(inout) :: buffer(dims(1),dims(2),dims(3)) + logical, optional, intent(in) :: indep ! independent I/O integer :: hdf5_err integer :: data_xfer_mode #ifdef PHDF5 integer(HID_T) :: plist ! property list #endif - integer(HID_T) :: dset ! data set handle type(c_ptr) :: f_ptr ! Set up collective vs. independent I/O @@ -674,21 +760,18 @@ contains if (indep) data_xfer_mode = H5FD_MPIO_INDEPENDENT_F end if - call h5dopen_f(group_id, trim(name), dset, hdf5_err) f_ptr = c_loc(buffer) - if (using_mpio_device(group_id)) then + if (using_mpio_device(dset_id)) then #ifdef PHDF5 call h5pcreate_f(H5P_DATASET_XFER_F, plist, hdf5_err) call h5pset_dxpl_mpio_f(plist, data_xfer_mode, hdf5_err) - call h5dread_f(dset, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err, xfer_prp=plist) + call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err, xfer_prp=plist) call h5pclose_f(plist, hdf5_err) #endif else - call h5dread_f(dset, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err) + call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err) end if - - call h5dclose_f(dset, hdf5_err) end subroutine read_double_3D_explicit !=============================================================================== @@ -757,35 +840,46 @@ contains ! READ_DOUBLE_4D reads double precision 4-D array data !=============================================================================== - subroutine read_double_4D(group_id, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - character(*), intent(in) :: name ! name of data - real(8), intent(inout), target :: buffer(:,:,:,:) ! data to write - logical, intent(in), optional :: indep ! independent I/O + subroutine read_double_4D(buffer, obj_id, name, indep) + real(8), target, intent(inout) :: buffer(:,:,:,:) + integer(HID_T), intent(in) :: obj_id + character(*), optional, intent(in) :: name + logical, optional, intent(in) :: indep ! independent I/O + integer :: hdf5_err + integer(HID_T) :: dset_id integer(HSIZE_T) :: dims(4) - dims(:) = shape(buffer) - if (present(indep)) then - call read_double_4D_explicit(group_id, dims, name, buffer, indep) + ! If 'name' argument is passed, obj_id is interpreted to be a group and + ! 'name' is the name of the dataset we should read from + if (present(name)) then + call h5dopen_f(obj_id, trim(name), dset_id, hdf5_err) else - call read_double_4D_explicit(group_id, dims, name, buffer) + dset_id = obj_id end if + + dims(:) = shape(buffer) + + if (present(indep)) then + call read_double_4D_explicit(dset_id, dims, buffer, indep) + else + call read_double_4D_explicit(dset_id, dims, buffer) + end if + + if (present(name)) call h5dclose_f(dset_id, hdf5_err) end subroutine read_double_4D - subroutine read_double_4D_explicit(group_id, dims, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - integer(HSIZE_T), intent(in) :: dims(4) - character(*), intent(in) :: name ! name of data - real(8), intent(inout), target :: buffer(dims(1),dims(2),dims(3),dims(4)) - logical, intent(in), optional :: indep ! independent I/O + subroutine read_double_4D_explicit(dset_id, dims, buffer, indep) + integer(HID_T), intent(in) :: dset_id + integer(HSIZE_T), intent(in) :: dims(4) + real(8), target, intent(inout) :: buffer(dims(1),dims(2),dims(3),dims(4)) + logical, optional, intent(in) :: indep ! independent I/O integer :: hdf5_err integer :: data_xfer_mode #ifdef PHDF5 integer(HID_T) :: plist ! property list #endif - integer(HID_T) :: dset ! data set handle type(c_ptr) :: f_ptr ! Set up collective vs. independent I/O @@ -794,21 +888,18 @@ contains if (indep) data_xfer_mode = H5FD_MPIO_INDEPENDENT_F end if - call h5dopen_f(group_id, trim(name), dset, hdf5_err) f_ptr = c_loc(buffer) - if (using_mpio_device(group_id)) then + if (using_mpio_device(dset_id)) then #ifdef PHDF5 call h5pcreate_f(H5P_DATASET_XFER_F, plist, hdf5_err) call h5pset_dxpl_mpio_f(plist, data_xfer_mode, hdf5_err) - call h5dread_f(dset, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err, xfer_prp=plist) + call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err, xfer_prp=plist) call h5pclose_f(plist, hdf5_err) #endif else - call h5dread_f(dset, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err) + call h5dread_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err) end if - - call h5dclose_f(dset, hdf5_err) end subroutine read_double_4D_explicit !=============================================================================== @@ -861,19 +952,27 @@ contains ! READ_INTEGER reads integer precision scalar data !=============================================================================== - subroutine read_integer(group_id, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - character(*), intent(in) :: name ! name for data - integer, intent(inout), target :: buffer ! read data to here - logical, intent(in), optional :: indep ! independent I/O + subroutine read_integer(buffer, obj_id, name, indep) + integer, target, intent(inout) :: buffer + integer(HID_T), intent(in) :: obj_id + character(*), optional, intent(in) :: name + logical, optional, intent(in) :: indep ! independent I/O - integer :: hdf5_err - integer :: data_xfer_mode + integer :: hdf5_err + integer :: data_xfer_mode #ifdef PHDF5 integer(HID_T) :: plist ! property list #endif - integer(HID_T) :: dset ! data set handle - type(c_ptr) :: f_ptr + integer(HID_T) :: dset_id + type(c_ptr) :: f_ptr + + ! If 'name' argument is passed, obj_id is interpreted to be a group and + ! 'name' is the name of the dataset we should read from + if (present(name)) then + call h5dopen_f(obj_id, trim(name), dset_id, hdf5_err) + else + dset_id = obj_id + end if ! Set up collective vs. independent I/O data_xfer_mode = H5FD_MPIO_COLLECTIVE_F @@ -881,21 +980,20 @@ contains if (indep) data_xfer_mode = H5FD_MPIO_INDEPENDENT_F end if - call h5dopen_f(group_id, trim(name), dset, hdf5_err) f_ptr = c_loc(buffer) - if (using_mpio_device(group_id)) then + if (using_mpio_device(dset_id)) then #ifdef PHDF5 call h5pcreate_f(H5P_DATASET_XFER_F, plist, hdf5_err) call h5pset_dxpl_mpio_f(plist, data_xfer_mode, hdf5_err) - call h5dread_f(dset, H5T_NATIVE_INTEGER, f_ptr, hdf5_err, xfer_prp=plist) + call h5dread_f(dset_id, H5T_NATIVE_INTEGER, f_ptr, hdf5_err, xfer_prp=plist) call h5pclose_f(plist, hdf5_err) #endif else - call h5dread_f(dset, H5T_NATIVE_INTEGER, f_ptr, hdf5_err) + call h5dread_f(dset_id, H5T_NATIVE_INTEGER, f_ptr, hdf5_err) end if - call h5dclose_f(dset, hdf5_err) + if (present(name)) call h5dclose_f(dset_id, hdf5_err) end subroutine read_integer !=============================================================================== @@ -964,35 +1062,46 @@ contains ! READ_INTEGER_1D reads integer precision 1-D array data !=============================================================================== - subroutine read_integer_1D(group_id, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - character(*), intent(in) :: name ! name of data - integer, intent(inout), target :: buffer(:) ! data to write - logical, intent(in), optional :: indep ! independent I/O + subroutine read_integer_1D(buffer, obj_id, name, indep) + integer, target, intent(inout) :: buffer(:) + integer(HID_T), intent(in) :: obj_id + character(*), optional, intent(in) :: name + logical, optional, intent(in) :: indep ! independent I/O + integer :: hdf5_err + integer(HID_T) :: dset_id integer(HSIZE_T) :: dims(1) - dims(:) = shape(buffer) - if (present(indep)) then - call read_integer_1D_explicit(group_id, dims, name, buffer, indep) + ! If 'name' argument is passed, obj_id is interpreted to be a group and + ! 'name' is the name of the dataset we should read from + if (present(name)) then + call h5dopen_f(obj_id, trim(name), dset_id, hdf5_err) else - call read_integer_1D_explicit(group_id, dims, name, buffer) + dset_id = obj_id end if + + dims(:) = shape(buffer) + + if (present(indep)) then + call read_integer_1D_explicit(dset_id, dims, buffer, indep) + else + call read_integer_1D_explicit(dset_id, dims, buffer) + end if + + if (present(name)) call h5dclose_f(dset_id, hdf5_err) end subroutine read_integer_1D - subroutine read_integer_1D_explicit(group_id, dims, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - integer(HSIZE_T), intent(in) :: dims(1) - character(*), intent(in) :: name ! name of data - integer, intent(inout), target :: buffer(dims(1)) ! data to write - logical, intent(in), optional :: indep ! independent I/O + subroutine read_integer_1D_explicit(dset_id, dims, buffer, indep) + integer(HID_T), intent(in) :: dset_id + integer(HSIZE_T), intent(in) :: dims(1) + integer, target, intent(inout) :: buffer(dims(1)) + logical, optional, intent(in) :: indep ! independent I/O integer :: hdf5_err integer :: data_xfer_mode #ifdef PHDF5 integer(HID_T) :: plist ! property list #endif - integer(HID_T) :: dset ! data set handle type(c_ptr) :: f_ptr ! Set up collective vs. independent I/O @@ -1001,21 +1110,18 @@ contains if (indep) data_xfer_mode = H5FD_MPIO_INDEPENDENT_F end if - call h5dopen_f(group_id, trim(name), dset, hdf5_err) f_ptr = c_loc(buffer) - if (using_mpio_device(group_id)) then + if (using_mpio_device(dset_id)) then #ifdef PHDF5 call h5pcreate_f(H5P_DATASET_XFER_F, plist, hdf5_err) call h5pset_dxpl_mpio_f(plist, data_xfer_mode, hdf5_err) - call h5dread_f(dset, H5T_NATIVE_INTEGER, f_ptr, hdf5_err, xfer_prp=plist) + call h5dread_f(dset_id, H5T_NATIVE_INTEGER, f_ptr, hdf5_err, xfer_prp=plist) call h5pclose_f(plist, hdf5_err) #endif else - call h5dread_f(dset, H5T_NATIVE_INTEGER, f_ptr, hdf5_err) + call h5dread_f(dset_id, H5T_NATIVE_INTEGER, f_ptr, hdf5_err) end if - - call h5dclose_f(dset, hdf5_err) end subroutine read_integer_1D_explicit !=============================================================================== @@ -1084,35 +1190,46 @@ contains ! READ_INTEGER_2D reads integer precision 2-D array data !=============================================================================== - subroutine read_integer_2D(group_id, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - character(*), intent(in) :: name ! name of data - integer, intent(inout), target :: buffer(:,:) ! data to write - logical, intent(in), optional :: indep ! independent I/O + subroutine read_integer_2D(buffer, obj_id, name, indep) + integer, target, intent(inout) :: buffer(:,:) + integer(HID_T), intent(in) :: obj_id + character(*), optional, intent(in) :: name + logical, optional, intent(in) :: indep ! independent I/O + integer :: hdf5_err + integer(HID_T) :: dset_id integer(HSIZE_T) :: dims(2) - dims(:) = shape(buffer) - if (present(indep)) then - call read_integer_2D_explicit(group_id, dims, name, buffer, indep) + ! If 'name' argument is passed, obj_id is interpreted to be a group and + ! 'name' is the name of the dataset we should read from + if (present(name)) then + call h5dopen_f(obj_id, trim(name), dset_id, hdf5_err) else - call read_integer_2D_explicit(group_id, dims, name, buffer) + dset_id = obj_id end if + + dims(:) = shape(buffer) + + if (present(indep)) then + call read_integer_2D_explicit(dset_id, dims, buffer, indep) + else + call read_integer_2D_explicit(dset_id, dims, buffer) + end if + + if (present(name)) call h5dclose_f(dset_id, hdf5_err) end subroutine read_integer_2D - subroutine read_integer_2D_explicit(group_id, dims, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - integer(HSIZE_T), intent(in) :: dims(2) - character(*), intent(in) :: name ! name of data - integer, intent(inout), target :: buffer(dims(1),dims(2)) - logical, intent(in), optional :: indep ! independent I/O + subroutine read_integer_2D_explicit(dset_id, dims, buffer, indep) + integer(HID_T), intent(in) :: dset_id + integer(HSIZE_T), intent(in) :: dims(2) + integer, target, intent(inout) :: buffer(dims(1),dims(2)) + logical, optional, intent(in) :: indep ! independent I/O integer :: hdf5_err integer :: data_xfer_mode #ifdef PHDF5 integer(HID_T) :: plist ! property list #endif - integer(HID_T) :: dset ! data set handle type(c_ptr) :: f_ptr ! Set up collective vs. independent I/O @@ -1121,21 +1238,18 @@ contains if (indep) data_xfer_mode = H5FD_MPIO_INDEPENDENT_F end if - call h5dopen_f(group_id, trim(name), dset, hdf5_err) f_ptr = c_loc(buffer) - if (using_mpio_device(group_id)) then + if (using_mpio_device(dset_id)) then #ifdef PHDF5 call h5pcreate_f(H5P_DATASET_XFER_F, plist, hdf5_err) call h5pset_dxpl_mpio_f(plist, data_xfer_mode, hdf5_err) - call h5dread_f(dset, H5T_NATIVE_INTEGER, f_ptr, hdf5_err, xfer_prp=plist) + call h5dread_f(dset_id, H5T_NATIVE_INTEGER, f_ptr, hdf5_err, xfer_prp=plist) call h5pclose_f(plist, hdf5_err) #endif else - call h5dread_f(dset, H5T_NATIVE_INTEGER, f_ptr, hdf5_err) + call h5dread_f(dset_id, H5T_NATIVE_INTEGER, f_ptr, hdf5_err) end if - - call h5dclose_f(dset, hdf5_err) end subroutine read_integer_2D_explicit !=============================================================================== @@ -1204,35 +1318,46 @@ contains ! READ_INTEGER_3D reads integer precision 3-D array data !=============================================================================== - subroutine read_integer_3D(group_id, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - character(*), intent(in) :: name ! name of data - integer, intent(inout), target :: buffer(:,:,:) ! data to write - logical, intent(in), optional :: indep ! independent I/O + subroutine read_integer_3D(buffer, obj_id, name, indep) + integer, target, intent(inout) :: buffer(:,:,:) + integer(HID_T), intent(in) :: obj_id + character(*), optional, intent(in) :: name + logical, optional, intent(in) :: indep ! independent I/O + integer :: hdf5_err + integer(HID_T) :: dset_id integer(HSIZE_T) :: dims(3) - dims(:) = shape(buffer) - if (present(indep)) then - call read_integer_3D_explicit(group_id, dims, name, buffer, indep) + ! If 'name' argument is passed, obj_id is interpreted to be a group and + ! 'name' is the name of the dataset we should read from + if (present(name)) then + call h5dopen_f(obj_id, trim(name), dset_id, hdf5_err) else - call read_integer_3D_explicit(group_id, dims, name, buffer) + dset_id = obj_id end if + + dims(:) = shape(buffer) + + if (present(indep)) then + call read_integer_3D_explicit(dset_id, dims, buffer, indep) + else + call read_integer_3D_explicit(dset_id, dims, buffer) + end if + + if (present(name)) call h5dclose_f(dset_id, hdf5_err) end subroutine read_integer_3D - subroutine read_integer_3D_explicit(group_id, dims, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - integer(HSIZE_T), intent(in) :: dims(3) - character(*), intent(in) :: name ! name of data - integer, intent(inout), target :: buffer(dims(1),dims(2),dims(3)) - logical, intent(in), optional :: indep ! independent I/O + subroutine read_integer_3D_explicit(dset_id, dims, buffer, indep) + integer(HID_T), intent(in) :: dset_id + integer(HSIZE_T), intent(in) :: dims(3) + integer, target, intent(inout) :: buffer(dims(1),dims(2),dims(3)) + logical, optional, intent(in) :: indep ! independent I/O integer :: hdf5_err integer :: data_xfer_mode #ifdef PHDF5 integer(HID_T) :: plist ! property list #endif - integer(HID_T) :: dset ! data set handle type(c_ptr) :: f_ptr ! Set up collective vs. independent I/O @@ -1241,21 +1366,18 @@ contains if (indep) data_xfer_mode = H5FD_MPIO_INDEPENDENT_F end if - call h5dopen_f(group_id, trim(name), dset, hdf5_err) f_ptr = c_loc(buffer) - if (using_mpio_device(group_id)) then + if (using_mpio_device(dset_id)) then #ifdef PHDF5 call h5pcreate_f(H5P_DATASET_XFER_F, plist, hdf5_err) call h5pset_dxpl_mpio_f(plist, data_xfer_mode, hdf5_err) - call h5dread_f(dset, H5T_NATIVE_INTEGER, f_ptr, hdf5_err, xfer_prp=plist) + call h5dread_f(dset_id, H5T_NATIVE_INTEGER, f_ptr, hdf5_err, xfer_prp=plist) call h5pclose_f(plist, hdf5_err) #endif else - call h5dread_f(dset, H5T_NATIVE_INTEGER, f_ptr, hdf5_err) + call h5dread_f(dset_id, H5T_NATIVE_INTEGER, f_ptr, hdf5_err) end if - - call h5dclose_f(dset, hdf5_err) end subroutine read_integer_3D_explicit !=============================================================================== @@ -1324,35 +1446,46 @@ contains ! READ_INTEGER_4D reads integer precision 4-D array data !=============================================================================== - subroutine read_integer_4D(group_id, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - character(*), intent(in) :: name ! name of data - integer, intent(inout), target :: buffer(:,:,:,:) ! data to write - logical, intent(in), optional :: indep ! independent I/O + subroutine read_integer_4D(buffer, obj_id, name, indep) + integer, target, intent(inout) :: buffer(:,:,:,:) + integer(HID_T), intent(in) :: obj_id + character(*), optional, intent(in) :: name + logical, optional, intent(in) :: indep ! independent I/O + integer :: hdf5_err + integer(HID_T) :: dset_id integer(HSIZE_T) :: dims(4) - dims(:) = shape(buffer) - if (present(indep)) then - call read_integer_4D_explicit(group_id, dims, name, buffer, indep) + ! If 'name' argument is passed, obj_id is interpreted to be a group and + ! 'name' is the name of the dataset we should read from + if (present(name)) then + call h5dopen_f(obj_id, trim(name), dset_id, hdf5_err) else - call read_integer_4D_explicit(group_id, dims, name, buffer) + dset_id = obj_id end if + + dims(:) = shape(buffer) + + if (present(indep)) then + call read_integer_4D_explicit(dset_id, dims, buffer, indep) + else + call read_integer_4D_explicit(dset_id, dims, buffer) + end if + + if (present(name)) call h5dclose_f(dset_id, hdf5_err) end subroutine read_integer_4D - subroutine read_integer_4D_explicit(group_id, dims, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - integer(HSIZE_T), intent(in) :: dims(4) - character(*), intent(in) :: name ! name of data - integer, intent(inout), target :: buffer(dims(1),dims(2),dims(3),dims(4)) - logical, intent(in), optional :: indep ! independent I/O + subroutine read_integer_4D_explicit(dset_id, dims, buffer, indep) + integer(HID_T), intent(in) :: dset_id + integer(HSIZE_T), intent(in) :: dims(4) + integer, target, intent(inout) :: buffer(dims(1),dims(2),dims(3),dims(4)) + logical, optional, intent(in) :: indep ! independent I/O integer :: hdf5_err integer :: data_xfer_mode #ifdef PHDF5 integer(HID_T) :: plist ! property list #endif - integer(HID_T) :: dset ! data set handle type(c_ptr) :: f_ptr ! Set up collective vs. independent I/O @@ -1361,21 +1494,18 @@ contains if (indep) data_xfer_mode = H5FD_MPIO_INDEPENDENT_F end if - call h5dopen_f(group_id, trim(name), dset, hdf5_err) f_ptr = c_loc(buffer) - if (using_mpio_device(group_id)) then + if (using_mpio_device(dset_id)) then #ifdef PHDF5 call h5pcreate_f(H5P_DATASET_XFER_F, plist, hdf5_err) call h5pset_dxpl_mpio_f(plist, data_xfer_mode, hdf5_err) - call h5dread_f(dset, H5T_NATIVE_INTEGER, f_ptr, hdf5_err, xfer_prp=plist) + call h5dread_f(dset_id, H5T_NATIVE_INTEGER, f_ptr, hdf5_err, xfer_prp=plist) call h5pclose_f(plist, hdf5_err) #endif else - call h5dread_f(dset, H5T_NATIVE_INTEGER, f_ptr, hdf5_err) + call h5dread_f(dset_id, H5T_NATIVE_INTEGER, f_ptr, hdf5_err) end if - - call h5dclose_f(dset, hdf5_err) end subroutine read_integer_4D_explicit !=============================================================================== @@ -1428,19 +1558,27 @@ contains ! READ_LONG reads long integer scalar data !=============================================================================== - subroutine read_long(group_id, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - character(*), intent(in) :: name ! name for data - integer(8), intent(inout), target :: buffer ! read data to here - logical, intent(in), optional :: indep ! independent I/O + subroutine read_long(buffer, obj_id, name, indep) + integer(8), target, intent(inout) :: buffer + integer(HID_T), intent(in) :: obj_id + character(*), optional, intent(in) :: name + logical, optional, intent(in) :: indep ! independent I/O - integer :: hdf5_err - integer :: data_xfer_mode + integer :: hdf5_err + integer :: data_xfer_mode #ifdef PHDF5 integer(HID_T) :: plist ! property list #endif - integer(HID_T) :: dset ! data set handle - type(c_ptr) :: f_ptr + integer(HID_T) :: dset_id + type(c_ptr) :: f_ptr + + ! If 'name' argument is passed, obj_id is interpreted to be a group and + ! 'name' is the name of the dataset we should read from + if (present(name)) then + call h5dopen_f(obj_id, trim(name), dset_id, hdf5_err) + else + dset_id = obj_id + end if ! Set up collective vs. independent I/O data_xfer_mode = H5FD_MPIO_COLLECTIVE_F @@ -1448,21 +1586,20 @@ contains if (indep) data_xfer_mode = H5FD_MPIO_INDEPENDENT_F end if - call h5dopen_f(group_id, trim(name), dset, hdf5_err) f_ptr = c_loc(buffer) - if (using_mpio_device(group_id)) then + if (using_mpio_device(dset_id)) then #ifdef PHDF5 call h5pcreate_f(H5P_DATASET_XFER_F, plist, hdf5_err) call h5pset_dxpl_mpio_f(plist, data_xfer_mode, hdf5_err) - call h5dread_f(dset, hdf5_integer8_t, f_ptr, hdf5_err, xfer_prp=plist) + call h5dread_f(dset_id, hdf5_integer8_t, f_ptr, hdf5_err, xfer_prp=plist) call h5pclose_f(plist, hdf5_err) #endif else - call h5dread_f(dset, hdf5_integer8_t, f_ptr, hdf5_err) + call h5dread_f(dset_id, hdf5_integer8_t, f_ptr, hdf5_err) end if - call h5dclose_f(dset, hdf5_err) + if (present(name)) call h5dclose_f(dset_id, hdf5_err) end subroutine read_long !=============================================================================== @@ -1530,37 +1667,42 @@ contains ! READ_STRING reads string data !=============================================================================== - subroutine read_string(group_id, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - character(*), intent(in) :: name ! name for data - character(*), intent(inout), target :: buffer ! read data to here - logical, intent(in), optional :: indep ! independent I/O + subroutine read_string(buffer, obj_id, name, indep) + character(*), target, intent(inout) :: buffer + integer(HID_T), intent(in) :: obj_id + character(*), optional, intent(in) :: name + logical, optional, intent(in) :: indep ! independent I/O integer :: hdf5_err integer :: data_xfer_mode #ifdef PHDF5 integer(HID_T) :: plist ! property list #endif - integer(HID_T) :: dset ! data set handle - integer(HID_T) :: dspace ! data or file space handle + integer(HID_T) :: dset_id + integer(HID_T) :: space_id integer(HID_T) :: filetype integer(HID_T) :: memtype integer(SIZE_T) :: size integer(SIZE_T) :: n type(c_ptr) :: f_ptr + if (present(name)) then + call h5dopen_f(obj_id, trim(name), dset_id, hdf5_err) + else + dset_id = obj_id + end if + ! Set up collective vs. independent I/O data_xfer_mode = H5FD_MPIO_COLLECTIVE_F if (present(indep)) then if (indep) data_xfer_mode = H5FD_MPIO_INDEPENDENT_F end if - ! Get dataset and dataspace - call h5dopen_f(group_id, trim(name), dset, hdf5_err) - call h5dget_space_f(dset, dspace, hdf5_err) + ! Get dataspace + call h5dget_space_f(dset_id, space_id, hdf5_err) ! Make sure buffer is large enough - call h5dget_type_f(dset, filetype, hdf5_err) + call h5dget_type_f(dset_id, filetype, hdf5_err) call h5tget_size_f(filetype, size, hdf5_err) if (size > len(buffer) + 1) then call fatal_error("Character buffer is not long enough to & @@ -1575,20 +1717,21 @@ contains ! Get pointer to start of string f_ptr = c_loc(buffer(1:1)) - if (using_mpio_device(group_id)) then + if (using_mpio_device(dset_id)) then #ifdef PHDF5 call h5pcreate_f(H5P_DATASET_XFER_F, plist, hdf5_err) call h5pset_dxpl_mpio_f(plist, data_xfer_mode, hdf5_err) - call h5dread_f(dset, memtype, f_ptr, hdf5_err, mem_space_id=dspace, & - xfer_prp=plist) + call h5dread_f(dset_id, memtype, f_ptr, hdf5_err, & + mem_space_id=space_id, xfer_prp=plist) call h5pclose_f(plist, hdf5_err) #endif else - call h5dread_f(dset, memtype, f_ptr, hdf5_err, mem_space_id=dspace) + call h5dread_f(dset_id, memtype, f_ptr, hdf5_err, mem_space_id=space_id) end if - call h5dclose_f(dset, hdf5_err) - call h5sclose_f(dspace, hdf5_err) + if (present(name)) call h5dclose_f(dset_id, hdf5_err) + + call h5sclose_f(space_id, hdf5_err) call h5tclose_f(filetype, hdf5_err) call h5tclose_f(memtype, hdf5_err) end subroutine read_string @@ -1675,36 +1818,45 @@ contains ! READ_STRING_1D reads string 1-D array data !=============================================================================== - subroutine read_string_1D(group_id, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - character(*), intent(in) :: name - character(*), intent(inout), target :: buffer(:) - logical, intent(in), optional :: indep ! independent I/O + subroutine read_string_1D(buffer, obj_id, name, indep) + character(*), target, intent(inout) :: buffer(:) + integer(HID_T), intent(in) :: obj_id + character(*), optional, intent(in) :: name + logical, optional, intent(in) :: indep ! independent I/O + integer :: hdf5_err + integer(HID_T) :: dset_id integer(HSIZE_T) :: dims(1) - dims(:) = shape(buffer) - if (present(indep)) then - call read_string_1D_explicit(group_id, dims, name, buffer, indep) + ! If 'name' argument is passed, obj_id is interpreted to be a group and + ! 'name' is the name of the dataset we should read from + if (present(name)) then + call h5dopen_f(obj_id, trim(name), dset_id, hdf5_err) else - call read_string_1D_explicit(group_id, dims, name, buffer) + dset_id = obj_id + end if + + dims(:) = shape(buffer) + + if (present(indep)) then + call read_string_1D_explicit(dset_id, dims, buffer, indep) + else + call read_string_1D_explicit(dset_id, dims, buffer) end if end subroutine read_string_1D - subroutine read_string_1D_explicit(group_id, dims, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - integer(HSIZE_T), intent(in) :: dims(1) - character(*), intent(in) :: name - character(*), intent(inout), target :: buffer(dims(1)) - logical, intent(in), optional :: indep ! independent I/O + subroutine read_string_1D_explicit(dset_id, dims, buffer, indep) + integer(HID_T), intent(in) :: dset_id + integer(HSIZE_T), intent(in) :: dims(1) + character(*), target, intent(inout) :: buffer(dims(1)) + logical, optional, intent(in) :: indep ! independent I/O integer :: hdf5_err integer :: data_xfer_mode #ifdef PHDF5 integer(HID_T) :: plist ! property list #endif - integer(HID_T) :: dset ! data set handle - integer(HID_T) :: dspace ! data or file space handle + integer(HID_T) :: space_id integer(HID_T) :: filetype integer(HID_T) :: memtype integer(SIZE_T) :: size @@ -1718,11 +1870,10 @@ contains end if ! Get dataset and dataspace - call h5dopen_f(group_id, trim(name), dset, hdf5_err) - call h5dget_space_f(dset, dspace, hdf5_err) + call h5dget_space_f(dset_id, space_id, hdf5_err) ! Make sure buffer is large enough - call h5dget_type_f(dset, filetype, hdf5_err) + call h5dget_type_f(dset_id, filetype, hdf5_err) call h5tget_size_f(filetype, size, hdf5_err) if (size > len(buffer(1)) + 1) then call fatal_error("Character buffer is not long enough to & @@ -1737,20 +1888,19 @@ contains ! Get pointer to start of string f_ptr = c_loc(buffer(1)(1:1)) - if (using_mpio_device(group_id)) then + if (using_mpio_device(dset_id)) then #ifdef PHDF5 call h5pcreate_f(H5P_DATASET_XFER_F, plist, hdf5_err) call h5pset_dxpl_mpio_f(plist, data_xfer_mode, hdf5_err) - call h5dread_f(dset, memtype, f_ptr, hdf5_err, mem_space_id=dspace, & + call h5dread_f(dset_id, memtype, f_ptr, hdf5_err, mem_space_id=space_id, & xfer_prp=plist) call h5pclose_f(plist, hdf5_err) #endif else - call h5dread_f(dset, memtype, f_ptr, hdf5_err, mem_space_id=dspace) + call h5dread_f(dset_id, memtype, f_ptr, hdf5_err, mem_space_id=space_id) end if - call h5dclose_f(dset, hdf5_err) - call h5sclose_f(dspace, hdf5_err) + call h5sclose_f(space_id, hdf5_err) call h5tclose_f(filetype, hdf5_err) call h5tclose_f(memtype, hdf5_err) end subroutine read_string_1D_explicit @@ -1894,6 +2044,254 @@ contains call h5dclose_f(dset, hdf5_err) end subroutine read_tally_result_2D_explicit + subroutine read_attribute_double(buffer, obj_id, name) + real(8), intent(inout), target :: buffer + integer(HID_T), intent(in) :: obj_id + character(*), intent(in) :: name + + integer :: hdf5_err + integer(HID_T) :: attr_id + type(c_ptr) :: f_ptr + + call h5aopen_f(obj_id, trim(name), attr_id, hdf5_err) + f_ptr = c_loc(buffer) + call h5aread_f(attr_id, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err) + call h5aclose_f(attr_id, hdf5_err) + end subroutine read_attribute_double + + subroutine read_attribute_double_1D(buffer, obj_id, name) + real(8), target, allocatable, intent(inout) :: buffer(:) + integer(HID_T), intent(in) :: obj_id + character(*), intent(in) :: name + + integer :: hdf5_err + integer(HID_T) :: space_id + integer(HID_T) :: attr_id + integer(HSIZE_T) :: dims(1) + integer(HSIZE_T) :: maxdims(1) + + call h5aopen_f(obj_id, trim(name), attr_id, hdf5_err) + + if (allocated(buffer)) then + dims(:) = shape(buffer) + else + call h5aget_space_f(attr_id, space_id, hdf5_err) + call h5sget_simple_extent_dims_f(space_id, dims, maxdims, hdf5_err) + allocate(buffer(dims(1))) + call h5sclose_f(space_id, hdf5_err) + end if + + call read_attribute_double_1D_explicit(attr_id, dims, buffer) + call h5aclose_f(attr_id, hdf5_err) + end subroutine read_attribute_double_1D + + subroutine read_attribute_double_1D_explicit(attr_id, dims, buffer) + integer(HID_T), intent(in) :: attr_id + integer(HSIZE_T), intent(in) :: dims(1) + real(8), target, intent(inout) :: buffer(dims(1)) + + integer :: hdf5_err + type(c_ptr) :: f_ptr + + f_ptr = c_loc(buffer) + call h5aread_f(attr_id, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err) + end subroutine read_attribute_double_1D_explicit + + subroutine read_attribute_double_2D(buffer, obj_id, name) + real(8), target, allocatable, intent(inout) :: buffer(:,:) + integer(HID_T), intent(in) :: obj_id + character(*), intent(in) :: name + + integer :: hdf5_err + integer(HID_T) :: space_id + integer(HID_T) :: attr_id + integer(HSIZE_T) :: dims(2) + integer(HSIZE_T) :: maxdims(2) + + call h5aopen_f(obj_id, trim(name), attr_id, hdf5_err) + + if (allocated(buffer)) then + dims(:) = shape(buffer) + else + call h5aget_space_f(attr_id, space_id, hdf5_err) + call h5sget_simple_extent_dims_f(space_id, dims, maxdims, hdf5_err) + allocate(buffer(dims(1), dims(2))) + call h5sclose_f(space_id, hdf5_err) + end if + + call read_attribute_double_2D_explicit(attr_id, dims, buffer) + call h5aclose_f(attr_id, hdf5_err) + end subroutine read_attribute_double_2D + + subroutine read_attribute_double_2D_explicit(attr_id, dims, buffer) + integer(HID_T), intent(in) :: attr_id + integer(HSIZE_T), intent(in) :: dims(2) + real(8), target, intent(inout) :: buffer(dims(1),dims(2)) + + integer :: hdf5_err + type(c_ptr) :: f_ptr + + f_ptr = c_loc(buffer) + call h5aread_f(attr_id, H5T_NATIVE_DOUBLE, f_ptr, hdf5_err) + end subroutine read_attribute_double_2D_explicit + + subroutine read_attribute_integer(buffer, obj_id, name) + integer, intent(inout), target :: buffer + integer(HID_T), intent(in) :: obj_id + character(*), intent(in) :: name + + integer :: hdf5_err + integer(HID_T) :: attr_id + type(c_ptr) :: f_ptr + + call h5aopen_f(obj_id, trim(name), attr_id, hdf5_err) + f_ptr = c_loc(buffer) + call h5aread_f(attr_id, H5T_NATIVE_INTEGER, f_ptr, hdf5_err) + call h5aclose_f(attr_id, hdf5_err) + end subroutine read_attribute_integer + + subroutine read_attribute_integer_1D(buffer, obj_id, name) + integer, target, allocatable, intent(inout) :: buffer(:) + integer(HID_T), intent(in) :: obj_id + character(*), intent(in) :: name + + integer :: hdf5_err + integer(HID_T) :: space_id + integer(HID_T) :: attr_id + integer(HSIZE_T) :: dims(1) + integer(HSIZE_T) :: maxdims(1) + + call h5aopen_f(obj_id, trim(name), attr_id, hdf5_err) + + if (allocated(buffer)) then + dims(:) = shape(buffer) + else + call h5aget_space_f(attr_id, space_id, hdf5_err) + call h5sget_simple_extent_dims_f(space_id, dims, maxdims, hdf5_err) + allocate(buffer(dims(1))) + call h5sclose_f(space_id, hdf5_err) + end if + + call read_attribute_integer_1D_explicit(attr_id, dims, buffer) + call h5aclose_f(attr_id, hdf5_err) + end subroutine read_attribute_integer_1D + + subroutine read_attribute_integer_1D_explicit(attr_id, dims, buffer) + integer(HID_T), intent(in) :: attr_id + integer(HSIZE_T), intent(in) :: dims(1) + integer, target, intent(inout) :: buffer(dims(1)) + + integer :: hdf5_err + type(c_ptr) :: f_ptr + + f_ptr = c_loc(buffer) + call h5aread_f(attr_id, H5T_NATIVE_INTEGER, f_ptr, hdf5_err) + end subroutine read_attribute_integer_1D_explicit + + subroutine read_attribute_integer_2D(buffer, obj_id, name) + integer, target, allocatable, intent(inout) :: buffer(:,:) + integer(HID_T), intent(in) :: obj_id + character(*), intent(in) :: name + + integer :: hdf5_err + integer(HID_T) :: space_id + integer(HID_T) :: attr_id + integer(HSIZE_T) :: dims(2) + integer(HSIZE_T) :: maxdims(2) + + call h5aopen_f(obj_id, trim(name), attr_id, hdf5_err) + + if (allocated(buffer)) then + dims(:) = shape(buffer) + else + call h5aget_space_f(attr_id, space_id, hdf5_err) + call h5sget_simple_extent_dims_f(space_id, dims, maxdims, hdf5_err) + allocate(buffer(dims(1), dims(2))) + call h5sclose_f(space_id, hdf5_err) + end if + + call read_attribute_integer_2D_explicit(attr_id, dims, buffer) + call h5aclose_f(attr_id, hdf5_err) + end subroutine read_attribute_integer_2D + + subroutine read_attribute_integer_2D_explicit(attr_id, dims, buffer) + integer(HID_T), intent(in) :: attr_id + integer(HSIZE_T), intent(in) :: dims(2) + integer, target, intent(inout) :: buffer(dims(1),dims(2)) + + integer :: hdf5_err + type(c_ptr) :: f_ptr + + f_ptr = c_loc(buffer) + call h5aread_f(attr_id, H5T_NATIVE_INTEGER, f_ptr, hdf5_err) + end subroutine read_attribute_integer_2D_explicit + + subroutine read_attribute_string(buffer, obj_id, name) + character(*), intent(inout), target :: buffer ! read data to here + integer(HID_T), intent(in) :: obj_id + character(*), intent(in) :: name ! name for data + + integer :: hdf5_err + integer(HID_T) :: attr_id ! data set handle + integer(HID_T) :: filetype + integer(HID_T) :: memtype + integer(SIZE_T) :: i + integer(SIZE_T) :: size + character(kind=C_CHAR), allocatable, target :: temp_buffer(:) + type(c_ptr) :: f_ptr + + ! Get dataset and dataspace + call h5aopen_f(obj_id, trim(name), attr_id, hdf5_err) + + ! Make sure buffer is large enough + call h5aget_type_f(attr_id, filetype, hdf5_err) + call h5tget_size_f(filetype, size, hdf5_err) + allocate(temp_buffer(size)) + if (size > len(buffer)) then + call fatal_error("Character buffer is not long enough to & + &read HDF5 string.") + end if + + ! Get datatype in memory based on Fortran character + call h5tcopy_f(H5T_C_S1, memtype, hdf5_err) + call h5tset_size_f(memtype, size + 1, hdf5_err) + + ! Get pointer to start of string + f_ptr = c_loc(temp_buffer(1)) + + call h5aread_f(attr_id, memtype, f_ptr, hdf5_err) + buffer = '' + do i = 1, size + buffer(i:i) = temp_buffer(i) + end do + deallocate(temp_buffer) + + call h5aclose_f(attr_id, hdf5_err) + call h5tclose_f(filetype, hdf5_err) + call h5tclose_f(memtype, hdf5_err) + end subroutine read_attribute_string + + subroutine get_shape(obj_id, dims) + integer(HID_T), intent(in) :: obj_id + integer(HSIZE_T), intent(out) :: dims(:) + + integer :: hdf5_err + integer :: type + integer(HID_T) :: space_id + integer(HSIZE_T) :: maxdims(size(dims)) + + call h5iget_type_f(obj_id, type, hdf5_err) + if (type == H5I_DATASET_F) then + call h5dget_space_f(obj_id, space_id, hdf5_err) + call h5sget_simple_extent_dims_f(space_id, dims, maxdims, hdf5_err) + call h5sclose_f(space_id, hdf5_err) + elseif (type == H5I_ATTR_F) then + call h5aget_space_f(obj_id, space_id, hdf5_err) + call h5sget_simple_extent_dims_f(space_id, dims, maxdims, hdf5_err) + call h5sclose_f(space_id, hdf5_err) + end if + end subroutine get_shape + function using_mpio_device(obj_id) result(mpio) integer(HID_T), intent(in) :: obj_id logical :: mpio @@ -1927,28 +2325,40 @@ contains ! the h5py HDF5 python module. !=============================================================================== - subroutine read_complex_2D(group_id, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - character(*), intent(in) :: name ! name of data - complex(8), intent(inout), target :: buffer(:,:) ! data to write - logical, intent(in), optional :: indep ! independent I/O + subroutine read_complex_2D(buffer, obj_id, name, indep) + complex(8), target, intent(inout) :: buffer(:,:) + integer(HID_T), intent(in) :: obj_id + character(*), optional, intent(in) :: name + logical, optional, intent(in) :: indep ! independent I/O + integer :: hdf5_err + integer(HID_T) :: dset_id integer(HSIZE_T) :: dims(2) - dims(:) = shape(buffer) - if (present(indep)) then - call read_complex_2D_explicit(group_id, dims, name, buffer, indep) + ! If 'name' argument is passed, obj_id is interpreted to be a group and + ! 'name' is the name of the dataset we should read from + if (present(name)) then + call h5dopen_f(obj_id, trim(name), dset_id, hdf5_err) else - call read_complex_2D_explicit(group_id, dims, name, buffer) + dset_id = obj_id end if + + dims(:) = shape(buffer) + + if (present(indep)) then + call read_complex_2D_explicit(dset_id, dims, buffer, indep) + else + call read_complex_2D_explicit(dset_id, dims, buffer) + end if + + if (present(name)) call h5dclose_f(dset_id, hdf5_err) end subroutine read_complex_2D - subroutine read_complex_2D_explicit(group_id, dims, name, buffer, indep) - integer(HID_T), intent(in) :: group_id - integer(HSIZE_T), intent(in) :: dims(2) - character(*), intent(in) :: name ! name of data - complex(8), intent(inout), target :: buffer(dims(1),dims(2)) - logical, intent(in), optional :: indep ! independent I/O + subroutine read_complex_2D_explicit(dset_id, dims, buffer, indep) + integer(HID_T), intent(in) :: dset_id + integer(HSIZE_T), intent(in) :: dims(2) + complex(8), target, intent(inout) :: buffer(dims(1), dims(2)) + logical, optional, intent(in) :: indep ! independent I/O real(8), target :: buffer_r(dims(1), dims(2)) real(8), target :: buffer_i(dims(1), dims(2)) @@ -1960,23 +2370,21 @@ contains #ifdef PHDF5 integer(HID_T) :: plist ! property list #endif - integer(HID_T) :: dset ! data set handle type(c_ptr) :: f_ptr_r, f_ptr_i ! Components needed for complex type support integer(HID_T) :: dtype_real integer(HID_T) :: dtype_imag integer(SIZE_T) :: size_double - integer :: error ! Create the complex type - call h5tget_size_f(H5T_NATIVE_DOUBLE, size_double, error) + call h5tget_size_f(H5T_NATIVE_DOUBLE, size_double, hdf5_err) ! Insert the 'r' and 'i' identifiers - call h5tcreate_f(H5T_COMPOUND_F, size_double, dtype_real, error) - call h5tcreate_f(H5T_COMPOUND_F, size_double, dtype_imag, error) - call h5tinsert_f(dtype_real, "r", 0_8, H5T_NATIVE_DOUBLE, error) - call h5tinsert_f(dtype_imag, "i", 0_8, H5T_NATIVE_DOUBLE, error) + call h5tcreate_f(H5T_COMPOUND_F, size_double, dtype_real, hdf5_err) + call h5tcreate_f(H5T_COMPOUND_F, size_double, dtype_imag, hdf5_err) + call h5tinsert_f(dtype_real, "r", 0_8, H5T_NATIVE_DOUBLE, hdf5_err) + call h5tinsert_f(dtype_imag, "i", 0_8, H5T_NATIVE_DOUBLE, hdf5_err) ! Set up collective vs. independent I/O data_xfer_mode = H5FD_MPIO_COLLECTIVE_F @@ -1984,31 +2392,28 @@ contains if (indep) data_xfer_mode = H5FD_MPIO_INDEPENDENT_F end if - call h5dopen_f(group_id, trim(name), dset, hdf5_err) f_ptr_r = c_loc(buffer_r) f_ptr_i = c_loc(buffer_i) - if (using_mpio_device(group_id)) then + if (using_mpio_device(dset_id)) then #ifdef PHDF5 call h5pcreate_f(H5P_DATASET_XFER_F, plist, hdf5_err) call h5pset_dxpl_mpio_f(plist, data_xfer_mode, hdf5_err) - call h5dread_f(dset, dtype_real, f_ptr_r, hdf5_err, xfer_prp=plist) - call h5dread_f(dset, dtype_imag, f_ptr_i, hdf5_err, xfer_prp=plist) + call h5dread_f(dset_id, dtype_real, f_ptr_r, hdf5_err, xfer_prp=plist) + call h5dread_f(dset_id, dtype_imag, f_ptr_i, hdf5_err, xfer_prp=plist) call h5pclose_f(plist, hdf5_err) #endif else - call h5dread_f(dset, dtype_real, f_ptr_r, hdf5_err) - call h5dread_f(dset, dtype_imag, f_ptr_i, hdf5_err) + call h5dread_f(dset_id, dtype_real, f_ptr_r, hdf5_err) + call h5dread_f(dset_id, dtype_imag, f_ptr_i, hdf5_err) end if ! Reconstitute the complex numbers - do i = 1,dims(1) - do j = 1,dims(2) - buffer(i,j) = cmplx(buffer_r(i,j), buffer_i(i,j), kind=8) + do i = 1, dims(1) + do j = 1, dims(2) + buffer(i, j) = cmplx(buffer_r(i,j), buffer_i(i,j), kind=8) end do end do - - call h5dclose_f(dset, hdf5_err) end subroutine read_complex_2D_explicit end module hdf5_interface diff --git a/src/initialize.F90 b/src/initialize.F90 index e3fe3e25d..c74893520 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -378,7 +378,7 @@ contains ! Check what type of file this is file_id = file_open(argv(i), 'r', parallel=.true.) - call read_dataset(file_id, 'filetype', filetype) + call read_dataset(filetype, file_id, 'filetype') call file_close(file_id) ! Set path and flag for type of run @@ -404,7 +404,7 @@ contains ! Check file type is a source file file_id = file_open(argv(i), 'r', parallel=.true.) - call read_dataset(file_id, 'filetype', filetype) + call read_dataset(filetype, file_id, 'filetype') call file_close(file_id) if (filetype /= 'source') then call fatal_error("Second file after restart flag must be a & diff --git a/src/input_xml.F90 b/src/input_xml.F90 index e7d666b4f..7fc1f5a3e 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -92,18 +92,22 @@ contains type(NodeList), pointer :: node_scat_list => null() type(NodeList), pointer :: node_source_list => null() - ! Display output message - call write_message("Reading settings XML file...", 5) - ! Check if settings.xml exists filename = trim(path_input) // "settings.xml" inquire(FILE=filename, EXIST=file_exists) if (.not. file_exists) then - call fatal_error("Settings XML file '" // trim(filename) // "' does not & - &exist! In order to run OpenMC, you first need a set of input files;& - & at a minimum, this includes settings.xml, geometry.xml, and & - &materials.xml. Please consult the user's guide at & - &http://mit-crpg.github.io/openmc for further information.") + if (run_mode /= MODE_PLOTTING) then + call fatal_error("Settings XML file '" // trim(filename) // "' does & + ¬ exist! In order to run OpenMC, you first need a set of input & + &files; at a minimum, this includes settings.xml, geometry.xml, & + &and materials.xml. Please consult the user's guide at & + &http://mit-crpg.github.io/openmc for further information.") + else + ! The settings.xml file is optional if we just want to make a plot. + return + end if + else + call write_message("Reading settings XML file...", 5) end if ! Parse settings.xml file @@ -150,7 +154,7 @@ contains call get_environment_variable("OPENMC_MG_CROSS_SECTIONS", & env_variable) if (len_trim(env_variable) == 0) then - call fatal_error("No cross_sections.xml file was specified in & + call fatal_error("No mgxs.xml file was specified in & &settings.xml or in the OPENMC_MG_CROSS_SECTIONS environment & &variable. OpenMC needs such a file to identify where to & &find the cross section libraries. Please consult the user's & @@ -184,9 +188,12 @@ contains if (check_for_node(doc, "max_order")) then call get_node_value(doc, "max_order", max_order) else - ! Set to default of largest int, which means to use whatever is - ! contained in library - max_order = huge(0) + ! Set to default of largest int - 1, which means to use whatever is + ! contained in library. + ! This is largest int - 1 because for legendre scattering, a value of + ! 1 is added to the order; adding 1 to huge(0) gets you the largest + ! negative integer, which is not what we want. + max_order = huge(0) - 1 end if else max_order = 0 @@ -3011,11 +3018,15 @@ contains allocate(t % filters(j) % real_bins(n_words)) call get_node_array(node_filt, "bins", t % filters(j) % real_bins) + ! We can save tallying time if we know that the tally bins + ! match the energy group structure. In that case, the matching bin + ! index is simply the group (after flipping for the different + ! ordering of the library and tallying systems). if (.not. run_CE) then - if (n_words /= energy_groups + 1) then - t % energy_matches_groups = .false. - else if (all(t % filters(j) % real_bins == energy_bins)) then - t % energy_matches_groups = .false. + if (n_words == energy_groups + 1) then + if (all(t % filters(j) % real_bins == & + energy_bins(energy_groups + 1:1:-1))) & + t % energy_matches_groups = .true. end if end if @@ -3030,11 +3041,15 @@ contains allocate(t % filters(j) % real_bins(n_words)) call get_node_array(node_filt, "bins", t % filters(j) % real_bins) + ! We can save tallying time if we know that the tally bins + ! match the energy group structure. In that case, the matching bin + ! index is simply the group (after flipping for the different + ! ordering of the library and tallying systems). if (.not. run_CE) then - if (n_words /= energy_groups + 1) then - t % energy_matches_groups = .false. - else if (all(t % filters(j) % real_bins == energy_bins)) then - t % energy_matches_groups = .false. + if (n_words == energy_groups + 1) then + if (all(t % filters(j) % real_bins == & + energy_bins(energy_groups + 1:1:-1))) & + t % energyout_matches_groups = .true. end if end if @@ -3494,27 +3509,22 @@ contains case ('nu-scatter') t % score_bins(j) = SCORE_NU_SCATTER - ! Set tally estimator to analog - t % estimator = ESTIMATOR_ANALOG - case ('scatter-n') - if (n_order == 0) then - t % score_bins(j) = SCORE_SCATTER - else - t % score_bins(j) = SCORE_SCATTER_N - ! Set tally estimator to analog + ! Set tally estimator to analog for CE mode + ! (MG mode has all data available without a collision being + ! necessary) + if (run_CE) then t % estimator = ESTIMATOR_ANALOG end if + + case ('scatter-n') + t % score_bins(j) = SCORE_SCATTER_N t % moment_order(j) = n_order + t % estimator = ESTIMATOR_ANALOG case ('nu-scatter-n') - ! Set tally estimator to analog - t % estimator = ESTIMATOR_ANALOG - if (n_order == 0) then - t % score_bins(j) = SCORE_NU_SCATTER - else - t % score_bins(j) = SCORE_NU_SCATTER_N - end if + t % score_bins(j) = SCORE_NU_SCATTER_N t % moment_order(j) = n_order + t % estimator = ESTIMATOR_ANALOG case ('scatter-pn') t % estimator = ESTIMATOR_ANALOG @@ -3553,10 +3563,14 @@ contains call fatal_error("Diffusion score no longer supported for tallies, & &please remove") case ('n1n') - t % score_bins(j) = SCORE_N_1N + if (run_CE) then + t % score_bins(j) = SCORE_N_1N - ! Set tally estimator to analog - t % estimator = ESTIMATOR_ANALOG + ! Set tally estimator to analog + t % estimator = ESTIMATOR_ANALOG + else + call fatal_error("Cannot tally n1n rate in multi-group mode!") + end if case ('n2n', '(n,2n)') t % score_bins(j) = N_2N @@ -4690,23 +4704,24 @@ contains subroutine read_mg_cross_sections_xml() integer :: i ! loop index - logical :: file_exists ! does cross_sections.xml exist? + logical :: file_exists ! does mgxs.xml exist? type(XsListing), pointer :: listing => null() type(Node), pointer :: doc => null() type(Node), pointer :: node_xsdata => null() type(NodeList), pointer :: node_xsdata_list => null() + real(8), allocatable :: rev_energy_bins(:) - ! Check if cross_sections.xml exists + ! Check if mgxs.xml exists inquire(FILE=path_cross_sections, EXIST=file_exists) if (.not. file_exists) then - ! Could not find cross_sections.xml file + ! Could not find mgxs.xml file call fatal_error("Cross sections XML file '" & // trim(path_cross_sections) // "' does not exist!") end if call write_message("Reading cross sections XML file...", 5) - ! Parse cross_sections.xml file + ! Parse mgxs.xml file call open_xmldoc(doc, path_cross_sections) if (check_for_node(doc, "groups")) then @@ -4716,6 +4731,7 @@ contains call fatal_error("groups element must exist!") end if + allocate(rev_energy_bins(energy_groups + 1)) allocate(energy_bins(energy_groups + 1)) if (check_for_node(doc, "group_structure")) then ! Get neutron group structure @@ -4724,6 +4740,9 @@ contains call fatal_error("group_structures element must exist!") end if + ! First reverse the order of energy_groups + energy_bins = energy_bins(energy_groups + 1:1:-1) + allocate(energy_bin_avg(energy_groups)) do i = 1, energy_groups energy_bin_avg(i) = HALF * (energy_bins(i) + energy_bins(i + 1)) @@ -4737,7 +4756,7 @@ contains ! If not given, estimate them by using average energy in group which is ! assumed to be the midpoint do i = 1, energy_groups - inverse_velocities(i) = & + inverse_velocities(i) = ONE / & (sqrt(TWO * energy_bin_avg(i) / (MASS_NEUTRON_MEV)) * & C_LIGHT * 100.0_8) end do @@ -4750,7 +4769,7 @@ contains ! Allocate xs_listings array if (n_listings == 0) then call fatal_error("At least one element must be present in & - &cross_sections.xml file!") + &mgxs.xml file!") else allocate(xs_listings(n_listings)) end if diff --git a/src/macroxs_header.F90 b/src/macroxs_header.F90 deleted file mode 100644 index 2a1234510..000000000 --- a/src/macroxs_header.F90 +++ /dev/null @@ -1,860 +0,0 @@ -module macroxs_header - - use constants, only: MAX_FILE_LEN, ZERO, ONE, TWO, PI - use list_header, only: ListInt - use material_header, only: material - use math, only: calc_pn, calc_rn, expand_harmonic, find_angle - use nuclide_header - use random_lcg, only: prn - use scattdata_header - - implicit none - -!=============================================================================== -! MACROXS_* contains cached macroscopic cross sections for the material a -! particle is traveling through -!=============================================================================== - - type, abstract :: MacroXS - ! Data Order - integer :: order - - contains - procedure(macroxs_init_), deferred :: init ! initializes object - procedure(macroxs_get_xs_), deferred :: get_xs ! Return xs - ! Sample the outgoing energy from a fission event - procedure(macroxs_sample_fission_), deferred :: sample_fission_energy - ! Sample the outgoing energy and angle from a scatter event - procedure(macroxs_sample_scatter_), deferred :: sample_scatter - ! Calculate the material specific MGXS data from the nuclides - procedure(macroxs_calculate_xs_), deferred :: calculate_xs - end type MacroXS - - abstract interface - subroutine macroxs_init_(this, mat, nuclides, groups, get_kfiss, get_fiss, & - max_order, scatt_type, legendre_mu_points, & - error_code, error_text) - import MacroXS, Material, NuclideMGContainer, MAX_LINE_LEN - class(MacroXS), intent(inout) :: this ! The MacroXS to initialize - type(Material), pointer, intent(in) :: mat ! base material - type(NuclideMGContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from - integer, intent(in) :: groups ! Number of E groups - logical, intent(in) :: get_kfiss ! Should we get kfiss data? - logical, intent(in) :: get_fiss ! Should we get fiss data? - integer, intent(in) :: max_order ! Maximum requested order - integer, intent(in) :: scatt_type ! Legendre or Tabular Scatt? - integer, intent(in) :: legendre_mu_points ! Treat as Leg or Tabular? - integer, intent(inout) :: error_code ! Code signifying error - character(MAX_LINE_LEN), intent(inout) :: error_text ! Error message to print - end subroutine macroxs_init_ - - function macroxs_get_xs_(this, g, xstype, gout, uvw) result(xs) - import MacroXS - class(MacroXS), intent(in) :: this ! The MacroXS to initialize - integer, intent(in) :: g ! Incoming Energy group - character(*) , intent(in) :: xstype ! Cross Section Type - integer, optional, intent(in) :: gout ! Outgoing Energy group - real(8), optional, intent(in) :: uvw(3) ! Requested Angle - real(8) :: xs ! Resultant xs - end function macroxs_get_xs_ - - function macroxs_sample_fission_(this, gin, uvw) result(gout) - import MacroXS - class(MacroXS), intent(in) :: this ! Data to work with - integer, intent(in) :: gin ! Incoming energy group - real(8), intent(in) :: uvw(3) ! Particle Direction - integer :: gout ! Sampled outgoing group - - end function macroxs_sample_fission_ - - subroutine macroxs_sample_scatter_(this, uvw, gin, gout, mu, wgt) - import MacroXS - class(MacroXS), intent(in) :: this - real(8), intent(in) :: uvw(3) ! Incoming neutron direction - integer, intent(in) :: gin ! Incoming neutron group - integer, intent(out) :: gout ! Sampled outgoin group - real(8), intent(out) :: mu ! Sampled change in angle - real(8), intent(inout) :: wgt ! Particle weight - end subroutine macroxs_sample_scatter_ - - subroutine macroxs_calculate_xs_(this, gin, uvw, xs) - import MacroXS, MaterialMacroXS - class(MacroXS), intent(in) :: this - integer, intent(in) :: gin ! Incoming neutron group - real(8), intent(in) :: uvw(3) ! Incoming neutron direction - type(MaterialMacroXS), intent(inout) :: xs - end subroutine macroxs_calculate_xs_ - end interface - - type, extends(MacroXS) :: MacroXSIso - ! Microscopic cross sections - real(8), allocatable :: total(:) ! total cross section - real(8), allocatable :: absorption(:) ! absorption cross section - class(ScattData), allocatable :: scatter ! scattering information - real(8), allocatable :: nu_fission(:) ! nu-fission - real(8), allocatable :: k_fission(:) ! kappa-fission - real(8), allocatable :: fission(:) ! fission x/s - real(8), allocatable :: scattxs(:) ! scattering xs - real(8), allocatable :: chi(:,:) ! fission spectra - - contains - procedure :: init => macroxsiso_init ! inits object - procedure :: get_xs => macroxsiso_get_xs ! Returns xs - procedure :: sample_fission_energy => macroxsiso_sample_fission_energy - procedure :: sample_scatter => macroxsiso_sample_scatter - procedure :: calculate_xs => macroxsiso_calculate_xs - end type MacroXSIso - - type, extends(MacroXS) :: MacroXSAngle - ! Macroscopic cross sections - real(8), allocatable :: total(:,:,:) ! total cross section - real(8), allocatable :: absorption(:,:,:) ! absorption cross section - type(ScattDataContainer), allocatable :: scatter(:,:) ! scattering information - real(8), allocatable :: nu_fission(:,:,:) ! nu-fission - real(8), allocatable :: k_fission(:,:,:) ! kappa-fission - real(8), allocatable :: fission(:,:,:) ! fission x/s - real(8), allocatable :: chi(:,:,:,:) ! fission spectra - real(8), allocatable :: scattxs(:,:,:) ! scattering xs - real(8), allocatable :: polar(:) ! polar angles - real(8), allocatable :: azimuthal(:) ! azimuthal angles - - contains - procedure :: init => macroxsangle_init ! inits object - procedure :: get_xs => macroxsangle_get_xs ! Returns xs - procedure :: sample_fission_energy => macroxsangle_sample_fission_energy - procedure :: sample_scatter => macroxsangle_sample_scatter - procedure :: calculate_xs => macroxsangle_calculate_xs - end type MacroXSAngle - -!=============================================================================== -! MACROXSCONTAINER pointer array for storing MacroXS objects. -!=============================================================================== - - type MacroXSContainer - class(MacroXS), allocatable :: obj - end type MacroXSContainer - -contains - -!=============================================================================== -! MACROXS*_INIT sets the MacroXS Data -!=============================================================================== - - subroutine macroxsiso_init(this, mat, nuclides, groups, get_kfiss, get_fiss, & - max_order, scatt_type, legendre_mu_points, error_code, error_text) - class(MacroXSIso), intent(inout) :: this ! The MacroXS to initialize - type(Material), pointer, intent(in) :: mat ! base material - type(NuclideMGContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from - integer, intent(in) :: groups ! Number of E groups - logical, intent(in) :: get_kfiss ! Should we get kfiss data? - logical, intent(in) :: get_fiss ! Should we get fiss data? - integer, intent(in) :: max_order ! Maximum requested order - integer, intent(in) :: scatt_type ! How is data presented - integer, intent(in) :: legendre_mu_points ! Treat as Leg or Tabular? - integer, intent(inout) :: error_code ! Code signifying error - character(MAX_LINE_LEN), intent(inout) :: error_text ! Error message to print - - integer :: i ! loop index over nuclides - integer :: gin, gout ! group indices - real(8) :: atom_density ! atom density of a nuclide - integer :: imu - real(8) :: norm - integer :: mat_max_order, order, l - real(8), allocatable :: temp_mult(:,:) - real(8), allocatable :: temp_energy(:,:) - real(8), allocatable :: scatt_coeffs(:,:,:) - - ! Initialize error data - error_code = 0 - error_text = '' - - ! If we have tabular only data, then make sure all datasets have same size - if (scatt_type == ANGLE_HISTOGRAM) then - ! Check all scattering data of same size - order = nuclides(mat % nuclide(1)) % obj % order - do i = 2, mat % n_nuclides - if (order /= nuclides(mat % nuclide(i)) % obj % order) then - error_code = 1 - error_text = "All Histogram Scattering Entries Must Be Same Length!" - return - end if - end do - ! Ok, got our order, store it - this % order = order - - ! Allocate stuff for later - allocate(scatt_coeffs(order, groups, groups)) - scatt_coeffs = ZERO - allocate(ScattDataHistogram :: this % scatter) - - else if (scatt_type == ANGLE_TABULAR) then - ! Check all scattering data of same size - order = nuclides(mat % nuclide(1)) % obj % order - do i = 2, mat % n_nuclides - if (order /= nuclides(mat % nuclide(i)) % obj % order) then - error_code = 1 - error_text = "All Tabular Scattering Entries Must Be Same Length!" - return - end if - end do - ! Ok, got our order, store it - this % order = order - - ! Allocate stuff for later - allocate(scatt_coeffs(order, groups, groups)) - scatt_coeffs = ZERO - allocate(ScattDataTabular :: this % scatter) - - else if (scatt_type == ANGLE_LEGENDRE) then - ! Otherwise find the maximum scattering order - ! Need to determine the maximum scattering order of all data in this material - mat_max_order = 0 - do i = 1, mat % n_nuclides - if (nuclides(mat % nuclide(i)) % obj % order > mat_max_order) then - mat_max_order = nuclides(mat % nuclide(i)) % obj % order - end if - end do - - ! Now need to compare this material maximum scattering order with - ! the problem wide max scatt order and use whichever is lower - order = min(mat_max_order, max_order) - this % order = order + 1 - - ! Now we can allocate our scatt_coeffs object accordingly - allocate(scatt_coeffs(order + 1, groups, groups)) - scatt_coeffs = ZERO - if (legendre_mu_points == 1) then - allocate(ScattDataLegendre :: this % scatter) - else - allocate(ScattDataTabular :: this % scatter) - end if - end if - - ! Allocate and initialize data within macro_xs(i_mat) object - allocate(this % total(groups)) - this % total = ZERO - allocate(this % absorption(groups)) - this % absorption = ZERO - if (get_fiss) then - allocate(this % fission(groups)) - this % fission = ZERO - end if - if (get_kfiss) then - allocate(this % k_fission(groups)) - this % k_fission = ZERO - end if - allocate(this % nu_fission(groups)) - this % nu_fission = ZERO - allocate(this % chi(groups, groups)) - this % chi = ZERO - allocate(temp_energy(groups, groups)) - temp_energy = ZERO - allocate(temp_mult(groups, groups)) - temp_mult = ZERO - allocate(this % scattxs(groups)) - - ! Add contribution from each nuclide in material - do i = 1, mat % n_nuclides - ! Copy atom density of nuclide in material - atom_density = mat % atom_density(i) - - ! Perform our operations which depend upon the type - select type(nuc => nuclides(mat % nuclide(i)) % obj) - type is (NuclideIso) - - ! Add contributions to total, absorption, and fission data (if necessary) - this % total = this % total + atom_density * nuc % total - this % absorption = this % absorption + & - atom_density * nuc % absorption - if (nuc % fissionable) then - if (allocated(nuc % chi)) then - do gin = 1, groups - do gout = 1, groups - this % chi(gout,gin) = this % chi(gout,gin) + atom_density * & - nuc % chi(gout) * nuc % nu_fission(gin,1) - end do - end do - this % nu_fission = this % nu_fission + atom_density * & - nuc % nu_fission(:,1) - else - this % chi = this % chi + atom_density * nuc % nu_fission - do gin = 1, groups - this % nu_fission(gin) = this % nu_fission(gin) + atom_density * & - sum(nuc % nu_fission(:,gin)) - end do - end if - if (get_fiss) then - this % fission = this % fission + atom_density * nuc % fission - end if - if (get_kfiss) then - this % k_fission = this % k_fission + atom_density * nuc % k_fission - end if - end if - - ! Now time to do the scattering - do gin = 1, groups - do gout = 1, groups - if (scatt_type == ANGLE_HISTOGRAM .or. scatt_type == ANGLE_TABULAR) then - ! Transfer matrix - temp_energy(gout,gin) = temp_energy(gout,gin) + atom_density * & - sum(nuc % scatter(gout,gin,:)) - - ! Determine the angular distribution - do imu = 1, order - scatt_coeffs(imu, gout, gin) = scatt_coeffs(imu, gout, gin) + & - nuc % scatter(gout,gin,imu) * & - atom_density - end do - - else if (scatt_type == ANGLE_LEGENDRE) then - ! Transfer matrix - temp_energy(gout,gin) = temp_energy(gout,gin) + atom_density * & - nuc % scatter(gout,gin,1) - - ! Determine the angular distribution coefficients so we can later - ! expand do the complete distribution - do l = 1, min(nuc % order, order) + 1 - scatt_coeffs(l, gout, gin) = scatt_coeffs(l, gout, gin) + & - nuc % scatter(gout,gin,l) * & - atom_density - end do - - end if - - ! Multiplicity matrix - temp_mult(gout,gin) = temp_mult(gout,gin) + atom_density * & - nuc % mult(gout,gin) - end do - end do - type is (NuclideAngle) - error_code = 1 - error_text = "Invalid Passing of NuclideAngle to MacroXSIso Object" - return - end select - end do - - ! Store the scattering xs - if (scatt_type == ANGLE_HISTOGRAM .or. scatt_type == ANGLE_TABULAR) then - this % scattxs(:) = sum(sum(scatt_coeffs(:,:,:),dim=1),dim=1) - else if (scatt_type == ANGLE_LEGENDRE) then - this % scattxs(:) = sum(scatt_coeffs(1,:,:),dim=1) - end if - - ! Normalize the scatt_coeffs - do gin = 1, groups - do gout = 1, groups - if (scatt_type == ANGLE_HISTOGRAM .or. scatt_type == ANGLE_TABULAR) then - norm = sum(scatt_coeffs(:,gout,gin)) - else if (scatt_type == ANGLE_LEGENDRE) then - norm = scatt_coeffs(1,gout,gin) - end if - if (norm /= ZERO) then - scatt_coeffs(:, gout, gin) = scatt_coeffs(:, gout,gin) / norm - end if - end do - ! Now normalize temp_energy (outgoing scattering energy probabilities) - norm = sum(temp_energy(:,gin)) - if (norm > ZERO) then - temp_energy(:,gin) = temp_energy(:,gin) / norm - end if - end do - - if (scatt_type == ANGLE_LEGENDRE .and. legendre_mu_points /= 1) then - call this % scatter % init(legendre_mu_points, temp_energy, temp_mult, & - scatt_coeffs) - else - call this % scatter % init(this % order, temp_energy, temp_mult, & - scatt_coeffs) - end if - - ! Now normalize chi - if (mat % fissionable) then - do gin = 1, groups - ! Normalize Chi - norm = sum(this % chi(:,gin)) - if (norm > ZERO) then - this % chi(:,gin) = this % chi(:,gin) / norm - end if - end do - end if - - ! Deallocate temporaries for the next material - deallocate(scatt_coeffs, temp_energy, temp_mult) - - end subroutine macroxsiso_init - - subroutine macroxsangle_init(this, mat, nuclides, groups, get_kfiss, get_fiss, & - max_order, scatt_type, legendre_mu_points, error_code, error_text) - class(MacroXSAngle), intent(inout) :: this ! The MacroXS to initialize - type(Material), pointer, intent(in) :: mat ! base material - type(NuclideMGContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from - integer, intent(in) :: groups ! Number of E groups - logical, intent(in) :: get_kfiss ! Should we get kfiss data? - logical, intent(in) :: get_fiss ! Should we get fiss data? - integer, intent(in) :: max_order ! Maximum requested order - integer, intent(in) :: scatt_type ! Legendre or Tabular Scatt? - integer, intent(in) :: legendre_mu_points ! Treat as Leg or Tabular? - integer, intent(inout) :: error_code ! Code signifying error - character(MAX_LINE_LEN), intent(inout) :: error_text ! Error message to print - - integer :: i ! loop index over nuclides - integer :: gin, gout ! group indices - real(8) :: atom_density ! atom density of a nuclide - integer :: ipol, iazi, npol, nazi - integer :: imu - real(8) :: norm - integer :: mat_max_order, order, l - real(8), allocatable :: temp_mult(:,:,:,:) - real(8), allocatable :: temp_energy(:,:,:,:) - real(8), allocatable :: scatt_coeffs(:,:,:,:,:) - - ! Initialize error data - error_code = 0 - error_text = '' - - ! Get the number of each polar and azi angles and make sure all the - ! NuclideAngle types have the same number of these angles - npol = -1 - nazi = -1 - do i = 1, mat % n_nuclides - select type(nuc => nuclides(mat % nuclide(i)) % obj) - type is (NuclideAngle) - if (npol == -1) then - npol = nuc % n_pol - nazi = nuc % n_azi - allocate(this % polar(npol)) - this % polar = nuc % polar - allocate(this % azimuthal(nazi)) - this % azimuthal = nuc % azimuthal - else - if ((npol /= nuc % n_pol) .or. (nazi /= nuc % n_azi)) then - error_code = 1 - error_text = "All Angular Data Must Be Same Length!" - end if - end if - end select - end do - - ! If we have tabular only data, then make sure all datasets have same size - if (scatt_type == ANGLE_HISTOGRAM) then - ! Check all scattering data of same size - order = nuclides(mat % nuclide(1)) % obj % order - do i = 2, mat % n_nuclides - if (order /= nuclides(mat % nuclide(i)) % obj % order) then - error_code = 1 - error_text = "All Histogram Scattering Entries Must Be Same Length!" - return - end if - end do - ! Ok, got our order, store it - this % order = order - - ! Allocate stuff for later - allocate(scatt_coeffs(order, groups, groups, nazi, npol)) - scatt_coeffs = ZERO - allocate(this % scatter(nazi, npol)) - do ipol = 1, npol - do iazi = 1, nazi - allocate(ScattDataHistogram :: this % scatter(iazi, ipol) % obj) - end do - end do - - else if (scatt_type == ANGLE_TABULAR) then - ! Check all scattering data of same size - order = nuclides(mat % nuclide(1)) % obj % order - do i = 2, mat % n_nuclides - if (order /= nuclides(mat % nuclide(i)) % obj % order) then - error_code = 1 - error_text = "All Tabular Scattering Entries Must Be Same Length!" - return - end if - end do - ! Ok, got our order, store it - this % order = order - - ! Allocate stuff for later - allocate(scatt_coeffs(order, groups, groups, nazi, npol)) - scatt_coeffs = ZERO - allocate(this % scatter(nazi, npol)) - do ipol = 1, npol - do iazi = 1, nazi - allocate(ScattDataTabular :: this % scatter(iazi, ipol) % obj) - end do - end do - - else if (scatt_type == ANGLE_LEGENDRE) then - ! Otherwise find the maximum scattering order - ! Need to determine the maximum scattering order of all data in this material - mat_max_order = 0 - do i = 1, mat % n_nuclides - if (nuclides(mat % nuclide(i)) % obj % order > mat_max_order) then - mat_max_order = nuclides(mat % nuclide(i)) % obj % order - end if - end do - - ! Now need to compare this material maximum scattering order with - ! the problem wide max scatt order and use whichever is lower - order = min(mat_max_order, max_order) - this % order = order + 1 - - ! Now we can allocate our scatt_coeffs object accordingly - allocate(scatt_coeffs(order + 1, groups, groups, nazi, npol)) - scatt_coeffs = ZERO - allocate(this % scatter(nazi, npol)) - do ipol = 1, npol - do iazi = 1, nazi - if (legendre_mu_points == 1) then - allocate(ScattDataLegendre :: this % scatter(iazi, ipol) % obj) - else - allocate(ScattDataTabular :: this % scatter(iazi, ipol) % obj) - end if - end do - end do - end if - - ! Allocate and initialize data within macro_xs(i_mat) object - allocate(this % total(groups,nazi,npol)) - this % total = ZERO - allocate(this % absorption(groups,nazi,npol)) - this % absorption = ZERO - if (get_fiss) then - allocate(this % fission(groups,nazi,npol)) - this % fission = ZERO - end if - if (get_kfiss) then - allocate(this % k_fission(groups,nazi,npol)) - this % k_fission = ZERO - end if - allocate(this % nu_fission(groups,nazi,npol)) - this % nu_fission = ZERO - allocate(this % chi(groups, groups, nazi, npol)) - this % chi = ZERO - allocate(temp_energy(groups,groups,nazi,npol)) - temp_energy = ZERO - allocate(temp_mult(groups,groups,nazi,npol)) - temp_mult = ZERO - allocate(this % scattxs(groups,nazi,npol)) - - ! Add contribution from each nuclide in material - do i = 1, mat % n_nuclides - ! Copy atom density of nuclide in material - atom_density = mat % atom_density(i) - - ! Perform our operations which depend upon the type - select type(nuc => nuclides(mat % nuclide(i)) % obj) - type is (NuclideIso) - error_code = 1 - error_text = "Invalid Passing of NuclideIso to MacroXSAngle Object" - return - type is (NuclideAngle) - ! Add contributions to total, absorption, and fission data (if necessary) - this % total = this % total + atom_density * nuc % total - this % absorption = this % absorption + & - atom_density * nuc % absorption - if (nuc % fissionable) then - if (allocated(nuc % chi)) then - do gin = 1, groups - do gout = 1, groups - this % chi(gout,gin,:,:) = this % chi(gout,gin,:,:) + atom_density * & - nuc % chi(gout,:,:) * nuc % nu_fission(gin,1,:,:) - end do - end do - this % nu_fission = this % nu_fission + atom_density * & - nuc % nu_fission(:,1,:,:) - else - this % chi = this % chi + atom_density * nuc % nu_fission - do gin = 1, groups - this % nu_fission(gin,:,:) = this % nu_fission(gin,:,:) + atom_density * & - sum(nuc % nu_fission(:,gin,:,:),dim=1) - end do - end if - if (get_fiss) then - this % fission = this % fission + atom_density * nuc % fission - end if - if (get_kfiss) then - this % k_fission = this % k_fission + atom_density * nuc % k_fission - end if - end if - - ! Now time to do the scattering - do gin = 1, groups - do gout = 1, groups - if (scatt_type == ANGLE_HISTOGRAM .or. scatt_type == ANGLE_TABULAR) then - ! Transfer matrix - temp_energy(gout,gin,:,:) = temp_energy(gout,gin,:,:) + atom_density * & - sum(nuc % scatter(gout,gin,:,:,:),dim=1) - - ! Determine the angular distribution - do imu = 1, order - scatt_coeffs(imu,gout,gin,:,:) = scatt_coeffs(imu,gout,gin,:,:) + & - nuc % scatter(gout,gin,imu,:,:) * & - atom_density - end do - else if (scatt_type == ANGLE_LEGENDRE) then - ! Transfer matrix - temp_energy(gout,gin,:,:) = temp_energy(gout,gin,:,:) + atom_density * & - nuc % scatter(gout,gin,1,:,:) - - ! Determine the angular distribution coefficients so we can later - ! expand do the complete distribution - do l = 1, min(nuc % order, order) + 1 - scatt_coeffs(l, gout, gin,:,:) = scatt_coeffs(l, gout, gin,:,:) + & - nuc % scatter(gout,gin,l,:,:) * & - atom_density - end do - end if - - ! Multiplicity matrix - temp_mult(gout,gin,:,:) = temp_mult(gout,gin,:,:) + atom_density * & - nuc % mult(gout,gin,:,:) - end do - end do - end select - end do - - ! Store the scattering xs - if (scatt_type == ANGLE_HISTOGRAM .or. scatt_type == ANGLE_TABULAR) then - this % scattxs(:,:,:) = sum(sum(scatt_coeffs(:,:,:,:,:),dim=1),dim=1) - else if (scatt_type == ANGLE_LEGENDRE) then - this % scattxs(:,:,:) = sum(scatt_coeffs(1,:,:,:,:),dim=1) - end if - - ! Normalize the scatt_coeffs - do ipol = 1, npol - do iazi = 1, nazi - do gin = 1, groups - do gout = 1, groups - if (scatt_type == ANGLE_HISTOGRAM .or. scatt_type == ANGLE_TABULAR) then - norm = sum(scatt_coeffs(:,gout,gin,iazi,ipol)) - else if (scatt_type == ANGLE_LEGENDRE) then - norm = scatt_coeffs(1,gout,gin,iazi,ipol) - end if - if (norm /= ZERO) then - scatt_coeffs(:,gout,gin,iazi,ipol) = & - scatt_coeffs(:,gout,gin,iazi,ipol) / norm - end if - end do - ! Now normalize temp_energy (outgoing scattering energy probabilities) - norm = sum(temp_energy(:,gin,iazi,ipol)) - if (norm > ZERO) then - temp_energy(:,gin,iazi,ipol) = temp_energy(:,gin,iazi,ipol) / norm - end if - end do - - if (scatt_type == ANGLE_LEGENDRE .and. legendre_mu_points /= 1) then - call this % scatter(iazi, ipol) % obj % init(legendre_mu_points, & - temp_energy(:,:,iazi,ipol), temp_mult(:,:,iazi,ipol), & - scatt_coeffs(:,:,:,iazi,ipol)) - else - call this % scatter(iazi, ipol) % obj % init(this % order, & - temp_energy(:,:,iazi,ipol), temp_mult(:,:,iazi,ipol), & - scatt_coeffs(:,:,:,iazi,ipol)) - end if - - end do - end do - - ! Now go through and normalize chi - if (mat % fissionable) then - do ipol = 1, npol - do iazi = 1, nazi - do gin = 1, groups - ! Normalize Chi - norm = sum(this % chi(:,gin,iazi,ipol)) - if (norm > ZERO) then - this % chi(:,gin,iazi,ipol) = this % chi(:,gin,iazi,ipol) / norm - end if - end do - end do - end do - end if - - ! Deallocate temporaries for the next material - deallocate(scatt_coeffs, temp_energy, temp_mult) - - end subroutine macroxsangle_init - -!=============================================================================== -! MACROXS_*_GET_XS returns the requested data type -!=============================================================================== - - function macroxsiso_get_xs(this, g, xstype, gout, uvw) result(xs) - class(MacroXSIso), intent(in) :: this ! The MacroXS to initialize - integer, intent(in) :: g ! Incoming Energy group - character(*) , intent(in) :: xstype ! Type of xs requested - integer, optional, intent(in) :: gout ! Outgoing Energy group - real(8), optional, intent(in) :: uvw(3) ! Requested Angle - real(8) :: xs ! Requested x/s - - select case(xstype) - case('total') - xs = this % total(g) - case('absorption') - xs = this % absorption(g) - case('fission') - xs = this % fission(g) - case('k_fission') - xs = this % k_fission(g) - case('nu_fission') - xs = this % nu_fission(g) - case('scatter') - xs = this % scattxs(g) - case('mult') - if (present(gout)) then - xs = this % scatter % mult(gout,g) - else - xs = sum(this % scatter % mult(:,g)) - end if - end select - - end function macroxsiso_get_xs - - function macroxsangle_get_xs(this, g, xstype, gout,uvw) result(xs) - class(MacroXSAngle), intent(in) :: this ! The MacroXS to initialize - integer, intent(in) :: g ! Incoming Energy group - character(*) , intent(in) :: xstype ! Type of xs requested - integer, optional, intent(in) :: gout ! Outgoing Energy group - real(8), optional, intent(in) :: uvw(3) ! Requested Angle - real(8) :: xs ! Requested x/s - - integer :: iazi, ipol - - if (present(uvw)) then - call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) - select case(xstype) - case('total') - xs = this % total(g,iazi,ipol) - case('absorption') - xs = this % absorption(g,iazi,ipol) - case('fission') - xs = this % fission(g,iazi,ipol) - case('k_fission') - xs = this % k_fission(g,iazi,ipol) - case('nu_fission') - xs = this % nu_fission(g,iazi,ipol) - case('scatter') - xs = this % scattxs(g,iazi,ipol) - case('mult') - if (present(gout)) then - xs = this % scatter(iazi,ipol) % obj % mult(gout,g) - else - xs = sum(this % scatter(iazi,ipol) % obj % mult(:,g)) - end if - end select - end if - - end function macroxsangle_get_xs - -!=============================================================================== -! MACROXS_*_SAMPLE_FISSION_ENERGY samples the outgoing energy from a fission -! event -!=============================================================================== - - function macroxsiso_sample_fission_energy(this, gin, uvw) result(gout) - class(MacroXSIso), intent(in) :: this ! Data to work with - integer, intent(in) :: gin ! Incoming energy group - real(8), intent(in) :: uvw(3) ! Particle Direction - integer :: gout ! Sampled outgoing group - real(8) :: xi ! Our random number - real(8) :: prob ! Running probability - - xi = prn() - prob = ZERO - gout = 0 - - do while (prob < xi) - gout = gout + 1 - prob = prob + this % chi(gout,gin) - end do - - end function macroxsiso_sample_fission_energy - - function macroxsangle_sample_fission_energy(this, gin, uvw) result(gout) - class(MacroXSAngle), intent(in) :: this ! Data to work with - integer, intent(in) :: gin ! Incoming energy group - real(8), intent(in) :: uvw(3) ! Particle Direction - integer :: gout ! Sampled outgoing group - real(8) :: xi ! Our random number - real(8) :: prob ! Running probability - integer :: iazi, ipol - - call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) - - xi = prn() - prob = ZERO - gout = 0 - - do while (prob < xi) - gout = gout + 1 - prob = prob + this % chi(gout,gin,iazi,ipol) - end do - - end function macroxsangle_sample_fission_energy - -!=============================================================================== -! MACROXS*_SAMPLE_SCATTER Selects outgoing energy and angle after a scatter -! event -!=============================================================================== - - subroutine macroxsiso_sample_scatter(this, uvw, gin, gout, mu, wgt) - class(MacroXSIso), intent(in) :: this - real(8), intent(in) :: uvw(3) ! Incoming neutron direction - integer, intent(in) :: gin ! Incoming neutron group - integer, intent(out) :: gout ! Sampled outgoin group - real(8), intent(out) :: mu ! Sampled change in angle - real(8), intent(inout) :: wgt ! Particle weight - - call this % scatter % sample(gin, gout, mu, wgt) - - end subroutine macroxsiso_sample_scatter - - subroutine macroxsangle_sample_scatter(this, uvw, gin, gout, mu, wgt) - class(MacroXSAngle), intent(in) :: this - real(8), intent(in) :: uvw(3) ! Incoming neutron direction - integer, intent(in) :: gin ! Incoming neutron group - integer, intent(out) :: gout ! Sampled outgoin group - real(8), intent(out) :: mu ! Sampled change in angle - real(8), intent(inout) :: wgt ! Particle weight - - integer :: iazi, ipol ! Angular indices - - call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) - call this % scatter(iazi,ipol) % obj % sample(gin,gout,mu,wgt) - - end subroutine macroxsangle_sample_scatter - -!=============================================================================== -! MACROXS*_CALCULATE_XS determines the multi-group macroscopic cross sections -! for the material the particle is currently traveling through. -!=============================================================================== - - subroutine macroxsiso_calculate_xs(this, gin, uvw, xs) - class(MacroXSIso), intent(in) :: this - integer, intent(in) :: gin ! Incoming neutron group - real(8), intent(in) :: uvw(3) ! Incoming neutron direction - type(MaterialMacroXS), intent(inout) :: xs ! Resultant MacroXS Data - - xs % total = this % total(gin) - xs % elastic = this % scattxs(gin) - xs % absorption = this % absorption(gin) - xs % nu_fission = this % nu_fission(gin) - - end subroutine macroxsiso_calculate_xs - - subroutine macroxsangle_calculate_xs(this, gin, uvw, xs) - class(MacroXSAngle), intent(in) :: this - integer, intent(in) :: gin ! Incoming neutron group - real(8), intent(in) :: uvw(3) ! Incoming neutron direction - type(MaterialMacroXS), intent(inout) :: xs ! Resultant MacroXS Data - - integer :: iazi, ipol - - call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) - xs % total = this % total(gin, iazi, ipol) - xs % elastic = this % scattxs(gin, iazi, ipol) - xs % absorption = this % absorption(gin, iazi, ipol) - xs % nu_fission = this % nu_fission(gin, iazi, ipol) - - end subroutine macroxsangle_calculate_xs - -end module macroxs_header diff --git a/src/math.F90 b/src/math.F90 index dfaa903f4..123cc9caa 100644 --- a/src/math.F90 +++ b/src/math.F90 @@ -826,30 +826,4 @@ contains end do end subroutine broaden_wmp_polynomials -!=============================================================================== -! find_angle finds the closest angle on the data grid and returns that index -!=============================================================================== - - pure subroutine find_angle(polar, azimuthal, uvw, i_azi, i_pol) - real(8), intent(in) :: polar(:) ! Polar angles [0,pi] - real(8), intent(in) :: azimuthal(:) ! Azi. angles [-pi,pi] - real(8), intent(in) :: uvw(3) ! Direction of motion - integer, intent(inout) :: i_pol ! Closest polar bin - integer, intent(inout) :: i_azi ! Closest azi bin - - real(8) :: my_pol, my_azi, dangle - - ! Convert uvw to polar and azi - - my_pol = acos(uvw(3)) - my_azi = atan2(uvw(2), uvw(1)) - - ! Search for equi-binned angles - dangle = PI / real(size(polar),8) - i_pol = floor(my_pol / dangle + ONE) - dangle = TWO * PI / real(size(azimuthal),8) - i_azi = floor((my_azi + PI) / dangle + ONE) - - end subroutine find_angle - end module math diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index 08941870c..38d6ebc6c 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -3,9 +3,8 @@ module mgxs_data use constants use error, only: fatal_error use global - use macroxs_header use material_header, only: Material - use nuclide_header + use mgxs_header use output, only: write_message use set_header, only: SetChar use string, only: to_lower @@ -71,7 +70,8 @@ contains if (tallies(i) % score_bins(l) == SCORE_KAPPA_FISSION) then get_kfiss = .true. end if - if (tallies(i) % score_bins(l) == SCORE_FISSION) then + if (tallies(i) % score_bins(l) == SCORE_FISSION .or. & + tallies(i) % score_bins(l) == SCORE_NU_FISSION) then get_fiss = .true. end if end do @@ -118,17 +118,14 @@ contains ! Now allocate accordingly select case(representation) case(MGXS_ISOTROPIC) - allocate(NuclideIso :: nuclides_MG(i_nuclide) % obj) + allocate(MgxsIso :: nuclides_MG(i_nuclide) % obj) case(MGXS_ANGLE) - allocate(NuclideAngle :: nuclides_MG(i_nuclide) % obj) + allocate(MgxsAngle :: nuclides_MG(i_nuclide) % obj) end select ! Now read in the data specific to the type we just declared - call nuclides_MG(i_nuclide) % obj % init(node_xsdata, energy_groups, & - get_kfiss, get_fiss) - - ! Keep track of what listing is associated with this nuclide - nuclides_MG(i_nuclide) % obj % listing = i_listing + call nuclides_MG(i_nuclide) % obj % init_file(node_xsdata, & + energy_groups, get_kfiss, get_fiss, max_order, i_listing) ! Add name and alias to dictionary call already_read % add(name) @@ -167,31 +164,8 @@ contains subroutine create_macro_xs() integer :: i_mat ! index in materials array - integer :: i ! loop index over nuclides - integer :: l ! Loop over score bins type(Material), pointer :: mat ! current material - logical :: get_kfiss, get_fiss - integer :: error_code - character(MAX_LINE_LEN) :: error_text integer :: scatt_type - integer :: legendre_mu_points - - ! Find out if we need fission & kappa fission - ! (i.e., are there any SCORE_FISSION or SCORE_KAPPA_FISSION tallies?) - get_kfiss = .false. - get_fiss = .false. - do i = 1, n_tallies - do l = 1, tallies(i) % n_score_bins - if (tallies(i) % score_bins(l) == SCORE_KAPPA_FISSION) then - get_kfiss = .true. - end if - if (tallies(i) % score_bins(l) == SCORE_FISSION) then - get_fiss = .true. - end if - end do - if (get_kfiss .and. get_fiss) & - exit - end do allocate(macro_xs(n_materials)) @@ -203,21 +177,15 @@ contains ! Therefore type(nuclides(mat % nuclide(1)) % obj) dictates type(macroxs) ! At the same time, we will find the scattering type, as that will dictate ! how we allocate the scatter object within macroxs - legendre_mu_points = nuclides_MG(mat % nuclide(1)) % obj % legendre_mu_points scatt_type = nuclides_MG(mat % nuclide(1)) % obj % scatt_type select type(nuc => nuclides_MG(mat % nuclide(1)) % obj) - type is (NuclideIso) - allocate(MacroXSIso :: macro_xs(i_mat) % obj) - type is (NuclideAngle) - allocate(MacroXSAngle :: macro_xs(i_mat) % obj) + type is (MgxsIso) + allocate(MgxsIso :: macro_xs(i_mat) % obj) + type is (MgxsAngle) + allocate(MgxsAngle :: macro_xs(i_mat) % obj) end select - - call macro_xs(i_mat) % obj % init(mat, nuclides_MG, energy_groups, & - get_kfiss, get_fiss, max_order, & - scatt_type, legendre_mu_points, & - error_code, error_text) - ! Handle any errors - if (error_code /= 0) call fatal_error(trim(error_text)) + call macro_xs(i_mat) % obj % combine(mat, nuclides_MG, energy_groups, & + max_order, scatt_type, i_mat) end do end subroutine create_macro_xs diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 new file mode 100644 index 000000000..88c1b23e2 --- /dev/null +++ b/src/mgxs_header.F90 @@ -0,0 +1,1929 @@ +module mgxs_header + + use constants, only: MAX_FILE_LEN, ZERO, ONE, TWO, PI + use error, only: fatal_error + use, intrinsic :: ISO_FORTRAN_ENV, only: OUTPUT_UNIT + use list_header, only: ListInt + use material_header, only: material + use math, only: calc_pn, calc_rn, expand_harmonic, & + evaluate_legendre + use nuclide_header, only: MaterialMacroXS + use random_lcg, only: prn + use scattdata_header + use string + use xml_interface + +!=============================================================================== +! MGXS contains the base mgxs data for a nuclide/material +!=============================================================================== + + type, abstract :: Mgxs + character(len=104) :: name ! name of dataset, e.g. 92235.03c + integer :: zaid ! Z and A identifier, e.g. 92235 + real(8) :: awr ! Atomic Weight Ratio + integer :: listing ! index in xs_listings + real(8) :: kT ! temperature in MeV (k*T) + + ! Fission information + logical :: fissionable ! mgxs object is fissionable? + integer :: scatt_type ! either legendre, histogram, or tabular. + + contains + procedure(mgxs_init_file_), deferred :: init_file ! Initialize the data + procedure(mgxs_print_), deferred :: print ! Writes object info + procedure(mgxs_get_xs_), deferred :: get_xs ! Get the requested xs + procedure(mgxs_combine_), deferred :: combine ! initializes object + ! Sample the outgoing energy from a fission event + procedure(mgxs_sample_fission_), deferred :: sample_fission_energy + ! Sample the outgoing energy and angle from a scatter event + procedure(mgxs_sample_scatter_), deferred :: sample_scatter + ! Calculate the material specific MGXS data from the nuclides + procedure(mgxs_calculate_xs_), deferred :: calculate_xs + end type Mgxs + +!=============================================================================== +! MGXSCONTAINER pointer array for storing Nuclides +!=============================================================================== + + type MgxsContainer + class(Mgxs), pointer :: obj + end type MgxsContainer + +!=============================================================================== +! Interfaces for MGXS +!=============================================================================== + + abstract interface + subroutine mgxs_init_file_(this,node_xsdata,groups,get_kfiss,get_fiss, & + max_order,i_listing) + import Mgxs, Node + class(Mgxs), intent(inout) :: this ! Working Object + type(Node), pointer, intent(in) :: node_xsdata ! Data from MGXS xml + integer, intent(in) :: groups ! Number of Energy groups + logical, intent(in) :: get_kfiss ! Need Kappa-Fission? + logical, intent(in) :: get_fiss ! Should we get fiss data? + integer, intent(in) :: max_order ! Maximum requested order + integer, intent(in) :: i_listing ! Index of listings array + end subroutine mgxs_init_file_ + + subroutine mgxs_print_(this, unit) + import Mgxs + class(Mgxs),intent(in) :: this + integer, optional, intent(in) :: unit + end subroutine mgxs_print_ + + pure function mgxs_get_xs_(this,xstype,gin,gout,uvw,mu) result(xs) + import Mgxs + class(Mgxs), intent(in) :: this + character(*), intent(in) :: xstype ! Cross Section Type + integer, intent(in) :: gin ! Incoming Energy group + integer, optional, intent(in) :: gout ! Outgoing Group + real(8), optional, intent(in) :: uvw(3) ! Requested Angle + real(8), optional, intent(in) :: mu ! Change in angle + real(8) :: xs ! Resultant xs + end function mgxs_get_xs_ + + pure function mgxs_calc_f_(this,gin,gout,mu,uvw,iazi,ipol) result(f) + import Mgxs + class(Mgxs), intent(in) :: this + integer, intent(in) :: gin ! Incoming Energy Group + integer, intent(in) :: gout ! Outgoing Energy Group + real(8), intent(in) :: mu ! Angle of interest + real(8), intent(in), optional :: uvw(3) ! Direction vector + integer, intent(in), optional :: iazi ! Incoming Energy Group + integer, intent(in), optional :: ipol ! Outgoing Energy Group + real(8) :: f ! Return value of f(mu) + + end function mgxs_calc_f_ + + subroutine mgxs_combine_(this,mat,nuclides,groups,max_order,scatt_type, & + i_listing) + import Mgxs, Material, MgxsContainer + class(Mgxs), intent(inout) :: this ! The Mgxs to initialize + type(Material), pointer, intent(in) :: mat ! base material + type(MgxsContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from + integer, intent(in) :: groups ! Number of E groups + integer, intent(in) :: max_order ! Maximum requested order + integer, intent(in) :: scatt_type ! Legendre or Tabular Scatt? + integer, intent(in) :: i_listing ! Index in listings + end subroutine mgxs_combine_ + + function mgxs_sample_fission_(this, gin, uvw) result(gout) + import Mgxs + class(Mgxs), intent(in) :: this ! Data to work with + integer, intent(in) :: gin ! Incoming energy group + real(8), intent(in) :: uvw(3) ! Particle Direction + integer :: gout ! Sampled outgoing group + + end function mgxs_sample_fission_ + + subroutine mgxs_sample_scatter_(this, uvw, gin, gout, mu, wgt) + import Mgxs + class(Mgxs), intent(in) :: this + real(8), intent(in) :: uvw(3) ! Incoming neutron direction + integer, intent(in) :: gin ! Incoming neutron group + integer, intent(out) :: gout ! Sampled outgoin group + real(8), intent(out) :: mu ! Sampled change in angle + real(8), intent(inout) :: wgt ! Particle weight + end subroutine mgxs_sample_scatter_ + + subroutine mgxs_calculate_xs_(this, gin, uvw, xs) + import Mgxs, MaterialMacroXS + class(Mgxs), intent(in) :: this + integer, intent(in) :: gin ! Incoming neutron group + real(8), intent(in) :: uvw(3) ! Incoming neutron direction + type(MaterialMacroXS), intent(inout) :: xs ! Resultant Mgxs Data + end subroutine mgxs_calculate_xs_ + end interface + +!=============================================================================== +! MGXSISO contains the base MGXS data specifically for +! isotropically weighted MGXS +!=============================================================================== + + type, extends(Mgxs) :: MgxsIso + + ! Microscopic cross sections + real(8), allocatable :: total(:) ! total cross section + real(8), allocatable :: absorption(:) ! absorption cross section + class(ScattData), allocatable :: scatter ! scattering information + real(8), allocatable :: nu_fission(:) ! fission matrix (Gout x Gin) + real(8), allocatable :: k_fission(:) ! kappa-fission + real(8), allocatable :: fission(:) ! neutron production + real(8), allocatable :: chi(:, :) ! Fission Spectra + + contains + procedure :: init_file => mgxsiso_init_file ! Initialize Nuclidic MGXS Data + procedure :: print => mgxsiso_print ! Writes nuclide info + procedure :: get_xs => mgxsiso_get_xs ! Gets Size of Data w/in Object + procedure :: combine => mgxsiso_combine ! inits object + procedure :: sample_fission_energy => mgxsiso_sample_fission_energy + procedure :: sample_scatter => mgxsiso_sample_scatter + procedure :: calculate_xs => mgxsiso_calculate_xs + end type MgxsIso + +!=============================================================================== +! MGXSANGLE contains the base MGXS data specifically for +! angular flux weighted MGXS +!=============================================================================== + + type, extends(Mgxs) :: MgxsAngle + + ! Microscopic cross sections + real(8), allocatable :: total(:, :, :) ! total cross section + real(8), allocatable :: absorption(:, :, :) ! absorption cross section + type(ScattDataContainer), allocatable :: scatter(:, :) ! scattering information + real(8), allocatable :: nu_fission(:, :, :) ! fission matrix (Gout x Gin) + real(8), allocatable :: k_fission(:, :, :) ! kappa-fission + real(8), allocatable :: fission(:, :, :) ! neutron production + real(8), allocatable :: chi(:, :, :, :) ! Fission Spectra + ! In all cases, right-most indices are theta, phi + integer :: n_pol ! Number of polar angles + integer :: n_azi ! Number of azimuthal angles + real(8), allocatable :: polar(:) ! polar angles + real(8), allocatable :: azimuthal(:) ! azimuthal angles + + contains + procedure :: init_file => mgxsang_init_file ! Initialize Nuclidic MGXS Data + procedure :: print => mgxsang_print ! Writes nuclide info + procedure :: get_xs => mgxsang_get_xs ! Gets Size of Data w/in Object + procedure :: combine => mgxsang_combine ! inits object + procedure :: sample_fission_energy => mgxsang_sample_fission_energy + procedure :: sample_scatter => mgxsang_sample_scatter + procedure :: calculate_xs => mgxsang_calculate_xs + end type MgxsAngle + + contains + +!=============================================================================== +! MGXS*_INIT reads in the data from the XML file. At the point of entry +! the file would have been opened and metadata read. This routine begins with +! the xsdata object node itself. +!=============================================================================== + + subroutine mgxs_init_file(this, node_xsdata, i_listing) + class(Mgxs), intent(inout) :: this ! Working Object + type(Node), pointer, intent(in) :: node_xsdata ! Data from MGXS xml + integer, intent(in) :: i_listing ! Index in listings array + + character(MAX_LINE_LEN) :: temp_str + + ! Load the nuclide metadata + call get_node_value(node_xsdata, "name", this % name) + this % name = to_lower(this % name) + if (check_for_node(node_xsdata, "kT")) then + call get_node_value(node_xsdata, "kT", this % kT) + else + this % kT = ZERO + end if + if (check_for_node(node_xsdata, "zaid")) then + call get_node_value(node_xsdata, "zaid", this % zaid) + else + this % zaid = 0 + end if + if (check_for_node(node_xsdata, "awr")) then + call get_node_value(node_xsdata, "awr", this % awr) + else + this % awr = -ONE + end if + if (check_for_node(node_xsdata, "scatt_type")) then + call get_node_value(node_xsdata, "scatt_type", temp_str) + temp_str = trim(to_lower(temp_str)) + if (temp_str == 'legendre') then + this % scatt_type = ANGLE_LEGENDRE + else if (temp_str == 'histogram') then + this % scatt_type = ANGLE_HISTOGRAM + else if (temp_str == 'tabular') then + this % scatt_type = ANGLE_TABULAR + else + call fatal_error("Invalid scatt_type option!") + end if + else + this % scatt_type = ANGLE_LEGENDRE + end if + + if (check_for_node(node_xsdata, "fissionable")) then + call get_node_value(node_xsdata, "fissionable", temp_str) + temp_str = to_lower(temp_str) + if (trim(temp_str) == 'true' .or. trim(temp_str) == '1') then + this % fissionable = .true. + else + this % fissionable = .false. + end if + else + call fatal_error("Fissionable element must be set!") + end if + + ! Keep track of what listing is associated with this nuclide + this % listing = i_listing + + end subroutine mgxs_init_file + + subroutine mgxsiso_init_file(this, node_xsdata, groups, get_kfiss, get_fiss, & + max_order, i_listing) + class(MgxsIso), intent(inout) :: this ! Working Object + type(Node), pointer, intent(in) :: node_xsdata ! Data from MGXS xml + integer, intent(in) :: groups ! Number of Energy groups + logical, intent(in) :: get_kfiss ! Need Kappa-Fission? + logical, intent(in) :: get_fiss ! Need fiss data? + integer, intent(in) :: max_order ! Maximum requested order + integer, intent(in) :: i_listing ! Index in listings array + + type(Node), pointer :: node_legendre_mu + character(MAX_LINE_LEN) :: temp_str + logical :: enable_leg_mu + real(8), allocatable :: temp_arr(:), temp_2d(:, :) + real(8), allocatable :: temp_mult(:, :) + real(8), allocatable :: scatt_coeffs(:, :, :) + real(8), allocatable :: input_scatt(:, :, :) + real(8), allocatable :: temp_scatt(:, :, :) + real(8) :: dmu, mu, norm + integer :: order, order_dim, gin, gout, l, arr_len + integer :: legendre_mu_points, imu + + ! Call generic data gathering routine (will populate the metadata) + call mgxs_init_file(this, node_xsdata, i_listing) + + ! Load the more specific data + allocate(this % nu_fission(groups)) + allocate(this % chi(groups,groups)) + if (this % fissionable) then + if (check_for_node(node_xsdata, "chi")) then + ! Chi was provided, that means they are giving chi and nu-fission + ! vectors + ! Get chi + allocate(temp_arr(groups)) + call get_node_array(node_xsdata, "chi", temp_arr) + do gin = 1, groups + do gout = 1, groups + this % chi(gout, gin) = temp_arr(gout) + end do + ! Normalize chi so its CDF goes to 1 + this % chi(:, gin) = this % chi(:, gin) / sum(this % chi(:, gin)) + end do + deallocate(temp_arr) + + ! Get nu_fission (as a vector) + if (check_for_node(node_xsdata, "nu_fission")) then + call get_node_array(node_xsdata, "nu_fission", this % nu_fission) + else + call fatal_error("If fissionable, must provide nu_fission!") + end if + + else + ! chi isnt provided but is within nu_fission, existing as a matrix + ! So, get nu_fission (as a matrix) + if (check_for_node(node_xsdata, "nu_fission")) then + allocate(temp_arr(groups*groups)) + call get_node_array(node_xsdata, "nu_fission", temp_arr) + allocate(temp_2d(groups, groups)) + temp_2d = reshape(temp_arr, (/groups, groups/)) + deallocate(temp_arr) + else + call fatal_error("If fissionable, must provide nu_fission!") + end if + + ! Set the vector nu-fission from the matrix nu-fission + do gin = 1, groups + this % nu_fission(gin) = sum(temp_2d(:, gin)) + end do + + ! Now pull out information needed for chi + this % chi(:, :) = temp_2d + ! Normalize chi so its CDF goes to 1 + do gin = 1, groups + this % chi(:, gin) = this % chi(:, gin) / sum(this % chi(:, gin)) + end do + deallocate(temp_2d) + end if + ! If we have a need* for the fission and kappa-fission x/s, get them + ! (*Need is defined as will be using it to tally) + if (get_fiss) then + allocate(this % fission(groups)) + if (check_for_node(node_xsdata, "fission")) then + call get_node_array(node_xsdata, "fission", this % fission) + else + call fatal_error("Fission data missing, required due to fission& + & tallies in tallies.xml file!") + end if + end if + if (get_kfiss) then + allocate(this % k_fission(groups)) + if (check_for_node(node_xsdata, "kappa_fission")) then + call get_node_array(node_xsdata, "kappa_fission", this % k_fission) + else + call fatal_error("kappa_fission data missing, required due to & + &kappa-fission tallies in tallies.xml file!") + end if + end if + else + this % nu_fission = ZERO + this % chi = ZERO + end if + + allocate(this % absorption(groups)) + if (check_for_node(node_xsdata, "absorption")) then + call get_node_array(node_xsdata, "absorption", this % absorption) + else + call fatal_error("Must provide absorption!") + end if + + ! Get multiplication data if present + allocate(temp_mult(groups, groups)) + if (check_for_node(node_xsdata, "multiplicity")) then + arr_len = get_arraysize_double(node_xsdata, "multiplicity") + if (arr_len == groups * groups) then + allocate(temp_arr(arr_len)) + call get_node_array(node_xsdata, "multiplicity", temp_arr) + temp_mult(:, :) = reshape(temp_arr, (/groups, groups/)) + deallocate(temp_arr) + else + call fatal_error("Multiplicity length not same as number of groups& + & squared!") + end if + else + temp_mult(:, :) = ONE + end if + + ! Get scattering treatment information + ! Tabular_legendre tells us if we are to treat the provided + ! Legendre polynomials as tabular data (if enable is true) or leaving + ! them as Legendres (if enable is false, or the default) + + ! Set the default (leave as Legendre polynomials) + enable_leg_mu = .false. + if (check_for_node(node_xsdata, "tabular_legendre")) then + call get_node_ptr(node_xsdata, "tabular_legendre", node_legendre_mu) + if (check_for_node(node_legendre_mu, "enable")) then + call get_node_value(node_legendre_mu, "enable", temp_str) + temp_str = trim(to_lower(temp_str)) + if (temp_str == 'true' .or. temp_str == '1') then + enable_leg_mu = .true. + elseif (temp_str == 'false' .or. temp_str == '0') then + enable_leg_mu = .false. + else + call fatal_error("Unrecognized tabular_legendre/enable: " & + // temp_str) + end if + end if + ! Ok, so if we need to convert to a tabular form, get the user provided + ! number of points + if (enable_leg_mu) then + if (check_for_node(node_legendre_mu, "num_points")) then + call get_node_value(node_legendre_mu, "num_points", & + legendre_mu_points) + if (legendre_mu_points <= 0) & + call fatal_error("num_points element must be positive& + & and non-zero!") + else + ! Set the default number of points (0.0625 spacing) + legendre_mu_points = 33 + end if + end if + end if + + ! Get the library's value for the order + if (check_for_node(node_xsdata, "order")) then + call get_node_value(node_xsdata, "order", order) + else + call fatal_error("Order must be provided!") + end if + + ! Before retrieving the data, store the dimensionality of the data in + ! order_dim. For Legendre data, we usually refer to it as Pn where + ! n is the order. However Pn has n+1 sets of points (since you need to + ! the count the P0 moment). Adjust for that. Histogram and Tabular + ! formats dont need this adjustment. + if (this % scatt_type == ANGLE_LEGENDRE) then + order_dim = order + 1 + else + order_dim = order + end if + + ! The input is gathered in the more user-friendly facing format of + ! Gout x Gin x Order. We will get it in that format in input_scatt, + ! but then need to convert it to a more useful ordering for processing + ! (Order x Gout x Gin). + allocate(input_scatt(groups, groups, order_dim)) + if (check_for_node(node_xsdata, "scatter")) then + allocate(temp_arr(groups * groups * order_dim)) + call get_node_array(node_xsdata, "scatter", temp_arr) + input_scatt = reshape(temp_arr, (/groups, groups, order_dim/)) + deallocate(temp_arr) + + ! Compare the number of orders given with the maximum order of the + ! problem. Strip off the supefluous orders if needed. + if (this % scatt_type == ANGLE_LEGENDRE) then + order = min(order_dim - 1, max_order) + order_dim = order + 1 + end if + allocate(temp_scatt(groups, groups, order_dim)) + temp_scatt(:, :, :) = input_scatt(:, :, 1:order_dim) + + ! Take input format (groups, groups, order) and convert to + ! the more useful format needed for scattdata: (order, groups, groups) + ! However, if scatt_type was ANGLE_LEGENDRE (i.e., the data was + ! provided as Legendre coefficients), and the user requested that + ! these legendres be converted to tabular form (note this is also + ! the default behavior), convert that now. + if (this % scatt_type == ANGLE_LEGENDRE .and. enable_leg_mu) then + ! Convert input parameters to what we need for the rest. + this % scatt_type = ANGLE_TABULAR + order_dim = legendre_mu_points + order = order_dim + dmu = TWO / real(order - 1, 8) + + allocate(scatt_coeffs(order_dim, groups, groups)) + do gin = 1, groups + do gout = 1, groups + norm = ZERO + do imu = 1, order_dim + if (imu == 1) then + mu = -ONE + else if (imu == order_dim) then + mu = ONE + else + mu = -ONE + real(imu - 1, 8) * dmu + end if + scatt_coeffs(imu, gout, gin) = & + evaluate_legendre(temp_scatt(gout, gin, :),mu) + ! Ensure positivity of distribution + if (scatt_coeffs(imu, gout, gin) < ZERO) & + scatt_coeffs(imu, gout, gin) = ZERO + ! And accrue the integral + if (imu > 1) then + norm = norm + HALF * dmu * & + (scatt_coeffs(imu - 1, gout, gin) + & + scatt_coeffs(imu, gout, gin)) + end if + end do + ! Now that we have the integral, lets ensure that the distribution + ! is normalized such that it preserves the original scattering xs + if (norm > ZERO) then + scatt_coeffs(:, gout, gin) = scatt_coeffs(:, gout, gin) * & + temp_scatt(gout, gin, 1) / norm + end if + end do + end do + else + ! Sticking with current representation, carry forward but change + ! the array ordering + allocate(scatt_coeffs(order_dim, groups, groups)) + do gin = 1, groups + do gout = 1, groups + do l = 1, order_dim + scatt_coeffs(l, gout, gin) = temp_scatt(gout, gin, l) + end do + end do + end do + end if + deallocate(temp_scatt) + else + call fatal_error("Must provide scatter!") + end if + + ! Allocate and initialize our ScattData Object. + if (this % scatt_type == ANGLE_HISTOGRAM) then + allocate(ScattDataHistogram :: this % scatter) + else if (this % scatt_type == ANGLE_TABULAR) then + allocate(ScattDataTabular :: this % scatter) + else if (this % scatt_type == ANGLE_LEGENDRE) then + allocate(ScattDataLegendre :: this % scatter) + end if + + ! Initialize the ScattData Object + call this % scatter % init(temp_mult, scatt_coeffs) + + ! Check sigA to ensure it is not 0 since it is + ! often divided by in the tally routines + ! (This may happen with Helium data) + do gin = 1, groups + if (this % absorption(gin) == ZERO) this % absorption(gin) = 1E-10_8 + end do + + ! Get, or infer, total xs data. + allocate(this % total(groups)) + if (check_for_node(node_xsdata, "total")) then + call get_node_array(node_xsdata, "total", this % total) + else + this % total(:) = this % absorption(:) + this % scatter % scattxs(:) + end if + + ! Deallocate temporaries for the next material + deallocate(input_scatt, scatt_coeffs, temp_mult) + + ! Finally, check sigT to ensure it is not 0 since it is + ! often divided by in the tally routines + do gin = 1, groups + if (this % total(gin) == ZERO) this % total(gin) = 1E-10_8 + end do + + + end subroutine mgxsiso_init_file + + subroutine mgxsang_init_file(this, node_xsdata, groups, get_kfiss, get_fiss, & + max_order, i_listing) + class(MgxsAngle), intent(inout) :: this ! Working Object + type(Node), pointer, intent(in) :: node_xsdata ! Data from MGXS xml + integer, intent(in) :: groups ! Number of Energy groups + logical, intent(in) :: get_kfiss ! Need Kappa-Fission? + logical, intent(in) :: get_fiss ! Should we get fiss data? + integer, intent(in) :: max_order ! Maximum requested order + integer, intent(in) :: i_listing ! Index in listings array + + type(Node), pointer :: node_legendre_mu + character(MAX_LINE_LEN) :: temp_str + logical :: enable_leg_mu + real(8), allocatable :: temp_arr(:), temp_4d(:, :, :, :) + real(8), allocatable :: temp_mult(:, :, :, :) + real(8), allocatable :: scatt_coeffs(:, :, :, :, :) + real(8), allocatable :: input_scatt(:, :, :, :, :) + real(8), allocatable :: temp_scatt(:, :, :, :, :) + real(8) :: dmu, mu, norm, dangle + integer :: order, order_dim, gin, gout, l, arr_len + integer :: legendre_mu_points, imu, ipol, iazi + + ! Call generic data gathering routine (will populate the metadata) + call mgxs_init_file(this, node_xsdata, i_listing) + + if (check_for_node(node_xsdata, "num_polar")) then + call get_node_value(node_xsdata, "num_polar", this % n_pol) + else + call fatal_error("num_polar must be provided!") + end if + + if (check_for_node(node_xsdata, "num_azimuthal")) then + call get_node_value(node_xsdata, "num_azimuthal", this % n_azi) + else + call fatal_error("num_azimuthal must be provided!") + end if + + ! Load angle data, if present (else equally spaced) + allocate(this % polar(this % n_pol)) + allocate(this % azimuthal(this % n_azi)) + if (check_for_node(node_xsdata, "polar")) then + call fatal_error("User-Specified polar angle bins not yet supported!") + ! When this feature is supported, this line will be activated + call get_node_array(node_xsdata, "polar", this % polar) + else + dangle = PI / real(this % n_pol, 8) + do ipol = 1, this % n_pol + this % polar(ipol) = (real(ipol, 8) - HALF) * dangle + end do + end if + if (check_for_node(node_xsdata, "azimuthal")) then + call fatal_error("User-Specified azimuthal angle bins not yet supported!") + ! When this feature is supported, this line will be activated + call get_node_array(node_xsdata, "azimuthal", this % azimuthal) + else + dangle = TWO * PI / real(this % n_azi, 8) + do iazi = 1, this % n_azi + this % azimuthal(iazi) = -PI + (real(iazi, 8) - HALF) * dangle + end do + end if + + ! Load the more specific data + allocate(this % nu_fission(groups, this % n_azi, this % n_pol)) + allocate(this % chi(groups, groups, this % n_azi, this % n_pol)) + if (this % fissionable) then + if (check_for_node(node_xsdata, "chi")) then + ! Chi was provided, that means they are giving chi and nu-fission + ! vectors + ! Get chi + allocate(temp_arr(1 * groups * this % n_azi * this % n_pol)) + call get_node_array(node_xsdata, "chi", temp_arr) + ! Initialize counter for temp_arr + l = 0 + gin = 1 + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gout = 1, groups + l = l + 1 + this % chi(gout, gin, iazi, ipol) = temp_arr(l) + end do + ! Normalize chi so its CDF goes to 1 + this % chi(:, gin, iazi, ipol) = & + this % chi(:, gin, iazi, ipol) / & + sum(this % chi(:, gin, iazi, ipol)) + end do + end do + + ! Now set all the other gin values + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 2, groups + this % chi(:, gin, iazi, ipol) = & + this % chi(:, 1, iazi, ipol) + end do + end do + end do + deallocate(temp_arr) + + ! Get nu_fission (as a vector) + if (check_for_node(node_xsdata, "nu_fission")) then + allocate(temp_arr(groups * this % n_azi * this % n_pol)) + call get_node_array(node_xsdata, "nu_fission", temp_arr) + this % nu_fission(:, :, :) = reshape(temp_arr, (/groups, & + this % n_azi, this % n_pol/)) + deallocate(temp_arr) + else + call fatal_error("If fissionable, must provide nu_fission!") + end if + + else + ! chi isnt provided but is within nu_fission, existing as a matrix + ! So, get nu_fission (as a matrix) + if (check_for_node(node_xsdata, "nu_fission")) then + allocate(temp_arr(groups * groups * this % n_azi * this % n_pol)) + call get_node_array(node_xsdata, "nu_fission", temp_arr) + allocate(temp_4d(groups, groups, this % n_azi,this % n_pol)) + temp_4d(:, :, :, :) = reshape(temp_arr, (/groups, groups, & + this % n_azi, this % n_pol/)) + deallocate(temp_arr) + else + call fatal_error("If fissionable, must provide nu_fission!") + end if + + ! Set the vector nu-fission from the matrix nu-fission + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, groups + this % nu_fission(gin, iazi, ipol) = & + sum(temp_4d(:, gin, iazi, ipol)) + end do + end do + end do + + ! Now pull out information needed for chi + this % chi = temp_4d + ! Normalize chi so its CDF goes to 1 + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, groups + this % chi(:, gin, iazi, ipol) = & + this % chi(:, gin, iazi, ipol) / & + sum(this % chi(:, gin, iazi, ipol)) + end do + end do + end do + deallocate(temp_4d) + end if + + ! If we have a need* for the fission and kappa-fission x/s, get them + ! (*Need is defined as will be using it to tally) + if (get_fiss) then + if (check_for_node(node_xsdata, "fission")) then + allocate(temp_arr(groups * this % n_azi * this % n_pol)) + call get_node_array(node_xsdata, "fission", temp_arr) + allocate(this % fission(groups, this % n_azi, this % n_pol)) + this % fission(:, :, :) = reshape(temp_arr, (/groups, this % n_azi, & + this % n_pol/)) + deallocate(temp_arr) + else + call fatal_error("Fission data missing, required due to fission& + & tallies in tallies.xml file!") + end if + end if + if (get_kfiss) then + if (check_for_node(node_xsdata, "kappa_fission")) then + allocate(temp_arr(groups * this % n_azi * this % n_pol)) + call get_node_array(node_xsdata, "kappa_fission", temp_arr) + allocate(this % k_fission(groups, this % n_azi, this % n_pol)) + this % k_fission(:, :, :) = reshape(temp_arr, (/groups, & + this % n_azi, this % n_pol/)) + deallocate(temp_arr) + else + call fatal_error("kappa_fission data missing, required due to & + &kappa-fission tallies in tallies.xml file!") + end if + end if + else + this % nu_fission(:, :, :) = ZERO + this % chi(:, :, :, :) = ZERO + end if + + if (check_for_node(node_xsdata, "absorption")) then + allocate(temp_arr(groups * this % n_azi * this % n_pol)) + call get_node_array(node_xsdata, "absorption", temp_arr) + allocate(this % absorption(groups, this % n_azi, this % n_pol)) + this % absorption(:, :, :) = reshape(temp_arr, (/groups, this % n_azi, & + this % n_pol/)) + deallocate(temp_arr) + else + call fatal_error("Must provide absorption!") + end if + + ! Get multiplication data if present + allocate(temp_mult(groups,groups, this % n_azi, this % n_pol)) + if (check_for_node(node_xsdata, "multiplicity")) then + arr_len = get_arraysize_double(node_xsdata, "multiplicity") + if (arr_len == groups * groups * this % n_azi * this % n_pol) then + allocate(temp_arr(arr_len)) + call get_node_array(node_xsdata, "multiplicity", temp_arr) + temp_mult(:, :, :, :) = reshape(temp_arr, (/groups, groups, & + this % n_azi, this % n_pol/)) + deallocate(temp_arr) + else + call fatal_error("Multiplicity length not same as number of groups& + & squared!") + end if + else + temp_mult(:, :, :, :) = ONE + end if + + ! Get scattering treatment information + ! Tabular_legendre tells us if we are to treat the provided + ! Legendre polynomials as tabular data (if enable is true) or leaving + ! them as Legendres (if enable is false, or the default) + + ! Set the default (leave as Legendre polynomials) + enable_leg_mu = .false. + if (check_for_node(node_xsdata, "tabular_legendre")) then + call get_node_ptr(node_xsdata, "tabular_legendre", node_legendre_mu) + if (check_for_node(node_legendre_mu, "enable")) then + call get_node_value(node_legendre_mu, "enable", temp_str) + temp_str = trim(to_lower(temp_str)) + if (temp_str == 'true' .or. temp_str == '1') then + enable_leg_mu = .true. + elseif (temp_str == 'false' .or. temp_str == '0') then + enable_leg_mu = .false. + else + call fatal_error("Unrecognized tabular_legendre/enable: " & + // temp_str) + end if + end if + ! Ok, so if we need to convert to a tabular form, get the user provided + ! number of points + if (enable_leg_mu) then + if (check_for_node(node_legendre_mu, "num_points")) then + call get_node_value(node_legendre_mu, "num_points", & + legendre_mu_points) + if (legendre_mu_points <= 0) & + call fatal_error("num_points element must be positive& + & and non-zero!") + else + ! Set the default number of points (0.0625 spacing) + legendre_mu_points = 33 + end if + end if + end if + + ! Get the library's value for the order + if (check_for_node(node_xsdata, "order")) then + call get_node_value(node_xsdata, "order", order) + else + call fatal_error("Order must be provided!") + end if + + ! Before retrieving the data, store the dimensionality of the data in + ! order_dim. For Legendre data, we usually refer to it as Pn where + ! n is the order. However Pn has n+1 sets of points (since you need to + ! the count the P0 moment). Adjust for that. Histogram and Tabular + ! formats dont need this adjustment. + if (this % scatt_type == ANGLE_LEGENDRE) then + order_dim = order + 1 + else + order_dim = order + end if + + ! The input is gathered in the more user-friendly facing format of + ! Gout x Gin x Order x Azi x Pol. We will get it in that format in + ! input_scatt, but then need to convert it to a more useful ordering + ! for processing (Order x Gout x Gin x Azi x Pol). + allocate(input_scatt(groups, groups, order_dim, this % n_azi, & + this % n_pol)) + if (check_for_node(node_xsdata, "scatter")) then + allocate(temp_arr(groups * groups * order_dim * this % n_azi * & + this % n_pol)) + call get_node_array(node_xsdata, "scatter", temp_arr) + input_scatt(:, :, :, :, :) = reshape(temp_arr, (/groups, groups, & + order_dim, this % n_azi, this % n_pol/)) + deallocate(temp_arr) + + ! Compare the number of orders given with the maximum order of the + ! problem. Strip off the supefluous orders if needed. + if (this % scatt_type == ANGLE_LEGENDRE) then + order = min(order_dim - 1, max_order) + order_dim = order + 1 + end if + + allocate(temp_scatt(groups, groups, order_dim, this % n_azi, & + this % n_pol)) + temp_scatt(:, :, :, :, :) = input_scatt(:, :, 1:order_dim, :, :) + + ! Take input format (groups, groups, order) and convert to + ! the more useful format needed for scattdata: (order, groups, groups) + ! However, if scatt_type was ANGLE_LEGENDRE (i.e., the data was + ! provided as Legendre coefficients), and the user requested that + ! these legendres be converted to tabular form (note this is also + ! the default behavior), convert that now. + if (this % scatt_type == ANGLE_LEGENDRE .and. enable_leg_mu) then + + ! Convert input parameters to what we need for the rest. + this % scatt_type = ANGLE_TABULAR + order_dim = legendre_mu_points + order = order_dim + dmu = TWO / real(order - 1, 8) + + allocate(scatt_coeffs(order_dim, groups, groups, this % n_azi, & + this % n_pol)) + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, groups + do gout = 1, groups + norm = ZERO + do imu = 1, order_dim + if (imu == 1) then + mu = -ONE + else if (imu == order_dim) then + mu = ONE + else + mu = -ONE + real(imu - 1, 8) * dmu + end if + scatt_coeffs(imu, gout, gin, iazi, ipol) = & + evaluate_legendre(temp_scatt(gout, gin, :, iazi, ipol), mu) + ! Ensure positivity of distribution + if (scatt_coeffs(imu, gout, gin, iazi, ipol) < ZERO) & + scatt_coeffs(imu, gout, gin, iazi, ipol) = ZERO + ! And accrue the integral + if (imu > 1) then + norm = norm + HALF * dmu * & + (scatt_coeffs(imu - 1, gout, gin, iazi, ipol) + & + scatt_coeffs(imu, gout, gin, iazi, ipol)) + end if + end do + ! Now that we have the integral, lets ensure that the distribution + ! is normalized such that it preserves the original scattering xs + if (norm > ZERO) then + scatt_coeffs(:, gout, gin, iazi, ipol) = & + scatt_coeffs(:, gout, gin, iazi, ipol) * & + temp_scatt(gout, gin, 1, iazi, ipol) / norm + end if + end do + end do + end do + end do + else + ! Sticking with current representation, carry forward but change + ! the array ordering + allocate(scatt_coeffs(order_dim, groups, groups, this % n_azi, & + this % n_pol)) + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, groups + do gout = 1, groups + do l = 1, order_dim + scatt_coeffs(l, gout, gin, iazi, ipol) = & + temp_scatt(gout, gin, l, iazi, ipol) + end do + end do + end do + end do + end do + end if + deallocate(temp_scatt) + else + call fatal_error("Must provide scatter!") + end if + + allocate(this % scatter(this % n_azi, this % n_pol)) + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + ! Allocate and initialize our ScattData Object. + if (this % scatt_type == ANGLE_HISTOGRAM) then + allocate(ScattDataHistogram :: this % scatter(iazi, ipol) % obj) + else if (this % scatt_type == ANGLE_TABULAR) then + allocate(ScattDataTabular :: this % scatter(iazi, ipol) % obj) + else if (this % scatt_type == ANGLE_LEGENDRE) then + allocate(ScattDataLegendre :: this % scatter(iazi, ipol) % obj) + end if + + ! Initialize the ScattData Object + call this % scatter(iazi, ipol) % obj % init(& + temp_mult(:, :, iazi, ipol), & + scatt_coeffs(:, :, :, iazi, ipol)) + end do + end do + ! Deallocate temporaries for the next material + deallocate(input_scatt, scatt_coeffs, temp_mult) + + allocate(this % total(groups, this % n_azi, this % n_pol)) + if (check_for_node(node_xsdata, "total")) then + allocate(temp_arr(groups * this % n_azi * this % n_pol)) + call get_node_array(node_xsdata, "total", temp_arr) + this % total(:, :, :) = reshape(temp_arr, (/groups, this % n_azi, & + this % n_pol/)) + deallocate(temp_arr) + else + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + this % total(:, iazi, ipol) = this % absorption(:, iazi, ipol) + & + this % scatter(iazi, ipol) % obj % scattxs(:) + end do + end do + end if + + end subroutine mgxsang_init_file + +!=============================================================================== +! MGXS*_PRINT displays information about a continuous-energy neutron +! cross_section table and its reactions and secondary angle/energy distributions +!=============================================================================== + + subroutine mgxs_print(this, unit_) + class(Mgxs), intent(in) :: this + integer, intent(in) :: unit_ + + character(MAX_LINE_LEN) :: temp_str + + ! Basic nuclide information + write(unit_,*) 'MGXS Entry: ' // trim(this % name) + if (this % zaid > 0) then + write(unit_,*) ' ZAID = ' // trim(to_str(this % zaid)) + else if (this % zaid < 0) then + write(unit_,*) ' Material id = ' // trim(to_str(-this % zaid)) + end if + if (this % awr > ZERO) then + write(unit_,*) ' AWR = ' // trim(to_str(this % awr)) + end if + if (this % kT > ZERO) then + write(unit_,*) ' kT = ' // trim(to_str(this % kT)) + end if + if (this % scatt_type == ANGLE_LEGENDRE) then + temp_str = "Legendre" + write(unit_,*) ' Scattering Type = ' // trim(temp_str) + select type(this) + type is (MgxsIso) + temp_str = to_str(size(this % scatter % dist(1) % data,dim=1) - 1) + end select + write(unit_,*) ' Scattering Order = ' // trim(temp_str) + else if (this % scatt_type == ANGLE_HISTOGRAM) then + temp_str = "Histogram" + write(unit_,*) ' Scattering Type = ' // trim(temp_str) + select type(this) + type is (MgxsIso) + temp_str = to_str(size(this % scatter % dist(1) % data,dim=1)) + end select + write(unit_,*) ' Num. Distribution Bins = ' // trim(temp_str) + else if (this % scatt_type == ANGLE_TABULAR) then + temp_str = "Tabular" + write(unit_,*) ' Scattering Type = ' // trim(temp_str) + select type(this) + type is (MgxsIso) + temp_str = to_str(size(this % scatter % dist(1) % data,dim=1)) + end select + write(unit_,*) ' Num. Distribution Points = ' // trim(temp_str) + end if + write(unit_,*) ' Fissionable = ', this % fissionable + + end subroutine mgxs_print + + subroutine mgxsiso_print(this, unit) + + class(MgxsIso), intent(in) :: this + integer, optional, intent(in) :: unit + + integer :: unit_ ! unit to write to + integer :: size_total, size_scattmat, size_mgxs + integer :: gin + + ! set default unit for writing information + if (present(unit)) then + unit_ = unit + else + unit_ = OUTPUT_UNIT + end if + + ! Write Basic Nuclide Information + call mgxs_print(this, unit_) + + ! Determine size of mgxs and scattering matrices + size_scattmat = 0 + do gin = 1, size(this % scatter % energy) + size_scattmat = size_scattmat + & + 2 * size(this % scatter % energy(gin) % data) + & + size(this % scatter % dist(gin) % data) + end do + size_scattmat = size_scattmat + size(this % scatter % scattxs) + size_scattmat = size_scattmat * 8 + + size_mgxs = size(this % total) + size(this % absorption) + & + size(this % nu_fission) + size(this % k_fission) + & + size(this % fission) + size(this % chi) + size_mgxs = size_mgxs * 8 + + ! Calculate total memory + size_total = size_scattmat + size_mgxs + + ! Write memory used + write(unit_,*) ' Memory Requirements' + write(unit_,*) ' Cross sections = ' // trim(to_str(size_mgxs)) // ' bytes' + write(unit_,*) ' Scattering Matrices = ' // & + trim(to_str(size_scattmat)) // ' bytes' + write(unit_,*) ' Total = ' // trim(to_str(size_total)) // ' bytes' + + ! Blank line at end of nuclide + write(unit_,*) + + end subroutine mgxsiso_print + + subroutine mgxsang_print(this, unit) + + class(MgxsAngle), intent(in) :: this + integer, optional, intent(in) :: unit + + integer :: unit_ ! unit to write to + integer :: size_total, size_scattmat, size_mgxs + integer :: ipol, iazi, gin + + ! set default unit for writing information + if (present(unit)) then + unit_ = unit + else + unit_ = OUTPUT_UNIT + end if + + ! Write Basic Nuclide Information + call mgxs_print(this, unit_) + + write(unit_,*) ' # of Polar Angles = ' // trim(to_str(this % n_pol)) + write(unit_,*) ' # of Azimuthal Angles = ' // trim(to_str(this % n_azi)) + + ! Determine size of mgxs and scattering matrices + size_scattmat = 0 + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, size(this % scatter(iazi, ipol) % obj % energy) + size_scattmat = size_scattmat + & + 2 * size(this % scatter(iazi, ipol) % obj % energy(gin) % data) + & + size(this % scatter(iazi, ipol) % obj % dist(gin) % data) + end do + size_scattmat = size_scattmat + & + size(this % scatter(iazi, ipol) % obj % scattxs) + end do + end do + size_scattmat = size_scattmat * 8 + + size_mgxs = size(this % total) + size(this % absorption) + & + size(this % nu_fission) + size(this % k_fission) + & + size(this % fission) + size(this % chi) + size_mgxs = size_mgxs * 8 + + ! Calculate total memory + size_total = size_scattmat + size_mgxs + + ! Write memory used + write(unit_,*) ' Memory Requirements' + write(unit_,*) ' Cross sections = ' // trim(to_str(size_mgxs)) // ' bytes' + write(unit_,*) ' Scattering Matrices = ' // & + trim(to_str(size_scattmat)) // ' bytes' + write(unit_,*) ' Total = ' // trim(to_str(size_total)) // ' bytes' + + ! Blank line at end of nuclide + write(unit_,*) + end subroutine mgxsang_print + +!=============================================================================== +! MGXS*_GET_XS returns the requested data cross section data +!=============================================================================== + + pure function mgxsiso_get_xs(this, xstype, gin, gout, uvw, mu) result(xs) + class(MgxsIso), intent(in) :: this ! The Mgxs to initialize + character(*) , intent(in) :: xstype ! Type of xs requested + integer, intent(in) :: gin ! Incoming Energy group + integer, optional, intent(in) :: gout ! Outgoing Energy group + real(8), optional, intent(in) :: uvw(3) ! Requested Angle + real(8), optional, intent(in) :: mu ! Change in angle + real(8) :: xs ! Requested x/s + + select case(xstype) + case('total') + xs = this % total(gin) + case('absorption') + xs = this % absorption(gin) + case('fission') + if (allocated(this % fission)) then + xs = this % fission(gin) + else + xs = ZERO + end if + case('kappa_fission') + if (allocated(this % k_fission)) then + xs = this % k_fission(gin) + else + xs = ZERO + end if + case('nu_fission') + xs = this % nu_fission(gin) + case('chi') + if (present(gout)) then + xs = this % chi(gout,gin) + else + ! Not sure youd want a 1 or a 0, but here you go! + xs = sum(this % chi(:, gin)) + end if + case('scatter') + if (present(gout)) then + if (gout < this % scatter % gmin(gin) .or. & + gout > this % scatter % gmax(gin)) then + xs = ZERO + else + xs = this % scatter % scattxs(gin) * & + this % scatter % energy(gin) % data(gout) + end if + else + xs = this % scatter % scattxs(gin) + end if + case('scatter/mult') + if (present(gout)) then + if (gout < this % scatter % gmin(gin) .or. & + gout > this % scatter % gmax(gin)) then + xs = ZERO + else + xs = this % scatter % scattxs(gin) * & + this % scatter % energy(gin) % data(gout) / & + this % scatter % mult(gin) % data(gout) + end if + else + xs = this % scatter % scattxs(gin) / & + (dot_product(this % scatter % mult(gin) % data, & + this % scatter % energy(gin) % data)) + end if + case('scatter*f_mu/mult','scatter*f_mu') + if (present(gout)) then + if (gout < this % scatter % gmin(gin) .or. & + gout > this % scatter % gmax(gin)) then + xs = ZERO + else + xs = this % scatter % scattxs(gin) * & + this % scatter % energy(gin) % data(gout) * & + this % scatter % calc_f(gin, gout, mu) + if (xstype == 'scatter*f_mu/mult') then + xs = xs / this % scatter % mult(gin) % data(gout) + end if + end if + else + xs = ZERO + ! TODO (Not likely needed) + ! (asking for f_mu without asking for a group or mu would mean the + ! user of this code wants the complete 1-outgoing group distribution + ! which Im not sure what they would do with that. + end if + case default + xs = ZERO + end select + + end function mgxsiso_get_xs + + pure function mgxsang_get_xs(this, xstype, gin, gout, uvw, mu) result(xs) + class(MgxsAngle), intent(in) :: this ! The Mgxs to initialize + character(*) , intent(in) :: xstype ! Type of xs requested + integer, intent(in) :: gin ! Incoming Energy group + integer, optional, intent(in) :: gout ! Outgoing Energy group + real(8), optional, intent(in) :: uvw(3) ! Requested Angle + real(8), optional, intent(in) :: mu ! Change in angle + real(8) :: xs ! Requested x/s + + integer :: iazi, ipol + + if (present(uvw)) then + call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) + select case(xstype) + case('total') + xs = this % total(gin, iazi, ipol) + case('absorption') + xs = this % absorption(gin, iazi, ipol) + case('fission') + if (allocated(this % fission)) then + xs = this % fission(gin, iazi, ipol) + else + xs = ZERO + end if + case('kappa_fission') + if (allocated(this % k_fission)) then + xs = this % k_fission(gin, iazi, ipol) + else + xs = ZERO + end if + case('nu_fission') + xs = this % nu_fission(gin, iazi, ipol) + case('chi') + if (present(gout)) then + xs = this % chi(gout, gin, iazi, ipol) + else + ! Not sure you would want a 1 or a 0, but here you go! + xs = sum(this % chi(:, gin, iazi, ipol)) + end if + case('scatter') + if (present(gout)) then + if (gout < this % scatter(iazi, ipol) % obj % gmin(gin) .or. & + gout > this % scatter(iazi, ipol) % obj % gmax(gin)) then + xs = ZERO + else + xs = this % scatter(iazi, ipol) % obj % scattxs(gin) * & + this % scatter(iazi, ipol) % obj % energy(gin) % data(gout) + end if + else + xs = this % scatter(iazi, ipol) % obj % scattxs(gin) + end if + case('scatter/mult') + if (present(gout)) then + if (gout < this % scatter(iazi, ipol) % obj % gmin(gin) .or. & + gout > this % scatter(iazi, ipol) % obj % gmax(gin)) then + xs = ZERO + else + xs = this % scatter(iazi, ipol) % obj % scattxs(gin) * & + this % scatter(iazi, ipol) % obj % energy(gin) % data(gout) / & + this % scatter(iazi, ipol) % obj % mult(gin) % data(gout) + end if + else + xs = this % scatter(iazi, ipol) % obj % scattxs(gin) / & + (dot_product(this % scatter(iazi, ipol) % obj % mult(gin) % data, & + this % scatter(iazi, ipol) % obj % energy(gin) % data)) + end if + case('scatter*f_mu/mult','scatter*f_mu') + if (present(gout)) then + if (gout < this % scatter(iazi, ipol) % obj % gmin(gin) .or. & + gout > this % scatter(iazi, ipol) % obj % gmax(gin)) then + xs = ZERO + else + xs = this % scatter(iazi, ipol) % obj % scattxs(gin) * & + this % scatter(iazi, ipol) % obj % energy(gin) % data(gout) + xs = xs * this % scatter(iazi, ipol) % obj % calc_f(gin, gout, mu) + if (xstype == 'scatter*f_mu/mult') then + xs = xs / & + this % scatter(iazi, ipol) % obj % mult(gin) % data(gout) + end if + end if + else + xs = ZERO + ! TODO (Not likely needed) + ! (asking for f_mu without asking for a group or mu would mean the + ! user of this code wants the complete 1-outgoing group distribution + ! which Im not sure what they would do with that. + end if + case default + xs = ZERO + end select + else + xs = ZERO + end if + + end function mgxsang_get_xs + +!=============================================================================== +! MACROXS*_COMBINE Builds a macroscopic Mgxs object from microscopic Mgxs +! objects +!=============================================================================== + + subroutine mgxs_combine(this, mat, scatt_type, i_listing) + class(Mgxs), intent(inout) :: this ! The Mgxs to initialize + type(Material), pointer, intent(in) :: mat ! base material + integer, intent(in) :: scatt_type ! How is data presented + integer, intent(in) :: i_listing ! Index in listings + + ! Fill in meta-data from material information + if (mat % name == "") then + this % name = trim(to_str(mat % id)) + else + this % name = mat % name + end if + this % zaid = -mat % id + this % listing = i_listing + this % fissionable = mat % fissionable + this % scatt_type = scatt_type + + ! The following info we should initialize, but we dont need it nor + ! does it have guaranteed meaning. + this % awr = -ONE + this % kT = -ONE + + end subroutine mgxs_combine + + subroutine mgxsiso_combine(this, mat, nuclides, groups, max_order, scatt_type, & + i_listing) + class(MgxsIso), intent(inout) :: this ! The Mgxs to initialize + type(Material), pointer, intent(in) :: mat ! base material + type(MgxsContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from + integer, intent(in) :: groups ! Number of E groups + integer, intent(in) :: max_order ! Maximum requested order + integer, intent(in) :: scatt_type ! How is data presented + integer, intent(in) :: i_listing ! Index in listings + + integer :: i ! loop index over nuclides + integer :: gin, gout ! group indices + real(8) :: atom_density ! atom density of a nuclide + real(8) :: norm, nuscatt + integer :: mat_max_order, order, order_dim, nuc_order_dim + real(8), allocatable :: temp_mult(:, :), mult_num(:, :), mult_denom(:, :) + real(8), allocatable :: scatt_coeffs(:, :, :) + + ! Set the meta-data + call mgxs_combine(this, mat, scatt_type, i_listing) + + ! Determine the scattering type of our data and ensure all scattering orders + ! are the same. + select type(nuc => nuclides(mat % nuclide(1)) % obj) + type is (MgxsIso) + order = size(nuc % scatter % dist(1) % data, dim=1) + end select + ! If we have tabular only data, then make sure all datasets have same size + if (scatt_type == ANGLE_HISTOGRAM) then + ! Check all scattering data to ensure it is the same size + do i = 2, mat % n_nuclides + select type(nuc => nuclides(mat % nuclide(i)) % obj) + type is (MgxsIso) + if (order /= size(nuc % scatter % dist(1) % data, dim=1)) & + call fatal_error("All histogram scattering entries must be& + & same length!") + end select + end do + ! Ok, got our order, store the dimensionality + order_dim = order + + ! Set our Scatter Object Type + allocate(ScattDataHistogram :: this % scatter) + + else if (scatt_type == ANGLE_TABULAR) then + ! Check all scattering data to ensure it is the same size + do i = 2, mat % n_nuclides + select type(nuc => nuclides(mat % nuclide(i)) % obj) + type is (MgxsIso) + if (order /= size(nuc % scatter % dist(1) % data, dim=1)) & + call fatal_error("All tabular scattering entries must be& + & same length!") + end select + end do + ! Ok, got our order, store the dimensionality + order_dim = order + + ! Set our Scatter Object Type + allocate(ScattDataTabular :: this % scatter) + + else if (scatt_type == ANGLE_LEGENDRE) then + ! Need to determine the maximum scattering order of all data in this material + mat_max_order = 0 + do i = 1, mat % n_nuclides + select type(nuc => nuclides(mat % nuclide(i)) % obj) + type is (MgxsIso) + if (size(nuc % scatter % dist(1) % data, dim=1) > mat_max_order) & + mat_max_order = size(nuc % scatter % dist(1) % data, dim=1) + end select + end do + + ! Now need to compare this material maximum scattering order with + ! the problem wide max scatt order and use whichever is lower + order = min(mat_max_order, max_order) + ! Ok, got our order, store the dimensionality + order_dim = order + 1 + + ! Set our Scatter Object Type + allocate(ScattDataLegendre :: this % scatter) + end if + + ! Allocate and initialize data needed for macro_xs(i_mat) object + allocate(this % total(groups)) + this % total(:) = ZERO + allocate(this % absorption(groups)) + this % absorption(:) = ZERO + allocate(this % fission(groups)) + this % fission(:) = ZERO + allocate(this % k_fission(groups)) + this % k_fission(:) = ZERO + allocate(this % nu_fission(groups)) + this % nu_fission(:) = ZERO + allocate(this % chi(groups,groups)) + this % chi(:, :) = ZERO + allocate(temp_mult(groups,groups)) + temp_mult(:, :) = ZERO + allocate(mult_num(groups,groups)) + mult_num(:, :) = ZERO + allocate(mult_denom(groups,groups)) + mult_denom(:, :) = ZERO + allocate(scatt_coeffs(order_dim,groups,groups)) + scatt_coeffs(:, :, :) = ZERO + + ! Add contribution from each nuclide in material + do i = 1, mat % n_nuclides + ! Copy atom density of nuclide in material + atom_density = mat % atom_density(i) + + ! Perform our operations which depend upon the type + select type(nuc => nuclides(mat % nuclide(i)) % obj) + type is (MgxsIso) + ! Add contributions to total, absorption, and fission data (if necessary) + this % total(:) = this % total(:) + atom_density * nuc % total(:) + this % absorption(:) = this % absorption(:) + & + atom_density * nuc % absorption(:) + if (nuc % fissionable) then + this % chi(:, :) = this % chi(:, :) + atom_density * nuc % chi(:, :) + this % nu_fission(:) = this % nu_fission(:)+ atom_density * & + nuc % nu_fission(:) + if (allocated(nuc % fission)) then + this % fission(:) = this % fission(:) + atom_density * nuc % fission(:) + end if + if (allocated(nuc % k_fission)) then + this % k_fission(:) = this % k_fission(:) + atom_density * & + nuc % k_fission(:) + end if + end if + + ! Get the multiplication matrix + ! To combine from nuclidic data we need to use the final relationship + ! mult_{gg'} = sum_i(N_i*nuscatt_{i,g,g'}) / + ! sum_i(N_i*(nuscatt_{i,g,g'} / mult_{i,g,g'})) + ! Developed as follows: + ! mult_{gg'} = nuScatt{g,g'} / Scatt{g,g'} + ! mult_{gg'} = sum_i(N_i*nuscatt_{i,g,g'}) / sum(N_i*scatt_{i,g,g'}) + ! mult_{gg'} = sum_i(N_i*nuscatt_{i,g,g'}) / + ! sum_i(N_i*(nuscatt_{i,g,g'} / mult_{i,g,g'})) + ! nuscatt_{i,g,g'} can be reconstructed from scatter % energy and + ! scatter % scattxs + do gin = 1, groups + do gout = nuc % scatter % gmin(gin), nuc % scatter % gmax(gin) + nuscatt = nuc % scatter % scattxs(gin) * & + nuc % scatter % energy(gin) % data(gout) + mult_num(gout, gin) = mult_num(gout, gin) + atom_density * & + nuscatt + mult_denom(gout, gin) = mult_denom(gout,gin) + atom_density * & + nuscatt / nuc % scatter % mult(gin) % data(gout) + end do + end do + + ! Get the complete scattering matrix + nuc_order_dim = size(nuc % scatter % dist(1) % data, dim=1) + scatt_coeffs(1:min(nuc_order_dim, order_dim), :, :) = & + scatt_coeffs(1:min(nuc_order_dim, order_dim), :, :) + & + atom_density * & + nuc % scatter % get_matrix(min(nuc_order_dim, order_dim)) + + type is (MgxsAngle) + call fatal_error("Invalid passing of MgxsAngle to MgxsIso object") + end select + end do + + ! Obtain temp_mult + do gin = 1, groups + do gout = 1, groups + if (mult_denom(gout, gin) > ZERO) then + temp_mult(gout, gin) = mult_num(gout, gin) / mult_denom(gout, gin) + else + temp_mult(gout, gin) = ONE + end if + end do + end do + + ! Initialize the ScattData Object + call this % scatter % init(temp_mult, scatt_coeffs) + + ! Now normalize chi + if (mat % fissionable) then + do gin = 1, groups + norm = sum(this % chi(:, gin)) + if (norm > ZERO) then + this % chi(:, gin) = this % chi(:, gin) / norm + end if + end do + end if + + ! Deallocate temporaries + deallocate(scatt_coeffs, temp_mult, mult_num, mult_denom) + + end subroutine mgxsiso_combine + + subroutine mgxsang_combine(this, mat, nuclides, groups, max_order, scatt_type, & + i_listing) + class(MgxsAngle), intent(inout) :: this ! The Mgxs to initialize + type(Material), pointer, intent(in) :: mat ! base material + type(MgxsContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from + integer, intent(in) :: groups ! Number of E groups + integer, intent(in) :: max_order ! Maximum requested order + integer, intent(in) :: scatt_type ! Legendre or Tabular Scatt? + integer, intent(in) :: i_listing ! Index in listings + + integer :: i ! loop index over nuclides + integer :: gin, gout ! group indices + real(8) :: atom_density ! atom density of a nuclide + integer :: ipol, iazi, n_pol, n_azi + real(8) :: norm, nuscatt + integer :: mat_max_order, order, order_dim, nuc_order_dim + real(8), allocatable :: temp_mult(:, :, :, :), mult_num(:, :, :, :) + real(8), allocatable :: mult_denom(:, :, :, :), scatt_coeffs(:, :, :, :, :) + + ! Set the meta-data + call mgxs_combine(this, mat, scatt_type, i_listing) + + ! Get the number of each polar and azi angles and make sure all the + ! NuclideAngle types have the same number of these angles + n_pol = -1 + n_azi = -1 + do i = 1, mat % n_nuclides + select type(nuc => nuclides(mat % nuclide(i)) % obj) + type is (MgxsAngle) + if (n_pol == -1) then + n_pol = nuc % n_pol + n_azi = nuc % n_azi + allocate(this % polar(n_pol)) + this % polar(:) = nuc % polar(:) + allocate(this % azimuthal(n_azi)) + this % azimuthal(:) = nuc % azimuthal(:) + else + if ((n_pol /= nuc % n_pol) .or. (n_azi /= nuc % n_azi)) then + call fatal_error("All angular data must be same length!") + end if + end if + end select + end do + + ! Determine the scattering type of our data and ensure all scattering orders + ! are the same. + select type(nuc => nuclides(mat % nuclide(1)) % obj) + type is (MgxsAngle) + order = size(nuc % scatter(1,1) % obj % dist(1) % data, dim=1) + end select + ! If we have tabular only data, then make sure all datasets have same size + if (scatt_type == ANGLE_HISTOGRAM) then + ! Check all scattering data to ensure it is the same size + ! order = size(nuclides(mat % nuclide(1)) % obj % scatter % data,dim=1) + do i = 2, mat % n_nuclides + select type(nuc => nuclides(mat % nuclide(i)) % obj) + type is (MgxsAngle) + if (order /= size(nuc % scatter(1,1) % obj % dist(1) % data, dim=1)) & + call fatal_error("All histogram scattering entries must be& + & same length!") + end select + end do + ! Ok, got our order, store the dimensionality + order_dim = order + + ! Set our Scatter Object Type + allocate(this % scatter(n_azi, n_pol)) + do ipol = 1, n_pol + do iazi = 1, n_azi + allocate(ScattDataHistogram :: this % scatter(iazi, ipol) % obj) + end do + end do + + else if (scatt_type == ANGLE_TABULAR) then + ! Check all scattering data to ensure it is the same size + do i = 2, mat % n_nuclides + select type(nuc => nuclides(mat % nuclide(i)) % obj) + type is (MgxsAngle) + if (order /= size(nuc % scatter(1, 1) % obj % dist(1) % data, dim=1)) & + call fatal_error("All tabular scattering entries must be& + & same length!") + end select + end do + ! Ok, got our order, store the dimensionality + order_dim = order + + ! Set our Scatter Object Type + allocate(this % scatter(n_azi, n_pol)) + do ipol = 1, n_pol + do iazi = 1, n_azi + allocate(ScattDataTabular :: this % scatter(iazi, ipol) % obj) + end do + end do + + else if (scatt_type == ANGLE_LEGENDRE) then + ! Need to determine the maximum scattering order of all data in this material + mat_max_order = 0 + do i = 1, mat % n_nuclides + select type(nuc => nuclides(mat % nuclide(i)) % obj) + type is (MgxsAngle) + if (size(nuc % scatter(1,1) % obj % dist(1) % data, dim=1) > mat_max_order) & + mat_max_order = size(nuc % scatter(1,1) % obj% dist(1) % data, dim=1) + end select + end do + + ! Now need to compare this material maximum scattering order with + ! the problem wide max scatt order and use whichever is lower + order = min(mat_max_order, max_order) + ! Ok, got our order, store the dimensionality + order_dim = order + 1 + + ! Set our Scatter Object Type + allocate(this % scatter(n_azi, n_pol)) + do ipol = 1, n_pol + do iazi = 1, n_azi + allocate(ScattDataLegendre :: this % scatter(iazi, ipol) % obj) + end do + end do + end if + + ! Allocate and initialize data within macro_xs(i_mat) object + allocate(this % total(groups, n_azi, n_pol)) + this % total(:, :, :) = ZERO + allocate(this % absorption(groups, n_azi, n_pol)) + this % absorption(:, :, :) = ZERO + allocate(this % fission(groups, n_azi, n_pol)) + this % fission(:, :, :) = ZERO + allocate(this % k_fission(groups, n_azi, n_pol)) + this % k_fission(:, :, :) = ZERO + allocate(this % nu_fission(groups, n_azi, n_pol)) + this % nu_fission(:, :, :) = ZERO + allocate(this % chi(groups, groups, n_azi, n_pol)) + this % chi(:, :, :, :) = ZERO + allocate(temp_mult(groups, groups, n_azi, n_pol)) + temp_mult(:, :, :, :) = ZERO + allocate(mult_num(groups, groups, n_azi, n_pol)) + mult_num(:, :, :, :) = ZERO + allocate(mult_denom(groups, groups, n_azi, n_pol)) + mult_denom(:, :, :, :) = ZERO + allocate(scatt_coeffs(order_dim, groups, groups, n_azi, n_pol)) + scatt_coeffs(:, :, :, :, :) = ZERO + + ! Add contribution from each nuclide in material + do i = 1, mat % n_nuclides + ! Copy atom density of nuclide in material + atom_density = mat % atom_density(i) + + ! Perform our operations which depend upon the type + select type(nuc => nuclides(mat % nuclide(i)) % obj) + type is (MgxsIso) + call fatal_error("Invalid passing of MgxsIso to MgxsAngle object") + type is (MgxsAngle) + ! Add contributions to total, absorption, and fission data (if necessary) + this % total(:, :, :) = this % total(:, :, :) + & + atom_density * nuc % total(:, :, :) + this % absorption(:, :, :) = this % absorption(:, :, :) + & + atom_density * nuc % absorption(:, :, :) + if (nuc % fissionable) then + this % chi = this % chi + atom_density * nuc % chi + this % nu_fission(:, :, :) = this % nu_fission(:, :, :) + & + atom_density * nuc % nu_fission(:, :, :) + if (allocated(nuc % fission)) then + this % fission(:, :, :) = this % fission(:, :, :) + & + atom_density * nuc % fission(:, :, :) + end if + if (allocated(nuc % k_fission)) then + this % k_fission(:, :, :) = this % k_fission(:, :, :) + & + atom_density * nuc % k_fission(:, :, :) + end if + end if + + ! Get the multiplication matrix + ! To combine from nuclidic data we need to use the final relationship + ! mult_{gg'} = sum_i(N_i*nuscatt_{i,g,g'}) / + ! sum_i(N_i*(nuscatt_{i,g,g'} / mult_{i,g,g'})) + ! Developed as follows: + ! mult_{gg'} = nuScatt{g,g'} / Scatt{g,g'} + ! mult_{gg'} = sum_i(N_i*nuscatt_{i,g,g'}) / sum(N_i*scatt_{i,g,g'}) + ! mult_{gg'} = sum_i(N_i*nuscatt_{i,g,g'}) / + ! sum_i(N_i*(nuscatt_{i,g,g'} / mult_{i,g,g'})) + ! nuscatt_{i,g,g'} can be reconstructed from scatter % energy and + ! scatter % scattxs + do ipol = 1, n_pol + do iazi = 1, n_azi + do gin = 1, groups + do gout = nuc % scatter(iazi, ipol) % obj % gmin(gin), & + nuc % scatter(iazi, ipol) % obj % gmax(gin) + nuscatt = nuc % scatter(iazi, ipol) % obj % scattxs(gin) * & + nuc % scatter(iazi, ipol) % obj % energy(gin) % data(gout) + mult_num(gout, gin, iazi, ipol) = mult_num(gout, gin, iazi, ipol) + & + atom_density * nuscatt + mult_denom(gout, gin, iazi, ipol) = & + mult_denom(gout, gin, iazi, ipol) + & + atom_density * nuscatt / & + nuc % scatter(iazi, ipol) % obj % mult(gin) % data(gout) + end do + end do + end do + end do + + ! Get the complete scattering matrix + nuc_order_dim = size(nuc % scatter(1, 1) % obj % dist(1) % data, dim=1) + do ipol = 1, n_pol + do iazi = 1, n_azi + scatt_coeffs(1:min(nuc_order_dim, order_dim), :, :, iazi, ipol) = & + scatt_coeffs(1:min(nuc_order_dim, order_dim), :, :, iazi, ipol) + & + atom_density * nuc % scatter(iazi, ipol) % obj % get_matrix(& + min(nuc_order_dim, order_dim)) + end do + end do + end select + end do + + ! Obtain temp_mult + do ipol = 1, n_pol + do iazi = 1, n_azi + do gin = 1, groups + do gout = 1, groups + if (mult_denom(gout, gin, iazi, ipol) > ZERO) then + temp_mult(gout, gin, iazi, ipol) = & + mult_num(gout, gin, iazi, ipol) / & + mult_denom(gout, gin, iazi, ipol) + else + temp_mult(gout, gin, iazi, ipol) = ONE + end if + end do + end do + end do + end do + + ! Initialize the ScattData Object + do ipol = 1, n_pol + do iazi = 1, n_azi + call this % scatter(iazi, ipol) % obj % init( & + temp_mult(:, :, iazi, ipol), scatt_coeffs(:, :, :, iazi, ipol)) + end do + end do + + ! Now normalize chi + if (mat % fissionable) then + do ipol = 1, n_pol + do iazi = 1, n_azi + do gin = 1, groups + norm = sum(this % chi(:, gin, iazi, ipol)) + if (norm > ZERO) then + this % chi(:, gin, iazi, ipol) = this % chi(:, gin, iazi, ipol) / norm + end if + end do + end do + end do + end if + + ! Deallocate temporaries for the next material + deallocate(scatt_coeffs, temp_mult) + + end subroutine mgxsang_combine + +!=============================================================================== +! MGXS*_SAMPLE_FISSION_ENERGY samples the outgoing energy from a fission event +!=============================================================================== + + function mgxsiso_sample_fission_energy(this, gin, uvw) result(gout) + class(MgxsIso), intent(in) :: this ! Data to work with + integer, intent(in) :: gin ! Incoming energy group + real(8), intent(in) :: uvw(3) ! Particle Direction + integer :: gout ! Sampled outgoing group + real(8) :: xi ! Our random number + real(8) :: prob ! Running probability + + xi = prn() + gout = 1 + prob = this % chi(gout,gin) + + do while (prob < xi) + gout = gout + 1 + prob = prob + this % chi(gout,gin) + end do + + end function mgxsiso_sample_fission_energy + + function mgxsang_sample_fission_energy(this, gin, uvw) result(gout) + class(MgxsAngle), intent(in) :: this ! Data to work with + integer, intent(in) :: gin ! Incoming energy group + real(8), intent(in) :: uvw(3) ! Particle Direction + integer :: gout ! Sampled outgoing group + real(8) :: xi ! Our random number + real(8) :: prob ! Running probability + integer :: iazi, ipol + + call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) + + xi = prn() + gout = 1 + prob = this % chi(gout, gin, iazi, ipol) + + do while (prob < xi) + gout = gout + 1 + prob = prob + this % chi(gout, gin, iazi, ipol) + end do + + end function mgxsang_sample_fission_energy + +!=============================================================================== +! MGXS*_SAMPLE_SCATTER Selects outgoing energy and angle after a scatter event +!=============================================================================== + + subroutine mgxsiso_sample_scatter(this, uvw, gin, gout, mu, wgt) + class(MgxsIso), intent(in) :: this + real(8), intent(in) :: uvw(3) ! Incoming neutron direction + integer, intent(in) :: gin ! Incoming neutron group + integer, intent(out) :: gout ! Sampled outgoin group + real(8), intent(out) :: mu ! Sampled change in angle + real(8), intent(inout) :: wgt ! Particle weight + + call this % scatter % sample(gin, gout, mu, wgt) + + end subroutine mgxsiso_sample_scatter + + subroutine mgxsang_sample_scatter(this, uvw, gin, gout, mu, wgt) + class(MgxsAngle), intent(in) :: this + real(8), intent(in) :: uvw(3) ! Incoming neutron direction + integer, intent(in) :: gin ! Incoming neutron group + integer, intent(out) :: gout ! Sampled outgoin group + real(8), intent(out) :: mu ! Sampled change in angle + real(8), intent(inout) :: wgt ! Particle weight + + integer :: iazi, ipol ! Angular indices + + call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) + call this % scatter(iazi, ipol) % obj % sample(gin, gout, mu, wgt) + + end subroutine mgxsang_sample_scatter + +!=============================================================================== +! MGXS*_CALCULATE_XS determines the multi-group cross sections +! for the material the particle is currently traveling through. +!=============================================================================== + + subroutine mgxsiso_calculate_xs(this, gin, uvw, xs) + class(MgxsIso), intent(in) :: this + integer, intent(in) :: gin ! Incoming neutron group + real(8), intent(in) :: uvw(3) ! Incoming neutron direction + type(MaterialMacroXS), intent(inout) :: xs ! Resultant Mgxs Data + + xs % total = this % total(gin) + xs % elastic = this % scatter % scattxs(gin) + xs % absorption = this % absorption(gin) + xs % fission = this % fission(gin) + xs % nu_fission = this % nu_fission(gin) + + end subroutine mgxsiso_calculate_xs + + subroutine mgxsang_calculate_xs(this, gin, uvw, xs) + class(MgxsAngle), intent(in) :: this + integer, intent(in) :: gin ! Incoming neutron group + real(8), intent(in) :: uvw(3) ! Incoming neutron direction + type(MaterialMacroXS), intent(inout) :: xs ! Resultant Mgxs Data + + integer :: iazi, ipol + + call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) + xs % total = this % total(gin, iazi, ipol) + xs % elastic = this % scatter(iazi, ipol) % obj % scattxs(gin) + xs % absorption = this % absorption(gin, iazi, ipol) + xs % fission = this % fission(gin, iazi, ipol) + xs % nu_fission = this % nu_fission(gin, iazi, ipol) + + end subroutine mgxsang_calculate_xs + +!=============================================================================== +! find_angle finds the closest angle on the data grid and returns that index +!=============================================================================== + + pure subroutine find_angle(polar, azimuthal, uvw, i_azi, i_pol) + real(8), intent(in) :: polar(:) ! Polar angles [0,pi] + real(8), intent(in) :: azimuthal(:) ! Azi. angles [-pi,pi] + real(8), intent(in) :: uvw(3) ! Direction of motion + integer, intent(inout) :: i_pol ! Closest polar bin + integer, intent(inout) :: i_azi ! Closest azi bin + + real(8) :: my_pol, my_azi, dangle + + ! Convert uvw to polar and azi + + my_pol = acos(uvw(3)) + my_azi = atan2(uvw(2), uvw(1)) + + ! Search for equi-binned angles + dangle = PI / real(size(polar),8) + i_pol = floor(my_pol / dangle + ONE) + dangle = TWO * PI / real(size(azimuthal),8) + i_azi = floor((my_azi + PI) / dangle + ONE) + + end subroutine find_angle + +end module mgxs_header \ No newline at end of file diff --git a/src/multipole.F90 b/src/multipole.F90 index cb83d85d1..59c7fed69 100644 --- a/src/multipole.F90 +++ b/src/multipole.F90 @@ -6,6 +6,7 @@ module multipole use hdf5_interface use multipole_header, only: MultipoleArray, FIT_T, FIT_A, FIT_F, & MP_FISS, FORM_MLBW, FORM_RM + use search, only: binary_search implicit none @@ -23,163 +24,191 @@ contains type(MultipoleArray), intent(out), target :: multipole ! The object to fill integer, intent(in) :: i_table ! index in nuclides/ ! sab_tables - integer(HID_T) :: file_id integer(HID_T) :: group_id - - ! Intermediate loading components - integer :: NMT - integer :: i, j - integer, allocatable :: MT(:) - logical :: accumulated_fission - character(len=24) :: MT_n ! Takes the form '/nuclide/reactions/MT???' integer :: is_fissionable + real(8) :: insert_pts(4) ! New points in the energy grid + integer :: cut1, cut2 ! Old indices just outside MP region + integer :: new_n_grid ! Number of points in new E grid + real(8), allocatable :: new_energy(:) ! New energy grid + real(8) :: f1, f2 ! Interpolation near cut1 & cut2 + real(8), allocatable :: new_xs(:) ! New cross sections + integer :: i + integer :: IE ! Reaction threshold associate (nuc => nuclides(i_table)) - ! Open file for reading and move into the /isotope group + !========================================================================= + ! Copy in data from the file. + + ! Open file for reading and move into the /isotope group. file_id = file_open(filename, 'r', parallel=.true.) group_id = open_group(file_id, "/nuclide") - ! Load in all the array size scalars - call read_dataset(group_id, "length", multipole % length) - call read_dataset(group_id, "windows", multipole % windows) - call read_dataset(group_id, "num_l", multipole % num_l) - call read_dataset(group_id, "fit_order", multipole % fit_order) - call read_dataset(group_id, "max_w", multipole % max_w) - call read_dataset(group_id, "fissionable", is_fissionable) + ! Load in all the array size scalars. + call read_dataset(multipole % length, group_id, "length") + call read_dataset(multipole % windows, group_id, "windows") + call read_dataset(multipole % num_l, group_id, "num_l") + call read_dataset(multipole % fit_order, group_id, "fit_order") + call read_dataset(multipole % max_w, group_id, "max_w") + call read_dataset(is_fissionable, group_id, "fissionable") if (is_fissionable == MP_FISS) then multipole % fissionable = .true. else multipole % fissionable = .false. end if - call read_dataset(group_id, "formalism", multipole % formalism) + call read_dataset(multipole % formalism, group_id, "formalism") - call read_dataset(group_id, "spacing", multipole % spacing) - call read_dataset(group_id, "sqrtAWR", multipole % sqrtAWR) - call read_dataset(group_id, "start_E", multipole % start_E) - call read_dataset(group_id, "end_E", multipole % end_E) + call read_dataset(multipole % spacing, group_id, "spacing") + call read_dataset(multipole % sqrtAWR, group_id, "sqrtAWR") + call read_dataset(multipole % start_E, group_id, "start_E") + call read_dataset(multipole % end_E, group_id, "end_E") - ! Allocate the multipole array components + ! Allocate the multipole array components. call multipole % allocate() - ! Read in arrays - call read_dataset(group_id, "data", multipole % data) - call read_dataset(group_id, "pseudo_K0RS", multipole % pseudo_k0RS) - call read_dataset(group_id, "l_value", multipole % l_value) - call read_dataset(group_id, "w_start", multipole % w_start) - call read_dataset(group_id, "w_end", multipole % w_end) - call read_dataset(group_id, "broaden_poly", multipole % broaden_poly) + ! Read in arrays. + call read_dataset(multipole % data, group_id, "data") + call read_dataset(multipole % pseudo_k0RS, group_id, "pseudo_K0RS") + call read_dataset(multipole % l_value, group_id, "l_value") + call read_dataset(multipole % w_start, group_id, "w_start") + call read_dataset(multipole % w_end, group_id, "w_end") + call read_dataset(multipole % broaden_poly, group_id, "broaden_poly") - call read_dataset(group_id, "curvefit", multipole % curvefit) - - ! Delete ACE pointwise data - call read_dataset(group_id, "n_grid", nuc % n_grid) - - deallocate(nuc % energy) - deallocate(nuc % total) - deallocate(nuc % elastic) - deallocate(nuc % fission) - deallocate(nuc % nu_fission) - deallocate(nuc % absorption) - - allocate(nuc % energy(nuc % n_grid)) - allocate(nuc % total(nuc % n_grid)) - allocate(nuc % elastic(nuc % n_grid)) - allocate(nuc % fission(nuc % n_grid)) - allocate(nuc % nu_fission(nuc % n_grid)) - allocate(nuc % absorption(nuc % n_grid)) - - nuc % total(:) = ZERO - nuc % absorption(:) = ZERO - nuc % fission(:) = ZERO - - ! Read in new energy axis (converting eV to MeV) - call read_dataset(group_id, "energy_points", nuc % energy) - nuc % energy = nuc % energy / 1.0e6_8 - - ! Get count and list of MT tables - call read_dataset(group_id, "MT_count", NMT) - allocate(MT(NMT)) - - call read_dataset(group_id, "MT_list", MT) + call read_dataset(multipole % curvefit, group_id, "curvefit") + ! Close the file. call close_group(group_id) + call file_close(file_id) - accumulated_fission = .false. + !========================================================================= + ! Remove the uneeded/inconsitent pointwise data. This step enforces the + ! assumption that no inelastic scattering reactions can occur in the + ! multipole region. The energy grid is replaced with one that removes all + ! energies covered by multiple and adds four new points. Two new points + ! mark the edges of the multipole region and cross sections will be + ! interpolated to these points. The other two points are used to zero the + ! cross sections inside the multipole region. - ! Loop over each MT entry and load it into a reaction. - do i = 1, NMT - write(MT_n, '(A, I3.3)') '/nuclide/reactions/MT', MT(i) + ! Define the four new inserted points. + insert_pts(:) = [multipole % start_E / 1e6_8, & + multipole % start_E / 1e6_8 + 1e-12_8, & + multipole % end_E / 1e6_8 - 1e-12_8, & + multipole % end_E / 1e6_8] - group_id = open_group(file_id, MT_n) + ! Find the points just outside the multipole region. + cut1 = binary_search(nuc % energy, nuc % n_grid, insert_pts(1)) + cut2 = binary_search(nuc % energy, nuc % n_grid, insert_pts(4)) + 1 + if (nuc % energy(cut1) == insert_pts(1)) cut1 = cut1 - 1 + if (nuc % energy(cut2) == insert_pts(4)) cut2 = cut2 + 1 - ! Each MT needs to be treated slightly differently. - select case (MT(i)) - case(ELASTIC) - call read_dataset(group_id, "MT_sigma", nuc % elastic) - nuc % total(:) = nuc % total + nuc % elastic - case(N_FISSION) - call read_dataset(group_id, "MT_sigma", nuc % fission) - nuc % total(:) = nuc % total + nuc % fission - nuc % absorption(:) = nuc % absorption + nuc % fission - accumulated_fission = .true. - case default - ! Search through all of our secondary reactions - do j = 1, nuc % n_reaction - if (nuc % reactions(j) % MT == MT(i)) then - ! Match found + ! Generate the new energy grid. + new_n_grid = nuc % n_grid - (cut2 - cut1 - 1) + 4 + allocate(new_energy(new_n_grid)) + new_energy(1:cut1) = nuc % energy(1:cut1) + new_energy(cut1+1:cut1+4) = insert_pts(:) + new_energy(cut1+5:new_n_grid) = nuc % energy(cut2:nuc % n_grid) - ! Individual Fission components exist, so remove the combined - ! fission cross section. - if ( (MT(i) == N_F .or. MT(i) == N_NF .or. MT(i) == N_2NF & - .or. MT(i) == N_3NF) .and. accumulated_fission) then - nuc % total(:) = nuc % total - nuc % fission - nuc % absorption(:) = nuc % absorption - nuc % fission - nuc % fission(:) = ZERO - accumulated_fission = .false. - end if + ! Compute interpolation factors for the new energy points. + f1 = (insert_pts(1) - nuc % energy(cut1)) & + / (nuc % energy(cut1+1) - nuc % energy(cut1)) + f2 = (insert_pts(4) - nuc % energy(cut2-1)) & + / (nuc % energy(cut2) - nuc % energy(cut2-1)) - deallocate(nuc % reactions(j) % sigma) - allocate(nuc % reactions(j) % sigma(nuc % n_grid)) + ! Adjust the total cross section. + allocate(new_xs(new_n_grid)) + new_xs(1:cut1) = nuc % total(1:cut1) + new_xs(cut1+1) = (ONE - f1) * nuc % total(cut1) & + + f1 * nuc % total(cut1+1) + new_xs(cut1+2:cut1+3) = ZERO + new_xs(cut1+4) = (ONE - f2) * nuc % total(cut2-1) & + + f2 * nuc % total(cut2) + new_xs(cut1+5:new_n_grid) = nuc % total(cut2:nuc % n_grid) + call move_alloc(new_xs, nuc % total) - call read_dataset(group_id, "MT_sigma", & - nuc % reactions(j) % sigma) - call read_dataset(group_id, "Q_value", & - nuc % reactions(j) % Q_value) - call read_dataset(group_id, "threshold", & - nuc % reactions(j) % threshold) - nuc % reactions(j) % threshold = 1 ! TODO: reconsider implications. - nuc % reactions(j) % Q_value = nuc % reactions(j) % Q_value & - / 1.0e6_8 + ! Adjust the elastic cross section. + allocate(new_xs(new_n_grid)) + new_xs(1:cut1) = nuc % elastic(1:cut1) + new_xs(cut1+1) = (ONE - f1) * nuc % elastic(cut1) & + + f1 * nuc % elastic(cut1+1) + new_xs(cut1+2:cut1+3) = ZERO + new_xs(cut1+4) = (ONE - f2) * nuc % elastic(cut2-1) & + + f2 * nuc % elastic(cut2) + new_xs(cut1+5:new_n_grid) = nuc % elastic(cut2:nuc % n_grid) + call move_alloc(new_xs, nuc % elastic) - ! Accumulate total - if (MT(i) /= N_LEVEL .and. MT(i) <= N_DA) then - nuc % total(:) = nuc % total + nuc % reactions(j) % sigma - end if + ! Adjust the fission cross section. + allocate(new_xs(new_n_grid)) + new_xs(1:cut1) = nuc % fission(1:cut1) + new_xs(cut1+1) = (ONE - f1) * nuc % fission(cut1) & + + f1 * nuc % fission(cut1+1) + new_xs(cut1+2:cut1+3) = ZERO + new_xs(cut1+4) = (ONE - f2) * nuc % fission(cut2-1) & + + f2 * nuc % fission(cut2) + new_xs(cut1+5:new_n_grid) = nuc % fission(cut2:nuc % n_grid) + call move_alloc(new_xs, nuc % fission) - ! Accumulate absorption - if (MT(i) >= N_GAMMA .and. MT(i) <= N_DA) then - nuc % absorption(:) = nuc % absorption & - + nuc % reactions(j) % sigma - end if + ! Adjust the nu-fission cross section. + allocate(new_xs(new_n_grid)) + new_xs(1:cut1) = nuc % nu_fission(1:cut1) + new_xs(cut1+1) = (ONE - f1) * nuc % nu_fission(cut1) & + + f1 * nuc % nu_fission(cut1+1) + new_xs(cut1+2:cut1+3) = ZERO + new_xs(cut1+4) = (ONE - f2) * nuc % nu_fission(cut2-1) & + + f2 * nuc % nu_fission(cut2) + new_xs(cut1+5:new_n_grid) = nuc % nu_fission(cut2:nuc % n_grid) + call move_alloc(new_xs, nuc % nu_fission) - ! Accumulate fission (if needed) - if ( (MT(i) == N_F .or. MT(i) == N_NF .or. MT(i) == N_2NF & - .or. MT(i) == N_3NF) ) then - nuc % fission(:) = nuc % fission + nuc % reactions(j) % sigma - nuc % absorption(:) = nuc % absorption & - + nuc % reactions(j) % sigma - end if - end if - end do - end select + ! Adjust the absorption cross section. + allocate(new_xs(new_n_grid)) + new_xs(1:cut1) = nuc % absorption(1:cut1) + new_xs(cut1+1) = (ONE - f1) * nuc % absorption(cut1) & + + f1 * nuc % absorption(cut1+1) + new_xs(cut1+2:cut1+3) = ZERO + new_xs(cut1+4) = (ONE - f2) * nuc % absorption(cut2-1) & + + f2 * nuc % absorption(cut2) + new_xs(cut1+5:new_n_grid) = nuc % absorption(cut2:nuc % n_grid) + call move_alloc(new_xs, nuc % absorption) - call close_group(group_id) + ! Adjust other cross sections. + do i = 1, nuc % n_reaction + associate (rxn => nuc % reactions(i)) + if (.not. allocated(rxn % sigma)) cycle ! Skip unallocated reactions + IE = rxn % threshold + if (rxn % threshold >= cut2) then + ! The threshold is above the multipole range. All we need to do + ! is adjust the threshold index to match the new grid. + rxn % threshold = rxn % threshold - (cut2 - cut1 - 1) + 4 + else if (rxn % threshold <= cut1) then + ! The threhold is below the multipole range. Remove the multipole + ! region just like we did with the other reactions. + ! The new grid removed (cut2 - cut1 - 1) points and added 4. + allocate(new_xs(size(rxn % sigma) - (cut2 - cut1 - 1) + 4)) + new_xs(1:cut1-IE+1) = rxn % sigma(1:cut1-IE+1) + new_xs(cut1-IE+2) = (ONE - f1) * rxn % sigma(cut1-IE+1) & + + f1 * rxn % sigma(cut1-IE+2) + new_xs(cut1-IE+3:cut1-IE+4) = ZERO + new_xs(cut1-IE+5) = (ONE - f2) * rxn % sigma(cut2-IE) & + + f2 * rxn % sigma(cut2-IE+1) + new_xs(cut1-IE+6:size(new_xs)) = & + rxn % sigma(cut2-IE+1:size(rxn % sigma)) + call move_alloc(new_xs, rxn % sigma) + else + ! The threshold lies within the multipole range. Remove the first + ! cut2-IE points and add an interpolated point + allocate(new_xs(size(rxn % sigma) - (cut2-IE) + 1)) + new_xs(1) = (ONE - f2) * rxn % sigma(cut2-IE) & + + f2 * rxn % sigma(cut2-IE+1) + new_xs(2:size(new_xs)) = rxn % sigma(cut2-IE+1:size(rxn % sigma)) + call move_alloc(new_xs, rxn % sigma) + rxn % threshold = cut1 + 4 + end if + end associate end do - ! Close file - call file_close(file_id) + ! Apply the new energy grid. + nuc % n_grid = new_n_grid + call move_alloc(new_energy, nuc % energy) end associate diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index ca128b6e1..2c59e700d 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -8,7 +8,7 @@ module nuclide_header use endf_header, only: Function1D use error, only: fatal_error, warning use list_header, only: ListInt - use math, only: evaluate_legendre, find_angle + use math, only: evaluate_legendre use multipole_header, only: MultipoleArray use product_header, only: AngleEnergyContainer use reaction_header, only: Reaction @@ -20,12 +20,12 @@ module nuclide_header implicit none !=============================================================================== -! Nuclide contains the base nuclidic data for a nuclide, which does not depend -! upon how the nuclear data is represented (i.e., CE, or any variant of MG). -! The extended types, NuclideCE and NuclideMG deal with the rest +! Nuclide contains the base nuclidic data for a nuclide described as needed +! for continuous-energy neutron transport. !=============================================================================== - type, abstract :: Nuclide + type :: Nuclide + ! Nuclide meta-data character(12) :: name ! name of nuclide, e.g. 92235.03c integer :: zaid ! Z and A identifier, e.g. 92235 real(8) :: awr ! Atomic Weight Ratio @@ -33,21 +33,8 @@ module nuclide_header real(8) :: kT ! temperature in MeV (k*T) ! Fission information - logical :: fissionable ! nuclide is fissionable? + logical :: fissionable ! nuclide is fissionable? - contains - procedure(nuclide_print_), deferred :: print ! Writes nuclide info - end type Nuclide - - abstract interface - subroutine nuclide_print_(this, unit) - import Nuclide - class(Nuclide),intent(in) :: this - integer, optional, intent(in) :: unit - end subroutine nuclide_print_ - end interface - - type, extends(Nuclide) :: NuclideCE ! Energy grid information integer :: n_grid ! # of nuclide grid points integer, allocatable :: grid_index(:) ! log grid mapping indices @@ -95,129 +82,14 @@ module nuclide_header ! array; used at tally-time contains - procedure :: clear => nuclidece_clear - procedure :: print => nuclidece_print - procedure :: nu => nuclidece_nu - end type NuclideCE - - type, abstract, extends(Nuclide) :: NuclideMG - ! Scattering Order Information - integer :: order ! Order of data (Scattering for NuclideIso, - ! Number of angles for all in NuclideAngle) - integer :: scatt_type ! either legendre, histogram, or tabular. - integer :: legendre_mu_points ! Number of tabular points to use to represent - ! Legendre distribs, -1 if sample with the - ! Legendres themselves - contains - procedure(nuclidemg_init_), deferred :: init ! Initialize the data - procedure(nuclidemg_get_xs_), deferred :: get_xs ! Get the requested xs - procedure(nuclidemg_calc_f_), deferred :: calc_f ! Calculates f, given mu - end type NuclideMG - - abstract interface - - subroutine nuclidemg_init_(this, node_xsdata, groups, get_kfiss, get_fiss) - import NuclideMG, Node - class(NuclideMG), intent(inout) :: this ! Working Object - type(Node), pointer, intent(in) :: node_xsdata ! Data from MGXS xml - integer, intent(in) :: groups ! Number of Energy groups - logical, intent(in) :: get_kfiss ! Need Kappa-Fission? - logical, intent(in) :: get_fiss ! Should we get fiss data? - end subroutine nuclidemg_init_ - - function nuclidemg_get_xs_(this, g, xstype, gout, uvw, mu, i_azi, i_pol) & - result(xs) - import NuclideMG - class(NuclideMG), intent(in) :: this - integer, intent(in) :: g ! Incoming Energy group - character(*), intent(in) :: xstype ! Cross Section Type - integer, optional, intent(in) :: gout ! Outgoing Group - real(8), optional, intent(in) :: uvw(3) ! Requested Angle - real(8), optional, intent(in) :: mu ! Change in angle - integer, optional, intent(in) :: i_azi ! Azimuthal Index - integer, optional, intent(in) :: i_pol ! Polar Index - real(8) :: xs ! Resultant xs - end function nuclidemg_get_xs_ - - pure function nuclidemg_calc_f_(this, gin, gout, mu, uvw, i_azi, i_pol) result(f) - import NuclideMG - class(NuclideMG), intent(in) :: this - integer, intent(in) :: gin ! Incoming Energy Group - integer, intent(in) :: gout ! Outgoing Energy Group - real(8), intent(in) :: mu ! Angle of interest - real(8), intent(in), optional :: uvw(3) ! Direction vector - integer, intent(in), optional :: i_azi ! Incoming Energy Group - integer, intent(in), optional :: i_pol ! Outgoing Energy Group - real(8) :: f ! Return value of f(mu) - - end function nuclidemg_calc_f_ - end interface - -!=============================================================================== -! NuclideIso contains the base MGXS data for a nuclide specifically for -! isotropically weighted MGXS -!=============================================================================== - - type, extends(NuclideMG) :: NuclideIso - - ! Microscopic cross sections - real(8), allocatable :: total(:) ! total cross section - real(8), allocatable :: absorption(:) ! absorption cross section - real(8), allocatable :: scatter(:,:,:) ! scattering information - real(8), allocatable :: nu_fission(:,:) ! fission matrix (Gout x Gin) - real(8), allocatable :: k_fission(:) ! kappa-fission - real(8), allocatable :: fission(:) ! neutron production - real(8), allocatable :: chi(:) ! Fission Spectra - real(8), allocatable :: mult(:,:) ! Scatter multiplicity (Gout x Gin) - - contains - procedure :: init => nuclideiso_init ! Initialize Nuclidic MGXS Data - procedure :: print => nuclideiso_print ! Writes nuclide info - procedure :: get_xs => nuclideiso_get_xs ! Gets Size of Data w/in Object - procedure :: calc_f => nuclideiso_calc_f ! Calcs f given mu - end type NuclideIso - -!=============================================================================== -! NuclideAngle contains the base MGXS data for a nuclide specifically for -! explicit angle-dependent weighted MGXS -!=============================================================================== - - type, extends(NuclideMG) :: NuclideAngle - - ! Microscopic cross sections. Dimensions are: (n_pol, n_azi, Nl, Ng, Ng) - real(8), allocatable :: total(:,:,:) ! total cross section - real(8), allocatable :: absorption(:,:,:) ! absorption cross section - real(8), allocatable :: scatter(:,:,:,:,:) ! scattering information - real(8), allocatable :: nu_fission(:,:,:,:) ! fission matrix (Gout x Gin) - real(8), allocatable :: k_fission(:,:,:) ! kappa-fission - real(8), allocatable :: fission(:,:,:) ! neutron production - real(8), allocatable :: chi(:,:,:) ! Fission Spectra - real(8), allocatable :: mult(:,:,:,:) ! Scatter multiplicity (Gout x Gin) - - ! In all cases, right-most indices are theta, phi - integer :: n_pol ! Number of polar angles - integer :: n_azi ! Number of azimuthal angles - real(8), allocatable :: polar(:) ! polar angles - real(8), allocatable :: azimuthal(:) ! azimuthal angles - - contains - procedure :: init => nuclideangle_init ! Initialize Nuclidic MGXS Data - procedure :: print => nuclideangle_print ! Gets Size of Data w/in Object - procedure :: get_xs => nuclideangle_get_xs ! Gets Size of Data w/in Object - procedure :: calc_f => nuclideangle_calc_f ! Calcs f given mu - end type NuclideAngle - -!=============================================================================== -! NUCLIDEMGCONTAINER pointer array for storing Nuclides -!=============================================================================== - - type NuclideMGContainer - class(NuclideMG), pointer :: obj - end type NuclideMGContainer + procedure :: clear => nuclide_clear + procedure :: print => nuclide_print + procedure :: nu => nuclide_nu + end type Nuclide !=============================================================================== ! NUCLIDE0K temporarily contains all 0K cross section data and other parameters -! needed to treat resonance scattering before transferring them to NuclideCE +! needed to treat resonance scattering before transferring them to Nuclide !=============================================================================== type Nuclide0K @@ -294,397 +166,11 @@ module nuclide_header contains !=============================================================================== -! NUCLIDE_*_INIT reads in the data from the XML file, as already accessed +! NUCLIDE_CLEAR resets and deallocates data in Nuclide !=============================================================================== - subroutine nuclidemg_init(this, node_xsdata) - class(NuclideMG), intent(inout) :: this ! Working Object - type(Node), pointer, intent(in) :: node_xsdata ! Data from MGXS xml - - type(Node), pointer :: node_legendre_mu - character(MAX_LINE_LEN) :: temp_str - logical :: enable_leg_mu - - ! Load the data - call get_node_value(node_xsdata, "name", this % name) - this % name = to_lower(this % name) - if (check_for_node(node_xsdata, "kT")) then - call get_node_value(node_xsdata, "kT", this % kT) - else - this % kT = ZERO - end if - if (check_for_node(node_xsdata, "zaid")) then - call get_node_value(node_xsdata, "zaid", this % zaid) - else - this % zaid = -1 - end if - if (check_for_node(node_xsdata, "scatt_type")) then - call get_node_value(node_xsdata, "scatt_type", temp_str) - temp_str = trim(to_lower(temp_str)) - if (temp_str == 'legendre') then - this % scatt_type = ANGLE_LEGENDRE - else if (temp_str == 'histogram') then - this % scatt_type = ANGLE_HISTOGRAM - else if (temp_str == 'tabular') then - this % scatt_type = ANGLE_TABULAR - else - call fatal_error("Invalid Scatt Type Option!") - end if - else - this % scatt_type = ANGLE_LEGENDRE - end if - - if (check_for_node(node_xsdata, "order")) then - call get_node_value(node_xsdata, "order", this % order) - else - call fatal_error("Order Must Be Provided!") - end if - - ! Get scattering treatment - if (check_for_node(node_xsdata, "tabular_legendre")) then - call get_node_ptr(node_xsdata, "tabular_legendre", node_legendre_mu) - if (check_for_node(node_legendre_mu, "enable")) then - call get_node_value(node_legendre_mu, "enable", temp_str) - temp_str = trim(to_lower(temp_str)) - if (temp_str == 'true' .or. temp_str == '1') then - enable_leg_mu = .true. - elseif (temp_str == 'false' .or. temp_str == '0') then - enable_leg_mu = .false. - this % legendre_mu_points = 1 - else - call fatal_error("Unrecognized tabular_legendre/enable: " // temp_str) - end if - else - enable_leg_mu = .true. - this % legendre_mu_points = 33 - end if - if (enable_leg_mu .and. & - check_for_node(node_legendre_mu, "num_points")) then - call get_node_value(node_legendre_mu, "num_points", & - this % legendre_mu_points) - if (this % legendre_mu_points <= 0) then - call fatal_error("num_points element must be positive and non-zero!") - end if - this % legendre_mu_points = -1 * this % legendre_mu_points - end if - else - this % legendre_mu_points = 1 - end if - - if (check_for_node(node_xsdata, "fissionable")) then - call get_node_value(node_xsdata, "fissionable", temp_str) - temp_str = to_lower(temp_str) - if (trim(temp_str) == 'true' .or. trim(temp_str) == '1') then - this % fissionable = .true. - else - this % fissionable = .false. - end if - else - call fatal_error("Fissionable element must be set!") - end if - - end subroutine nuclidemg_init - - subroutine nuclideiso_init(this, node_xsdata, groups, get_kfiss, get_fiss) - class(NuclideIso), intent(inout) :: this ! Working Object - type(Node), pointer, intent(in) :: node_xsdata ! Data from MGXS xml - integer, intent(in) :: groups ! Number of Energy groups - logical, intent(in) :: get_kfiss ! Need Kappa-Fission? - logical, intent(in) :: get_fiss ! Need fiss data? - - real(8), allocatable :: temp_arr(:) - integer :: arr_len - integer :: order_dim - - ! Call generic data gathering routine - call nuclidemg_init(this, node_xsdata) - - ! Load the more specific data - if (this % fissionable) then - - if (check_for_node(node_xsdata, "chi")) then - ! Get chi - allocate(this % chi(groups)) - call get_node_array(node_xsdata, "chi", this % chi) - - ! Get nu_fission (as a vector) - if (check_for_node(node_xsdata, "nu_fission")) then - allocate(temp_arr(groups * 1)) - call get_node_array(node_xsdata, "nu_fission", temp_arr) - allocate(this % nu_fission(groups, 1)) - this % nu_fission = reshape(temp_arr, (/groups, 1/)) - deallocate(temp_arr) - else - call fatal_error("If fissionable, must provide nu_fission!") - end if - - else - ! Get nu_fission (as a matrix) - if (check_for_node(node_xsdata, "nu_fission")) then - - allocate(temp_arr(groups*groups)) - call get_node_array(node_xsdata, "nu_fission", temp_arr) - allocate(this % nu_fission(groups, groups)) - this % nu_fission = reshape(temp_arr, (/groups, groups/)) - deallocate(temp_arr) - else - call fatal_error("If fissionable, must provide nu_fission!") - end if - end if - if (get_fiss) then - allocate(this % fission(groups)) - if (check_for_node(node_xsdata, "fission")) then - call get_node_array(node_xsdata, "fission", this % fission) - else - call fatal_error("Fission data missing, required due to fission& - & tallies in tallies.xml file!") - end if - end if - if (get_kfiss) then - allocate(this % k_fission(groups)) - if (check_for_node(node_xsdata, "kappa_fission")) then - call get_node_array(node_xsdata, "kappa_fission", this % k_fission) - else - call fatal_error("kappa_fission data missing, required due to & - &kappa-fission tallies in tallies.xml file!") - end if - end if - end if - - allocate(this % absorption(groups)) - if (check_for_node(node_xsdata, "absorption")) then - call get_node_array(node_xsdata, "absorption", this % absorption) - else - call fatal_error("Must provide absorption!") - end if - - if (this % scatt_type == ANGLE_LEGENDRE) then - order_dim = this % order + 1 - else if (this % scatt_type == ANGLE_HISTOGRAM) then - order_dim = this % order - else if (this % scatt_type == ANGLE_TABULAR) then - order_dim = this % order - end if - - allocate(this % scatter(groups, groups, order_dim)) - if (check_for_node(node_xsdata, "scatter")) then - allocate(temp_arr(groups * groups * order_dim)) - call get_node_array(node_xsdata, "scatter", temp_arr) - this % scatter = reshape(temp_arr, (/groups, groups, order_dim/)) - deallocate(temp_arr) - else - call fatal_error("Must provide scatter!") - return - end if - - - allocate(this % total(groups)) - if (check_for_node(node_xsdata, "total")) then - call get_node_array(node_xsdata, "total", this % total) - else - this % total = this % absorption + sum(this%scatter(:,:,1),dim=1) - end if - - ! Get Mult Data - allocate(this % mult(groups, groups)) - if (check_for_node(node_xsdata, "multiplicity")) then - arr_len = get_arraysize_double(node_xsdata, "multiplicity") - if (arr_len == groups * groups) then - allocate(temp_arr(arr_len)) - call get_node_array(node_xsdata, "multiplicity", temp_arr) - this % mult = reshape(temp_arr, (/groups, groups/)) - deallocate(temp_arr) - else - call fatal_error("Multiplicity length not same as number of groups& - & squared!") - return - end if - else - this % mult = ONE - end if - - end subroutine nuclideiso_init - - subroutine nuclideangle_init(this, node_xsdata, groups, get_kfiss, get_fiss) - class(NuclideAngle), intent(inout) :: this ! Working Object - type(Node), pointer, intent(in) :: node_xsdata ! Data from MGXS xml - integer, intent(in) :: groups ! Number of Energy groups - logical, intent(in) :: get_kfiss ! Need Kappa-Fission? - logical, intent(in) :: get_fiss ! Should we get fiss data? - - real(8), allocatable :: temp_arr(:) - integer :: arr_len - real(8) :: dangle - integer :: iangle - integer :: order_dim - - ! Call generic data gathering routine - call nuclidemg_init(this, node_xsdata) - - if (this % scatt_type == ANGLE_LEGENDRE) then - order_dim = this % order + 1 - else if (this % scatt_type == ANGLE_HISTOGRAM) then - order_dim = this % order - else if (this % scatt_type == ANGLE_TABULAR) then - order_dim = this % order - end if - - if (check_for_node(node_xsdata, "num_polar")) then - call get_node_value(node_xsdata, "num_polar", this % n_pol) - else - call fatal_error("num_polar Must Be Provided!") - end if - - if (check_for_node(node_xsdata, "num_azimuthal")) then - call get_node_value(node_xsdata, "num_azimuthal", this % n_azi) - else - call fatal_error("num_azimuthal Must Be Provided!") - end if - - ! Load angle data, if present (else equally spaced) - allocate(this % polar(this % n_pol)) - allocate(this % azimuthal(this % n_azi)) - if (check_for_node(node_xsdata, "polar")) then - call fatal_error("User-Specified polar angle bins not yet supported!") - ! When this feature is supported, this line will be activated - call get_node_array(node_xsdata, "polar", this % polar) - else - dangle = PI / real(this % n_pol,8) - do iangle = 1, this % n_pol - this % polar(iangle) = (real(iangle,8) - HALF) * dangle - end do - end if - if (check_for_node(node_xsdata, "azimuthal")) then - call fatal_error("User-Specified azimuthal angle bins not yet supported!") - ! When this feature is supported, this line will be activated - call get_node_array(node_xsdata, "azimuthal", this % azimuthal) - else - dangle = TWO * PI / real(this % n_azi,8) - do iangle = 1, this % n_azi - this % azimuthal(iangle) = -PI + (real(iangle,8) - HALF) * dangle - end do - end if - - ! Load the more specific data - if (this % fissionable) then - - if (check_for_node(node_xsdata, "chi")) then - ! Get chi - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "chi", temp_arr) - allocate(this % chi(groups, this % n_azi, this % n_pol)) - this % chi = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) - deallocate(temp_arr) - - ! Get nu_fission (as a vector) - if (check_for_node(node_xsdata, "nu_fission")) then - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "nu_fission", temp_arr) - allocate(this % nu_fission(groups, 1, this % n_azi, this % n_pol)) - this % nu_fission = reshape(temp_arr, (/groups, 1, this % n_azi, & - this % n_pol/)) - deallocate(temp_arr) - else - call fatal_error("If fissionable, must provide nu_fission!") - end if - - else - ! Get nu_fission (as a matrix) - if (check_for_node(node_xsdata, "nu_fission")) then - - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "nu_fission", temp_arr) - allocate(this % nu_fission(groups, groups, this % n_azi, this % n_pol)) - this % nu_fission = reshape(temp_arr, (/groups, groups, & - this % n_azi, this % n_pol/)) - deallocate(temp_arr) - else - call fatal_error("If fissionable, must provide nu_fission!") - end if - end if - if (get_fiss) then - if (check_for_node(node_xsdata, "fission")) then - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "fission", temp_arr) - allocate(this % fission(groups, this % n_azi, this % n_pol)) - this % fission = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) - deallocate(temp_arr) - else - call fatal_error("Fission data missing, required due to fission& - & tallies in tallies.xml file!") - end if - end if - if (get_kfiss) then - if (check_for_node(node_xsdata, "kappa_fission")) then - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "kappa_fission", temp_arr) - allocate(this % k_fission(groups, this % n_azi, this % n_pol)) - this % k_fission = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) - deallocate(temp_arr) - else - call fatal_error("kappa_fission data missing, required due to & - &kappa-fission tallies in tallies.xml file!") - end if - end if - end if - - if (check_for_node(node_xsdata, "absorption")) then - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "absorption", temp_arr) - allocate(this % absorption(groups, this % n_azi, this % n_pol)) - this % absorption = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) - deallocate(temp_arr) - else - call fatal_error("Must provide absorption!") - end if - - allocate(this % scatter(groups, groups, order_dim, this % n_azi, this % n_pol)) - if (check_for_node(node_xsdata, "scatter")) then - allocate(temp_arr(groups * groups * order_dim * this % n_azi * this%n_pol)) - call get_node_array(node_xsdata, "scatter", temp_arr) - this % scatter = reshape(temp_arr, (/groups, groups, order_dim, & - this%n_azi,this%n_pol/)) - deallocate(temp_arr) - else - call fatal_error("Must provide scatter!") - end if - - if (check_for_node(node_xsdata, "total")) then - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "total", temp_arr) - allocate(this % total(groups, this % n_azi, this % n_pol)) - this % total = reshape(temp_arr, (/groups, this % n_azi, this % n_pol/)) - deallocate(temp_arr) - else - this % total = this % absorption + sum(this%scatter(:,:,1,:,:),dim=1) - end if - - ! Get Mult Data - allocate(this % mult(groups, groups, this % n_azi, this % n_pol)) - if (check_for_node(node_xsdata, "multiplicity")) then - arr_len = get_arraysize_double(node_xsdata, "multiplicity") - if (arr_len == groups * groups * this % n_azi * this % n_pol) then - allocate(temp_arr(arr_len)) - call get_node_array(node_xsdata, "multiplicity", temp_arr) - this % mult = reshape(temp_arr, (/groups, groups, this % n_azi, this % n_pol/)) - deallocate(temp_arr) - else - call fatal_error("Multiplicity Length Does Not Match!") - end if - else - this % mult = ONE - end if - - end subroutine nuclideangle_init - -!=============================================================================== -! NUCLIDECE_CLEAR resets and deallocates data in Nuclide, NuclideIso -! or NuclideAngle -!=============================================================================== - - subroutine nuclidece_clear(this) - - class(NuclideCE), intent(inout) :: this ! The Nuclide object to clear + subroutine nuclide_clear(this) + class(Nuclide), intent(inout) :: this ! The Nuclide object to clear if (associated(this % urr_data)) deallocate(this % urr_data) @@ -692,10 +178,14 @@ module nuclide_header if (associated(this % multipole)) deallocate(this % multipole) - end subroutine nuclidece_clear + end subroutine nuclide_clear - function nuclidece_nu(this, E, emission_mode, group) result(nu) - class(NuclideCE), intent(in) :: this +!=============================================================================== +! NUCLIDE_NU is an interface to the number of fission neutrons produced +!=============================================================================== + + function nuclide_nu(this, E, emission_mode, group) result(nu) + class(Nuclide), intent(in) :: this real(8), intent(in) :: E integer, intent(in) :: emission_mode integer, optional, intent(in) :: group @@ -753,15 +243,16 @@ module nuclide_header end if end select - end function nuclidece_nu + end function nuclide_nu + !=============================================================================== ! NUCLIDE*_PRINT displays information about a continuous-energy neutron ! cross_section table and its reactions and secondary angle/energy distributions !=============================================================================== - subroutine nuclidece_print(this, unit) - class(NuclideCE), intent(in) :: this + subroutine nuclide_print(this, unit) + class(Nuclide), intent(in) :: this integer, intent(in), optional :: unit integer :: i ! loop index over nuclides @@ -834,346 +325,6 @@ module nuclide_header ! Blank line at end of nuclide write(unit_,*) - end subroutine nuclidece_print - - subroutine nuclidemg_print(this, unit_) - class(NuclideMG), intent(in) :: this - integer, intent(in) :: unit_ - - character(MAX_LINE_LEN) :: temp_str - - ! Basic nuclide information - write(unit_,*) 'Nuclide ' // trim(this % name) - if (this % zaid > 0) then - ! Dont print if data was macroscopic and thus zaid & AWR would be nonsense - write(unit_,*) ' zaid = ' // trim(to_str(this % zaid)) - write(unit_,*) ' awr = ' // trim(to_str(this % awr)) - end if - write(unit_,*) ' kT = ' // trim(to_str(this % kT)) - if (this % scatt_type == ANGLE_LEGENDRE) then - temp_str = "Legendre" - write(unit_,*) ' Scattering Type = ' // trim(temp_str) - write(unit_,*) ' # of Scatter Moments = ' // & - trim(to_str(this % order)) - else if (this % scatt_type == ANGLE_HISTOGRAM) then - temp_str = "Histogram" - write(unit_,*) ' Scattering Type = ' // trim(temp_str) - write(unit_,*) ' # of Scatter Bins = ' // & - trim(to_str(this % order)) - else if (this % scatt_type == ANGLE_TABULAR) then - temp_str = "Tabular" - write(unit_,*) ' Scattering Type = ' // trim(temp_str) - write(unit_,*) ' # of Scatter Points = ' // trim(to_str(this % order)) - end if - write(unit_,*) ' Fissionable = ', this % fissionable - - end subroutine nuclidemg_print - - subroutine nuclideiso_print(this, unit) - - class(NuclideIso), intent(in) :: this - integer, optional, intent(in) :: unit - - integer :: unit_ ! unit to write to - integer :: size_total, size_scattmat, size_mgxs - - ! set default unit for writing information - if (present(unit)) then - unit_ = unit - else - unit_ = OUTPUT_UNIT - end if - - ! Write Basic Nuclide Information - call nuclidemg_print(this, unit_) - - ! Determine size of mgxs and scattering matrices - size_scattmat = (size(this % scatter) + size(this % mult)) * 8 - size_mgxs = size(this % total) + size(this % absorption) + & - size(this % nu_fission) + size(this % k_fission) + & - size(this % fission) + size(this % chi) - size_mgxs = size_mgxs * 8 - - ! Calculate total memory - size_total = size_scattmat + size_mgxs - - ! Write memory used - write(unit_,*) ' Memory Requirements' - write(unit_,*) ' Cross sections = ' // trim(to_str(size_mgxs)) // ' bytes' - write(unit_,*) ' Scattering Matrices = ' // & - trim(to_str(size_scattmat)) // ' bytes' - write(unit_,*) ' Total = ' // trim(to_str(size_total)) // ' bytes' - - ! Blank line at end of nuclide - write(unit_,*) - - end subroutine nuclideiso_print - - subroutine nuclideangle_print(this, unit) - - class(NuclideAngle), intent(in) :: this - integer, optional, intent(in) :: unit - - integer :: unit_ ! unit to write to - integer :: size_total, size_scattmat, size_mgxs - - ! set default unit for writing information - if (present(unit)) then - unit_ = unit - else - unit_ = OUTPUT_UNIT - end if - - ! Write Basic Nuclide Information - call nuclidemg_print(this, unit_) - write(unit_,*) ' # of Polar Angles = ' // trim(to_str(this % n_pol)) - write(unit_,*) ' # of Azimuthal Angles = ' // trim(to_str(this % n_azi)) - - ! Determine size of mgxs and scattering matrices - size_scattmat = (size(this % scatter) + size(this % mult)) * 8 - size_mgxs = size(this % total) + size(this % absorption) + & - size(this % nu_fission) + size(this % k_fission) + & - size(this % fission) + size(this % chi) - size_mgxs = size_mgxs * 8 - - ! Calculate total memory - size_total = size_scattmat + size_mgxs - - ! Write memory used - write(unit_,*) ' Memory Requirements' - write(unit_,*) ' Cross sections = ' // trim(to_str(size_mgxs)) // ' bytes' - write(unit_,*) ' Scattering Matrices = ' // & - trim(to_str(size_scattmat)) // ' bytes' - write(unit_,*) ' Total = ' // trim(to_str(size_total)) // ' bytes' - - ! Blank line at end of nuclide - write(unit_,*) - - - end subroutine nuclideangle_print - -!=============================================================================== -! NUCLIDE*_GET_XS Returns the requested data type -!=============================================================================== - - function nuclideiso_get_xs(this, g, xstype, gout, uvw, mu, i_azi, i_pol) & - result(xs) - class(NuclideIso), intent(in) :: this - integer, intent(in) :: g ! Incoming Energy group - character(*), intent(in) :: xstype ! Cross Section Type - integer, optional, intent(in) :: gout ! Outgoing Group - real(8), optional, intent(in) :: uvw(3) ! Requested Angle - real(8), optional, intent(in) :: mu ! Change in angle - integer, optional, intent(in) :: i_azi ! Azimuthal Index - integer, optional, intent(in) :: i_pol ! Polar Index - real(8) :: xs ! Resultant xs - - xs = ZERO - - if ((xstype == 'nu_fission' .or. xstype == 'fission' .or. xstype =='chi' & - .or. xstype =='k_fission') .and. (.not. this % fissionable)) then - return - end if - - if (present(gout)) then - select case(xstype) - case('mult') - xs = this % mult(gout,g) - case('nu_fission') - xs = this % nu_fission(gout,g) - case('f_mu', 'f_mu/mult') - xs = this % calc_f(g, gout, mu) - if (xstype == 'f_mu/mult') then - xs = xs / this % mult(gout,g) - end if - end select - else - select case(xstype) - case('total') - xs = this % total(g) - case('absorption') - xs = this % absorption(g) - case('fission') - xs = this % fission(g) - case('k_fission') - if (allocated(this % k_fission)) then - xs = this % k_fission(g) - end if - case('chi') - xs = this % chi(g) - case('scatter') - xs = this % total(g) - this % absorption(g) - end select - end if - end function nuclideiso_get_xs - - function nuclideangle_get_xs(this, g, xstype, gout, uvw, mu, i_azi, i_pol) & - result(xs) - class(NuclideAngle), intent(in) :: this - integer, intent(in) :: g ! Incoming Energy group - character(*), intent(in) :: xstype ! Cross Section Type - integer, optional, intent(in) :: gout ! Outgoing Group - real(8), optional, intent(in) :: mu ! Change in angle - real(8), optional, intent(in) :: uvw(3) ! Requested Angle - integer, optional, intent(in) :: i_azi ! Azimuthal Index - integer, optional, intent(in) :: i_pol ! Polar Index - real(8) :: xs ! Resultant xs - - integer :: i_azi_, i_pol_ - - xs = ZERO - - if ((xstype == 'nu_fission' .or. xstype == 'fission' .or. xstype =='chi' & - .or. xstype =='k_fission') .and. (.not. this % fissionable)) then - return - end if - - if (present(i_azi) .and. present(i_pol)) then - i_azi_ = i_azi - i_pol_ = i_pol - else - call find_angle(this % polar, this % azimuthal, uvw, i_azi_, i_pol_) - end if - - if (present(gout)) then - select case(xstype) - case('mult') - xs = this % mult(gout,g,i_azi_,i_pol_) - case('nu_fission') - xs = this % nu_fission(gout,g,i_azi_,i_pol_) - case('chi') - xs = this % chi(gout,i_azi_,i_pol_) - case('f_mu', 'f_mu/mult') - xs = this % calc_f(g, gout, mu, I_AZI=i_azi_, I_POL=i_pol_) - if (xstype == 'f_mu/mult') then - xs = xs / this % mult(gout,g,i_azi_,i_pol_) - end if - end select - else - select case(xstype) - case('total') - xs = this % total(g,i_azi_,i_pol_) - case('absorption') - xs = this % absorption(g,i_azi_,i_pol_) - case('fission') - xs = this % fission(g,i_azi_,i_pol_) - case('k_fission') - if (allocated(this % k_fission)) then - xs = this % k_fission(g,i_azi_,i_pol_) - end if - case('chi') - xs = this % chi(g,i_azi_,i_pol_) - case('scatter') - xs = this % total(g,i_azi_,i_pol_) - this % absorption(g,i_azi_,i_pol_) - end select - end if - - end function nuclideangle_get_xs - -!=============================================================================== -! NUCLIDE*_CALC_F Finds the value of f(mu), the scattering angle probability, -! given mu -!=============================================================================== - - pure function nuclideiso_calc_f(this, gin, gout, mu, uvw, i_azi, i_pol) & - result(f) - class(NuclideIso), intent(in) :: this - integer, intent(in) :: gin ! Incoming Energy Group - integer, intent(in) :: gout ! Outgoing Energy Group - real(8), intent(in) :: mu ! Angle of interest - real(8), intent(in), optional :: uvw(3) ! Direction vector - integer, intent(in), optional :: i_azi ! Incoming Energy Group - integer, intent(in), optional :: i_pol ! Outgoing Energy Group - real(8) :: f ! Return value of f(mu) - - real(8) :: dmu, r - integer :: imu - - if (this % scatt_type == ANGLE_LEGENDRE) then - f = evaluate_legendre(this % scatter(gout,gin,:), mu) - else if (this % scatt_type == ANGLE_TABULAR) then - dmu = TWO / real(this % order - 1,8) - ! Find mu bin algebraically, knowing that the spacing is equal - f = (mu + ONE) / dmu + ONE - imu = floor(f) - ! But save the amount that mu is past the previous index - ! so we can use interpolation later. - f = f - real(imu,8) - ! Adjust so interpolation works on the last bin if necessary - if (imu == size(this % scatter, dim=3)) then - imu = imu - 1 - end if - - ! Now intepolate to find f(mu) - r = f / dmu - f = (ONE - r) * this % scatter(gout,gin,imu) + & - r * this % scatter(gout,gin,imu+1) - else ! (ANGLE_HISTOGRAM) - dmu = TWO / real(this % order,8) - ! Find mu bin algebraically, knowing that the spacing is equal - imu = floor((mu + ONE) / dmu + ONE) - ! Adjust so interpolation works on the last bin if necessary - if (imu == size(this % scatter, dim=3)) then - imu = imu - 1 - end if - f = this % scatter(gout, gin, imu) - - end if - - end function nuclideiso_calc_f - - pure function nuclideangle_calc_f(this, gin, gout, mu, uvw, i_azi, & - i_pol) result(f) - class(NuclideAngle), intent(in) :: this - integer, intent(in) :: gin ! Incoming Energy Group - integer, intent(in) :: gout ! Outgoing Energy Group - real(8), intent(in) :: mu ! Angle of interest - real(8), intent(in), optional :: uvw(3) ! Direction vector - integer, intent(in), optional :: i_azi ! Incoming Energy Group - integer, intent(in), optional :: i_pol ! Outgoing Energy Group - real(8) :: f ! Return value of f(mu) - - real(8) :: dmu, r - integer :: imu - integer :: i_azi_, i_pol_ - if (present(i_azi) .and. present(i_pol)) then - i_azi_ = i_azi - i_pol_ = i_pol - else if (present(uvw)) then - call find_angle(this % polar, this % azimuthal, uvw, i_azi_, i_pol_) - end if - - if (this % scatt_type == ANGLE_LEGENDRE) then - f = evaluate_legendre(this % scatter(gout,gin,:,i_azi_,i_pol_), mu) - else if (this % scatt_type == ANGLE_TABULAR) then - dmu = TWO / real(this % order - 1,8) - ! Find mu bin algebraically, knowing that the spacing is equal - f = (mu + ONE) / dmu + ONE - imu = floor(f) - ! But save the amount that mu is past the previous index - ! so we can use interpolation later. - f = f - real(imu,8) - ! Adjust so interpolation works on the last bin if necessary - if (imu == size(this % scatter, dim=3)) then - imu = imu - 1 - end if - - ! Now intepolate to find f(mu) - r = f / dmu - f = (ONE - r) * this % scatter(gout,gin,imu,i_azi_,i_pol_) + & - r * this % scatter(gout,gin,imu+1,i_azi_,i_pol_) - else ! (ANGLE_HISTOGRAM) - dmu = TWO / real(this % order,8) - ! Find mu bin algebraically, knowing that the spacing is equal - imu = floor((mu + ONE) / dmu + ONE) - ! Adjust so interpolation works on the last bin if necessary - if (imu == size(this % scatter, dim=3)) then - imu = imu - 1 - end if - f = this % scatter(gout, gin, imu,i_azi_,i_pol_) - - end if - - end function nuclideangle_calc_f + end subroutine nuclide_print end module nuclide_header diff --git a/src/output.F90 b/src/output.F90 index 5e427aa6d..3b7f1f101 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -52,9 +52,9 @@ contains ! Write version information write(UNIT=OUTPUT_UNIT, FMT=*) & - ' Copyright: 2011-2015 Massachusetts Institute of Technology' + ' Copyright: 2011-2016 Massachusetts Institute of Technology' write(UNIT=OUTPUT_UNIT, FMT=*) & - ' License: http://mit-crpg.github.io/openmc/license.html' + ' License: http://openmc.readthedocs.io/en/latest/license.html' write(UNIT=OUTPUT_UNIT, FMT='(6X,"Version:",8X,I1,".",I1,".",I1)') & VERSION_MAJOR, VERSION_MINOR, VERSION_RELEASE #ifdef GIT_SHA1 @@ -335,10 +335,10 @@ contains ! Open log file for writing open(NEWUNIT=unit_xs, FILE=path, STATUS='replace', ACTION='write') - ! Write header - call header("CROSS SECTION TABLES", unit=unit_xs) - if (run_CE) then + ! Write header + call header("CROSS SECTION TABLES", unit=unit_xs) + NUCLIDE_LOOP: do i = 1, n_nuclides_total ! Print information about nuclide call nuclides(i) % print(unit=unit_xs) @@ -349,10 +349,17 @@ contains call sab_tables(i) % print(unit=unit_xs) end do SAB_TABLES_LOOP else + ! Write header + call header("MGXS LIBRARY TABLES", unit=unit_xs) NuclideMG_LOOP: do i = 1, n_nuclides_total ! Print information about nuclide call nuclides_mg(i) % obj % print(unit=unit_xs) end do NuclideMG_LOOP + call header("MATERIAL MGXS TABLES", unit=unit_xs) + MATERIAL_LOOP: do i = 1, n_materials + ! Print information about Materials + call macro_xs(i) % obj % print(unit=unit_xs) + end do MATERIAL_LOOP end if ! Close cross section summary file @@ -920,7 +927,11 @@ contains write(UNIT=unit_tally, FMT='(1X,2A,1X,A)') repeat(" ", indent), & "Total Material" else - i_listing = nuclides(i_nuclide) % listing + if (run_CE) then + i_listing = nuclides(i_nuclide) % listing + else + i_listing = nuclides_MG(i_nuclide) % obj % listing + end if write(UNIT=unit_tally, FMT='(1X,2A,1X,A)') repeat(" ", indent), & trim(xs_listings(i_listing) % alias) end if diff --git a/src/particle_header.F90 b/src/particle_header.F90 index 141f70c8b..a313c6ed5 100644 --- a/src/particle_header.F90 +++ b/src/particle_header.F90 @@ -206,7 +206,7 @@ contains this % last_g = int(src % E) this % E = energy_bin_avg(this % g) end if - this % last_E = src % E + this % last_E = this % E end subroutine initialize_from_source diff --git a/src/particle_restart.F90 b/src/particle_restart.F90 index 9d49a4f97..e5cca17bf 100644 --- a/src/particle_restart.F90 +++ b/src/particle_restart.F90 @@ -34,7 +34,7 @@ contains verbosity = 10 ! Initialize the particle to be tracked - call p%initialize() + call p % initialize() ! Read in the restart information call read_particle_restart(p, previous_run_mode) @@ -46,9 +46,9 @@ contains select case (previous_run_mode) case (MODE_EIGENVALUE) particle_seed = ((current_batch - 1)*gen_per_batch + & - current_gen - 1)*n_particles + p%id + current_gen - 1)*n_particles + p % id case (MODE_FIXEDSOURCE) - particle_seed = p%id + particle_seed = p % id end select call set_particle_seed(particle_seed) @@ -71,7 +71,7 @@ contains integer :: int_scalar integer(HID_T) :: file_id - character(MAX_WORD_LEN) :: mode + character(MAX_WORD_LEN) :: tempstr ! Write meessage call write_message("Loading particle restart file " & @@ -81,32 +81,32 @@ contains file_id = file_open(path_particle_restart, 'r') ! Read data from file - call read_dataset(file_id, 'filetype', int_scalar) - call read_dataset(file_id, 'revision', int_scalar) - call read_dataset(file_id, 'current_batch', current_batch) - call read_dataset(file_id, 'gen_per_batch', gen_per_batch) - call read_dataset(file_id, 'current_gen', current_gen) - call read_dataset(file_id, 'n_particles', n_particles) - call read_dataset(file_id, 'run_mode', mode) - select case (mode) + call read_dataset(tempstr, file_id, 'filetype') + call read_dataset(int_scalar, file_id, 'revision') + call read_dataset(current_batch, file_id, 'current_batch') + call read_dataset(gen_per_batch, file_id, 'gen_per_batch') + call read_dataset(current_gen, file_id, 'current_gen') + call read_dataset(n_particles, file_id, 'n_particles') + call read_dataset(tempstr, file_id, 'run_mode') + select case (tempstr) case ('k-eigenvalue') previous_run_mode = MODE_EIGENVALUE case ('fixed source') previous_run_mode = MODE_FIXEDSOURCE end select - call read_dataset(file_id, 'id', p%id) - call read_dataset(file_id, 'weight', p%wgt) - call read_dataset(file_id, 'energy', p%E) - call read_dataset(file_id, 'energy_group', p%g) - call read_dataset(file_id, 'xyz', p%coord(1)%xyz) - call read_dataset(file_id, 'uvw', p%coord(1)%uvw) + call read_dataset(p % id, file_id, 'id') + call read_dataset(p % wgt, file_id, 'weight') + call read_dataset(p % E, file_id, 'energy') + call read_dataset(p % g, file_id, 'energy_group') + call read_dataset(p % coord(1) % xyz, file_id, 'xyz') + call read_dataset(p % coord(1) % uvw, file_id, 'uvw') ! Set particle last attributes - p%last_wgt = p%wgt - p%last_xyz = p%coord(1)%xyz - p%last_uvw = p%coord(1)%uvw - p%last_E = p%E - p%last_g = p%g + p % last_wgt = p % wgt + p % last_xyz = p % coord(1)%xyz + p % last_uvw = p % coord(1)%uvw + p % last_E = p % E + p % last_g = p % g ! Close hdf5 file call file_close(file_id) diff --git a/src/physics.F90 b/src/physics.F90 index d6c4c45b0..09a43aa99 100644 --- a/src/physics.F90 +++ b/src/physics.F90 @@ -80,7 +80,7 @@ contains integer :: i_nuclide ! index in nuclides array integer :: i_nuc_mat ! index in material's nuclides array integer :: i_reaction ! index in nuc % reactions array - type(NuclideCE), pointer :: nuc + type(Nuclide), pointer :: nuc call sample_nuclide(p, 'total ', i_nuclide, i_nuc_mat) @@ -203,7 +203,7 @@ contains real(8) :: f real(8) :: prob real(8) :: cutoff - type(NuclideCE), pointer :: nuc + type(Nuclide), pointer :: nuc ! Get pointer to nuclide nuc => nuclides(i_nuclide) @@ -301,7 +301,7 @@ contains real(8) :: uvw_new(3) ! outgoing uvw for iso-in-lab scattering real(8) :: uvw_old(3) ! incoming uvw for iso-in-lab scattering real(8) :: phi ! azimuthal angle for iso-in-lab scattering - type(NuclideCE), pointer :: nuc + type(Nuclide), pointer :: nuc ! copy incoming direction uvw_old(:) = p % coord(1) % uvw @@ -416,7 +416,7 @@ contains real(8) :: v_cm(3) ! velocity of center-of-mass real(8) :: v_t(3) ! velocity of target nucleus real(8) :: uvw_cm(3) ! directional cosines in center-of-mass - type(NuclideCE), pointer :: nuc + type(Nuclide), pointer :: nuc ! get pointer to nuclide nuc => nuclides(i_nuclide) @@ -742,7 +742,7 @@ contains !=============================================================================== subroutine sample_target_velocity(nuc, v_target, E, uvw, v_neut, wgt, xs_eff) - type(NuclideCE), intent(in) :: nuc ! target nuclide at temperature T + type(Nuclide), intent(in) :: nuc ! target nuclide at temperature T real(8), intent(out) :: v_target(3) ! target velocity real(8), intent(in) :: v_neut(3) ! neutron velocity real(8), intent(in) :: E ! particle energy @@ -987,7 +987,7 @@ contains !=============================================================================== subroutine sample_cxs_target_velocity(nuc, v_target, E, uvw) - type(NuclideCE), intent(in) :: nuc ! target nuclide at temperature + type(Nuclide), intent(in) :: nuc ! target nuclide at temperature real(8), intent(out) :: v_target(3) real(8), intent(in) :: E real(8), intent(in) :: uvw(3) @@ -1073,7 +1073,7 @@ contains real(8) :: nu_t ! total nu real(8) :: weight ! weight adjustment for ufs method logical :: in_mesh ! source site in ufs mesh? - type(NuclideCE), pointer :: nuc + type(Nuclide), pointer :: nuc ! Get pointers nuc => nuclides(i_nuclide) @@ -1169,10 +1169,10 @@ contains !=============================================================================== subroutine sample_fission_neutron(nuc, rxn, E_in, site) - type(NuclideCE), intent(in) :: nuc - type(Reaction), intent(in) :: rxn - real(8), intent(in) :: E_in - type(Bank), intent(inout) :: site + type(Nuclide), intent(in) :: nuc + type(Reaction), intent(in) :: rxn + real(8), intent(in) :: E_in + type(Bank), intent(inout) :: site integer :: group ! index on nu energy grid / precursor group integer :: n_sample ! number of resamples @@ -1278,7 +1278,7 @@ contains !=============================================================================== subroutine inelastic_scatter(nuc, rxn, p) - type(NuclideCE), intent(in) :: nuc + type(Nuclide), intent(in) :: nuc type(Reaction), intent(in) :: rxn type(Particle), intent(inout) :: p diff --git a/src/physics_mg.F90 b/src/physics_mg.F90 index 6a58540c1..2e5e467c1 100644 --- a/src/physics_mg.F90 +++ b/src/physics_mg.F90 @@ -5,9 +5,9 @@ module physics_mg use constants use error, only: fatal_error, warning use global - use macroxs_header, only: MacroXS, MacroXSContainer use material_header, only: Material use math, only: rotate_angle + use mgxs_header, only: Mgxs, MgxsContainer use mesh, only: get_mesh_indices use output, only: write_message use particle_header, only: Particle @@ -77,6 +77,7 @@ contains call create_fission_sites(p, p % secondary_bank, p % n_secondary) end if end if + ! If survival biasing is being used, the following subroutine adjusts the ! weight of the particle. Otherwise, it checks to see if absorption occurs @@ -178,7 +179,7 @@ contains real(8) :: phi ! fission neutron azimuthal angle real(8) :: weight ! weight adjustment for ufs method logical :: in_mesh ! source site in ufs mesh? - class(MacroXS), pointer :: xs + class(Mgxs), pointer :: xs ! Get Pointers xs => macro_xs(p % material) % obj @@ -241,14 +242,12 @@ contains ! Set weight of fission bank site bank_array(i) % wgt = ONE/weight - ! Sample cosine of angle -- fission neutrons are always emitted - ! isotropically. Sometimes in ACE data, fission reactions actually have - ! an angular distribution listed, but for those that do, it's simply just - ! a uniform distribution in mu + ! Sample cosine of angle -- fission neutrons are treated as being emitted + ! isotropically. mu = TWO * prn() - ONE ! Sample azimuthal angle uniformly in [0,2*pi) - phi = TWO*PI*prn() + phi = TWO * PI * prn() bank_array(i) % uvw(1) = mu bank_array(i) % uvw(2) = sqrt(ONE - mu*mu) * cos(phi) bank_array(i) % uvw(3) = sqrt(ONE - mu*mu) * sin(phi) @@ -256,7 +255,7 @@ contains ! Sample secondary energy distribution for fission reaction and set energy ! in fission bank bank_array(i) % E = & - real(xs % sample_fission_energy(p % g, fission_bank(i) % uvw), 8) + real(xs % sample_fission_energy(p % g, bank_array(i) % uvw), 8) end do ! increment number of bank sites diff --git a/src/scattdata_header.F90 b/src/scattdata_header.F90 index f8fddbc6b..12c11e2e4 100644 --- a/src/scattdata_header.F90 +++ b/src/scattdata_header.F90 @@ -8,36 +8,56 @@ module scattdata_header implicit none + +!=============================================================================== +! JAGGED1D and JAGGED2D is a type which allows for jagged 1-D or 2-D array. +!=============================================================================== + + type :: Jagged2D + real(8), allocatable :: data(:, :) + end type Jagged2D + + type :: Jagged1D + real(8), allocatable :: data(:) + end type Jagged1D + !=============================================================================== ! SCATTDATA contains all the data to describe the scattering energy and ! angular distribution !=============================================================================== type, abstract :: ScattData - ! p0 matrix on its own for sampling energy - real(8), allocatable :: energy(:,:) ! (Gout x Gin) - real(8), allocatable :: mult(:,:) ! (Gout x Gin) - real(8), allocatable :: data(:,:,:) ! (Order/Nmu x Gout x Gin) + ! The data attribute of the energy, mult, and dist arrays + ! are not necessarily 1-indexed as they instead will be allocated + ! from a minimum outgoing group to an outgoing minimum group. + ! Normalized p0 matrix on its own for sampling energy + type(Jagged1D), allocatable :: energy(:) ! (Gin % data(Gout)) + ! Nu-scatter multiplication (i.e. nu-scatt/scatt) + type(Jagged1D), allocatable :: mult(:) ! (Gin % data(Gout)) + ! Angular distribution + type(Jagged2D), allocatable :: dist(:) ! (Gin % data(Order/Nmu, Gout) + integer, allocatable :: gmin(:) ! Minimum outgoing group + integer, allocatable :: gmax(:) ! Maximum outgoing group + real(8), allocatable :: scattxs(:) ! Isotropic Sigma_{s,g_{in}} contains procedure(scattdata_init_), deferred :: init ! Initializes ScattData procedure(scattdata_calc_f_), deferred :: calc_f ! Calculates f, given mu procedure(scattdata_sample_), deferred :: sample ! sample the scatter event + procedure :: get_matrix => scattdata_get_matrix ! Rebuild scattering matrix end type ScattData abstract interface - subroutine scattdata_init_(this, order, energy, mult, coeffs) + subroutine scattdata_init_(this, mult, coeffs) import ScattData - class(ScattData), intent(inout) :: this ! Object to work on - integer, intent(in) :: order ! Data Order - real(8), intent(in) :: energy(:,:) ! Energy Transfer Matrix - real(8), intent(in) :: mult(:,:) ! Scatter Prod'n Matrix - real(8), intent(in) :: coeffs(:,:,:) ! Coefficients to use + class(ScattData), intent(inout) :: this ! Object to work with + real(8), intent(in) :: mult(:, :) ! Scatter Prod'n Matrix + real(8), intent(in) :: coeffs(:, :, :) ! Coefficients to use end subroutine scattdata_init_ pure function scattdata_calc_f_(this, gin, gout, mu) result(f) import ScattData - class(ScattData), intent(in) :: this ! The ScattData to evaluate + class(ScattData), intent(in) :: this ! Scattering Object to work with integer, intent(in) :: gin ! Incoming Energy Group integer, intent(in) :: gout ! Outgoing Energy Group real(8), intent(in) :: mu ! Angle of interest @@ -47,7 +67,7 @@ module scattdata_header subroutine scattdata_sample_(this, gin, gout, mu, wgt) import ScattData - class(ScattData), intent(in) :: this ! Scattering Object to Use + class(ScattData), intent(in) :: this ! Scattering Object to work with integer, intent(in) :: gin ! Incoming neutron group integer, intent(out) :: gout ! Sampled outgoin group real(8), intent(out) :: mu ! Sampled change in angle @@ -57,30 +77,35 @@ module scattdata_header type, extends(ScattData) :: ScattDataLegendre ! Maximal value for rejection sampling from rectangle - real(8), allocatable :: max_val(:,:) + type(Jagged1D), allocatable :: max_val(:) ! (Gin % data(Gout)) contains - procedure :: init => scattdatalegendre_init - procedure :: calc_f => scattdatalegendre_calc_f - procedure :: sample => scattdatalegendre_sample + procedure :: init => scattdatalegendre_init + procedure :: calc_f => scattdatalegendre_calc_f + procedure :: sample => scattdatalegendre_sample end type ScattDataLegendre - type, extends(ScattData) :: ScattDataHistogram - real(8), allocatable :: mu(:) ! Mu bins - real(8) :: dmu ! Mu spacing + type, extends(ScattData) :: ScattDataHistogram + real(8), allocatable :: mu(:) ! Mu bins + real(8) :: dmu ! Mu spacing + ! Histogram of f(mu) (dist has CDF) + type(Jagged2D), allocatable :: fmu(:) ! (Gin % data(Order/Nmu x Gout) contains - procedure :: init => scattdatahistogram_init - procedure :: calc_f => scattdatahistogram_calc_f - procedure :: sample => scattdatahistogram_sample + procedure :: init => scattdatahistogram_init + procedure :: calc_f => scattdatahistogram_calc_f + procedure :: sample => scattdatahistogram_sample + procedure :: get_matrix => scattdatahistogram_get_matrix end type ScattDataHistogram - type, extends(ScattData) :: ScattDataTabular - real(8), allocatable :: mu(:) ! Mu bins - real(8) :: dmu ! Mu spacing - real(8), allocatable :: fmu(:,:,:) ! PDF of f(mu) + type, extends(ScattData) :: ScattDataTabular + real(8), allocatable :: mu(:) ! Mu bins + real(8) :: dmu ! Mu spacing + ! PDF of f(mu) (dist has CDF) + type(Jagged2D), allocatable :: fmu(:) ! (Gin % data(Order/Nmu x Gout) contains - procedure :: init => scattdatatabular_init - procedure :: calc_f => scattdatatabular_calc_f - procedure :: sample => scattdatatabular_sample + procedure :: init => scattdatatabular_init + procedure :: calc_f => scattdatatabular_calc_f + procedure :: sample => scattdatatabular_sample + procedure :: get_matrix => scattdatatabular_get_matrix end type ScattDataTabular !=============================================================================== @@ -94,189 +119,313 @@ module scattdata_header contains !=============================================================================== -! SCATTDATA_INIT builds the scattdata object +! SCATTDATA*_INIT builds the scattdata object !=============================================================================== subroutine scattdata_init(this, order, energy, mult) - class(ScattData), intent(inout) :: this ! Object to work on - integer, intent(in) :: order ! Data Order - real(8), intent(in) :: energy(:,:) ! Energy Transfer Matrix - real(8), intent(in) :: mult(:,:) ! Scatter Prod'n Matrix + class(ScattData), intent(inout) :: this ! Object to work on + integer, intent(in) :: order ! Data Order + real(8), intent(inout) :: energy(:, :) ! Energy Transfer Matrix + real(8), intent(in) :: mult(:, :) ! Scatter Prod'n Matrix - integer :: groups + integer :: groups, gmin, gmax, gin + real(8) :: norm groups = size(energy, dim=1) - allocate(this % energy(groups, groups)) - this % energy = energy - allocate(this % mult(groups, groups)) - this % mult = mult - allocate(this % data(order, groups, groups)) - this % data = ZERO - + allocate(this % gmin(groups)) + allocate(this % gmax(groups)) + allocate(this % energy(groups)) + allocate(this % mult(groups)) + allocate(this % dist(groups)) + ! Use energy to find the gmin and gmax values + ! Also set energy values when doing it + do gin = 1, groups + ! Make sure energy is normalized (i.e., CDF is 1) + norm = sum(energy(:, gin)) + if (norm /= ZERO) energy(:, gin) = energy(:, gin) / norm + ! Find gmin by checking the P0 moment + do gmin = 1, groups + if (energy(gmin, gin) > ZERO) exit + end do + ! Find gmax by checking the P0 moment + do gmax = groups, 1, -1 + if (energy(gmax, gin) > ZERO) exit + end do + ! Treat the case of all zeros + if (gmin > gmax) then + gmin = gin + gmax = gin + ! By not changing energy(gin) here we are leaving it as zero + end if + allocate(this % energy(gin) % data(gmin:gmax)) + this % energy(gin) % data(gmin:gmax) = energy(gmin:gmax, gin) + allocate(this % mult(gin) % data(gmin:gmax)) + this % mult(gin) % data(gmin:gmax) = mult(gmin:gmax, gin) + allocate(this % dist(gin) % data(order, gmin:gmax)) + this % dist(gin) % data = ZERO + this % gmin(gin) = gmin + this % gmax(gin) = gmax + end do end subroutine scattdata_init - subroutine scattdatalegendre_init(this, order, energy, mult, coeffs) - class(ScattDataLegendre), intent(inout) :: this ! Object to work on - integer, intent(in) :: order ! Data Order - real(8), intent(in) :: energy(:,:) ! Energy Transfer Matrix - real(8), intent(in) :: mult(:,:) ! Scatter Prod'n Matrix - real(8), intent(in) :: coeffs(:,:,:) ! Coefficients to use + subroutine scattdatalegendre_init(this, mult, coeffs) + class(ScattDataLegendre), intent(inout) :: this ! Object to work on + real(8), intent(in) :: mult(:, :) ! Scatter Prod'n Matrix + real(8), intent(in) :: coeffs(:, :, :) ! Coefficients to use - real(8) :: dmu, mu, f - integer :: imu, Nmu, gout, gin, groups + real(8) :: dmu, mu, f, norm + integer :: imu, Nmu, gout, gin, groups, order + real(8), allocatable :: energy(:, :) + real(8), allocatable :: matrix(:, :, :) - call scattdata_init(this, order, energy, mult) + groups = size(coeffs, dim=3) + order = size(coeffs, dim=1) - this % data = coeffs + ! make a copy of coeffs that we can use to extract data and normalize + allocate(matrix(order, groups, groups)) + matrix (:, :, :)= coeffs - groups = size(this % energy,dim=1) + ! Get scattxs value + allocate(this % scattxs(groups)) + ! Get this by summing the un-normalized P0 coefficient in matrix + ! over all outgoing groups + this % scattxs(:) = sum(matrix(1, :, :), dim=1) - allocate(this % max_val(groups, groups)) - this % max_val = ZERO - ! Step through the polynomial with fixed number of points to identify - ! the maximal value. - Nmu = 1001 - dmu = TWO / real(Nmu,8) - do imu = 1, Nmu - ! Update mu. Do first and last seperate to avoid float errors - if (imu == 1) then - mu = -ONE - else if (imu == Nmu) then - mu = ONE - end if - mu = -ONE + real(imu - 1,8) * dmu - do gin = 1, groups - do gout = 1, groups - ! Calculate probability - f = this % calc_f(gin,gout,mu) - ! If this is a new max, store it. - if (f > this % max_val(gout,gin)) this % max_val(gout,gin) = f - end do + allocate(energy(groups, groups)) + energy(:, :) = ZERO + ! Build energy transfer probability matrix from data in matrix + ! while also normalizing matrix itself (making CDF of f(mu=1)=1) + do gin = 1, groups + do gout = 1, groups + norm = matrix(1, gout, gin) + energy(gout, gin) = norm + if (norm /= ZERO) then + matrix(:, gout, gin) = matrix(:, gout, gin) / norm + end if end do end do - ! Finally, since we may not have caught the exact max, add 10% margin - this % max_val = this % max_val * 1.1_8 + call scattdata_init(this, order, energy, mult) + allocate(this % max_val(groups)) + ! Set dist values from matrix and initialize max_val + do gin = 1, groups + do gout = this % gmin(gin), this % gmax(gin) + this % dist(gin) % data(:, gout) = matrix(:, gout, gin) + end do + allocate(this % max_val(gin) % data(this % gmin(gin):this % gmax(gin))) + this % max_val(gin) % data(:) = ZERO + end do + + ! Step through the polynomial with fixed number of points to identify + ! the maximal value. + Nmu = 1001 + dmu = TWO / real(Nmu - 1, 8) + do gin = 1, groups + do gout = this % gmin(gin), this % gmax(gin) + do imu = 1, Nmu + ! Update mu. Do first and last seperate to avoid float errors + if (imu == 1) then + mu = -ONE + else if (imu == Nmu) then + mu = ONE + else + mu = -ONE + real(imu - 1, 8) * dmu + end if + ! Calculate probability + f = this % calc_f(gin,gout,mu) + ! If this is a new max, store it. + if (f > this % max_val(gin) % data(gout)) & + this % max_val(gin) % data(gout) = f + end do + ! Finally, since we may not have caught the exact max, add 10% margin + this % max_val(gin) % data(gout) = & + this % max_val(gin) % data(gout) * 1.1_8 + end do + end do end subroutine scattdatalegendre_init - subroutine scattdatahistogram_init(this, order, energy, mult, coeffs) + subroutine scattdatahistogram_init(this, mult, coeffs) class(ScattDataHistogram), intent(inout) :: this ! Object to work on - integer, intent(in) :: order ! Data Order - real(8), intent(in) :: energy(:,:) ! Energy Transfer Matrix - real(8), intent(in) :: mult(:,:) ! Scatter Prod'n Matrix - real(8), intent(in) :: coeffs(:,:,:) ! Coefficients to use + real(8), intent(in) :: mult(:, :) ! Scatter Prod'n Matrix + real(8), intent(in) :: coeffs(:, :, :) ! Coefficients to use - integer :: imu, gin, gout, groups + integer :: imu, gin, gout, groups, order real(8) :: norm + real(8), allocatable :: energy(:, :) + real(8), allocatable :: matrix(:, :, :) - groups = size(energy,dim=1) + groups = size(coeffs, dim=3) + order = size(coeffs, dim=1) + + ! make a copy of coeffs that we can use to extract data and normalize + allocate(matrix(order, groups, groups)) + matrix(:, :, :) = coeffs + + ! Get scattxs value + allocate(this % scattxs(groups)) + ! Get this by summing the un-normalized P0 coefficient in matrix + ! over all outgoing groups + this % scattxs(:) = sum(sum(matrix(:, :, :), dim=1), dim=1) + + allocate(energy(groups, groups)) + energy(:, :) = ZERO + ! Build energy transfer probability matrix from data in matrix + ! while also normalizing matrix itself (making CDF of f(mu=1)=1) + do gin = 1, groups + do gout = 1, groups + norm = sum(matrix(:, gout, gin)) + energy(gout, gin) = norm + if (norm /= ZERO) then + matrix(:, gout, gin) = matrix(:, gout, gin) / norm + end if + end do + end do call scattdata_init(this, order, energy, mult) allocate(this % mu(order)) - this % dmu = TWO / real(order,8) + this % dmu = TWO / real(order, 8) this % mu(1) = -ONE do imu = 2, order - this % mu(imu) = -ONE + real(imu - 1,8) * this % dmu + this % mu(imu) = -ONE + real(imu - 1, 8) * this % dmu end do - ! Best to integrate this histogram so we can avoid rejection sampling + ! Integrate this histogram so we can avoid rejection sampling while + ! also saving the original histogram in fmu + allocate(this % fmu(groups)) do gin = 1, groups - do gout = 1, groups - if (energy(gout,gin) > ZERO) then - ! Integrate the histogram - this % data(1,gout,gin) = this % dmu * coeffs(1,gout,gin) - do imu = 2, order - this % data(imu,gout,gin) = this % dmu * coeffs(imu,gout,gin) + & - this % data(imu-1,gout,gin) - end do - ! Now make sure integral norms to zero - norm = this % data(order,gout,gin) - if (norm > ZERO) then - this % data(:,gout,gin) = this % data(:,gout,gin) / norm - end if + allocate(this % fmu(gin) % data(order, & + this % gmin(gin):this % gmax(gin))) + do gout = this % gmin(gin), this % gmax(gin) + ! Store the histogram + this % fmu(gin) % data(:, gout) = matrix(:, gout, gin) + ! Integrate the histogram + this % dist(gin) % data(1, gout) = & + this % dmu * matrix(1, gout, gin) + do imu = 2, order + this % dist(gin) % data(imu, gout) = & + this % dmu * matrix(imu, gout, gin) + & + this % dist(gin) % data(imu - 1, gout) + end do + + ! Now make sure integral norms to zero + norm = this % dist(gin) % data(order, gout) + if (norm > ZERO) then + this % fmu(gin) % data(:, gout) = & + this % fmu(gin) % data(:, gout) / norm + this % dist(gin) % data(:, gout) = & + this % dist(gin) % data(:, gout) / norm end if end do end do end subroutine scattdatahistogram_init - subroutine scattdatatabular_init(this, order, energy, mult, coeffs) + subroutine scattdatatabular_init(this, mult, coeffs) class(ScattDataTabular), intent(inout) :: this ! Object to work on - integer, intent(in) :: order ! Data Order - real(8), intent(in) :: energy(:,:) ! Energy Transfer Matrix - real(8), intent(in) :: mult(:,:) ! Scatter Prod'n Matrix - real(8), intent(in) :: coeffs(:,:,:) ! Coefficients to use + real(8), intent(in) :: mult(:, :) ! Scatter Prod'n Matrix + real(8), intent(in) :: coeffs(:, :, :) ! Coefficients to use - integer :: imu, gin, gout, groups + integer :: imu, gin, gout, groups, order real(8) :: norm - logical :: legendre_flag - integer :: this_order + real(8), allocatable :: energy(:, :) + real(8), allocatable :: matrix(:, :, :) - if (order < 0) then - legendre_flag = .true. - this_order = -1 * order - else - legendre_flag = .false. - this_order = order - end if + groups = size(coeffs, dim=3) + order = size(coeffs, dim=1) - groups = size(energy,dim=1) + ! make a copy of coeffs that we can use to extract data and normalize + allocate(matrix(order, groups, groups)) + matrix(:, :, :) = coeffs - call scattdata_init(this, this_order, energy, mult) - - allocate(this % mu(this_order)) - this % dmu = TWO / real(this_order - 1) - do imu = 1, this_order - 1 - this % mu(imu) = -ONE + real(imu - 1) * this % dmu + ! Build the angular distribution mu values + allocate(this % mu(order)) + this % dmu = TWO / real(order - 1, 8) + this % mu(1) = -ONE + do imu = 2, order - 1 + this % mu(imu) = -ONE + real(imu - 1, 8) * this % dmu end do - this % mu(this_order) = ONE + this % mu(order) = ONE - ! Best to integrate this histogram so we can avoid rejection sampling - allocate(this % fmu(this_order,groups,groups)) + ! Get scattxs + allocate(this % scattxs(groups)) + ! Get this by integrating the scattering distribution over all mu points + ! and then combining over all outgoing groups + ! over all outgoing groups + do gin = 1, groups + norm = ZERO + do gout = 1, groups + do imu = 2, order + norm = norm + HALF * this % dmu * (matrix(imu - 1, gout, gin) + & + matrix(imu, gout, gin)) + end do + end do + this % scattxs(gin) = norm + end do + + allocate(energy(groups, groups)) + energy(:, :) = ZERO + ! Build energy transfer probability matrix from data in matrix do gin = 1, groups do gout = 1, groups - if (energy(gout,gin) > ZERO) then - if (legendre_flag) then - ! Coeffs are legendre coeffs. Need to build f(mu) then integrate - ! and store the integral in this % data - ! Ensure the coeffs are normalized - norm = ONE / coeffs(1,gout,gin) - do imu = 1, this_order - this % fmu(imu,gout,gin) = evaluate_legendre(norm * coeffs(:,gout,gin), this % mu(imu)) - ! Force positivity - if (this % fmu(imu,gout,gin) < ZERO) then - this % fmu(imu,gout,gin) = ZERO - end if - end do - else - ! Coeffs contain f(mu), put in f(mu) to save duplicate. - this % fmu(:,gout,gin) = this % data(:,gout,gin) - end if + norm = ZERO + do imu = 2, order + norm = norm + HALF * this % dmu * & + (matrix(imu - 1, gout, gin) + matrix(imu, gout, gin)) + end do + energy(gout, gin) = norm + end do + end do + call scattdata_init(this, order, energy, mult) - ! Re-normalize fmu for numerical integration issues and in case - ! the negative fix-up introduced un-normalized data - norm = ZERO - do imu = 2, this_order - norm = norm + HALF * this % dmu * (this % fmu(imu-1,gout,gin) + this % fmu(imu,gout,gin)) - end do - if (norm > ZERO) then - this % fmu(:,gout,gin) = this % fmu(:,gout,gin) / norm - end if + ! Calculate f(mu) and integrate it so we can avoid rejection sampling + allocate(this % fmu(groups)) + do gin = 1, groups + allocate(this % fmu(gin) % data(order, & + this % gmin(gin):this % gmax(gin))) + do gout = this % gmin(gin), this % gmax(gin) + ! Coeffs contain f(mu), put in f(mu) as that is where the + ! PDF lives + this % fmu(gin) % data(:, gout) = matrix(:, gout, gin) - ! Now create CDF from fmu with trapezoidal rule - this % data(1,gout,gin) = ZERO - do imu = 2, this_order - 1 - this % data(imu,gout,gin) = this % data(imu-1,gout,gin) + & - HALF * this % dmu * (this % fmu(imu-1,gout,gin) + this % fmu(imu,gout,gin)) - end do - this % data(this_order,gout,gin) = ONE + ! Force positivity + do imu = 1, order + if (this % fmu(gin) % data(imu, gout) < ZERO) then + this % fmu(gin) % data(imu, gout) = ZERO + end if + end do + + ! Re-normalize fmu for numerical integration issues and in case + ! the negative fix-up introduced un-normalized data + norm = ZERO + do imu = 2, order + norm = norm + HALF * this % dmu * & + (this % fmu(gin) % data(imu - 1, gout) + & + this % fmu(gin) % data(imu, gout)) + end do + if (norm > ZERO) then + this % fmu(gin) % data(:, gout) = & + this % fmu(gin) % data(:, gout) / norm + end if + + ! Now create CDF from fmu with trapezoidal rule + this % dist(gin) % data(1, gout) = ZERO + do imu = 2, order + this % dist(gin) % data(imu, gout) = & + this % dist(gin) % data(imu - 1, gout) + & + HALF * this % dmu * (this % fmu(gin) % data(imu - 1, gout) + & + this % fmu(gin) % data(imu, gout)) + end do + ! Ensure we normalize to 1 still + norm = this % dist(gin) % data(order, gout) + if (norm > ZERO) then + this % dist(gin) % data(:, gout) = & + this % dist(gin) % data(:, gout) / norm end if end do end do - end subroutine scattdatatabular_init !=============================================================================== @@ -285,58 +434,69 @@ contains pure function scattdatalegendre_calc_f(this, gin, gout, mu) result(f) class(ScattDataLegendre), intent(in) :: this ! The ScattData to evaluate - integer, intent(in) :: gin ! Incoming Energy Group - integer, intent(in) :: gout ! Outgoing Energy Group - real(8), intent(in) :: mu ! Angle of interest - real(8) :: f ! Return value of f(mu) - - ! Plug mu in to the legendre expansion and go from there - f = evaluate_legendre(this % data(:, gout, gin), mu) - - end function scattdatalegendre_calc_f - - pure function scattdatahistogram_calc_f(this, gin, gout, mu) result(f) - class(ScattDataHistogram), intent(in) :: this ! The ScattData to evaluate - integer, intent(in) :: gin ! Incoming Energy Group - integer, intent(in) :: gout ! Outgoing Energy Group - real(8), intent(in) :: mu ! Angle of interest - real(8) :: f ! Return value of f(mu) - - integer :: imu - - ! Find mu bin - imu = floor((mu + ONE)/ this % dmu + ONE) - ! Adjust so interpolation works on the last bin if necessary - if (imu == size(this % data, dim=1)) then - imu = imu - 1 - end if - - ! Use histogram interpolation to find f(mu) - f = this % data(imu, gout, gin) - - end function scattdatahistogram_calc_f - - pure function scattdatatabular_calc_f(this, gin, gout, mu) result(f) - class(ScattDataTabular), intent(in) :: this ! The ScattData to evaluate integer, intent(in) :: gin ! Incoming Energy Group integer, intent(in) :: gout ! Outgoing Energy Group real(8), intent(in) :: mu ! Angle of interest real(8) :: f ! Return value of f(mu) + ! Plug mu in to the legendre expansion and go from there + if (gout < this % gmin(gin) .or. gout > this % gmax(gin)) then + f = ZERO + else + f = evaluate_legendre(this % dist(gin) % data(:, gout), mu) + end if + + end function scattdatalegendre_calc_f + + pure function scattdatahistogram_calc_f(this, gin, gout, mu) result(f) + class(ScattDataHistogram), intent(in) :: this ! The ScattData to evaluate + integer, intent(in) :: gin ! Incoming Energy Group + integer, intent(in) :: gout ! Outgoing Energy Group + real(8), intent(in) :: mu ! Angle of interest + real(8) :: f ! Return value of f(mu) + + integer :: imu + + if (gout < this % gmin(gin) .or. gout > this % gmax(gin)) then + f = ZERO + else + ! Find mu bin + if (mu == ONE) then + imu = size(this % fmu(gin) % data, dim=1) + else + imu = floor((mu + ONE) / this % dmu + ONE) + end if + + f = this % fmu(gin) % data(imu, gout) + end if + + end function scattdatahistogram_calc_f + + pure function scattdatatabular_calc_f(this, gin, gout, mu) result(f) + class(ScattDataTabular), intent(in) :: this ! The ScattData to evaluate + integer, intent(in) :: gin ! Incoming Energy Group + integer, intent(in) :: gout ! Outgoing Energy Group + real(8), intent(in) :: mu ! Angle of interest + real(8) :: f ! Return value of f(mu) + integer :: imu real(8) :: r - ! Find mu bin - imu = floor((mu + ONE)/ this % dmu + ONE) - ! Adjust so interpolation works on the last bin if necessary - if (imu == size(this % data, dim=1)) then - imu = imu - 1 - end if + if (gout < this % gmin(gin) .or. gout > this % gmax(gin)) then + f = ZERO + else + ! Find mu bin + if (mu == ONE) then + imu = size(this % fmu(gin) % data, dim=1) - 1 + else + imu = floor((mu + ONE) / this % dmu + ONE) + end if - ! ! Now interpolate to find f(mu) - r = (mu - this % mu(imu)) / (this % mu(imu + 1) - this % mu(imu)) - f = (ONE - r) * this % data(imu, gout, gin) + & - r * this % data(imu + 1, gout, gin) + ! Now interpolate to find f(mu) + r = (mu - this % mu(imu)) / (this % mu(imu + 1) - this % mu(imu)) + f = (ONE - r) * this % fmu(gin) % data(imu, gout) + & + r * this % fmu(gin) % data(imu + 1, gout) + end if end function scattdatatabular_calc_f @@ -357,24 +517,24 @@ contains integer :: samples xi = prn() - prob = ZERO - gout = 0 + gout = this % gmin(gin) + prob = this % energy(gin) % data(gout) do while (prob < xi) gout = gout + 1 - prob = prob + this % energy(gout,gin) + prob = prob + this % energy(gin) % data(gout) end do - ! Now we can sample mu using the legendre representation of the thisering + ! Now we can sample mu using the legendre representation of the scattering ! kernel in data(1:this % order) - ! Do with rejection sampling + ! Do with rejection sampling from a rectangular bounding box ! Set maximal value - M = this % max_val(gout,gin) + M = this % max_val(gin) % data(gout) samples = 0 do mu = TWO * prn() - ONE - f = this % calc_f(gin,gout,mu) + f = this % calc_f(gin, gout, mu) if (f > ZERO) then u = prn() * M if (u <= f) then @@ -387,7 +547,7 @@ contains end if end do - wgt = wgt * this % mult(gout,gin) + wgt = wgt * this % mult(gin) % data(gout) end subroutine scattdatalegendre_sample @@ -403,26 +563,26 @@ contains integer :: imu xi = prn() - prob = ZERO - gout = 0 + gout = this % gmin(gin) + prob = this % energy(gin) % data(gout) do while (prob < xi) gout = gout + 1 - prob = prob + this % energy(gout,gin) + prob = prob + this % energy(gin) % data(gout) end do xi = prn() - if (xi < this % data(1,gout,gin)) then + if (xi < this % dist(gin) % data(1, gout)) then imu = 1 else - imu = binary_search(this % data(:,gout,gin), & - size(this % data(:,gout,gin)), xi) + imu = binary_search(this % dist(gin) % data(:, gout), & + size(this % dist(gin) % data(:, gout)), xi) end if ! Randomly select a mu in this bin. mu = prn() * this % dmu + this % mu(imu) - wgt = wgt * this % mult(gout,gin) + wgt = wgt * this % mult(gin) % data(gout) end subroutine scattdatahistogram_sample @@ -440,21 +600,21 @@ contains integer :: k, NP xi = prn() - prob = ZERO - gout = 0 + gout = this % gmin(gin) + prob = this % energy(gin) % data(gout) do while (prob < xi) gout = gout + 1 - prob = prob + this % energy(gout,gin) + prob = prob + this % energy(gin) % data(gout) end do ! determine outgoing cosine bin - NP = size(this % data(:,gout,gin)) + NP = size(this % dist(gin) % data(:, gout)) xi = prn() - c_k = this % data(1,gout,gin) + c_k = this % dist(gin) % data(1, gout) do k = 1, NP - 1 - c_k1 = this % data(k+1,gout,gin) + c_k1 = this % dist(gin) % data(k + 1, gout) if (xi < c_k1) exit c_k = c_k1 end do @@ -462,18 +622,19 @@ contains ! check to make sure k is <= NP - 1 k = min(k, NP - 1) - p0 = this % fmu(k,gout,gin) + p0 = this % fmu(gin) % data(k, gout) mu0 = this % mu(k) ! Linear-linear interpolation to find mu value w/in bin. - p1 = this % fmu(k+1,gout,gin) - mu1 = this % mu(k+1) + p1 = this % fmu(gin) % data(k + 1, gout) + mu1 = this % mu(k + 1) - frac = (p1 - p0)/(mu1 - mu0) + frac = (p1 - p0) / (mu1 - mu0) if (frac == ZERO) then - mu = mu0 + (xi - c_k)/p0 + mu = mu0 + (xi - c_k) / p0 else - mu = mu0 + (sqrt(max(ZERO, p0*p0 + TWO*frac*(xi - c_k))) - p0)/frac + mu = mu0 + & + (sqrt(max(ZERO, p0 * p0 + TWO * frac * (xi - c_k))) - p0) / frac end if if (mu <= -ONE) then @@ -482,8 +643,86 @@ contains mu = ONE end if - wgt = wgt * this % mult(gout,gin) + wgt = wgt * this % mult(gin) % data(gout) end subroutine scattdatatabular_sample +!=============================================================================== +! SCATTDATA*_GET_MATRIX Reproduces the original scattering matrix (densely) +! using ScattData's information of fmu/dist, energy, and scattxs +!=============================================================================== + + pure function scattdata_get_matrix(this, req_order) result(matrix) + class(ScattData), intent(in) :: this ! Scattering Object to work with + integer, intent(in) :: req_order ! Requested order of matrix + real(8), allocatable :: matrix(:, :, :) ! Resultant matrix just built + + integer :: order, groups, gin, gout + + groups = size(this % energy) + ! Set gin and gout for getting the order + order = min(req_order, size(this % dist(1) % data, dim=1)) + + allocate(matrix(order, groups, groups)) + ! Initialize to 0; this way the zero entries in the dense matrix dont + ! need to be explicitly set, requiring a significant increase in the + ! lines of code. + matrix(:, :, :) = ZERO + do gin = 1, groups + do gout = this % gmin(gin), this % gmax(gin) + matrix(:, gout, gin) = this % scattxs(gin) * & + this % energy(gin) % data(gout) * & + this % dist(gin) % data(1:order, gout) + end do + end do + end function scattdata_get_matrix + + pure function scattdatahistogram_get_matrix(this, req_order) result(matrix) + class(ScattDataHistogram), intent(in) :: this ! Scattering Object to work with + integer, intent(in) :: req_order ! Requested order of matrix + real(8), allocatable :: matrix(:, :, :) ! Resultant matrix just built + + integer :: order, groups, gin, gout + + groups = size(this % energy) + order = min(req_order, size(this % dist(1) % data, dim=1)) + + allocate(matrix(order, groups, groups)) + ! Initialize to 0; this way the zero entries in the dense matrix dont + ! need to be explicitly set, requiring a significant increase in the + ! lines of code. + matrix(:, :, :) = ZERO + do gin = 1, groups + do gout = this % gmin(gin), this % gmax(gin) + matrix(:, gout, gin) = this % scattxs(gin) * & + this % energy(gin) % data(gout) * & + this % fmu(gin) % data(1:order, gout) + end do + end do + end function scattdatahistogram_get_matrix + + pure function scattdatatabular_get_matrix(this, req_order) result(matrix) + class(ScattDataTabular), intent(in) :: this ! Scattering Object to work with + integer, intent(in) :: req_order ! Requested order of matrix + real(8), allocatable :: matrix(:, :, :) ! Resultant matrix just built + + integer :: order, groups, gin, gout + + groups = size(this % energy) + order = min(req_order, size(this % dist(1) % data, dim=1)) + + allocate(matrix(order, groups, groups)) + ! Initialize to 0; this way the zero entries in the dense matrix dont + ! need to be explicitly set, requiring a significant increase in the + ! lines of code. + matrix(:, :, :) = ZERO + do gin = 1, groups + do gout = this % gmin(gin), this % gmax(gin) + matrix(:, gout, gin) = this % scattxs(gin) * & + this % energy(gin) % data(gout) * & + this % fmu(gin) % data(1:order, gout) + end do + end do + end function scattdatatabular_get_matrix + end module scattdata_header diff --git a/src/simulation.F90 b/src/simulation.F90 index 7741338de..bb4da64c0 100644 --- a/src/simulation.F90 +++ b/src/simulation.F90 @@ -1,7 +1,7 @@ module simulation #ifdef MPI - use mpi + use message_passing #endif use cmfd_execute, only: cmfd_init_batch, execute_cmfd diff --git a/src/source.F90 b/src/source.F90 index ad565c95c..194c8c6ad 100644 --- a/src/source.F90 +++ b/src/source.F90 @@ -53,7 +53,7 @@ contains file_id = file_open(path_source, 'r', parallel=.true.) ! Read the file type - call read_dataset(file_id, "filetype", filetype) + call read_dataset(filetype, file_id, "filetype") ! Check to make sure this is a source file if (filetype /= 'source') then diff --git a/src/state_point.F90 b/src/state_point.F90 index 1cbe59c9c..3a55af22c 100644 --- a/src/state_point.F90 +++ b/src/state_point.F90 @@ -330,7 +330,11 @@ contains NUCLIDE_LOOP: do j = 1, tally % n_nuclide_bins if (tally % nuclide_bins(j) > 0) then ! Get index in cross section listings for this nuclide - i_list = nuclides(tally % nuclide_bins(j)) % listing + if (run_CE) then + i_list = nuclides(tally % nuclide_bins(j)) % listing + else + i_list = nuclides_MG(tally % nuclide_bins(j)) % obj % listing + end if ! Determine position of . in alias string (e.g. "U-235.71c"). If ! no . is found, just use the entire string. @@ -371,11 +375,11 @@ contains MOMENT_LOOP: do j = 1, tally % n_user_score_bins select case(tally % score_bins(k)) case (SCORE_SCATTER_N, SCORE_NU_SCATTER_N) - str_array(k) = 'P' // trim(to_str(tally % moment_order(k))) + str_array(k) = trim(to_str(tally % moment_order(k))) k = k + 1 case (SCORE_SCATTER_PN, SCORE_NU_SCATTER_PN) do n_order = 0, tally % moment_order(k) - str_array(k) = 'P' // trim(to_str(n_order)) + str_array(k) = trim(to_str(n_order)) k = k + 1 end do case (SCORE_SCATTER_YN, SCORE_NU_SCATTER_YN, SCORE_FLUX_YN, & @@ -740,25 +744,25 @@ contains file_id = file_open(path_state_point, 'r', parallel=.true.) ! Read filetype - call read_dataset(file_id, "filetype", word) + call read_dataset(word, file_id, "filetype") if (word /= 'statepoint') then call fatal_error("OpenMC tried to restart from a non-statepoint file.") end if ! Read revision number for state point file and make sure it matches with ! current version - call read_dataset(file_id, "revision", int_array(1)) + call read_dataset(int_array(1), file_id, "revision") if (int_array(1) /= REVISION_STATEPOINT) then call fatal_error("State point version does not match current version & &in OpenMC.") end if ! Read and overwrite random number seed - call read_dataset(file_id, "seed", seed) + call read_dataset(seed, file_id, "seed") ! It is not impossible for a state point to be generated from a CE run but ! to be loaded in to an MG run (or vice versa), check to prevent that. - call read_dataset(file_id, "run_CE", sp_run_CE) + call read_dataset(sp_run_CE, file_id, "run_CE") if (sp_run_CE == 0 .and. run_CE) then call fatal_error("State point file is from multi-group run but & & current run is continous-energy!") @@ -768,24 +772,24 @@ contains end if ! Read and overwrite run information except number of batches - call read_dataset(file_id, "run_mode", word) + call read_dataset(word, file_id, "run_mode") select case(word) case ('fixed source') run_mode = MODE_FIXEDSOURCE case ('k-eigenvalue') run_mode = MODE_EIGENVALUE end select - call read_dataset(file_id, "n_particles", n_particles) - call read_dataset(file_id, "n_batches", int_array(1)) + call read_dataset(n_particles, file_id, "n_particles") + call read_dataset(int_array(1), file_id, "n_batches") ! Take maximum of statepoint n_batches and input n_batches n_batches = max(n_batches, int_array(1)) ! Read batch number to restart at - call read_dataset(file_id, "current_batch", restart_batch) + call read_dataset(restart_batch, file_id, "current_batch") ! Check for source in statepoint if needed - call read_dataset(file_id, "source_present", int_array(1)) + call read_dataset(int_array(1), file_id, "source_present") if (int_array(1) == 1) then source_present = .true. else @@ -799,37 +803,37 @@ contains ! Read information specific to eigenvalue run if (run_mode == MODE_EIGENVALUE) then - call read_dataset(file_id, "n_inactive", int_array(1)) - call read_dataset(file_id, "gen_per_batch", gen_per_batch) - call read_dataset(file_id, "k_generation", & - k_generation(1:restart_batch*gen_per_batch)) - call read_dataset(file_id, "entropy", & - entropy(1:restart_batch*gen_per_batch)) - call read_dataset(file_id, "k_col_abs", k_col_abs) - call read_dataset(file_id, "k_col_tra", k_col_tra) - call read_dataset(file_id, "k_abs_tra", k_abs_tra) - call read_dataset(file_id, "k_combined", real_array(1:2)) + call read_dataset(int_array(1), file_id, "n_inactive") + call read_dataset(gen_per_batch, file_id, "gen_per_batch") + call read_dataset(k_generation(1:restart_batch*gen_per_batch), & + file_id, "k_generation") + call read_dataset(entropy(1:restart_batch*gen_per_batch), & + file_id, "entropy") + call read_dataset(k_col_abs, file_id, "k_col_abs") + call read_dataset(k_col_tra, file_id, "k_col_tra") + call read_dataset(k_abs_tra, file_id, "k_abs_tra") + call read_dataset(real_array(1:2), file_id, "k_combined") ! Take maximum of statepoint n_inactive and input n_inactive n_inactive = max(n_inactive, int_array(1)) ! Read in to see if CMFD was on - call read_dataset(file_id, "cmfd_on", int_array(1)) + call read_dataset(int_array(1), file_id, "cmfd_on") ! Read in CMFD info if (int_array(1) == 1) then cmfd_group = open_group(file_id, "cmfd") - call read_dataset(cmfd_group, "indices", cmfd%indices) - call read_dataset(cmfd_group, "k_cmfd", cmfd%k_cmfd(1:restart_batch)) - call read_dataset(cmfd_group, "cmfd_src", cmfd%cmfd_src) - call read_dataset(cmfd_group, "cmfd_entropy", & - cmfd%entropy(1:restart_batch)) - call read_dataset(cmfd_group, "cmfd_balance", & - cmfd%balance(1:restart_batch)) - call read_dataset(cmfd_group, "cmfd_dominance", & - cmfd%dom(1:restart_batch)) - call read_dataset(cmfd_group, "cmfd_srccmp", & - cmfd%src_cmp(1:restart_batch)) + call read_dataset(cmfd % indices, cmfd_group, "indices") + call read_dataset(cmfd % k_cmfd(1:restart_batch), cmfd_group, "k_cmfd") + call read_dataset(cmfd % cmfd_src, cmfd_group, "cmfd_src") + call read_dataset(cmfd % entropy(1:restart_batch), cmfd_group, & + "cmfd_entropy") + call read_dataset(cmfd % balance(1:restart_batch), cmfd_group, & + "cmfd_balance") + call read_dataset(cmfd % dom(1:restart_batch), cmfd_group, & + "cmfd_dominance") + call read_dataset(cmfd % src_cmp(1:restart_batch), cmfd_group, & + "cmfd_srccmp") call close_group(cmfd_group) end if end if @@ -849,14 +853,14 @@ contains #endif ! Read number of realizations for global tallies - call read_dataset(file_id, "n_realizations", n_realizations, indep=.true.) + call read_dataset(n_realizations, file_id, "n_realizations", indep=.true.) ! Read global tally data call read_dataset(file_id, "global_tallies", global_tallies) ! Check if tally results are present tallies_group = open_group(file_id, "tallies") - call read_dataset(tallies_group, "tallies_present", int_array(1), & + call read_dataset(int_array(1), tallies_group, "tallies_present", & indep=.true.) ! Read in sum and sum squared @@ -869,8 +873,8 @@ contains tally_group = open_group(tallies_group, "tally " // & trim(to_str(tally % id))) call read_dataset(tally_group, "results", tally % results) - call read_dataset(tally_group, "n_realizations", & - tally % n_realizations) + call read_dataset(tally % n_realizations, tally_group, & + "n_realizations") call close_group(tally_group) end do TALLY_RESULTS end if @@ -896,7 +900,7 @@ contains file_id = file_open(path_source_point, 'r', parallel=.true.) ! Read file type - call read_dataset(file_id, "filetype", int_array(1)) + call read_dataset(int_array(1), file_id, "filetype") end if diff --git a/src/summary.F90 b/src/summary.F90 index a1f024df8..2ec96042c 100644 --- a/src/summary.F90 +++ b/src/summary.F90 @@ -68,6 +68,7 @@ contains "description", "Number of generations per batch") end if + call write_nuclides(file_id) call write_geometry(file_id) call write_materials(file_id) if (n_tallies > 0) then @@ -105,6 +106,49 @@ contains end subroutine write_header +!=============================================================================== +! WRITE_NUCLIDES +!=============================================================================== + + subroutine write_nuclides(file_id) + integer(HID_T), intent(in) :: file_id + integer(HID_T) :: nuclide_group + integer :: i + character(12), allocatable :: nucnames(:) + real(8), allocatable :: awrs(:) + integer, allocatable :: zaids(:) + + ! Write useful data from nuclide objects + nuclide_group = create_group(file_id, "nuclides") + call write_dataset(nuclide_group, "n_nuclides_total", n_nuclides_total) + + ! Build array of nuclide names, awrs, and zaids + allocate(nucnames(n_nuclides_total)) + allocate(awrs(n_nuclides_total)) + allocate(zaids(n_nuclides_total)) + do i = 1, n_nuclides_total + if (run_CE) then + nucnames(i) = xs_listings(nuclides(i) % listing) % alias + awrs(i) = nuclides(i) % awr + zaids(i) = nuclides(i) % zaid + else + nucnames(i) = xs_listings(nuclides_MG(i) % obj % listing) % alias + awrs(i) = nuclides_MG(i) % obj % awr + zaids(i) = nuclides_MG(i) % obj % zaid + end if + end do + + ! Write nuclide names, awrs and zaids + call write_dataset(nuclide_group, "names", nucnames) + call write_dataset(nuclide_group, "awrs", awrs) + call write_dataset(nuclide_group, "zaids", zaids) + + call close_group(nuclide_group) + + deallocate(nucnames, awrs, zaids) + + end subroutine write_nuclides + !=============================================================================== ! WRITE_GEOMETRY !=============================================================================== @@ -661,7 +705,11 @@ contains allocate(str_array(t%n_nuclide_bins)) NUCLIDE_LOOP: do j = 1, t%n_nuclide_bins if (t%nuclide_bins(j) > 0) then - i_list = nuclides(t%nuclide_bins(j))%listing + if (run_CE) then + i_list = nuclides(t % nuclide_bins(j)) % listing + else + i_list = nuclides_MG(t % nuclide_bins(j)) % obj % listing + end if i_xs = index(xs_listings(i_list)%alias, '.') if (i_xs > 0) then str_array(j) = xs_listings(i_list)%alias(1:i_xs - 1) diff --git a/src/tally.F90 b/src/tally.F90 index 43e10986e..3884d592a 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -27,8 +27,9 @@ module tally !$omp threadprivate(position) - procedure(score_general_), pointer :: score_general => null() - procedure(get_scoring_bins_), pointer :: get_scoring_bins => null() + procedure(score_general_), pointer :: score_general => null() + procedure(score_analog_tally_), pointer :: score_analog_tally => null() + procedure(get_scoring_bins_), pointer :: get_scoring_bins => null() abstract interface subroutine score_general_(p, t, start_index, filter_index, i_nuclide, & @@ -44,6 +45,11 @@ module tally real(8), intent(in) :: atom_density ! atom/b-cm end subroutine score_general_ + subroutine score_analog_tally_(p) + import Particle + type(Particle), intent(in) :: p + end subroutine score_analog_tally_ + subroutine get_scoring_bins_(p, i_tally, found_bin) import Particle type(Particle), intent(in) :: p @@ -61,11 +67,13 @@ contains subroutine init_tally_routines() if (run_CE) then - score_general => score_general_ce - get_scoring_bins => get_scoring_bins_ce + score_general => score_general_ce + score_analog_tally => score_analog_tally_ce + get_scoring_bins => get_scoring_bins_ce else - score_general => score_general_mg - get_scoring_bins => get_scoring_bins_mg + score_general => score_general_mg + score_analog_tally => score_analog_tally_mg + get_scoring_bins => get_scoring_bins_mg end if end subroutine init_tally_routines @@ -810,16 +818,48 @@ contains integer :: score_bin ! scoring bin, e.g. SCORE_FLUX integer :: score_index ! scoring bin index real(8) :: score ! analog tally score - real(8) :: macro_total ! material macro total xs - real(8) :: macro_scatt ! material macro scatt xs - real(8) :: micro_abs ! nuclidic microscopic abs real(8) :: p_uvw(3) ! Particle's current uvw + integer :: p_g ! Particle group to use for getting info + ! to tally with. + class(Mgxs), pointer :: matxs + class(Mgxs), pointer :: nucxs - ! Set the direction, if needed for nuclidic data, so that nuc % get_xs - ! knows wihch direction it should be using for direction-dependent - ! mgxs - if (i_nuclide > 0) then + ! Set the direction and group to use with get_xs + ! this only depends on if we + if (t % estimator == ESTIMATOR_ANALOG .or. & + t % estimator == ESTIMATOR_COLLISION) then + if (survival_biasing) then + ! Then we either are alive and had a scatter (and so g changed), + ! or are dead and g did not change + if (p % alive) then + p_uvw = p % last_uvw + p_g = p % last_g + else + p_uvw = p % coord(p % n_coord) % uvw + p_g = p % g + end if + else if (p % event == EVENT_SCATTER) then + ! Then the energy group has been changed by the scattering routine + ! meaning gin is now in p % last_g + p_uvw = p % last_uvw + p_g = p % last_g + else + ! No scatter, no change in g. + p_uvw = p % coord(p % n_coord) % uvw + p_g = p % g + end if + else + ! No actual collision so g has not changed. p_uvw = p % coord(p % n_coord) % uvw + p_g = p % g + end if + + ! To significantly reduce de-referencing, point matxs to the + ! macroscopic Mgxs for the material of interest + matxs => macro_xs(p % material) % obj + ! Do same for nucxs, point it to the microscopic nuclide data of interest + if (i_nuclide > 0) then + nucxs => nuclides_MG(i_nuclide) % obj end if i = 0 @@ -870,13 +910,16 @@ contains else score = p % last_wgt end if + if (i_nuclide > 0) then + score = score * atom_density * & + nucxs % get_xs('total', p_g, UVW=p_uvw) / & + matxs % get_xs('total', p_g, UVW=p_uvw) + end if else if (i_nuclide > 0) then - associate (nuc => nuclides_MG(i_nuclide) % obj) - score = nuc % get_xs(p % g, 'total', UVW=p_uvw) * & - atom_density * flux - end associate + score = nucxs % get_xs('total', p_g, UVW=p_uvw) * & + atom_density * flux else score = material_xs % total * flux end if @@ -884,7 +927,8 @@ contains case (SCORE_INVERSE_VELOCITY) - if (t % estimator == ESTIMATOR_ANALOG) then + if (t % estimator == ESTIMATOR_ANALOG .or. & + t % estimator == ESTIMATOR_COLLISION) then ! All events score to an inverse velocity bin. We actually use a ! collision estimator in place of an analog one since there is no way ! to count 'events' exactly for the inverse velocity @@ -895,150 +939,94 @@ contains else score = p % last_wgt end if - score = score * inverse_velocities(p % last_g) + score = score * inverse_velocities(p_g) / material_xs % total else ! For inverse velocity, we need no cross section - score = score * inverse_velocities(p % g) + score = flux * inverse_velocities(p_g) end if - case (SCORE_SCATTER, SCORE_SCATTER_N) + case (SCORE_SCATTER, SCORE_SCATTER_N, SCORE_SCATTER_PN, SCORE_SCATTER_YN) if (t % estimator == ESTIMATOR_ANALOG) then ! Skip any event where the particle didn't scatter - if (p % event /= EVENT_SCATTER) cycle SCORE_LOOP + if (p % event /= EVENT_SCATTER) then + if (score_bin == SCORE_SCATTER_PN) then + i = i + t % moment_order(i) + else if (score_bin == SCORE_SCATTER_YN) then + i = i + (t % moment_order(i) + 1)**2 - 1 + end if + cycle SCORE_LOOP + end if + ! Since only scattering events make it here, again we can use ! the weight entering the collision as the estimator for the ! reaction rate score = p % last_wgt - else - ! Note SCORE_SCATTER_N not available for tracklength/collision. + ! Since we transport based on material data, the angle selected + ! was not selected from the f(mu) for the nuclide. Therefore + ! adjust the score by the actual probability for that nuclide. if (i_nuclide > 0) then - associate (nuc => nuclides_MG(i_nuclide) % obj) - score = nuc % get_xs(p % g, 'scatter', UVW=p_uvw) * & - atom_density * flux - end associate + score = score * atom_density * & + nucxs % get_xs('scatter*f_mu/mult', p % last_g, p % g, & + UVW=p_uvw, MU=p % mu) / & + matxs % get_xs('scatter*f_mu/mult', p % last_g, p % g, & + UVW=p_uvw, MU=p % mu) + end if + + else + ! Note SCORE_SCATTER_*N not available for tracklength/collision. + if (i_nuclide > 0) then + score = atom_density * flux * & + nucxs % get_xs('scatter/mult', p_g, UVW=p_uvw) else - ! Get the scattering x/s (stored in % elastic) - score = material_xs % elastic * flux + ! Get the scattering x/s and take away + ! the multiplication baked in to sigS + score = flux * & + matxs % get_xs('scatter/mult', p_g, UVW=p_uvw) end if end if - if (i_nuclide > 0) then - associate (nuc => nuclides_MG(i_nuclide) % obj) - score = score * nuc % get_xs(p % g, 'f_mu/mult', p % last_g, & - p % last_uvw, p % mu) - end associate + + case (SCORE_NU_SCATTER, SCORE_NU_SCATTER_N, SCORE_NU_SCATTER_PN, & + SCORE_NU_SCATTER_YN) + if (t % estimator == ESTIMATOR_ANALOG) then + ! Skip any event where the particle didn't scatter + if (p % event /= EVENT_SCATTER) then + if (score_bin == SCORE_NU_SCATTER_PN) then + i = i + t % moment_order(i) + else if (score_bin == SCORE_NU_SCATTER_YN) then + i = i + (t % moment_order(i) + 1)**2 - 1 + end if + cycle SCORE_LOOP + end if + + ! For scattering production, we need to use the pre-collision + ! weight times the multiplicity as the estimate for the number of + ! neutrons exiting a reaction with neutrons in the exit channel + score = p % wgt + + ! Since we transport based on material data, the angle selected + ! was not selected from the f(mu) for the nuclide. Therefore + ! adjust the score by the actual probability for that nuclide. + if (i_nuclide > 0) then + score = score * atom_density * & + nucxs % get_xs('scatter*f_mu', p % last_g, p % g, & + UVW=p_uvw, MU=p % mu) / & + matxs % get_xs('scatter*f_mu', p % last_g, p % g, & + UVW=p_uvw, MU=p % mu) + end if + else - score = score / & - macro_xs(p % material) % obj % get_xs(p % g, 'mult', & - p % last_g, & - p % last_uvw) - end if - - - case (SCORE_SCATTER_PN) - ! Only analog estimators are available. - ! Skip any event where the particle didn't scatter - if (p % event /= EVENT_SCATTER) then - i = i + t % moment_order(i) - cycle SCORE_LOOP - end if - ! Since only scattering events make it here, again we can use - ! the weight entering the collision as the estimator for the - ! reaction rate - score = p % last_wgt - - if (i_nuclide > 0) then - associate (nuc => nuclides_MG(i_nuclide) % obj) - score = score * nuc % get_xs(p % g, 'f_mu/mult', p % last_g, & - p % last_uvw, p % mu) - end associate - else - score = score / & - macro_xs(p % material) % obj % get_xs(p % g, 'mult', & - p % last_g, & - p % last_uvw) - end if - - - case (SCORE_SCATTER_YN) - ! Only analog estimators are available. - ! Skip any event where the particle didn't scatter - if (p % event /= EVENT_SCATTER) then - i = i + (t % moment_order(i) + 1)**2 - 1 - cycle SCORE_LOOP - end if - ! Since only scattering events make it here, again we can use - ! the weight entering the collision as the estimator for the - ! reaction rate - score = p % last_wgt - - if (i_nuclide > 0) then - associate (nuc => nuclides_MG(i_nuclide) % obj) - score = score * nuc % get_xs(p % g, 'f_mu/mult', p % last_g, & - p % last_uvw, p % mu) - end associate - else - score = score / & - macro_xs(p % material) % obj % get_xs(p % g, 'mult', & - p % last_g, & - p % last_uvw) - end if - - - case (SCORE_NU_SCATTER, SCORE_NU_SCATTER_N) - ! Only analog estimators are available. - ! Skip any event where the particle didn't scatter - if (p % event /= EVENT_SCATTER) cycle SCORE_LOOP - ! For scattering production, we need to use the pre-collision - ! weight times the multiplicity as the estimate for the number of - ! neutrons exiting a reaction with neutrons in the exit channel - score = p % wgt - if (i_nuclide > 0) then - associate (nuc => nuclides_MG(i_nuclide) % obj) - score = score * nuc % get_xs(p % g, 'f_mu', p % last_g, & - p % last_uvw, p % mu) - end associate - end if - - - case (SCORE_NU_SCATTER_PN) - ! Only analog estimators are available. - ! Skip any event where the particle didn't scatter - if (p % event /= EVENT_SCATTER) then - i = i + t % moment_order(i) - cycle SCORE_LOOP - end if - ! For scattering production, we need to use the pre-collision - ! weight times the multiplicity as the estimate for the number of - ! neutrons exiting a reaction with neutrons in the exit channel - score = p % wgt - if (i_nuclide > 0) then - associate (nuc => nuclides_MG(i_nuclide) % obj) - score = score * nuc % get_xs(p % g, 'f_mu', p % last_g, & - p % last_uvw, p % mu) - end associate - end if - - - case (SCORE_NU_SCATTER_YN) - ! Only analog estimators are available. - ! Skip any event where the particle didn't scatter - if (p % event /= EVENT_SCATTER) then - i = i + (t % moment_order(i) + 1)**2 - 1 - cycle SCORE_LOOP - end if - ! For scattering production, we need to use the pre-collision - ! weight times the multiplicity as the estimate for the number of - ! neutrons exiting a reaction with neutrons in the exit channel - score = p % wgt - if (i_nuclide > 0) then - associate (nuc => nuclides_MG(i_nuclide) % obj) - score = score * nuc % get_xs(p % g, 'f_mu', p % last_g, & - p % last_uvw, p % mu) - end associate + ! Note SCORE_NU_SCATTER_*N not available for tracklength/collision. + if (i_nuclide > 0) then + score = nucxs % get_xs('scatter', p_g, UVW=p_uvw) * & + atom_density * flux + else + ! Get the scattering x/s, which includes multiplication + score = matxs % get_xs('scatter', p_g, UVW=p_uvw) * flux + end if end if @@ -1046,24 +1034,14 @@ contains ! Only analog estimators are available. ! Skip any event where the particle didn't scatter if (p % event /= EVENT_SCATTER) cycle SCORE_LOOP - ! get material macros - macro_total = material_xs % total - macro_scatt = material_xs % elastic ! Score total rate - p1 scatter rate Note estimator needs to be ! adjusted since tallying is only occuring when a scatter has ! happened. Effectively this means multiplying the estimator by ! total/scatter macro - score = (macro_total - p % mu * macro_scatt) * (ONE / macro_scatt) - - - case (SCORE_N_1N) - ! Only analog estimators are available. - ! Skip any event where the particle didn't scatter - if (p % event /= EVENT_SCATTER) cycle SCORE_LOOP - ! Skip any events where weight of particle changed - if (p % wgt /= p % last_wgt) cycle SCORE_LOOP - ! All events that reach this point are (n,1n) reactions - score = p % last_wgt + score = (material_xs % total - p % mu * material_xs % elastic) + if (material_xs % elastic /= ZERO) then + score = score / material_xs % elastic + end if case (SCORE_ABSORPTION) @@ -1079,13 +1057,15 @@ contains ! can just use the particle's weight entering the collision score = p % last_wgt end if - + if (i_nuclide > 0) then + score = score * atom_density * & + nucxs % get_xs('absorption', p_g, UVW=p_uvw) / & + matxs % get_xs('absorption', p_g, UVW=p_uvw) + end if else if (i_nuclide > 0) then - associate (nuc => nuclides_MG(i_nuclide) % obj) - score = nuc % get_xs(p % g, 'absorption', UVW=p_uvw) & - * atom_density * flux - end associate + score = nucxs % get_xs('absorption', p_g, UVW=p_uvw) * & + atom_density * flux else score = material_xs % absorption * flux end if @@ -1098,38 +1078,30 @@ contains ! No fission events occur if survival biasing is on -- need to ! calculate fraction of absorptions that would have resulted in ! fission - associate (nuc => nuclides_MG(i_nuclide) % obj) - micro_abs = nuc % get_xs(p % g, 'absorption', UVW=p_uvw) - if (micro_abs > ZERO) then - score = p % absorb_wgt * & - nuc % get_xs(p % g, 'fission', UVW=p_uvw) & - / micro_abs - else - score = ZERO - end if - end associate + score = p % absorb_wgt else ! Skip any non-absorption events if (p % event == EVENT_SCATTER) cycle SCORE_LOOP ! All fission events will contribute, so again we can use ! particle's weight entering the collision as the estimate for the ! fission reaction rate - associate (nuc => nuclides_MG(i_nuclide) % obj) - score = p % last_wgt & - * nuc % get_xs(p % g, 'fission', UVW=p_uvw) & - / nuc % get_xs(p % g, 'absorption', UVW=p_uvw) - end associate + score = p % last_wgt end if - + if (i_nuclide > 0) then + score = score * atom_density * & + nucxs % get_xs('fission', p_g, UVW=p_uvw) / & + matxs % get_xs('absorption', p_g, UVW=p_uvw) + else + score = score * & + matxs % get_xs('fission', p_g, UVW=p_uvw) / & + matxs % get_xs('absorption', p_g, UVW=p_uvw) + end if else if (i_nuclide > 0) then - associate (nuc => nuclides_MG(i_nuclide) % obj) - score = nuc % get_xs(p % g, 'fission', UVW=p_uvw) * & - atom_density * flux - end associate + score = nucxs % get_xs('fission', p_g, UVW=p_uvw) * & + atom_density * flux else - score = flux * macro_xs(p % material) % obj % get_xs(p % g, & - 'fission', UVW=p_uvw) + score = flux * material_xs % fission end if end if @@ -1144,7 +1116,8 @@ contains ! neutrons were emitted with different energies, multiple ! outgoing energy bins may have been scored to. The following ! logic treats this special case and results to multiple bins - call score_fission_eout_mg(p, t, score_index) + call score_fission_eout_mg(p, t, score_index, i_nuclide, & + atom_density) cycle SCORE_LOOP end if end if @@ -1152,16 +1125,16 @@ contains ! No fission events occur if survival biasing is on -- need to ! calculate fraction of absorptions that would have resulted in ! nu-fission - associate (nuc => nuclides_MG(i_nuclide) % obj) - micro_abs = nuc % get_xs(p % g, 'absorption', UVW=p_uvw) - if (micro_abs > ZERO) then - score = p % absorb_wgt * & - nuc % get_xs(p % g, 'fission', UVW=p_uvw) / & - micro_abs - else - score = ZERO - end if - end associate + score = p % absorb_wgt + if (i_nuclide > 0) then + score = score * atom_density * & + nucxs % get_xs('nu_fission', p_g, UVW=p_uvw) / & + matxs % get_xs('absorption', p_g, UVW=p_uvw) + else + score = score * & + matxs % get_xs('nu_fission', p_g, UVW=p_uvw) / & + matxs % get_xs('absorption', p_g, UVW=p_uvw) + end if else ! Skip any non-fission events if (.not. p % fission) cycle SCORE_LOOP @@ -1171,14 +1144,17 @@ contains ! bank. Since this was weighted by 1/keff, we multiply by keff ! to get the proper score. score = keff * p % wgt_bank + if (i_nuclide > 0) then + score = score * atom_density * & + nucxs % get_xs('fission', p_g, UVW=p_uvw) / & + matxs % get_xs('fission', p_g, UVW=p_uvw) + end if end if else if (i_nuclide > 0) then - associate (nuc => nuclides_MG(i_nuclide) % obj) - score = nuc % get_xs(p % g, 'nu_fission', UVW=p_uvw) & - * atom_density * flux - end associate + score = nucxs % get_xs('nu_fission', p_g, UVW=p_uvw) * & + atom_density * flux else score = material_xs % nu_fission * flux end if @@ -1186,43 +1162,36 @@ contains case (SCORE_KAPPA_FISSION) - ! Determine kappa-fission cross section - score = ZERO if (t % estimator == ESTIMATOR_ANALOG) then if (survival_biasing) then ! No fission events occur if survival biasing is on -- need to ! calculate fraction of absorptions that would have resulted in - ! fission scale by kappa-fission - associate (nuc => nuclides_MG(i_nuclide) % obj) - micro_abs = nuc % get_xs(p % g, 'absorption', UVW=p_uvw) - if (micro_abs > ZERO) then - score = p % absorb_wgt * & - nuc % get_xs(p % g, 'k_fission', UVW=p_uvw) / & - micro_abs - end if - end associate + ! fission + score = p % absorb_wgt else ! Skip any non-absorption events if (p % event == EVENT_SCATTER) cycle SCORE_LOOP ! All fission events will contribute, so again we can use - ! particle's weight entering the collision as the estimate for - ! the fission energy production rate - associate (nuc => nuclides_MG(i_nuclide) % obj) - score = p % last_wgt * & - nuc % get_xs(p % g, 'k_fission', UVW=p_uvw) / & - nuc % get_xs(p % g, 'absorption', UVW=p_uvw) - end associate + ! particle's weight entering the collision as the estimate for the + ! fission reaction rate + score = p % last_wgt + end if + if (i_nuclide > 0) then + score = score * atom_density * & + nucxs % get_xs('kappa_fission', p_g, UVW=p_uvw) / & + matxs % get_xs('absorption', p_g, UVW=p_uvw) + else + score = score * & + matxs % get_xs('kappa_fission', p_g, UVW=p_uvw) / & + matxs % get_xs('absorption', p_g, UVW=p_uvw) end if - else if (i_nuclide > 0) then - associate (nuc => nuclides_MG(i_nuclide) % obj) - score = nuc % get_xs(p % g, 'k_fission', UVW=p_uvw) & - * atom_density * flux - end associate + score = flux * atom_density * & + nucxs % get_xs('kappa_fission', p_g, UVW=p_uvw) else - score = flux * macro_xs(p % material) % obj % get_xs(p % g, & - 'k_fission', UVW=p_uvw) + score = flux * matxs % get_xs('kappa_fission', p_g, UVW=p_uvw) + end if end if @@ -1239,6 +1208,8 @@ contains score, i) end do SCORE_LOOP + + nullify(matxs,nucxs) end subroutine score_general_mg !=============================================================================== @@ -1413,7 +1384,7 @@ contains ! triggered at every collision, not every event !=============================================================================== - subroutine score_analog_tally(p) + subroutine score_analog_tally_ce(p) type(Particle), intent(in) :: p @@ -1423,17 +1394,9 @@ contains ! position during the loop integer :: filter_index ! single index for single bin integer :: i_nuclide ! index in nuclides array - real(8) :: last_wgt ! pre-collision particle weight - real(8) :: wgt ! post-collision particle weight - real(8) :: mu ! cosine of angle of collision logical :: found_bin ! scoring bin found? type(TallyObject), pointer :: t - ! Copy particle's pre- and post-collision weight and angle - last_wgt = p % last_wgt - wgt = p % wgt - mu = p % mu - ! A loop over all tallies is necessary because we need to simultaneously ! determine different filter bins for the same tally in order to score to it @@ -1512,7 +1475,87 @@ contains ! Reset tally map positioning position = 0 - end subroutine score_analog_tally + end subroutine score_analog_tally_ce + + subroutine score_analog_tally_mg(p) + + type(Particle), intent(in) :: p + + integer :: i, m + integer :: i_tally + integer :: k ! loop index for nuclide bins + ! position during the loop + integer :: filter_index ! single index for single bin + integer :: i_nuclide ! index in nuclides array + logical :: found_bin ! scoring bin found? + type(TallyObject), pointer :: t + type(Material), pointer :: mat + real(8) :: atom_density + + ! A loop over all tallies is necessary because we need to simultaneously + ! determine different filter bins for the same tally in order to score to it + + TALLY_LOOP: do i = 1, active_analog_tallies % size() + ! Get index of tally and pointer to tally + i_tally = active_analog_tallies % get_item(i) + t => tallies(i_tally) + + ! Get pointer to current material. We need this in order to determine what + ! nuclides are in the material + mat => materials(p % material) + + ! ======================================================================= + ! DETERMINE SCORING BIN COMBINATION + + call get_scoring_bins(p, i_tally, found_bin) + if (.not. found_bin) cycle + + ! ======================================================================= + ! CALCULATE RESULTS AND ACCUMULATE TALLY + + ! If we have made it here, we have a scoring combination of bins for this + ! tally -- now we need to determine where in the results array we should + ! be accumulating the tally values + + ! Determine scoring index for this filter combination + filter_index = sum((matching_bins(1:t%n_filters) - 1) * t % stride) + 1 + + ! Check for nuclide bins + k = 0 + NUCLIDE_LOOP: do while (k < t % n_nuclide_bins) + + ! Increment the index in the list of nuclide bins + k = k + 1 + + i_nuclide = t % nuclide_bins(k) + + ! Check to see if this nuclide was in the material of our collision. + do m = 1, mat % n_nuclides + if (mat % nuclide(m) == i_nuclide) then + atom_density = mat % atom_density(m) + exit + end if + end do + + ! Determine score for each bin + call score_general(p, t, (k-1)*t % n_score_bins, filter_index, & + i_nuclide, atom_density, ZERO) + + end do NUCLIDE_LOOP + + ! If the user has specified that we can assume all tallies are spatially + ! separate, this implies that once a tally has been scored to, we needn't + ! check the others. This cuts down on overhead when there are many + ! tallies specified + + if (assume_separate) exit TALLY_LOOP + + end do TALLY_LOOP + + ! Reset tally map positioning + position = 0 + + end subroutine score_analog_tally_mg !=============================================================================== ! SCORE_FISSION_EOUT handles a special case where we need to store neutron @@ -1582,10 +1625,12 @@ contains end subroutine score_fission_eout_ce - subroutine score_fission_eout_mg(p, t, i_score) + subroutine score_fission_eout_mg(p, t, i_score, i_nuclide, atom_density) type(Particle), intent(in) :: p type(TallyObject), intent(inout) :: t - integer, intent(in) :: i_score ! index for score + integer, intent(in) :: i_score ! index for score + integer, intent(in) :: i_nuclide ! index for nuclide + real(8), intent(in) :: atom_density integer :: i ! index of outgoing energy filter integer :: n ! number of energies on filter @@ -1594,6 +1639,7 @@ contains integer :: i_filter ! index for matching filter bin combination real(8) :: score ! actual score integer :: gout ! energy group of fission bank site + integer :: gin ! energy group of incident particle real(8) :: E_out ! save original outgoing energy bin and score index @@ -1612,6 +1658,18 @@ contains do k = 1, p % n_bank ! determine score based on bank site weight and keff score = keff * fission_bank(n_bank - p % n_bank + k) % wgt + if (i_nuclide > 0) then + if (survival_biasing) then + gin = p % g + else + gin = p % last_g + end if + score = score * atom_density * & + nuclides_MG(i_nuclide) % obj % get_xs('fission', gin, & + UVW=p % last_uvw) / & + macro_xs(p % material) % obj % get_xs('fission', gin, & + UVW=p % last_uvw) + end if if (t % energyout_matches_groups) then ! determine outgoing energy from fission bank @@ -1621,7 +1679,7 @@ contains matching_bins(i) = gout else ! determine outgoing energy from fission bank - E_out = fission_bank(n_bank - p % n_bank + k) % E + E_out = energy_bin_avg(int(fission_bank(n_bank - p % n_bank + k) % E)) ! check if outgoing energy is within specified range on filter if (E_out < t % filters(i) % real_bins(1) .or. & @@ -2617,7 +2675,6 @@ contains end if end if - case (FILTER_ENERGYOUT) if (t % energyout_matches_groups) then ! Since all groups are filters, the filter bin is the group @@ -2641,7 +2698,6 @@ contains end if end if - case (FILTER_MU) ! determine mu bin n = t % filters(i) % n_bins diff --git a/src/tracking.F90 b/src/tracking.F90 index 63b2de98b..9b358076d 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -7,7 +7,6 @@ module tracking cross_lattice, check_cell_overlap use geometry_header, only: Universe, BASE_UNIVERSE use global - use macroxs_header, only: MacroXS use output, only: write_message use particle_header, only: LocalCoord, Particle use physics, only: collision @@ -103,6 +102,7 @@ contains material_xs % total = ZERO material_xs % elastic = ZERO material_xs % absorption = ZERO + material_xs % fission = ZERO material_xs % nu_fission = ZERO end if end if diff --git a/tests/input_set.py b/tests/input_set.py index daff38ba1..2c6841e25 100644 --- a/tests/input_set.py +++ b/tests/input_set.py @@ -5,9 +5,9 @@ from openmc.stats import Box class InputSet(object): def __init__(self): - self.settings = openmc.SettingsFile() - self.materials = openmc.MaterialsFile() - self.geometry = openmc.GeometryFile() + self.settings = openmc.Settings() + self.materials = openmc.Materials() + self.geometry = openmc.Geometry() self.tallies = None self.plots = None @@ -267,9 +267,9 @@ class InputSet(object): # Define the materials file. self.materials.default_xs = '71c' - self.materials.add_materials((fuel, clad, cold_water, hot_water, - rpv_steel, lower_rad_ref, upper_rad_ref, bot_plate, bot_nozzle, - top_nozzle, top_fa, bot_fa)) + self.materials += (fuel, clad, cold_water, hot_water, rpv_steel, + lower_rad_ref, upper_rad_ref, bot_plate, + bot_nozzle, top_nozzle, top_fa, bot_fa) # Define surfaces. s1 = openmc.ZCylinder(R=0.41, surface_id=1) @@ -550,11 +550,8 @@ class InputSet(object): root.add_cells((c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12)) - # Define the geometry file. - geometry = openmc.Geometry() - geometry.root_universe = root - - self.geometry.geometry = geometry + # Assign root universe to geometry + self.geometry.root_universe = root def build_default_settings(self): self.settings.batches = 10 @@ -593,7 +590,7 @@ class MGInputSet(InputSet): # Define the materials file. self.materials.default_xs = '71c' - self.materials.add_materials((uo2, clad, water)) + self.materials += (uo2, clad, water) # Define surfaces. @@ -630,12 +627,8 @@ class MGInputSet(InputSet): root.add_cells((c1,c2,c3)) - # Define the geometry file. - geometry = openmc.Geometry() - geometry.root_universe = root - - self.geometry.geometry = geometry - + # Assign root universe to geometry + self.geometry.root_universe = root def build_default_settings(self): self.settings.batches = 10 @@ -656,8 +649,3 @@ class MGInputSet(InputSet): plot.color = 'mat' self.plots.add_plot(plot) - - - - - diff --git a/tests/test_asymmetric_lattice/inputs_true.dat b/tests/test_asymmetric_lattice/inputs_true.dat index e3b00b185..f40e661b3 100644 --- a/tests/test_asymmetric_lattice/inputs_true.dat +++ b/tests/test_asymmetric_lattice/inputs_true.dat @@ -1 +1 @@ -b9b4222c4beea80fe6083590f6b785303d174972d80671fb661bac8e030db6f4a61648240cfad6162799361fc0e08a23c61d31aff844d978528d6dad5b5fbc63 \ No newline at end of file +9b859eb5501c05b6a652d299bd0cadc0a924ffae31117babbdc9f7f8ca87689322c275818eb0dde0ff5fa78317d8d8f1585b18dcc772e3ff4ed499de8a491dc3 \ No newline at end of file diff --git a/tests/test_asymmetric_lattice/test_asymmetric_lattice.py b/tests/test_asymmetric_lattice/test_asymmetric_lattice.py index fdb21db33..504cc4746 100644 --- a/tests/test_asymmetric_lattice/test_asymmetric_lattice.py +++ b/tests/test_asymmetric_lattice/test_asymmetric_lattice.py @@ -7,8 +7,6 @@ import hashlib sys.path.insert(0, os.pardir) from testing_harness import PyAPITestHarness import openmc -from openmc.source import Source -from openmc.stats import Box class AsymmetricLatticeTestHarness(PyAPITestHarness): @@ -20,7 +18,7 @@ class AsymmetricLatticeTestHarness(PyAPITestHarness): self._input_set.build_default_materials_and_geometry() # Extract universes encapsulating fuel and water assemblies - geometry = self._input_set.geometry.geometry + geometry = self._input_set.geometry water = geometry.get_universes_by_name('water assembly (hot)')[0] fuel = geometry.get_universes_by_name('fuel assembly (hot)')[0] @@ -49,19 +47,18 @@ class AsymmetricLatticeTestHarness(PyAPITestHarness): root_univ.add_cell(root_cell) # Over-ride geometry in the input set with this 3x3 lattice - self._input_set.geometry.geometry.root_universe = root_univ + self._input_set.geometry.root_universe = root_univ # Initialize a "distribcell" filter for the fuel pin cell distrib_filter = openmc.Filter(type='distribcell', bins=[27]) # Initialize the tallies tally = openmc.Tally(name='distribcell tally', tally_id=27) - tally.add_filter(distrib_filter) - tally.add_score('nu-fission') + tally.filters.append(distrib_filter) + tally.scores.append('nu-fission') # Initialize the tallies file - tallies_file = openmc.TalliesFile() - tallies_file.add_tally(tally) + tallies_file = openmc.Tallies([tally]) # Assign the tallies file to the input set self._input_set.tallies = tallies_file @@ -70,7 +67,7 @@ class AsymmetricLatticeTestHarness(PyAPITestHarness): self._input_set.build_default_settings() # Specify summary output and correct source sampling box - source = Source(space=Box([-32, -32, 0], [32, 32, 32])) + source = openmc.Source(space=openmc.stats.Box([-32, -32, 0], [32, 32, 32])) source.space.only_fissionable = True self._input_set.settings.source = source self._input_set.settings.output = {'summary': True} @@ -85,11 +82,6 @@ class AsymmetricLatticeTestHarness(PyAPITestHarness): statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] sp = openmc.StatePoint(statepoint) - # Read the summary file - summary = glob.glob(os.path.join(os.getcwd(), 'summary.h5'))[0] - su = openmc.Summary(summary) - sp.link_with_summary(su) - # Extract the tally of interest tally = sp.get_tally(name='distribcell tally') @@ -99,8 +91,8 @@ class AsymmetricLatticeTestHarness(PyAPITestHarness): outstr += ', '.join(map(str, tally.std_dev.flatten())) + '\n' # Extract fuel assembly lattices from the summary - core = su.get_cell_by_id(1) - fuel = su.get_cell_by_id(80) + core = sp.summary.get_cell_by_id(1) + fuel = sp.summary.get_cell_by_id(80) fuel = fuel.fill core = core.fill diff --git a/tests/test_distribmat/inputs_true.dat b/tests/test_distribmat/inputs_true.dat index fddab0a60..9c8a86bfa 100644 --- a/tests/test_distribmat/inputs_true.dat +++ b/tests/test_distribmat/inputs_true.dat @@ -1 +1 @@ -401b8be1b296db7f21ccae089c7ac480044d953b7264ca0ae8e34bb79e24cbb57195bcb568deda6f2f7e07366bbfac408a92306351b9169edd04499723707e1b \ No newline at end of file +96c54eb4f1da175445bf2187449ee32c9ff435d8c60e9421a4a16497aae9f233e3e494f531892dd55f6ac1a06e0240799503ff19e14e2436a0b0f0d83ba56cb8 \ No newline at end of file diff --git a/tests/test_distribmat/test_distribmat.py b/tests/test_distribmat/test_distribmat.py index a0608c108..d8f78c5cf 100644 --- a/tests/test_distribmat/test_distribmat.py +++ b/tests/test_distribmat/test_distribmat.py @@ -28,9 +28,8 @@ class DistribmatTestHarness(PyAPITestHarness): light_fuel.set_density('g/cc', 2.0) light_fuel.add_nuclide('U-235', 1.0) - mats_file = openmc.MaterialsFile() + mats_file = openmc.Materials([moderator, dense_fuel, light_fuel]) mats_file.default_xs = '71c' - mats_file.add_materials([moderator, dense_fuel, light_fuel]) mats_file.export_to_xml() @@ -74,16 +73,14 @@ class DistribmatTestHarness(PyAPITestHarness): geometry = openmc.Geometry() geometry.root_universe = root_univ - geo_file = openmc.GeometryFile() - geo_file.geometry = geometry - geo_file.export_to_xml() + geometry.export_to_xml() #################### # Settings #################### - sets_file = openmc.SettingsFile() + sets_file = openmc.Settings() sets_file.batches = 5 sets_file.inactive = 0 sets_file.particles = 1000 @@ -96,7 +93,7 @@ class DistribmatTestHarness(PyAPITestHarness): # Plots #################### - plots_file = openmc.PlotsFile() + plots_file = openmc.Plots() plot = openmc.Plot(plot_id=1) plot.basis = 'xy' diff --git a/tests/test_iso_in_lab/inputs_true.dat b/tests/test_iso_in_lab/inputs_true.dat index 9a21b06f1..bd722c9f6 100644 --- a/tests/test_iso_in_lab/inputs_true.dat +++ b/tests/test_iso_in_lab/inputs_true.dat @@ -1 +1 @@ -e0409e0660d58857a6a96ff5cb539ccc41c82f0e443e8081ee00bbee7b6c81b0ad43c870950ae37d4a18c329067b09479a27aa171c3a3f5771f53b384496fe61 \ No newline at end of file +85faac9b8c725ec9242ebc3793b70dcd1c8e58aeb4296345aefd8031304263bd66eaad0c6f1c61a1c644b73f397699856ab3d76d2b397295176650b4069acc9e \ No newline at end of file diff --git a/tests/test_mg_basic/inputs_true.dat b/tests/test_mg_basic/inputs_true.dat index fdbdb1c96..3f83de760 100644 --- a/tests/test_mg_basic/inputs_true.dat +++ b/tests/test_mg_basic/inputs_true.dat @@ -1 +1 @@ -04b4a5099f0097bbe02983c67dea691d0d0d4ece7fb7c264b9b2c29955baa9e870b6fa999480da08ead1e5a0c078ae33ce1b0a5c8594ad465aedf9bf3933e104 \ No newline at end of file +2fdba76bad058eec6e43657692ef759de79c934076067d4ec5c9f2bdb131877e001f67e16b16bb14889e5e0a1ba84c780979b9d6772573aa6f82d979774c2af8 \ No newline at end of file diff --git a/tests/test_mg_basic/results_true.dat b/tests/test_mg_basic/results_true.dat index 35f3e73d4..55c2af813 100644 --- a/tests/test_mg_basic/results_true.dat +++ b/tests/test_mg_basic/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.045320E+00 5.851680E-02 +1.033731E+00 4.974463E-02 diff --git a/tests/test_mg_max_order/inputs_true.dat b/tests/test_mg_max_order/inputs_true.dat index 1ad336e19..63bdaab03 100644 --- a/tests/test_mg_max_order/inputs_true.dat +++ b/tests/test_mg_max_order/inputs_true.dat @@ -1 +1 @@ -abe20c626d613e73ccb1a3f8468ad1b9aecca528afa9e8131a411d754eb86b8ab64a6fb1fdc9c0b8b8158ff7c82f548de5912041bf035aa5a2d4532cfe0c9510 \ No newline at end of file +60a35864ad71646309d7f1687ba0826d4d53a5b2e8babf73614362645205484bad3c0e7bf605ec0b11cadf58474b2e3d0a97bf2d9297f9118682c37ff0269afd \ No newline at end of file diff --git a/tests/test_mg_max_order/results_true.dat b/tests/test_mg_max_order/results_true.dat index 1b2300560..f75c1300a 100644 --- a/tests/test_mg_max_order/results_true.dat +++ b/tests/test_mg_max_order/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.083030E+00 1.855038E-02 +1.055274E+00 1.715904E-02 diff --git a/tests/test_mg_max_order/test_mg_max_order.py b/tests/test_mg_max_order/test_mg_max_order.py index 2f5ee4e4e..088f6914b 100644 --- a/tests/test_mg_max_order/test_mg_max_order.py +++ b/tests/test_mg_max_order/test_mg_max_order.py @@ -27,7 +27,7 @@ class MGNuclideInputSet(MGInputSet): # Define the materials file. self.materials.default_xs = '71c' - self.materials.add_materials((uo2, clad, water)) + self.materials += (uo2, clad, water) # Define surfaces. @@ -68,7 +68,7 @@ class MGNuclideInputSet(MGInputSet): geometry = openmc.Geometry() geometry.root_universe = root - self.geometry.geometry = geometry + self.geometry = geometry class MGMaxOrderTestHarness(PyAPITestHarness): def __init__(self, statepoint_name, tallies_present, mg=False): @@ -76,9 +76,10 @@ class MGMaxOrderTestHarness(PyAPITestHarness): self._input_set = MGNuclideInputSet() def _build_inputs(self): - super(MGMaxOrderTestHarness, self)._build_inputs() # Set P1 scattering self._input_set.settings.max_order = 1 + # Call standard input build + super(MGMaxOrderTestHarness, self)._build_inputs() if __name__ == '__main__': harness = MGMaxOrderTestHarness('statepoint.10.*', False, mg=True) diff --git a/tests/test_mg_nuclide/inputs_true.dat b/tests/test_mg_nuclide/inputs_true.dat index eb643bbaf..e0af3352b 100644 --- a/tests/test_mg_nuclide/inputs_true.dat +++ b/tests/test_mg_nuclide/inputs_true.dat @@ -1 +1 @@ -c9f9e7211bfb2af58130bedfd64592d093b7bfa424953eba433ecf08940595a96b8de7a892f12d1ab465cebd8e5dd784114c1b1299b534ed329df92752c9ed1f \ No newline at end of file +0efba3dd7882fdd38756d0a8f01ff00d7a1abdaab6430b3f090f3339e552448453bbb733852b6bd6ff09608d923c282f168320f942fc2eb3a45610873c588734 \ No newline at end of file diff --git a/tests/test_mg_nuclide/results_true.dat b/tests/test_mg_nuclide/results_true.dat index 5b60cef22..55c2af813 100644 --- a/tests/test_mg_nuclide/results_true.dat +++ b/tests/test_mg_nuclide/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.380785E-01 5.556526E-03 +1.033731E+00 4.974463E-02 diff --git a/tests/test_mg_nuclide/test_mg_nuclide.py b/tests/test_mg_nuclide/test_mg_nuclide.py index deb784bad..89694eea2 100644 --- a/tests/test_mg_nuclide/test_mg_nuclide.py +++ b/tests/test_mg_nuclide/test_mg_nuclide.py @@ -12,21 +12,21 @@ class MGNuclideInputSet(MGInputSet): # Define materials needed for 1D/1G slab problem # This time do using nuclide, not macroscopic uo2 = openmc.Material(name='UO2', material_id=1) - uo2.set_density('g/cm3', 1.0) + uo2.set_density('sum', 1.0) uo2.add_nuclide("uo2_iso", 1.0) clad = openmc.Material(name='Clad', material_id=2) - clad.set_density('g/cm3', 1.0) + clad.set_density('sum', 1.0) clad.add_nuclide("clad_ang_mu", 1.0) - water_data = openmc.Nuclide('lwtr_iso_mu', '71c') + # water_data = openmc.Nuclide('lwtr_iso_mu', '71c') water = openmc.Material(name='LWTR', material_id=3) - water.set_density('g/cm3', 1.0) + water.set_density('sum', 1.0) water.add_nuclide("lwtr_iso_mu", 1.0) # Define the materials file. self.materials.default_xs = '71c' - self.materials.add_materials((uo2, clad, water)) + self.materials += (uo2, clad, water) # Define surfaces. @@ -67,7 +67,7 @@ class MGNuclideInputSet(MGInputSet): geometry = openmc.Geometry() geometry.root_universe = root - self.geometry.geometry = geometry + self.geometry = geometry class MGNuclideTestHarness(PyAPITestHarness): def __init__(self, statepoint_name, tallies_present, mg=False): diff --git a/tests/test_mg_tallies/inputs_true.dat b/tests/test_mg_tallies/inputs_true.dat index 304d2e888..41bbd2136 100644 --- a/tests/test_mg_tallies/inputs_true.dat +++ b/tests/test_mg_tallies/inputs_true.dat @@ -1 +1 @@ -ca8490e0e4549fed727ddc75b6d92cfe5162e11b905218a0afaa3ce2ee0763e2ff38074de27aaa678818624f49c5823650475dfa8f66f502a98fc03145399c0d \ No newline at end of file +6c437c3f9281c52a80a9b166971aa0f5db7ff8b6cf65c79b6d7bf294fad30cc7044f6a665cd9059f8580441bcbb581f7152ff5bccbc21fbcc407847ea6fe3306 \ No newline at end of file diff --git a/tests/test_mg_tallies/results_true.dat b/tests/test_mg_tallies/results_true.dat index 0cb47a712..debbfa537 100644 --- a/tests/test_mg_tallies/results_true.dat +++ b/tests/test_mg_tallies/results_true.dat @@ -1,86 +1,86 @@ k-combined: -1.045320E+00 5.851680E-02 +1.033731E+00 4.974463E-02 tally 1: -2.286064E+00 -1.057353E+00 -6.503987E-02 -8.851627E-04 -3.376363E+00 -2.323627E+00 -2.733240E-02 -1.607534E-04 -6.776283E-02 -9.880704E-04 -2.391658E+00 -1.201477E+00 -7.241106E-02 -1.103780E-03 -3.614949E+00 -2.730438E+00 -3.146867E-02 -2.110753E-04 -7.801752E-02 -1.297373E-03 -2.762725E+00 -1.705088E+00 -8.684520E-02 -1.654173E-03 -4.172232E+00 -3.847245E+00 -3.834947E-02 -3.212662E-04 -9.507651E-02 -1.974662E-03 -2.802290E+00 -1.773339E+00 -8.347451E-02 -1.574952E-03 -4.206829E+00 -3.971225E+00 -3.593646E-02 -2.967708E-04 -8.909414E-02 -1.824101E-03 -2.383708E+00 -1.176784E+00 -7.337273E-02 -1.097240E-03 -3.624903E+00 -2.690697E+00 -3.213890E-02 -2.139948E-04 -7.967917E-02 -1.315319E-03 -2.398216E+00 -1.234567E+00 -6.905889E-02 -9.879327E-04 -3.479138E+00 -2.538252E+00 -2.911091E-02 -1.750648E-04 -7.217215E-02 -1.076035E-03 -2.563998E+00 -1.354089E+00 -7.357381E-02 -1.097086E-03 -3.753156E+00 -2.867475E+00 -3.097034E-02 -1.948794E-04 -7.678206E-02 -1.197826E-03 -2.293243E+00 -1.172767E+00 -6.702582E-02 -9.267762E-04 -3.407144E+00 -2.469472E+00 -2.857514E-02 -1.688581E-04 -7.084385E-02 -1.037886E-03 +3.163666E+00 +2.165097E+00 +9.964133E-02 +2.052446E-03 +4.861844E+00 +4.978206E+00 +4.417216E-02 +4.040216E-04 +1.095122E-01 +2.483317E-03 +3.324437E+00 +2.299850E+00 +9.574329E-02 +1.968438E-03 +4.881821E+00 +4.943976E+00 +4.041706E-02 +3.650255E-04 +1.002025E-01 +2.243628E-03 +3.199995E+00 +2.091126E+00 +8.859707E-02 +1.592091E-03 +4.671522E+00 +4.439001E+00 +3.660515E-02 +2.728602E-04 +9.075197E-02 +1.677135E-03 +2.910284E+00 +1.723356E+00 +9.207508E-02 +1.744614E-03 +4.421737E+00 +3.979362E+00 +4.080063E-02 +3.481887E-04 +1.011535E-01 +2.140141E-03 +2.506574E+00 +1.326705E+00 +8.637880E-02 +1.598941E-03 +3.920683E+00 +3.263607E+00 +3.978214E-02 +3.424111E-04 +9.862841E-02 +2.104629E-03 +2.951103E+00 +1.826551E+00 +8.748324E-02 +1.648479E-03 +4.309848E+00 +3.903067E+00 +3.741466E-02 +3.141687E-04 +9.275891E-02 +1.931037E-03 +3.048521E+00 +2.007251E+00 +9.483162E-02 +1.935789E-03 +4.599534E+00 +4.527383E+00 +4.168244E-02 +3.813062E-04 +1.033396E-01 +2.343697E-03 +2.982958E+00 +1.966657E+00 +9.896454E-02 +2.016812E-03 +4.645921E+00 +4.599347E+00 +4.489740E-02 +4.108900E-04 +1.113102E-01 +2.525534E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -171,86 +171,86 @@ tally 1: 0.000000E+00 0.000000E+00 0.000000E+00 -2.604127E+00 -1.442914E+00 -7.142299E-02 -1.083324E-03 -3.786547E+00 -2.990260E+00 -2.935394E-02 -1.905369E-04 -7.277467E-02 -1.171135E-03 -2.457755E+00 -1.228862E+00 -6.655630E-02 -9.411086E-04 -3.528688E+00 -2.561047E+00 -2.709124E-02 -1.640319E-04 -6.716494E-02 -1.008221E-03 -2.450846E+00 -1.295337E+00 -6.779278E-02 -9.992248E-04 -3.519409E+00 -2.693620E+00 -2.793186E-02 -1.714064E-04 -6.924902E-02 -1.053549E-03 -2.469234E+00 -1.300419E+00 -7.347034E-02 -1.175743E-03 -3.675903E+00 -2.880386E+00 -3.155996E-02 -2.200036E-04 -7.824386E-02 -1.352252E-03 -2.576106E+00 -1.365945E+00 -7.241428E-02 -1.090052E-03 -3.719498E+00 -2.861357E+00 -3.008961E-02 -1.906170E-04 -7.459854E-02 -1.171627E-03 -2.503651E+00 -1.290812E+00 -7.432507E-02 -1.132918E-03 -3.702398E+00 -2.813425E+00 -3.186491E-02 -2.091477E-04 -7.899991E-02 -1.285525E-03 -2.395349E+00 -1.202098E+00 -7.095925E-02 -1.051988E-03 -3.559388E+00 -2.628753E+00 -3.041477E-02 -1.959992E-04 -7.540470E-02 -1.204709E-03 -1.910174E+00 -7.331782E-01 -6.366813E-02 -8.166135E-04 -2.966770E+00 -1.762376E+00 -2.893278E-02 -1.712979E-04 -7.173053E-02 -1.052882E-03 +2.806322E+00 +1.650116E+00 +8.677689E-02 +1.577748E-03 +4.271173E+00 +3.787053E+00 +3.812147E-02 +3.107861E-04 +9.451124E-02 +1.910246E-03 +2.767101E+00 +1.574082E+00 +8.523508E-02 +1.523190E-03 +4.143067E+00 +3.546386E+00 +3.725690E-02 +2.974028E-04 +9.236779E-02 +1.827986E-03 +2.767691E+00 +1.557585E+00 +7.816996E-02 +1.254835E-03 +4.015666E+00 +3.289915E+00 +3.260527E-02 +2.211412E-04 +8.083542E-02 +1.359243E-03 +2.734236E+00 +1.510579E+00 +8.505695E-02 +1.474976E-03 +4.114798E+00 +3.424404E+00 +3.737976E-02 +2.870194E-04 +9.267239E-02 +1.764164E-03 +2.421441E+00 +1.195490E+00 +8.292263E-02 +1.384777E-03 +3.817448E+00 +2.942804E+00 +3.814207E-02 +2.931372E-04 +9.456230E-02 +1.801767E-03 +2.724650E+00 +1.519118E+00 +9.238437E-02 +1.725646E-03 +4.305602E+00 +3.753830E+00 +4.235399E-02 +3.657508E-04 +1.050046E-01 +2.248086E-03 +2.703678E+00 +1.593893E+00 +8.744732E-02 +1.597761E-03 +4.110489E+00 +3.592877E+00 +3.913038E-02 +3.184391E-04 +9.701255E-02 +1.957285E-03 +2.707705E+00 +1.792230E+00 +8.754036E-02 +1.760104E-03 +4.203619E+00 +4.162497E+00 +3.927598E-02 +3.456207E-04 +9.737351E-02 +2.124357E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -341,86 +341,86 @@ tally 1: 0.000000E+00 0.000000E+00 0.000000E+00 -2.593479E+00 -1.421618E+00 -7.731733E-02 -1.249860E-03 -3.880469E+00 -3.167768E+00 -3.330331E-02 -2.319171E-04 -8.256599E-02 -1.425478E-03 -2.563470E+00 -1.449702E+00 -7.411043E-02 -1.158986E-03 -3.692974E+00 -2.935486E+00 -3.125554E-02 -2.061246E-04 -7.748913E-02 -1.266944E-03 -2.657580E+00 -1.493736E+00 -7.749682E-02 -1.277831E-03 -3.892576E+00 -3.190262E+00 -3.289903E-02 -2.334764E-04 -8.156370E-02 -1.435062E-03 -2.701357E+00 -1.517431E+00 -8.804410E-02 -1.639744E-03 -4.161224E+00 -3.606273E+00 -3.959674E-02 -3.345554E-04 -9.816875E-02 -2.056343E-03 -2.745200E+00 -1.523378E+00 -7.925308E-02 -1.270874E-03 -3.962649E+00 -3.165021E+00 -3.340000E-02 -2.283904E-04 -8.280570E-02 -1.403801E-03 -2.678775E+00 -1.492394E+00 -8.646776E-02 -1.554919E-03 -4.147456E+00 -3.551060E+00 -3.875994E-02 -3.125295E-04 -9.609415E-02 -1.920962E-03 -2.678888E+00 -1.497390E+00 -7.616647E-02 -1.203778E-03 -3.868905E+00 -3.108718E+00 -3.186093E-02 -2.136540E-04 -7.899003E-02 -1.313223E-03 -2.189117E+00 -9.756340E-01 -6.824988E-02 -9.549688E-04 -3.259136E+00 -2.150849E+00 -2.997262E-02 -1.883650E-04 -7.430850E-02 -1.157785E-03 +2.333969E+00 +1.124588E+00 +6.982134E-02 +1.014762E-03 +3.448351E+00 +2.435965E+00 +3.004987E-02 +1.926319E-04 +7.450003E-02 +1.184011E-03 +3.086286E+00 +1.981929E+00 +1.016918E-01 +2.146313E-03 +4.741530E+00 +4.626144E+00 +4.593581E-02 +4.489950E-04 +1.138847E-01 +2.759746E-03 +2.871515E+00 +1.672027E+00 +8.533571E-02 +1.469319E-03 +4.221958E+00 +3.599412E+00 +3.658547E-02 +2.721530E-04 +9.070318E-02 +1.672788E-03 +2.715053E+00 +1.498990E+00 +8.595576E-02 +1.530999E-03 +4.139891E+00 +3.493193E+00 +3.815373E-02 +3.059779E-04 +9.459122E-02 +1.880692E-03 +2.265823E+00 +1.080584E+00 +6.709890E-02 +9.696052E-04 +3.397886E+00 +2.446009E+00 +2.882467E-02 +1.820798E-04 +7.146249E-02 +1.119153E-03 +2.443336E+00 +1.255468E+00 +8.222450E-02 +1.373726E-03 +3.836077E+00 +3.019588E+00 +3.754438E-02 +2.866712E-04 +9.308051E-02 +1.762024E-03 +2.450506E+00 +1.305510E+00 +7.897423E-02 +1.293368E-03 +3.725732E+00 +2.954033E+00 +3.530661E-02 +2.549027E-04 +8.753260E-02 +1.566759E-03 +2.463151E+00 +1.385265E+00 +8.072623E-02 +1.376083E-03 +3.828575E+00 +3.178469E+00 +3.645911E-02 +2.733269E-04 +9.038989E-02 +1.680003E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -511,86 +511,86 @@ tally 1: 0.000000E+00 0.000000E+00 0.000000E+00 -2.761165E+00 -1.657839E+00 -7.810542E-02 -1.334149E-03 -4.026290E+00 -3.495574E+00 -3.264226E-02 -2.359256E-04 -8.092710E-02 -1.450116E-03 -2.601284E+00 -1.465130E+00 -7.485486E-02 -1.239170E-03 -3.829638E+00 -3.199488E+00 -3.159745E-02 -2.288567E-04 -7.833681E-02 -1.406667E-03 -2.419174E+00 -1.228134E+00 -7.422066E-02 -1.117508E-03 -3.667795E+00 -2.787048E+00 -3.244938E-02 -2.129012E-04 -8.044893E-02 -1.308597E-03 -2.491535E+00 -1.259222E+00 -7.470359E-02 -1.133979E-03 -3.773164E+00 -2.887196E+00 -3.234132E-02 -2.142511E-04 -8.018101E-02 -1.316894E-03 -2.430358E+00 -1.305969E+00 -7.236826E-02 -1.077801E-03 -3.691969E+00 -2.914191E+00 -3.123416E-02 -2.001679E-04 -7.743613E-02 -1.230332E-03 -3.133682E+00 -1.984584E+00 -8.337467E-02 -1.392595E-03 -4.451265E+00 -3.978527E+00 -3.354318E-02 -2.282172E-04 -8.316070E-02 -1.402736E-03 -2.662704E+00 -1.448336E+00 -7.530385E-02 -1.164529E-03 -3.880423E+00 -3.054138E+00 -3.144058E-02 -2.085301E-04 -7.794791E-02 -1.281730E-03 -2.130205E+00 -9.297660E-01 -6.583066E-02 -8.790174E-04 -3.226341E+00 -2.120506E+00 -2.889944E-02 -1.698754E-04 -7.164788E-02 -1.044139E-03 +2.433621E+00 +1.298731E+00 +7.126855E-02 +1.084489E-03 +3.556720E+00 +2.723689E+00 +3.032075E-02 +1.974495E-04 +7.517159E-02 +1.213623E-03 +2.717435E+00 +1.549804E+00 +7.064960E-02 +1.006179E-03 +3.808148E+00 +2.988456E+00 +2.796674E-02 +1.570090E-04 +6.933552E-02 +9.650556E-04 +2.679858E+00 +1.486542E+00 +8.030738E-02 +1.319629E-03 +4.018748E+00 +3.302325E+00 +3.467552E-02 +2.467113E-04 +8.596801E-02 +1.516410E-03 +2.404649E+00 +1.193262E+00 +6.941086E-02 +9.897421E-04 +3.496702E+00 +2.518136E+00 +2.928903E-02 +1.763988E-04 +7.261375E-02 +1.084234E-03 +2.147183E+00 +9.523277E-01 +6.709152E-02 +9.314107E-04 +3.232389E+00 +2.147105E+00 +2.954891E-02 +1.829794E-04 +7.325805E-02 +1.124682E-03 +2.636339E+00 +1.437307E+00 +7.792975E-02 +1.238873E-03 +3.915670E+00 +3.133618E+00 +3.338754E-02 +2.290709E-04 +8.277483E-02 +1.407984E-03 +2.771906E+00 +1.608332E+00 +8.667994E-02 +1.535886E-03 +4.183761E+00 +3.623671E+00 +3.819000E-02 +2.976177E-04 +9.468114E-02 +1.829306E-03 +2.269663E+00 +1.042807E+00 +7.391262E-02 +1.128121E-03 +3.476219E+00 +2.457866E+00 +3.321742E-02 +2.316107E-04 +8.235305E-02 +1.423595E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -681,86 +681,86 @@ tally 1: 0.000000E+00 0.000000E+00 0.000000E+00 -2.599461E+00 -1.458035E+00 -7.809884E-02 -1.305214E-03 -3.901359E+00 -3.258238E+00 -3.379142E-02 -2.432493E-04 -8.377612E-02 -1.495131E-03 -2.748044E+00 -1.595569E+00 -8.641555E-02 -1.591494E-03 -4.133038E+00 -3.610482E+00 -3.815976E-02 -3.125423E-04 -9.460617E-02 -1.921040E-03 -2.827693E+00 -1.681951E+00 -9.214026E-02 -1.815952E-03 -4.343252E+00 -3.980138E+00 -4.139309E-02 -3.763771E-04 -1.026223E-01 -2.313401E-03 -2.848302E+00 -1.709266E+00 -8.618471E-02 -1.555247E-03 -4.293029E+00 -3.893924E+00 -3.742129E-02 -2.947160E-04 -9.277535E-02 -1.811471E-03 -3.107129E+00 -1.985180E+00 -9.390982E-02 -1.778566E-03 -4.705512E+00 -4.502266E+00 -4.077729E-02 -3.361217E-04 -1.010956E-01 -2.065971E-03 -3.176743E+00 -2.076916E+00 -9.535836E-02 -1.843238E-03 -4.782883E+00 -4.655802E+00 -4.125628E-02 -3.453802E-04 -1.022831E-01 -2.122878E-03 -3.158364E+00 -2.020031E+00 -9.047734E-02 -1.652565E-03 -4.641857E+00 -4.326900E+00 -3.809128E-02 -2.983406E-04 -9.443638E-02 -1.833749E-03 -2.750064E+00 -1.515295E+00 -7.550745E-02 -1.157933E-03 -4.022702E+00 -3.249004E+00 -3.106532E-02 -2.005988E-04 -7.701755E-02 -1.232980E-03 +2.364354E+00 +1.160200E+00 +6.641096E-02 +8.852085E-04 +3.392824E+00 +2.329004E+00 +2.757158E-02 +1.580033E-04 +6.835582E-02 +9.711667E-04 +2.524962E+00 +1.341947E+00 +7.077935E-02 +1.024802E-03 +3.665788E+00 +2.770692E+00 +2.942129E-02 +1.757498E-04 +7.294165E-02 +1.080245E-03 +2.400937E+00 +1.186871E+00 +6.912946E-02 +9.715758E-04 +3.511555E+00 +2.501540E+00 +2.915335E-02 +1.747298E-04 +7.227736E-02 +1.073976E-03 +2.114087E+00 +8.990260E-01 +7.043720E-02 +1.000660E-03 +3.333143E+00 +2.235823E+00 +3.206435E-02 +2.087641E-04 +7.949434E-02 +1.283168E-03 +2.130919E+00 +9.474100E-01 +7.007826E-02 +9.974302E-04 +3.308019E+00 +2.242723E+00 +3.167506E-02 +2.044420E-04 +7.852922E-02 +1.256602E-03 +2.315558E+00 +1.159276E+00 +6.983615E-02 +1.023301E-03 +3.433129E+00 +2.511229E+00 +3.018652E-02 +1.890787E-04 +7.483880E-02 +1.162171E-03 +2.729503E+00 +1.530826E+00 +8.250917E-02 +1.373688E-03 +4.093393E+00 +3.424963E+00 +3.577102E-02 +2.569031E-04 +8.868397E-02 +1.579054E-03 +2.303613E+00 +1.077186E+00 +6.880069E-02 +9.471902E-04 +3.366481E+00 +2.277404E+00 +2.953353E-02 +1.751404E-04 +7.321992E-02 +1.076500E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -851,86 +851,86 @@ tally 1: 0.000000E+00 0.000000E+00 0.000000E+00 -2.571690E+00 -1.405222E+00 -6.998368E-02 -1.010782E-03 -3.645470E+00 -2.775516E+00 -2.848750E-02 -1.694087E-04 -7.062657E-02 -1.041270E-03 -3.305320E+00 -2.344814E+00 -9.985328E-02 -2.111130E-03 -4.992554E+00 -5.332303E+00 -4.332586E-02 -3.970490E-04 -1.074140E-01 -2.440461E-03 -2.746305E+00 -1.652960E+00 -9.402849E-02 -1.982149E-03 -4.315533E+00 -4.099428E+00 -4.322622E-02 -4.235148E-04 -1.071670E-01 -2.603132E-03 -2.975372E+00 -1.824531E+00 -9.627993E-02 -1.863677E-03 -4.624041E+00 -4.351874E+00 -4.324350E-02 -3.743520E-04 -1.072099E-01 -2.300953E-03 -2.968077E+00 -1.807761E+00 -9.337061E-02 -1.790184E-03 -4.455263E+00 -4.056544E+00 -4.122926E-02 -3.540009E-04 -1.022161E-01 -2.175865E-03 -3.337278E+00 -2.233238E+00 -1.017763E-01 -2.083989E-03 -4.981699E+00 -4.981154E+00 -4.428100E-02 -3.964318E-04 -1.097820E-01 -2.436667E-03 -3.083638E+00 -1.958766E+00 -9.111141E-02 -1.726305E-03 -4.546082E+00 -4.260420E+00 -3.895365E-02 -3.200133E-04 -9.657439E-02 -1.966961E-03 -2.644733E+00 -1.407404E+00 -8.635553E-02 -1.527997E-03 -4.094426E+00 -3.382785E+00 -3.888081E-02 -3.161126E-04 -9.639381E-02 -1.942985E-03 +2.603449E+00 +1.382310E+00 +7.044110E-02 +1.048854E-03 +3.683939E+00 +2.770822E+00 +2.858207E-02 +1.846566E-04 +7.086104E-02 +1.134991E-03 +2.458052E+00 +1.211571E+00 +7.271340E-02 +1.061659E-03 +3.628656E+00 +2.636961E+00 +3.113049E-02 +1.956492E-04 +7.717911E-02 +1.202557E-03 +2.200265E+00 +9.745445E-01 +7.058665E-02 +1.016272E-03 +3.372745E+00 +2.298238E+00 +3.151097E-02 +2.069373E-04 +7.812240E-02 +1.271940E-03 +2.154223E+00 +9.469347E-01 +6.893166E-02 +1.008453E-03 +3.298063E+00 +2.220933E+00 +3.075978E-02 +2.125545E-04 +7.626005E-02 +1.306466E-03 +2.057172E+00 +8.672290E-01 +6.372568E-02 +8.190278E-04 +3.108552E+00 +1.951197E+00 +2.795535E-02 +1.595890E-04 +6.930727E-02 +9.809131E-04 +2.295642E+00 +1.124640E+00 +6.209725E-02 +8.275041E-04 +3.320499E+00 +2.339919E+00 +2.530846E-02 +1.388437E-04 +6.274506E-02 +8.534023E-04 +2.411516E+00 +1.208668E+00 +7.127755E-02 +1.051206E-03 +3.599456E+00 +2.675604E+00 +3.057946E-02 +1.929511E-04 +7.581300E-02 +1.185973E-03 +2.170599E+00 +9.911770E-01 +6.225331E-02 +8.096954E-04 +3.174400E+00 +2.102442E+00 +2.621745E-02 +1.490631E-04 +6.499865E-02 +9.162161E-04 0.000000E+00 0.000000E+00 0.000000E+00 @@ -1021,86 +1021,86 @@ tally 1: 0.000000E+00 0.000000E+00 0.000000E+00 -3.316522E+00 -2.302876E+00 -8.987919E-02 -1.676655E-03 -4.716109E+00 -4.596488E+00 -3.654407E-02 -2.855910E-04 -9.060053E-02 -1.755384E-03 -3.091331E+00 -2.117646E+00 -8.528196E-02 -1.564336E-03 -4.492326E+00 -4.405850E+00 -3.513814E-02 -2.665883E-04 -8.711494E-02 -1.638584E-03 -2.649730E+00 -1.444519E+00 -8.510948E-02 -1.506094E-03 -4.117595E+00 -3.501517E+00 -3.810553E-02 -3.052819E-04 -9.447172E-02 -1.876414E-03 -2.875773E+00 -1.758531E+00 -9.127582E-02 -1.780419E-03 -4.328266E+00 -3.989840E+00 -4.045386E-02 -3.513542E-04 -1.002937E-01 -2.159598E-03 -3.102792E+00 -1.949906E+00 -9.153879E-02 -1.691646E-03 -4.578530E+00 -4.235906E+00 -3.913672E-02 -3.094156E-04 -9.702826E-02 -1.901822E-03 -3.238743E+00 -2.146355E+00 -8.902551E-02 -1.593536E-03 -4.683916E+00 -4.438028E+00 -3.660342E-02 -2.683183E-04 -9.074766E-02 -1.649218E-03 -3.006635E+00 -1.887385E+00 -8.716712E-02 -1.586834E-03 -4.383965E+00 -4.008888E+00 -3.688262E-02 -2.862513E-04 -9.143987E-02 -1.759443E-03 -2.749904E+00 -1.550561E+00 -9.244273E-02 -1.748082E-03 -4.241273E+00 -3.669144E+00 -4.208622E-02 -3.633241E-04 -1.043407E-01 -2.233170E-03 +2.374348E+00 +1.146696E+00 +6.443426E-02 +8.746572E-04 +3.428224E+00 +2.405912E+00 +2.629872E-02 +1.523681E-04 +6.520012E-02 +9.365302E-04 +2.464893E+00 +1.229701E+00 +7.050588E-02 +1.022217E-03 +3.660115E+00 +2.719644E+00 +2.971255E-02 +1.859463E-04 +7.366374E-02 +1.142918E-03 +2.086598E+00 +8.776819E-01 +6.304625E-02 +8.239181E-04 +3.124875E+00 +1.968039E+00 +2.731211E-02 +1.609716E-04 +6.771252E-02 +9.894116E-04 +2.314873E+00 +1.083111E+00 +5.761556E-02 +6.762901E-04 +3.205662E+00 +2.074555E+00 +2.215216E-02 +1.044406E-04 +5.491992E-02 +6.419437E-04 +2.313273E+00 +1.119912E+00 +6.126598E-02 +7.845228E-04 +3.266340E+00 +2.226545E+00 +2.455456E-02 +1.271226E-04 +6.087598E-02 +7.813588E-04 +2.283282E+00 +1.100474E+00 +6.665553E-02 +9.193170E-04 +3.364565E+00 +2.364829E+00 +2.834631E-02 +1.672037E-04 +7.027653E-02 +1.027717E-03 +2.186072E+00 +9.712029E-01 +7.000241E-02 +1.019717E-03 +3.374290E+00 +2.313941E+00 +3.125803E-02 +2.124583E-04 +7.749531E-02 +1.305874E-03 +2.250156E+00 +1.052173E+00 +6.400255E-02 +8.818690E-04 +3.268015E+00 +2.245559E+00 +2.679559E-02 +1.634377E-04 +6.643197E-02 +1.004569E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -1191,86 +1191,86 @@ tally 1: 0.000000E+00 0.000000E+00 0.000000E+00 -2.556952E+00 -1.416458E+00 -8.087467E-02 -1.431667E-03 -3.806748E+00 -3.158182E+00 -3.571995E-02 -2.831832E-04 -8.855737E-02 -1.740585E-03 -2.546384E+00 -1.446967E+00 -8.000281E-02 -1.363415E-03 -3.844739E+00 -3.222133E+00 -3.533522E-02 -2.621956E-04 -8.760354E-02 -1.611584E-03 -2.474418E+00 -1.302438E+00 -7.728372E-02 -1.265047E-03 -3.818517E+00 -3.076074E+00 -3.414744E-02 -2.483215E-04 -8.465877E-02 -1.526307E-03 -2.478272E+00 -1.299434E+00 -7.866430E-02 -1.293627E-03 -3.758685E+00 -2.973817E+00 -3.491240E-02 -2.542033E-04 -8.655529E-02 -1.562460E-03 -2.941937E+00 -1.842278E+00 -9.491310E-02 -1.902183E-03 -4.564730E+00 -4.427111E+00 -4.252722E-02 -3.828960E-04 -1.054340E-01 -2.353469E-03 -2.850564E+00 -1.719152E+00 -8.118192E-02 -1.404765E-03 -4.190858E+00 -3.722715E+00 -3.411695E-02 -2.522778E-04 -8.458318E-02 -1.550625E-03 -2.726097E+00 -1.648250E+00 -7.879124E-02 -1.424955E-03 -3.940978E+00 -3.461222E+00 -3.322044E-02 -2.688615E-04 -8.236053E-02 -1.652557E-03 -2.304822E+00 -1.153775E+00 -7.500010E-02 -1.314077E-03 -3.542935E+00 -2.786864E+00 -3.369367E-02 -2.798215E-04 -8.353377E-02 -1.719922E-03 +2.149693E+00 +9.566763E-01 +6.325375E-02 +8.781459E-04 +3.163781E+00 +2.089993E+00 +2.699802E-02 +1.754950E-04 +6.693384E-02 +1.078679E-03 +2.368262E+00 +1.206255E+00 +6.517665E-02 +9.363557E-04 +3.403305E+00 +2.501730E+00 +2.677251E-02 +1.620249E-04 +6.637476E-02 +9.958857E-04 +2.280249E+00 +1.070455E+00 +7.456831E-02 +1.147671E-03 +3.475673E+00 +2.476848E+00 +3.352210E-02 +2.345869E-04 +8.310842E-02 +1.441888E-03 +2.226928E+00 +1.011037E+00 +7.770236E-02 +1.243393E-03 +3.524398E+00 +2.538453E+00 +3.601410E-02 +2.702997E-04 +8.928663E-02 +1.661396E-03 +2.407411E+00 +1.170093E+00 +7.171133E-02 +1.029235E-03 +3.502484E+00 +2.461827E+00 +3.070568E-02 +1.889715E-04 +7.612591E-02 +1.161513E-03 +2.331359E+00 +1.134448E+00 +6.734317E-02 +9.407363E-04 +3.333577E+00 +2.267345E+00 +2.832929E-02 +1.772720E-04 +7.023433E-02 +1.089602E-03 +2.008838E+00 +8.722179E-01 +5.586199E-02 +7.051708E-04 +2.903675E+00 +1.807255E+00 +2.309145E-02 +1.322637E-04 +5.724863E-02 +8.129585E-04 +2.226061E+00 +1.048269E+00 +6.536859E-02 +9.623671E-04 +3.297988E+00 +2.324450E+00 +2.791406E-02 +1.866630E-04 +6.920490E-02 +1.147324E-03 0.000000E+00 0.000000E+00 0.000000E+00 @@ -2892,15 +2892,15 @@ tally 1: 0.000000E+00 0.000000E+00 tally 2: -4.283244E+01 -3.698890E+02 -4.285612E+01 -3.702981E+02 -6.926001E+00 -9.669342E+00 -6.926497E+00 -9.670727E+00 -1.223563E+02 -3.025594E+03 -1.223563E+02 -3.025594E+03 +4.076711E+01 +3.341374E+02 +4.077838E+01 +3.343221E+02 +6.274781E+00 +7.937573E+00 +6.275007E+00 +7.938146E+00 +1.122968E+02 +2.557771E+03 +1.122968E+02 +2.557771E+03 diff --git a/tests/test_mg_tallies/test_mg_tallies.py b/tests/test_mg_tallies/test_mg_tallies.py index c54fb4d32..3048f4a39 100644 --- a/tests/test_mg_tallies/test_mg_tallies.py +++ b/tests/test_mg_tallies/test_mg_tallies.py @@ -27,24 +27,15 @@ class MGTalliesTestHarness(PyAPITestHarness): mat_filter = openmc.Filter(type='material', bins=[1,2,3]) tally1 = openmc.Tally(tally_id=1) - tally1.add_filter(mesh_filter) - tally1.add_score('total') - tally1.add_score('absorption') - tally1.add_score('flux') - tally1.add_score('fission') - tally1.add_score('nu-fission') + tally1.filters = [mesh_filter] + tally1.scores = ['total', 'absorption', 'flux', + 'fission', 'nu-fission'] tally2 = openmc.Tally(tally_id=2) - tally2.add_filter(mat_filter) - tally2.add_filter(energy_filter) - tally2.add_filter(energyout_filter) - tally2.add_score('scatter') - tally2.add_score('nu-scatter') + tally2.filters = [mat_filter, energy_filter, energyout_filter] + tally2.scores = ['scatter', 'nu-scatter'] - self._input_set.tallies = openmc.TalliesFile() - self._input_set.tallies.add_mesh(mesh) - self._input_set.tallies.add_tally(tally1) - self._input_set.tallies.add_tally(tally2) + self._input_set.tallies = openmc.Tallies([tally1, tally2]) super(MGTalliesTestHarness, self)._build_inputs() diff --git a/tests/test_mgxs_library_condense/inputs_true.dat b/tests/test_mgxs_library_condense/inputs_true.dat index b94f64122..3643c9a2e 100644 --- a/tests/test_mgxs_library_condense/inputs_true.dat +++ b/tests/test_mgxs_library_condense/inputs_true.dat @@ -1 +1 @@ -53b1740921b71e4ead909ab9e4c25f7d43990fe7d7051fde6f66c39c0a6082177385640244010e1b9dbeaf5f34adf1627e9603088af729fadd6b589c19102edc \ No newline at end of file +104e7fb527770ac5d3fc636da7716e8fb05d55761253d30516c899f466e6b38ffd881611a3d0cdf65c6af058c32f6f6758c68782be7a170d21024bdae751862f \ No newline at end of file diff --git a/tests/test_mgxs_library_condense/results_true.dat b/tests/test_mgxs_library_condense/results_true.dat index 438215372..184be68bf 100644 --- a/tests/test_mgxs_library_condense/results_true.dat +++ b/tests/test_mgxs_library_condense/results_true.dat @@ -1,49 +1,85 @@ material group in nuclide mean std. dev. 0 1 1 total 0.412084 0.02359 material group in nuclide mean std. dev. -0 1 1 total 0.076425 0.003691 material group in group out nuclide mean std. dev. -0 1 1 1 total 0.345643 0.021487 material group out nuclide mean std. dev. +0 1 1 total 0.076425 0.003691 material group in group out nuclide moment mean std. dev. +0 1 1 1 total P0 0.384780 0.022253 +1 1 1 1 total P1 0.039277 0.004308 +2 1 1 1 total P2 0.017574 0.002402 +3 1 1 1 total P3 0.012203 0.002164 material group out nuclide mean std. dev. 0 1 1 total 1.0 0.055333 material group in nuclide mean std. dev. 0 2 1 total 0.241262 0.00841 material group in nuclide mean std. dev. -0 2 1 total 0.0 0.0 material group in group out nuclide mean std. dev. -0 2 1 1 total 0.241262 0.00841 material group out nuclide mean std. dev. +0 2 1 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +0 2 1 1 total P0 0.272369 0.006872 +1 2 1 1 total P1 0.031107 0.005483 +2 2 1 1 total P2 0.025999 0.006151 +3 2 1 1 total P3 0.003219 0.003312 material group out nuclide mean std. dev. 0 2 1 total 0.0 0.0 material group in nuclide mean std. dev. 0 3 1 total 0.400028 0.034667 material group in nuclide mean std. dev. -0 3 1 total 0.0 0.0 material group in group out nuclide mean std. dev. -0 3 1 1 total 0.393462 0.033646 material group out nuclide mean std. dev. +0 3 1 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +0 3 1 1 total P0 0.794999 0.036548 +1 3 1 1 total P1 0.401537 0.016175 +2 3 1 1 total P2 0.143623 0.008719 +3 3 1 1 total P3 0.001991 0.004433 material group out nuclide mean std. dev. 0 3 1 total 0.0 0.0 material group in nuclide mean std. dev. 0 4 1 total 0.377402 0.072937 material group in nuclide mean std. dev. -0 4 1 total 0.0 0.0 material group in group out nuclide mean std. dev. -0 4 1 1 total 0.371473 0.071226 material group out nuclide mean std. dev. +0 4 1 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +0 4 1 1 total P0 0.727311 0.080096 +1 4 1 1 total P1 0.355839 0.037901 +2 4 1 1 total P2 0.124483 0.015823 +3 4 1 1 total P3 0.012168 0.006224 material group out nuclide mean std. dev. 0 4 1 total 0.0 0.0 material group in nuclide mean std. dev. 0 5 1 total 0.0 0.0 material group in nuclide mean std. dev. -0 5 1 total 0.0 0.0 material group in group out nuclide mean std. dev. -0 5 1 1 total 0.0 0.0 material group out nuclide mean std. dev. +0 5 1 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +0 5 1 1 total P0 0.0 0.0 +1 5 1 1 total P1 0.0 0.0 +2 5 1 1 total P2 0.0 0.0 +3 5 1 1 total P3 0.0 0.0 material group out nuclide mean std. dev. 0 5 1 total 0.0 0.0 material group in nuclide mean std. dev. 0 6 1 total 0.0 0.0 material group in nuclide mean std. dev. -0 6 1 total 0.0 0.0 material group in group out nuclide mean std. dev. -0 6 1 1 total 0.0 0.0 material group out nuclide mean std. dev. +0 6 1 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +0 6 1 1 total P0 0.0 0.0 +1 6 1 1 total P1 0.0 0.0 +2 6 1 1 total P2 0.0 0.0 +3 6 1 1 total P3 0.0 0.0 material group out nuclide mean std. dev. 0 6 1 total 0.0 0.0 material group in nuclide mean std. dev. 0 7 1 total 0.0 0.0 material group in nuclide mean std. dev. -0 7 1 total 0.0 0.0 material group in group out nuclide mean std. dev. -0 7 1 1 total 0.0 0.0 material group out nuclide mean std. dev. +0 7 1 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +0 7 1 1 total P0 0.0 0.0 +1 7 1 1 total P1 0.0 0.0 +2 7 1 1 total P2 0.0 0.0 +3 7 1 1 total P3 0.0 0.0 material group out nuclide mean std. dev. 0 7 1 total 0.0 0.0 material group in nuclide mean std. dev. 0 8 1 total 0.0 0.0 material group in nuclide mean std. dev. -0 8 1 total 0.0 0.0 material group in group out nuclide mean std. dev. -0 8 1 1 total 0.0 0.0 material group out nuclide mean std. dev. +0 8 1 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +0 8 1 1 total P0 0.0 0.0 +1 8 1 1 total P1 0.0 0.0 +2 8 1 1 total P2 0.0 0.0 +3 8 1 1 total P3 0.0 0.0 material group out nuclide mean std. dev. 0 8 1 total 0.0 0.0 material group in nuclide mean std. dev. 0 9 1 total 0.600536 0.748875 material group in nuclide mean std. dev. -0 9 1 total 0.0 0.0 material group in group out nuclide mean std. dev. -0 9 1 1 total 0.600536 0.748875 material group out nuclide mean std. dev. +0 9 1 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +0 9 1 1 total P0 0.720380 0.771015 +1 9 1 1 total P1 0.119844 0.184691 +2 9 1 1 total P2 0.038522 0.064485 +3 9 1 1 total P3 0.056023 0.050595 material group out nuclide mean std. dev. 0 9 1 total 0.0 0.0 material group in nuclide mean std. dev. 0 10 1 total 0.235515 0.613974 material group in nuclide mean std. dev. -0 10 1 total 0.0 0.0 material group in group out nuclide mean std. dev. -0 10 1 1 total 0.235515 0.613974 material group out nuclide mean std. dev. +0 10 1 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +0 10 1 1 total P0 0.501009 0.708534 +1 10 1 1 total P1 0.265494 0.375465 +2 10 1 1 total P2 0.141979 0.200788 +3 10 1 1 total P3 0.074258 0.105017 material group out nuclide mean std. dev. 0 10 1 total 0.0 0.0 material group in nuclide mean std. dev. 0 11 1 total 0.510145 0.741941 material group in nuclide mean std. dev. -0 11 1 total 0.0 0.0 material group in group out nuclide mean std. dev. -0 11 1 1 total 0.491857 0.715554 material group out nuclide mean std. dev. +0 11 1 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +0 11 1 1 total P0 0.804661 0.817658 +1 11 1 1 total P1 0.312803 0.315315 +2 11 1 1 total P2 0.168113 0.172935 +3 11 1 1 total P3 0.003808 0.037911 material group out nuclide mean std. dev. 0 11 1 total 0.0 0.0 material group in nuclide mean std. dev. 0 12 1 total 0.73836 0.825631 material group in nuclide mean std. dev. -0 12 1 total 0.0 0.0 material group in group out nuclide mean std. dev. -0 12 1 1 total 0.723265 0.808231 material group out nuclide mean std. dev. +0 12 1 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +0 12 1 1 total P0 0.943429 0.856119 +1 12 1 1 total P1 0.220164 0.163180 +2 12 1 1 total P2 0.052884 0.042440 +3 12 1 1 total P3 0.039939 0.032867 material group out nuclide mean std. dev. 0 12 1 total 0.0 0.0 \ No newline at end of file diff --git a/tests/test_mgxs_library_condense/test_mgxs_library_condense.py b/tests/test_mgxs_library_condense/test_mgxs_library_condense.py index 82ce3acab..561232b22 100644 --- a/tests/test_mgxs_library_condense/test_mgxs_library_condense.py +++ b/tests/test_mgxs_library_condense/test_mgxs_library_condense.py @@ -23,16 +23,17 @@ class MGXSTestHarness(PyAPITestHarness): energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 0.625e-6, 20.]) # Initialize MGXS Library for a few cross section types - self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry.geometry) + self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry) self.mgxs_lib.by_nuclide = False self.mgxs_lib.mgxs_types = ['transport', 'nu-fission', 'nu-scatter matrix', 'chi'] self.mgxs_lib.energy_groups = energy_groups + self.mgxs_lib.legendre_order = 3 self.mgxs_lib.domain_type = 'material' self.mgxs_lib.build_library() # Initialize a tallies file - self._input_set.tallies = openmc.TalliesFile() + self._input_set.tallies = openmc.Tallies() self.mgxs_lib.add_to_tallies_file(self._input_set.tallies, merge=False) self._input_set.tallies.export_to_xml() @@ -43,11 +44,6 @@ class MGXSTestHarness(PyAPITestHarness): statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] sp = openmc.StatePoint(statepoint) - # Read the summary file. - summary = glob.glob(os.path.join(os.getcwd(), 'summary.h5'))[0] - su = openmc.Summary(summary) - sp.link_with_summary(su) - # Load the MGXS library from the statepoint self.mgxs_lib.load_from_statepoint(sp) diff --git a/tests/test_mgxs_library_distribcell/inputs_true.dat b/tests/test_mgxs_library_distribcell/inputs_true.dat index 04e56658f..21927c800 100644 --- a/tests/test_mgxs_library_distribcell/inputs_true.dat +++ b/tests/test_mgxs_library_distribcell/inputs_true.dat @@ -1 +1 @@ -224a9e84e87c8a21385326d34ef27c046107d4a2ace6ee85d7a36142a3726e12532e2fc1a318ab707437e0b306a81c6d2b80c531d4c3210d4162242e6265ba70 \ No newline at end of file +018bbbc2099f7b94180b391e46e42fc9a82498c60b3f8f7f4c91480ea373427932d287fe571d53b2397f329e71485e7155d7644f0f995bbcb458ba3e872ab043 \ No newline at end of file diff --git a/tests/test_mgxs_library_distribcell/results_true.dat b/tests/test_mgxs_library_distribcell/results_true.dat index 0d5c7c7b4..fa55249d1 100644 --- a/tests/test_mgxs_library_distribcell/results_true.dat +++ b/tests/test_mgxs_library_distribcell/results_true.dat @@ -1,5 +1,8 @@ avg(distribcell) group in nuclide mean std. dev. 0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 0.718919 0.520644 avg(distribcell) group in nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 0.0 0.0 avg(distribcell) group in group out nuclide mean std. dev. -0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total 0.695166 0.510606 avg(distribcell) group out nuclide mean std. dev. +0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 0.0 0.0 avg(distribcell) group in group out nuclide moment mean std. dev. +0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total P0 1.142547 0.570131 +1 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total P1 0.447381 0.216322 +2 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total P2 0.141202 0.066504 +3 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 1 total P3 0.039228 0.024621 avg(distribcell) group out nuclide mean std. dev. 0 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... 1 total 0.0 0.0 \ No newline at end of file diff --git a/tests/test_mgxs_library_distribcell/test_mgxs_library_distribcell.py b/tests/test_mgxs_library_distribcell/test_mgxs_library_distribcell.py index 1de21a603..32f5ea1bd 100644 --- a/tests/test_mgxs_library_distribcell/test_mgxs_library_distribcell.py +++ b/tests/test_mgxs_library_distribcell/test_mgxs_library_distribcell.py @@ -24,18 +24,19 @@ class MGXSTestHarness(PyAPITestHarness): # Initialize MGXS Library for a few cross section types # for one material-filled cell in the geometry - self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry.geometry) + self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry) self.mgxs_lib.by_nuclide = False self.mgxs_lib.mgxs_types = ['transport', 'nu-fission', 'nu-scatter matrix', 'chi'] self.mgxs_lib.energy_groups = energy_groups + self.mgxs_lib.legendre_order = 3 self.mgxs_lib.domain_type = 'distribcell' material_cells = self.mgxs_lib.openmc_geometry.get_all_material_cells() self.mgxs_lib.domains = [material_cells[-1]] self.mgxs_lib.build_library() # Initialize a tallies file - self._input_set.tallies = openmc.TalliesFile() + self._input_set.tallies = openmc.Tallies() self.mgxs_lib.add_to_tallies_file(self._input_set.tallies, merge=False) self._input_set.tallies.export_to_xml() @@ -46,11 +47,6 @@ class MGXSTestHarness(PyAPITestHarness): statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] sp = openmc.StatePoint(statepoint) - # Read the summary file. - summary = glob.glob(os.path.join(os.getcwd(), 'summary.h5'))[0] - su = openmc.Summary(summary) - sp.link_with_summary(su) - # Load the MGXS library from the statepoint self.mgxs_lib.load_from_statepoint(sp) diff --git a/tests/test_mgxs_library_hdf5/inputs_true.dat b/tests/test_mgxs_library_hdf5/inputs_true.dat index b94f64122..3643c9a2e 100644 --- a/tests/test_mgxs_library_hdf5/inputs_true.dat +++ b/tests/test_mgxs_library_hdf5/inputs_true.dat @@ -1 +1 @@ -53b1740921b71e4ead909ab9e4c25f7d43990fe7d7051fde6f66c39c0a6082177385640244010e1b9dbeaf5f34adf1627e9603088af729fadd6b589c19102edc \ No newline at end of file +104e7fb527770ac5d3fc636da7716e8fb05d55761253d30516c899f466e6b38ffd881611a3d0cdf65c6af058c32f6f6758c68782be7a170d21024bdae751862f \ No newline at end of file diff --git a/tests/test_mgxs_library_hdf5/results_true.dat b/tests/test_mgxs_library_hdf5/results_true.dat index e19b9ffa5..3cae57747 100644 --- a/tests/test_mgxs_library_hdf5/results_true.dat +++ b/tests/test_mgxs_library_hdf5/results_true.dat @@ -5,10 +5,16 @@ domain=1 type=nu-fission [ 0.02178897 0.71407658] [ 0.00118187 0.04055185] domain=1 type=nu-scatter matrix -[[ 0.3373971 0.00155945] - [ 0. 0.42205129]] -[[ 0.02303884 0.00051015] - [ 0. 0.02161702]] +[[[ 3.81546297e-01 4.43012537e-02 2.06462886e-02 1.36952959e-02] + [ 1.55945353e-03 -5.97269486e-04 -2.38789528e-04 1.75508083e-04]] + + [[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] + [ 4.03915981e-01 -1.13103276e-02 -1.48065932e-02 -6.85505346e-03]]] +[[[ 0.02403322 0.00472203 0.00253903 0.00222437] + [ 0.00051015 0.00022485 0.00022157 0.00020939]] + + [[ 0. 0. 0. 0. ] + [ 0.01896646 0.00783919 0.00862908 0.00904704]]] domain=1 type=chi [ 1. 0.] [ 0.05533329 0. ] @@ -19,10 +25,16 @@ domain=2 type=nu-fission [ 0. 0.] [ 0. 0.] domain=2 type=nu-scatter matrix -[[ 0.23725441 0. ] - [ 0. 0.28593027]] -[[ 0.00818357 0. ] - [ 0. 0.04879593]] +[[[ 0.27311543 0.03586102 0.02970389 0.00224892] + [ 0. 0. 0. 0. ]] + + [[ 0. 0. 0. 0. ] + [ 0.26405068 -0.02187959 -0.01529469 0.01403395]]] +[[[ 0.00625287 0.00587756 0.00664018 0.00337568] + [ 0. 0. 0. 0. ]] + + [[ 0. 0. 0. 0. ] + [ 0.04539742 0.01221814 0.01027609 0.01431818]]] domain=2 type=chi [ 0. 0.] [ 0. 0.] @@ -33,10 +45,16 @@ domain=3 type=nu-fission [ 0. 0.] [ 0. 0.] domain=3 type=nu-scatter matrix -[[ 0.25993686 0.02618721] - [ 0. 1.35952132]] -[[ 0.02611466 0.00166461] - [ 0. 0.2585046 ]] +[[[ 0.64334557 0.38340871 0.15218526 0.00303724] + [ 0.02618721 0.00736219 -0.00273849 -0.00271989]] + + [[ 0. 0. 0. 0. ] + [ 1.92421362 0.4984312 0.09120485 0.01705441]]] +[[[ 0.02837604 0.01644677 0.00957372 0.00464802] + [ 0.00166461 0.00093414 0.00075617 0.00055807]] + + [[ 0. 0. 0. 0. ] + [ 0.28406198 0.06342067 0.01372628 0.01391602]]] domain=3 type=chi [ 0. 0.] [ 0. 0.] @@ -47,10 +65,16 @@ domain=4 type=nu-fission [ 0. 0.] [ 0. 0.] domain=4 type=nu-scatter matrix -[[ 0.2179296 0.023662 ] - [ 0. 1.21507398]] -[[ 0.0585649 0.00308328] - [ 0. 0.3810251 ]] +[[[ 0.54394096 0.32601136 0.13113269 0.01210477] + [ 0.023662 0.00752551 -0.00272975 -0.0031405 ]] + + [[ 0. 0. 0. 0. ] + [ 1.76464845 0.50069481 0.09902596 0.03297543]]] +[[[ 0.06542705 0.03860196 0.0174751 0.00607268] + [ 0.00308328 0.00130111 0.00084112 0.00057761]] + + [[ 0. 0. 0. 0. ] + [ 0.41620952 0.12217802 0.03871874 0.02510259]]] domain=4 type=chi [ 0. 0.] [ 0. 0.] @@ -61,10 +85,16 @@ domain=5 type=nu-fission [ 0. 0.] [ 0. 0.] domain=5 type=nu-scatter matrix -[[ 0. 0.] - [ 0. 0.]] -[[ 0. 0.] - [ 0. 0.]] +[[[ 0. 0. 0. 0.] + [ 0. 0. 0. 0.]] + + [[ 0. 0. 0. 0.] + [ 0. 0. 0. 0.]]] +[[[ 0. 0. 0. 0.] + [ 0. 0. 0. 0.]] + + [[ 0. 0. 0. 0.] + [ 0. 0. 0. 0.]]] domain=5 type=chi [ 0. 0.] [ 0. 0.] @@ -75,10 +105,16 @@ domain=6 type=nu-fission [ 0. 0.] [ 0. 0.] domain=6 type=nu-scatter matrix -[[ 0. 0.] - [ 0. 0.]] -[[ 0. 0.] - [ 0. 0.]] +[[[ 0. 0. 0. 0.] + [ 0. 0. 0. 0.]] + + [[ 0. 0. 0. 0.] + [ 0. 0. 0. 0.]]] +[[[ 0. 0. 0. 0.] + [ 0. 0. 0. 0.]] + + [[ 0. 0. 0. 0.] + [ 0. 0. 0. 0.]]] domain=6 type=chi [ 0. 0.] [ 0. 0.] @@ -89,10 +125,16 @@ domain=7 type=nu-fission [ 0. 0.] [ 0. 0.] domain=7 type=nu-scatter matrix -[[ 0. 0.] - [ 0. 0.]] -[[ 0. 0.] - [ 0. 0.]] +[[[ 0. 0. 0. 0.] + [ 0. 0. 0. 0.]] + + [[ 0. 0. 0. 0.] + [ 0. 0. 0. 0.]]] +[[[ 0. 0. 0. 0.] + [ 0. 0. 0. 0.]] + + [[ 0. 0. 0. 0.] + [ 0. 0. 0. 0.]]] domain=7 type=chi [ 0. 0.] [ 0. 0.] @@ -103,10 +145,16 @@ domain=8 type=nu-fission [ 0. 0.] [ 0. 0.] domain=8 type=nu-scatter matrix -[[ 0. 0.] - [ 0. 0.]] -[[ 0. 0.] - [ 0. 0.]] +[[[ 0. 0. 0. 0.] + [ 0. 0. 0. 0.]] + + [[ 0. 0. 0. 0.] + [ 0. 0. 0. 0.]]] +[[[ 0. 0. 0. 0.] + [ 0. 0. 0. 0.]] + + [[ 0. 0. 0. 0.] + [ 0. 0. 0. 0.]]] domain=8 type=chi [ 0. 0.] [ 0. 0.] @@ -117,10 +165,16 @@ domain=9 type=nu-fission [ 0. 0.] [ 0. 0.] domain=9 type=nu-scatter matrix -[[ 0.60053598 0. ] - [ 0. 0. ]] -[[ 0.74887543 0. ] - [ 0. 0. ]] +[[[ 0.72037987 0.11984389 0.03852204 0.05602285] + [ 0. 0. 0. 0. ]] + + [[ 0. 0. 0. 0. ] + [ 0. 0. 0. 0. ]]] +[[[ 0.77101455 0.18469083 0.06448453 0.05059534] + [ 0. 0. 0. 0. ]] + + [[ 0. 0. 0. 0. ] + [ 0. 0. 0. 0. ]]] domain=9 type=chi [ 0. 0.] [ 0. 0.] @@ -131,10 +185,16 @@ domain=10 type=nu-fission [ 0. 0.] [ 0. 0.] domain=10 type=nu-scatter matrix -[[ 0.23551495 0. ] - [ 0. 0. ]] -[[ 0.61397415 0. ] - [ 0. 0. ]] +[[[ 0.50100891 0.26549396 0.14197875 0.07425836] + [ 0. 0. 0. 0. ]] + + [[ 0. 0. 0. 0. ] + [ 0. 0. 0. 0. ]]] +[[[ 0.70853359 0.37546516 0.20078827 0.10501718] + [ 0. 0. 0. 0. ]] + + [[ 0. 0. 0. 0. ] + [ 0. 0. 0. 0. ]]] domain=10 type=chi [ 0. 0.] [ 0. 0.] @@ -145,10 +205,16 @@ domain=11 type=nu-fission [ 0. 0.] [ 0. 0.] domain=11 type=nu-scatter matrix -[[ 0.15444875 0.03187517] - [ 0. 0.90308451]] -[[ 0.59768579 0.0450783 ] - [ 0. 1.53214394]] +[[[ 0.47812753 0.32367878 0.14337507 0.05400336] + [ 0.03187517 0.00858456 -0.01246962 -0.01132019]] + + [[ 0. 0. 0. 0. ] + [ 1.20124973 0.28661101 0.21819147 -0.04851424]]] +[[[ 0.67617444 0.45775092 0.20276296 0.07637229] + [ 0.0450783 0.0121404 0.01763471 0.01600917]] + + [[ 0. 0. 0. 0. ] + [ 1.69882367 0.40532917 0.30856933 0.0686095 ]]] domain=11 type=chi [ 0. 0.] [ 0. 0.] @@ -159,10 +225,16 @@ domain=12 type=nu-fission [ 0. 0.] [ 0. 0.] domain=12 type=nu-scatter matrix -[[ 0.18605249 0.02723959] - [ 0. 1.35711799]] -[[ 0.25763254 0.02955488] - [ 0. 2.08984614]] +[[[ 0.40859392 0.22254143 0.0909719 0.03100368] + [ 0.02723959 -0.01008785 -0.00694631 0.00969231]] + + [[ 0. 0. 0. 0. ] + [ 1.57432766 0.22974802 0.01417839 0.03899727]]] +[[[ 0.27812309 0.14577636 0.06962553 0.03598053] + [ 0.02955488 0.01094529 0.00753673 0.01051613]] + + [[ 0. 0. 0. 0. ] + [ 2.22643553 0.32491277 0.02005128 0.05515046]]] domain=12 type=chi [ 0. 0.] [ 0. 0.] diff --git a/tests/test_mgxs_library_hdf5/test_mgxs_library_hdf5.py b/tests/test_mgxs_library_hdf5/test_mgxs_library_hdf5.py index 642073104..2d7ed2ef3 100644 --- a/tests/test_mgxs_library_hdf5/test_mgxs_library_hdf5.py +++ b/tests/test_mgxs_library_hdf5/test_mgxs_library_hdf5.py @@ -24,16 +24,17 @@ class MGXSTestHarness(PyAPITestHarness): energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 0.625e-6, 20.]) # Initialize MGXS Library for a few cross section types - self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry.geometry) + self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry) self.mgxs_lib.by_nuclide = False self.mgxs_lib.mgxs_types = ['transport', 'nu-fission', 'nu-scatter matrix', 'chi'] self.mgxs_lib.energy_groups = energy_groups + self.mgxs_lib.legendre_order = 3 self.mgxs_lib.domain_type = 'material' self.mgxs_lib.build_library() # Initialize a tallies file - self._input_set.tallies = openmc.TalliesFile() + self._input_set.tallies = openmc.Tallies() self.mgxs_lib.add_to_tallies_file(self._input_set.tallies, merge=False) self._input_set.tallies.export_to_xml() @@ -44,14 +45,9 @@ class MGXSTestHarness(PyAPITestHarness): statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] sp = openmc.StatePoint(statepoint) - # Read the summary file. - summary = glob.glob(os.path.join(os.getcwd(), 'summary.h5'))[0] - su = openmc.Summary(summary) - sp.link_with_summary(su) - # Load the MGXS library from the statepoint self.mgxs_lib.load_from_statepoint(sp) - + # Export the MGXS Library to an HDF5 file self.mgxs_lib.build_hdf5_store(directory='.') @@ -67,7 +63,7 @@ class MGXSTestHarness(PyAPITestHarness): outstr += str(f[key][...]) + '\n' key = 'material/{0}/{1}/std. dev.'.format(domain.id, mgxs_type) outstr += str(f[key][...]) + '\n' - + # Close the MGXS HDF5 file f.close() diff --git a/tests/test_mgxs_library_no_nuclides/inputs_true.dat b/tests/test_mgxs_library_no_nuclides/inputs_true.dat index b94f64122..3643c9a2e 100644 --- a/tests/test_mgxs_library_no_nuclides/inputs_true.dat +++ b/tests/test_mgxs_library_no_nuclides/inputs_true.dat @@ -1 +1 @@ -53b1740921b71e4ead909ab9e4c25f7d43990fe7d7051fde6f66c39c0a6082177385640244010e1b9dbeaf5f34adf1627e9603088af729fadd6b589c19102edc \ No newline at end of file +104e7fb527770ac5d3fc636da7716e8fb05d55761253d30516c899f466e6b38ffd881611a3d0cdf65c6af058c32f6f6758c68782be7a170d21024bdae751862f \ No newline at end of file diff --git a/tests/test_mgxs_library_no_nuclides/results_true.dat b/tests/test_mgxs_library_no_nuclides/results_true.dat index 442b8ac7b..94150a202 100644 --- a/tests/test_mgxs_library_no_nuclides/results_true.dat +++ b/tests/test_mgxs_library_no_nuclides/results_true.dat @@ -2,120 +2,264 @@ 1 1 1 total 0.372745 0.024269 0 1 2 total 0.861607 0.032349 material group in nuclide mean std. dev. 1 1 1 total 0.021789 0.001182 -0 1 2 total 0.714077 0.040552 material group in group out nuclide mean std. dev. -3 1 1 1 total 0.337397 0.023039 -2 1 1 2 total 0.001559 0.000510 -1 1 2 1 total 0.000000 0.000000 -0 1 2 2 total 0.422051 0.021617 material group out nuclide mean std. dev. +0 1 2 total 0.714077 0.040552 material group in group out nuclide moment mean std. dev. +12 1 1 1 total P0 0.381546 0.024033 +13 1 1 1 total P1 0.044301 0.004722 +14 1 1 1 total P2 0.020646 0.002539 +15 1 1 1 total P3 0.013695 0.002224 +8 1 1 2 total P0 0.001559 0.000510 +9 1 1 2 total P1 -0.000597 0.000225 +10 1 1 2 total P2 -0.000239 0.000222 +11 1 1 2 total P3 0.000176 0.000209 +4 1 2 1 total P0 0.000000 0.000000 +5 1 2 1 total P1 0.000000 0.000000 +6 1 2 1 total P2 0.000000 0.000000 +7 1 2 1 total P3 0.000000 0.000000 +0 1 2 2 total P0 0.403916 0.018966 +1 1 2 2 total P1 -0.011310 0.007839 +2 1 2 2 total P2 -0.014807 0.008629 +3 1 2 2 total P3 -0.006855 0.009047 material group out nuclide mean std. dev. 1 1 1 total 1.0 0.055333 0 1 2 total 0.0 0.000000 material group in nuclide mean std. dev. 1 2 1 total 0.237254 0.008184 0 2 2 total 0.285930 0.048796 material group in nuclide mean std. dev. 1 2 1 total 0.0 0.0 -0 2 2 total 0.0 0.0 material group in group out nuclide mean std. dev. -3 2 1 1 total 0.237254 0.008184 -2 2 1 2 total 0.000000 0.000000 -1 2 2 1 total 0.000000 0.000000 -0 2 2 2 total 0.285930 0.048796 material group out nuclide mean std. dev. +0 2 2 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +12 2 1 1 total P0 0.273115 0.006253 +13 2 1 1 total P1 0.035861 0.005878 +14 2 1 1 total P2 0.029704 0.006640 +15 2 1 1 total P3 0.002249 0.003376 +8 2 1 2 total P0 0.000000 0.000000 +9 2 1 2 total P1 0.000000 0.000000 +10 2 1 2 total P2 0.000000 0.000000 +11 2 1 2 total P3 0.000000 0.000000 +4 2 2 1 total P0 0.000000 0.000000 +5 2 2 1 total P1 0.000000 0.000000 +6 2 2 1 total P2 0.000000 0.000000 +7 2 2 1 total P3 0.000000 0.000000 +0 2 2 2 total P0 0.264051 0.045397 +1 2 2 2 total P1 -0.021880 0.012218 +2 2 2 2 total P2 -0.015295 0.010276 +3 2 2 2 total P3 0.014034 0.014318 material group out nuclide mean std. dev. 1 2 1 total 0.0 0.0 0 2 2 total 0.0 0.0 material group in nuclide mean std. dev. 1 3 1 total 0.286906 0.027401 0 3 2 total 1.418151 0.265308 material group in nuclide mean std. dev. 1 3 1 total 0.0 0.0 -0 3 2 total 0.0 0.0 material group in group out nuclide mean std. dev. -3 3 1 1 total 0.259937 0.026115 -2 3 1 2 total 0.026187 0.001665 -1 3 2 1 total 0.000000 0.000000 -0 3 2 2 total 1.359521 0.258505 material group out nuclide mean std. dev. +0 3 2 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +12 3 1 1 total P0 0.643346 0.028376 +13 3 1 1 total P1 0.383409 0.016447 +14 3 1 1 total P2 0.152185 0.009574 +15 3 1 1 total P3 0.003037 0.004648 +8 3 1 2 total P0 0.026187 0.001665 +9 3 1 2 total P1 0.007362 0.000934 +10 3 1 2 total P2 -0.002738 0.000756 +11 3 1 2 total P3 -0.002720 0.000558 +4 3 2 1 total P0 0.000000 0.000000 +5 3 2 1 total P1 0.000000 0.000000 +6 3 2 1 total P2 0.000000 0.000000 +7 3 2 1 total P3 0.000000 0.000000 +0 3 2 2 total P0 1.924214 0.284062 +1 3 2 2 total P1 0.498431 0.063421 +2 3 2 2 total P2 0.091205 0.013726 +3 3 2 2 total P3 0.017054 0.013916 material group out nuclide mean std. dev. 1 3 1 total 0.0 0.0 0 3 2 total 0.0 0.0 material group in nuclide mean std. dev. 1 4 1 total 0.242447 0.061031 0 4 2 total 1.253959 0.388363 material group in nuclide mean std. dev. 1 4 1 total 0.0 0.0 -0 4 2 total 0.0 0.0 material group in group out nuclide mean std. dev. -3 4 1 1 total 0.217930 0.058565 -2 4 1 2 total 0.023662 0.003083 -1 4 2 1 total 0.000000 0.000000 -0 4 2 2 total 1.215074 0.381025 material group out nuclide mean std. dev. +0 4 2 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +12 4 1 1 total P0 0.543941 0.065427 +13 4 1 1 total P1 0.326011 0.038602 +14 4 1 1 total P2 0.131133 0.017475 +15 4 1 1 total P3 0.012105 0.006073 +8 4 1 2 total P0 0.023662 0.003083 +9 4 1 2 total P1 0.007526 0.001301 +10 4 1 2 total P2 -0.002730 0.000841 +11 4 1 2 total P3 -0.003140 0.000578 +4 4 2 1 total P0 0.000000 0.000000 +5 4 2 1 total P1 0.000000 0.000000 +6 4 2 1 total P2 0.000000 0.000000 +7 4 2 1 total P3 0.000000 0.000000 +0 4 2 2 total P0 1.764648 0.416210 +1 4 2 2 total P1 0.500695 0.122178 +2 4 2 2 total P2 0.099026 0.038719 +3 4 2 2 total P3 0.032975 0.025103 material group out nuclide mean std. dev. 1 4 1 total 0.0 0.0 0 4 2 total 0.0 0.0 material group in nuclide mean std. dev. 1 5 1 total 0.0 0.0 0 5 2 total 0.0 0.0 material group in nuclide mean std. dev. 1 5 1 total 0.0 0.0 -0 5 2 total 0.0 0.0 material group in group out nuclide mean std. dev. -3 5 1 1 total 0.0 0.0 -2 5 1 2 total 0.0 0.0 -1 5 2 1 total 0.0 0.0 -0 5 2 2 total 0.0 0.0 material group out nuclide mean std. dev. +0 5 2 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +12 5 1 1 total P0 0.0 0.0 +13 5 1 1 total P1 0.0 0.0 +14 5 1 1 total P2 0.0 0.0 +15 5 1 1 total P3 0.0 0.0 +8 5 1 2 total P0 0.0 0.0 +9 5 1 2 total P1 0.0 0.0 +10 5 1 2 total P2 0.0 0.0 +11 5 1 2 total P3 0.0 0.0 +4 5 2 1 total P0 0.0 0.0 +5 5 2 1 total P1 0.0 0.0 +6 5 2 1 total P2 0.0 0.0 +7 5 2 1 total P3 0.0 0.0 +0 5 2 2 total P0 0.0 0.0 +1 5 2 2 total P1 0.0 0.0 +2 5 2 2 total P2 0.0 0.0 +3 5 2 2 total P3 0.0 0.0 material group out nuclide mean std. dev. 1 5 1 total 0.0 0.0 0 5 2 total 0.0 0.0 material group in nuclide mean std. dev. 1 6 1 total 0.0 0.0 0 6 2 total 0.0 0.0 material group in nuclide mean std. dev. 1 6 1 total 0.0 0.0 -0 6 2 total 0.0 0.0 material group in group out nuclide mean std. dev. -3 6 1 1 total 0.0 0.0 -2 6 1 2 total 0.0 0.0 -1 6 2 1 total 0.0 0.0 -0 6 2 2 total 0.0 0.0 material group out nuclide mean std. dev. +0 6 2 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +12 6 1 1 total P0 0.0 0.0 +13 6 1 1 total P1 0.0 0.0 +14 6 1 1 total P2 0.0 0.0 +15 6 1 1 total P3 0.0 0.0 +8 6 1 2 total P0 0.0 0.0 +9 6 1 2 total P1 0.0 0.0 +10 6 1 2 total P2 0.0 0.0 +11 6 1 2 total P3 0.0 0.0 +4 6 2 1 total P0 0.0 0.0 +5 6 2 1 total P1 0.0 0.0 +6 6 2 1 total P2 0.0 0.0 +7 6 2 1 total P3 0.0 0.0 +0 6 2 2 total P0 0.0 0.0 +1 6 2 2 total P1 0.0 0.0 +2 6 2 2 total P2 0.0 0.0 +3 6 2 2 total P3 0.0 0.0 material group out nuclide mean std. dev. 1 6 1 total 0.0 0.0 0 6 2 total 0.0 0.0 material group in nuclide mean std. dev. 1 7 1 total 0.0 0.0 0 7 2 total 0.0 0.0 material group in nuclide mean std. dev. 1 7 1 total 0.0 0.0 -0 7 2 total 0.0 0.0 material group in group out nuclide mean std. dev. -3 7 1 1 total 0.0 0.0 -2 7 1 2 total 0.0 0.0 -1 7 2 1 total 0.0 0.0 -0 7 2 2 total 0.0 0.0 material group out nuclide mean std. dev. +0 7 2 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +12 7 1 1 total P0 0.0 0.0 +13 7 1 1 total P1 0.0 0.0 +14 7 1 1 total P2 0.0 0.0 +15 7 1 1 total P3 0.0 0.0 +8 7 1 2 total P0 0.0 0.0 +9 7 1 2 total P1 0.0 0.0 +10 7 1 2 total P2 0.0 0.0 +11 7 1 2 total P3 0.0 0.0 +4 7 2 1 total P0 0.0 0.0 +5 7 2 1 total P1 0.0 0.0 +6 7 2 1 total P2 0.0 0.0 +7 7 2 1 total P3 0.0 0.0 +0 7 2 2 total P0 0.0 0.0 +1 7 2 2 total P1 0.0 0.0 +2 7 2 2 total P2 0.0 0.0 +3 7 2 2 total P3 0.0 0.0 material group out nuclide mean std. dev. 1 7 1 total 0.0 0.0 0 7 2 total 0.0 0.0 material group in nuclide mean std. dev. 1 8 1 total 0.0 0.0 0 8 2 total 0.0 0.0 material group in nuclide mean std. dev. 1 8 1 total 0.0 0.0 -0 8 2 total 0.0 0.0 material group in group out nuclide mean std. dev. -3 8 1 1 total 0.0 0.0 -2 8 1 2 total 0.0 0.0 -1 8 2 1 total 0.0 0.0 -0 8 2 2 total 0.0 0.0 material group out nuclide mean std. dev. +0 8 2 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +12 8 1 1 total P0 0.0 0.0 +13 8 1 1 total P1 0.0 0.0 +14 8 1 1 total P2 0.0 0.0 +15 8 1 1 total P3 0.0 0.0 +8 8 1 2 total P0 0.0 0.0 +9 8 1 2 total P1 0.0 0.0 +10 8 1 2 total P2 0.0 0.0 +11 8 1 2 total P3 0.0 0.0 +4 8 2 1 total P0 0.0 0.0 +5 8 2 1 total P1 0.0 0.0 +6 8 2 1 total P2 0.0 0.0 +7 8 2 1 total P3 0.0 0.0 +0 8 2 2 total P0 0.0 0.0 +1 8 2 2 total P1 0.0 0.0 +2 8 2 2 total P2 0.0 0.0 +3 8 2 2 total P3 0.0 0.0 material group out nuclide mean std. dev. 1 8 1 total 0.0 0.0 0 8 2 total 0.0 0.0 material group in nuclide mean std. dev. 1 9 1 total 0.600536 0.748875 0 9 2 total 0.000000 0.000000 material group in nuclide mean std. dev. 1 9 1 total 0.0 0.0 -0 9 2 total 0.0 0.0 material group in group out nuclide mean std. dev. -3 9 1 1 total 0.600536 0.748875 -2 9 1 2 total 0.000000 0.000000 -1 9 2 1 total 0.000000 0.000000 -0 9 2 2 total 0.000000 0.000000 material group out nuclide mean std. dev. +0 9 2 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +12 9 1 1 total P0 0.720380 0.771015 +13 9 1 1 total P1 0.119844 0.184691 +14 9 1 1 total P2 0.038522 0.064485 +15 9 1 1 total P3 0.056023 0.050595 +8 9 1 2 total P0 0.000000 0.000000 +9 9 1 2 total P1 0.000000 0.000000 +10 9 1 2 total P2 0.000000 0.000000 +11 9 1 2 total P3 0.000000 0.000000 +4 9 2 1 total P0 0.000000 0.000000 +5 9 2 1 total P1 0.000000 0.000000 +6 9 2 1 total P2 0.000000 0.000000 +7 9 2 1 total P3 0.000000 0.000000 +0 9 2 2 total P0 0.000000 0.000000 +1 9 2 2 total P1 0.000000 0.000000 +2 9 2 2 total P2 0.000000 0.000000 +3 9 2 2 total P3 0.000000 0.000000 material group out nuclide mean std. dev. 1 9 1 total 0.0 0.0 0 9 2 total 0.0 0.0 material group in nuclide mean std. dev. 1 10 1 total 0.235515 0.613974 0 10 2 total 0.000000 0.000000 material group in nuclide mean std. dev. 1 10 1 total 0.0 0.0 -0 10 2 total 0.0 0.0 material group in group out nuclide mean std. dev. -3 10 1 1 total 0.235515 0.613974 -2 10 1 2 total 0.000000 0.000000 -1 10 2 1 total 0.000000 0.000000 -0 10 2 2 total 0.000000 0.000000 material group out nuclide mean std. dev. +0 10 2 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +12 10 1 1 total P0 0.501009 0.708534 +13 10 1 1 total P1 0.265494 0.375465 +14 10 1 1 total P2 0.141979 0.200788 +15 10 1 1 total P3 0.074258 0.105017 +8 10 1 2 total P0 0.000000 0.000000 +9 10 1 2 total P1 0.000000 0.000000 +10 10 1 2 total P2 0.000000 0.000000 +11 10 1 2 total P3 0.000000 0.000000 +4 10 2 1 total P0 0.000000 0.000000 +5 10 2 1 total P1 0.000000 0.000000 +6 10 2 1 total P2 0.000000 0.000000 +7 10 2 1 total P3 0.000000 0.000000 +0 10 2 2 total P0 0.000000 0.000000 +1 10 2 2 total P1 0.000000 0.000000 +2 10 2 2 total P2 0.000000 0.000000 +3 10 2 2 total P3 0.000000 0.000000 material group out nuclide mean std. dev. 1 10 1 total 0.0 0.0 0 10 2 total 0.0 0.0 material group in nuclide mean std. dev. 1 11 1 total 0.186324 0.632129 0 11 2 total 0.945986 1.591133 material group in nuclide mean std. dev. 1 11 1 total 0.0 0.0 -0 11 2 total 0.0 0.0 material group in group out nuclide mean std. dev. -3 11 1 1 total 0.154449 0.597686 -2 11 1 2 total 0.031875 0.045078 -1 11 2 1 total 0.000000 0.000000 -0 11 2 2 total 0.903085 1.532144 material group out nuclide mean std. dev. +0 11 2 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +12 11 1 1 total P0 0.478128 0.676174 +13 11 1 1 total P1 0.323679 0.457751 +14 11 1 1 total P2 0.143375 0.202763 +15 11 1 1 total P3 0.054003 0.076372 +8 11 1 2 total P0 0.031875 0.045078 +9 11 1 2 total P1 0.008585 0.012140 +10 11 1 2 total P2 -0.012470 0.017635 +11 11 1 2 total P3 -0.011320 0.016009 +4 11 2 1 total P0 0.000000 0.000000 +5 11 2 1 total P1 0.000000 0.000000 +6 11 2 1 total P2 0.000000 0.000000 +7 11 2 1 total P3 0.000000 0.000000 +0 11 2 2 total P0 1.201250 1.698824 +1 11 2 2 total P1 0.286611 0.405329 +2 11 2 2 total P2 0.218191 0.308569 +3 11 2 2 total P3 -0.048514 0.068609 material group out nuclide mean std. dev. 1 11 1 total 0.0 0.0 0 11 2 total 0.0 0.0 material group in nuclide mean std. dev. 1 12 1 total 0.213292 0.271444 0 12 2 total 1.390975 2.137346 material group in nuclide mean std. dev. 1 12 1 total 0.0 0.0 -0 12 2 total 0.0 0.0 material group in group out nuclide mean std. dev. -3 12 1 1 total 0.186052 0.257633 -2 12 1 2 total 0.027240 0.029555 -1 12 2 1 total 0.000000 0.000000 -0 12 2 2 total 1.357118 2.089846 material group out nuclide mean std. dev. +0 12 2 total 0.0 0.0 material group in group out nuclide moment mean std. dev. +12 12 1 1 total P0 0.408594 0.278123 +13 12 1 1 total P1 0.222541 0.145776 +14 12 1 1 total P2 0.090972 0.069626 +15 12 1 1 total P3 0.031004 0.035981 +8 12 1 2 total P0 0.027240 0.029555 +9 12 1 2 total P1 -0.010088 0.010945 +10 12 1 2 total P2 -0.006946 0.007537 +11 12 1 2 total P3 0.009692 0.010516 +4 12 2 1 total P0 0.000000 0.000000 +5 12 2 1 total P1 0.000000 0.000000 +6 12 2 1 total P2 0.000000 0.000000 +7 12 2 1 total P3 0.000000 0.000000 +0 12 2 2 total P0 1.574328 2.226436 +1 12 2 2 total P1 0.229748 0.324913 +2 12 2 2 total P2 0.014178 0.020051 +3 12 2 2 total P3 0.038997 0.055150 material group out nuclide mean std. dev. 1 12 1 total 0.0 0.0 0 12 2 total 0.0 0.0 \ No newline at end of file diff --git a/tests/test_mgxs_library_no_nuclides/test_mgxs_library_no_nuclides.py b/tests/test_mgxs_library_no_nuclides/test_mgxs_library_no_nuclides.py index 2afa9039e..6ee8813d0 100644 --- a/tests/test_mgxs_library_no_nuclides/test_mgxs_library_no_nuclides.py +++ b/tests/test_mgxs_library_no_nuclides/test_mgxs_library_no_nuclides.py @@ -23,16 +23,17 @@ class MGXSTestHarness(PyAPITestHarness): energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 0.625e-6, 20.]) # Initialize MGXS Library for a few cross section types - self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry.geometry) + self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry) self.mgxs_lib.by_nuclide = False self.mgxs_lib.mgxs_types = ['transport', 'nu-fission', 'nu-scatter matrix', 'chi'] self.mgxs_lib.energy_groups = energy_groups + self.mgxs_lib.legendre_order = 3 self.mgxs_lib.domain_type = 'material' self.mgxs_lib.build_library() # Initialize a tallies file - self._input_set.tallies = openmc.TalliesFile() + self._input_set.tallies = openmc.Tallies() self.mgxs_lib.add_to_tallies_file(self._input_set.tallies, merge=False) self._input_set.tallies.export_to_xml() @@ -43,11 +44,6 @@ class MGXSTestHarness(PyAPITestHarness): statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] sp = openmc.StatePoint(statepoint) - # Read the summary file. - summary = glob.glob(os.path.join(os.getcwd(), 'summary.h5'))[0] - su = openmc.Summary(summary) - sp.link_with_summary(su) - # Load the MGXS library from the statepoint self.mgxs_lib.load_from_statepoint(sp) diff --git a/tests/test_mgxs_library_nuclides/inputs_true.dat b/tests/test_mgxs_library_nuclides/inputs_true.dat index f87bc242d..9e25fe96a 100644 --- a/tests/test_mgxs_library_nuclides/inputs_true.dat +++ b/tests/test_mgxs_library_nuclides/inputs_true.dat @@ -1 +1 @@ -c6a2a1c707bc723fd38bafd18efcfb22beaac0bd5953d7524ced1d47866cc1e1ee4152e39234d32a06fe43aff446fb12f8c5b62a44075607f274778b49110762 \ No newline at end of file +791a2bd647b8bae03aafc39e29ff1ce1ffc44063b0d757ccba4e1eda6eb73b8a275020f4f5774b17dede49fbf15549787279c8b2fc45caba0097155b32e56fa8 \ No newline at end of file diff --git a/tests/test_mgxs_library_nuclides/results_true.dat b/tests/test_mgxs_library_nuclides/results_true.dat index 145521964..06f838206 100644 --- a/tests/test_mgxs_library_nuclides/results_true.dat +++ b/tests/test_mgxs_library_nuclides/results_true.dat @@ -1,1971 +1 @@ - material group in nuclide mean std. dev. -34 1 1 U-234 0.000173 0.000173 -35 1 1 U-235 0.010677 0.001889 -36 1 1 U-236 0.002390 0.001055 -37 1 1 U-238 0.213680 0.013272 -38 1 1 Np-237 0.000000 0.000000 -39 1 1 Pu-238 0.000000 0.000000 -40 1 1 Pu-239 0.002911 0.000639 -41 1 1 Pu-240 0.004426 0.000806 -42 1 1 Pu-241 0.000690 0.000387 -43 1 1 Pu-242 0.000000 0.000000 -44 1 1 Am-241 0.000173 0.000173 -45 1 1 Am-242m 0.000000 0.000000 -46 1 1 Am-243 0.000000 0.000000 -47 1 1 Cm-242 0.000000 0.000000 -48 1 1 Cm-243 0.000000 0.000000 -49 1 1 Cm-244 0.000000 0.000000 -50 1 1 Cm-245 0.000000 0.000000 -51 1 1 Mo-95 0.000000 0.000000 -52 1 1 Tc-99 0.000173 0.000173 -53 1 1 Ru-101 0.000238 0.000254 -54 1 1 Ru-103 0.000002 0.000243 -55 1 1 Ag-109 0.000000 0.000000 -56 1 1 Xe-135 0.000000 0.000000 -57 1 1 Cs-133 0.000347 0.000213 -58 1 1 Nd-143 0.000447 0.000292 -59 1 1 Nd-145 0.000564 0.000294 -60 1 1 Sm-147 0.000000 0.000000 -61 1 1 Sm-149 0.000000 0.000000 -62 1 1 Sm-150 0.000472 0.000239 -63 1 1 Sm-151 0.000000 0.000000 -64 1 1 Sm-152 0.000492 0.000352 -65 1 1 Eu-153 0.000173 0.000173 -66 1 1 Gd-155 0.000000 0.000000 -67 1 1 O-16 0.134715 0.009801 -0 1 2 U-234 0.000000 0.000000 -1 1 2 U-235 0.199907 0.007776 -2 1 2 U-236 0.001501 0.002037 -3 1 2 U-238 0.255355 0.029743 -4 1 2 Np-237 0.000000 0.000000 -5 1 2 Pu-238 0.000000 0.000000 -6 1 2 Pu-239 0.160378 0.011366 -7 1 2 Pu-240 0.007920 0.003710 -8 1 2 Pu-241 0.017820 0.003733 -9 1 2 Pu-242 0.000000 0.000000 -10 1 2 Am-241 0.000000 0.000000 -11 1 2 Am-242m 0.000000 0.000000 -12 1 2 Am-243 0.000000 0.000000 -13 1 2 Cm-242 0.000000 0.000000 -14 1 2 Cm-243 0.000000 0.000000 -15 1 2 Cm-244 0.000000 0.000000 -16 1 2 Cm-245 0.000000 0.000000 -17 1 2 Mo-95 0.000000 0.000000 -18 1 2 Tc-99 0.000000 0.000000 -19 1 2 Ru-101 0.000000 0.000000 -20 1 2 Ru-103 0.000000 0.000000 -21 1 2 Ag-109 0.000000 0.000000 -22 1 2 Xe-135 0.013860 0.003976 -23 1 2 Cs-133 0.000000 0.000000 -24 1 2 Nd-143 0.003960 0.002427 -25 1 2 Nd-145 0.000000 0.000000 -26 1 2 Sm-147 0.000000 0.000000 -27 1 2 Sm-149 0.001980 0.001981 -28 1 2 Sm-150 0.000000 0.000000 -29 1 2 Sm-151 0.001980 0.001981 -30 1 2 Sm-152 0.000000 0.000000 -31 1 2 Eu-153 0.000000 0.000000 -32 1 2 Gd-155 0.000000 0.000000 -33 1 2 O-16 0.196946 0.014729 material group in nuclide mean std. dev. -34 1 1 U-234 7.274440e-06 4.419477e-07 -35 1 1 U-235 9.587803e-03 5.936922e-04 -36 1 1 U-236 7.566099e-05 7.523935e-06 -37 1 1 U-238 7.178367e-03 6.505680e-04 -38 1 1 Np-237 1.315682e-05 8.036501e-07 -39 1 1 Pu-238 7.746151e-06 3.992835e-07 -40 1 1 Pu-239 3.805294e-03 3.637600e-04 -41 1 1 Pu-240 6.941319e-05 4.729737e-06 -42 1 1 Pu-241 1.033844e-03 9.083913e-05 -43 1 1 Pu-242 5.995332e-06 3.821721e-07 -44 1 1 Am-241 1.148585e-06 8.271648e-08 -45 1 1 Am-242m 1.100215e-06 6.159956e-08 -46 1 1 Am-243 8.323826e-07 5.841792e-08 -47 1 1 Cm-242 5.088970e-07 5.258007e-08 -48 1 1 Cm-243 2.245435e-07 1.459025e-08 -49 1 1 Cm-244 2.993206e-07 2.746129e-08 -50 1 1 Cm-245 3.063611e-07 3.057751e-08 -51 1 1 Mo-95 0.000000e+00 0.000000e+00 -52 1 1 Tc-99 0.000000e+00 0.000000e+00 -53 1 1 Ru-101 0.000000e+00 0.000000e+00 -54 1 1 Ru-103 0.000000e+00 0.000000e+00 -55 1 1 Ag-109 0.000000e+00 0.000000e+00 -56 1 1 Xe-135 0.000000e+00 0.000000e+00 -57 1 1 Cs-133 0.000000e+00 0.000000e+00 -58 1 1 Nd-143 0.000000e+00 0.000000e+00 -59 1 1 Nd-145 0.000000e+00 0.000000e+00 -60 1 1 Sm-147 0.000000e+00 0.000000e+00 -61 1 1 Sm-149 0.000000e+00 0.000000e+00 -62 1 1 Sm-150 0.000000e+00 0.000000e+00 -63 1 1 Sm-151 0.000000e+00 0.000000e+00 -64 1 1 Sm-152 0.000000e+00 0.000000e+00 -65 1 1 Eu-153 0.000000e+00 0.000000e+00 -66 1 1 Gd-155 0.000000e+00 0.000000e+00 -67 1 1 O-16 0.000000e+00 0.000000e+00 -0 1 2 U-234 4.408576e-07 2.828309e-08 -1 1 2 U-235 3.768094e-01 2.445671e-02 -2 1 2 U-236 6.097538e-06 3.733038e-07 -3 1 2 U-238 5.353074e-07 3.310544e-08 -4 1 2 Np-237 2.702971e-07 2.098939e-08 -5 1 2 Pu-238 3.463109e-05 2.638394e-06 -6 1 2 Pu-239 2.889643e-01 1.376004e-02 -7 1 2 Pu-240 4.533642e-06 2.544289e-07 -8 1 2 Pu-241 4.809366e-02 2.778345e-03 -9 1 2 Pu-242 8.715325e-08 5.460893e-09 -10 1 2 Am-241 4.611736e-06 2.155039e-07 -11 1 2 Am-242m 1.428047e-04 8.436437e-06 -12 1 2 Am-243 7.883895e-08 4.734503e-09 -13 1 2 Cm-242 9.731025e-07 6.143750e-08 -14 1 2 Cm-243 1.825830e-06 1.074849e-07 -15 1 2 Cm-244 1.581823e-07 9.938064e-09 -16 1 2 Cm-245 1.213386e-05 8.812019e-07 -17 1 2 Mo-95 0.000000e+00 0.000000e+00 -18 1 2 Tc-99 0.000000e+00 0.000000e+00 -19 1 2 Ru-101 0.000000e+00 0.000000e+00 -20 1 2 Ru-103 0.000000e+00 0.000000e+00 -21 1 2 Ag-109 0.000000e+00 0.000000e+00 -22 1 2 Xe-135 0.000000e+00 0.000000e+00 -23 1 2 Cs-133 0.000000e+00 0.000000e+00 -24 1 2 Nd-143 0.000000e+00 0.000000e+00 -25 1 2 Nd-145 0.000000e+00 0.000000e+00 -26 1 2 Sm-147 0.000000e+00 0.000000e+00 -27 1 2 Sm-149 0.000000e+00 0.000000e+00 -28 1 2 Sm-150 0.000000e+00 0.000000e+00 -29 1 2 Sm-151 0.000000e+00 0.000000e+00 -30 1 2 Sm-152 0.000000e+00 0.000000e+00 -31 1 2 Eu-153 0.000000e+00 0.000000e+00 -32 1 2 Gd-155 0.000000e+00 0.000000e+00 -33 1 2 O-16 0.000000e+00 0.000000e+00 material group in group out nuclide mean std. dev. -102 1 1 1 U-234 0.000000 0.000000 -103 1 1 1 U-235 0.003226 0.001139 -104 1 1 1 U-236 0.001697 0.000923 -105 1 1 1 U-238 0.194620 0.013297 -106 1 1 1 Np-237 0.000000 0.000000 -107 1 1 1 Pu-238 0.000000 0.000000 -108 1 1 1 Pu-239 0.001005 0.000477 -109 1 1 1 Pu-240 0.001307 0.000295 -110 1 1 1 Pu-241 0.000344 0.000244 -111 1 1 1 Pu-242 0.000000 0.000000 -112 1 1 1 Am-241 0.000000 0.000000 -113 1 1 1 Am-242m 0.000000 0.000000 -114 1 1 1 Am-243 0.000000 0.000000 -115 1 1 1 Cm-242 0.000000 0.000000 -116 1 1 1 Cm-243 0.000000 0.000000 -117 1 1 1 Cm-244 0.000000 0.000000 -118 1 1 1 Cm-245 0.000000 0.000000 -119 1 1 1 Mo-95 0.000000 0.000000 -120 1 1 1 Tc-99 0.000000 0.000000 -121 1 1 1 Ru-101 0.000238 0.000254 -122 1 1 1 Ru-103 0.000002 0.000243 -123 1 1 1 Ag-109 0.000000 0.000000 -124 1 1 1 Xe-135 0.000000 0.000000 -125 1 1 1 Cs-133 0.000000 0.000000 -126 1 1 1 Nd-143 0.000447 0.000292 -127 1 1 1 Nd-145 0.000564 0.000294 -128 1 1 1 Sm-147 0.000000 0.000000 -129 1 1 1 Sm-149 0.000000 0.000000 -130 1 1 1 Sm-150 0.000299 0.000238 -131 1 1 1 Sm-151 0.000000 0.000000 -132 1 1 1 Sm-152 0.000492 0.000352 -133 1 1 1 Eu-153 0.000000 0.000000 -134 1 1 1 Gd-155 0.000000 0.000000 -135 1 1 1 O-16 0.133156 0.009821 -68 1 1 2 U-234 0.000000 0.000000 -69 1 1 2 U-235 0.000000 0.000000 -70 1 1 2 U-236 0.000000 0.000000 -71 1 1 2 U-238 0.000173 0.000173 -72 1 1 2 Np-237 0.000000 0.000000 -73 1 1 2 Pu-238 0.000000 0.000000 -74 1 1 2 Pu-239 0.000000 0.000000 -75 1 1 2 Pu-240 0.000000 0.000000 -76 1 1 2 Pu-241 0.000000 0.000000 -77 1 1 2 Pu-242 0.000000 0.000000 -78 1 1 2 Am-241 0.000000 0.000000 -79 1 1 2 Am-242m 0.000000 0.000000 -80 1 1 2 Am-243 0.000000 0.000000 -81 1 1 2 Cm-242 0.000000 0.000000 -82 1 1 2 Cm-243 0.000000 0.000000 -83 1 1 2 Cm-244 0.000000 0.000000 -84 1 1 2 Cm-245 0.000000 0.000000 -85 1 1 2 Mo-95 0.000000 0.000000 -86 1 1 2 Tc-99 0.000000 0.000000 -87 1 1 2 Ru-101 0.000000 0.000000 -88 1 1 2 Ru-103 0.000000 0.000000 -89 1 1 2 Ag-109 0.000000 0.000000 -90 1 1 2 Xe-135 0.000000 0.000000 -91 1 1 2 Cs-133 0.000000 0.000000 -92 1 1 2 Nd-143 0.000000 0.000000 -93 1 1 2 Nd-145 0.000000 0.000000 -94 1 1 2 Sm-147 0.000000 0.000000 -95 1 1 2 Sm-149 0.000000 0.000000 -96 1 1 2 Sm-150 0.000000 0.000000 -97 1 1 2 Sm-151 0.000000 0.000000 -98 1 1 2 Sm-152 0.000000 0.000000 -99 1 1 2 Eu-153 0.000000 0.000000 -100 1 1 2 Gd-155 0.000000 0.000000 -101 1 1 2 O-16 0.001386 0.000446 -34 1 2 1 U-234 0.000000 0.000000 -35 1 2 1 U-235 0.000000 0.000000 -36 1 2 1 U-236 0.000000 0.000000 -37 1 2 1 U-238 0.000000 0.000000 -38 1 2 1 Np-237 0.000000 0.000000 -39 1 2 1 Pu-238 0.000000 0.000000 -40 1 2 1 Pu-239 0.000000 0.000000 -41 1 2 1 Pu-240 0.000000 0.000000 -42 1 2 1 Pu-241 0.000000 0.000000 -43 1 2 1 Pu-242 0.000000 0.000000 -44 1 2 1 Am-241 0.000000 0.000000 -45 1 2 1 Am-242m 0.000000 0.000000 -46 1 2 1 Am-243 0.000000 0.000000 -47 1 2 1 Cm-242 0.000000 0.000000 -48 1 2 1 Cm-243 0.000000 0.000000 -49 1 2 1 Cm-244 0.000000 0.000000 -50 1 2 1 Cm-245 0.000000 0.000000 -51 1 2 1 Mo-95 0.000000 0.000000 -52 1 2 1 Tc-99 0.000000 0.000000 -53 1 2 1 Ru-101 0.000000 0.000000 -54 1 2 1 Ru-103 0.000000 0.000000 -55 1 2 1 Ag-109 0.000000 0.000000 -56 1 2 1 Xe-135 0.000000 0.000000 -57 1 2 1 Cs-133 0.000000 0.000000 -58 1 2 1 Nd-143 0.000000 0.000000 -59 1 2 1 Nd-145 0.000000 0.000000 -60 1 2 1 Sm-147 0.000000 0.000000 -61 1 2 1 Sm-149 0.000000 0.000000 -62 1 2 1 Sm-150 0.000000 0.000000 -63 1 2 1 Sm-151 0.000000 0.000000 -64 1 2 1 Sm-152 0.000000 0.000000 -65 1 2 1 Eu-153 0.000000 0.000000 -66 1 2 1 Gd-155 0.000000 0.000000 -67 1 2 1 O-16 0.000000 0.000000 -0 1 2 2 U-234 0.000000 0.000000 -1 1 2 2 U-235 0.003889 0.003962 -2 1 2 2 U-236 0.001501 0.002037 -3 1 2 2 U-238 0.219715 0.025984 -4 1 2 2 Np-237 0.000000 0.000000 -5 1 2 2 Pu-238 0.000000 0.000000 -6 1 2 2 Pu-239 0.000000 0.000000 -7 1 2 2 Pu-240 0.000000 0.000000 -8 1 2 2 Pu-241 0.000000 0.000000 -9 1 2 2 Pu-242 0.000000 0.000000 -10 1 2 2 Am-241 0.000000 0.000000 -11 1 2 2 Am-242m 0.000000 0.000000 -12 1 2 2 Am-243 0.000000 0.000000 -13 1 2 2 Cm-242 0.000000 0.000000 -14 1 2 2 Cm-243 0.000000 0.000000 -15 1 2 2 Cm-244 0.000000 0.000000 -16 1 2 2 Cm-245 0.000000 0.000000 -17 1 2 2 Mo-95 0.000000 0.000000 -18 1 2 2 Tc-99 0.000000 0.000000 -19 1 2 2 Ru-101 0.000000 0.000000 -20 1 2 2 Ru-103 0.000000 0.000000 -21 1 2 2 Ag-109 0.000000 0.000000 -22 1 2 2 Xe-135 0.000000 0.000000 -23 1 2 2 Cs-133 0.000000 0.000000 -24 1 2 2 Nd-143 0.000000 0.000000 -25 1 2 2 Nd-145 0.000000 0.000000 -26 1 2 2 Sm-147 0.000000 0.000000 -27 1 2 2 Sm-149 0.000000 0.000000 -28 1 2 2 Sm-150 0.000000 0.000000 -29 1 2 2 Sm-151 0.000000 0.000000 -30 1 2 2 Sm-152 0.000000 0.000000 -31 1 2 2 Eu-153 0.000000 0.000000 -32 1 2 2 Gd-155 0.000000 0.000000 -33 1 2 2 O-16 0.196946 0.014729 material group out nuclide mean std. dev. -34 1 1 U-234 0.0 0.000000 -35 1 1 U-235 1.0 0.066362 -36 1 1 U-236 0.0 0.000000 -37 1 1 U-238 1.0 0.093082 -38 1 1 Np-237 0.0 0.000000 -39 1 1 Pu-238 0.0 0.000000 -40 1 1 Pu-239 1.0 0.104567 -41 1 1 Pu-240 0.0 0.000000 -42 1 1 Pu-241 1.0 0.263696 -43 1 1 Pu-242 0.0 0.000000 -44 1 1 Am-241 0.0 0.000000 -45 1 1 Am-242m 0.0 0.000000 -46 1 1 Am-243 0.0 0.000000 -47 1 1 Cm-242 0.0 0.000000 -48 1 1 Cm-243 0.0 0.000000 -49 1 1 Cm-244 0.0 0.000000 -50 1 1 Cm-245 0.0 0.000000 -51 1 1 Mo-95 0.0 0.000000 -52 1 1 Tc-99 0.0 0.000000 -53 1 1 Ru-101 0.0 0.000000 -54 1 1 Ru-103 0.0 0.000000 -55 1 1 Ag-109 0.0 0.000000 -56 1 1 Xe-135 0.0 0.000000 -57 1 1 Cs-133 0.0 0.000000 -58 1 1 Nd-143 0.0 0.000000 -59 1 1 Nd-145 0.0 0.000000 -60 1 1 Sm-147 0.0 0.000000 -61 1 1 Sm-149 0.0 0.000000 -62 1 1 Sm-150 0.0 0.000000 -63 1 1 Sm-151 0.0 0.000000 -64 1 1 Sm-152 0.0 0.000000 -65 1 1 Eu-153 0.0 0.000000 -66 1 1 Gd-155 0.0 0.000000 -67 1 1 O-16 0.0 0.000000 -0 1 2 U-234 0.0 0.000000 -1 1 2 U-235 0.0 0.000000 -2 1 2 U-236 0.0 0.000000 -3 1 2 U-238 0.0 0.000000 -4 1 2 Np-237 0.0 0.000000 -5 1 2 Pu-238 0.0 0.000000 -6 1 2 Pu-239 0.0 0.000000 -7 1 2 Pu-240 0.0 0.000000 -8 1 2 Pu-241 0.0 0.000000 -9 1 2 Pu-242 0.0 0.000000 -10 1 2 Am-241 0.0 0.000000 -11 1 2 Am-242m 0.0 0.000000 -12 1 2 Am-243 0.0 0.000000 -13 1 2 Cm-242 0.0 0.000000 -14 1 2 Cm-243 0.0 0.000000 -15 1 2 Cm-244 0.0 0.000000 -16 1 2 Cm-245 0.0 0.000000 -17 1 2 Mo-95 0.0 0.000000 -18 1 2 Tc-99 0.0 0.000000 -19 1 2 Ru-101 0.0 0.000000 -20 1 2 Ru-103 0.0 0.000000 -21 1 2 Ag-109 0.0 0.000000 -22 1 2 Xe-135 0.0 0.000000 -23 1 2 Cs-133 0.0 0.000000 -24 1 2 Nd-143 0.0 0.000000 -25 1 2 Nd-145 0.0 0.000000 -26 1 2 Sm-147 0.0 0.000000 -27 1 2 Sm-149 0.0 0.000000 -28 1 2 Sm-150 0.0 0.000000 -29 1 2 Sm-151 0.0 0.000000 -30 1 2 Sm-152 0.0 0.000000 -31 1 2 Eu-153 0.0 0.000000 -32 1 2 Gd-155 0.0 0.000000 -33 1 2 O-16 0.0 0.000000 material group in nuclide mean std. dev. -5 2 1 Zr-90 0.104734 0.008915 -6 2 1 Zr-91 0.036155 0.003735 -7 2 1 Zr-92 0.042422 0.003029 -8 2 1 Zr-94 0.046148 0.006251 -9 2 1 Zr-96 0.007794 0.001536 -0 2 2 Zr-90 0.121688 0.034934 -1 2 2 Zr-91 0.061792 0.024317 -2 2 2 Zr-92 0.041633 0.016323 -3 2 2 Zr-94 0.060818 0.021483 -4 2 2 Zr-96 0.000000 0.000000 material group in nuclide mean std. dev. -5 2 1 Zr-90 0.0 0.0 -6 2 1 Zr-91 0.0 0.0 -7 2 1 Zr-92 0.0 0.0 -8 2 1 Zr-94 0.0 0.0 -9 2 1 Zr-96 0.0 0.0 -0 2 2 Zr-90 0.0 0.0 -1 2 2 Zr-91 0.0 0.0 -2 2 2 Zr-92 0.0 0.0 -3 2 2 Zr-94 0.0 0.0 -4 2 2 Zr-96 0.0 0.0 material group in group out nuclide mean std. dev. -15 2 1 1 Zr-90 0.104734 0.008915 -16 2 1 1 Zr-91 0.036155 0.003735 -17 2 1 1 Zr-92 0.042422 0.003029 -18 2 1 1 Zr-94 0.046148 0.006251 -19 2 1 1 Zr-96 0.007794 0.001536 -10 2 1 2 Zr-90 0.000000 0.000000 -11 2 1 2 Zr-91 0.000000 0.000000 -12 2 1 2 Zr-92 0.000000 0.000000 -13 2 1 2 Zr-94 0.000000 0.000000 -14 2 1 2 Zr-96 0.000000 0.000000 -5 2 2 1 Zr-90 0.000000 0.000000 -6 2 2 1 Zr-91 0.000000 0.000000 -7 2 2 1 Zr-92 0.000000 0.000000 -8 2 2 1 Zr-94 0.000000 0.000000 -9 2 2 1 Zr-96 0.000000 0.000000 -0 2 2 2 Zr-90 0.121688 0.034934 -1 2 2 2 Zr-91 0.061792 0.024317 -2 2 2 2 Zr-92 0.041633 0.016323 -3 2 2 2 Zr-94 0.060818 0.021483 -4 2 2 2 Zr-96 0.000000 0.000000 material group out nuclide mean std. dev. -5 2 1 Zr-90 0.0 0.0 -6 2 1 Zr-91 0.0 0.0 -7 2 1 Zr-92 0.0 0.0 -8 2 1 Zr-94 0.0 0.0 -9 2 1 Zr-96 0.0 0.0 -0 2 2 Zr-90 0.0 0.0 -1 2 2 Zr-91 0.0 0.0 -2 2 2 Zr-92 0.0 0.0 -3 2 2 Zr-94 0.0 0.0 -4 2 2 Zr-96 0.0 0.0 material group in nuclide mean std. dev. -4 3 1 H-1 0.207103 0.023028 -5 3 1 O-16 0.079282 0.005197 -6 3 1 B-10 0.000521 0.000244 -7 3 1 B-11 0.000000 0.000000 -0 3 2 H-1 1.283344 0.250946 -1 3 2 O-16 0.085363 0.014001 -2 3 2 B-10 0.049249 0.008232 -3 3 2 B-11 0.000195 0.001527 material group in nuclide mean std. dev. -4 3 1 H-1 0.0 0.0 -5 3 1 O-16 0.0 0.0 -6 3 1 B-10 0.0 0.0 -7 3 1 B-11 0.0 0.0 -0 3 2 H-1 0.0 0.0 -1 3 2 O-16 0.0 0.0 -2 3 2 B-10 0.0 0.0 -3 3 2 B-11 0.0 0.0 material group in group out nuclide mean std. dev. -12 3 1 1 H-1 0.181306 0.022102 -13 3 1 1 O-16 0.078631 0.005044 -14 3 1 1 B-10 0.000000 0.000000 -15 3 1 1 B-11 0.000000 0.000000 -8 3 1 2 H-1 0.025666 0.001582 -9 3 1 2 O-16 0.000521 0.000131 -10 3 1 2 B-10 0.000000 0.000000 -11 3 1 2 B-11 0.000000 0.000000 -4 3 2 1 H-1 0.000000 0.000000 -5 3 2 1 O-16 0.000000 0.000000 -6 3 2 1 B-10 0.000000 0.000000 -7 3 2 1 B-11 0.000000 0.000000 -0 3 2 2 H-1 1.273963 0.250623 -1 3 2 2 O-16 0.085363 0.014001 -2 3 2 2 B-10 0.000000 0.000000 -3 3 2 2 B-11 0.000195 0.001527 material group out nuclide mean std. dev. -4 3 1 H-1 0.0 0.0 -5 3 1 O-16 0.0 0.0 -6 3 1 B-10 0.0 0.0 -7 3 1 B-11 0.0 0.0 -0 3 2 H-1 0.0 0.0 -1 3 2 O-16 0.0 0.0 -2 3 2 B-10 0.0 0.0 -3 3 2 B-11 0.0 0.0 material group in nuclide mean std. dev. -4 4 1 H-1 0.175242 0.053715 -5 4 1 O-16 0.066545 0.010083 -6 4 1 B-10 0.000570 0.000352 -7 4 1 B-11 0.000089 0.000346 -0 4 2 H-1 1.142895 0.365140 -1 4 2 O-16 0.085141 0.028073 -2 4 2 B-10 0.025923 0.007276 -3 4 2 B-11 0.000000 0.000000 material group in nuclide mean std. dev. -4 4 1 H-1 0.0 0.0 -5 4 1 O-16 0.0 0.0 -6 4 1 B-10 0.0 0.0 -7 4 1 B-11 0.0 0.0 -0 4 2 H-1 0.0 0.0 -1 4 2 O-16 0.0 0.0 -2 4 2 B-10 0.0 0.0 -3 4 2 B-11 0.0 0.0 material group in group out nuclide mean std. dev. -12 4 1 1 H-1 0.151295 0.051491 -13 4 1 1 O-16 0.066545 0.010083 -14 4 1 1 B-10 0.000000 0.000000 -15 4 1 1 B-11 0.000089 0.000346 -8 4 1 2 H-1 0.023662 0.003083 -9 4 1 2 O-16 0.000000 0.000000 -10 4 1 2 B-10 0.000000 0.000000 -11 4 1 2 B-11 0.000000 0.000000 -4 4 2 1 H-1 0.000000 0.000000 -5 4 2 1 O-16 0.000000 0.000000 -6 4 2 1 B-10 0.000000 0.000000 -7 4 2 1 B-11 0.000000 0.000000 -0 4 2 2 H-1 1.129933 0.361681 -1 4 2 2 O-16 0.085141 0.028073 -2 4 2 2 B-10 0.000000 0.000000 -3 4 2 2 B-11 0.000000 0.000000 material group out nuclide mean std. dev. -4 4 1 H-1 0.0 0.0 -5 4 1 O-16 0.0 0.0 -6 4 1 B-10 0.0 0.0 -7 4 1 B-11 0.0 0.0 -0 4 2 H-1 0.0 0.0 -1 4 2 O-16 0.0 0.0 -2 4 2 B-10 0.0 0.0 -3 4 2 B-11 0.0 0.0 material group in nuclide mean std. dev. -27 5 1 Fe-54 0.0 0.0 -28 5 1 Fe-56 0.0 0.0 -29 5 1 Fe-57 0.0 0.0 -30 5 1 Fe-58 0.0 0.0 -31 5 1 Ni-58 0.0 0.0 -32 5 1 Ni-60 0.0 0.0 -33 5 1 Ni-61 0.0 0.0 -34 5 1 Ni-62 0.0 0.0 -35 5 1 Ni-64 0.0 0.0 -36 5 1 Mn-55 0.0 0.0 -37 5 1 Mo-92 0.0 0.0 -38 5 1 Mo-94 0.0 0.0 -39 5 1 Mo-95 0.0 0.0 -40 5 1 Mo-96 0.0 0.0 -41 5 1 Mo-97 0.0 0.0 -42 5 1 Mo-98 0.0 0.0 -43 5 1 Mo-100 0.0 0.0 -44 5 1 Si-28 0.0 0.0 -45 5 1 Si-29 0.0 0.0 -46 5 1 Si-30 0.0 0.0 -47 5 1 Cr-50 0.0 0.0 -48 5 1 Cr-52 0.0 0.0 -49 5 1 Cr-53 0.0 0.0 -50 5 1 Cr-54 0.0 0.0 -51 5 1 C-Nat 0.0 0.0 -52 5 1 Cu-63 0.0 0.0 -53 5 1 Cu-65 0.0 0.0 -0 5 2 Fe-54 0.0 0.0 -1 5 2 Fe-56 0.0 0.0 -2 5 2 Fe-57 0.0 0.0 -3 5 2 Fe-58 0.0 0.0 -4 5 2 Ni-58 0.0 0.0 -5 5 2 Ni-60 0.0 0.0 -6 5 2 Ni-61 0.0 0.0 -7 5 2 Ni-62 0.0 0.0 -8 5 2 Ni-64 0.0 0.0 -9 5 2 Mn-55 0.0 0.0 -10 5 2 Mo-92 0.0 0.0 -11 5 2 Mo-94 0.0 0.0 -12 5 2 Mo-95 0.0 0.0 -13 5 2 Mo-96 0.0 0.0 -14 5 2 Mo-97 0.0 0.0 -15 5 2 Mo-98 0.0 0.0 -16 5 2 Mo-100 0.0 0.0 -17 5 2 Si-28 0.0 0.0 -18 5 2 Si-29 0.0 0.0 -19 5 2 Si-30 0.0 0.0 -20 5 2 Cr-50 0.0 0.0 -21 5 2 Cr-52 0.0 0.0 -22 5 2 Cr-53 0.0 0.0 -23 5 2 Cr-54 0.0 0.0 -24 5 2 C-Nat 0.0 0.0 -25 5 2 Cu-63 0.0 0.0 -26 5 2 Cu-65 0.0 0.0 material group in nuclide mean std. dev. -27 5 1 Fe-54 0.0 0.0 -28 5 1 Fe-56 0.0 0.0 -29 5 1 Fe-57 0.0 0.0 -30 5 1 Fe-58 0.0 0.0 -31 5 1 Ni-58 0.0 0.0 -32 5 1 Ni-60 0.0 0.0 -33 5 1 Ni-61 0.0 0.0 -34 5 1 Ni-62 0.0 0.0 -35 5 1 Ni-64 0.0 0.0 -36 5 1 Mn-55 0.0 0.0 -37 5 1 Mo-92 0.0 0.0 -38 5 1 Mo-94 0.0 0.0 -39 5 1 Mo-95 0.0 0.0 -40 5 1 Mo-96 0.0 0.0 -41 5 1 Mo-97 0.0 0.0 -42 5 1 Mo-98 0.0 0.0 -43 5 1 Mo-100 0.0 0.0 -44 5 1 Si-28 0.0 0.0 -45 5 1 Si-29 0.0 0.0 -46 5 1 Si-30 0.0 0.0 -47 5 1 Cr-50 0.0 0.0 -48 5 1 Cr-52 0.0 0.0 -49 5 1 Cr-53 0.0 0.0 -50 5 1 Cr-54 0.0 0.0 -51 5 1 C-Nat 0.0 0.0 -52 5 1 Cu-63 0.0 0.0 -53 5 1 Cu-65 0.0 0.0 -0 5 2 Fe-54 0.0 0.0 -1 5 2 Fe-56 0.0 0.0 -2 5 2 Fe-57 0.0 0.0 -3 5 2 Fe-58 0.0 0.0 -4 5 2 Ni-58 0.0 0.0 -5 5 2 Ni-60 0.0 0.0 -6 5 2 Ni-61 0.0 0.0 -7 5 2 Ni-62 0.0 0.0 -8 5 2 Ni-64 0.0 0.0 -9 5 2 Mn-55 0.0 0.0 -10 5 2 Mo-92 0.0 0.0 -11 5 2 Mo-94 0.0 0.0 -12 5 2 Mo-95 0.0 0.0 -13 5 2 Mo-96 0.0 0.0 -14 5 2 Mo-97 0.0 0.0 -15 5 2 Mo-98 0.0 0.0 -16 5 2 Mo-100 0.0 0.0 -17 5 2 Si-28 0.0 0.0 -18 5 2 Si-29 0.0 0.0 -19 5 2 Si-30 0.0 0.0 -20 5 2 Cr-50 0.0 0.0 -21 5 2 Cr-52 0.0 0.0 -22 5 2 Cr-53 0.0 0.0 -23 5 2 Cr-54 0.0 0.0 -24 5 2 C-Nat 0.0 0.0 -25 5 2 Cu-63 0.0 0.0 -26 5 2 Cu-65 0.0 0.0 material group in group out nuclide mean std. dev. -81 5 1 1 Fe-54 0.0 0.0 -82 5 1 1 Fe-56 0.0 0.0 -83 5 1 1 Fe-57 0.0 0.0 -84 5 1 1 Fe-58 0.0 0.0 -85 5 1 1 Ni-58 0.0 0.0 -86 5 1 1 Ni-60 0.0 0.0 -87 5 1 1 Ni-61 0.0 0.0 -88 5 1 1 Ni-62 0.0 0.0 -89 5 1 1 Ni-64 0.0 0.0 -90 5 1 1 Mn-55 0.0 0.0 -91 5 1 1 Mo-92 0.0 0.0 -92 5 1 1 Mo-94 0.0 0.0 -93 5 1 1 Mo-95 0.0 0.0 -94 5 1 1 Mo-96 0.0 0.0 -95 5 1 1 Mo-97 0.0 0.0 -96 5 1 1 Mo-98 0.0 0.0 -97 5 1 1 Mo-100 0.0 0.0 -98 5 1 1 Si-28 0.0 0.0 -99 5 1 1 Si-29 0.0 0.0 -100 5 1 1 Si-30 0.0 0.0 -101 5 1 1 Cr-50 0.0 0.0 -102 5 1 1 Cr-52 0.0 0.0 -103 5 1 1 Cr-53 0.0 0.0 -104 5 1 1 Cr-54 0.0 0.0 -105 5 1 1 C-Nat 0.0 0.0 -106 5 1 1 Cu-63 0.0 0.0 -107 5 1 1 Cu-65 0.0 0.0 -54 5 1 2 Fe-54 0.0 0.0 -55 5 1 2 Fe-56 0.0 0.0 -56 5 1 2 Fe-57 0.0 0.0 -57 5 1 2 Fe-58 0.0 0.0 -58 5 1 2 Ni-58 0.0 0.0 -59 5 1 2 Ni-60 0.0 0.0 -60 5 1 2 Ni-61 0.0 0.0 -61 5 1 2 Ni-62 0.0 0.0 -62 5 1 2 Ni-64 0.0 0.0 -63 5 1 2 Mn-55 0.0 0.0 -64 5 1 2 Mo-92 0.0 0.0 -65 5 1 2 Mo-94 0.0 0.0 -66 5 1 2 Mo-95 0.0 0.0 -67 5 1 2 Mo-96 0.0 0.0 -68 5 1 2 Mo-97 0.0 0.0 -69 5 1 2 Mo-98 0.0 0.0 -70 5 1 2 Mo-100 0.0 0.0 -71 5 1 2 Si-28 0.0 0.0 -72 5 1 2 Si-29 0.0 0.0 -73 5 1 2 Si-30 0.0 0.0 -74 5 1 2 Cr-50 0.0 0.0 -75 5 1 2 Cr-52 0.0 0.0 -76 5 1 2 Cr-53 0.0 0.0 -77 5 1 2 Cr-54 0.0 0.0 -78 5 1 2 C-Nat 0.0 0.0 -79 5 1 2 Cu-63 0.0 0.0 -80 5 1 2 Cu-65 0.0 0.0 -27 5 2 1 Fe-54 0.0 0.0 -28 5 2 1 Fe-56 0.0 0.0 -29 5 2 1 Fe-57 0.0 0.0 -30 5 2 1 Fe-58 0.0 0.0 -31 5 2 1 Ni-58 0.0 0.0 -32 5 2 1 Ni-60 0.0 0.0 -33 5 2 1 Ni-61 0.0 0.0 -34 5 2 1 Ni-62 0.0 0.0 -35 5 2 1 Ni-64 0.0 0.0 -36 5 2 1 Mn-55 0.0 0.0 -37 5 2 1 Mo-92 0.0 0.0 -38 5 2 1 Mo-94 0.0 0.0 -39 5 2 1 Mo-95 0.0 0.0 -40 5 2 1 Mo-96 0.0 0.0 -41 5 2 1 Mo-97 0.0 0.0 -42 5 2 1 Mo-98 0.0 0.0 -43 5 2 1 Mo-100 0.0 0.0 -44 5 2 1 Si-28 0.0 0.0 -45 5 2 1 Si-29 0.0 0.0 -46 5 2 1 Si-30 0.0 0.0 -47 5 2 1 Cr-50 0.0 0.0 -48 5 2 1 Cr-52 0.0 0.0 -49 5 2 1 Cr-53 0.0 0.0 -50 5 2 1 Cr-54 0.0 0.0 -51 5 2 1 C-Nat 0.0 0.0 -52 5 2 1 Cu-63 0.0 0.0 -53 5 2 1 Cu-65 0.0 0.0 -0 5 2 2 Fe-54 0.0 0.0 -1 5 2 2 Fe-56 0.0 0.0 -2 5 2 2 Fe-57 0.0 0.0 -3 5 2 2 Fe-58 0.0 0.0 -4 5 2 2 Ni-58 0.0 0.0 -5 5 2 2 Ni-60 0.0 0.0 -6 5 2 2 Ni-61 0.0 0.0 -7 5 2 2 Ni-62 0.0 0.0 -8 5 2 2 Ni-64 0.0 0.0 -9 5 2 2 Mn-55 0.0 0.0 -10 5 2 2 Mo-92 0.0 0.0 -11 5 2 2 Mo-94 0.0 0.0 -12 5 2 2 Mo-95 0.0 0.0 -13 5 2 2 Mo-96 0.0 0.0 -14 5 2 2 Mo-97 0.0 0.0 -15 5 2 2 Mo-98 0.0 0.0 -16 5 2 2 Mo-100 0.0 0.0 -17 5 2 2 Si-28 0.0 0.0 -18 5 2 2 Si-29 0.0 0.0 -19 5 2 2 Si-30 0.0 0.0 -20 5 2 2 Cr-50 0.0 0.0 -21 5 2 2 Cr-52 0.0 0.0 -22 5 2 2 Cr-53 0.0 0.0 -23 5 2 2 Cr-54 0.0 0.0 -24 5 2 2 C-Nat 0.0 0.0 -25 5 2 2 Cu-63 0.0 0.0 -26 5 2 2 Cu-65 0.0 0.0 material group out nuclide mean std. dev. -27 5 1 Fe-54 0.0 0.0 -28 5 1 Fe-56 0.0 0.0 -29 5 1 Fe-57 0.0 0.0 -30 5 1 Fe-58 0.0 0.0 -31 5 1 Ni-58 0.0 0.0 -32 5 1 Ni-60 0.0 0.0 -33 5 1 Ni-61 0.0 0.0 -34 5 1 Ni-62 0.0 0.0 -35 5 1 Ni-64 0.0 0.0 -36 5 1 Mn-55 0.0 0.0 -37 5 1 Mo-92 0.0 0.0 -38 5 1 Mo-94 0.0 0.0 -39 5 1 Mo-95 0.0 0.0 -40 5 1 Mo-96 0.0 0.0 -41 5 1 Mo-97 0.0 0.0 -42 5 1 Mo-98 0.0 0.0 -43 5 1 Mo-100 0.0 0.0 -44 5 1 Si-28 0.0 0.0 -45 5 1 Si-29 0.0 0.0 -46 5 1 Si-30 0.0 0.0 -47 5 1 Cr-50 0.0 0.0 -48 5 1 Cr-52 0.0 0.0 -49 5 1 Cr-53 0.0 0.0 -50 5 1 Cr-54 0.0 0.0 -51 5 1 C-Nat 0.0 0.0 -52 5 1 Cu-63 0.0 0.0 -53 5 1 Cu-65 0.0 0.0 -0 5 2 Fe-54 0.0 0.0 -1 5 2 Fe-56 0.0 0.0 -2 5 2 Fe-57 0.0 0.0 -3 5 2 Fe-58 0.0 0.0 -4 5 2 Ni-58 0.0 0.0 -5 5 2 Ni-60 0.0 0.0 -6 5 2 Ni-61 0.0 0.0 -7 5 2 Ni-62 0.0 0.0 -8 5 2 Ni-64 0.0 0.0 -9 5 2 Mn-55 0.0 0.0 -10 5 2 Mo-92 0.0 0.0 -11 5 2 Mo-94 0.0 0.0 -12 5 2 Mo-95 0.0 0.0 -13 5 2 Mo-96 0.0 0.0 -14 5 2 Mo-97 0.0 0.0 -15 5 2 Mo-98 0.0 0.0 -16 5 2 Mo-100 0.0 0.0 -17 5 2 Si-28 0.0 0.0 -18 5 2 Si-29 0.0 0.0 -19 5 2 Si-30 0.0 0.0 -20 5 2 Cr-50 0.0 0.0 -21 5 2 Cr-52 0.0 0.0 -22 5 2 Cr-53 0.0 0.0 -23 5 2 Cr-54 0.0 0.0 -24 5 2 C-Nat 0.0 0.0 -25 5 2 Cu-63 0.0 0.0 -26 5 2 Cu-65 0.0 0.0 material group in nuclide mean std. dev. -21 6 1 H-1 0.0 0.0 -22 6 1 O-16 0.0 0.0 -23 6 1 B-10 0.0 0.0 -24 6 1 B-11 0.0 0.0 -25 6 1 Fe-54 0.0 0.0 -26 6 1 Fe-56 0.0 0.0 -27 6 1 Fe-57 0.0 0.0 -28 6 1 Fe-58 0.0 0.0 -29 6 1 Ni-58 0.0 0.0 -30 6 1 Ni-60 0.0 0.0 -31 6 1 Ni-61 0.0 0.0 -32 6 1 Ni-62 0.0 0.0 -33 6 1 Ni-64 0.0 0.0 -34 6 1 Mn-55 0.0 0.0 -35 6 1 Si-28 0.0 0.0 -36 6 1 Si-29 0.0 0.0 -37 6 1 Si-30 0.0 0.0 -38 6 1 Cr-50 0.0 0.0 -39 6 1 Cr-52 0.0 0.0 -40 6 1 Cr-53 0.0 0.0 -41 6 1 Cr-54 0.0 0.0 -0 6 2 H-1 0.0 0.0 -1 6 2 O-16 0.0 0.0 -2 6 2 B-10 0.0 0.0 -3 6 2 B-11 0.0 0.0 -4 6 2 Fe-54 0.0 0.0 -5 6 2 Fe-56 0.0 0.0 -6 6 2 Fe-57 0.0 0.0 -7 6 2 Fe-58 0.0 0.0 -8 6 2 Ni-58 0.0 0.0 -9 6 2 Ni-60 0.0 0.0 -10 6 2 Ni-61 0.0 0.0 -11 6 2 Ni-62 0.0 0.0 -12 6 2 Ni-64 0.0 0.0 -13 6 2 Mn-55 0.0 0.0 -14 6 2 Si-28 0.0 0.0 -15 6 2 Si-29 0.0 0.0 -16 6 2 Si-30 0.0 0.0 -17 6 2 Cr-50 0.0 0.0 -18 6 2 Cr-52 0.0 0.0 -19 6 2 Cr-53 0.0 0.0 -20 6 2 Cr-54 0.0 0.0 material group in nuclide mean std. dev. -21 6 1 H-1 0.0 0.0 -22 6 1 O-16 0.0 0.0 -23 6 1 B-10 0.0 0.0 -24 6 1 B-11 0.0 0.0 -25 6 1 Fe-54 0.0 0.0 -26 6 1 Fe-56 0.0 0.0 -27 6 1 Fe-57 0.0 0.0 -28 6 1 Fe-58 0.0 0.0 -29 6 1 Ni-58 0.0 0.0 -30 6 1 Ni-60 0.0 0.0 -31 6 1 Ni-61 0.0 0.0 -32 6 1 Ni-62 0.0 0.0 -33 6 1 Ni-64 0.0 0.0 -34 6 1 Mn-55 0.0 0.0 -35 6 1 Si-28 0.0 0.0 -36 6 1 Si-29 0.0 0.0 -37 6 1 Si-30 0.0 0.0 -38 6 1 Cr-50 0.0 0.0 -39 6 1 Cr-52 0.0 0.0 -40 6 1 Cr-53 0.0 0.0 -41 6 1 Cr-54 0.0 0.0 -0 6 2 H-1 0.0 0.0 -1 6 2 O-16 0.0 0.0 -2 6 2 B-10 0.0 0.0 -3 6 2 B-11 0.0 0.0 -4 6 2 Fe-54 0.0 0.0 -5 6 2 Fe-56 0.0 0.0 -6 6 2 Fe-57 0.0 0.0 -7 6 2 Fe-58 0.0 0.0 -8 6 2 Ni-58 0.0 0.0 -9 6 2 Ni-60 0.0 0.0 -10 6 2 Ni-61 0.0 0.0 -11 6 2 Ni-62 0.0 0.0 -12 6 2 Ni-64 0.0 0.0 -13 6 2 Mn-55 0.0 0.0 -14 6 2 Si-28 0.0 0.0 -15 6 2 Si-29 0.0 0.0 -16 6 2 Si-30 0.0 0.0 -17 6 2 Cr-50 0.0 0.0 -18 6 2 Cr-52 0.0 0.0 -19 6 2 Cr-53 0.0 0.0 -20 6 2 Cr-54 0.0 0.0 material group in group out nuclide mean std. dev. -63 6 1 1 H-1 0.0 0.0 -64 6 1 1 O-16 0.0 0.0 -65 6 1 1 B-10 0.0 0.0 -66 6 1 1 B-11 0.0 0.0 -67 6 1 1 Fe-54 0.0 0.0 -68 6 1 1 Fe-56 0.0 0.0 -69 6 1 1 Fe-57 0.0 0.0 -70 6 1 1 Fe-58 0.0 0.0 -71 6 1 1 Ni-58 0.0 0.0 -72 6 1 1 Ni-60 0.0 0.0 -73 6 1 1 Ni-61 0.0 0.0 -74 6 1 1 Ni-62 0.0 0.0 -75 6 1 1 Ni-64 0.0 0.0 -76 6 1 1 Mn-55 0.0 0.0 -77 6 1 1 Si-28 0.0 0.0 -78 6 1 1 Si-29 0.0 0.0 -79 6 1 1 Si-30 0.0 0.0 -80 6 1 1 Cr-50 0.0 0.0 -81 6 1 1 Cr-52 0.0 0.0 -82 6 1 1 Cr-53 0.0 0.0 -83 6 1 1 Cr-54 0.0 0.0 -42 6 1 2 H-1 0.0 0.0 -43 6 1 2 O-16 0.0 0.0 -44 6 1 2 B-10 0.0 0.0 -45 6 1 2 B-11 0.0 0.0 -46 6 1 2 Fe-54 0.0 0.0 -47 6 1 2 Fe-56 0.0 0.0 -48 6 1 2 Fe-57 0.0 0.0 -49 6 1 2 Fe-58 0.0 0.0 -50 6 1 2 Ni-58 0.0 0.0 -51 6 1 2 Ni-60 0.0 0.0 -52 6 1 2 Ni-61 0.0 0.0 -53 6 1 2 Ni-62 0.0 0.0 -54 6 1 2 Ni-64 0.0 0.0 -55 6 1 2 Mn-55 0.0 0.0 -56 6 1 2 Si-28 0.0 0.0 -57 6 1 2 Si-29 0.0 0.0 -58 6 1 2 Si-30 0.0 0.0 -59 6 1 2 Cr-50 0.0 0.0 -60 6 1 2 Cr-52 0.0 0.0 -61 6 1 2 Cr-53 0.0 0.0 -62 6 1 2 Cr-54 0.0 0.0 -21 6 2 1 H-1 0.0 0.0 -22 6 2 1 O-16 0.0 0.0 -23 6 2 1 B-10 0.0 0.0 -24 6 2 1 B-11 0.0 0.0 -25 6 2 1 Fe-54 0.0 0.0 -26 6 2 1 Fe-56 0.0 0.0 -27 6 2 1 Fe-57 0.0 0.0 -28 6 2 1 Fe-58 0.0 0.0 -29 6 2 1 Ni-58 0.0 0.0 -30 6 2 1 Ni-60 0.0 0.0 -31 6 2 1 Ni-61 0.0 0.0 -32 6 2 1 Ni-62 0.0 0.0 -33 6 2 1 Ni-64 0.0 0.0 -34 6 2 1 Mn-55 0.0 0.0 -35 6 2 1 Si-28 0.0 0.0 -36 6 2 1 Si-29 0.0 0.0 -37 6 2 1 Si-30 0.0 0.0 -38 6 2 1 Cr-50 0.0 0.0 -39 6 2 1 Cr-52 0.0 0.0 -40 6 2 1 Cr-53 0.0 0.0 -41 6 2 1 Cr-54 0.0 0.0 -0 6 2 2 H-1 0.0 0.0 -1 6 2 2 O-16 0.0 0.0 -2 6 2 2 B-10 0.0 0.0 -3 6 2 2 B-11 0.0 0.0 -4 6 2 2 Fe-54 0.0 0.0 -5 6 2 2 Fe-56 0.0 0.0 -6 6 2 2 Fe-57 0.0 0.0 -7 6 2 2 Fe-58 0.0 0.0 -8 6 2 2 Ni-58 0.0 0.0 -9 6 2 2 Ni-60 0.0 0.0 -10 6 2 2 Ni-61 0.0 0.0 -11 6 2 2 Ni-62 0.0 0.0 -12 6 2 2 Ni-64 0.0 0.0 -13 6 2 2 Mn-55 0.0 0.0 -14 6 2 2 Si-28 0.0 0.0 -15 6 2 2 Si-29 0.0 0.0 -16 6 2 2 Si-30 0.0 0.0 -17 6 2 2 Cr-50 0.0 0.0 -18 6 2 2 Cr-52 0.0 0.0 -19 6 2 2 Cr-53 0.0 0.0 -20 6 2 2 Cr-54 0.0 0.0 material group out nuclide mean std. dev. -21 6 1 H-1 0.0 0.0 -22 6 1 O-16 0.0 0.0 -23 6 1 B-10 0.0 0.0 -24 6 1 B-11 0.0 0.0 -25 6 1 Fe-54 0.0 0.0 -26 6 1 Fe-56 0.0 0.0 -27 6 1 Fe-57 0.0 0.0 -28 6 1 Fe-58 0.0 0.0 -29 6 1 Ni-58 0.0 0.0 -30 6 1 Ni-60 0.0 0.0 -31 6 1 Ni-61 0.0 0.0 -32 6 1 Ni-62 0.0 0.0 -33 6 1 Ni-64 0.0 0.0 -34 6 1 Mn-55 0.0 0.0 -35 6 1 Si-28 0.0 0.0 -36 6 1 Si-29 0.0 0.0 -37 6 1 Si-30 0.0 0.0 -38 6 1 Cr-50 0.0 0.0 -39 6 1 Cr-52 0.0 0.0 -40 6 1 Cr-53 0.0 0.0 -41 6 1 Cr-54 0.0 0.0 -0 6 2 H-1 0.0 0.0 -1 6 2 O-16 0.0 0.0 -2 6 2 B-10 0.0 0.0 -3 6 2 B-11 0.0 0.0 -4 6 2 Fe-54 0.0 0.0 -5 6 2 Fe-56 0.0 0.0 -6 6 2 Fe-57 0.0 0.0 -7 6 2 Fe-58 0.0 0.0 -8 6 2 Ni-58 0.0 0.0 -9 6 2 Ni-60 0.0 0.0 -10 6 2 Ni-61 0.0 0.0 -11 6 2 Ni-62 0.0 0.0 -12 6 2 Ni-64 0.0 0.0 -13 6 2 Mn-55 0.0 0.0 -14 6 2 Si-28 0.0 0.0 -15 6 2 Si-29 0.0 0.0 -16 6 2 Si-30 0.0 0.0 -17 6 2 Cr-50 0.0 0.0 -18 6 2 Cr-52 0.0 0.0 -19 6 2 Cr-53 0.0 0.0 -20 6 2 Cr-54 0.0 0.0 material group in nuclide mean std. dev. -21 7 1 H-1 0.0 0.0 -22 7 1 O-16 0.0 0.0 -23 7 1 B-10 0.0 0.0 -24 7 1 B-11 0.0 0.0 -25 7 1 Fe-54 0.0 0.0 -26 7 1 Fe-56 0.0 0.0 -27 7 1 Fe-57 0.0 0.0 -28 7 1 Fe-58 0.0 0.0 -29 7 1 Ni-58 0.0 0.0 -30 7 1 Ni-60 0.0 0.0 -31 7 1 Ni-61 0.0 0.0 -32 7 1 Ni-62 0.0 0.0 -33 7 1 Ni-64 0.0 0.0 -34 7 1 Mn-55 0.0 0.0 -35 7 1 Si-28 0.0 0.0 -36 7 1 Si-29 0.0 0.0 -37 7 1 Si-30 0.0 0.0 -38 7 1 Cr-50 0.0 0.0 -39 7 1 Cr-52 0.0 0.0 -40 7 1 Cr-53 0.0 0.0 -41 7 1 Cr-54 0.0 0.0 -0 7 2 H-1 0.0 0.0 -1 7 2 O-16 0.0 0.0 -2 7 2 B-10 0.0 0.0 -3 7 2 B-11 0.0 0.0 -4 7 2 Fe-54 0.0 0.0 -5 7 2 Fe-56 0.0 0.0 -6 7 2 Fe-57 0.0 0.0 -7 7 2 Fe-58 0.0 0.0 -8 7 2 Ni-58 0.0 0.0 -9 7 2 Ni-60 0.0 0.0 -10 7 2 Ni-61 0.0 0.0 -11 7 2 Ni-62 0.0 0.0 -12 7 2 Ni-64 0.0 0.0 -13 7 2 Mn-55 0.0 0.0 -14 7 2 Si-28 0.0 0.0 -15 7 2 Si-29 0.0 0.0 -16 7 2 Si-30 0.0 0.0 -17 7 2 Cr-50 0.0 0.0 -18 7 2 Cr-52 0.0 0.0 -19 7 2 Cr-53 0.0 0.0 -20 7 2 Cr-54 0.0 0.0 material group in nuclide mean std. dev. -21 7 1 H-1 0.0 0.0 -22 7 1 O-16 0.0 0.0 -23 7 1 B-10 0.0 0.0 -24 7 1 B-11 0.0 0.0 -25 7 1 Fe-54 0.0 0.0 -26 7 1 Fe-56 0.0 0.0 -27 7 1 Fe-57 0.0 0.0 -28 7 1 Fe-58 0.0 0.0 -29 7 1 Ni-58 0.0 0.0 -30 7 1 Ni-60 0.0 0.0 -31 7 1 Ni-61 0.0 0.0 -32 7 1 Ni-62 0.0 0.0 -33 7 1 Ni-64 0.0 0.0 -34 7 1 Mn-55 0.0 0.0 -35 7 1 Si-28 0.0 0.0 -36 7 1 Si-29 0.0 0.0 -37 7 1 Si-30 0.0 0.0 -38 7 1 Cr-50 0.0 0.0 -39 7 1 Cr-52 0.0 0.0 -40 7 1 Cr-53 0.0 0.0 -41 7 1 Cr-54 0.0 0.0 -0 7 2 H-1 0.0 0.0 -1 7 2 O-16 0.0 0.0 -2 7 2 B-10 0.0 0.0 -3 7 2 B-11 0.0 0.0 -4 7 2 Fe-54 0.0 0.0 -5 7 2 Fe-56 0.0 0.0 -6 7 2 Fe-57 0.0 0.0 -7 7 2 Fe-58 0.0 0.0 -8 7 2 Ni-58 0.0 0.0 -9 7 2 Ni-60 0.0 0.0 -10 7 2 Ni-61 0.0 0.0 -11 7 2 Ni-62 0.0 0.0 -12 7 2 Ni-64 0.0 0.0 -13 7 2 Mn-55 0.0 0.0 -14 7 2 Si-28 0.0 0.0 -15 7 2 Si-29 0.0 0.0 -16 7 2 Si-30 0.0 0.0 -17 7 2 Cr-50 0.0 0.0 -18 7 2 Cr-52 0.0 0.0 -19 7 2 Cr-53 0.0 0.0 -20 7 2 Cr-54 0.0 0.0 material group in group out nuclide mean std. dev. -63 7 1 1 H-1 0.0 0.0 -64 7 1 1 O-16 0.0 0.0 -65 7 1 1 B-10 0.0 0.0 -66 7 1 1 B-11 0.0 0.0 -67 7 1 1 Fe-54 0.0 0.0 -68 7 1 1 Fe-56 0.0 0.0 -69 7 1 1 Fe-57 0.0 0.0 -70 7 1 1 Fe-58 0.0 0.0 -71 7 1 1 Ni-58 0.0 0.0 -72 7 1 1 Ni-60 0.0 0.0 -73 7 1 1 Ni-61 0.0 0.0 -74 7 1 1 Ni-62 0.0 0.0 -75 7 1 1 Ni-64 0.0 0.0 -76 7 1 1 Mn-55 0.0 0.0 -77 7 1 1 Si-28 0.0 0.0 -78 7 1 1 Si-29 0.0 0.0 -79 7 1 1 Si-30 0.0 0.0 -80 7 1 1 Cr-50 0.0 0.0 -81 7 1 1 Cr-52 0.0 0.0 -82 7 1 1 Cr-53 0.0 0.0 -83 7 1 1 Cr-54 0.0 0.0 -42 7 1 2 H-1 0.0 0.0 -43 7 1 2 O-16 0.0 0.0 -44 7 1 2 B-10 0.0 0.0 -45 7 1 2 B-11 0.0 0.0 -46 7 1 2 Fe-54 0.0 0.0 -47 7 1 2 Fe-56 0.0 0.0 -48 7 1 2 Fe-57 0.0 0.0 -49 7 1 2 Fe-58 0.0 0.0 -50 7 1 2 Ni-58 0.0 0.0 -51 7 1 2 Ni-60 0.0 0.0 -52 7 1 2 Ni-61 0.0 0.0 -53 7 1 2 Ni-62 0.0 0.0 -54 7 1 2 Ni-64 0.0 0.0 -55 7 1 2 Mn-55 0.0 0.0 -56 7 1 2 Si-28 0.0 0.0 -57 7 1 2 Si-29 0.0 0.0 -58 7 1 2 Si-30 0.0 0.0 -59 7 1 2 Cr-50 0.0 0.0 -60 7 1 2 Cr-52 0.0 0.0 -61 7 1 2 Cr-53 0.0 0.0 -62 7 1 2 Cr-54 0.0 0.0 -21 7 2 1 H-1 0.0 0.0 -22 7 2 1 O-16 0.0 0.0 -23 7 2 1 B-10 0.0 0.0 -24 7 2 1 B-11 0.0 0.0 -25 7 2 1 Fe-54 0.0 0.0 -26 7 2 1 Fe-56 0.0 0.0 -27 7 2 1 Fe-57 0.0 0.0 -28 7 2 1 Fe-58 0.0 0.0 -29 7 2 1 Ni-58 0.0 0.0 -30 7 2 1 Ni-60 0.0 0.0 -31 7 2 1 Ni-61 0.0 0.0 -32 7 2 1 Ni-62 0.0 0.0 -33 7 2 1 Ni-64 0.0 0.0 -34 7 2 1 Mn-55 0.0 0.0 -35 7 2 1 Si-28 0.0 0.0 -36 7 2 1 Si-29 0.0 0.0 -37 7 2 1 Si-30 0.0 0.0 -38 7 2 1 Cr-50 0.0 0.0 -39 7 2 1 Cr-52 0.0 0.0 -40 7 2 1 Cr-53 0.0 0.0 -41 7 2 1 Cr-54 0.0 0.0 -0 7 2 2 H-1 0.0 0.0 -1 7 2 2 O-16 0.0 0.0 -2 7 2 2 B-10 0.0 0.0 -3 7 2 2 B-11 0.0 0.0 -4 7 2 2 Fe-54 0.0 0.0 -5 7 2 2 Fe-56 0.0 0.0 -6 7 2 2 Fe-57 0.0 0.0 -7 7 2 2 Fe-58 0.0 0.0 -8 7 2 2 Ni-58 0.0 0.0 -9 7 2 2 Ni-60 0.0 0.0 -10 7 2 2 Ni-61 0.0 0.0 -11 7 2 2 Ni-62 0.0 0.0 -12 7 2 2 Ni-64 0.0 0.0 -13 7 2 2 Mn-55 0.0 0.0 -14 7 2 2 Si-28 0.0 0.0 -15 7 2 2 Si-29 0.0 0.0 -16 7 2 2 Si-30 0.0 0.0 -17 7 2 2 Cr-50 0.0 0.0 -18 7 2 2 Cr-52 0.0 0.0 -19 7 2 2 Cr-53 0.0 0.0 -20 7 2 2 Cr-54 0.0 0.0 material group out nuclide mean std. dev. -21 7 1 H-1 0.0 0.0 -22 7 1 O-16 0.0 0.0 -23 7 1 B-10 0.0 0.0 -24 7 1 B-11 0.0 0.0 -25 7 1 Fe-54 0.0 0.0 -26 7 1 Fe-56 0.0 0.0 -27 7 1 Fe-57 0.0 0.0 -28 7 1 Fe-58 0.0 0.0 -29 7 1 Ni-58 0.0 0.0 -30 7 1 Ni-60 0.0 0.0 -31 7 1 Ni-61 0.0 0.0 -32 7 1 Ni-62 0.0 0.0 -33 7 1 Ni-64 0.0 0.0 -34 7 1 Mn-55 0.0 0.0 -35 7 1 Si-28 0.0 0.0 -36 7 1 Si-29 0.0 0.0 -37 7 1 Si-30 0.0 0.0 -38 7 1 Cr-50 0.0 0.0 -39 7 1 Cr-52 0.0 0.0 -40 7 1 Cr-53 0.0 0.0 -41 7 1 Cr-54 0.0 0.0 -0 7 2 H-1 0.0 0.0 -1 7 2 O-16 0.0 0.0 -2 7 2 B-10 0.0 0.0 -3 7 2 B-11 0.0 0.0 -4 7 2 Fe-54 0.0 0.0 -5 7 2 Fe-56 0.0 0.0 -6 7 2 Fe-57 0.0 0.0 -7 7 2 Fe-58 0.0 0.0 -8 7 2 Ni-58 0.0 0.0 -9 7 2 Ni-60 0.0 0.0 -10 7 2 Ni-61 0.0 0.0 -11 7 2 Ni-62 0.0 0.0 -12 7 2 Ni-64 0.0 0.0 -13 7 2 Mn-55 0.0 0.0 -14 7 2 Si-28 0.0 0.0 -15 7 2 Si-29 0.0 0.0 -16 7 2 Si-30 0.0 0.0 -17 7 2 Cr-50 0.0 0.0 -18 7 2 Cr-52 0.0 0.0 -19 7 2 Cr-53 0.0 0.0 -20 7 2 Cr-54 0.0 0.0 material group in nuclide mean std. dev. -21 8 1 H-1 0.0 0.0 -22 8 1 O-16 0.0 0.0 -23 8 1 B-10 0.0 0.0 -24 8 1 B-11 0.0 0.0 -25 8 1 Fe-54 0.0 0.0 -26 8 1 Fe-56 0.0 0.0 -27 8 1 Fe-57 0.0 0.0 -28 8 1 Fe-58 0.0 0.0 -29 8 1 Ni-58 0.0 0.0 -30 8 1 Ni-60 0.0 0.0 -31 8 1 Ni-61 0.0 0.0 -32 8 1 Ni-62 0.0 0.0 -33 8 1 Ni-64 0.0 0.0 -34 8 1 Mn-55 0.0 0.0 -35 8 1 Si-28 0.0 0.0 -36 8 1 Si-29 0.0 0.0 -37 8 1 Si-30 0.0 0.0 -38 8 1 Cr-50 0.0 0.0 -39 8 1 Cr-52 0.0 0.0 -40 8 1 Cr-53 0.0 0.0 -41 8 1 Cr-54 0.0 0.0 -0 8 2 H-1 0.0 0.0 -1 8 2 O-16 0.0 0.0 -2 8 2 B-10 0.0 0.0 -3 8 2 B-11 0.0 0.0 -4 8 2 Fe-54 0.0 0.0 -5 8 2 Fe-56 0.0 0.0 -6 8 2 Fe-57 0.0 0.0 -7 8 2 Fe-58 0.0 0.0 -8 8 2 Ni-58 0.0 0.0 -9 8 2 Ni-60 0.0 0.0 -10 8 2 Ni-61 0.0 0.0 -11 8 2 Ni-62 0.0 0.0 -12 8 2 Ni-64 0.0 0.0 -13 8 2 Mn-55 0.0 0.0 -14 8 2 Si-28 0.0 0.0 -15 8 2 Si-29 0.0 0.0 -16 8 2 Si-30 0.0 0.0 -17 8 2 Cr-50 0.0 0.0 -18 8 2 Cr-52 0.0 0.0 -19 8 2 Cr-53 0.0 0.0 -20 8 2 Cr-54 0.0 0.0 material group in nuclide mean std. dev. -21 8 1 H-1 0.0 0.0 -22 8 1 O-16 0.0 0.0 -23 8 1 B-10 0.0 0.0 -24 8 1 B-11 0.0 0.0 -25 8 1 Fe-54 0.0 0.0 -26 8 1 Fe-56 0.0 0.0 -27 8 1 Fe-57 0.0 0.0 -28 8 1 Fe-58 0.0 0.0 -29 8 1 Ni-58 0.0 0.0 -30 8 1 Ni-60 0.0 0.0 -31 8 1 Ni-61 0.0 0.0 -32 8 1 Ni-62 0.0 0.0 -33 8 1 Ni-64 0.0 0.0 -34 8 1 Mn-55 0.0 0.0 -35 8 1 Si-28 0.0 0.0 -36 8 1 Si-29 0.0 0.0 -37 8 1 Si-30 0.0 0.0 -38 8 1 Cr-50 0.0 0.0 -39 8 1 Cr-52 0.0 0.0 -40 8 1 Cr-53 0.0 0.0 -41 8 1 Cr-54 0.0 0.0 -0 8 2 H-1 0.0 0.0 -1 8 2 O-16 0.0 0.0 -2 8 2 B-10 0.0 0.0 -3 8 2 B-11 0.0 0.0 -4 8 2 Fe-54 0.0 0.0 -5 8 2 Fe-56 0.0 0.0 -6 8 2 Fe-57 0.0 0.0 -7 8 2 Fe-58 0.0 0.0 -8 8 2 Ni-58 0.0 0.0 -9 8 2 Ni-60 0.0 0.0 -10 8 2 Ni-61 0.0 0.0 -11 8 2 Ni-62 0.0 0.0 -12 8 2 Ni-64 0.0 0.0 -13 8 2 Mn-55 0.0 0.0 -14 8 2 Si-28 0.0 0.0 -15 8 2 Si-29 0.0 0.0 -16 8 2 Si-30 0.0 0.0 -17 8 2 Cr-50 0.0 0.0 -18 8 2 Cr-52 0.0 0.0 -19 8 2 Cr-53 0.0 0.0 -20 8 2 Cr-54 0.0 0.0 material group in group out nuclide mean std. dev. -63 8 1 1 H-1 0.0 0.0 -64 8 1 1 O-16 0.0 0.0 -65 8 1 1 B-10 0.0 0.0 -66 8 1 1 B-11 0.0 0.0 -67 8 1 1 Fe-54 0.0 0.0 -68 8 1 1 Fe-56 0.0 0.0 -69 8 1 1 Fe-57 0.0 0.0 -70 8 1 1 Fe-58 0.0 0.0 -71 8 1 1 Ni-58 0.0 0.0 -72 8 1 1 Ni-60 0.0 0.0 -73 8 1 1 Ni-61 0.0 0.0 -74 8 1 1 Ni-62 0.0 0.0 -75 8 1 1 Ni-64 0.0 0.0 -76 8 1 1 Mn-55 0.0 0.0 -77 8 1 1 Si-28 0.0 0.0 -78 8 1 1 Si-29 0.0 0.0 -79 8 1 1 Si-30 0.0 0.0 -80 8 1 1 Cr-50 0.0 0.0 -81 8 1 1 Cr-52 0.0 0.0 -82 8 1 1 Cr-53 0.0 0.0 -83 8 1 1 Cr-54 0.0 0.0 -42 8 1 2 H-1 0.0 0.0 -43 8 1 2 O-16 0.0 0.0 -44 8 1 2 B-10 0.0 0.0 -45 8 1 2 B-11 0.0 0.0 -46 8 1 2 Fe-54 0.0 0.0 -47 8 1 2 Fe-56 0.0 0.0 -48 8 1 2 Fe-57 0.0 0.0 -49 8 1 2 Fe-58 0.0 0.0 -50 8 1 2 Ni-58 0.0 0.0 -51 8 1 2 Ni-60 0.0 0.0 -52 8 1 2 Ni-61 0.0 0.0 -53 8 1 2 Ni-62 0.0 0.0 -54 8 1 2 Ni-64 0.0 0.0 -55 8 1 2 Mn-55 0.0 0.0 -56 8 1 2 Si-28 0.0 0.0 -57 8 1 2 Si-29 0.0 0.0 -58 8 1 2 Si-30 0.0 0.0 -59 8 1 2 Cr-50 0.0 0.0 -60 8 1 2 Cr-52 0.0 0.0 -61 8 1 2 Cr-53 0.0 0.0 -62 8 1 2 Cr-54 0.0 0.0 -21 8 2 1 H-1 0.0 0.0 -22 8 2 1 O-16 0.0 0.0 -23 8 2 1 B-10 0.0 0.0 -24 8 2 1 B-11 0.0 0.0 -25 8 2 1 Fe-54 0.0 0.0 -26 8 2 1 Fe-56 0.0 0.0 -27 8 2 1 Fe-57 0.0 0.0 -28 8 2 1 Fe-58 0.0 0.0 -29 8 2 1 Ni-58 0.0 0.0 -30 8 2 1 Ni-60 0.0 0.0 -31 8 2 1 Ni-61 0.0 0.0 -32 8 2 1 Ni-62 0.0 0.0 -33 8 2 1 Ni-64 0.0 0.0 -34 8 2 1 Mn-55 0.0 0.0 -35 8 2 1 Si-28 0.0 0.0 -36 8 2 1 Si-29 0.0 0.0 -37 8 2 1 Si-30 0.0 0.0 -38 8 2 1 Cr-50 0.0 0.0 -39 8 2 1 Cr-52 0.0 0.0 -40 8 2 1 Cr-53 0.0 0.0 -41 8 2 1 Cr-54 0.0 0.0 -0 8 2 2 H-1 0.0 0.0 -1 8 2 2 O-16 0.0 0.0 -2 8 2 2 B-10 0.0 0.0 -3 8 2 2 B-11 0.0 0.0 -4 8 2 2 Fe-54 0.0 0.0 -5 8 2 2 Fe-56 0.0 0.0 -6 8 2 2 Fe-57 0.0 0.0 -7 8 2 2 Fe-58 0.0 0.0 -8 8 2 2 Ni-58 0.0 0.0 -9 8 2 2 Ni-60 0.0 0.0 -10 8 2 2 Ni-61 0.0 0.0 -11 8 2 2 Ni-62 0.0 0.0 -12 8 2 2 Ni-64 0.0 0.0 -13 8 2 2 Mn-55 0.0 0.0 -14 8 2 2 Si-28 0.0 0.0 -15 8 2 2 Si-29 0.0 0.0 -16 8 2 2 Si-30 0.0 0.0 -17 8 2 2 Cr-50 0.0 0.0 -18 8 2 2 Cr-52 0.0 0.0 -19 8 2 2 Cr-53 0.0 0.0 -20 8 2 2 Cr-54 0.0 0.0 material group out nuclide mean std. dev. -21 8 1 H-1 0.0 0.0 -22 8 1 O-16 0.0 0.0 -23 8 1 B-10 0.0 0.0 -24 8 1 B-11 0.0 0.0 -25 8 1 Fe-54 0.0 0.0 -26 8 1 Fe-56 0.0 0.0 -27 8 1 Fe-57 0.0 0.0 -28 8 1 Fe-58 0.0 0.0 -29 8 1 Ni-58 0.0 0.0 -30 8 1 Ni-60 0.0 0.0 -31 8 1 Ni-61 0.0 0.0 -32 8 1 Ni-62 0.0 0.0 -33 8 1 Ni-64 0.0 0.0 -34 8 1 Mn-55 0.0 0.0 -35 8 1 Si-28 0.0 0.0 -36 8 1 Si-29 0.0 0.0 -37 8 1 Si-30 0.0 0.0 -38 8 1 Cr-50 0.0 0.0 -39 8 1 Cr-52 0.0 0.0 -40 8 1 Cr-53 0.0 0.0 -41 8 1 Cr-54 0.0 0.0 -0 8 2 H-1 0.0 0.0 -1 8 2 O-16 0.0 0.0 -2 8 2 B-10 0.0 0.0 -3 8 2 B-11 0.0 0.0 -4 8 2 Fe-54 0.0 0.0 -5 8 2 Fe-56 0.0 0.0 -6 8 2 Fe-57 0.0 0.0 -7 8 2 Fe-58 0.0 0.0 -8 8 2 Ni-58 0.0 0.0 -9 8 2 Ni-60 0.0 0.0 -10 8 2 Ni-61 0.0 0.0 -11 8 2 Ni-62 0.0 0.0 -12 8 2 Ni-64 0.0 0.0 -13 8 2 Mn-55 0.0 0.0 -14 8 2 Si-28 0.0 0.0 -15 8 2 Si-29 0.0 0.0 -16 8 2 Si-30 0.0 0.0 -17 8 2 Cr-50 0.0 0.0 -18 8 2 Cr-52 0.0 0.0 -19 8 2 Cr-53 0.0 0.0 -20 8 2 Cr-54 0.0 0.0 material group in nuclide mean std. dev. -21 9 1 H-1 0.150655 0.480993 -22 9 1 O-16 0.116221 0.114089 -23 9 1 B-10 0.000000 0.000000 -24 9 1 B-11 0.000000 0.000000 -25 9 1 Fe-54 0.000000 0.000000 -26 9 1 Fe-56 0.186217 0.199795 -27 9 1 Fe-57 0.000000 0.000000 -28 9 1 Fe-58 0.000000 0.000000 -29 9 1 Ni-58 0.000000 0.000000 -30 9 1 Ni-60 0.000000 0.000000 -31 9 1 Ni-61 0.000000 0.000000 -32 9 1 Ni-62 0.000000 0.000000 -33 9 1 Ni-64 0.000000 0.000000 -34 9 1 Mn-55 0.000000 0.000000 -35 9 1 Si-28 0.000000 0.000000 -36 9 1 Si-29 0.000000 0.000000 -37 9 1 Si-30 0.000000 0.000000 -38 9 1 Cr-50 0.000000 0.000000 -39 9 1 Cr-52 0.000000 0.000000 -40 9 1 Cr-53 0.147443 0.139574 -41 9 1 Cr-54 0.000000 0.000000 -0 9 2 H-1 0.000000 0.000000 -1 9 2 O-16 0.000000 0.000000 -2 9 2 B-10 0.000000 0.000000 -3 9 2 B-11 0.000000 0.000000 -4 9 2 Fe-54 0.000000 0.000000 -5 9 2 Fe-56 0.000000 0.000000 -6 9 2 Fe-57 0.000000 0.000000 -7 9 2 Fe-58 0.000000 0.000000 -8 9 2 Ni-58 0.000000 0.000000 -9 9 2 Ni-60 0.000000 0.000000 -10 9 2 Ni-61 0.000000 0.000000 -11 9 2 Ni-62 0.000000 0.000000 -12 9 2 Ni-64 0.000000 0.000000 -13 9 2 Mn-55 0.000000 0.000000 -14 9 2 Si-28 0.000000 0.000000 -15 9 2 Si-29 0.000000 0.000000 -16 9 2 Si-30 0.000000 0.000000 -17 9 2 Cr-50 0.000000 0.000000 -18 9 2 Cr-52 0.000000 0.000000 -19 9 2 Cr-53 0.000000 0.000000 -20 9 2 Cr-54 0.000000 0.000000 material group in nuclide mean std. dev. -21 9 1 H-1 0.0 0.0 -22 9 1 O-16 0.0 0.0 -23 9 1 B-10 0.0 0.0 -24 9 1 B-11 0.0 0.0 -25 9 1 Fe-54 0.0 0.0 -26 9 1 Fe-56 0.0 0.0 -27 9 1 Fe-57 0.0 0.0 -28 9 1 Fe-58 0.0 0.0 -29 9 1 Ni-58 0.0 0.0 -30 9 1 Ni-60 0.0 0.0 -31 9 1 Ni-61 0.0 0.0 -32 9 1 Ni-62 0.0 0.0 -33 9 1 Ni-64 0.0 0.0 -34 9 1 Mn-55 0.0 0.0 -35 9 1 Si-28 0.0 0.0 -36 9 1 Si-29 0.0 0.0 -37 9 1 Si-30 0.0 0.0 -38 9 1 Cr-50 0.0 0.0 -39 9 1 Cr-52 0.0 0.0 -40 9 1 Cr-53 0.0 0.0 -41 9 1 Cr-54 0.0 0.0 -0 9 2 H-1 0.0 0.0 -1 9 2 O-16 0.0 0.0 -2 9 2 B-10 0.0 0.0 -3 9 2 B-11 0.0 0.0 -4 9 2 Fe-54 0.0 0.0 -5 9 2 Fe-56 0.0 0.0 -6 9 2 Fe-57 0.0 0.0 -7 9 2 Fe-58 0.0 0.0 -8 9 2 Ni-58 0.0 0.0 -9 9 2 Ni-60 0.0 0.0 -10 9 2 Ni-61 0.0 0.0 -11 9 2 Ni-62 0.0 0.0 -12 9 2 Ni-64 0.0 0.0 -13 9 2 Mn-55 0.0 0.0 -14 9 2 Si-28 0.0 0.0 -15 9 2 Si-29 0.0 0.0 -16 9 2 Si-30 0.0 0.0 -17 9 2 Cr-50 0.0 0.0 -18 9 2 Cr-52 0.0 0.0 -19 9 2 Cr-53 0.0 0.0 -20 9 2 Cr-54 0.0 0.0 material group in group out nuclide mean std. dev. -63 9 1 1 H-1 0.150655 0.480993 -64 9 1 1 O-16 0.116221 0.114089 -65 9 1 1 B-10 0.000000 0.000000 -66 9 1 1 B-11 0.000000 0.000000 -67 9 1 1 Fe-54 0.000000 0.000000 -68 9 1 1 Fe-56 0.186217 0.199795 -69 9 1 1 Fe-57 0.000000 0.000000 -70 9 1 1 Fe-58 0.000000 0.000000 -71 9 1 1 Ni-58 0.000000 0.000000 -72 9 1 1 Ni-60 0.000000 0.000000 -73 9 1 1 Ni-61 0.000000 0.000000 -74 9 1 1 Ni-62 0.000000 0.000000 -75 9 1 1 Ni-64 0.000000 0.000000 -76 9 1 1 Mn-55 0.000000 0.000000 -77 9 1 1 Si-28 0.000000 0.000000 -78 9 1 1 Si-29 0.000000 0.000000 -79 9 1 1 Si-30 0.000000 0.000000 -80 9 1 1 Cr-50 0.000000 0.000000 -81 9 1 1 Cr-52 0.000000 0.000000 -82 9 1 1 Cr-53 0.147443 0.139574 -83 9 1 1 Cr-54 0.000000 0.000000 -42 9 1 2 H-1 0.000000 0.000000 -43 9 1 2 O-16 0.000000 0.000000 -44 9 1 2 B-10 0.000000 0.000000 -45 9 1 2 B-11 0.000000 0.000000 -46 9 1 2 Fe-54 0.000000 0.000000 -47 9 1 2 Fe-56 0.000000 0.000000 -48 9 1 2 Fe-57 0.000000 0.000000 -49 9 1 2 Fe-58 0.000000 0.000000 -50 9 1 2 Ni-58 0.000000 0.000000 -51 9 1 2 Ni-60 0.000000 0.000000 -52 9 1 2 Ni-61 0.000000 0.000000 -53 9 1 2 Ni-62 0.000000 0.000000 -54 9 1 2 Ni-64 0.000000 0.000000 -55 9 1 2 Mn-55 0.000000 0.000000 -56 9 1 2 Si-28 0.000000 0.000000 -57 9 1 2 Si-29 0.000000 0.000000 -58 9 1 2 Si-30 0.000000 0.000000 -59 9 1 2 Cr-50 0.000000 0.000000 -60 9 1 2 Cr-52 0.000000 0.000000 -61 9 1 2 Cr-53 0.000000 0.000000 -62 9 1 2 Cr-54 0.000000 0.000000 -21 9 2 1 H-1 0.000000 0.000000 -22 9 2 1 O-16 0.000000 0.000000 -23 9 2 1 B-10 0.000000 0.000000 -24 9 2 1 B-11 0.000000 0.000000 -25 9 2 1 Fe-54 0.000000 0.000000 -26 9 2 1 Fe-56 0.000000 0.000000 -27 9 2 1 Fe-57 0.000000 0.000000 -28 9 2 1 Fe-58 0.000000 0.000000 -29 9 2 1 Ni-58 0.000000 0.000000 -30 9 2 1 Ni-60 0.000000 0.000000 -31 9 2 1 Ni-61 0.000000 0.000000 -32 9 2 1 Ni-62 0.000000 0.000000 -33 9 2 1 Ni-64 0.000000 0.000000 -34 9 2 1 Mn-55 0.000000 0.000000 -35 9 2 1 Si-28 0.000000 0.000000 -36 9 2 1 Si-29 0.000000 0.000000 -37 9 2 1 Si-30 0.000000 0.000000 -38 9 2 1 Cr-50 0.000000 0.000000 -39 9 2 1 Cr-52 0.000000 0.000000 -40 9 2 1 Cr-53 0.000000 0.000000 -41 9 2 1 Cr-54 0.000000 0.000000 -0 9 2 2 H-1 0.000000 0.000000 -1 9 2 2 O-16 0.000000 0.000000 -2 9 2 2 B-10 0.000000 0.000000 -3 9 2 2 B-11 0.000000 0.000000 -4 9 2 2 Fe-54 0.000000 0.000000 -5 9 2 2 Fe-56 0.000000 0.000000 -6 9 2 2 Fe-57 0.000000 0.000000 -7 9 2 2 Fe-58 0.000000 0.000000 -8 9 2 2 Ni-58 0.000000 0.000000 -9 9 2 2 Ni-60 0.000000 0.000000 -10 9 2 2 Ni-61 0.000000 0.000000 -11 9 2 2 Ni-62 0.000000 0.000000 -12 9 2 2 Ni-64 0.000000 0.000000 -13 9 2 2 Mn-55 0.000000 0.000000 -14 9 2 2 Si-28 0.000000 0.000000 -15 9 2 2 Si-29 0.000000 0.000000 -16 9 2 2 Si-30 0.000000 0.000000 -17 9 2 2 Cr-50 0.000000 0.000000 -18 9 2 2 Cr-52 0.000000 0.000000 -19 9 2 2 Cr-53 0.000000 0.000000 -20 9 2 2 Cr-54 0.000000 0.000000 material group out nuclide mean std. dev. -21 9 1 H-1 0.0 0.0 -22 9 1 O-16 0.0 0.0 -23 9 1 B-10 0.0 0.0 -24 9 1 B-11 0.0 0.0 -25 9 1 Fe-54 0.0 0.0 -26 9 1 Fe-56 0.0 0.0 -27 9 1 Fe-57 0.0 0.0 -28 9 1 Fe-58 0.0 0.0 -29 9 1 Ni-58 0.0 0.0 -30 9 1 Ni-60 0.0 0.0 -31 9 1 Ni-61 0.0 0.0 -32 9 1 Ni-62 0.0 0.0 -33 9 1 Ni-64 0.0 0.0 -34 9 1 Mn-55 0.0 0.0 -35 9 1 Si-28 0.0 0.0 -36 9 1 Si-29 0.0 0.0 -37 9 1 Si-30 0.0 0.0 -38 9 1 Cr-50 0.0 0.0 -39 9 1 Cr-52 0.0 0.0 -40 9 1 Cr-53 0.0 0.0 -41 9 1 Cr-54 0.0 0.0 -0 9 2 H-1 0.0 0.0 -1 9 2 O-16 0.0 0.0 -2 9 2 B-10 0.0 0.0 -3 9 2 B-11 0.0 0.0 -4 9 2 Fe-54 0.0 0.0 -5 9 2 Fe-56 0.0 0.0 -6 9 2 Fe-57 0.0 0.0 -7 9 2 Fe-58 0.0 0.0 -8 9 2 Ni-58 0.0 0.0 -9 9 2 Ni-60 0.0 0.0 -10 9 2 Ni-61 0.0 0.0 -11 9 2 Ni-62 0.0 0.0 -12 9 2 Ni-64 0.0 0.0 -13 9 2 Mn-55 0.0 0.0 -14 9 2 Si-28 0.0 0.0 -15 9 2 Si-29 0.0 0.0 -16 9 2 Si-30 0.0 0.0 -17 9 2 Cr-50 0.0 0.0 -18 9 2 Cr-52 0.0 0.0 -19 9 2 Cr-53 0.0 0.0 -20 9 2 Cr-54 0.0 0.0 material group in nuclide mean std. dev. -21 10 1 H-1 0.123944 0.541390 -22 10 1 O-16 0.000000 0.000000 -23 10 1 B-10 0.000000 0.000000 -24 10 1 B-11 0.000000 0.000000 -25 10 1 Fe-54 0.000000 0.000000 -26 10 1 Fe-56 0.000000 0.000000 -27 10 1 Fe-57 0.000000 0.000000 -28 10 1 Fe-58 0.000000 0.000000 -29 10 1 Ni-58 0.000000 0.000000 -30 10 1 Ni-60 0.000000 0.000000 -31 10 1 Ni-61 0.000000 0.000000 -32 10 1 Ni-62 0.000000 0.000000 -33 10 1 Ni-64 0.000000 0.000000 -34 10 1 Mn-55 0.000000 0.000000 -35 10 1 Si-28 0.000000 0.000000 -36 10 1 Si-29 0.000000 0.000000 -37 10 1 Si-30 0.000000 0.000000 -38 10 1 Cr-50 0.111571 0.138458 -39 10 1 Cr-52 0.000000 0.000000 -40 10 1 Cr-53 0.000000 0.000000 -41 10 1 Cr-54 0.000000 0.000000 -0 10 2 H-1 0.000000 0.000000 -1 10 2 O-16 0.000000 0.000000 -2 10 2 B-10 0.000000 0.000000 -3 10 2 B-11 0.000000 0.000000 -4 10 2 Fe-54 0.000000 0.000000 -5 10 2 Fe-56 0.000000 0.000000 -6 10 2 Fe-57 0.000000 0.000000 -7 10 2 Fe-58 0.000000 0.000000 -8 10 2 Ni-58 0.000000 0.000000 -9 10 2 Ni-60 0.000000 0.000000 -10 10 2 Ni-61 0.000000 0.000000 -11 10 2 Ni-62 0.000000 0.000000 -12 10 2 Ni-64 0.000000 0.000000 -13 10 2 Mn-55 0.000000 0.000000 -14 10 2 Si-28 0.000000 0.000000 -15 10 2 Si-29 0.000000 0.000000 -16 10 2 Si-30 0.000000 0.000000 -17 10 2 Cr-50 0.000000 0.000000 -18 10 2 Cr-52 0.000000 0.000000 -19 10 2 Cr-53 0.000000 0.000000 -20 10 2 Cr-54 0.000000 0.000000 material group in nuclide mean std. dev. -21 10 1 H-1 0.0 0.0 -22 10 1 O-16 0.0 0.0 -23 10 1 B-10 0.0 0.0 -24 10 1 B-11 0.0 0.0 -25 10 1 Fe-54 0.0 0.0 -26 10 1 Fe-56 0.0 0.0 -27 10 1 Fe-57 0.0 0.0 -28 10 1 Fe-58 0.0 0.0 -29 10 1 Ni-58 0.0 0.0 -30 10 1 Ni-60 0.0 0.0 -31 10 1 Ni-61 0.0 0.0 -32 10 1 Ni-62 0.0 0.0 -33 10 1 Ni-64 0.0 0.0 -34 10 1 Mn-55 0.0 0.0 -35 10 1 Si-28 0.0 0.0 -36 10 1 Si-29 0.0 0.0 -37 10 1 Si-30 0.0 0.0 -38 10 1 Cr-50 0.0 0.0 -39 10 1 Cr-52 0.0 0.0 -40 10 1 Cr-53 0.0 0.0 -41 10 1 Cr-54 0.0 0.0 -0 10 2 H-1 0.0 0.0 -1 10 2 O-16 0.0 0.0 -2 10 2 B-10 0.0 0.0 -3 10 2 B-11 0.0 0.0 -4 10 2 Fe-54 0.0 0.0 -5 10 2 Fe-56 0.0 0.0 -6 10 2 Fe-57 0.0 0.0 -7 10 2 Fe-58 0.0 0.0 -8 10 2 Ni-58 0.0 0.0 -9 10 2 Ni-60 0.0 0.0 -10 10 2 Ni-61 0.0 0.0 -11 10 2 Ni-62 0.0 0.0 -12 10 2 Ni-64 0.0 0.0 -13 10 2 Mn-55 0.0 0.0 -14 10 2 Si-28 0.0 0.0 -15 10 2 Si-29 0.0 0.0 -16 10 2 Si-30 0.0 0.0 -17 10 2 Cr-50 0.0 0.0 -18 10 2 Cr-52 0.0 0.0 -19 10 2 Cr-53 0.0 0.0 -20 10 2 Cr-54 0.0 0.0 material group in group out nuclide mean std. dev. -63 10 1 1 H-1 0.123944 0.541390 -64 10 1 1 O-16 0.000000 0.000000 -65 10 1 1 B-10 0.000000 0.000000 -66 10 1 1 B-11 0.000000 0.000000 -67 10 1 1 Fe-54 0.000000 0.000000 -68 10 1 1 Fe-56 0.000000 0.000000 -69 10 1 1 Fe-57 0.000000 0.000000 -70 10 1 1 Fe-58 0.000000 0.000000 -71 10 1 1 Ni-58 0.000000 0.000000 -72 10 1 1 Ni-60 0.000000 0.000000 -73 10 1 1 Ni-61 0.000000 0.000000 -74 10 1 1 Ni-62 0.000000 0.000000 -75 10 1 1 Ni-64 0.000000 0.000000 -76 10 1 1 Mn-55 0.000000 0.000000 -77 10 1 1 Si-28 0.000000 0.000000 -78 10 1 1 Si-29 0.000000 0.000000 -79 10 1 1 Si-30 0.000000 0.000000 -80 10 1 1 Cr-50 0.111571 0.138458 -81 10 1 1 Cr-52 0.000000 0.000000 -82 10 1 1 Cr-53 0.000000 0.000000 -83 10 1 1 Cr-54 0.000000 0.000000 -42 10 1 2 H-1 0.000000 0.000000 -43 10 1 2 O-16 0.000000 0.000000 -44 10 1 2 B-10 0.000000 0.000000 -45 10 1 2 B-11 0.000000 0.000000 -46 10 1 2 Fe-54 0.000000 0.000000 -47 10 1 2 Fe-56 0.000000 0.000000 -48 10 1 2 Fe-57 0.000000 0.000000 -49 10 1 2 Fe-58 0.000000 0.000000 -50 10 1 2 Ni-58 0.000000 0.000000 -51 10 1 2 Ni-60 0.000000 0.000000 -52 10 1 2 Ni-61 0.000000 0.000000 -53 10 1 2 Ni-62 0.000000 0.000000 -54 10 1 2 Ni-64 0.000000 0.000000 -55 10 1 2 Mn-55 0.000000 0.000000 -56 10 1 2 Si-28 0.000000 0.000000 -57 10 1 2 Si-29 0.000000 0.000000 -58 10 1 2 Si-30 0.000000 0.000000 -59 10 1 2 Cr-50 0.000000 0.000000 -60 10 1 2 Cr-52 0.000000 0.000000 -61 10 1 2 Cr-53 0.000000 0.000000 -62 10 1 2 Cr-54 0.000000 0.000000 -21 10 2 1 H-1 0.000000 0.000000 -22 10 2 1 O-16 0.000000 0.000000 -23 10 2 1 B-10 0.000000 0.000000 -24 10 2 1 B-11 0.000000 0.000000 -25 10 2 1 Fe-54 0.000000 0.000000 -26 10 2 1 Fe-56 0.000000 0.000000 -27 10 2 1 Fe-57 0.000000 0.000000 -28 10 2 1 Fe-58 0.000000 0.000000 -29 10 2 1 Ni-58 0.000000 0.000000 -30 10 2 1 Ni-60 0.000000 0.000000 -31 10 2 1 Ni-61 0.000000 0.000000 -32 10 2 1 Ni-62 0.000000 0.000000 -33 10 2 1 Ni-64 0.000000 0.000000 -34 10 2 1 Mn-55 0.000000 0.000000 -35 10 2 1 Si-28 0.000000 0.000000 -36 10 2 1 Si-29 0.000000 0.000000 -37 10 2 1 Si-30 0.000000 0.000000 -38 10 2 1 Cr-50 0.000000 0.000000 -39 10 2 1 Cr-52 0.000000 0.000000 -40 10 2 1 Cr-53 0.000000 0.000000 -41 10 2 1 Cr-54 0.000000 0.000000 -0 10 2 2 H-1 0.000000 0.000000 -1 10 2 2 O-16 0.000000 0.000000 -2 10 2 2 B-10 0.000000 0.000000 -3 10 2 2 B-11 0.000000 0.000000 -4 10 2 2 Fe-54 0.000000 0.000000 -5 10 2 2 Fe-56 0.000000 0.000000 -6 10 2 2 Fe-57 0.000000 0.000000 -7 10 2 2 Fe-58 0.000000 0.000000 -8 10 2 2 Ni-58 0.000000 0.000000 -9 10 2 2 Ni-60 0.000000 0.000000 -10 10 2 2 Ni-61 0.000000 0.000000 -11 10 2 2 Ni-62 0.000000 0.000000 -12 10 2 2 Ni-64 0.000000 0.000000 -13 10 2 2 Mn-55 0.000000 0.000000 -14 10 2 2 Si-28 0.000000 0.000000 -15 10 2 2 Si-29 0.000000 0.000000 -16 10 2 2 Si-30 0.000000 0.000000 -17 10 2 2 Cr-50 0.000000 0.000000 -18 10 2 2 Cr-52 0.000000 0.000000 -19 10 2 2 Cr-53 0.000000 0.000000 -20 10 2 2 Cr-54 0.000000 0.000000 material group out nuclide mean std. dev. -21 10 1 H-1 0.0 0.0 -22 10 1 O-16 0.0 0.0 -23 10 1 B-10 0.0 0.0 -24 10 1 B-11 0.0 0.0 -25 10 1 Fe-54 0.0 0.0 -26 10 1 Fe-56 0.0 0.0 -27 10 1 Fe-57 0.0 0.0 -28 10 1 Fe-58 0.0 0.0 -29 10 1 Ni-58 0.0 0.0 -30 10 1 Ni-60 0.0 0.0 -31 10 1 Ni-61 0.0 0.0 -32 10 1 Ni-62 0.0 0.0 -33 10 1 Ni-64 0.0 0.0 -34 10 1 Mn-55 0.0 0.0 -35 10 1 Si-28 0.0 0.0 -36 10 1 Si-29 0.0 0.0 -37 10 1 Si-30 0.0 0.0 -38 10 1 Cr-50 0.0 0.0 -39 10 1 Cr-52 0.0 0.0 -40 10 1 Cr-53 0.0 0.0 -41 10 1 Cr-54 0.0 0.0 -0 10 2 H-1 0.0 0.0 -1 10 2 O-16 0.0 0.0 -2 10 2 B-10 0.0 0.0 -3 10 2 B-11 0.0 0.0 -4 10 2 Fe-54 0.0 0.0 -5 10 2 Fe-56 0.0 0.0 -6 10 2 Fe-57 0.0 0.0 -7 10 2 Fe-58 0.0 0.0 -8 10 2 Ni-58 0.0 0.0 -9 10 2 Ni-60 0.0 0.0 -10 10 2 Ni-61 0.0 0.0 -11 10 2 Ni-62 0.0 0.0 -12 10 2 Ni-64 0.0 0.0 -13 10 2 Mn-55 0.0 0.0 -14 10 2 Si-28 0.0 0.0 -15 10 2 Si-29 0.0 0.0 -16 10 2 Si-30 0.0 0.0 -17 10 2 Cr-50 0.0 0.0 -18 10 2 Cr-52 0.0 0.0 -19 10 2 Cr-53 0.0 0.0 -20 10 2 Cr-54 0.0 0.0 material group in nuclide mean std. dev. -9 11 1 H-1 0.131470 0.476035 -10 11 1 O-16 0.028684 0.043000 -11 11 1 B-10 0.000000 0.000000 -12 11 1 B-11 0.000000 0.000000 -13 11 1 Zr-90 0.021980 0.039963 -14 11 1 Zr-91 0.000000 0.000000 -15 11 1 Zr-92 0.000000 0.000000 -16 11 1 Zr-94 0.004191 0.087344 -17 11 1 Zr-96 0.000000 0.000000 -0 11 2 H-1 0.687243 1.239217 -1 11 2 O-16 0.000000 0.000000 -2 11 2 B-10 0.042902 0.060672 -3 11 2 B-11 0.000000 0.000000 -4 11 2 Zr-90 0.039576 0.105193 -5 11 2 Zr-91 0.000000 0.000000 -6 11 2 Zr-92 0.084226 0.103161 -7 11 2 Zr-94 0.092039 0.125985 -8 11 2 Zr-96 0.000000 0.000000 material group in nuclide mean std. dev. -9 11 1 H-1 0.0 0.0 -10 11 1 O-16 0.0 0.0 -11 11 1 B-10 0.0 0.0 -12 11 1 B-11 0.0 0.0 -13 11 1 Zr-90 0.0 0.0 -14 11 1 Zr-91 0.0 0.0 -15 11 1 Zr-92 0.0 0.0 -16 11 1 Zr-94 0.0 0.0 -17 11 1 Zr-96 0.0 0.0 -0 11 2 H-1 0.0 0.0 -1 11 2 O-16 0.0 0.0 -2 11 2 B-10 0.0 0.0 -3 11 2 B-11 0.0 0.0 -4 11 2 Zr-90 0.0 0.0 -5 11 2 Zr-91 0.0 0.0 -6 11 2 Zr-92 0.0 0.0 -7 11 2 Zr-94 0.0 0.0 -8 11 2 Zr-96 0.0 0.0 material group in group out nuclide mean std. dev. -27 11 1 1 H-1 0.099594 0.442578 -28 11 1 1 O-16 0.028684 0.043000 -29 11 1 1 B-10 0.000000 0.000000 -30 11 1 1 B-11 0.000000 0.000000 -31 11 1 1 Zr-90 0.021980 0.039963 -32 11 1 1 Zr-91 0.000000 0.000000 -33 11 1 1 Zr-92 0.000000 0.000000 -34 11 1 1 Zr-94 0.004191 0.087344 -35 11 1 1 Zr-96 0.000000 0.000000 -18 11 1 2 H-1 0.031875 0.045078 -19 11 1 2 O-16 0.000000 0.000000 -20 11 1 2 B-10 0.000000 0.000000 -21 11 1 2 B-11 0.000000 0.000000 -22 11 1 2 Zr-90 0.000000 0.000000 -23 11 1 2 Zr-91 0.000000 0.000000 -24 11 1 2 Zr-92 0.000000 0.000000 -25 11 1 2 Zr-94 0.000000 0.000000 -26 11 1 2 Zr-96 0.000000 0.000000 -9 11 2 1 H-1 0.000000 0.000000 -10 11 2 1 O-16 0.000000 0.000000 -11 11 2 1 B-10 0.000000 0.000000 -12 11 2 1 B-11 0.000000 0.000000 -13 11 2 1 Zr-90 0.000000 0.000000 -14 11 2 1 Zr-91 0.000000 0.000000 -15 11 2 1 Zr-92 0.000000 0.000000 -16 11 2 1 Zr-94 0.000000 0.000000 -17 11 2 1 Zr-96 0.000000 0.000000 -0 11 2 2 H-1 0.687243 1.239217 -1 11 2 2 O-16 0.000000 0.000000 -2 11 2 2 B-10 0.000000 0.000000 -3 11 2 2 B-11 0.000000 0.000000 -4 11 2 2 Zr-90 0.039576 0.105193 -5 11 2 2 Zr-91 0.000000 0.000000 -6 11 2 2 Zr-92 0.084226 0.103161 -7 11 2 2 Zr-94 0.092039 0.125985 -8 11 2 2 Zr-96 0.000000 0.000000 material group out nuclide mean std. dev. -9 11 1 H-1 0.0 0.0 -10 11 1 O-16 0.0 0.0 -11 11 1 B-10 0.0 0.0 -12 11 1 B-11 0.0 0.0 -13 11 1 Zr-90 0.0 0.0 -14 11 1 Zr-91 0.0 0.0 -15 11 1 Zr-92 0.0 0.0 -16 11 1 Zr-94 0.0 0.0 -17 11 1 Zr-96 0.0 0.0 -0 11 2 H-1 0.0 0.0 -1 11 2 O-16 0.0 0.0 -2 11 2 B-10 0.0 0.0 -3 11 2 B-11 0.0 0.0 -4 11 2 Zr-90 0.0 0.0 -5 11 2 Zr-91 0.0 0.0 -6 11 2 Zr-92 0.0 0.0 -7 11 2 Zr-94 0.0 0.0 -8 11 2 Zr-96 0.0 0.0 material group in nuclide mean std. dev. -9 12 1 H-1 0.098944 0.178543 -10 12 1 O-16 0.013270 0.020403 -11 12 1 B-10 0.000000 0.000000 -12 12 1 B-11 0.000000 0.000000 -13 12 1 Zr-90 0.089997 0.075538 -14 12 1 Zr-91 0.000000 0.000000 -15 12 1 Zr-92 0.003501 0.017031 -16 12 1 Zr-94 0.004850 0.016327 -17 12 1 Zr-96 0.002730 0.017476 -0 12 2 H-1 1.261686 1.980336 -1 12 2 O-16 0.079159 0.104796 -2 12 2 B-10 0.016928 0.023940 -3 12 2 B-11 0.000000 0.000000 -4 12 2 Zr-90 0.000000 0.000000 -5 12 2 Zr-91 0.033201 0.040665 -6 12 2 Zr-92 0.000000 0.000000 -7 12 2 Zr-94 0.000000 0.000000 -8 12 2 Zr-96 0.000000 0.000000 material group in nuclide mean std. dev. -9 12 1 H-1 0.0 0.0 -10 12 1 O-16 0.0 0.0 -11 12 1 B-10 0.0 0.0 -12 12 1 B-11 0.0 0.0 -13 12 1 Zr-90 0.0 0.0 -14 12 1 Zr-91 0.0 0.0 -15 12 1 Zr-92 0.0 0.0 -16 12 1 Zr-94 0.0 0.0 -17 12 1 Zr-96 0.0 0.0 -0 12 2 H-1 0.0 0.0 -1 12 2 O-16 0.0 0.0 -2 12 2 B-10 0.0 0.0 -3 12 2 B-11 0.0 0.0 -4 12 2 Zr-90 0.0 0.0 -5 12 2 Zr-91 0.0 0.0 -6 12 2 Zr-92 0.0 0.0 -7 12 2 Zr-94 0.0 0.0 -8 12 2 Zr-96 0.0 0.0 material group in group out nuclide mean std. dev. -27 12 1 1 H-1 0.071704 0.167588 -28 12 1 1 O-16 0.013270 0.020403 -29 12 1 1 B-10 0.000000 0.000000 -30 12 1 1 B-11 0.000000 0.000000 -31 12 1 1 Zr-90 0.089997 0.075538 -32 12 1 1 Zr-91 0.000000 0.000000 -33 12 1 1 Zr-92 0.003501 0.017031 -34 12 1 1 Zr-94 0.004850 0.016327 -35 12 1 1 Zr-96 0.002730 0.017476 -18 12 1 2 H-1 0.027240 0.029555 -19 12 1 2 O-16 0.000000 0.000000 -20 12 1 2 B-10 0.000000 0.000000 -21 12 1 2 B-11 0.000000 0.000000 -22 12 1 2 Zr-90 0.000000 0.000000 -23 12 1 2 Zr-91 0.000000 0.000000 -24 12 1 2 Zr-92 0.000000 0.000000 -25 12 1 2 Zr-94 0.000000 0.000000 -26 12 1 2 Zr-96 0.000000 0.000000 -9 12 2 1 H-1 0.000000 0.000000 -10 12 2 1 O-16 0.000000 0.000000 -11 12 2 1 B-10 0.000000 0.000000 -12 12 2 1 B-11 0.000000 0.000000 -13 12 2 1 Zr-90 0.000000 0.000000 -14 12 2 1 Zr-91 0.000000 0.000000 -15 12 2 1 Zr-92 0.000000 0.000000 -16 12 2 1 Zr-94 0.000000 0.000000 -17 12 2 1 Zr-96 0.000000 0.000000 -0 12 2 2 H-1 1.244758 1.956675 -1 12 2 2 O-16 0.079159 0.104796 -2 12 2 2 B-10 0.000000 0.000000 -3 12 2 2 B-11 0.000000 0.000000 -4 12 2 2 Zr-90 0.000000 0.000000 -5 12 2 2 Zr-91 0.033201 0.040665 -6 12 2 2 Zr-92 0.000000 0.000000 -7 12 2 2 Zr-94 0.000000 0.000000 -8 12 2 2 Zr-96 0.000000 0.000000 material group out nuclide mean std. dev. -9 12 1 H-1 0.0 0.0 -10 12 1 O-16 0.0 0.0 -11 12 1 B-10 0.0 0.0 -12 12 1 B-11 0.0 0.0 -13 12 1 Zr-90 0.0 0.0 -14 12 1 Zr-91 0.0 0.0 -15 12 1 Zr-92 0.0 0.0 -16 12 1 Zr-94 0.0 0.0 -17 12 1 Zr-96 0.0 0.0 -0 12 2 H-1 0.0 0.0 -1 12 2 O-16 0.0 0.0 -2 12 2 B-10 0.0 0.0 -3 12 2 B-11 0.0 0.0 -4 12 2 Zr-90 0.0 0.0 -5 12 2 Zr-91 0.0 0.0 -6 12 2 Zr-92 0.0 0.0 -7 12 2 Zr-94 0.0 0.0 -8 12 2 Zr-96 0.0 0.0 \ No newline at end of file +1ee58383dc8ac46c5e0d72321cbc34b0dba531435d5e0e632cbbf9572eb7d669c8c8ad9f370345325afa0bdeb2f818b0f5204b7c4a7c4aaf58ded7acbd715ef8 \ No newline at end of file diff --git a/tests/test_mgxs_library_nuclides/test_mgxs_library_nuclides.py b/tests/test_mgxs_library_nuclides/test_mgxs_library_nuclides.py index 173043cf0..47c1ec60a 100644 --- a/tests/test_mgxs_library_nuclides/test_mgxs_library_nuclides.py +++ b/tests/test_mgxs_library_nuclides/test_mgxs_library_nuclides.py @@ -23,31 +23,27 @@ class MGXSTestHarness(PyAPITestHarness): energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 0.625e-6, 20.]) # Initialize MGXS Library for a few cross section types - self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry.geometry) + self.mgxs_lib = openmc.mgxs.Library(self._input_set.geometry) self.mgxs_lib.by_nuclide = True self.mgxs_lib.mgxs_types = ['transport', 'nu-fission', 'nu-scatter matrix', 'chi'] self.mgxs_lib.energy_groups = energy_groups + self.mgxs_lib.legendre_order = 3 self.mgxs_lib.domain_type = 'material' self.mgxs_lib.build_library() # Initialize a tallies file - self._input_set.tallies = openmc.TalliesFile() + self._input_set.tallies = openmc.Tallies() self.mgxs_lib.add_to_tallies_file(self._input_set.tallies, merge=False) self._input_set.tallies.export_to_xml() - def _get_results(self, hash_output=False): + def _get_results(self, hash_output=True): """Digest info in the statepoint and return as a string.""" # Read the statepoint file. statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] sp = openmc.StatePoint(statepoint) - # Read the summary file. - summary = glob.glob(os.path.join(os.getcwd(), 'summary.h5'))[0] - su = openmc.Summary(summary) - sp.link_with_summary(su) - # Load the MGXS library from the statepoint self.mgxs_lib.load_from_statepoint(sp) diff --git a/tests/test_multipole/inputs_true.dat b/tests/test_multipole/inputs_true.dat index 04fc11746..5890332ed 100644 --- a/tests/test_multipole/inputs_true.dat +++ b/tests/test_multipole/inputs_true.dat @@ -1 +1 @@ -7658bebe2b6f93feae06417a05bfd4bbbfca668eebd100d976543326439b82d16ea23752ac0537284e1839d9681714df116828daf30857bc83e86cc67e4550d7 \ No newline at end of file +28df9e4c4729798d35741e6e9a4f910f3386c831acc54325d0e583bd989065a487cea6981068d8669bc80c3388b166c002c2127446936733f8f3f0da3e154bae \ No newline at end of file diff --git a/tests/test_multipole/results_true.dat b/tests/test_multipole/results_true.dat index 83d7e762e..2c2b879fe 100644 --- a/tests/test_multipole/results_true.dat +++ b/tests/test_multipole/results_true.dat @@ -1,5 +1,5 @@ k-combined: -1.457760E+00 1.119659E-02 +1.457760E+00 1.119656E-02 Cell ID = 11 Name = diff --git a/tests/test_multipole/test_multipole.py b/tests/test_multipole/test_multipole.py index f1deb92cb..7c3615ad7 100644 --- a/tests/test_multipole/test_multipole.py +++ b/tests/test_multipole/test_multipole.py @@ -23,9 +23,8 @@ class MultipoleTestHarness(PyAPITestHarness): dense_fuel.set_density('g/cc', 4.5) dense_fuel.add_nuclide('U-235', 1.0) - mats_file = openmc.MaterialsFile() + mats_file = openmc.Materials([moderator, dense_fuel]) mats_file.default_xs = '71c' - mats_file.add_materials([moderator, dense_fuel]) mats_file.export_to_xml() @@ -70,16 +69,14 @@ class MultipoleTestHarness(PyAPITestHarness): geometry = openmc.Geometry() geometry.root_universe = root_univ - geo_file = openmc.GeometryFile() - geo_file.geometry = geometry - geo_file.export_to_xml() + geometry.export_to_xml() #################### # Settings #################### - sets_file = openmc.SettingsFile() + sets_file = openmc.Settings() sets_file.batches = 5 sets_file.inactive = 0 sets_file.particles = 1000 @@ -93,7 +90,7 @@ class MultipoleTestHarness(PyAPITestHarness): # Plots #################### - plots_file = openmc.PlotsFile() + plots_file = openmc.Plots() plot = openmc.Plot(plot_id=1) plot.basis = 'xy' @@ -102,7 +99,7 @@ class MultipoleTestHarness(PyAPITestHarness): plot.origin = (0, 0, 0) plot.width = (7, 7) plot.pixels = (400, 400) - plots_file.add_plot(plot) + plots_file.append(plot) plot = openmc.Plot(plot_id=2) plot.basis = 'xy' @@ -111,7 +108,7 @@ class MultipoleTestHarness(PyAPITestHarness): plot.origin = (0, 0, 0) plot.width = (7, 7) plot.pixels = (400, 400) - plots_file.add_plot(plot) + plots_file.append(plot) plots_file.export_to_xml() diff --git a/tests/test_plot/test_plot.py b/tests/test_plot/test_plot.py index 015577d21..606a1fd64 100644 --- a/tests/test_plot/test_plot.py +++ b/tests/test_plot/test_plot.py @@ -9,7 +9,7 @@ from testing_harness import TestHarness import h5py -from openmc import Executor +import openmc class PlotTestHarness(TestHarness): @@ -19,8 +19,7 @@ class PlotTestHarness(TestHarness): self._plot_names = plot_names def _run_openmc(self): - executor = Executor() - returncode = executor.plot_geometry(openmc_exec=self._opts.exe) + returncode = openmc.plot_geometry(openmc_exec=self._opts.exe) assert returncode == 0, 'OpenMC did not exit successfully.' def _test_output_created(self): diff --git a/tests/test_resonance_scattering/test_resonance_scattering.py b/tests/test_resonance_scattering/test_resonance_scattering.py index d977488bf..b752cf7f3 100644 --- a/tests/test_resonance_scattering/test_resonance_scattering.py +++ b/tests/test_resonance_scattering/test_resonance_scattering.py @@ -17,9 +17,8 @@ class ResonanceScatteringTestHarness(PyAPITestHarness): mat.add_nuclide('Pu-239', 0.02) mat.add_nuclide('H-1', 20.0) - mats_file = openmc.MaterialsFile() + mats_file = openmc.Materials([mat]) mats_file.default_xs = '71c' - mats_file.add_material(mat) mats_file.export_to_xml() # Geometry @@ -35,9 +34,7 @@ class ResonanceScatteringTestHarness(PyAPITestHarness): geometry = openmc.Geometry() geometry.root_universe = root_univ - geo_file = openmc.GeometryFile() - geo_file.geometry = geometry - geo_file.export_to_xml() + geometry.export_to_xml() # Settings nuclide = openmc.Nuclide('U-238', '71c') @@ -67,7 +64,7 @@ class ResonanceScatteringTestHarness(PyAPITestHarness): res_scatt_ares.E_min = 1e-6 res_scatt_ares.E_max = 210e-6 - sets_file = openmc.SettingsFile() + sets_file = openmc.Settings() sets_file.batches = 10 sets_file.inactive = 5 sets_file.particles = 1000 diff --git a/tests/test_source/test_source.py b/tests/test_source/test_source.py index 9d303b06b..0abae4344 100644 --- a/tests/test_source/test_source.py +++ b/tests/test_source/test_source.py @@ -9,8 +9,6 @@ import numpy as np sys.path.insert(0, os.pardir) from testing_harness import PyAPITestHarness import openmc -import openmc.stats -from openmc.source import Source class SourceTestHarness(PyAPITestHarness): @@ -18,8 +16,7 @@ class SourceTestHarness(PyAPITestHarness): mat1 = openmc.Material(material_id=1) mat1.set_density('g/cm3', 4.5) mat1.add_nuclide(openmc.Nuclide('U-235', '71c'), 1.0) - materials = openmc.MaterialsFile() - materials.add_material(mat1) + materials = openmc.Materials([mat1]) materials.export_to_xml() sphere = openmc.Sphere(surface_id=1, R=10.0, boundary_type='vacuum') @@ -31,9 +28,7 @@ class SourceTestHarness(PyAPITestHarness): root.add_cell(inside_sphere) geometry = openmc.Geometry() geometry.root_universe = root - geometry_xml = openmc.GeometryFile() - geometry_xml.geometry = geometry - geometry_xml.export_to_xml() + geometry.export_to_xml() # Create an array of different sources x_dist = openmc.stats.Uniform(-3., 3.) @@ -56,11 +51,11 @@ class SourceTestHarness(PyAPITestHarness): energy2 = openmc.stats.Watt(0.988, 2.249) energy3 = openmc.stats.Tabular(E, p, interpolation='histogram') - source1 = Source(spatial1, angle1, energy1, strength=0.5) - source2 = Source(spatial2, angle2, energy2, strength=0.3) - source3 = Source(spatial3, angle3, energy3, strength=0.2) + source1 = openmc.Source(spatial1, angle1, energy1, strength=0.5) + source2 = openmc.Source(spatial2, angle2, energy2, strength=0.3) + source3 = openmc.Source(spatial3, angle3, energy3, strength=0.2) - settings = openmc.SettingsFile() + settings = openmc.Settings() settings.batches = 10 settings.inactive = 5 settings.particles = 1000 diff --git a/tests/test_statepoint_restart/test_statepoint_restart.py b/tests/test_statepoint_restart/test_statepoint_restart.py index c842689d9..d39bf7cd5 100644 --- a/tests/test_statepoint_restart/test_statepoint_restart.py +++ b/tests/test_statepoint_restart/test_statepoint_restart.py @@ -5,8 +5,7 @@ import os import sys sys.path.insert(0, os.pardir) from testing_harness import TestHarness -from openmc.statepoint import StatePoint -from openmc.executor import Executor +import openmc class StatepointRestartTestHarness(TestHarness): @@ -50,17 +49,15 @@ class StatepointRestartTestHarness(TestHarness): statepoint = statepoint[0] # Run OpenMC - executor = Executor() - if self._opts.mpi_exec is not None: - returncode = executor.run_simulation(mpi_procs=self._opts.mpi_np, - restart_file=statepoint, - openmc_exec=self._opts.exe, - mpi_exec=self._opts.mpi_exec) + returncode = openmc.run(mpi_procs=self._opts.mpi_np, + restart_file=statepoint, + openmc_exec=self._opts.exe, + mpi_exec=self._opts.mpi_exec) else: - returncode = executor.run_simulation(openmc_exec=self._opts.exe, - restart_file=statepoint) + returncode = openmc.run(openmc_exec=self._opts.exe, + restart_file=statepoint) assert returncode == 0, 'OpenMC did not exit successfully.' diff --git a/tests/test_tallies/inputs_true.dat b/tests/test_tallies/inputs_true.dat index 657a9e77d..be789fc83 100644 --- a/tests/test_tallies/inputs_true.dat +++ b/tests/test_tallies/inputs_true.dat @@ -1 +1 @@ -5e168146d91b7b5fadecb80a32df9edc906718fb2d70b68b4c18dbed0641739251a1c16177c9f4d47516dfd528ec930879534292ff0eb82af89eca2c3fa4a3e0 \ No newline at end of file +0597eff3fddbc45a09b5b324c9704e540b694b07c136f2040426fdcfe5ec544f036073e4afa34a5fb0fbd721a4c0a609b9b68bf17ce4ec78302023b46b71930c \ No newline at end of file diff --git a/tests/test_tallies/test_tallies.py b/tests/test_tallies/test_tallies.py index 81e8641de..52d4084fd 100644 --- a/tests/test_tallies/test_tallies.py +++ b/tests/test_tallies/test_tallies.py @@ -4,7 +4,7 @@ import os import sys sys.path.insert(0, os.pardir) from testing_harness import PyAPITestHarness -from openmc import Filter, Mesh, Tally, TalliesFile +from openmc import Filter, Mesh, Tally, Tallies from openmc.source import Source from openmc.stats import Box @@ -42,7 +42,8 @@ class TalliesTestHarness(PyAPITestHarness): mesh_2x2.lower_left = [-182.07, -182.07] mesh_2x2.upper_right = [182.07, 182.07] mesh_2x2.dimension = [2, 2] - mesh_filter = Filter(type='mesh', bins=(1,)) + mesh_filter = Filter(type='mesh') + mesh_filter.mesh = mesh_2x2 azimuthal_tally4 = Tally() azimuthal_tally4.filters = [azimuthal_filter2, mesh_filter] azimuthal_tally4.scores = ['flux'] @@ -170,33 +171,19 @@ class TalliesTestHarness(PyAPITestHarness): all_nuclide_tallies[0].estimator = 'tracklength' all_nuclide_tallies[0].estimator = 'collision' - self._input_set.tallies = TalliesFile() - self._input_set.tallies.add_tally(azimuthal_tally1) - self._input_set.tallies.add_tally(azimuthal_tally2) - self._input_set.tallies.add_tally(azimuthal_tally3) - self._input_set.tallies.add_tally(azimuthal_tally4) - self._input_set.tallies.add_tally(cellborn_tally) - self._input_set.tallies.add_tally(dg_tally) - self._input_set.tallies.add_tally(energy_tally) - self._input_set.tallies.add_tally(energyout_tally) - self._input_set.tallies.add_tally(transfer_tally) - self._input_set.tallies.add_tally(material_tally) - self._input_set.tallies.add_tally(mu_tally1) - self._input_set.tallies.add_tally(mu_tally2) - self._input_set.tallies.add_tally(mu_tally3) - self._input_set.tallies.add_tally(polar_tally1) - self._input_set.tallies.add_tally(polar_tally2) - self._input_set.tallies.add_tally(polar_tally3) - self._input_set.tallies.add_tally(polar_tally4) - self._input_set.tallies.add_tally(universe_tally) - [self._input_set.tallies.add_tally(t) for t in score_tallies] - [self._input_set.tallies.add_tally(t) for t in flux_tallies] - self._input_set.tallies.add_tally(scatter_tally1) - self._input_set.tallies.add_tally(scatter_tally2) - [self._input_set.tallies.add_tally(t) for t in total_tallies] - self._input_set.tallies.add_tally(questionable_tally) - [self._input_set.tallies.add_tally(t) for t in all_nuclide_tallies] - self._input_set.tallies.add_mesh(mesh_2x2) + self._input_set.tallies = Tallies() + self._input_set.tallies += ( + [azimuthal_tally1, azimuthal_tally2, azimuthal_tally3, + azimuthal_tally4, cellborn_tally, dg_tally, energy_tally, + energyout_tally, transfer_tally, material_tally, mu_tally1, + mu_tally2, mu_tally3, polar_tally1, polar_tally2, polar_tally3, + polar_tally4, universe_tally]) + self._input_set.tallies += score_tallies + self._input_set.tallies += flux_tallies + self._input_set.tallies += (scatter_tally1, scatter_tally2) + self._input_set.tallies += total_tallies + self._input_set.tallies.append(questionable_tally) + self._input_set.tallies += all_nuclide_tallies self._input_set.export() diff --git a/tests/test_tally_aggregation/inputs_true.dat b/tests/test_tally_aggregation/inputs_true.dat index 7b4276f59..055ac76fd 100644 --- a/tests/test_tally_aggregation/inputs_true.dat +++ b/tests/test_tally_aggregation/inputs_true.dat @@ -1 +1 @@ -530a5e969901e153531f74aed46246b1e8783a0e2f347e472f7554c9970152f45d85499f17d7df9c35c74fed6f78d449aa70bf0c1f8947cd34d3a829483a0055 \ No newline at end of file +f819f1b3564ca1df1e235f120f4bd65003cd80935fa8261f0a5982b7e7ec5b2e7497716673c142fab99f3fb26c174ac7a12e145b9a6f2caf707d2a07702f6eb2 \ No newline at end of file diff --git a/tests/test_tally_aggregation/test_tally_aggregation.py b/tests/test_tally_aggregation/test_tally_aggregation.py index 7d682b698..fdc086e68 100644 --- a/tests/test_tally_aggregation/test_tally_aggregation.py +++ b/tests/test_tally_aggregation/test_tally_aggregation.py @@ -15,9 +15,6 @@ class TallyAggregationTestHarness(PyAPITestHarness): # The summary.h5 file needs to be created to read in the tallies self._input_set.settings.output = {'summary': True} - # Initialize the tallies file - tallies_file = openmc.TalliesFile() - # Initialize the nuclides u235 = openmc.Nuclide('U-235') u238 = openmc.Nuclide('U-238') @@ -33,7 +30,7 @@ class TallyAggregationTestHarness(PyAPITestHarness): tally.filters = [energy_filter, distrib_filter] tally.scores = ['nu-fission', 'total'] tally.nuclides = [u235, u238, pu239] - tallies_file.add_tally(tally) + tallies_file = openmc.Tallies([tally]) # Export tallies to file self._input_set.tallies = tallies_file @@ -46,11 +43,6 @@ class TallyAggregationTestHarness(PyAPITestHarness): statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] sp = openmc.StatePoint(statepoint) - # Read the summary file. - summary = glob.glob(os.path.join(os.getcwd(), 'summary.h5'))[0] - su = openmc.Summary(summary) - sp.link_with_summary(su) - # Extract the tally of interest tally = sp.get_tally(name='distribcell tally') diff --git a/tests/test_tally_arithmetic/inputs_true.dat b/tests/test_tally_arithmetic/inputs_true.dat index 1b6046f1a..d7b854a51 100644 --- a/tests/test_tally_arithmetic/inputs_true.dat +++ b/tests/test_tally_arithmetic/inputs_true.dat @@ -1 +1 @@ -57384883e37964076aa82c19fa542434331cdb09735d710485b5aa0ca3445d543729e40cb9c7b6a70e7101ef186923eb1ff6315c73b01ff257052838add68fc7 \ No newline at end of file +bb7e730630f7bb4694a27fd77c3c0171f70c78df2681acc26b0ef88bcff367523b11335f487b46269325adbcee7faeb756484af64055c3c91b0103f7ed962053 \ No newline at end of file diff --git a/tests/test_tally_arithmetic/test_tally_arithmetic.py b/tests/test_tally_arithmetic/test_tally_arithmetic.py index cf8d012e8..a5919909f 100644 --- a/tests/test_tally_arithmetic/test_tally_arithmetic.py +++ b/tests/test_tally_arithmetic/test_tally_arithmetic.py @@ -16,7 +16,7 @@ class TallyArithmeticTestHarness(PyAPITestHarness): self._input_set.settings.output = {'summary': True} # Initialize the tallies file - tallies_file = openmc.TalliesFile() + tallies_file = openmc.Tallies() # Initialize the nuclides u235 = openmc.Nuclide('U-235') @@ -43,14 +43,13 @@ class TallyArithmeticTestHarness(PyAPITestHarness): tally.filters = [material_filter, energy_filter, distrib_filter] tally.scores = ['nu-fission', 'total'] tally.nuclides = [u235, pu239] - tallies_file.add_tally(tally) + tallies_file.append(tally) tally = openmc.Tally(name='tally 2') tally.filters = [energy_filter, mesh_filter] tally.scores = ['total', 'fission'] tally.nuclides = [u238, u235] - tallies_file.add_tally(tally) - tallies_file.add_mesh(mesh) + tallies_file.append(tally) # Export tallies to file self._input_set.tallies = tallies_file @@ -63,11 +62,6 @@ class TallyArithmeticTestHarness(PyAPITestHarness): statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] sp = openmc.StatePoint(statepoint) - # Read the summary file. - summary = glob.glob(os.path.join(os.getcwd(), 'summary.h5'))[0] - su = openmc.Summary(summary) - sp.link_with_summary(su) - # Load the tallies tally_1 = sp.get_tally(name='tally 1') tally_2 = sp.get_tally(name='tally 2') diff --git a/tests/test_tally_slice_merge/inputs_true.dat b/tests/test_tally_slice_merge/inputs_true.dat index 29f0f1d82..be2ec63dc 100644 --- a/tests/test_tally_slice_merge/inputs_true.dat +++ b/tests/test_tally_slice_merge/inputs_true.dat @@ -1 +1 @@ -8d1ab9e4add51b99045e990ac9c3dad9447e9720d811bc430d4bfdd7c2c035424bcb7750e4a4d0ec0460ea1ef4be46ac58372ed01d55f5d8cfeebbce75559066 \ No newline at end of file +bb4ae3b75445846bd5db05a06cc20e7589990154ccef8302f276cd8356630d585c513ebb6bfa99f9fc93dd2d30c42bfbb67dd3454134f4c9fcb3bac128d1f1c5 \ No newline at end of file diff --git a/tests/test_tally_slice_merge/test_tally_slice_merge.py b/tests/test_tally_slice_merge/test_tally_slice_merge.py index 79acf182d..4dbb993d5 100644 --- a/tests/test_tally_slice_merge/test_tally_slice_merge.py +++ b/tests/test_tally_slice_merge/test_tally_slice_merge.py @@ -17,7 +17,7 @@ class TallySliceMergeTestHarness(PyAPITestHarness): self._input_set.settings.output = {'summary': True} # Initialize the tallies file - tallies_file = openmc.TalliesFile() + tallies_file = openmc.Tallies() # Define nuclides and scores to add to both tallies self.nuclides = ['U-235', 'U-238'] @@ -69,10 +69,8 @@ class TallySliceMergeTestHarness(PyAPITestHarness): for nuclide in self.nuclides: distribcell_tally.add_nuclide(nuclide) - # Add tallies to a TalliesFile - tallies_file = openmc.TalliesFile() - tallies_file.add_tally(tallies[0]) - tallies_file.add_tally(distribcell_tally) + # Add tallies to a Tallies object + tallies_file = openmc.Tallies((tallies[0], distribcell_tally)) # Export tallies to file self._input_set.tallies = tallies_file @@ -85,17 +83,12 @@ class TallySliceMergeTestHarness(PyAPITestHarness): statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] sp = openmc.StatePoint(statepoint) - # Read the summary file. - summary = glob.glob(os.path.join(os.getcwd(), 'summary.h5'))[0] - su = openmc.Summary(summary) - sp.link_with_summary(su) - # Extract the cell tally tallies = [sp.get_tally(name='cell tally')] # Slice the tallies by cell filter bins cell_filter_prod = itertools.product(tallies, self.cell_filters) - tallies = map(lambda tf: tf[0].get_slice(filters=[tf[1].type], + tallies = map(lambda tf: tf[0].get_slice(filters=[tf[1].type], filter_bins=[tf[1].get_bin(0)]), cell_filter_prod) # Slice the tallies by energy filter bins @@ -133,11 +126,11 @@ class TallySliceMergeTestHarness(PyAPITestHarness): # Extract the distribcell tally distribcell_tally = sp.get_tally(name='distribcell tally') - # Sum up a few subdomains from the distribcell tally - sum1 = distribcell_tally.summation(filter_type='distribcell', + # Sum up a few subdomains from the distribcell tally + sum1 = distribcell_tally.summation(filter_type='distribcell', filter_bins=[0,100,2000,30000]) # Sum up a few subdomains from the distribcell tally - sum2 = distribcell_tally.summation(filter_type='distribcell', + sum2 = distribcell_tally.summation(filter_type='distribcell', filter_bins=[500,5000,50000]) # Merge the distribcell tally slices diff --git a/tests/testing_harness.py b/tests/testing_harness.py index 7d6dbc914..78e5553e8 100644 --- a/tests/testing_harness.py +++ b/tests/testing_harness.py @@ -13,9 +13,7 @@ import numpy as np sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from input_set import InputSet, MGInputSet -from openmc.statepoint import StatePoint -from openmc.executor import Executor -import openmc.particle_restart as pr +import openmc class TestHarness(object): @@ -63,15 +61,13 @@ class TestHarness(object): self._cleanup() def _run_openmc(self): - executor = Executor() - if self._opts.mpi_exec is not None: - returncode = executor.run_simulation(mpi_procs=self._opts.mpi_np, - openmc_exec=self._opts.exe, - mpi_exec=self._opts.mpi_exec) + returncode = openmc.run(mpi_procs=self._opts.mpi_np, + openmc_exec=self._opts.exe, + mpi_exec=self._opts.mpi_exec) else: - returncode = executor.run_simulation(openmc_exec=self._opts.exe) + returncode = openmc.run(openmc_exec=self._opts.exe) assert returncode == 0, 'OpenMC did not exit successfully.' @@ -90,7 +86,7 @@ class TestHarness(object): """Digest info in the statepoint and return as a string.""" # Read the statepoint file. statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] - sp = StatePoint(statepoint) + sp = openmc.StatePoint(statepoint) # Write out k-combined. outstr = 'k-combined:\n' @@ -158,7 +154,7 @@ class CMFDTestHarness(TestHarness): """Digest info in the statepoint and return as a string.""" # Read the statepoint file. statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] - sp = StatePoint(statepoint) + sp = openmc.StatePoint(statepoint) # Write out the eigenvalue and tallies. outstr = super(CMFDTestHarness, self)._get_results() @@ -195,13 +191,12 @@ class ParticleRestartTestHarness(TestHarness): 'mpi_exec': self._opts.mpi_exec}) # Initial run - executor = Executor() - returncode = executor.run_simulation(**args) + returncode = openmc.run(**args) assert returncode == 0, 'OpenMC did not exit successfully.' # Run particle restart args.update({'restart_file': self._sp_name}) - returncode = executor.run_simulation(**args) + returncode = openmc.run(**args) assert returncode == 0, 'OpenMC did not exit successfully.' def _test_output_created(self): @@ -216,7 +211,7 @@ class ParticleRestartTestHarness(TestHarness): """Digest info in the statepoint and return as a string.""" # Read the particle restart file. particle = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] - p = pr.Particle(particle) + p = openmc.Particle(particle) # Write out the properties. outstr = ''
energy low [MeV]energy high [MeV]cellnuclidescoremeanstd. dev.
000.06.250000e-0710000total