diff --git a/docs/source/conf.py b/docs/source/conf.py index 22fc13a3f..89dd585d7 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -25,7 +25,7 @@ except ImportError: MOCK_MODULES = ['numpy', 'numpy.polynomial', 'numpy.polynomial.polynomial', - 'h5py', 'pandas', 'uncertainties', 'opencg'] + 'h5py', 'pandas', 'uncertainties', 'openmoc'] sys.modules.update((mod_name, MagicMock()) for mod_name in MOCK_MODULES) import numpy as np diff --git a/docs/source/pythonapi/examples/mdgxs-part-ii.ipynb b/docs/source/pythonapi/examples/mdgxs-part-ii.ipynb index 936cb15cc..cbeb3ea8d 100644 --- a/docs/source/pythonapi/examples/mdgxs-part-ii.ipynb +++ b/docs/source/pythonapi/examples/mdgxs-part-ii.ipynb @@ -49,10 +49,6 @@ "\n", "import openmc\n", "import openmc.mgxs\n", - "import openmoc\n", - "import openmoc.process\n", - "from openmoc.opencg_compatible import get_openmoc_geometry\n", - "from openmoc.materialize import load_openmc_mgxs_lib\n", "\n", "%matplotlib inline" ] diff --git a/docs/source/pythonapi/examples/mgxs-part-i.ipynb b/docs/source/pythonapi/examples/mgxs-part-i.ipynb index 17d64ee2d..c05516a89 100644 --- a/docs/source/pythonapi/examples/mgxs-part-i.ipynb +++ b/docs/source/pythonapi/examples/mgxs-part-i.ipynb @@ -524,9 +524,9 @@ " Copyright | 2011-2017 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | 60a1f157dae88b62e1865a5fe3efd7ef0773a068\n", - " Date/Time | 2017-02-25 14:26:54\n", - " OpenMP Threads | 8\n", + " Git SHA1 | 43b141e9ba542da8b28c078cf2df8a6777cfb2ad\n", + " Date/Time | 2017-02-28 11:52:00\n", + " OpenMP Threads | 4\n", "\n", " ===========================================================================\n", " ========================> INITIALIZATION <=========================\n", @@ -536,11 +536,16 @@ " Reading geometry XML file...\n", " Reading materials XML file...\n", " Reading cross sections XML file...\n", - " Reading H1 from /opt/xsdata/nndc/H1.h5\n", - " Reading O16 from /opt/xsdata/nndc/O16.h5\n", - " Reading U235 from /opt/xsdata/nndc/U235.h5\n", - " Reading U238 from /opt/xsdata/nndc/U238.h5\n", - " Reading Zr90 from /opt/xsdata/nndc/Zr90.h5\n", + " Reading H1 from\n", + " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/H1.h5\n", + " Reading O16 from\n", + " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/O16.h5\n", + " Reading U235 from\n", + " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/U235.h5\n", + " Reading U238 from\n", + " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/U238.h5\n", + " Reading Zr90 from\n", + " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/Zr90.h5\n", " Maximum neutron transport energy: 2.00000E+07 eV for H1\n", " Reading tallies XML file...\n", " Building neighboring cells lists for each surface...\n", @@ -611,20 +616,20 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 3.5070E-01 seconds\n", - " Reading cross sections = 2.4151E-01 seconds\n", - " Total time in simulation = 2.3276E+00 seconds\n", - " Time in transport only = 2.2350E+00 seconds\n", - " Time in inactive batches = 2.5677E-01 seconds\n", - " Time in active batches = 2.0708E+00 seconds\n", - " Time synchronizing fission bank = 2.7683E-03 seconds\n", - " Sampling source sites = 2.0233E-03 seconds\n", - " SEND/RECV source sites = 7.1007E-04 seconds\n", - " Time accumulating tallies = 5.0753E-05 seconds\n", - " Total time for finalization = 3.8695E-04 seconds\n", - " Total time elapsed = 2.6857E+00 seconds\n", - " Calculation Rate (inactive) = 97364.6 neutrons/second\n", - " Calculation Rate (active) = 48290.8 neutrons/second\n", + " Total time for initialization = 3.0114E-01 seconds\n", + " Reading cross sections = 1.8743E-01 seconds\n", + " Total time in simulation = 9.7641E+00 seconds\n", + " Time in transport only = 9.5168E+00 seconds\n", + " Time in inactive batches = 1.2602E+00 seconds\n", + " Time in active batches = 8.5039E+00 seconds\n", + " Time synchronizing fission bank = 5.4293E-03 seconds\n", + " Sampling source sites = 4.3508E-03 seconds\n", + " SEND/RECV source sites = 9.9399E-04 seconds\n", + " Time accumulating tallies = 1.2758E-04 seconds\n", + " Total time for finalization = 3.6982E-04 seconds\n", + " Total time elapsed = 1.0075E+01 seconds\n", + " Calculation Rate (inactive) = 19838.7 neutrons/second\n", + " Calculation Rate (active) = 11759.3 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", @@ -905,7 +910,7 @@ " 6.250000e-01\n", " total\n", " (((total / flux) - (absorption / flux)) - (sca...\n", - " -5.551115e-15\n", + " -1.110223e-15\n", " 0.011292\n", " \n", " \n", @@ -915,7 +920,7 @@ " 2.000000e+07\n", " total\n", " (((total / flux) - (absorption / flux)) - (sca...\n", - " -1.110223e-16\n", + " 1.776357e-15\n", " 0.002570\n", " \n", " \n", @@ -928,8 +933,8 @@ "1 1 6.25e-01 2.00e+07 total \n", "\n", " score mean std. dev. \n", - "0 (((total / flux) - (absorption / flux)) - (sca... -5.55e-15 1.13e-02 \n", - "1 (((total / flux) - (absorption / flux)) - (sca... -1.11e-16 2.57e-03 " + "0 (((total / flux) - (absorption / flux)) - (sca... -1.11e-15 1.13e-02 \n", + "1 (((total / flux) - (absorption / flux)) - (sca... 1.78e-15 2.57e-03 " ] }, "execution_count": 22, @@ -1192,7 +1197,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.0" + "version": "3.5.2" } }, "nbformat": 4, diff --git a/docs/source/pythonapi/examples/mgxs-part-ii.ipynb b/docs/source/pythonapi/examples/mgxs-part-ii.ipynb index a0e47fa12..3346027ee 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 the **`openmc.data`** module 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." + "**Note:** This Notebook was created using [OpenMOC](https://mit-crpg.github.io/OpenMOC/) to verify the multi-group cross-sections generated by OpenMC. You must install [OpenMOC](https://mit-crpg.github.io/OpenMOC/) on your system in order to run this Notebook in its entirety. In addition, this Notebook illustrates the use of [Pandas](http://pandas.pydata.org/) `DataFrames` to containerize multi-group cross section data." ] }, { @@ -34,7 +34,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/usr/lib/python3.6/site-packages/matplotlib/__init__.py:1401: UserWarning: This call to matplotlib.use() has no effect\n", + "/home/wbinventor/miniconda3/lib/python3.5/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", @@ -49,12 +49,11 @@ "plt.style.use('seaborn-dark')\n", "\n", "import openmoc\n", - "from openmoc.opencg_compatible import get_openmoc_geometry\n", "\n", "import openmc\n", "import openmc.mgxs as mgxs\n", "import openmc.data\n", - "from openmc.opencg_compatible import get_opencg_geometry\n", + "from openmc.openmoc_compatible import get_openmoc_geometry\n", "\n", "%matplotlib inline" ] @@ -454,9 +453,9 @@ " Copyright | 2011-2017 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | 60a1f157dae88b62e1865a5fe3efd7ef0773a068\n", - " Date/Time | 2017-02-25 14:28:21\n", - " OpenMP Threads | 8\n", + " Git SHA1 | 647bf77a57a3cc5cce24b39cb192e1b99f52e499\n", + " Date/Time | 2017-02-27 13:35:52\n", + " OpenMP Threads | 4\n", "\n", " ===========================================================================\n", " ========================> INITIALIZATION <=========================\n", @@ -466,11 +465,16 @@ " Reading geometry XML file...\n", " Reading materials XML file...\n", " Reading cross sections XML file...\n", - " Reading U235 from /opt/xsdata/nndc/U235.h5\n", - " Reading U238 from /opt/xsdata/nndc/U238.h5\n", - " Reading O16 from /opt/xsdata/nndc/O16.h5\n", - " Reading H1 from /opt/xsdata/nndc/H1.h5\n", - " Reading Zr90 from /opt/xsdata/nndc/Zr90.h5\n", + " Reading U235 from\n", + " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/U235.h5\n", + " Reading U238 from\n", + " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/U238.h5\n", + " Reading O16 from\n", + " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/O16.h5\n", + " Reading H1 from\n", + " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/H1.h5\n", + " Reading Zr90 from\n", + " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/Zr90.h5\n", " Maximum neutron transport energy: 2.00000E+07 eV for U235\n", " Reading tallies XML file...\n", " Building neighboring cells lists for each surface...\n", @@ -532,7 +536,7 @@ " 48/1 1.22204 1.22140 +/- 0.00239\n", " 49/1 1.22077 1.22139 +/- 0.00232\n", " 50/1 1.23166 1.22164 +/- 0.00228\n", - " Triggers unsatisfied, max unc./thresh. is 1.17623 for flux in tally 10050\n", + " Triggers unsatisfied, max unc./thresh. is 1.17623 for flux in tally 10052\n", " The estimated number of batches is 66\n", " Creating state point statepoint.050.h5...\n", " 51/1 1.20071 1.22113 +/- 0.00228\n", @@ -551,7 +555,7 @@ " 64/1 1.23955 1.22122 +/- 0.00200\n", " 65/1 1.21143 1.22104 +/- 0.00197\n", " 66/1 1.21791 1.22099 +/- 0.00194\n", - " Triggers unsatisfied, max unc./thresh. is 1.13207 for flux in tally 10050\n", + " Triggers unsatisfied, max unc./thresh. is 1.13207 for flux in tally 10052\n", " The estimated number of batches is 82\n", " 67/1 1.24897 1.22148 +/- 0.00196\n", " 68/1 1.22221 1.22149 +/- 0.00193\n", @@ -579,20 +583,20 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 3.2089E-01 seconds\n", - " Reading cross sections = 2.2960E-01 seconds\n", - " Total time in simulation = 3.1332E+01 seconds\n", - " Time in transport only = 3.1007E+01 seconds\n", - " Time in inactive batches = 1.6660E+00 seconds\n", - " Time in active batches = 2.9666E+01 seconds\n", - " Time synchronizing fission bank = 1.7043E-02 seconds\n", - " Sampling source sites = 1.1813E-02 seconds\n", - " SEND/RECV source sites = 5.1688E-03 seconds\n", - " Time accumulating tallies = 5.0509E-04 seconds\n", - " Total time for finalization = 1.6880E-02 seconds\n", - " Total time elapsed = 3.1699E+01 seconds\n", - " Calculation Rate (inactive) = 60024.2 neutrons/second\n", - " Calculation Rate (active) = 13483.6 neutrons/second\n", + " Total time for initialization = 4.8359E-01 seconds\n", + " Reading cross sections = 3.0552E-01 seconds\n", + " Total time in simulation = 1.4019E+02 seconds\n", + " Time in transport only = 1.3995E+02 seconds\n", + " Time in inactive batches = 8.5036E+00 seconds\n", + " Time in active batches = 1.3169E+02 seconds\n", + " Time synchronizing fission bank = 2.6010E-02 seconds\n", + " Sampling source sites = 1.8806E-02 seconds\n", + " SEND/RECV source sites = 7.0698E-03 seconds\n", + " Time accumulating tallies = 2.8324E-03 seconds\n", + " Total time for finalization = 2.2540E-02 seconds\n", + " Total time elapsed = 1.4077E+02 seconds\n", + " Calculation Rate (inactive) = 11759.7 neutrons/second\n", + " Calculation Rate (active) = 3037.46 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", @@ -617,7 +621,7 @@ ], "source": [ "# Run OpenMC\n", - "openmc.run(output=True)" + "openmc.run()" ] }, { @@ -733,7 +737,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/home/nelsonag/git/openmc/openmc/tallies.py:1835: RuntimeWarning: invalid value encountered in true_divide\n", + "/home/wbinventor/Documents/NSE-CRPG-Codes/openmc/openmc/tallies.py:1835: RuntimeWarning: invalid value encountered in true_divide\n", " self_rel_err = data['self']['std. dev.'] / data['self']['mean']\n" ] } @@ -803,7 +807,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/home/nelsonag/git/openmc/openmc/tallies.py:1835: RuntimeWarning: invalid value encountered in true_divide\n", + "/home/wbinventor/Documents/NSE-CRPG-Codes/openmc/openmc/tallies.py:1835: RuntimeWarning: invalid value encountered in true_divide\n", " self_rel_err = data['self']['std. dev.'] / data['self']['mean']\n" ] }, @@ -1117,7 +1121,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Now, let's verify our cross sections using OpenMOC. First, we use OpenCG construct an equivalent OpenMOC geometry." + "Now, let's verify our cross sections using OpenMOC. First, we construct an equivalent OpenMOC geometry." ] }, { @@ -1128,9 +1132,8 @@ }, "outputs": [], "source": [ - "# Create an OpenMOC Geometry from an equivalent OpenCG Geometry\n", - "opencg_geometry = get_opencg_geometry(sp.summary.geometry)\n", - "openmoc_geometry = get_openmoc_geometry(opencg_geometry)" + "# Create an OpenMOC Geometry from the OpenMC Geometry\n", + "openmoc_geometry = get_openmoc_geometry(sp.summary.geometry)" ] }, { @@ -1151,11 +1154,11 @@ "name": "stderr", "output_type": "stream", "text": [ - "/home/nelsonag/git/openmc/openmc/tallies.py:1835: RuntimeWarning: invalid value encountered in true_divide\n", + "/home/wbinventor/Documents/NSE-CRPG-Codes/openmc/openmc/tallies.py:1835: 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:1836: RuntimeWarning: invalid value encountered in true_divide\n", + "/home/wbinventor/Documents/NSE-CRPG-Codes/openmc/openmc/tallies.py:1836: 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:1837: RuntimeWarning: invalid value encountered in true_divide\n", + "/home/wbinventor/Documents/NSE-CRPG-Codes/openmc/openmc/tallies.py:1837: RuntimeWarning: invalid value encountered in true_divide\n", " new_tally._mean = data['self']['mean'] / data['other']['mean']\n" ] } @@ -1510,18 +1513,17 @@ "name": "stderr", "output_type": "stream", "text": [ - "/home/nelsonag/git/openmc/openmc/tallies.py:1835: RuntimeWarning: invalid value encountered in true_divide\n", + "/home/wbinventor/Documents/NSE-CRPG-Codes/openmc/openmc/tallies.py:1835: 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:1836: RuntimeWarning: invalid value encountered in true_divide\n", + "/home/wbinventor/Documents/NSE-CRPG-Codes/openmc/openmc/tallies.py:1836: 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:1837: RuntimeWarning: invalid value encountered in true_divide\n", + "/home/wbinventor/Documents/NSE-CRPG-Codes/openmc/openmc/tallies.py:1837: RuntimeWarning: invalid value encountered in true_divide\n", " new_tally._mean = data['self']['mean'] / data['other']['mean']\n" ] } ], "source": [ - "opencg_geometry = get_opencg_geometry(sp.summary.geometry)\n", - "openmoc_geometry = get_openmoc_geometry(opencg_geometry)\n", + "openmoc_geometry = get_openmoc_geometry(sp.summary.geometry)\n", "openmoc_cells = openmoc_geometry.getRootUniverse().getAllCells()\n", "\n", "# Inject multi-group cross sections into OpenMOC Materials\n", @@ -1990,7 +1992,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/home/nelsonag/git/openmc/openmc/tallies.py:1835: RuntimeWarning: invalid value encountered in true_divide\n", + "/home/wbinventor/Documents/NSE-CRPG-Codes/openmc/openmc/tallies.py:1835: RuntimeWarning: invalid value encountered in true_divide\n", " self_rel_err = data['self']['std. dev.'] / data['self']['mean']\n" ] }, @@ -2006,9 +2008,9 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -2091,9 +2093,9 @@ "outputs": [ { "data": { - "image/png": "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\n4C3won+7HwAAAABJRU5ErkJggg==\n", + "image/png": "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\niTQvPToippHm9Xci7Wy9n7Tf5sI2flWNPH+LNG10bkTcRfqMzqL3mtAzz/8iSc2vSbqHNJJ/iLQD\n+XLS52dKHvTcBDwZERv00kbj+QHAdEnX5L/B9/K/0nT5eurznrwl8TtJvR39YFYLeUQ9E1hc0sy5\n3Z9OqeNI3XrIm+3TGpu5pL38U+dmn8zKEBG3RURjX9TOwIPzUkEHj9TnGZGOBT+etN/gGdIx5n0d\nLmY2JEXEWNKhgwuRdpz+q6Q7526vOstF3cysRjz9YmZWI3P9OPWuOwd2tEp/Vvn4/UWF4tEpa895\nJRsSuscN+HpAgzaeqwrL6yldK8x5pZZdNOdVbMjo7p70vtz2SN3MrEZc1M3MasRF3cysRlzUzcxq\npPQdpRFxCuna0LOAQyTdUXabZmVzXltVlTpSzxfWWU3SWNL1snu7qYPZkOK8tiore/plU/KdRCT9\nCVg8X5fYbChzXltllV3Ul2H2u7e8kJeZDWXOa6usTu8o7fhJIGYd4Ly2yii7qE9n9hHMcqSLSZkN\nZc5rq6yyi/o1pDt0ExFjgGmNe3eaDWHOa6usUou6pKnAnRFxE3+/dZnZkOa8tior/Th1SYeX3YZZ\npzmvrap8RqmZWY24qJuZ1YiLuplZjbiom5nVyFy/8xGvFhdqUYq7afiG464rLNbUKZsUFsuGhild\ntxQW6yi2LizW0ZxcWKzklYLj2WB5pG5mViMu6mZmNeKibmZWIy7qZmY14qJuZlYjpRf1iFgnIh6O\niAPKbsusk5zbVkVl385uEdKtviaX2Y5Zpzm3rarKHqm/AWyNrzVt9ePctkoq+9K7syS9WWYbZnOD\nc9uqyjtKzcxqxEXdzKxGOlnUfXNeqyvntlVGqRf0yvdvPBlYEXg7InYEPifp5TLbNSubc9uqqtSi\nLukuYOMy2zCbG5zbVlWeUzczqxEXdTOzGnFRNzOrERd1M7Mamfu3syvQPVM2KCzWf437j8JivTtu\n/sJi3XbruMJiAfBORWPZe47mqMJiHcuhhcUCOKLQ2+P51nhF8EjdzKxGXNTNzGrERd3MrEZc1M3M\nasRF3cysRko/+iUiTgQ+DcwPHC/p0rLbNCub89qqquzb2Y0H1pI0lnSXmFPLbM+sE5zXVmVlT79M\nAXbKj18GFokIX6bUhjrntVVW2Vdp7AZez0/3BX6dl5kNWc5rq7KOnFEaEROAvYEtOtGeWSc4r62K\n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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -2137,7 +2139,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.0" + "version": "3.5.2" } }, "nbformat": 4, diff --git a/docs/source/pythonapi/examples/mgxs-part-iii.ipynb b/docs/source/pythonapi/examples/mgxs-part-iii.ipynb index a41fb1374..58c137608 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." + "**Note:** This Notebook was created using [OpenMOC](https://mit-crpg.github.io/OpenMOC/) to verify the multi-group cross-sections generated by OpenMC. You must install [OpenMOC](https://mit-crpg.github.io/OpenMOC/) on your system to run this Notebook in its entirety. 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/lib/python3.6/site-packages/matplotlib/__init__.py:1401: UserWarning: This call to matplotlib.use() has no effect\n", + "/home/wbinventor/miniconda3/lib/python3.5/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", @@ -51,10 +51,9 @@ "\n", "import openmc\n", "import openmc.mgxs\n", - "from openmc.opencg_compatible import get_opencg_geometry\n", + "from openmc.openmoc_compatible import get_openmoc_geometry\n", "import openmoc\n", "import openmoc.process\n", - "from openmoc.opencg_compatible import get_openmoc_geometry\n", "from openmoc.materialize import load_openmc_mgxs_lib\n", "\n", "%matplotlib inline" @@ -458,7 +457,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "" ] @@ -739,9 +738,9 @@ " Copyright | 2011-2017 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | 60a1f157dae88b62e1865a5fe3efd7ef0773a068\n", - " Date/Time | 2017-02-25 14:32:59\n", - " OpenMP Threads | 8\n", + " Git SHA1 | 647bf77a57a3cc5cce24b39cb192e1b99f52e499\n", + " Date/Time | 2017-02-27 14:21:38\n", + " OpenMP Threads | 4\n", "\n", " ===========================================================================\n", " ========================> INITIALIZATION <=========================\n", @@ -751,12 +750,18 @@ " Reading geometry XML file...\n", " Reading materials XML file...\n", " Reading cross sections XML file...\n", - " Reading U235 from /opt/xsdata/nndc/U235.h5\n", - " Reading U238 from /opt/xsdata/nndc/U238.h5\n", - " Reading O16 from /opt/xsdata/nndc/O16.h5\n", - " Reading H1 from /opt/xsdata/nndc/H1.h5\n", - " Reading B10 from /opt/xsdata/nndc/B10.h5\n", - " Reading Zr90 from /opt/xsdata/nndc/Zr90.h5\n", + " Reading U235 from\n", + " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/U235.h5\n", + " Reading U238 from\n", + " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/U238.h5\n", + " Reading O16 from\n", + " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/O16.h5\n", + " Reading H1 from\n", + " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/H1.h5\n", + " Reading B10 from\n", + " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/B10.h5\n", + " Reading Zr90 from\n", + " /home/wbinventor/Documents/NSE-CRPG-Codes/openmc/data/nndc_hdf5/Zr90.h5\n", " Maximum neutron transport energy: 2.00000E+07 eV for U235\n", " Reading tallies XML file...\n", " Building neighboring cells lists for each surface...\n", @@ -827,20 +832,20 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 3.4863E-01 seconds\n", - " Reading cross sections = 2.6337E-01 seconds\n", - " Total time in simulation = 6.2906E+00 seconds\n", - " Time in transport only = 6.0984E+00 seconds\n", - " Time in inactive batches = 5.0785E-01 seconds\n", - " Time in active batches = 5.7827E+00 seconds\n", - " Time synchronizing fission bank = 2.6573E-03 seconds\n", - " Sampling source sites = 1.9038E-03 seconds\n", - " SEND/RECV source sites = 7.1726E-04 seconds\n", - " Time accumulating tallies = 2.9242E-04 seconds\n", - " Total time for finalization = 7.4980E-06 seconds\n", - " Total time elapsed = 6.6484E+00 seconds\n", - " Calculation Rate (inactive) = 49227.5 neutrons/second\n", - " Calculation Rate (active) = 17292.9 neutrons/second\n", + " Total time for initialization = 3.4887E-01 seconds\n", + " Reading cross sections = 2.1990E-01 seconds\n", + " Total time in simulation = 3.2195E+01 seconds\n", + " Time in transport only = 3.1778E+01 seconds\n", + " Time in inactive batches = 1.9903E+00 seconds\n", + " Time in active batches = 3.0205E+01 seconds\n", + " Time synchronizing fission bank = 5.9614E-03 seconds\n", + " Sampling source sites = 4.8344E-03 seconds\n", + " SEND/RECV source sites = 1.0392E-03 seconds\n", + " Time accumulating tallies = 1.5849E-03 seconds\n", + " Total time for finalization = 3.9664E-05 seconds\n", + " Total time elapsed = 3.2560E+01 seconds\n", + " Calculation Rate (inactive) = 12561.1 neutrons/second\n", + " Calculation Rate (active) = 3310.69 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", @@ -967,7 +972,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/home/nelsonag/git/openmc/openmc/tallies.py:1835: RuntimeWarning: invalid value encountered in true_divide\n", + "/home/wbinventor/Documents/NSE-CRPG-Codes/openmc/openmc/tallies.py:1835: RuntimeWarning: invalid value encountered in true_divide\n", " self_rel_err = data['self']['std. dev.'] / data['self']['mean']\n" ] }, @@ -1104,7 +1109,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/home/nelsonag/git/openmc/openmc/tallies.py:1506: RuntimeWarning: invalid value encountered in true_divide\n", + "/home/wbinventor/Documents/NSE-CRPG-Codes/openmc/openmc/tallies.py:1506: RuntimeWarning: invalid value encountered in true_divide\n", " data = self.std_dev[indices] / self.mean[indices]\n" ] } @@ -1131,11 +1136,11 @@ "name": "stderr", "output_type": "stream", "text": [ - "/home/nelsonag/git/openmc/openmc/tallies.py:1835: RuntimeWarning: invalid value encountered in true_divide\n", + "/home/wbinventor/Documents/NSE-CRPG-Codes/openmc/openmc/tallies.py:1835: 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:1836: RuntimeWarning: invalid value encountered in true_divide\n", + "/home/wbinventor/Documents/NSE-CRPG-Codes/openmc/openmc/tallies.py:1836: 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:1837: RuntimeWarning: invalid value encountered in true_divide\n", + "/home/wbinventor/Documents/NSE-CRPG-Codes/openmc/openmc/tallies.py:1837: RuntimeWarning: invalid value encountered in true_divide\n", " new_tally._mean = data['self']['mean'] / data['other']['mean']\n" ] } @@ -1209,7 +1214,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/home/nelsonag/git/openmc/openmc/tallies.py:1835: RuntimeWarning: invalid value encountered in true_divide\n", + "/home/wbinventor/Documents/NSE-CRPG-Codes/openmc/openmc/tallies.py:1835: RuntimeWarning: invalid value encountered in true_divide\n", " self_rel_err = data['self']['std. dev.'] / data['self']['mean']\n" ] }, @@ -1288,7 +1293,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Of course it is always a good idea to verify that one's cross sections are accurate. We can easily do so here with the deterministic transport code [OpenMOC](https://mit-crpg.github.io/OpenMOC/). We will extract an OpenCG geometry from the summary file and convert it into an equivalent OpenMOC geometry." + "Of course it is always a good idea to verify that one's cross sections are accurate. We can easily do so here with the deterministic transport code [OpenMOC](https://mit-crpg.github.io/OpenMOC/). We first construct an equivalent OpenMOC geometry." ] }, { @@ -1299,9 +1304,8 @@ }, "outputs": [], "source": [ - "# Create an OpenMOC Geometry from an equivalent OpenCG Geometry\n", - "opencg_geometry = get_opencg_geometry(mgxs_lib.geometry)\n", - "openmoc_geometry = get_openmoc_geometry(opencg_geometry)" + "# Create an OpenMOC Geometry from the OpenMC Geometry\n", + "openmoc_geometry = get_openmoc_geometry(mgxs_lib.geometry)" ] }, { @@ -1322,11 +1326,11 @@ "name": "stderr", "output_type": "stream", "text": [ - "/home/nelsonag/git/openmc/openmc/tallies.py:1835: RuntimeWarning: invalid value encountered in true_divide\n", + "/home/wbinventor/Documents/NSE-CRPG-Codes/openmc/openmc/tallies.py:1835: 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:1836: RuntimeWarning: invalid value encountered in true_divide\n", + "/home/wbinventor/Documents/NSE-CRPG-Codes/openmc/openmc/tallies.py:1836: 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:1837: RuntimeWarning: invalid value encountered in true_divide\n", + "/home/wbinventor/Documents/NSE-CRPG-Codes/openmc/openmc/tallies.py:1837: RuntimeWarning: invalid value encountered in true_divide\n", " new_tally._mean = data['self']['mean'] / data['other']['mean']\n" ] } @@ -1450,37 +1454,37 @@ "[ NORMAL ] Iteration 90:\tk_eff = 1.023226\tres = 1.493E-04\n", "[ NORMAL ] Iteration 91:\tk_eff = 1.023356\tres = 1.382E-04\n", "[ NORMAL ] Iteration 92:\tk_eff = 1.023477\tres = 1.279E-04\n", - "[ NORMAL ] Iteration 93:\tk_eff = 1.023589\tres = 1.184E-04\n", - "[ NORMAL ] Iteration 94:\tk_eff = 1.023692\tres = 1.096E-04\n", + "[ NORMAL ] Iteration 93:\tk_eff = 1.023588\tres = 1.184E-04\n", + "[ NORMAL ] Iteration 94:\tk_eff = 1.023692\tres = 1.097E-04\n", "[ NORMAL ] Iteration 95:\tk_eff = 1.023788\tres = 1.015E-04\n", "[ NORMAL ] Iteration 96:\tk_eff = 1.023876\tres = 9.392E-05\n", "[ NORMAL ] Iteration 97:\tk_eff = 1.023958\tres = 8.694E-05\n", - "[ NORMAL ] Iteration 98:\tk_eff = 1.024034\tres = 8.044E-05\n", - "[ NORMAL ] Iteration 99:\tk_eff = 1.024104\tres = 7.445E-05\n", - "[ NORMAL ] Iteration 100:\tk_eff = 1.024169\tres = 6.889E-05\n", + "[ NORMAL ] Iteration 98:\tk_eff = 1.024034\tres = 8.045E-05\n", + "[ NORMAL ] Iteration 99:\tk_eff = 1.024104\tres = 7.446E-05\n", + "[ NORMAL ] Iteration 100:\tk_eff = 1.024169\tres = 6.890E-05\n", "[ NORMAL ] Iteration 101:\tk_eff = 1.024229\tres = 6.374E-05\n", - "[ NORMAL ] Iteration 102:\tk_eff = 1.024285\tres = 5.896E-05\n", + "[ NORMAL ] Iteration 102:\tk_eff = 1.024285\tres = 5.897E-05\n", "[ NORMAL ] Iteration 103:\tk_eff = 1.024336\tres = 5.457E-05\n", - "[ NORMAL ] Iteration 104:\tk_eff = 1.024384\tres = 5.048E-05\n", - "[ NORMAL ] Iteration 105:\tk_eff = 1.024428\tres = 4.671E-05\n", - "[ NORMAL ] Iteration 106:\tk_eff = 1.024469\tres = 4.320E-05\n", - "[ NORMAL ] Iteration 107:\tk_eff = 1.024507\tres = 3.994E-05\n", + "[ NORMAL ] Iteration 104:\tk_eff = 1.024384\tres = 5.049E-05\n", + "[ NORMAL ] Iteration 105:\tk_eff = 1.024428\tres = 4.672E-05\n", + "[ NORMAL ] Iteration 106:\tk_eff = 1.024469\tres = 4.321E-05\n", + "[ NORMAL ] Iteration 107:\tk_eff = 1.024506\tres = 3.994E-05\n", "[ NORMAL ] Iteration 108:\tk_eff = 1.024541\tres = 3.696E-05\n", - "[ NORMAL ] Iteration 109:\tk_eff = 1.024574\tres = 3.416E-05\n", - "[ NORMAL ] Iteration 110:\tk_eff = 1.024603\tres = 3.163E-05\n", - "[ NORMAL ] Iteration 111:\tk_eff = 1.024631\tres = 2.924E-05\n", - "[ NORMAL ] Iteration 112:\tk_eff = 1.024656\tres = 2.704E-05\n", + "[ NORMAL ] Iteration 109:\tk_eff = 1.024574\tres = 3.418E-05\n", + "[ NORMAL ] Iteration 110:\tk_eff = 1.024603\tres = 3.164E-05\n", + "[ NORMAL ] Iteration 111:\tk_eff = 1.024631\tres = 2.925E-05\n", + "[ NORMAL ] Iteration 112:\tk_eff = 1.024657\tres = 2.705E-05\n", "[ NORMAL ] Iteration 113:\tk_eff = 1.024680\tres = 2.501E-05\n", - "[ NORMAL ] Iteration 114:\tk_eff = 1.024702\tres = 2.312E-05\n", - "[ NORMAL ] Iteration 115:\tk_eff = 1.024722\tres = 2.138E-05\n", + "[ NORMAL ] Iteration 114:\tk_eff = 1.024702\tres = 2.313E-05\n", + "[ NORMAL ] Iteration 115:\tk_eff = 1.024722\tres = 2.140E-05\n", "[ NORMAL ] Iteration 116:\tk_eff = 1.024741\tres = 1.981E-05\n", "[ NORMAL ] Iteration 117:\tk_eff = 1.024758\tres = 1.827E-05\n", "[ NORMAL ] Iteration 118:\tk_eff = 1.024774\tres = 1.690E-05\n", "[ NORMAL ] Iteration 119:\tk_eff = 1.024789\tres = 1.564E-05\n", - "[ NORMAL ] Iteration 120:\tk_eff = 1.024802\tres = 1.446E-05\n", + "[ NORMAL ] Iteration 120:\tk_eff = 1.024802\tres = 1.445E-05\n", "[ NORMAL ] Iteration 121:\tk_eff = 1.024815\tres = 1.338E-05\n", "[ NORMAL ] Iteration 122:\tk_eff = 1.024827\tres = 1.236E-05\n", - "[ NORMAL ] Iteration 123:\tk_eff = 1.024837\tres = 1.143E-05\n", + "[ NORMAL ] Iteration 123:\tk_eff = 1.024837\tres = 1.142E-05\n", "[ NORMAL ] Iteration 124:\tk_eff = 1.024847\tres = 1.057E-05\n" ] } @@ -1623,7 +1627,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 43, @@ -1632,9 +1636,9 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX4AAADHCAYAAAAeaDj1AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJztnXu8VWW1978/kbuAchNQEBUveWmjbpXMXglLECmygyUe\nDdNCTTN7tfTUSSk9Jyu7mJoeNF+8pOblkJYUkh5NX0XZKiiWCiIkclORiwgIOM4fc+5aLNZeY7LX\nvs/x/XzWZ681528+z5hzjjn2vI1nyMwIgiAI8sMOzW1AEARB0LRE4A+CIMgZEfiDIAhyRgT+IAiC\nnBGBPwiCIGdE4A+CIMgZEfhbGZJukPS9Cpb/jqSbGtKmIGgMJH1C0isVLD9I0nuS2jWkXW2BVh/4\nJZ0u6UVJ70taJul6STs3Ud8LJX0gqXfR9NmSTNLggmlHSJomaZWklZKekfTlOto9XdKW1GlrP9cC\nmNnZZnZ5fW02s/80s6/Ud/m6KLJ5jaQ5ksZsx/JTJF3R0Ha1FlqRHx8l6RFJayWtlvR7SQcULddd\n0i8k/T31h/np763aL9CbpHUFvr4KwMweN7P96rteZvZ3M9vJzLbUt426KLL5TUk/y/oPRtJwSYsb\n2qbtoVUHfkkXAj8CvgX0AIYBewAzJHVoIjNeB8YX2HQw0LnIzo8BjwCPAUOAXsA5wPFl2n0qddra\nz3kNbnnD85SZ7QTsDPwKuKupgldrppX58UPA/cAAYE9gDvD/Je2VajoADwMHAqOA7sBRwDvAEWX6\nryrw9dbiM1Wpvx8DfBE4o5ntyY6ZtcoPiUO9B3yhaPpOwArgjPT3JOBe4LfAWuA5kh1Wqx8A3Ae8\nReL85xfMmwTcDdyaLvsSUF0wfyHw78CsgmlXAd8FDBicTnsCuG471u104Ik65k0Brki/9wb+AKwC\nVgKPAzuk8y4G3kztfgU4tmCdbi9o77Ppeq0CHgU+UrR+FwEvAKvTbdgpi81Al3QbHF4w7R5gWdrW\nX4AD0+kTgU3AB+k+/X2GfXMEUAOsAZYDP2tun8yBHz8O/KrEOvwRuDX9/pV0f+y0HdvAgCElpg8H\nFhf8rsunS/oCMDhte8eCbfQAybEyH/hq1m3k2Zwue13B7y8Df0vbWgCclU7vCqwHPkz3+3upXTsA\nlwCvkfyTvBvomS7TCbg9nb4KmAXsWpHfNbfjV3DAjAI21+7Uonm3AHcW7NBNwDigPUkgez39vgPw\nLHAp0AHYK91JIwuW3QCMBtoBPwRmFh0wn0qd8COp5g2SszVLHa8LsAX45Has2+lkC/w/BG5I16U9\n8AlAwH6pHQMKDoC9C9bp9vT7vsA64NPp8t9OD4gOBev3TOqYPVNHPtuzOd0O55IE8r4FmjOAbkBH\n4BfA7FLrlf729s1TwGnp952AYc3tk3n1Y5IgtzT9fhdwy3ZuAzfwOz5d0hfYNvA/RnIl2gkYSvJP\n8tgs26iczcD+wFLgmwXzTwD2JjkejwHeBw4tXq8C/QXATGB3kuPjvwr2/VnA79N90A44DOheid+1\n5ls9vYG3zWxziXlL0/m1PGtm95rZJuBnJDt+GHA40MfMfmBmH5jZAuBG4OSCZZ8ws2mW3Ce8Dagq\n0d9twJdIAujLJGcltexCcmAu3c71G5Y+D6j9DCuh2QT0B/Yws02W3BM1kgO0I3CApPZmttDMXiux\n/BeBB81sRrptriK5vD+qQPNLM1tiZitJnG+oZzPJAXQVcKqZraidaWY3m9laM9tIcqBVSepRR1ve\nvtkEDJHU28zeM7OZZexqybQWP+5J3X5caGevOjQezxX4+i9LzC/n064vSBoIHA1cbGYbzGw2cBNw\nWoEsyzYqtnkdyQnRoyT/VAAwswfN7DVLeIzkFtknyrR1FvBdM1tccHyMk7Rjun69SP7RbDGzZ81s\njWNbWVpz4H8b6J1umGL6p/NreaP2i5l9CCwmOYvdAxhQGGCB7wC7Fiy7rOD7+0CnEn3eBpxCctZ7\na9G8d0ku6/pnXK9aZprZzgWfUoHtJyRn6A9JWiDpknQd55OcQUwCVki6S9KAEssPABbV/ki3zRvA\nbgWa4vXfybOZ5J/dAxQ4uqR2kq6U9JqkNSRnmbB1YCvE2zdnklyxvCxp1vY8SG5htAU/LrTznTo0\nHocW+Pr5xTMdn87iCwOAlWa2tmDaIsr7eqlttJXNJMfDF4EjSW7jACDpeEkz0xc5VpFcSdTl65Ds\nw6kF++9vJP/sdiXZL9NJnpktkfRjSe3LtOXSmgP/U8BG4POFEyV1JXlo+nDB5IEF83cguZxaQnIg\nvV4UYLuZ2ejtMcTMFpFcdo8G/rto3vuprf+yPW1m7HetmV1oZnsBnwH+r6Rj03l3mNnR/PNy/Ucl\nmliSzgdAkki21ZsltNtj13vA14DTJB2STj4FGEtyS6EHyWU4JJfCpDYWUnbfmNk8MxsP9E3X7d50\n37c2Wosfr0ttPanEol8osPPPwMjG2Bd1+XRGX1gC9JTUrWDaICr3dTOzu0m2zaUAkjqSPG+5iuRe\n/M7ANOr2dUj24fFF+7CTmb2ZXs1/38wOILkaH0NyZVZvWm3gN7PVwPeBaySNktQ+fe3sHpIzodsK\n5IdJ+nz63/sCkgNtJsn96zWSLpbUOT0rPUjS4fUw6UxgRHqAFPNt4HRJ35LUC0BSlaS76tHPP5A0\nRtKQNGCvITlD2CJpP0kjUgfcQPIwqdQrbXcDJ0g6Nj2DuJBk2zxZiV0AZvYOyaX0pemkbmnb75Dc\nq/zPokWWk9ybrqXsvpF0qqQ+6ZnvqnSZBn9tr7FpZX58CTBB0vmSuknaRckruB9L14HU3jeA+yTt\nL2kHSb2U5I9s1z+iQsr5dBZfMLM3SPz6h5I6Sfpouq6/qa9NRVwJTJTUj+Q5S0eSZwibJR0PHFeg\nXQ70KrrNeQPwH5L2SNepj6Sx6fdPSjpYyeuia0hu/VTk66028AOY2Y9JLmmvItkgT5M43bHpfbJa\n7ie5HHuX5J7e59P/oltIzpSHkpzpvE0SrOq671zOltfMrKaOeU8CI9LPAkkrgckkZwGVsA/JGdZ7\nJGccvzKzR0mc7kqS9VlGcib0nRJ2vQKcClyTaj8DfMbMPqjQrlp+AYxOD7JbSS6t3wT+ShKwCvk1\nyf3bVZJ+l2HfjAJekvQecDVwspltaCC7m5RW5MdPACNJrk6WkuzPQ4CjzWxeqtlIclX3MjAjXZ9n\nSG5zPL299hRQzqez+sJ4kivNJcBU4DIzm1GBTf/AzF4keXj8rfR20vkkJ1bvklztPlCgfRm4kyQW\nrEpvWV2dah6StJbk+DgyXaQfyRtda0huAT1G8pZPvZFZ2y7EImkSyUORU5vbliCoL+HHQUPSqs/4\ngyAIgu0nAn8QBEHOaPO3eoIgCIKtiTP+IAiCnBGBPwiCIGeUy0prNrr27mw9B3crq1lBH7edD17t\n7Gq0d6lM+SKNXAkddvDfgOzC+65mDd39vvD7ap9Bs3qTPwhiz/YrXc3KFeUSEhN27LvR1Wye19HV\nbJWLWhevO/O3LMQ+fDvDXm1YpF6W5FyV4y2/oa6lkrCL6OdLOu1c6lX9rdm4xd8n9oEfRjp19vva\nsN7P+WqodtTBP+47tvN9dsOqDHlqy3wJ65ZkEHkxbzFm72Ty64oCv6RRJO+ftgNuMrMri+Z3JHl/\n+zCSxJ0vmtlCr92eg7vxzZpxZTXXca5r34JPH+hqOt7rB7Ydd/RzJQZ2fcPVHMazrmY6I/2++HsG\njW/P75d/1tWM3vUOV3P7dV91Nb3PXeBqlh2/l6vhAl+C98Ljqmq3icbx7d1Jhmwpx/WubRw8yddc\n4kuGjJ3lauav3tvVbFjY0++ryu9r7hw/36yh2uk42D/uh/QoNbxVUV/3Z8iRu9KXMHNSBtE5zvzj\nnPn/pN63etIssutI0soPAMarqCADSWbcu2Y2BPg5pYcNCIIWRfh20Nap5B7/EcB8M1uQZnreRTIW\nSyFjSYaWhSTz7Nh0eIEgaMmEbwdtmkoC/26w1f2ExWw90t1WGkuGnV1NMrzoNkiaKKlGUs26t9ZX\nYFYQVEyD+XahXyf1P4Kg+akk8Jc6uylOCsiiSSaaTTazajOr7trHfygbBI1Ig/l2oV8nQ9oHQfNT\nSeBfTMEwsfxziNiSmnREwR7EaU/Q8gnfDto0lQT+WcA+kvZUUmD5ZApGoEt5AJiQfh8HPGKRKhy0\nfMK3gzZNvV/nNLPNks4jqQzTDrjZzF6S9AOgxsweIBlq9zZJ80nOhk6uu8WCthEbKf/+8GgedNv5\n6Az/PaqfcJGrmTfdq8AGrwzt4moO29V/nfP1jXu6mq4Pf+hqdGDDjKw82H0pHn53rv8Kag2HuZor\nhhcP0b8t7av9inObZncoLxhdPj43nm+/hf+65qf8ZjIMPt1vrP/6bJZXfh/pMcLV3Fvl1xhaS/m8\nHIATqz7vaqbyOVfTreo6VzOO+1zNhH88u6+bt8eWfGS5FcsmZXhNOct+d30nQw5ISkXv8ZvZNIrG\nlDezSwu+b6B0xZ4gaNGEbwdtmRiyIQiCIGdE4A+CIMgZEfiDIAhyRgT+IAiCnBGBPwiCIGdE4A+C\nIMgZEfiDIAhyRossxLKRjixkcFnN5P7fcNt5bWl/V7OZdq5mysgvu5qnOcbVsGKiK3mk78dczYjR\nT7qaKma6mixJNZfjJ1XN4mBX8yKnu5o/Xjzc1Zyw3E/cG7Hbn8vOn9XeTwJrFLoO8MfSz5CcxRhf\nsvRpfxz9bQahKMWJfjLyUezraqpq5vl9Vft9fbvGHwB1TvU+rqYPa13NtKkZBlvNUBNHY7IkdB/t\nSzo5mhf/kKGfhDjjD4IgyBkR+IMgCHJGBP4gCIKcEYE/CIIgZ0TgD4IgyBmVFFsfKOl/JP1N0kuS\ntnnNRtJwSaslzU4/l5ZqKwhaEuHbQVunktc5NwMXmtlzkroBz0qaYWZ/LdI9bmYZXkALghZD+HbQ\npqn3Gb+ZLTWz59Lva4G/sW1B6iBodYRvB22dBkngkjQYOAR4usTsj0maQ5IucpGZvVRHGxOBJMOp\n/yAmzymfoHXE0sdcuwauXuZqzukxxde87idyzNzTr9JFX19zHte6mqHc7GqWM9zV/Ct3uJqLudfV\nTOV2V/Mq/rpfxGuu5upd/cS9ry9yKhV90N1to5ZKfXsrv+4zCC4p31+WylmZkrOO9JOG1nTy/br7\nwb5m/Sx/3y6r7uFq+r3s95WlnfX41fA43O9rzYt+M903+NvZ8Pvqf7nv+8vudyp5Xeg28Q8qfrgr\naSfgPuACMytOiXwO2MPMqoBrgN/V1Y6ZTTazajOrZpc+lZoVBBXTEL69lV93D78OWgYVBX5J7UkO\njN+Y2X8XzzezNWb2Xvp9GtBeUu9K+gyCpiB8O2jLVPJWj0gKTv/NzH5Wh6ZfqkPSEWl/79S3zyBo\nCsK3g7ZOJff4Pw6cBrwoaXY67TvAIAAzuwEYB5wjaTOwHjjZzLKMWBQEzUn4dtCmqXfgN7MnoPxT\nCzO7FjI8rQyCFkT4dtDWiczdIAiCnBGBPwiCIGdE4A+CIMgZLbICF2uBR8tLvl51jd9Mj06uZoVT\n6QtgwKD2rmbYTXNczTe/4lezmv/OEFdze69TXc0dc890NX84aISr2Y9X/b44xdUsoq+rWcKVruYA\nikdNKMFiZ399kKGyUiPQaed1DBk7q6xmIG/4DWWonJUlOWv9Rr+dbn4+GfvyiqvpeU+G0mJTfEm/\n01e7mg4n+fZYhvXKsn3IkgR3p9/MIcx2NW+MLf/S2PzL1/kdpcQZfxAEQc6IwB8EQZAzIvAHQRDk\njAj8QRAEOSMCfxAEQc6IwB8EQZAzIvAHQRDkjAj8QRAEOaNFJnCp5xZ2PLW47sXWvMK+bjunZqge\ntTZDYtELO25yNUdnGJixM3497k3j/OpQh/6Pn8S07KCdXc2Y2Y+4Gob66/VGjZ/Esmkfv6s7epzh\navQ9X+MWBMuQANUYbNzSkfmry1fPeqSHn1THif4+yVI5K0tylt7x++p5UYaEuBpfwqMZBjcd7vfV\n8+kMyWIZ1qtvL78vOUWxgEz76xa6uZpBqxeVnb9xS8cMxiQ0RAWuhZJelDRb0ja7Vwm/lDRf0guS\nDq20zyBobMKvg7ZMQ53xf9LM3q5j3vHAPunnSOD69G8QtHTCr4M2SVPc4x8L3GoJM4GdJfVvgn6D\noDEJvw5aLQ0R+A14SNKzkiaWmL8bbDXy1OJ0WhC0ZMKvgzZLQ9zq+biZLZHUF5gh6WUz+0vB/FJP\nSLZ52pEeXMkBtvvABjArCCqi4f164O6NYmgQbC8Vn/Gb2ZL07wpgKnBEkWQxUBjJd6fEexVmNtnM\nqs2sWr16VWpWEFRE+HXQlqko8EvqKqlb7XfgOGBukewB4EvpWxDDgNVmtrSSfoOgMQm/Dto6ld7q\n2RWYKqm2rTvM7E+SzgYwsxuAacBoYD7wPvDlCvsMgsYm/Dpo08gyJB41Nb2r97AxNZeU1UwZ+TW3\nnUkP+X3taV9wNRNuv9tvaIAvmTfCv8f7c77parbQztXcu2Wcq/lmu5+7mtO41dXsMe8tV8NNvmT4\nj/7oatbT2dU8o2McRTVmGbLOGhgdWG3cUT6T6VdVp7vtHMWTrmY9XVxNpspZF/nJUI9dVXwXbFs6\n4pezGnaIX8Vu5vNVrmYjfiLTMRc942pWXuVX8HuV/VxNZ953NU9ylKv52pwp5QWnVGMvZfPrGLIh\nCIIgZ0TgD4IgyBkR+IMgCHJGBP4gCIKcEYE/CIIgZ0TgD4IgyBkR+IMgCHJGBP4gCIKc0SIrcL1P\nF2ZzSFnND6df4LYz6cu/cDUHc5GrOb3bb13N+BE3u5osiTc/W3ehq+nDClez9jG/stj1oye4mj1+\n4Cdn6cz1rmbhjwa5mk/xZ1czkumu5gwrvy/mV69z22gMOnVex5CqWWU1azNUYqqqmedqllX3cDU9\n78lQqSpD5axMyVmn+clZk2b7fU3K0M7M2/wkryzrlWX7DD5poavpV7Pa1UyvHulqDnJ8Z37n7H4d\nZ/xBEAQ5IwJ/EARBzojAHwRBkDMi8AdBEOSMCPxBEAQ5o96BX9J+kmYXfNZIuqBIM1zS6gLNpZWb\nHASNS/h20Nap9+ucZvYKMBRAUjvgTZISdcU8bmZj6ttPEDQ14dtBW6ehbvUcC7xmZosaqL0gaCmE\nbwdtjoZK4DoZuLOOeR+TNIekEPVFZvZSKZGkicBEAPoOYs70YWU7PGDkX32r/p9fXexg/MSrbmPX\nupo7OMPV/JjnXU2n4squJVh7ZB9f5OfvcE7NLb7oUn8b2my/6M/9ux3nav6dq1zNptU/dTVzzzu8\nvOD1rm4bBVTk21v5df9BzJ1T3rYTqz7vW1Tt75N+L2coxDTFl/Co39ewQ/y+MiVnZagGOEkZ+prr\nJ3nxfIbKgyf4ffU72E/OyrK/TmSgq7l4zjXlBeuz+3XFZ/ySOgCfBe4pMfs5YA8zqwKuAX5XVztm\nNtnMqs2smh4ZAlsQNDIN4dtb+fUu4ddBy6AhbvUcDzxnZsuLZ5jZGjN7L/0+DWgvqXcD9BkETUH4\ndtAmaYjAP546LoUl9ZOSazNJR6T9vdMAfQZBUxC+HbRJKrrHL6kL8GngrIJpZwOY2Q3AOOAcSZuB\n9cDJZhlu5AVBMxO+HbRlKgr8ZvY+0Kto2g0F368Frq2kjyBoDsK3g7ZMZO4GQRDkjAj8QRAEOSMC\nfxAEQc5okRW4Ondfx74jZ5bVfEAHt51u6/zqUQu6fsPVHE75yjcAV//zGWCdPMtRroaOvoSbMiTn\n+EW6uPM7Y13N+Dv9vt4c39PVPJlh3adyvasZ12OEq2GS84w1QzJRY5ClAtdUPue28+0af59kqcDV\n7/QMyUfD/b5mPu9XvMpSOStTctapriRTBa5hGdaLc33Jsv0zbOcM+2tq9XmuJipwBUEQBPUmAn8Q\nBEHOiMAfBEGQMyLwB0EQ5IwI/EEQBDkjAn8QBEHOiMAfBEGQMyLwB0EQ5IwWmcC1I5vpxdtlNffN\n8TM5rqn6iqsZy/2u5toMmRxjHnvE1ZxVPdnV8Jgv2XS6r2mfIYHrUzzsizLYc+/4ca7mrxzgakYy\n3dVcxvd9g25wEmb8vL5GYcP6rm4Frm5V17ntzKnex9Wsp4ur6XDSK66m59MbXM3GDFmHWZKqslTO\nytJOFnuo9iUrT+rkahYy2NUsr37f1XTDr/Ln+U6DV+CSdLOkFZLmFkzrKWmGpHnp313qWHZCqpkn\naUJmy4KgkQm/DvJK1ls9U4BRRdMuAR42s32Ah9PfWyGpJ3AZcCRwBHBZXQdSEDQDUwi/DnJIpsBv\nZn8BVhZNHgvUVuu+BUoOMjISmGFmK83sXWAG2x5oQdAshF8HeaWSh7u7mtlSgPRv3xKa3YA3Cn4v\nTqcFQUsl/Dpo8zT2Wz2lnrKVHDpR0kRJNZJqPngrw6iBQdB81MuvebeZnioHQRGVBP7lkvoDpH9L\nvUeyGBhY8Ht3YEmpxsxssplVm1l1hz7+UKdB0Eg0ml+zS58GNzYI6kMlgf8BoPZthglQ8r3I6cBx\nknZJH34dl04LgpZK+HXQ5sn6OuedwFPAfpIWSzoTuBL4tKR5wKfT30iqlnQTgJmtBC4HZqWfH6TT\ngqDZCb8O8orMnGpFzYA0wGBiWU2V+S9RzGaYq7kzQ8Wj8Y/5SV4ck2E7Xu1X4pn1jYNczeG86GrG\ncburufeE01wND/rrtThD5aTdb/C74iy/r8G87GoWnbN/ecF91diKDGWRGpgdDhlqHR8tn+j39x57\nuO30yZDsw+H+6tkCvxm9k8GvL8qwKWt8CY9m6CtL5awMyVlc5fdlvfy+tFeGvmb5fb1FN1czaPWi\nsvM3Dh/Bh8/PzuTXMWRDEARBzojAHwRBkDMi8AdBEOSMCPxBEAQ5IwJ/EARBzojAHwRBkDMi8AdB\nEOSMCPxBEAQ5o0VW4KLfADh9UllJNde6zTzGN1zN+IuecTWfuOohV3Njhko873/jI67m8K/OdTU3\n33iKqxntKmDGg0e7msPo7Go62k6uZlGGdv6Nm13NaFa5mkevL1/x6PVZfkWkxqBju40M6fFaWc2E\nf4wIXTfTpvo5Omv8HD/Wb/Q1fTMkMb37jl+pquc9fiUvTsiQe+QXw8tUOWuXDOu1IkMudud1vqZ7\nhv014cT7XI3nO/PbZdihKXHGHwRBkDMi8AdBEOSMCPxBEAQ5IwJ/EARBzojAHwRBkDPcwC/pZkkr\nJM0tmPYTSS9LekHSVEk717HsQkkvSpotKcvArEHQZIRvB3klyxn/FKB48PsZwEFm9lHgVeDfyiz/\nSTMbamZZRskOgqZkCuHbQQ5xA7+Z/QVYWTTtITPbnP6cSVJzNAhaFeHbQV5piASuM4Df1jHPgIck\nGfBfZja5rkYkTaS27FaXQTC/fKe/vu8817Bf7+hr7CpXwuNf8BMwjrr7YVfzNr1cTc0Nh7uaM56+\n09WccuSvXc2XuNXVdFvtJ9483eNQV3M0z7qaar7mai5cdLWr4fb25ecv7eK3kVCxb2/l130GMff+\n8vv37bG+jzDAl3TfkKGaVaeGqTD1Kvu5msEnLXQ1/Q5e7WqW7d/D1SzMkEw5bK85riZTclaW7fy0\nv52fZ6irWXa/szNWdfVtSako8Ev6LrAZ+E0dko+b2RJJfYEZkl5Oz7K2IT1wJgOoZ3XLqwcZ5IqG\n8u2t/HpI+HXQMqj3Wz2SJgBjgH+1Ogr3mtmS9O8KYCpwRH37C4KmInw7aOvUK/BLGgVcDHzWzEoO\nfCKpq6Rutd+B4wB/IJogaEbCt4M8kOV1zjuBp4D9JC2WdCZwLdCN5BJ3tqQbUu0ASdPSRXcFnpA0\nB3gGeNDM/tQoaxEE9SB8O8gr7j1+MxtfYnLJJ4fp5e/o9PsCoKoi64KgEQnfDvJKZO4GQRDkjAj8\nQRAEOSMCfxAEQc5omRW4NoNbaGl/v5mjD5zhi6Yc52v+w5c8yQhfdHaGCkPH+hJO8l8Hv4L+rmav\n25f5fZ3q99WFA1zNwcxyNSOzZCZd5CRnAR+557my81+f2jwVuFgGXOlIJvkZUxrj7xPD97Xufh4g\nnOj31Zl9XU2/Gj85iwxpDv1q/PVaXp1h/87y+8pSOStLcpb+kCF942xfgldYLMPhXEuc8QdBEOSM\nCPxBEAQ5IwJ/EARBzojAHwRBkDMi8AdBEOSMCPxBEAQ5IwJ/EARBzojAHwRBkDNaZALXrvsu5dQZ\nV5TVXLHue247nfWGq9FMP7li9j5+gsoY5rmaDjf4I/dezfmupiOfcDUnbXze1ay+r5+rYaAvYUj5\nhCmAM3e7ydUsyZDAdfQ9flLeWrqVnS+aqR7KuiUwc5Ij+lSGho52Ff0vf83VHMJsV3OLsy0BnuRf\nXM306pGu5sQMzja12q+q1421rmZAhvWacOJ9riZL5axMyVmzn8gg+rMzf0mGNhKyDMt8s6QVkuYW\nTJsk6c102NrZkkbXsewoSa9Imi/pksxWBUETEL4d5JUst3qmAKNKTP+5mQ1NP9OKZ0pqB1wHHA8c\nAIyX5Of2B0HTMYXw7SCHuIE/rSO6sh5tHwHMN7MFZvYBcBcwth7tBEGjEL4d5JVKHu6eJ+mF9HJ5\nlxLzdwMKb7IvTqeVRNJESTWSat5/K0N5+yBoPBrMtwv9GpppcLggKKK+gf96YG9gKLAU+GkJTalh\n6+p8qmZmk82s2syqu/TpWk+zgqBiGtS3C/0aujSclUFQAfUK/Ga23My2mNmHwI0kl77FLGbrd0J2\nZ3seOwdBMxC+HeSBegV+SYWDvZ8IlHpPcRawj6Q9JXUATgYeqE9/QdBUhG8HecB9j1/SncBwoLek\nxcBlwHBJQ0kubxcCZ6XaAcBNZjbazDZLOg+YDrQDbjazlxplLYKgHoRvB3lFZs2UzFIGaXeDr5cX\njbrYb2hMhs42+JI9LnzZ1SzqnKEkWIZ8qVNfv9HVTNtS8tXyrTi/3S9dzaTTfuQbdPuzrmSHZf66\nfzgpw3Ob3X3Jt7/7fVfzGnuXnf9w9aW8W7MgQ3mlhkWqMnjIUV3vNzRskq/JkFlw0Fi/Ktr81eW3\nJcCGhT3V+OuBAAADO0lEQVT9vqr8vubOObzJ2uk02H+Za0gPPwlu7v1+X17VNSBDYh/AOc784zCb\nk8mvY8iGIAiCnBGBPwiCIGdE4A+CIMgZEfiDIAhyRgT+IAiCnBGBPwiCIGdE4A+CIMgZEfiDIAhy\nRgtN4NJbwKKCSb2Bt5vJnPoSNjc+9bV3DzPr09DGeJTwa8jPNm9O8mJzZr9ukYG/GEk1yeiGrYew\nufFpbfaWorWtQ2uzF8LmUsStniAIgpwRgT8IgiBntJbAP7m5DagHYXPj09rsLUVrW4fWZi+EzdvQ\nKu7xB0EQBA1HaznjD4IgCBqIFh/4JY2S9Iqk+ZIyjDLevEhaKOlFSbOTAtstj7SI+ApJcwum9ZQ0\nQ9K89G+pIuPNRh02T5L0ZrqtZ0vyCxW0EFqbX0P4dmPRHL7dogO/pHbAdcDxwAHAeEkHNK9Vmfik\nmQ1twa+QTQFGFU27BHjYzPYBHiZTKY8mZQrb2gzw83RbDzWzaU1sU71oxX4N4duNwRSa2LdbdOAn\nKXQ938wWmNkHwF3A2Ga2qdVjZn8BiksQjQVuSb/fAnyuSY1yqMPm1kr4dSMRvp2Nlh74dwPeKPi9\nOJ3WkjHgIUnPSprY3MZsB7ua2VKA9G/fZrYnK+dJeiG9XG5Rl/BlaI1+DeHbTU2j+XZLD/yl6ke2\n9NeQPm5mh5Jcxp8r6f80t0FtmOuBvYGhwFLgp81rTmZao19D+HZT0qi+3dID/2JgYMHv3YElzWRL\nJsxsSfp3BTCV5LK+NbBcUn+A9O+KZrbHxcyWm9kWM/sQuJHWs61bnV9D+HZT0ti+3dID/yxgH0l7\nSuoAnAw80Mw21YmkrpK61X4HjgPmll+qxfAAMCH9PgG4vxltyUTtwZxyIq1nW7cqv4bw7aamsX17\nx4ZsrKExs82SzgOmA+2Am83spWY2qxy7AlMlQbJt7zCzPzWvSdsi6U5gONBb0mLgMuBK4G5JZwJ/\nB05qPgu3pQ6bh0saSnKbZCFwVrMZuB20Qr+G8O1Gozl8OzJ3gyAIckZLv9UTBEEQNDAR+IMgCHJG\nBP4gCIKcEYE/CIIgZ0TgD4IgyBkR+IMgCHJGBP4gCIKcEYE/CIIgZ/wvRmjoaxBudh4AAAAASUVO\nRK5CYII=\n", + "image/png": "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\nAAAAAElFTkSuQmCC\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1675,7 +1679,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.0" + "version": "3.5.2" } }, "nbformat": 4, diff --git a/docs/source/pythonapi/opencg_compatible.rst b/docs/source/pythonapi/opencg_compatible.rst deleted file mode 100644 index c807e19cc..000000000 --- a/docs/source/pythonapi/opencg_compatible.rst +++ /dev/null @@ -1,8 +0,0 @@ -.. _pythonapi_opencg_compatible: - -==================== -OpenCG Compatibility -==================== - -.. automodule:: openmc.opencg_compatible - :members: diff --git a/docs/source/pythonapi/openmoc_compatible.rst b/docs/source/pythonapi/openmoc_compatible.rst new file mode 100644 index 000000000..bf353b96e --- /dev/null +++ b/docs/source/pythonapi/openmoc_compatible.rst @@ -0,0 +1,8 @@ +.. _pythonapi_openmoc_compatible: + +===================== +OpenMOC Compatibility +===================== + +.. automodule:: openmc.openmoc_compatible + :members: diff --git a/openmc/__init__.py b/openmc/__init__.py index 9d8c7cf43..99baf4f29 100644 --- a/openmc/__init__.py +++ b/openmc/__init__.py @@ -28,6 +28,6 @@ from openmc.mixin import * from openmc.plotter import * try: - from openmc.opencg_compatible import * + from openmc.openmoc_compatible import * except ImportError: pass diff --git a/openmc/arithmetic.py b/openmc/arithmetic.py index f54953720..9593042d9 100644 --- a/openmc/arithmetic.py +++ b/openmc/arithmetic.py @@ -399,7 +399,6 @@ class CrossFilter(object): 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. Returns ------- diff --git a/openmc/filter.py b/openmc/filter.py index 3f070ba8e..71b1c2313 100644 --- a/openmc/filter.py +++ b/openmc/filter.py @@ -1301,8 +1301,7 @@ class DistribcellFilter(Filter): filter_bins = np.tile(filter_bins, tile_factor) df = pd.DataFrame({self.short_name.lower() : filter_bins}) - # If OpenCG level info DataFrame was created, concatenate - # with DataFrame of distribcell instance IDs + # Concatenate with DataFrame of distribcell instance IDs if level_df is not None: level_df = level_df.dropna(axis=1, how='all') level_df = level_df.astype(np.int) diff --git a/openmc/material.py b/openmc/material.py index b9705243e..34dfd7876 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -610,7 +610,7 @@ class Material(object): def make_isotropic_in_lab(self): for nuclide, percent, percent_type in self._nuclides: nuclide.scattering = 'iso-in-lab' - for element, percent, percent_type in self._elements: + for element, percent, percent_type, enrichment in self._elements: element.scattering = 'iso-in-lab' def get_nuclides(self): diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index 627fb2508..0a9a94828 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -586,7 +586,7 @@ class Library(object): self._geometry = statepoint.summary.geometry self._nuclides = statepoint.summary.nuclides - if statepoint.run_mode == 'k-eigenvalue': + if statepoint.run_mode == 'eigenvalue': self._keff = statepoint.k_combined[0] # Load tallies for each MGXS for each domain and mgxs type diff --git a/openmc/opencg_compatible.py b/openmc/opencg_compatible.py deleted file mode 100644 index 8983f5fa0..000000000 --- a/openmc/opencg_compatible.py +++ /dev/null @@ -1,1051 +0,0 @@ -import copy -import operator - -import numpy as np - -try: - import opencg -except ImportError: - raise ImportError('Unable to import opencg which is needed by ' - 'openmc.opencg_compatible') - -import openmc -import openmc.checkvalue as cv - - -# A dictionary of all OpenMC Materials created -# Keys - Material IDs -# Values - Materials -OPENMC_MATERIALS = {} - -# A dictionary of all OpenCG Materials created -# Keys - Material IDs -# Values - Materials -OPENCG_MATERIALS = {} - -# A dictionary of all OpenMC Surfaces created -# Keys - Surface IDs -# Values - Surfaces -OPENMC_SURFACES = {} - -# A dictionary of all OpenCG Surfaces created -# Keys - Surface IDs -# Values - Surfaces -OPENCG_SURFACES = {} - -# A dictionary of all OpenMC Cells created -# Keys - Cell IDs -# Values - Cells -OPENMC_CELLS = {} - -# A dictionary of all OpenCG Cells created -# Keys - Cell IDs -# Values - Cells -OPENCG_CELLS = {} - -# A dictionary of all OpenMC Universes created -# Keys - Universes IDs -# Values - Universes -OPENMC_UNIVERSES = {} - -# A dictionary of all OpenCG Universes created -# Keys - Universes IDs -# Values - Universes -OPENCG_UNIVERSES = {} - -# A dictionary of all OpenMC Lattices created -# Keys - Lattice IDs -# Values - Lattices -OPENMC_LATTICES = {} - -# A dictionary of all OpenCG Lattices created -# Keys - Lattice IDs -# Values - Lattices -OPENCG_LATTICES = {} - - -def get_opencg_material(openmc_material): - """Return an OpenCG material corresponding to an OpenMC material. - - Parameters - ---------- - openmc_material : openmc.material.Material - OpenMC material - - Returns - ------- - opencg_material : opencg.Material - Equivalent OpenCG material - - """ - - cv.check_type('openmc_material', openmc_material, openmc.Material) - - material_id = openmc_material.id - - # If this Material was already created, use it - if material_id in OPENCG_MATERIALS: - return OPENCG_MATERIALS[material_id] - - # Create an OpenCG Material to represent this OpenMC Material - name = openmc_material.name - opencg_material = opencg.Material(material_id=material_id, name=name) - - # Add the OpenMC Material to the global collection of all OpenMC Materials - OPENMC_MATERIALS[material_id] = openmc_material - - # Add the OpenCG Material to the global collection of all OpenCG Materials - OPENCG_MATERIALS[material_id] = opencg_material - - return opencg_material - - -def get_openmc_material(opencg_material): - """Return an OpenMC material corresponding to an OpenCG material. - - Parameters - ---------- - opencg_material : opencg.Material - OpenCG material - - Returns - ------- - openmc_material : openmc.material.Material - Equivalent OpenMC material - - """ - - cv.check_type('opencg_material', opencg_material, opencg.Material) - - material_id = opencg_material.id - - # If this Material was already created, use it - if material_id in OPENMC_MATERIALS: - return OPENMC_MATERIALS[material_id] - - # Create an OpenMC Material to represent this OpenCG Material - name = opencg_material.name - openmc_material = openmc.Material(material_id=material_id, name=name) - - # Add the OpenMC Material to the global collection of all OpenMC Materials - OPENMC_MATERIALS[material_id] = openmc_material - - # Add the OpenCG Material to the global collection of all OpenCG Materials - OPENCG_MATERIALS[material_id] = opencg_material - - return openmc_material - - -def is_opencg_surface_compatible(opencg_surface): - """Determine whether OpenCG surface is compatible with OpenMC geometry. - - A surface is considered compatible if there is a one-to-one correspondence - between OpenMC and OpenCG surface types. Note that some OpenCG surfaces, - e.g. SquarePrism, do not have a one-to-one correspondence with OpenMC - surfaces but can still be converted into an equivalent collection of OpenMC - surfaces. - - Parameters - ---------- - opencg_surface : opencg.Surface - OpenCG surface - - Returns - ------- - bool - Whether OpenCG surface is compatible with OpenMC - - """ - - cv.check_type('opencg_surface', opencg_surface, opencg.Surface) - - if opencg_surface.type in ['x-squareprism', - 'y-squareprism', 'z-squareprism']: - return False - else: - return True - - -def get_opencg_surface(openmc_surface): - """Return an OpenCG surface corresponding to an OpenMC surface. - - Parameters - ---------- - openmc_surface : openmc.surface.Surface - OpenMC surface - - Returns - ------- - opencg_surface : opencg.Surface - Equivalent OpenCG surface - - """ - - cv.check_type('openmc_surface', openmc_surface, openmc.Surface) - - surface_id = openmc_surface.id - - # If this Material was already created, use it - if surface_id in OPENCG_SURFACES: - return OPENCG_SURFACES[surface_id] - - # Create an OpenCG Surface to represent this OpenMC Surface - name = openmc_surface.name - - # Correct for OpenMC's syntax for Surfaces dividing Cells - boundary = openmc_surface.boundary_type - if boundary == 'transmission': - boundary = 'interface' - - opencg_surface = None - - if openmc_surface.type == 'plane': - A = openmc_surface.a - B = openmc_surface.b - C = openmc_surface.c - D = openmc_surface.d - opencg_surface = opencg.Plane(surface_id, name, boundary, A, B, C, D) - - elif openmc_surface.type == 'x-plane': - x0 = openmc_surface.x0 - opencg_surface = opencg.XPlane(surface_id, name, boundary, x0) - - elif openmc_surface.type == 'y-plane': - y0 = openmc_surface.y0 - opencg_surface = opencg.YPlane(surface_id, name, boundary, y0) - - elif openmc_surface.type == 'z-plane': - z0 = openmc_surface.z0 - opencg_surface = opencg.ZPlane(surface_id, name, boundary, z0) - - elif openmc_surface.type == 'x-cylinder': - y0 = openmc_surface.y0 - z0 = openmc_surface.z0 - R = openmc_surface.r - opencg_surface = opencg.XCylinder(surface_id, name, - boundary, y0, z0, R) - - elif openmc_surface.type == 'y-cylinder': - x0 = openmc_surface.x0 - z0 = openmc_surface.z0 - R = openmc_surface.r - opencg_surface = opencg.YCylinder(surface_id, name, - boundary, x0, z0, R) - - elif openmc_surface.type == 'z-cylinder': - x0 = openmc_surface.x0 - y0 = openmc_surface.y0 - R = openmc_surface.r - opencg_surface = opencg.ZCylinder(surface_id, name, - boundary, x0, y0, R) - - # Add the OpenMC Surface to the global collection of all OpenMC Surfaces - OPENMC_SURFACES[surface_id] = openmc_surface - - # Add the OpenCG Surface to the global collection of all OpenCG Surfaces - OPENCG_SURFACES[surface_id] = opencg_surface - - return opencg_surface - - -def get_openmc_surface(opencg_surface): - """Return an OpenMC surface corresponding to an OpenCG surface. - - Parameters - ---------- - opencg_surface : opencg.Surface - OpenCG surface - - Returns - ------- - openmc_surface : openmc.surface.Surface - Equivalent OpenMC surface - - """ - - cv.check_type('opencg_surface', opencg_surface, opencg.Surface) - - surface_id = opencg_surface.id - - # If this Surface was already created, use it - if surface_id in OPENMC_SURFACES: - return OPENMC_SURFACES[surface_id] - - # Create an OpenMC Surface to represent this OpenCG Surface - name = opencg_surface.name - - # Correct for OpenMC's syntax for Surfaces dividing Cells - boundary = opencg_surface.boundary_type - if boundary == 'interface': - boundary = 'transmission' - - if opencg_surface.type == 'plane': - A = opencg_surface.a - B = opencg_surface.b - C = opencg_surface.c - D = opencg_surface.d - openmc_surface = openmc.Plane(surface_id, boundary, A, B, C, D, name) - - elif opencg_surface.type == 'x-plane': - x0 = opencg_surface.x0 - openmc_surface = openmc.XPlane(surface_id, boundary, x0, name) - - elif opencg_surface.type == 'y-plane': - y0 = opencg_surface.y0 - openmc_surface = openmc.YPlane(surface_id, boundary, y0, name) - - elif opencg_surface.type == 'z-plane': - z0 = opencg_surface.z0 - openmc_surface = openmc.ZPlane(surface_id, boundary, z0, name) - - elif opencg_surface.type == 'x-cylinder': - y0 = opencg_surface.y0 - z0 = opencg_surface.z0 - R = opencg_surface.r - openmc_surface = openmc.XCylinder(surface_id, boundary, y0, z0, R, name) - - elif opencg_surface.type == 'y-cylinder': - x0 = opencg_surface.x0 - z0 = opencg_surface.z0 - R = opencg_surface.r - openmc_surface = openmc.YCylinder(surface_id, boundary, x0, z0, R, name) - - elif opencg_surface.type == 'z-cylinder': - x0 = opencg_surface.x0 - y0 = opencg_surface.y0 - R = opencg_surface.r - openmc_surface = openmc.ZCylinder(surface_id, boundary, x0, y0, R, name) - - else: - msg = 'Unable to create an OpenMC Surface from an OpenCG ' \ - 'Surface of type "{0}" since it is not a compatible ' \ - 'Surface type in OpenMC'.format(opencg_surface.type) - raise ValueError(msg) - - # Add the OpenMC Surface to the global collection of all OpenMC Surfaces - OPENMC_SURFACES[surface_id] = openmc_surface - - # Add the OpenCG Surface to the global collection of all OpenCG Surfaces - OPENCG_SURFACES[surface_id] = opencg_surface - - return openmc_surface - - -def get_compatible_opencg_surfaces(opencg_surface): - """Generate OpenCG surfaces that are compatible with OpenMC equivalent to an - OpenCG surface that is not compatible. For example, this method may be used - to convert a ZSquarePrism OpenCG surface into a collection of equivalent - XPlane and YPlane OpenCG surfaces. - - Parameters - ---------- - opencg_surface : opencg.Surface - OpenCG surface that is incompatible with OpenMC - - Returns - ------- - surfaces : list of opencg.Surface - Collection of surfaces equivalent to the original one but compatible - with OpenMC - - """ - - cv.check_type('opencg_surface', opencg_surface, opencg.Surface) - - surface_id = opencg_surface.id - - # If this Surface was already created, use it - if surface_id in OPENMC_SURFACES: - return OPENMC_SURFACES[surface_id] - - # Create an OpenMC Surface to represent this OpenCG Surface - name = opencg_surface.name - boundary = opencg_surface.boundary_type - - if opencg_surface.type == 'x-squareprism': - y0 = opencg_surface.y0 - z0 = opencg_surface.z0 - R = opencg_surface.r - - # Create a list of the four planes we need - left = opencg.YPlane(name=name, boundary=boundary, y0=y0-R) - right = opencg.YPlane(name=name, boundary=boundary, y0=y0+R) - bottom = opencg.ZPlane(name=name, boundary=boundary, z0=z0-R) - top = opencg.ZPlane(name=name, boundary=boundary, z0=z0+R) - surfaces = [left, right, bottom, top] - - elif opencg_surface.type == 'y-squareprism': - x0 = opencg_surface.x0 - z0 = opencg_surface.z0 - R = opencg_surface.r - - # Create a list of the four planes we need - left = opencg.XPlane(name=name, boundary=boundary, x0=x0-R) - right = opencg.XPlane(name=name, boundary=boundary, x0=x0+R) - bottom = opencg.ZPlane(name=name, boundary=boundary, z0=z0-R) - top = opencg.ZPlane(name=name, boundary=boundary, z0=z0+R) - surfaces = [left, right, bottom, top] - - elif opencg_surface.type == 'z-squareprism': - 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) - right = opencg.XPlane(name=name, boundary=boundary, x0=x0+R) - bottom = opencg.YPlane(name=name, boundary=boundary, y0=y0-R) - top = opencg.YPlane(name=name, boundary=boundary, y0=y0+R) - surfaces = [left, right, bottom, top] - - else: - msg = 'Unable to create a compatible OpenMC Surface an OpenCG ' \ - 'Surface of type "{0}" since it already a compatible ' \ - 'Surface type in OpenMC'.format(opencg_surface.type) - raise ValueError(msg) - - # Add the OpenMC Surface(s) to the global collection of all OpenMC Surfaces - OPENMC_SURFACES[surface_id] = surfaces - - # Add the OpenCG Surface to the global collection of all OpenCG Surfaces - OPENCG_SURFACES[surface_id] = opencg_surface - - return surfaces - - -def get_opencg_cell(openmc_cell): - """Return an OpenCG cell corresponding to an OpenMC cell. - - Parameters - ---------- - openmc_cell : openmc.universe.Cell - OpenMC cell - - Returns - ------- - opencg_cell : opencg.Cell - Equivalent OpenCG cell - - """ - - cv.check_type('openmc_cell', openmc_cell, openmc.Cell) - - cell_id = openmc_cell.id - - # If this Cell was already created, use it - if cell_id in OPENCG_CELLS: - return OPENCG_CELLS[cell_id] - - # Create an OpenCG Cell to represent this OpenMC Cell - name = openmc_cell.name - opencg_cell = opencg.Cell(cell_id, name) - - fill = openmc_cell.fill - - if openmc_cell.fill_type == 'material': - opencg_cell.fill = get_opencg_material(fill) - elif openmc_cell.fill_type == 'universe': - opencg_cell.fill = get_opencg_universe(fill) - else: - opencg_cell.fill = get_opencg_lattice(fill) - - if openmc_cell.rotation is not None: - opencg_cell.rotation = openmc_cell.rotation - - if openmc_cell.translation is not None: - opencg_cell.translation = openmc_cell.translation - - # Add surfaces to OpenCG cell from OpenMC cell region. Right now this only - # works if the region is a single half-space or an intersection of - # half-spaces, i.e., no complex cells. - region = openmc_cell.region - if region is not None: - if isinstance(region, openmc.Halfspace): - surface = region.surface - halfspace = -1 if region.side == '-' else 1 - opencg_cell.add_surface(get_opencg_surface(surface), halfspace) - elif isinstance(region, openmc.Intersection): - for node in region.nodes: - if not isinstance(node, openmc.Halfspace): - raise NotImplementedError("Complex cells not yet " - "supported in OpenCG.") - surface = node.surface - halfspace = -1 if node.side == '-' else 1 - opencg_cell.add_surface(get_opencg_surface(surface), halfspace) - else: - raise NotImplementedError("Complex cells not yet supported " - "in OpenCG.") - - # Add the OpenMC Cell to the global collection of all OpenMC Cells - OPENMC_CELLS[cell_id] = openmc_cell - - # Add the OpenCG Cell to the global collection of all OpenCG Cells - OPENCG_CELLS[cell_id] = opencg_cell - - return opencg_cell - - -def get_compatible_opencg_cells(opencg_cell, opencg_surface, halfspace): - """Generate OpenCG cells that are compatible with OpenMC equivalent to an OpenCG - cell that is not compatible. - - Parameters - ---------- - opencg_cell : opencg.Cell - OpenCG cell - opencg_surface : opencg.Surface - OpenCG surface that causes the incompatibility, e.g. an instance of - XSquarePrism - halfspace : {-1, 1} - Which halfspace defined by the surface is contained in the cell - - Returns - ------- - compatible_cells : list of opencg.Cell - Collection of cells equivalent to the original one but compatible with - OpenMC - - """ - - cv.check_type('opencg_cell', opencg_cell, opencg.Cell) - cv.check_type('opencg_surface', opencg_surface, opencg.Surface) - cv.check_value('halfspace', halfspace, (-1, +1)) - - # Initialize an empty list for the new compatible cells - compatible_cells = [] - - # SquarePrism Surfaces - if opencg_surface.type in ['x-squareprism', 'y-squareprism', - 'z-squareprism']: - - # Get the compatible Surfaces (XPlanes and YPlanes) - compatible_surfaces = get_compatible_opencg_surfaces(opencg_surface) - - opencg_cell.remove_surface(opencg_surface) - - # If Cell is inside SquarePrism, add "inside" of Surface halfspaces - if halfspace == -1: - opencg_cell.add_surface(compatible_surfaces[0], +1) - opencg_cell.add_surface(compatible_surfaces[1], -1) - opencg_cell.add_surface(compatible_surfaces[2], +1) - opencg_cell.add_surface(compatible_surfaces[3], -1) - compatible_cells.append(opencg_cell) - - # If Cell is outside SquarePrism, add "outside" of Surface halfspaces - else: - # Create 8 Cell clones to represent each of the disjoint planar - # Surface halfspace intersections - num_clones = 8 - - for clone_id in range(num_clones): - # Create cloned OpenCG Cell with Surfaces compatible with OpenMC - clone = opencg_cell.clone() - compatible_cells.append(clone) - - # Top left subcell - add left XPlane, top YPlane - if clone_id == 0: - clone.add_surface(compatible_surfaces[0], -1) - clone.add_surface(compatible_surfaces[3], +1) - - # Top center subcell - add top YPlane, left/right XPlanes - elif clone_id == 1: - clone.add_surface(compatible_surfaces[0], +1) - clone.add_surface(compatible_surfaces[1], -1) - clone.add_surface(compatible_surfaces[3], +1) - - # Top right subcell - add top YPlane, right XPlane - elif clone_id == 2: - clone.add_surface(compatible_surfaces[1], +1) - clone.add_surface(compatible_surfaces[3], +1) - - # Right center subcell - add right XPlane, top/bottom YPlanes - elif clone_id == 3: - clone.add_surface(compatible_surfaces[1], +1) - clone.add_surface(compatible_surfaces[3], -1) - clone.add_surface(compatible_surfaces[2], +1) - - # Bottom right subcell - add right XPlane, bottom YPlane - elif clone_id == 4: - clone.add_surface(compatible_surfaces[1], +1) - clone.add_surface(compatible_surfaces[2], -1) - - # Bottom center subcell - add bottom YPlane, left/right XPlanes - elif clone_id == 5: - clone.add_surface(compatible_surfaces[0], +1) - clone.add_surface(compatible_surfaces[1], -1) - clone.add_surface(compatible_surfaces[2], -1) - - # Bottom left subcell - add bottom YPlane, left XPlane - elif clone_id == 6: - clone.add_surface(compatible_surfaces[0], -1) - clone.add_surface(compatible_surfaces[2], -1) - - # Left center subcell - add left XPlane, top/bottom YPlanes - elif clone_id == 7: - clone.add_surface(compatible_surfaces[0], -1) - clone.add_surface(compatible_surfaces[3], -1) - clone.add_surface(compatible_surfaces[2], +1) - - # Remove redundant Surfaces from the Cells - for cell in compatible_cells: - cell.remove_redundant_surfaces() - - # Return the list of OpenMC compatible OpenCG Cells - return compatible_cells - - -def make_opencg_cells_compatible(opencg_universe): - """Make all cells in an OpenCG universe compatible with OpenMC. - - Parameters - ---------- - opencg_universe : opencg.Universe - Universe to check - - """ - - cv.check_type('opencg_universe', opencg_universe, opencg.Universe) - - # Check all OpenCG Cells in this Universe for compatibility with OpenMC - opencg_cells = opencg_universe.cells - - for opencg_cell in opencg_cells.values(): - - # Check each of the OpenCG Surfaces for OpenMC compatibility - surfaces = opencg_cell.surfaces - - for surface_id in surfaces: - surface = surfaces[surface_id][0] - halfspace = surfaces[surface_id][1] - - # If this Surface is not compatible with OpenMC, create compatible - # OpenCG cells with a compatible version of this OpenCG Surface - if not is_opencg_surface_compatible(surface): - - # Get one or more OpenCG Cells that are compatible with OpenMC - # NOTE: This does not necessarily make OpenCG fully compatible. - # It only removes the incompatible Surface and replaces it with - # compatible OpenCG Surface(s). The recursive call at the end - # of this block is necessary in the event that there are more - # incompatible Surfaces in this Cell that are not accounted for. - cells = get_compatible_opencg_cells(opencg_cell, - surface, halfspace) - - # Remove the non-compatible OpenCG Cell from the Universe - opencg_universe.remove_cell(opencg_cell) - - # Add the compatible OpenCG Cells to the Universe - opencg_universe.add_cells(cells) - - # Make recursive call to look at the updated state of the - # OpenCG Universe and return - return make_opencg_cells_compatible(opencg_universe) - - # If all OpenCG Cells in the OpenCG Universe are compatible, return - return - - -def get_openmc_cell(opencg_cell): - """Return an OpenMC cell corresponding to an OpenCG cell. - - Parameters - ---------- - opencg_cell : opencg.Cell - OpenCG cell - - Returns - ------- - openmc_cell : openmc.universe.Cell - Equivalent OpenMC cell - - """ - - cv.check_type('opencg_cell', opencg_cell, opencg.Cell) - - cell_id = opencg_cell.id - - # If this Cell was already created, use it - if cell_id in OPENMC_CELLS: - return OPENMC_CELLS[cell_id] - - # Create an OpenCG Cell to represent this OpenMC Cell - name = opencg_cell.name - openmc_cell = openmc.Cell(cell_id, name) - - fill = opencg_cell.fill - - if opencg_cell.type == 'universe': - openmc_cell.fill = get_openmc_universe(fill) - elif opencg_cell.type == 'lattice': - openmc_cell.fill = get_openmc_lattice(fill) - else: - openmc_cell.fill = get_openmc_material(fill) - - if opencg_cell.rotation is not None: - rotation = np.asarray(opencg_cell.rotation, dtype=np.float64) - openmc_cell.rotation = rotation - - if opencg_cell.translation is not None: - translation = np.asarray(opencg_cell.translation, dtype=np.float64) - openmc_cell.translation = translation - - if opencg_cell.surfaces: - surfaces = [] - operators = [] - for surface, halfspace in opencg_cell.surfaces.values(): - surfaces.append(get_openmc_surface(surface)) - operators.append(operator.neg if halfspace == -1 else operator.pos) - openmc_cell.region = openmc.Intersection( - *[op(s) for op, s in zip(operators, surfaces)]) - - # Add the OpenMC Cell to the global collection of all OpenMC Cells - OPENMC_CELLS[cell_id] = openmc_cell - - # Add the OpenCG Cell to the global collection of all OpenCG Cells - OPENCG_CELLS[cell_id] = opencg_cell - - return openmc_cell - - -def get_opencg_universe(openmc_universe): - """Return an OpenCG universe corresponding to an OpenMC universe. - - Parameters - ---------- - openmc_universe : openmc.universe.Universe - OpenMC universe - - Returns - ------- - opencg_universe : opencg.Universe - Equivalent OpenCG universe - - """ - - cv.check_type('openmc_universe', openmc_universe, openmc.Universe) - - universe_id = openmc_universe.id - - # If this Universe was already created, use it - if universe_id in OPENCG_UNIVERSES: - return OPENCG_UNIVERSES[universe_id] - - # Create an OpenCG Universe to represent this OpenMC Universe - name = openmc_universe.name - opencg_universe = opencg.Universe(universe_id, name) - - # Convert all OpenMC Cells in this Universe to OpenCG Cells - openmc_cells = openmc_universe.cells - - for openmc_cell in openmc_cells.values(): - opencg_cell = get_opencg_cell(openmc_cell) - opencg_universe.add_cell(opencg_cell) - - # Add the OpenMC Universe to the global collection of all OpenMC Universes - OPENMC_UNIVERSES[universe_id] = openmc_universe - - # Add the OpenCG Universe to the global collection of all OpenCG Universes - OPENCG_UNIVERSES[universe_id] = opencg_universe - - return opencg_universe - - -def get_openmc_universe(opencg_universe): - """Return an OpenMC universe corresponding to an OpenCG universe. - - Parameters - ---------- - opencg_universe : opencg.Universe - OpenCG universe - - Returns - ------- - openmc_universe : openmc.universe.Universe - Equivalent OpenMC universe - - """ - - cv.check_type('opencg_universe', opencg_universe, opencg.Universe) - - universe_id = opencg_universe.id - - # If this Universe was already created, use it - if universe_id in OPENMC_UNIVERSES: - return OPENMC_UNIVERSES[universe_id] - - # Make all OpenCG Cells and Surfaces in this Universe compatible with OpenMC - make_opencg_cells_compatible(opencg_universe) - - # Create an OpenMC Universe to represent this OpenCSg Universe - name = opencg_universe.name - openmc_universe = openmc.Universe(universe_id, name) - - # Convert all OpenCG Cells in this Universe to OpenMC Cells - opencg_cells = opencg_universe.cells - - for opencg_cell in opencg_cells.values(): - openmc_cell = get_openmc_cell(opencg_cell) - openmc_universe.add_cell(openmc_cell) - - # Add the OpenMC Universe to the global collection of all OpenMC Universes - OPENMC_UNIVERSES[universe_id] = openmc_universe - - # Add the OpenCG Universe to the global collection of all OpenCG Universes - OPENCG_UNIVERSES[universe_id] = opencg_universe - - return openmc_universe - - -def get_opencg_lattice(openmc_lattice): - """Return an OpenCG lattice corresponding to an OpenMC lattice. - - Parameters - ---------- - openmc_lattice : openmc.universe.Lattice - OpenMC lattice - - Returns - ------- - opencg_lattice : opencg.Lattice - Equivalent OpenCG lattice - - """ - - cv.check_type('openmc_lattice', openmc_lattice, openmc.Lattice) - - lattice_id = openmc_lattice.id - - # If this Lattice was already created, use it - if lattice_id in OPENCG_LATTICES: - return OPENCG_LATTICES[lattice_id] - - # Create an OpenCG Lattice to represent this OpenMC Lattice - name = openmc_lattice.name - dimension = openmc_lattice.shape - pitch = openmc_lattice.pitch - lower_left = openmc_lattice.lower_left - universes = openmc_lattice.universes - outer = openmc_lattice.outer - - # Convert 2D dimension to 3D for OpenCG - if len(dimension) == 2: - new_dimension = np.ones(3, dtype=np.int) - new_dimension[:2] = dimension - dimension = new_dimension - - # Convert 2D pitch to 3D for OpenCG - if len(pitch) == 2: - new_pitch = np.ones(3, dtype=np.float64) * np.finfo(np.float64).max - new_pitch[:2] = pitch - pitch = new_pitch - - # Convert 2D lower left to 3D for OpenCG - if len(lower_left) == 2: - new_lower_left = np.ones(3, dtype=np.float64) * np.finfo(np.float64).min - new_lower_left[:2] = lower_left - lower_left = new_lower_left - - # Convert 2D universes array to 3D for OpenCG - if len(universes.shape) == 2: - new_universes = universes.copy() - new_universes.shape = (1,) + universes.shape - universes = new_universes - - # Initialize an empty array for the OpenCG nested Universes in this Lattice - universe_array = np.empty(tuple(np.array(dimension)[::-1]), - dtype=opencg.Universe) - - # Create OpenCG Universes for each unique nested Universe in this Lattice - unique_universes = openmc_lattice.get_unique_universes() - - for universe_id, universe in unique_universes.items(): - unique_universes[universe_id] = get_opencg_universe(universe) - - # Build the nested Universe array - for z in range(dimension[2]): - for y in range(dimension[1]): - for x in range(dimension[0]): - universe_id = universes[z][y][x].id - universe_array[z][y][x] = unique_universes[universe_id] - - opencg_lattice = opencg.Lattice(lattice_id, name) - opencg_lattice.dimension = dimension - opencg_lattice.width = pitch - opencg_lattice.universes = universe_array - if outer is not None: - opencg_lattice.outside = get_opencg_universe(outer) - - offset = np.array(lower_left, dtype=np.float64) - \ - ((np.array(pitch, dtype=np.float64) * - np.array(dimension, dtype=np.float64))) / -2.0 - opencg_lattice.offset = offset - - # Add the OpenMC Lattice to the global collection of all OpenMC Lattices - OPENMC_LATTICES[lattice_id] = openmc_lattice - - # Add the OpenCG Lattice to the global collection of all OpenCG Lattices - OPENCG_LATTICES[lattice_id] = opencg_lattice - - return opencg_lattice - - -def get_openmc_lattice(opencg_lattice): - """Return an OpenMC lattice corresponding to an OpenCG lattice. - - Parameters - ---------- - opencg_lattice : opencg.Lattice - OpenCG lattice - - Returns - ------- - openmc_lattice : openmc.universe.Lattice - Equivalent OpenMC lattice - - """ - - cv.check_type('opencg_lattice', opencg_lattice, opencg.Lattice) - - lattice_id = opencg_lattice.id - - # If this Lattice was already created, use it - if lattice_id in OPENMC_LATTICES: - return OPENMC_LATTICES[lattice_id] - - name = opencg_lattice.name - dimension = opencg_lattice.dimension - width = opencg_lattice.width - offset = opencg_lattice.offset - universes = opencg_lattice.universes - outer = opencg_lattice.outside - - # Initialize an empty array for the OpenMC nested Universes in this Lattice - universe_array = np.empty(tuple(np.array(dimension)[::-1]), - dtype=openmc.Universe) - - # Create OpenMC Universes for each unique nested Universe in this Lattice - unique_universes = opencg_lattice.get_unique_universes() - - for universe_id, universe in unique_universes.items(): - unique_universes[universe_id] = get_openmc_universe(universe) - - # Build the nested Universe array - for z in range(dimension[2]): - for y in range(dimension[1]): - for x in range(dimension[0]): - universe_id = universes[z][y][x].id - universe_array[z][y][x] = unique_universes[universe_id] - - # Reverse y-dimension in array to match ordering in OpenCG - universe_array = universe_array[:, ::-1, :] - - lower_left = np.array(offset, dtype=np.float64) + \ - ((np.array(width, dtype=np.float64) * - np.array(dimension, dtype=np.float64))) / -2.0 - - openmc_lattice = openmc.RectLattice(lattice_id=lattice_id, name=name) - openmc_lattice.pitch = width - openmc_lattice.universes = universe_array - openmc_lattice.lower_left = lower_left - if outer is not None: - openmc_lattice.outer = get_openmc_universe(outer) - - # Add the OpenMC Lattice to the global collection of all OpenMC Lattices - OPENMC_LATTICES[lattice_id] = openmc_lattice - - # Add the OpenCG Lattice to the global collection of all OpenCG Lattices - OPENCG_LATTICES[lattice_id] = opencg_lattice - - return openmc_lattice - - -def get_opencg_geometry(openmc_geometry): - """Return an OpenCG geometry corresponding to an OpenMC geometry. - - Parameters - ---------- - openmc_geometry : openmc.universe.Geometry - OpenMC geometry - - Returns - ------- - opencg_geometry : opencg.Geometry - Equivalent OpenCG geometry - - """ - - cv.check_type('openmc_geometry', openmc_geometry, openmc.Geometry) - - # Clear dictionaries and auto-generated IDs - OPENMC_SURFACES.clear() - OPENCG_SURFACES.clear() - OPENMC_CELLS.clear() - OPENCG_CELLS.clear() - OPENMC_UNIVERSES.clear() - OPENCG_UNIVERSES.clear() - OPENMC_LATTICES.clear() - OPENCG_LATTICES.clear() - - openmc_root_universe = openmc_geometry.root_universe - opencg_root_universe = get_opencg_universe(openmc_root_universe) - - opencg_geometry = opencg.Geometry() - opencg_geometry.root_universe = opencg_root_universe - opencg_geometry.initialize_cell_offsets() - opencg_geometry.assign_auto_ids() - - return opencg_geometry - - -def get_openmc_geometry(opencg_geometry, compatible=False): - """Return an OpenMC geometry corresponding to an OpenCG geometry. - - Parameters - ---------- - opencg_geometry : opencg.Geometry - OpenCG geometry - compatible : bool - Whether the OpenCG geometry is compatible with OpenMC's geometric - primitives. This should be set to False if the OpenCG geometry - uses SquarePrism surfaces. False by default. - - Returns - ------- - openmc_geometry : openmc.universe.Geometry - Equivalent OpenMC geometry - - """ - - cv.check_type('opencg_geometry', opencg_geometry, opencg.Geometry) - - # Deep copy the goemetry since it may be modified to make all Surfaces - # compatible with OpenMC's specifications - opencg_geometry.assign_auto_ids() - opencg_geometry = copy.deepcopy(opencg_geometry) - - # Clear dictionaries and auto-generated ID - OPENMC_SURFACES.clear() - OPENCG_SURFACES.clear() - OPENMC_CELLS.clear() - OPENCG_CELLS.clear() - OPENMC_UNIVERSES.clear() - OPENCG_UNIVERSES.clear() - OPENMC_LATTICES.clear() - OPENCG_LATTICES.clear() - - # Make the entire geometry "compatible" before assigning auto IDs - if not compatible: - universes = opencg_geometry.get_all_universes() - for universe in universes.values(): - if not isinstance(universe, opencg.Lattice): - make_opencg_cells_compatible(universe) - - opencg_geometry.assign_auto_ids() - - opencg_root_universe = opencg_geometry.root_universe - openmc_root_universe = get_openmc_universe(opencg_root_universe) - - openmc_geometry = openmc.Geometry() - openmc_geometry.root_universe = openmc_root_universe - - return openmc_geometry diff --git a/openmc/openmoc_compatible.py b/openmc/openmoc_compatible.py new file mode 100644 index 000000000..fcedc945a --- /dev/null +++ b/openmc/openmoc_compatible.py @@ -0,0 +1,738 @@ +import copy +import operator + +import numpy as np + +import openmoc +import openmc +import openmc.checkvalue as cv + + +# A dictionary of all OpenMC Materials created +# Keys - Material IDs +# Values - Materials +OPENMC_MATERIALS = {} + +# A dictionary of all OpenMOC Materials created +# Keys - Material IDs +# Values - Materials +OPENMOC_MATERIALS = {} + +# A dictionary of all OpenMC Surfaces created +# Keys - Surface IDs +# Values - Surfaces +OPENMC_SURFACES = {} + +# A dictionary of all OpenMOC Surfaces created +# Keys - Surface IDs +# Values - Surfaces +OPENMOC_SURFACES = {} + +# A dictionary of all OpenMC Cells created +# Keys - Cell IDs +# Values - Cells +OPENMC_CELLS = {} + +# A dictionary of all OpenMOC Cells created +# Keys - Cell IDs +# Values - Cells +OPENMOC_CELLS = {} + +# A dictionary of all OpenMC Universes created +# Keys - Universes IDs +# Values - Universes +OPENMC_UNIVERSES = {} + +# A dictionary of all OpenMOC Universes created +# Keys - Universes IDs +# Values - Universes +OPENMOC_UNIVERSES = {} + +# A dictionary of all OpenMC Lattices created +# Keys - Lattice IDs +# Values - Lattices +OPENMC_LATTICES = {} + +# A dictionary of all OpenMOC Lattices created +# Keys - Lattice IDs +# Values - Lattices +OPENMOC_LATTICES = {} + + +def get_openmoc_material(openmc_material): + """Return an OpenMOC material corresponding to an OpenMC material. + + Parameters + ---------- + openmc_material : openmc.Material + OpenMC material + + Returns + ------- + openmoc_material : openmoc.Material + Equivalent OpenMOC material + + """ + + cv.check_type('openmc_material', openmc_material, openmc.Material) + + material_id = openmc_material.id + + # If this Material was already created, use it + if material_id in OPENMOC_MATERIALS: + return OPENMOC_MATERIALS[material_id] + + # Create an OpenMOC Material to represent this OpenMC Material + name = str(openmc_material.name) + openmoc_material = openmoc.Material(id=material_id, name=name) + + # Add the OpenMC Material to the global collection of all OpenMC Materials + OPENMC_MATERIALS[material_id] = openmc_material + + # Add the OpenMOC Material to the global collection of all OpenMOC Materials + OPENMOC_MATERIALS[material_id] = openmoc_material + + return openmoc_material + + +def get_openmc_material(openmoc_material): + """Return an OpenMC material corresponding to an OpenMOC material. + + Parameters + ---------- + openmoc_material : openmoc.Material + OpenMOC material + + Returns + ------- + openmc_material : openmc.Material + Equivalent OpenMC material + + """ + + cv.check_type('openmoc_material', openmoc_material, openmoc.Material) + + material_id = openmoc_material.getId() + + # If this Material was already created, use it + if material_id in OPENMC_MATERIALS: + return OPENMC_MATERIALS[material_id] + + # Create an OpenMC Material to represent this OpenMOC Material + name = openmoc_material.getName() + openmc_material = openmc.Material(material_id=material_id, name=name) + + # Add the OpenMOC Material to the global collection of all OpenMOC Materials + OPENMOC_MATERIALS[material_id] = openmoc_material + + # Add the OpenMC Material to the global collection of all OpenMC Materials + OPENMC_MATERIALS[material_id] = openmc_material + + return openmc_material + + +def get_openmoc_surface(openmc_surface): + """Return an OpenMOC surface corresponding to an OpenMC surface. + + Parameters + ---------- + openmc_surface : openmc.Surface + OpenMC surface + + Returns + ------- + openmoc_surface : openmoc.Surface + Equivalent OpenMOC surface + + """ + + cv.check_type('openmc_surface', openmc_surface, openmc.Surface) + + surface_id = openmc_surface.id + + # If this Material was already created, use it + if surface_id in OPENMOC_SURFACES: + return OPENMOC_SURFACES[surface_id] + + # Create an OpenMOC Surface to represent this OpenMC Surface + name = openmc_surface.name + + # Determine the type of boundary conditions applied to the Surface + if openmc_surface.boundary_type == 'vacuum': + boundary = openmoc.VACUUM + elif openmc_surface.boundary_type == 'reflective': + boundary = openmoc.REFLECTIVE + elif openmc_surface.boundary_type == 'periodic': + boundary = openmoc.PERIODIC + else: + boundary = openmoc.BOUNDARY_NONE + + if openmc_surface.type == 'plane': + A = openmc_surface.a + B = openmc_surface.b + C = openmc_surface.c + D = openmc_surface.d + openmoc_surface = openmoc.Plane(A, B, C, D, surface_id, name) + + elif openmc_surface.type == 'x-plane': + x0 = openmc_surface.x0 + openmoc_surface = openmoc.XPlane(x0, surface_id, name) + + elif openmc_surface.type == 'y-plane': + y0 = openmc_surface.y0 + openmoc_surface = openmoc.YPlane(y0, surface_id, name) + + elif openmc_surface.type == 'z-plane': + z0 = openmc_surface.z0 + openmoc_surface = openmoc.ZPlane(z0, surface_id, name) + + elif openmc_surface.type == 'z-cylinder': + x0 = openmc_surface.x0 + y0 = openmc_surface.y0 + R = openmc_surface.r + openmoc_surface = openmoc.ZCylinder(x0, y0, R, surface_id, name) + + else: + msg = 'Unable to create an OpenMOC Surface from an OpenMC ' \ + 'Surface of type "{}" since it is not a compatible ' \ + 'Surface type in OpenMOC'.format(type(openmc_surface)) + raise ValueError(msg) + + # Set the boundary condition for this Surface + openmoc_surface.setBoundaryType(boundary) + + # Add the OpenMC Surface to the global collection of all OpenMC Surfaces + OPENMC_SURFACES[surface_id] = openmc_surface + + # Add the OpenMOC Surface to the global collection of all OpenMOC Surfaces + OPENMOC_SURFACES[surface_id] = openmoc_surface + + return openmoc_surface + + +def get_openmc_surface(openmoc_surface): + """Return an OpenMC surface corresponding to an OpenMOC surface. + + Parameters + ---------- + openmoc_surface : openmoc.Surface + OpenMOC surface + + Returns + ------- + openmc_surface : openmc.Surface + Equivalent OpenMC surface + + """ + + cv.check_type('openmoc_surface', openmoc_surface, openmoc.Surface) + + surface_id = openmoc_surface.id + + # If this Surface was already created, use it + if surface_id in OPENMC_SURFACES: + return OPENMC_SURFACES[surface_id] + + # Create an OpenMC Surface to represent this OpenMOC Surface + name = openmoc_surface.name + + # Correct for OpenMC's syntax for Surfaces dividing Cells + boundary = openmoc_surface.getBoundaryType() + if boundary == openmoc.VACUUM: + boundary = 'vacuum' + elif boundary == openmoc.REFLECTIVE: + boundary = 'reflective' + elif boundary == openmoc.PERIODIC: + boundary = 'periodic' + else: + boundary = 'transmission' + + if openmoc_surface.getSurfaceType() == openmoc.PLANE: + A = openmoc_surface.getA() + B = openmoc_surface.getB() + C = openmoc_surface.getC() + D = openmoc_surface.getD() + openmc_surface = openmc.Plane(surface_id, boundary, A, B, C, D, name) + + elif openmoc_surface.getSurfaceType() == openmoc.XPLANE: + x0 = openmoc_surface.getX() + openmc_surface = openmc.XPlane(surface_id, boundary, x0, name) + + elif openmoc_surface.getSurfaceType() == openmoc.YPLANE: + y0 = openmoc_surface.getY() + openmc_surface = openmc.YPlane(surface_id, boundary, y0, name) + + elif openmoc_surface.getSurfaceType() == openmoc.ZPLANE: + z0 = openmoc_surface.getZ() + openmc_surface = openmc.ZPlane(surface_id, boundary, z0, name) + + elif openmoc_surface.getSurfaceType() == openmoc.ZCYLINDER: + x0 = openmoc_surface.getX0() + y0 = openmoc_surface.getY0() + R = openmoc_surface.getR() + openmc_surface = openmc.ZCylinder(surface_id, boundary, x0, y0, R, name) + + # Add the OpenMC Surface to the global collection of all OpenMC Surfaces + OPENMC_SURFACES[surface_id] = openmc_surface + + # Add the OpenMOC Surface to the global collection of all OpenMOC Surfaces + OPENMOC_SURFACES[surface_id] = openmoc_surface + + return openmc_surface + + +def get_openmoc_cell(openmc_cell): + """Return an OpenMOC cell corresponding to an OpenMC cell. + + Parameters + ---------- + openmc_cell : openmc.Cell + OpenMC cell + + Returns + ------- + openmoc_cell : openmoc.Cell + Equivalent OpenMOC cell + + """ + + cv.check_type('openmc_cell', openmc_cell, openmc.Cell) + + cell_id = openmc_cell.id + + # If this Cell was already created, use it + if cell_id in OPENMOC_CELLS: + return OPENMOC_CELLS[cell_id] + + # Create an OpenMOC Cell to represent this OpenMC Cell + name = openmc_cell.name + openmoc_cell = openmoc.Cell(cell_id, name) + + fill = openmc_cell.fill + + if openmc_cell.fill_type == 'material': + openmoc_cell.setFill(get_openmoc_material(fill)) + elif openmc_cell.fill_type == 'universe': + openmoc_cell.setFill(get_openmoc_universe(fill)) + else: + openmoc_cell.setFill(get_openmoc_lattice(fill)) + + if openmc_cell.rotation is not None: + rotation = np.asarray(openmc_cell.rotation, dtype=np.float64) + openmoc_cell.setRotation(rotation) + if openmc_cell.translation is not None: + translation = np.asarray(openmc_cell.translation, dtype=np.float64) + openmoc_cell.setTranslation(translation) + + # Add surfaces to OpenMOC cell from OpenMC cell region. Right now this only + # works if the region is a single half-space or an intersection of + # half-spaces, i.e., no complex cells. + region = openmc_cell.region + if region is not None: + if isinstance(region, openmc.Halfspace): + surface = region.surface + halfspace = -1 if region.side == '-' else 1 + openmoc_cell.addSurface(halfspace, get_openmoc_surface(surface)) + elif isinstance(region, openmc.Intersection): + for node in region.nodes: + if not isinstance(node, openmc.Halfspace): + raise NotImplementedError("Complex cells not yet " + "supported in OpenMOC.") + surface = node.surface + halfspace = -1 if node.side == '-' else 1 + openmoc_cell.addSurface(halfspace, get_openmoc_surface(surface)) + else: + raise NotImplementedError("Complex cells not yet supported " + "in OpenMOC.") + + # Add the OpenMC Cell to the global collection of all OpenMC Cells + OPENMC_CELLS[cell_id] = openmc_cell + + # Add the OpenMOC Cell to the global collection of all OpenMOC Cells + OPENMOC_CELLS[cell_id] = openmoc_cell + + return openmoc_cell + + +def get_openmc_cell(openmoc_cell): + """Return an OpenMC cell corresponding to an OpenMOC cell. + + Parameters + ---------- + openmoc_cell : openmoc.Cell + OpenMOC cell + + Returns + ------- + openmc_cell : openmc.Cell + Equivalent OpenMC cell + + """ + + cv.check_type('openmoc_cell', openmoc_cell, openmoc.Cell) + + cell_id = openmoc_cell.getId() + + # If this Cell was already created, use it + if cell_id in OPENMC_CELLS: + return OPENMC_CELLS[cell_id] + + # Create an OpenMOC Cell to represent this OpenMC Cell + name = openmoc_cell.getName() + openmc_cell = openmc.Cell(cell_id, name) + + if (openmoc_cell.getType() == openmoc.MATERIAL): + fill = openmoc_cell.getFillMaterial() + openmc_cell.fill = get_openmc_material(fill) + elif (openmoc_cell.getType() == openmoc.FILL): + fill = openmoc_cell.getFillUniverse() + if isinstance(fill, openmoc.Lattice): + openmc_cell.fill = get_openmc_lattice(fill) + else: + openmc_cell.fill = get_openmc_universe(fill) + + if openmoc_cell.isRotated(): + rotation = openmoc_cell.getRotation(3) + openmc_cell.rotation = rotation + if openmoc_cell.isTranslated(): + translation = openmoc_cell.getTranslation(3) + openmc_cell.translation = translation + + regions = [] + for surf_id, surf_halfspace in openmoc_cell.getSurfaces().values(): + halfspace = surf_halfspace._halfspace + surface = get_openmc_surface(surf_halfspace._surface) + regions.append(-surface if halfspace == -1 else +surface) + openmc_cell.region = openmc.Intersection(*regions) + + # Add the OpenMC Cell to the global collection of all OpenMC Cells + OPENMC_CELLS[cell_id] = openmc_cell + + # Add the OpenMOC Cell to the global collection of all OpenMOC Cells + OPENMOC_CELLS[cell_id] = openmoc_cell + + return openmc_cell + + +def get_openmoc_universe(openmc_universe): + """Return an OpenMOC universe corresponding to an OpenMC universe. + + Parameters + ---------- + openmc_universe : openmc.Universe + OpenMC universe + + Returns + ------- + openmoc_universe : openmoc.Universe + Equivalent OpenMOC universe + + """ + + cv.check_type('openmc_universe', openmc_universe, openmc.Universe) + + universe_id = openmc_universe.id + + # If this Universe was already created, use it + if universe_id in OPENMOC_UNIVERSES: + return OPENMOC_UNIVERSES[universe_id] + + # Create an OpenMOC Universe to represent this OpenMC Universe + name = openmc_universe.name + openmoc_universe = openmoc.Universe(universe_id, name) + + # Convert all OpenMC Cells in this Universe to OpenMOC Cells + openmc_cells = openmc_universe.cells + + for openmc_cell in openmc_cells.values(): + openmoc_cell = get_openmoc_cell(openmc_cell) + openmoc_universe.addCell(openmoc_cell) + + # Add the OpenMC Universe to the global collection of all OpenMC Universes + OPENMC_UNIVERSES[universe_id] = openmc_universe + + # Add the OpenMOC Universe to the global collection of all OpenMOC Universes + OPENMOC_UNIVERSES[universe_id] = openmoc_universe + + return openmoc_universe + + +def get_openmc_universe(openmoc_universe): + """Return an OpenMC universe corresponding to an OpenMOC universe. + + Parameters + ---------- + openmoc_universe : openmoc.Universe + OpenMOC universe + + Returns + ------- + openmc_universe : openmc.Universe + Equivalent OpenMC universe + + """ + + cv.check_type('openmoc_universe', openmoc_universe, openmoc.Universe) + + universe_id = openmoc_universe.getId() + + # If this Universe was already created, use it + if universe_id in OPENMC_UNIVERSES: + return OPENMC_UNIVERSES[universe_id] + + # Create an OpenMC Universe to represent this OpenMOC Universe + name = openmoc_universe.getName() + openmc_universe = openmc.Universe(universe_id, name) + + # Convert all OpenMOC Cells in this Universe to OpenMC Cells + for openmoc_cell in openmoc_universe.getCells(): + openmc_cell = get_openmc_cell(openmoc_cell) + openmc_universe.add_cell(openmc_cell) + + # Add the OpenMC Universe to the global collection of all OpenMC Universes + OPENMC_UNIVERSES[universe_id] = openmc_universe + + # Add the OpenMOC Universe to the global collection of all OpenMOC Universes + OPENMOC_UNIVERSES[universe_id] = openmoc_universe + + return openmc_universe + + +def get_openmoc_lattice(openmc_lattice): + """Return an OpenMOC lattice corresponding to an OpenMOC lattice. + + Parameters + ---------- + openmc_lattice : openmc.RectLattice + OpenMC lattice + + Returns + ------- + openmoc_lattice : openmoc.Lattice + Equivalent OpenMOC lattice + + """ + + cv.check_type('openmc_lattice', openmc_lattice, openmc.RectLattice) + + lattice_id = openmc_lattice.id + + # If this Lattice was already created, use it + if lattice_id in OPENMOC_LATTICES: + return OPENMOC_LATTICES[lattice_id] + + # Create an OpenMOC Lattice to represent this OpenMC Lattice + name = openmc_lattice.name + dimension = openmc_lattice.shape + pitch = openmc_lattice.pitch + lower_left = openmc_lattice.lower_left + universes = openmc_lattice.universes + + # Convert 2D dimension to 3D for OpenMOC + if len(dimension) == 2: + new_dimension = np.ones(3, dtype=int) + new_dimension[:2] = dimension + dimension = new_dimension + + # Convert 2D pitch to 3D for OpenMOC + if len(pitch) == 2: + new_pitch = np.ones(3, dtype=np.float64) * np.finfo(np.float64).max + new_pitch[:2] = pitch + pitch = new_pitch + + # Convert 2D lower left to 3D for OpenMOC + if len(lower_left) == 2: + new_lower_left = np.ones(3, dtype=np.float64) * np.finfo(np.float64).min + new_lower_left[:2] = lower_left + lower_left = new_lower_left + + # Convert 2D universes array to 3D for OpenMOC + if len(universes.shape) == 2: + new_universes = universes.copy() + new_universes.shape = (1,) + universes.shape + universes = new_universes + + # Initialize an empty array for the OpenMOC nested Universes in this Lattice + universe_array = np.ndarray(tuple(dimension[::-1]), dtype=openmoc.Universe) + + # Create OpenMOC Universes for each unique nested Universe in this Lattice + unique_universes = openmc_lattice.get_unique_universes() + + for universe_id, universe in unique_universes.items(): + unique_universes[universe_id] = get_openmoc_universe(universe) + + # Build the nested Universe array + for z in range(dimension[2]): + for y in range(dimension[1]): + for x in range(dimension[0]): + universe_id = universes[z][y][x].id + universe_array[z][dimension[1]-y-1][x] = unique_universes[universe_id] + + openmoc_lattice = openmoc.Lattice(lattice_id, name) + openmoc_lattice.setWidth(pitch[0], pitch[1], pitch[2]) + openmoc_lattice.setUniverses(universe_array.tolist()) + + offset = np.array(lower_left, dtype=np.float64) - \ + ((np.array(pitch, dtype=np.float64) * + np.array(dimension, dtype=np.float64))) / -2.0 + openmoc_lattice.setOffset(offset[0], offset[1], offset[2]) + + # Add the OpenMC Lattice to the global collection of all OpenMC Lattices + OPENMC_LATTICES[lattice_id] = openmc_lattice + + # Add the OpenMOC Lattice to the global collection of all OpenMOC Lattices + OPENMOC_LATTICES[lattice_id] = openmoc_lattice + + return openmoc_lattice + + +def get_openmc_lattice(openmoc_lattice): + """Return an OpenMC lattice corresponding to an OpenMOC lattice. + + Parameters + ---------- + openmoc_lattice : openmoc.Lattice + OpenMOC lattice + + Returns + ------- + openmc_lattice : openmc.RectLattice + Equivalent OpenMC lattice + + """ + + cv.check_type('openmoc_lattice', openmoc_lattice, openmoc.Lattice) + + lattice_id = openmoc_lattice.getId() + + # If this Lattice was already created, use it + if lattice_id in OPENMC_LATTICES: + return OPENMC_LATTICES[lattice_id] + + name = openmoc_lattice.getName() + dimension = [1, openmoc_lattice.getNumY(), openmoc_lattice.getNumX()] + width = [1, openmoc_lattice.getWidthY(), openmoc_lattice.getWidthX()] + offset = openmoc_lattice.getOffset() + lower_left = np.array(offset, dtype=np.float64) + \ + ((np.array(width, dtype=np.float64) * + np.array(dimension, dtype=np.float64))) / -2.0 + + # Initialize an empty array for the OpenMOC nested Universes in this Lattice + universe_array = np.ndarray(tuple(np.array(dimension)[::-1]), + dtype=openmoc.Universe) + + # Create OpenMOC Universes for each unique nested Universe in this Lattice + unique_universes = openmoc_lattice.getUniqueUniverses() + + for universe_id, universe in unique_universes.items(): + unique_universes[universe_id] = get_openmc_universe(universe) + + # Build the nested Universe array + for z in range(dimension[2]): + for y in range(dimension[1]): + for x in range(dimension[0]): + universe = openmoc_lattice.getUniverse(x, y) + universe_id = universe.getId() + universe_array[z][dimension[1]-y-1][x] = unique_universes[universe_id] + + openmc_lattice = openmc.RectLattice(lattice_id=lattice_id, name=name) + openmc_lattice.pitch = width + openmc_lattice.lower_left = lower_left + openmc_lattice.universes = universe_array + + # Add the OpenMC Lattice to the global collection of all OpenMC Lattices + OPENMC_LATTICES[lattice_id] = openmc_lattice + + # Add the OpenMOC Lattice to the global collection of all OpenMOC Lattices + OPENMOC_LATTICES[lattice_id] = openmoc_lattice + + return openmc_lattice + + +def get_openmoc_geometry(openmc_geometry): + """Return an OpenMC geometry corresponding to an OpenMOC geometry. + + Parameters + ---------- + openmc_geometry : openmc.Geometry + OpenMC geometry + + Returns + ------- + openmoc_geometry : openmoc.Geometry + Equivalent OpenMOC geometry + + """ + + cv.check_type('openmc_geometry', openmc_geometry, openmc.Geometry) + + # Clear dictionaries and auto-generated IDs + OPENMC_SURFACES.clear() + OPENMOC_SURFACES.clear() + OPENMC_CELLS.clear() + OPENMOC_CELLS.clear() + OPENMC_UNIVERSES.clear() + OPENMOC_UNIVERSES.clear() + OPENMC_LATTICES.clear() + OPENMOC_LATTICES.clear() + + openmc_root_universe = openmc_geometry.root_universe + openmoc_root_universe = get_openmoc_universe(openmc_root_universe) + + openmoc_geometry = openmoc.Geometry() + openmoc_geometry.setRootUniverse(openmoc_root_universe) + + # Update OpenMOC's auto-generated object IDs (e.g., Surface, Material) + # with the maximum of those created from the OpenMC objects + all_materials = openmoc_geometry.getAllMaterials() + all_surfaces = openmoc_geometry.getAllSurfaces() + all_cells = openmoc_geometry.getAllCells() + all_universes = openmoc_geometry.getAllUniverses() + + max_material_id = max(all_materials.keys()) + max_surface_id = max(all_surfaces.keys()) + max_cell_id = max(all_cells.keys()) + max_universe_id = max(all_universes.keys()) + + openmoc.maximize_material_id(max_material_id+1) + openmoc.maximize_surface_id(max_surface_id+1) + openmoc.maximize_cell_id(max_cell_id+1) + openmoc.maximize_universe_id(max_universe_id+1) + + return openmoc_geometry + + +def get_openmc_geometry(openmoc_geometry): + """Return an OpenMC geometry corresponding to an OpenMOC geometry. + + Parameters + ---------- + openmoc_geometry : openmoc.Geometry + OpenMOC geometry + + Returns + ------- + openmc_geometry : openmc.Geometry + Equivalent OpenMC geometry + + """ + + cv.check_type('openmoc_geometry', openmoc_geometry, openmoc.Geometry) + + # Clear dictionaries and auto-generated ID + OPENMC_SURFACES.clear() + OPENMOC_SURFACES.clear() + OPENMC_CELLS.clear() + OPENMOC_CELLS.clear() + OPENMC_UNIVERSES.clear() + OPENMOC_UNIVERSES.clear() + OPENMC_LATTICES.clear() + OPENMOC_LATTICES.clear() + + openmoc_root_universe = \ + openmoc_geometry.getRootUniverse(openmoc_root_universe) + + openmc_geometry = openmc.Geometry() + openmc_geometry.root_universe = openmc_root_universe + + return openmc_geometry diff --git a/src/initialize.F90 b/src/initialize.F90 index 2ed47a8ba..4c4ae3be5 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -179,13 +179,15 @@ contains integer :: bank_types(5) ! Datatypes #endif integer(MPI_ADDRESS_KIND) :: bank_disp(5) ! Displacements - type(Bank) :: b + logical :: init_called + type(Bank) :: b ! Indicate that MPI is turned on mpi_enabled = .true. ! Initialize MPI - call MPI_INIT(mpi_err) + call MPI_INITIALIZED(init_called, mpi_err) + if (.not. init_called) call MPI_INIT(mpi_err) ! Determine number of processors and rank of each processor mpi_intracomm = intracomm diff --git a/src/tally_filter.F90 b/src/tally_filter.F90 index 21fc3a472..6eadc4242 100644 --- a/src/tally_filter.F90 +++ b/src/tally_filter.F90 @@ -262,6 +262,9 @@ contains ! A track can span multiple mesh bins so we need to handle a lot of ! intersection logic for tracklength tallies. + ! ======================================================================== + ! Determine if the track intersects the tally mesh. + ! Copy the starting and ending coordinates of the particle. Offset these ! just a bit for the purposes of determining if there was an intersection ! in case the mesh surfaces coincide with lattice/geometric surfaces which @@ -296,6 +299,9 @@ contains end if end if + ! ======================================================================== + ! Figure out which mesh cell to tally. + ! Copy the un-modified coordinates the particle direction. xyz0 = p % last_xyz xyz1 = p % coord(1) % xyz @@ -304,11 +310,20 @@ contains ! Compute the length of the entire track. total_distance = sqrt(sum((xyz1 - xyz0)**2)) - ! If we're looking for the first valid bin, check to see if the particle - ! starts inside the mesh. if (current_bin == NO_BIN_FOUND) then + ! We are looking for the first valid mesh bin. Check to see if the + ! particle starts inside the mesh. if (any(ijk0(:m % n_dimension) < 1) & .or. any(ijk0(:m % n_dimension) > m % dimension)) then + ! The particle does not start in the mesh. Note that we nudged the + ! start and end coordinates by a TINY_BIT each so we will have + ! difficulty resolving tracks that are less than 2*TINY_BIT in length. + ! If the track is that short, it is also insignificant so we can + ! safely ignore it in the tallies. + if (total_distance < 2*TINY_BIT) then + next_bin = NO_BIN_FOUND + return + end if ! The particle does not start in the mesh so keep iterating the ijk0 ! indices to cross the nearest mesh surface until we've found a valid @@ -347,14 +362,12 @@ contains xyz0 = xyz0 + distance * uvw end if - end if - ! ======================================================================== - ! If we've already scored some mesh bins, figure out which mesh cell is - ! next and where the particle enters that cell. + else + ! We have already scored some mesh bins for this track. Pick up where + ! we left off and find the next mesh cell that the particle enters. - if (current_bin /= NO_BIN_FOUND) then - ! Get the indices to the last bin. + ! Get the indices to the last bin we scored. call bin_to_mesh_indices(m, current_bin, ijk0(:m % n_dimension)) ! If the particle track ends in that bin, then we are done. @@ -401,7 +414,10 @@ contains end if end if - ! Compute the length of the track segment in this mesh cell. + ! ======================================================================== + ! Compute the length of the track segment in the appropiate mesh cell and + ! return. + if (all(ijk0(:m % n_dimension) == ijk1(:m % n_dimension))) then ! The track ends in this cell. Use the particle end location rather ! than the mesh surface. @@ -422,7 +438,7 @@ contains distance = minval(d(:m % n_dimension)) end if - ! Assign the next tally bin and the score + ! Assign the next tally bin and the score. next_bin = mesh_indices_to_bin(m, ijk0(:m % n_dimension)) weight = distance / total_distance endif