From 255aba1fc0ca9f576b9784acda8c7778927e4210 Mon Sep 17 00:00:00 2001 From: Adam Nelson Date: Sat, 10 Sep 2016 11:28:08 -0400 Subject: [PATCH] Updated ipython notebook, fixed minor corrections throughout, and added h5 wrapper functions in hdf5_interface so the various from_hdf5 routines dont have to call low-level functions directly --- .../pythonapi/examples/mgxs-part-iv.ipynb | 112 ++++++------ docs/source/usersguide/input.rst | 2 +- openmc/mesh.py | 4 + openmc/mgxs_library.py | 6 +- src/hdf5_interface.F90 | 22 +++ src/mgxs_header.F90 | 169 ++++++++++-------- src/nuclide_header.F90 | 37 ++-- src/reaction_header.F90 | 17 +- src/sab_header.F90 | 16 +- src/secondary_uncorrelated.F90 | 17 +- 10 files changed, 206 insertions(+), 196 deletions(-) diff --git a/docs/source/pythonapi/examples/mgxs-part-iv.ipynb b/docs/source/pythonapi/examples/mgxs-part-iv.ipynb index b36020691..f384afb55 100644 --- a/docs/source/pythonapi/examples/mgxs-part-iv.ipynb +++ b/docs/source/pythonapi/examples/mgxs-part-iv.ipynb @@ -431,7 +431,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "" ] @@ -734,8 +734,8 @@ " Copyright | 2011-2016 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | 84df6a1f10c7811eed59e4ea04cddf2afd42ef75\n", - " Date/Time | 2016-09-10 08:37:58\n", + " Git SHA1 | 61feb8cc6de0bcac0bab46876f2c7fe978d9fe46\n", + " Date/Time | 2016-09-10 09:22:09\n", " OpenMP Threads | 4\n", "\n", " ===========================================================================\n", @@ -822,20 +822,20 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 3.3600E-01 seconds\n", - " Reading cross sections = 2.1200E-01 seconds\n", - " Total time in simulation = 2.1540E+01 seconds\n", - " Time in transport only = 2.1352E+01 seconds\n", - " Time in inactive batches = 2.4040E+00 seconds\n", - " Time in active batches = 1.9136E+01 seconds\n", - " Time synchronizing fission bank = 6.0000E-03 seconds\n", - " Sampling source sites = 3.0000E-03 seconds\n", - " SEND/RECV source sites = 3.0000E-03 seconds\n", + " Total time for initialization = 2.9000E-01 seconds\n", + " Reading cross sections = 1.7200E-01 seconds\n", + " Total time in simulation = 1.9592E+01 seconds\n", + " Time in transport only = 1.9464E+01 seconds\n", + " Time in inactive batches = 2.3150E+00 seconds\n", + " Time in active batches = 1.7277E+01 seconds\n", + " Time synchronizing fission bank = 1.0000E-02 seconds\n", + " Sampling source sites = 5.0000E-03 seconds\n", + " SEND/RECV source sites = 5.0000E-03 seconds\n", " Time accumulating tallies = 0.0000E+00 seconds\n", " Total time for finalization = 0.0000E+00 seconds\n", - " Total time elapsed = 2.1898E+01 seconds\n", - " Calculation Rate (inactive) = 20798.7 neutrons/second\n", - " Calculation Rate (active) = 10451.5 neutrons/second\n", + " Total time elapsed = 1.9904E+01 seconds\n", + " Calculation Rate (inactive) = 21598.3 neutrons/second\n", + " Calculation Rate (active) = 11576.1 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", @@ -1108,8 +1108,8 @@ " Copyright | 2011-2016 Massachusetts Institute of Technology\n", " License | http://openmc.readthedocs.io/en/latest/license.html\n", " Version | 0.8.0\n", - " Git SHA1 | 84df6a1f10c7811eed59e4ea04cddf2afd42ef75\n", - " Date/Time | 2016-09-10 08:38:20\n", + " Git SHA1 | 61feb8cc6de0bcac0bab46876f2c7fe978d9fe46\n", + " Date/Time | 2016-09-10 09:22:29\n", " OpenMP Threads | 4\n", "\n", " ===========================================================================\n", @@ -1165,25 +1165,25 @@ " 29/1 1.02831 1.02797 +/- 0.00336\n", " 30/1 1.02643 1.02789 +/- 0.00319\n", " 31/1 1.03939 1.02844 +/- 0.00308\n", - " 32/1 1.03277 1.02864 +/- 0.00294\n", - " 33/1 1.00167 1.02746 +/- 0.00305\n", - " 34/1 1.01791 1.02707 +/- 0.00294\n", - " 35/1 1.03889 1.02754 +/- 0.00286\n", - " 36/1 1.02693 1.02752 +/- 0.00275\n", - " 37/1 1.02346 1.02737 +/- 0.00265\n", - " 38/1 1.00974 1.02674 +/- 0.00263\n", - " 39/1 1.01456 1.02632 +/- 0.00257\n", - " 40/1 1.02217 1.02618 +/- 0.00249\n", - " 41/1 0.99130 1.02505 +/- 0.00266\n", - " 42/1 1.05167 1.02588 +/- 0.00271\n", - " 43/1 1.01675 1.02561 +/- 0.00264\n", - " 44/1 1.00496 1.02500 +/- 0.00263\n", - " 45/1 1.00466 1.02442 +/- 0.00262\n", - " 46/1 1.01644 1.02420 +/- 0.00255\n", - " 47/1 1.01033 1.02382 +/- 0.00251\n", - " 48/1 1.02299 1.02380 +/- 0.00245\n", - " 49/1 1.01468 1.02357 +/- 0.00239\n", - " 50/1 1.02616 1.02363 +/- 0.00233\n", + " 32/1 1.03282 1.02864 +/- 0.00294\n", + " 33/1 1.00098 1.02744 +/- 0.00306\n", + " 34/1 1.01763 1.02703 +/- 0.00296\n", + " 35/1 1.01412 1.02651 +/- 0.00288\n", + " 36/1 1.01564 1.02609 +/- 0.00280\n", + " 37/1 1.02255 1.02596 +/- 0.00270\n", + " 38/1 1.04764 1.02674 +/- 0.00271\n", + " 39/1 1.03299 1.02695 +/- 0.00263\n", + " 40/1 1.01040 1.02640 +/- 0.00260\n", + " 41/1 1.03493 1.02667 +/- 0.00253\n", + " 42/1 1.00289 1.02593 +/- 0.00256\n", + " 43/1 1.01429 1.02558 +/- 0.00250\n", + " 44/1 1.04207 1.02606 +/- 0.00248\n", + " 45/1 1.03141 1.02622 +/- 0.00241\n", + " 46/1 1.02055 1.02606 +/- 0.00235\n", + " 47/1 1.03659 1.02634 +/- 0.00230\n", + " 48/1 1.04200 1.02676 +/- 0.00228\n", + " 49/1 1.02003 1.02658 +/- 0.00222\n", + " 50/1 1.04396 1.02702 +/- 0.00221\n", " Creating state point statepoint.50.h5...\n", "\n", " ===========================================================================\n", @@ -1193,27 +1193,27 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 4.0000E-02 seconds\n", - " Reading cross sections = 8.0000E-03 seconds\n", - " Total time in simulation = 1.5523E+01 seconds\n", - " Time in transport only = 1.5428E+01 seconds\n", - " Time in inactive batches = 1.6880E+00 seconds\n", - " Time in active batches = 1.3835E+01 seconds\n", - " Time synchronizing fission bank = 7.0000E-03 seconds\n", + " Total time for initialization = 3.1000E-02 seconds\n", + " Reading cross sections = 6.0000E-03 seconds\n", + " Total time in simulation = 1.4773E+01 seconds\n", + " Time in transport only = 1.4743E+01 seconds\n", + " Time in inactive batches = 1.4380E+00 seconds\n", + " Time in active batches = 1.3335E+01 seconds\n", + " Time synchronizing fission bank = 5.0000E-03 seconds\n", " Sampling source sites = 5.0000E-03 seconds\n", - " SEND/RECV source sites = 2.0000E-03 seconds\n", + " SEND/RECV source sites = 0.0000E+00 seconds\n", " Time accumulating tallies = 0.0000E+00 seconds\n", " Total time for finalization = 0.0000E+00 seconds\n", - " Total time elapsed = 1.5587E+01 seconds\n", - " Calculation Rate (inactive) = 29620.9 neutrons/second\n", - " Calculation Rate (active) = 14456.1 neutrons/second\n", + " Total time elapsed = 1.4827E+01 seconds\n", + " Calculation Rate (inactive) = 34770.5 neutrons/second\n", + " Calculation Rate (active) = 14998.1 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", - " k-effective (Collision) = 1.02217 +/- 0.00260\n", - " k-effective (Track-length) = 1.02363 +/- 0.00233\n", - " k-effective (Absorption) = 1.02649 +/- 0.00171\n", - " Combined k-effective = 1.02638 +/- 0.00171\n", + " k-effective (Collision) = 1.02681 +/- 0.00251\n", + " k-effective (Track-length) = 1.02702 +/- 0.00221\n", + " k-effective (Absorption) = 1.02734 +/- 0.00171\n", + " Combined k-effective = 1.02733 +/- 0.00150\n", " Leakage Fraction = 0.00000 +/- 0.00000\n", "\n" ] @@ -1295,8 +1295,8 @@ "output_type": "stream", "text": [ "Continuous-Energy keff = 1.024295\n", - "Multi-Group keff = 1.026377\n", - "bias [pcm]: -208.3\n" + "Multi-Group keff = 1.027328\n", + "bias [pcm]: -303.3\n" ] } ], @@ -1393,7 +1393,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 40, @@ -1402,9 +1402,9 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAADDCAYAAACS2+oqAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJztnXeYFtX1xz9nBRUQBBsqig1bLCBRNMboagxR1GjsLbbE\nFg3mp5HYWYyxxWCJJVhiiQU1SLCLia4JdgVEo9gogggqoFhR2PP7Y2bhZdl3zrvsLu/u+P08zzy7\n79zv3Hvmzpkzd+7MnWvujhBCiNZPRbkNEEII0TQooAshRE5QQBdCiJyggC6EEDlBAV0IIXKCAroQ\nQuSEFhfQzew1M9ux3HZ8lzGzh83sF43Y/jozO7spbfouYmY1ZrZ+RnpuzxX54BLi7uECHAq8CHwG\nvA88BPywlG2DfG8Gzm9sPuVc0n2YC8xJl8+AMeW2qwS7BwLfFNg8B/hdue1qgM2zgFHAdg3Y/kng\nmKVg5yTga2ClOuvHAjVA9xLzmQ+sX+BnDTpXgLbAecD49BhPSc/dn5T7WNZzPOWDTbCELXQzOxUY\nDFwArAZ0B64FfhZt+x3iEnfvlC4d3X2rpi7AzJZp6jyBoQU2d3L3y5qhjKZmqLt3AlYBqoF7y2tO\nvTgwETikdoWZbQ4sn6aVijXSjmHAXsDhQBdgPeBKoF+9hTWPj0XIB5uS4GrSieTKuW+GZlngCpKW\n+1TgcqBtmrYTSavgVGBGqjkqTTuW5Er3NcnVbkS6fiKwS8HV8G7g1lTzKtC7oOwa0hZM+nuRVkxa\nxtvAx8A/gTXS9euk21bUd+UENiA5UJ8AHwJ3Zex/0ZZTQTlHAJPTvM4qSDfgDOAd4CNgKNC5zrbH\npNtWp+uPIGkBfgScU1tfQFfgC6BLQf7fT8tcpkhL47aoFZFVF+mxnpGmjQW+15DjUHAMjwfeAmYC\nVweto9sKfm9K0opdOf3dGXggtXNm+v+aadoFwDzgy9SXrkrXbwKMTPVvAAcU5N8P+F+qnwKcWmIr\nbCJwFvBCwbo/AWem9navr7UGHAn8t65/U8K5Uo8Nu6b+sEYJtg4AXgG+IumG3TS1bTbJObdXfb6R\nYfNvgHfT43BpqcdTPth4H4xa6D8AlksroBjnAH2ALYGe6f/nFKSvDnQE1gR+BVxjZiu6+w3AHSQH\nvJO7710k/72AO4EV08q5piCtaGvHzHYBLgT2B9YA3iMJmOG2wB+Ax9y9M7AW8JcMbSn8ENiQ5CQ7\nz8w2TtefQnKn8yOS+plNcvdTyI4kB/ynZrYpyf4fQrJPK6bb4e4zSE6CAwu2PYzE+ec3wvZ668LM\n+gI7AD3StINIHHIRSjgOAHuQXHx6AQemeWdiZsuSBJOZJPUGSTD6G7A2yZ3kl6T+4u7nAP8FTk79\nrb+ZtSc5kW4naW0dAlyb1jPAjcCxnrTGNgeeiOwq4Dmgo5ltbGYVJMflduJW92J+2YBzpZAfA8+7\n+wclaA8GdicJRhXA/cCjwKpAf+AOM9uwATbvA/ROl73N7JgSbMhCPliiD0YBfWXgY3evydAcCgxy\n95nuPhMYBBQ+zPgG+IO7z3f3R4DPgY3ryacYo9z9MU8uV38nuXDUknVyHArc5O6vuPu3JK2jH5hZ\n9xLK/BZYx8y6ufs37v5MoD/dzGaZ2ez0780FaQ5UpfmMI2kJ9UzTjgPOdvcPUhvPB/ZPA0DttgPd\n/St3n0vikPe7+7PuPo+kf7SQ20jrPs3jEJI6K8ZBdexevQF18S3Jhfp7Zmbu/mZ6UalLKcfhInf/\nzN2nkFyUekU2k5wovwT2r/VPd5/l7sPdfa67fwFcRHJBLMaewER3v80TxpJ0U+yfpn8DbGZmHd39\n0zS9Ifyd5IT/CUk/9rQGbt8YVgGm1/4wsy7pcf7EzL6qo73S3aelPrYd0MHdL3H3ee7+JPAgBd1H\nJXBxWl9TSe7es7aVDzahD0YBfSawSkGAqY81Sa54tUxO1y3Io84F4UtghaDcQqYX/P8lsHxgT6Fd\nk2t/pJU7E+hWwrank9TNC2b2qpkdDWBmZ5rZZ2Y2x8wKW9J/cveV3L1L+vfoOvkVOlnh/q8DDE8d\neRbwOomTdi3QT62zT1MK9ukrFm2RjAA2NbN1gb7AJ+7+UsZ+3l3H7un1aOqti/REv5qk9THdzP5q\nZvUd11KOQ7H6KWozyfOc14CtaxPMrJ2ZDTGzSWb2CfAU0NnMil341wG2q61/M5tNcvLX1v9+JC23\nyWb2pJltl2FXfdye5ncUycW22Uj9stY31yKp4zVq0919trt3IWmFLltn86I+ljKZ0s6b+vKrGw/q\nIh9sQh+MAuOzJP12+2Ro3k+NKjSw1JZIQx4Q1ceXQPuC34VX92mFdplZB5I7jqkkfYsU29bdP3T3\n49y9G3ACyS3Q+u5+kS98ePPrRtoOyYVw99SRa526Q53b5MI6+oDklrN2n9ql+1Rr91zgHpKHYIeT\n3ToviWJ1kaZd7e5bA5uR3HWdXk8WWcehMXbNSu2pMrNa5z+NpGtrm/QWvLZlVHsy1fW3KSTPJgrr\nv5O7n5yW8bK770PS9TCCpG4bYuN7JH3UuwP31SP5guL+u1h2QVkdC3xzKvBvYBszqy+Y1g0uhXlP\nI+kuKKQ7yXleqs2F23enkXcm8sHSfTAzoLv7HJKHANeY2d7p1aeNme1uZhensqHAOWa2ipmtApxL\n6YFkBslDn4ZQ6IxjgEPNrMLMdiN5CFvLncDRZralmS1H0of2nLtPcfePSRz08HTbY0gevCQFmO1v\nZrVX709IHposaT90VrfQEODC2ls/M1vVzArfHqq77T+AvcxsOzNrS9K9VZe/k7QI9yJpITaKYnVh\nZlubWR8za0PyMO1r6q+josehsba5+5skfb2/T1d1TG2ZY2YrAVV1Nqnrbw8CG5nZ4alft033a5P0\n/0PNrJMnzyA+I3mg1VCOIXlwWbebA5KHePum51UPktv3YjToXHH3x0m6Dv6ZHqe26bH6AdkXh+eB\nL8xsQFonlSTdAnc1wObTzayzma1N8pyobn91g5APlu6DYdeFu19O8pbKOSRPbt8Dfs3CB6UXAC8B\ntf3DLwF/zMqy4P+bSPqHZpnZffWkR9v/luSh4mySfrrhBXY/QXJxuY8keK9H8vCnlmNJnu5/TPKk\n+umCtG2A581sTrqf/d19MsUZkN7qzklvez8sYm/d31eSXHVHmtmnwDMkD5Xr3dbdXyd5g+BuklbH\npyTHZG6B5hkShx+dthCXhMJyi9VFJ+AGkndxJ5LU42KvnJVwHLLqpxQuA45NGxNXkLQePyapy4fr\naK8EDjCzmWZ2hbt/TtI1dTBJfU4DLmZhl8QvgInprfNxJA+ZS2HBPrj7RHcfXV8ayRsa35J0K97M\n4hfgxp4r+5IEjNtJzpEJJOfJT4uUQdrH/DOStys+JunS+IW7v12izZD49MvAaJIXGf4W2Fkf8sGE\nBvmguTe210OUi/TW8ROSp/yTC9b/G7jD3ZfkRBJiiTGzGhJ/nFBuW76LtLih/yIbM9szvd3tAPwZ\nGFcnmG8DbEXSihdCfIdQQG997E1yWzaVpN9/wa2jmd1C8k7rKemTfCGWNrrlLyPqchFCiJygFroQ\nQuSENs2RafoK4RUkF4yb3P2SejS6NRDNirs39uNWiyHfFi2BYr7d5F0ulozifIvkWxLTSD67e7C7\nj6+jc35fUPaoKtihatHMSnmsV8q32daN9/Gl728Wag6s807/rKprWalq0fFFZ/mFYT6/uueOUHPw\nQTdnpr9F1qc1EtZebMAfjK8axiZV+y34/Ru/Osxn14eiLx+w6Eufxdi2BM2Qeo7V21WwYdWCn799\n5OLFNXW4ws5q8oDeIN++sWBw9Igq2Ltqwc+Lf9k/LOtuPyjUjKnYITb68Nj317vt9cXWza66hi5V\nJy34PXFcfH7QJi7r9c3WCzVHcUuouZ5jF1t3XdVMTqxaMM6OZcj6YknCf/hRqBniJ4SacXeUMIj4\nH3XqZ3wVbFK16LoRszKz6Nu3LSNHrljUt5ujy6UP8La7T07faR1K8iBPiNaOfFu0aJojoHdj0W9B\nTKVh34EQoqUi3xYtmuboQ6/vVqD+e7FRVQv/X65zM5jSvLSr3KbcJjSYVSo3jUUtjZUqQ8mU6glM\nrW72sSyl+/aIqoX/t2t9vr18K/TtrSvblduEhrFKZYnCUdT2ab7zTvYcJM0R0KeSfJCnlrUo9nGe\nun3mrYzWGdC/V24TGs7KlaFk7cr1Wbty4Scynh/UkE+Xl0zpvl3QZ94aaVfZJxa1MLapbB+LWhIl\nB/Qd0gV69GjLhAnFnyE1R5fLi0APM1vHkg/AH0zywXwhWjvybdGiafIWurvPN7OTSUYs1r7a9UZT\nlyPE0ka+LVo6zfIeurs/SsNmJRKiVSDfFi2ZZgnoJXNrkL5HCXl8XYKmhPmRtnk/a2KfhNHdsmal\nSpjMuqFm/mbx5Op3sG9m+hZedw6CxTnnP38ONcM/jL8Ie/r+9X12fVGe6bd9qHn6D7uGmiMe/muo\n6ctjoeaKUNG8rHfM4u9213KPH1g0rZYxv/5hXMh18Xvf3Y5/J9QUnUungPW3fC3UvD1ti1Dz5Qpx\nYS8smzVjW5rPrA6h5hIGhJoevFuCJq7DcW1KeA/9k1iy6MRJ9ZG93xr6L4QQOUEBXQghcoICuhBC\n5AQFdCGEyAkK6EIIkRMU0IUQIicooAshRE5QQBdCiJxQtjlFzcy5K/sD9BWV8TzHx3cdEmqunvW7\n2KCZ8YAH23B+qDnBrgw1r9T0DDXPWmVm+sHhqCy4a+IxocbWi/fJr4oHQv2sfzwbyUOv7B9qVtjw\no1DTr8PDoeYeO7pZZiwqBTPzR2uKT5yw2zIPxJlc1CmUzD0+bo/NaxNXQbsOsQ+Mt3hiihk1XUPN\n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\nAwmwhqwYOz+DAAAAAElFTkSuQmCC\n", + "image/png": "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\ngg==\n", "text/plain": [ - "" + "" ] }, "metadata": {}, diff --git a/docs/source/usersguide/input.rst b/docs/source/usersguide/input.rst index 08444f23a..b6e66c85a 100644 --- a/docs/source/usersguide/input.rst +++ b/docs/source/usersguide/input.rst @@ -737,7 +737,7 @@ coefficients. This element has the following attributes/sub-elements: *Default*: 33 - .. note:: This element is not used in the multi-group :ref:`energy_mode`. + .. note:: This element is only used in the multi-group :ref:`energy_mode`. .. _temperature_default: diff --git a/openmc/mesh.py b/openmc/mesh.py index 43ac7aef0..d2a911262 100644 --- a/openmc/mesh.py +++ b/openmc/mesh.py @@ -291,6 +291,10 @@ class Mesh(object): # Would prefer to have the z ranges be the max supported float, but # these values are apparently different between python and Fortran. # Choosing a safe and sane default. + # Values of +/-1000 are used here as there seems to be an + # inconsistency between what numpy uses as the max float and what + # Fortran expects for a real(8), so this avoids code complication + # and achieves the same goal. zplanes = [openmc.ZPlane(z0=-1000., boundary_type='reflective'), openmc.ZPlane(z0=1000., diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 2079b8801..a15aa51ae 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -14,14 +14,10 @@ if sys.version_info[0] >= 3: basestring = str # Supported incoming particle MGXS angular treatment representations -_REPRESENTATION_ISOTROPIC = 1 -_REPRESENTATION_ANGLE = 2 -_SCATTER_TYPE_TABULAR = 3 -_SCATTER_TYPE_LEGENDRE = 4 -_SCATTER_TYPE_HISTOGRAM = 5 _REPRESENTATIONS = ['isotropic', 'angle'] _SCATTER_TYPES = ['tabular', 'legendre', 'histogram'] + class XSdata(object): """A multi-group cross section data set providing all the multi-group data necessary for a multi-group OpenMC calculation. diff --git a/src/hdf5_interface.F90 b/src/hdf5_interface.F90 index 2ac06595b..0eafd49b3 100644 --- a/src/hdf5_interface.F90 +++ b/src/hdf5_interface.F90 @@ -102,6 +102,7 @@ module hdf5_interface public :: write_attribute_string public :: get_groups public :: get_datasets + public :: get_name contains @@ -333,6 +334,27 @@ contains end subroutine get_datasets +!=============================================================================== +! GET_NAME Obtains the name of the current group in group_id +!=============================================================================== + + function get_name(group_id, name_len_) result(name) + integer(HID_T), intent(in) :: group_id + integer(SIZE_T), optional, intent(in) :: name_len_ + + character(len=255) :: name ! name of group + integer(SIZE_T) :: name_len, name_file_len + integer :: hdf5_err ! HDF5 error code + + if (present(name_len_)) then + name_len = name_len_ + else + name_len = 255 + end if + + call h5iget_name_f(group_id, name, name_len, name_file_len, hdf5_err) + end function get_name + !=============================================================================== ! OPEN_GROUP opens an existing HDF5 group !=============================================================================== diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index 47081eb5a..e3cc09bd7 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -3,8 +3,7 @@ module mgxs_header use, intrinsic :: ISO_FORTRAN_ENV use, intrinsic :: ISO_C_BINDING - use hdf5, only: HID_T, HSIZE_T, SIZE_T, h5iget_name_f - use h5lt, only: h5ltpath_valid_f + use hdf5, only: HID_T, HSIZE_T, SIZE_T use algorithm, only: find, sort use constants, only: MAX_FILE_LEN, ZERO, ONE, TWO, PI @@ -212,8 +211,7 @@ module mgxs_header type(VectorInt), intent(out) :: temps_to_read ! Temperatures to read integer, intent(out) :: order_dim ! Scattering data order size - integer :: hdf5_err - integer(SIZE_T) :: name_len, name_file_len + integer(SIZE_T) :: name_len integer(HID_T) :: kT_group character(MAX_FILE_LEN), allocatable :: dset_names(:) real(8), allocatable :: temps_available(:) ! temperatures available @@ -225,7 +223,7 @@ module mgxs_header ! Get name of dataset from group name_len = len(this % name) - call h5iget_name_f(xs_id, this % name, name_len, name_file_len, hdf5_err) + this % name = get_name(xs_id, name_len) ! Get rid of leading '/' this % name = trim(this % name(2:)) @@ -452,8 +450,8 @@ module mgxs_header ! If we have a need* for the fission and kappa-fission x/s, get them ! (*Need is defined as will be using it to tally) if (get_fiss) then - allocate(xs % fission(groups)) if (check_dataset(xsdata_grp, "fission")) then + allocate(xs % fission(groups)) call read_dataset(xs % fission, xsdata_grp, "fission") else call fatal_error("Fission data missing, required due to fission& @@ -461,8 +459,8 @@ module mgxs_header end if end if if (get_kfiss) then - allocate(xs % k_fission(groups)) if (check_dataset(xsdata_grp, "kappa-fission")) then + allocate(xs % k_fission(groups)) call read_dataset(xs % k_fission, xsdata_grp, "kappa-fission") else call fatal_error("kappa-fission data missing, required due to & @@ -471,8 +469,8 @@ module mgxs_header end if end if - allocate(xs % absorption(groups)) if (check_dataset(xsdata_grp, "absorption")) then + allocate(xs % absorption(groups)) call read_dataset(xs % absorption, xsdata_grp, "absorption") else call fatal_error("Must provide absorption!") @@ -581,30 +579,37 @@ module mgxs_header deallocate(input_scatt) ! Now get the multiplication matrix - ! Now use this information to find the length of a container array - ! to hold the flattened data - length = 0 - do gin = 1, groups - length = length + (gmax(gin) - gmin(gin) + 1) - end do - ! Allocate flattened array - allocate(temp_arr(length)) - if (.not. check_dataset(scatt_grp, 'multiplicity matrix')) & - call fatal_error("'multiplicity matrix' must be provided") - call read_dataset(temp_arr, scatt_grp, "multiplicity matrix") - - ! Convert temp_arr to a jagged array ((gin) % data(gout)) for passing - ! to ScattData - allocate(temp_mult(groups)) - index = 1 - do gin = 1, groups - allocate(temp_mult(gin) % data(gmin(gin):gmax(gin))) - do gout = gmin(gin), gmax(gin) - temp_mult(gin) % data(gout) = temp_arr(index) - index = index + 1 + if (check_dataset(scatt_grp, 'multiplicity matrix')) then + ! Now use this information to find the length of a container array + ! to hold the flattened data + length = 0 + do gin = 1, groups + length = length + (gmax(gin) - gmin(gin) + 1) end do - end do - deallocate(temp_arr) + ! Allocate flattened array + allocate(temp_arr(length)) + call read_dataset(temp_arr, scatt_grp, "multiplicity matrix") + + ! Convert temp_arr to a jagged array ((gin) % data(gout)) for passing + ! to ScattData + allocate(temp_mult(groups)) + index = 1 + do gin = 1, groups + allocate(temp_mult(gin) % data(gmin(gin):gmax(gin))) + do gout = gmin(gin), gmax(gin) + temp_mult(gin) % data(gout) = temp_arr(index) + index = index + 1 + end do + end do + deallocate(temp_arr) + else + ! Default to multiplicities of 1.0 + allocate(temp_mult(groups)) + do gin = 1, groups + allocate(temp_mult(gin) % data(gmin(gin):gmax(gin))) + temp_mult(gin) % data = ONE + end do + end if ! Allocate and initialize our ScattData Object. if (this % scatter_type == ANGLE_HISTOGRAM) then @@ -641,6 +646,7 @@ module mgxs_header ! Close the groups we have opened and deallocate call close_group(xsdata_grp) + call close_group(scatt_grp) deallocate(scatt_coeffs, temp_mult) end associate ! xs end do ! Temperatures @@ -689,7 +695,7 @@ module mgxs_header if (check_dataset(xsdata_grp, "chi")) then ! Chi was provided, that means we need chi and nu-fission vectors ! Get chi - allocate(temp_arr(1 * groups * this % n_azi * this % n_pol)) + allocate(temp_arr(groups * this % n_azi * this % n_pol)) call read_dataset(temp_arr, xsdata_grp, "chi") ! Initialize counter for temp_arr l = 0 @@ -920,39 +926,50 @@ module mgxs_header deallocate(input_scatt) ! Now get the multiplication matrix - ! Now use this information to find the length of a container array - ! to hold the flattened data - length = 0 - do ipol = 1, this % n_pol - do iazi = 1, this % n_azi - do gin = 1, groups - length = length + (gmax(gin, iazi, ipol) - gmin(gin, iazi, ipol) + 1) - end do - end do - end do - ! Allocate flattened array - allocate(temp_arr(length)) - if (.not. check_dataset(scatt_grp, 'multiplicity matrix')) & - call fatal_error("'multiplicity matrix' must be provided") - call read_dataset(temp_arr, scatt_grp, "multiplicity matrix") - - ! Convert temp_arr to a jagged array ((gin) % data(gout)) for passing - ! to ScattData - allocate(temp_mult(groups, this % n_azi, this % n_pol)) - index = 1 - do ipol = 1, this % n_pol - do iazi = 1, this % n_azi - do gin = 1, groups - allocate(temp_mult(gin, iazi, ipol) % data( & - gmin(gin, iazi, ipol):gmax(gin, iazi, ipol))) - do gout = gmin(gin, iazi, ipol), gmax(gin, iazi, ipol) - temp_mult(gin, iazi, ipol) % data(gout) = temp_arr(index) - index = index + 1 + if (check_dataset(scatt_grp, 'multiplicity matrix')) then + ! Now use this information to find the length of a container array + ! to hold the flattened data + length = 0 + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, groups + length = length + (gmax(gin, iazi, ipol) - gmin(gin, iazi, ipol) + 1) end do end do end do - end do - deallocate(temp_arr) + ! Allocate flattened array + allocate(temp_arr(length)) + call read_dataset(temp_arr, scatt_grp, "multiplicity matrix") + ! Convert temp_arr to a jagged array ((gin) % data(gout)) for passing + ! to ScattData + allocate(temp_mult(groups, this % n_azi, this % n_pol)) + index = 1 + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, groups + allocate(temp_mult(gin, iazi, ipol) % data( & + gmin(gin, iazi, ipol):gmax(gin, iazi, ipol))) + do gout = gmin(gin, iazi, ipol), gmax(gin, iazi, ipol) + temp_mult(gin, iazi, ipol) % data(gout) = temp_arr(index) + index = index + 1 + end do + end do + end do + end do + deallocate(temp_arr) + else + allocate(temp_mult(groups, this % n_azi, this % n_pol)) + ! Default to multiplicities of 1.0 + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, groups + allocate(temp_mult(gin, iazi, ipol) % data( & + gmin(gin, iazi, ipol):gmax(gin, iazi, ipol))) + temp_mult(gin, iazi, ipol) % data = ONE + end do + end do + end do + end if ! Allocate and initialize our ScattData Object. allocate(xs % scatter(this % n_azi, this % n_pol)) @@ -1013,6 +1030,7 @@ module mgxs_header ! Close the groups we have opened and deallocate call close_group(xsdata_grp) + call close_group(scatt_grp) deallocate(scatt_coeffs, temp_mult) end associate ! xs end do ! Temperatures @@ -1220,22 +1238,22 @@ module mgxs_header type is (MgxsIso) ! Perform our operations which depend upon the type ! Add contributions to total, absorption, and fission data (if necessary) - this % xs(t) % total(:) = this % xs(t) % total(:) + & - atom_density * nuc % xs(nuc_t) % total(:) - this % xs(t) % absorption(:) = this % xs(t) % absorption(:) + & - atom_density * nuc % xs(nuc_t) % absorption(:) + this % xs(t) % total = this % xs(t) % total + & + atom_density * nuc % xs(nuc_t) % total + this % xs(t) % absorption = this % xs(t) % absorption + & + atom_density * nuc % xs(nuc_t) % absorption if (nuc % fissionable) then - this % xs(t) % chi(:, :) = this % xs(t) % chi(:, :) + & - atom_density * nuc % xs(nuc_t) % chi(:, :) - this % xs(t) % nu_fission(:) = this % xs(t) % nu_fission(:) + & - atom_density * nuc % xs(nuc_t) % nu_fission(:) + this % xs(t) % chi = this % xs(t) % chi + & + atom_density * nuc % xs(nuc_t) % chi + this % xs(t) % nu_fission = this % xs(t) % nu_fission + & + atom_density * nuc % xs(nuc_t) % nu_fission if (allocated(nuc % xs(nuc_t) % fission)) then - this % xs(t) % fission(:) = this % xs(t) % fission(:) + & - atom_density * nuc % xs(nuc_t) % fission(:) + this % xs(t) % fission = this % xs(t) % fission + & + atom_density * nuc % xs(nuc_t) % fission end if if (allocated(nuc % xs(nuc_t) % k_fission)) then - this % xs(t) % k_fission(:) = this % xs(t) % k_fission(:) + & - atom_density * nuc % xs(nuc_t) % k_fission(:) + this % xs(t) % k_fission = this % xs(t) % k_fission + & + atom_density * nuc % xs(nuc_t) % k_fission end if end if @@ -1547,13 +1565,12 @@ module mgxs_header end do end do - ! Create the Jagged arrays + ! Now create our jagged data from the dense data call jagged_from_dense_2D(scatt_coeffs(:, :, :, iazi, ipol), & jagged_scatt) call jagged_from_dense_1D(temp_mult(:, :, iazi, ipol), & jagged_mult, gmin, gmax) - ! Initialize the ScattData Object ! Initialize the ScattData Object call this % xs(t) % scatter(iazi, ipol) % obj % init(gmin, & gmax, jagged_mult, jagged_scatt) diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 1fbd691ee..07b8a99b7 100644 --- a/src/nuclide_header.F90 +++ b/src/nuclide_header.F90 @@ -3,9 +3,7 @@ module nuclide_header use, intrinsic :: ISO_FORTRAN_ENV use, intrinsic :: ISO_C_BINDING - use hdf5, only: HID_T, HSIZE_T, SIZE_T, h5iget_name_f, h5gget_info_f, & - h5lget_name_by_idx_f, H5_INDEX_NAME_F, H5_ITER_INC_F - use h5lt, only: h5ltpath_valid_f + use hdf5, only: HID_T, HSIZE_T, SIZE_T use algorithm, only: sort, find use constants @@ -14,7 +12,8 @@ module nuclide_header use endf_header, only: Function1D, Polynomial, Tabulated1D use error, only: fatal_error, warning use hdf5_interface, only: read_attribute, open_group, close_group, & - open_dataset, read_dataset, close_dataset, get_shape, get_datasets + open_dataset, read_dataset, close_dataset, get_shape, get_datasets, & + check_group, get_name, get_groups use list_header, only: ListInt use math, only: evaluate_legendre use multipole_header, only: MultipoleArray @@ -194,10 +193,6 @@ module nuclide_header real(8), intent(in) :: tolerance integer :: i - integer :: storage_type - integer :: max_corder - integer :: n_links - integer :: hdf5_err integer :: i_closest integer :: n_temperature integer(HID_T) :: urr_group, nu_group @@ -208,21 +203,21 @@ module nuclide_header integer(HID_T) :: total_nu integer(HID_T) :: fer_group ! fission_energy_release group integer(HID_T) :: fer_dset - integer(SIZE_T) :: name_len, name_file_len + integer(SIZE_T) :: name_len integer(HSIZE_T) :: j integer(HSIZE_T) :: dims(1) character(MAX_WORD_LEN) :: temp_str character(MAX_FILE_LEN), allocatable :: dset_names(:) + character(MAX_FILE_LEN), allocatable :: grp_names(:) real(8), allocatable :: temps_available(:) ! temperatures available real(8) :: temp_desired real(8) :: temp_actual - logical :: exists type(VectorInt) :: MTs type(VectorInt) :: temps_to_read ! Get name of nuclide from group name_len = len(this % name) - call h5iget_name_f(group_id, this % name, name_len, name_file_len, hdf5_err) + this % name = get_name(group_id, name_len) ! Get rid of leading '/' this % name = trim(this % name(2:)) @@ -305,12 +300,10 @@ module nuclide_header ! Get MT values based on group names rxs_group = open_group(group_id, 'reactions') - call h5gget_info_f(rxs_group, storage_type, n_links, max_corder, hdf5_err) - do j = 0, n_links - 1 - call h5lget_name_by_idx_f(rxs_group, ".", H5_INDEX_NAME_F, H5_ITER_INC_F, & - j, temp_str, hdf5_err, name_len) - if (starts_with(temp_str, "reaction_")) then - call MTs % push_back(int(str_to_int(temp_str(10:12)))) + call get_groups(rxs_group, grp_names) + do j = 1, size(grp_names) + if (starts_with(grp_names(j), "reaction_")) then + call MTs % push_back(int(str_to_int(grp_names(j)(10:12)))) end if end do @@ -326,8 +319,7 @@ module nuclide_header call close_group(rxs_group) ! Read unresolved resonance probability tables if present - call h5ltpath_valid_f(group_id, 'urr', .true., exists, hdf5_err) - if (exists) then + if (check_group(group_id, 'urr')) then this % urr_present = .true. allocate(this % urr_data(n_temperature)) @@ -368,8 +360,7 @@ module nuclide_header end if ! Check for nu-total - call h5ltpath_valid_f(group_id, 'total_nu', .true., exists, hdf5_err) - if (exists) then + if (check_group(group_id, 'total_nu')) then nu_group = open_group(group_id, 'total_nu') ! Read total nu data @@ -388,9 +379,7 @@ module nuclide_header end if ! Read fission energy release data if present - call h5ltpath_valid_f(group_id, 'fission_energy_release', .true., exists, & - hdf5_err) - if (exists) then + if (check_group(group_id, 'fission_energy_release')) then fer_group = open_group(group_id, 'fission_energy_release') ! Check to see if this is polynomial or tabulated data diff --git a/src/reaction_header.F90 b/src/reaction_header.F90 index a7896e9ff..12b3888c4 100644 --- a/src/reaction_header.F90 +++ b/src/reaction_header.F90 @@ -5,7 +5,7 @@ module reaction_header use constants, only: MAX_WORD_LEN use hdf5_interface, only: read_attribute, open_group, close_group, & - open_dataset, read_dataset, close_dataset, get_shape + open_dataset, read_dataset, close_dataset, get_shape, get_groups use product_header, only: ReactionProduct use stl_vector, only: VectorInt use string, only: to_str, starts_with @@ -42,17 +42,12 @@ contains integer :: i integer :: cm integer :: n_product - integer :: storage_type - integer :: max_corder - integer :: n_links - integer :: hdf5_err integer(HID_T) :: pgroup integer(HID_T) :: xs, temp_group - integer(SIZE_T) :: name_len integer(HSIZE_T) :: dims(1) integer(HSIZE_T) :: j - character(MAX_WORD_LEN) :: name character(MAX_WORD_LEN) :: temp_str ! temperature dataset name, e.g. '294K' + character(MAX_WORD_LEN), allocatable :: grp_names(:) call read_attribute(this % Q_value, group_id, 'Q_value') call read_attribute(this % MT, group_id, 'mt') @@ -74,12 +69,10 @@ contains end do ! Determine number of products - call h5gget_info_f(group_id, storage_type, n_links, max_corder, hdf5_err) n_product = 0 - do j = 0, n_links - 1 - call h5lget_name_by_idx_f(group_id, ".", H5_INDEX_NAME_F, H5_ITER_INC_F, & - j, name, hdf5_err, name_len) - if (starts_with(name, "product_")) n_product = n_product + 1 + call get_groups(group_id, grp_names) + do j = 1, size(grp_names) + if (starts_with(grp_names(j), "product_")) n_product = n_product + 1 end do ! Read products diff --git a/src/sab_header.F90 b/src/sab_header.F90 index 147643065..5f49fdc42 100644 --- a/src/sab_header.F90 +++ b/src/sab_header.F90 @@ -8,9 +8,9 @@ module sab_header use distribution_univariate, only: Tabular use error, only: warning, fatal_error use hdf5, only: HID_T, HSIZE_T, SIZE_T - use h5lt, only: h5ltpath_valid_f, h5iget_name_f use hdf5_interface, only: read_attribute, get_shape, open_group, close_group, & - open_dataset, read_dataset, close_dataset, get_datasets + open_dataset, read_dataset, close_dataset, get_datasets, check_group, & + get_name use secondary_correlated, only: CorrelatedAngleEnergy use stl_vector, only: VectorInt, VectorReal use string, only: to_str, str_to_int @@ -91,8 +91,7 @@ contains integer :: n_energy, n_energy_out, n_mu integer :: i_closest integer :: n_temperature - integer :: hdf5_err - integer(SIZE_T) :: name_len, name_file_len + integer(SIZE_T) :: name_len integer(HID_T) :: T_group integer(HID_T) :: elastic_group integer(HID_T) :: inelastic_group @@ -102,7 +101,6 @@ contains integer(HSIZE_T) :: dims3(3) real(8), allocatable :: temp(:,:) character(20) :: type - logical :: exists type(CorrelatedAngleEnergy) :: correlated_dist character(MAX_WORD_LEN) :: temp_str @@ -114,7 +112,7 @@ contains ! Get name of table from group name_len = len(this % name) - call h5iget_name_f(group_id, this % name, name_len, name_file_len, hdf5_err) + this % name = get_name(group_id, name_len) ! Get rid of leading '/' this % name = trim(this % name(2:)) @@ -180,8 +178,7 @@ contains T_group = open_group(group_id, temp_str) ! Coherent elastic data - call h5ltpath_valid_f(T_group, 'elastic', .true., exists, hdf5_err) - if (exists) then + if (check_group(T_group, 'elastic')) then ! Read cross section data elastic_group = open_group(T_group, 'elastic') dset_id = open_dataset(elastic_group, 'xs') @@ -223,8 +220,7 @@ contains end if ! Inelastic data - call h5ltpath_valid_f(T_group, 'inelastic', .true., exists, hdf5_err) - if (exists) then + if (check_group(T_group, 'inelastic')) then ! Read type of inelastic data inelastic_group = open_group(T_group, 'inelastic') diff --git a/src/secondary_uncorrelated.F90 b/src/secondary_uncorrelated.F90 index fc215484a..756ff83df 100644 --- a/src/secondary_uncorrelated.F90 +++ b/src/secondary_uncorrelated.F90 @@ -1,6 +1,5 @@ module secondary_uncorrelated - use h5lt, only: h5ltpath_valid_f use hdf5, only: HID_T use angle_distribution, only: AngleDistribution @@ -9,7 +8,7 @@ module secondary_uncorrelated use energy_distribution, only: EnergyDistribution, LevelInelastic, & ContinuousTabular, MaxwellEnergy, Evaporation, WattEnergy, DiscretePhoton use error, only: warning - use hdf5_interface, only: read_attribute, open_group, close_group + use hdf5_interface, only: read_attribute, open_group, close_group, check_group use random_lcg, only: prn !=============================================================================== @@ -56,25 +55,19 @@ contains class(UncorrelatedAngleEnergy), intent(inout) :: this integer(HID_T), intent(in) :: group_id - logical :: exists - integer :: hdf5_err integer(HID_T) :: energy_group integer(HID_T) :: angle_group character(MAX_WORD_LEN) :: type - ! Check if energy group is present - call h5ltpath_valid_f(group_id, 'angle', .true., exists, hdf5_err) - - if (exists) then + ! Check if angle group is present & read + if (check_group(group_id, 'angle')) then angle_group = open_group(group_id, 'angle') call this%angle%from_hdf5(angle_group) call close_group(angle_group) end if - ! Check if energy group is present - call h5ltpath_valid_f(group_id, 'energy', .true., exists, hdf5_err) - - if (exists) then + ! Check if energy group is present & read + if (check_group(group_id, 'energy')) then energy_group = open_group(group_id, 'energy') call read_attribute(type, energy_group, 'type') select case (type)