diff --git a/docs/source/io_formats/mgxs_library.rst b/docs/source/io_formats/mgxs_library.rst index b6708a88db..4e5ea21969 100644 --- a/docs/source/io_formats/mgxs_library.rst +++ b/docs/source/io_formats/mgxs_library.rst @@ -6,21 +6,19 @@ Multi-Group Cross Section Library Format OpenMC can be run in continuous-energy mode or multi-group mode, provided the nuclear data is available. In continuous-energy mode, the -``cross_sections.xml`` file contains necessary meta-data for each data set, +``cross_sections.xml`` file contains necessary meta-data for each dataset, including the name and a file system location where the complete library -can be found. In multi-group mode, this ``mgxs.xml`` file contains -this same meta-data describing the nuclide or material, but also contains the -group-wise nuclear data. This portion of the manual describes the format of -the multi-group data library required to be used in the ``mgxs.xml`` -file. +can be found. In multi-group mode, the multi-group meta-data and the +nuclear data itself is contained within an ``mgxs.h5`` file. This portion of +the manual describes the format of the multi-group data library required +to be used in the ``mgxs.h5`` file. -Similar to the other input file types, the multi-group library is provided in -the XML_ format. This library must provide some meta-data about the library -itself (such as the number of groups and the group structure, etc.) as well as -the actual cross section data itself for each of the necessary nuclides or -materials. +The multi-group library is provided in the HDF5_ format. This library must +provide some meta-data about the library itself (such as the number of +groups and the group structure, etc.) as well as the actual cross section +data itself for each of the necessary nuclides or materials. -.. _XML: http://www.w3.org/XML/ +.. _HDF5: http://www.hdfgroup.org/HDF5/ .. _mgxs_lib_spec: @@ -28,277 +26,139 @@ materials. MGXS Library Specification -------------------------- -The multi-group library meta-data is contained within the groups_, -group_structure_, and inverse_velocities_ elements. -The actual multi-group data itself is contained within the xsdata_ element. +**/** -.. _groups: +:Attributes: - **groups** (*int*) -- Number of energy groups + - **group structure** (*double[]*) -- Monotonically increasing + list of group boundaries, in units of MeV. The length of this + array should be the number of groups plus 1. -```` Element --------------------- +**//** -The ```` element has no attributes and simply provides the number of -energy groups contained within the library. +The data within contains the temperature-dependent multi-group +data for the nuclide or material that it represents. - *Default*: None, this must be provided. +:Attributes: - **atomic_weight_ratio** (*double*) -- The atomic weight ratio + (optional, i.e. it is not meaningful for material-wise data). + - **fissionable** (*bool*) -- Whether the dataset is fissionable + (True) or not (False). + - **representation** (*char[]*) -- The method used to generate and + represent the multi-group cross sections. That is, whether they + were generated with scalar flux weighting (or reduced to a + similar representation) and thus are angle-independent, or if the + data was generated with angular dependent fluxes and thus the + data is angle-dependent. Valid values are either "isotropic" or + "angle". + - **num_azimuthal** (*int*) -- Number of equal width angular bins + that the azimuthal angular domain is subdivided if the + `representation` attribute is "angle". This parameter is + ignored otherwise. + - **num_polar** (*int*) -- Number of equal width angular bins + that the polar angular domain is subdivided if the + `representation` attribute is "angle". This parameter is + ignored otherwise. + - **scatter_format** (*char[]*) -- The representation of the + scattering angular distribution. The options are either + "legendre", "histogram", or "tabular". If not provided, the + default of "legendre" will be assumed. + - **order** (*int*) -- Either the Legendre order, number of bins, + or number of points (depending on the value of `scatter_format`) + used to describe the angular distribution associated with each + group-to-group transfer probability. + - **scatter_shape** (*char[]*) -- The shape of the provided + scatter and multiplicity matrix. The values provided are strings + describing the ordering the scattering array is provided in + row-major (i.e., C/C++ and Python) indexing. Valid values are + "[Order][G][G']" or "[Order][G'][G]" where "G'" denotes the + secondary/outgoing energy groups, "G" denotes the incoming + energy groups, and "Order" is the angular distribution index. + This value is not required; if not the default value of + "[Order][G][G']" will be assumed. -.. _group_structure: +**//kTs/** -```` Element ------------------------------ +:Datasets: + - **K** (*double*) -- kT values (in MeV) for each Temperature + TTT (in Kelvin), rounded to the nearest integer -The ```` element has no attributes and should be provided as a -monotonically increasing list of bounding energies, in MeV, for a number of -groups. To provide proper energy boundaries, the length of the data within the -```` element should be one more than the number of groups in -the problem. For example, a two-group problem could be specified as: +**//K/** -.. code-block:: xml +Temperature-dependent data, provided for temperature K. - 0.0 0.625E-6 20.0 +:Datasets: - **total** (*double[]* or *double[][][]*) -- Total cross section. + This is a 1-D vector if `representation` is "isotropic", or a 3-D + vector if `representation` is "angle" with dimensions of + [groups][azimuthal][polar]. + - **absorption** (*double[]* or *double[][][]*) -- Absorption + cross section. + This is a 1-D vector if `representation` is "isotropic", or a 3-D + vector if `representation` is "angle" with dimensions of + [groups][azimuthal][polar]. + - **fission** (*double[]* or *double[][][]*) -- Fission + cross section. + This is a 1-D vector if `representation` is "isotropic", or a 3-D + vector if `representation` is "angle" with dimensions of + [groups][azimuthal][polar]. This is only required if the dataset + is fissionable and fission-tallies are expected to be used. + - **kappa-fission** (*double[]* or *double[][][]*) -- Kappa-Fission + (energy-release from fission) cross section. + This is a 1-D vector if `representation` is "isotropic", or a 3-D + vector if `representation` is "angle" with dimensions of + [groups][azimuthal][polar]. This is only required if the dataset + is fissionable and fission-tallies are expected to be used. + - **chi** (*double[]* or *double[][][]*) -- Fission neutron energy + spectra. + This is a 1-D vector if `representation` is "isotropic", or a 3-D + vector if `representation` is "angle" with dimensions of + [groups][azimuthal][polar]. This is only required if the dataset + is fissionable and fission-tallies are expected to be used. + - **nu-fission** (*double[]* to *double[][][][]*) -- Nu-Fission + cross section. + If **chi** is provided, then `nu-fission` has the same + dimensionality as `fission`. If **chi** is not provided, then + the `nu-fission` data must represent the fission neutron energy + spectra as well and thus will have one additional dimension + for the outgoing energy group. In this case, `nu-fission` has the + same dimensionality as `multiplicity_matrix`. + - **inverse_velocities** (*double[]*) -- Average inverse velocity + for each of the groups in the library. This dataset is optional. -*Default*: None, this must be provided. +**//K/scatter_data/** -.. _inverse_velocities: - -```` Element --------------------------------- - -The ```` element optionally indicates the average -inverse velocity corresponding to each of the groups in the problem. -This element should therefore be an array with a length which matches the -number of groups set in the groups_ element. - -*Default*: Should this be needed by the presence of an ``inverse-velocity`` -score in the ``tallies.xml`` file and not provided in this element, OpenMC -will simply convert the group mid-point energy to an inverse of the velocity -and use this information for tallying. - -.. _xsdata: - -```` Element --------------------- - -The ```` element contains the nuclide or material-specific meta-data as -well as the actual cross section data. The following are the -attributes/sub-elements required to describe the meta-data: - - :name: - The name of the microscopic or macroscopic data set. An extension to the - name must be provided (e.g., the ``.300K`` in ``UO2.300K``). The name and - extension together must be twelve or less characters in length. This - extension must follow a period and be five characters or less in length. - similar to the equivalent in the continuous-energy ``cross_sections.xml`` - file, is used to denote variants of the particular nuclide or material of - interest (i.e. the ``UO2`` data in this example could have been generated - at a temperature of 300K). - - *Default*: None, this must be provided. - - :alias: - An alternative name to use for the microscopic or macroscopic data set. - - *Default*: If no alias is provided, it will adopt the value of ``name``. - - :kT: - The temperature times Boltzmann's constant (in units of MeV) at which the - data was generated. - - *Default*: Room temperature, 2.53E-8 MeV - - :fissionable: - This element states whether or not the data in question is fissionable. - Accepted values are "true" or "false". - - *Default*: None, this element must be provided. - - :representation: - This element provides the method used to generate and represent the - multi-group cross sections. That is, whether they were generated with - scalar flux weighting (or reduced to an equivalent representation) - and thus are angle-independent, or if the data was generated with angular - dependent fluxes and thus the data is angle-dependent. The options are - either "isotropic" or "angle". - - *Default*: "isotropic" - - :num_azimuthal: - This element provides the number of equal width angular bins that the - azimuthal angular domain is subdivided in the case of angle-dependent - cross sections (i.e., "angle" is passed to the ``representation`` element). - Note that these bins are equal in azimuthal angle widths, not equal in the - cosine of the azimuthal angle widths. - - *Default*: If ``representation`` is "angle", this must be provided. This - parameter is not used for other ``representation`` types. - - :num_polar: - This element provides the number of equal width angular bins that the - polar angular domain is subdivided in the case of angle-dependent - cross sections (i.e., "angle" is passed to the ``representation`` element). - Note that these bins are equal in polar angle widths, not equal in the - cosine of the polar angle widths. - - - *Default*: If ``representation`` is "angle", this must be provided. This - parameter is not used for other ``representation`` types. - - :scatt_type: - This element provides the representation of the angular distribution - associated with each group-to-group transfer probability. The options are - either "legendre", "histogram", or "tabular". - The "legendre" option means the angular distribution has been - expanded via Legendre polynomials of the order provided in the "order" - element. - The "histogram" option means the angular distribution is provided in - an equi-width histogram format with a number of bins as provided in the - "order" element. This is useful when the angular distribution was - obtained from a Monte Carlo tally and thus is natively in the histogram - format. - The "tabular" option means the angular distribution is provided in an - equi-spaced point-wise representation. - - *Default*: "legendre" - - :order: - This element provides either the Legendre order, number of bins, or number - of points used to describe the angular distribution associated with each - group-to-group transfer probability. The specific meaning of this bin - depends upon the value of ``scatt_type`` as discussed above. - - *Default*: None, this element must be provided. - - :tabular_legendre: - This optional element is used to set how the Legendre scattering kernel, if - provided via the ``scatt_type`` element above, is represented and thus used - during the scattering process. Specifically, the options are to either - convert the Legendre expansion to a tabular representation or leave it as - a set of Legendre coefficients. Converting to a tabular representation - will cost memory but can allow for a decrease in runtime compared to - leaving as a set of Legendre coefficients. This element has the following - attributes/sub-elements: - - :enable: - This attribute/sub-element denotes whether or not the conversion to the - tabular format should be performed or not. A value of "true" means - the conversion should be performed, "false" means it should not. - - *Default*: "true" - - :num_points: - If the conversion is to take place the number of tabular points is - required. This attribute/sub-element allows the user to set the desired - number of points. - - *Default*: 33 - - The following attributes/sub-elements are the cross section values to - be used during the transport process. - - :total: - This element requires the group-wise total cross section ordered by - increasing group index (i.e., fast to thermal). If ``representation`` is - "isotropic", then the length of this list should equal the number of - groups described in the ``groups`` element. If ``representation`` is - "angle", then the length of this list should equal the number of groups - times the number of azimuthal angles times the number of polar angles, - with the inner-dimension being groups, intermediate-dimension being - azimuthal angles and outer-dimension being the polar angles. - - *Default*: If not provided, it will be determined by summing the - absorption and scattering cross sections. - - :absorption: - This element requires the group-wise absorption cross section ordered by - increasing group index (i.e., fast to thermal). If ``representation`` is - "isotropic", then the length of this list should equal the number of - groups described in the ``groups`` element. If ``representation`` is - "angle", then the length of this list should equal the number of groups - times the number of azimuthal angles times the number of polar angles, - with the inner-dimension being groups, intermediate-dimension being - azimuthal angles and outer-dimension being the polar angles. - - *Default*: None, this must be provided. - - :scatter: - This element requires the scattering moment matrices presented with the - columns representing incoming group and rows representing the outgoing - group. That is, down-scatter will be above the diagonal of the resultant - matrix. This matrix is repeated for every Legendre order (in order of - increasing orders) if ``scatt_type`` is "legendre"; otherwise, this - matrix is repeated for every bin of the histogram or tabular - representation. Finally, if ``representation`` is "angle", the above - is repeated for every azimuthal angle and every polar angle, in that - order. - - *Default*: None, this must be provided. - - :multiplicity: - This element provides the ratio of neutrons produced in scattering - collisions to the neutrons which undergo scattering collisions; that is, - the multiplicity provides the code with a scaling factor to account for - neutrons being produced in (n,xn) reactions. This information is assumed - isotropic and therefore does not need to be repeated for every Legendre - moment or histogram/tabular bin. This matrix follows the same arrangement - as described for the ``scatter`` element, with the exception of the - data needed to provide the scattering type information. - - *Default*: Multiplicities of 1.0 are assumed (i.e., (n,xn) reactions are - neglected). - - The following fission-specific data are only needed should ``fissionable`` - be "true". - - :fission: - This element requires the group-wise fission cross section ordered by - increasing group index (i.e., fast to thermal). If ``representation`` is - "isotropic", then the length of this list should equal the number of - groups described in the ``groups`` element. If ``representation`` is - "angle", then the length of this list should equal the number of groups - times the number of azimuthal angles times the number of polar angles, - with the inner-dimension being groups, intermediate-dimension being - azimuthal angles and outer-dimension being the polar angles. - - *Default*: None, this is required only if fission tallies are - requested and the material is fissionable. - - :kappa_fission: - This element requires the group-wise kappa-fission cross section ordered by - increasing group index (i.e., fast to thermal). If ``representation`` is - "isotropic", then the length of this list should equal the number of - groups described in the ``groups`` element. If ``representation`` is - "angle", then the length of this list should equal the number of groups - times the number of azimuthal angles times the number of polar angles, - with the inner-dimension being groups, intermediate-dimension being - azimuthal angles and outer-dimension being the polar angles. - - *Default*: None, this is required only if kappa_fission tallies are - requested and the material is fissionable. - - :chi: - This element requires the group-wise fission spectra ordered by - increasing group index (i.e., fast to thermal). This element should be - used if making the common approximation that the fission spectra does - not depend on incoming energy. If the user does not wish to make this - approximation, then this should not be provided and this information - included in the ``nu_fission`` element instead. If ``representation`` is - "isotropic", then the length of this list should equal the number of - groups described in the ``groups`` element. If ``representation`` is - "angle", then the length of this list should equal the number of groups - times the number of azimuthal angles times the number of polar angles, - with the inner-dimension being groups, intermediate-dimension being - azimuthal angles and outer-dimension being the polar angles. - - *Default*: None, either this element is provided or ``nu_fission`` is - provided in fission matrix form, or the material is not fissionable. - - :nu_fission: - This element provides either the group-wise fission production cross - section vector (i.e., if ``chi`` is provided), or is the group-wise fission - production matrix. If providing the vector, it should be ordered the same - as the ``fission`` data. If providing the matrix, it should be ordered - the same as the ``multiplicity`` matrix. - - *Default*: None, either this element must be provided if the material - is fissionable. +Data specific to neutron scattering for the temperature K +:Datasets: - **g_min** (*int[]* or *int[][][]*) -- + Minimum (most energetic) groups with non-zero values of + the scattering matrix provided. If `scatter_shape` is + "[Order][G][G']" then `g_min` will describe the minimum values + of "G'" for each "G"; if `scatter_shape` is "[Order][G'][G]" + then `g_min` will describe the minimum values of "G" for each "G'". + These group numbers use the standard + ordering where the fastest neutron energy group is group 1 while + the slowest neutron energy group is group G. + The dimensionality of `g_min` is: + `g_min[g]`, or `g_min[num_polar][num_azimuthal][g]`. + The former is used when `representation` is "isotropic", and the + latter when `representation` is "angle". + - **g_max** (*int[]* or *int[][][]*) -- + Similar to `g_min`, except this dataset describes the maximum + (least energetic) groups with non-zero values of + the scattering matrix. + - **scatter_matrix** (*double[]*) -- Flattened representation of the + scattering moment matrices. The pre-flattened array corresponds to + the shape provied in `scatter_shape`, but if `representation` is + "angle" the dimensionality in `scatter_shape` is prepended by + "[num_polar][num_azimuthal]" dimensions. The right-most energy + group dimension will only include the entries between `g_min` and + `g_max`. + dimension has a dimensionality of `g_min` to `g_max`. + - **multiplicity_matrix** (*double[]*) -- Flattened representation of + the scattering moment matrices. This dataset provides the code with + a scaling factor to account for neutrons being produced in (n,xn) + reactions. This is assumed isotropic and therefore is not repeated + for every Legendre moment or histogram/tabular bin. This dataset is + optional, if it is not provided no multiplication (i.e., values of + 1.0) will be assumed. + The pre-flattened array is shapes consistent with `scatter_matrix` + except the "[Order]" dimension in `scatter_shape` is ignored since + this data is assumed isotropic. \ No newline at end of file diff --git a/docs/source/pythonapi/examples/mgxs-part-iv.ipynb b/docs/source/pythonapi/examples/mgxs-part-iv.ipynb index 0101b402dc..74bbfb7d35 100644 --- a/docs/source/pythonapi/examples/mgxs-part-iv.ipynb +++ b/docs/source/pythonapi/examples/mgxs-part-iv.ipynb @@ -8,9 +8,7 @@ "\n", " - Calculation of multi-group cross sections for a fuel assembly\n", " - Automated creation and storage of MGXS with openmc.mgxs.Library\n", - " - Steady-state pin-by-pin fission rates comparison between continuous-energy and multi-group OpenMC.\n", - "\n", - "Note: This Notebook illustrates the use of Pandas DataFrames to containerize multi-group cross section data. We recommend using Pandas >v0.15.0 or later since OpenMC's Python API leverages the multi-indexing feature included in the most recent releases of Pandas.\n" + " - Steady-state pin-by-pin fission rates comparison between continuous-energy and multi-group OpenMC.\n" ] }, { @@ -431,7 +429,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "" ] @@ -577,7 +575,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/home/smharper/openmc/openmc/mgxs/library.py:373: RuntimeWarning: The P0 correction will be ignored since the scattering order 0 is greater than zero\n", + "/home/nelsonag/git/openmc/openmc/mgxs/library.py:373: RuntimeWarning: The P0 correction will be ignored since the scattering order 0 is greater than zero\n", " warn(msg, RuntimeWarning)\n" ] } @@ -733,9 +731,9 @@ " 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 | b02fa21928a37a2254bec13c9802ff8173b6aefd\n", - " Date/Time | 2016-09-29 23:02:46\n", - " MPI Processes | 1\n", + " Git SHA1 | 9d769378838a8404a7e878a65a6bf7f9fb8e083d\n", + " Date/Time | 2016-10-04 19:54:41\n", + " OpenMP Threads | 8\n", "\n", " ===========================================================================\n", " ========================> INITIALIZATION <=========================\n", @@ -745,12 +743,12 @@ " Reading geometry XML file...\n", " Reading cross sections XML file...\n", " Reading materials XML file...\n", - " Reading U235 from /home/smharper/openmc/data/nndc_hdf5/U235.h5\n", - " Reading U238 from /home/smharper/openmc/data/nndc_hdf5/U238.h5\n", - " Reading O16 from /home/smharper/openmc/data/nndc_hdf5/O16.h5\n", - " Reading Zr90 from /home/smharper/openmc/data/nndc_hdf5/Zr90.h5\n", - " Reading H1 from /home/smharper/openmc/data/nndc_hdf5/H1.h5\n", - " Reading B10 from /home/smharper/openmc/data/nndc_hdf5/B10.h5\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 Zr90 from /opt/xsdata/nndc/Zr90.h5\n", + " Reading H1 from /opt/xsdata/nndc/H1.h5\n", + " Reading B10 from /opt/xsdata/nndc/B10.h5\n", " Maximum neutron transport energy: 20.0000 MeV for U235\n", " Reading tallies XML file...\n", " Building neighboring cells lists for each surface...\n", @@ -821,20 +819,20 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 2.9400E-01 seconds\n", - " Reading cross sections = 1.7600E-01 seconds\n", - " Total time in simulation = 7.0412E+01 seconds\n", - " Time in transport only = 7.0399E+01 seconds\n", - " Time in inactive batches = 9.6650E+00 seconds\n", - " Time in active batches = 6.0747E+01 seconds\n", - " Time synchronizing fission bank = 5.0000E-03 seconds\n", - " Sampling source sites = 3.0000E-03 seconds\n", - " SEND/RECV source sites = 2.0000E-03 seconds\n", - " Time accumulating tallies = 0.0000E+00 seconds\n", - " Total time for finalization = 0.0000E+00 seconds\n", - " Total time elapsed = 7.0742E+01 seconds\n", - " Calculation Rate (inactive) = 5173.31 neutrons/second\n", - " Calculation Rate (active) = 3292.34 neutrons/second\n", + " Total time for initialization = 2.5432E-01 seconds\n", + " Reading cross sections = 1.4823E-01 seconds\n", + " Total time in simulation = 7.6226E+00 seconds\n", + " Time in transport only = 7.5567E+00 seconds\n", + " Time in inactive batches = 8.4858E-01 seconds\n", + " Time in active batches = 6.7740E+00 seconds\n", + " Time synchronizing fission bank = 4.9022E-03 seconds\n", + " Sampling source sites = 3.4092E-03 seconds\n", + " SEND/RECV source sites = 1.4584E-03 seconds\n", + " Time accumulating tallies = 1.0030E-04 seconds\n", + " Total time for finalization = 3.2380E-06 seconds\n", + " Total time elapsed = 7.8942E+00 seconds\n", + " Calculation Rate (inactive) = 58922.0 neutrons/second\n", + " Calculation Rate (active) = 29524.6 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", @@ -972,13 +970,26 @@ "metadata": { "collapsed": false }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/nelsonag/git/openmc/openmc/tallies.py:1945: 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:1946: 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:1947: RuntimeWarning: invalid value encountered in true_divide\n", + " new_tally._mean = data['self']['mean'] / data['other']['mean']\n" + ] + } + ], "source": [ "# Create a MGXS File which can then be written to disk\n", "mgxs_file = mgxs_lib.create_mg_library(xs_type='macro', xsdata_names=['fuel', 'zircaloy', 'water'])\n", "\n", - "# Write the file to disk using the default filename of `mgxs.xml`\n", - "mgxs_file.export_to_xml()" + "# Write the file to disk using the default filename of `mgxs.h5`\n", + "mgxs_file.export_to_hdf5()" ] }, { @@ -1050,7 +1061,7 @@ "outputs": [], "source": [ "# Set the location of the cross sections file\n", - "settings_file.cross_sections = './mgxs.xml'\n", + "settings_file.cross_sections = './mgxs.h5'\n", "settings_file.energy_mode = 'multi-group'\n", "\n", "# Export to \"settings.xml\"\n", @@ -1107,9 +1118,9 @@ " 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 | b02fa21928a37a2254bec13c9802ff8173b6aefd\n", - " Date/Time | 2016-09-29 23:04:13\n", - " MPI Processes | 1\n", + " Git SHA1 | 9d769378838a8404a7e878a65a6bf7f9fb8e083d\n", + " Date/Time | 2016-10-04 19:54:49\n", + " OpenMP Threads | 8\n", "\n", " ===========================================================================\n", " ========================> INITIALIZATION <=========================\n", @@ -1117,14 +1128,14 @@ "\n", " Reading settings XML file...\n", " Reading geometry XML file...\n", - " Reading cross sections XML file...\n", + " Reading cross sections HDF5 file...\n", " Reading materials XML file...\n", " Reading tallies XML file...\n", - " Building neighboring cells lists for each surface...\n", " Loading Cross Section Data...\n", " Loading fuel Data...\n", " Loading zircaloy Data...\n", " Loading water Data...\n", + " Building neighboring cells lists for each surface...\n", " Initializing source particles...\n", "\n", " ===========================================================================\n", @@ -1133,56 +1144,56 @@ "\n", " Bat./Gen. k Average k \n", " ========= ======== ==================== \n", - " 1/1 0.99122 \n", - " 2/1 1.03963 \n", - " 3/1 1.01551 \n", - " 4/1 1.03582 \n", - " 5/1 0.99023 \n", - " 6/1 1.00419 \n", - " 7/1 1.02047 \n", - " 8/1 1.05456 \n", - " 9/1 1.01063 \n", - " 10/1 1.03370 \n", - " 11/1 1.04616 \n", - " 12/1 1.04458 1.04537 +/- 0.00079\n", - " 13/1 1.02171 1.03748 +/- 0.00790\n", - " 14/1 1.02060 1.03326 +/- 0.00700\n", - " 15/1 1.01653 1.02992 +/- 0.00637\n", - " 16/1 1.02956 1.02986 +/- 0.00520\n", - " 17/1 1.01145 1.02723 +/- 0.00512\n", - " 18/1 1.03774 1.02854 +/- 0.00463\n", - " 19/1 1.00829 1.02629 +/- 0.00466\n", - " 20/1 1.03624 1.02729 +/- 0.00429\n", - " 21/1 1.03296 1.02780 +/- 0.00391\n", - " 22/1 0.99315 1.02491 +/- 0.00459\n", - " 23/1 0.99628 1.02271 +/- 0.00476\n", - " 24/1 1.04034 1.02397 +/- 0.00459\n", - " 25/1 1.02523 1.02406 +/- 0.00427\n", - " 26/1 1.07905 1.02749 +/- 0.00527\n", - " 27/1 1.01678 1.02686 +/- 0.00499\n", - " 28/1 1.01817 1.02638 +/- 0.00473\n", - " 29/1 1.03293 1.02672 +/- 0.00449\n", - " 30/1 1.01224 1.02600 +/- 0.00432\n", - " 31/1 1.01524 1.02549 +/- 0.00414\n", - " 32/1 1.00996 1.02478 +/- 0.00401\n", - " 33/1 1.05545 1.02612 +/- 0.00406\n", - " 34/1 1.02082 1.02589 +/- 0.00389\n", - " 35/1 0.99120 1.02451 +/- 0.00398\n", - " 36/1 1.03012 1.02472 +/- 0.00383\n", - " 37/1 1.01179 1.02424 +/- 0.00372\n", - " 38/1 1.04023 1.02481 +/- 0.00363\n", - " 39/1 1.05876 1.02598 +/- 0.00369\n", - " 40/1 0.99332 1.02490 +/- 0.00373\n", - " 41/1 1.05319 1.02581 +/- 0.00372\n", - " 42/1 1.03381 1.02606 +/- 0.00361\n", - " 43/1 1.00607 1.02545 +/- 0.00355\n", - " 44/1 1.03957 1.02587 +/- 0.00347\n", - " 45/1 1.02472 1.02584 +/- 0.00337\n", - " 46/1 1.00948 1.02538 +/- 0.00331\n", - " 47/1 1.02380 1.02534 +/- 0.00322\n", - " 48/1 1.05392 1.02609 +/- 0.00322\n", - " 49/1 1.01171 1.02572 +/- 0.00316\n", - " 50/1 1.03942 1.02606 +/- 0.00310\n", + " 1/1 0.99100 \n", + " 2/1 1.02112 \n", + " 3/1 1.04240 \n", + " 4/1 1.01591 \n", + " 5/1 1.02044 \n", + " 6/1 1.04127 \n", + " 7/1 1.01783 \n", + " 8/1 1.03856 \n", + " 9/1 1.03637 \n", + " 10/1 1.03884 \n", + " 11/1 1.04466 \n", + " 12/1 1.01060 1.02763 +/- 0.01703\n", + " 13/1 1.02517 1.02681 +/- 0.00987\n", + " 14/1 1.05287 1.03333 +/- 0.00954\n", + " 15/1 1.04369 1.03540 +/- 0.00768\n", + " 16/1 1.01304 1.03167 +/- 0.00729\n", + " 17/1 1.04258 1.03323 +/- 0.00636\n", + " 18/1 1.02301 1.03195 +/- 0.00565\n", + " 19/1 1.03906 1.03274 +/- 0.00505\n", + " 20/1 1.04148 1.03362 +/- 0.00460\n", + " 21/1 1.01271 1.03172 +/- 0.00457\n", + " 22/1 1.02021 1.03076 +/- 0.00428\n", + " 23/1 0.99553 1.02805 +/- 0.00478\n", + " 24/1 1.02434 1.02778 +/- 0.00443\n", + " 25/1 1.02987 1.02792 +/- 0.00413\n", + " 26/1 1.01676 1.02722 +/- 0.00393\n", + " 27/1 1.02738 1.02723 +/- 0.00369\n", + " 28/1 1.04014 1.02795 +/- 0.00355\n", + " 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.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.02379 1.02601 +/- 0.00270\n", + " 38/1 1.03648 1.02638 +/- 0.00263\n", + " 39/1 1.03237 1.02659 +/- 0.00254\n", + " 40/1 1.03501 1.02687 +/- 0.00247\n", + " 41/1 1.02054 1.02666 +/- 0.00240\n", + " 42/1 1.05751 1.02763 +/- 0.00252\n", + " 43/1 1.00751 1.02702 +/- 0.00251\n", + " 44/1 1.04743 1.02762 +/- 0.00251\n", + " 45/1 1.05212 1.02832 +/- 0.00254\n", + " 46/1 1.01839 1.02804 +/- 0.00248\n", + " 47/1 1.00424 1.02740 +/- 0.00250\n", + " 48/1 1.03117 1.02750 +/- 0.00243\n", + " 49/1 1.00988 1.02705 +/- 0.00241\n", + " 50/1 1.01943 1.02686 +/- 0.00236\n", " Creating state point statepoint.50.h5...\n", "\n", " ===========================================================================\n", @@ -1192,27 +1203,27 @@ "\n", " =======================> TIMING STATISTICS <=======================\n", "\n", - " Total time for initialization = 2.3000E-02 seconds\n", - " Reading cross sections = 2.0000E-03 seconds\n", - " Total time in simulation = 5.2404E+01 seconds\n", - " Time in transport only = 5.2378E+01 seconds\n", - " Time in inactive batches = 6.5320E+00 seconds\n", - " Time in active batches = 4.5872E+01 seconds\n", - " Time synchronizing fission bank = 1.2000E-02 seconds\n", - " Sampling source sites = 6.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 = 5.2467E+01 seconds\n", - " Calculation Rate (inactive) = 7654.62 neutrons/second\n", - " Calculation Rate (active) = 4359.96 neutrons/second\n", + " Total time for initialization = 9.9611E-02 seconds\n", + " Reading cross sections = 2.2051E-02 seconds\n", + " Total time in simulation = 6.3645E+00 seconds\n", + " Time in transport only = 6.3383E+00 seconds\n", + " Time in inactive batches = 6.3592E-01 seconds\n", + " Time in active batches = 5.7285E+00 seconds\n", + " Time synchronizing fission bank = 5.1108E-03 seconds\n", + " Sampling source sites = 3.7109E-03 seconds\n", + " SEND/RECV source sites = 1.3393E-03 seconds\n", + " Time accumulating tallies = 8.0199E-05 seconds\n", + " Total time for finalization = 2.9170E-06 seconds\n", + " Total time elapsed = 6.4828E+00 seconds\n", + " Calculation Rate (inactive) = 78625.7 neutrons/second\n", + " Calculation Rate (active) = 34912.9 neutrons/second\n", "\n", " ============================> RESULTS <============================\n", "\n", - " k-effective (Collision) = 1.02474 +/- 0.00282\n", - " k-effective (Track-length) = 1.02606 +/- 0.00310\n", - " k-effective (Absorption) = 1.02589 +/- 0.00165\n", - " Combined k-effective = 1.02601 +/- 0.00170\n", + " k-effective (Collision) = 1.02515 +/- 0.00252\n", + " k-effective (Track-length) = 1.02686 +/- 0.00236\n", + " k-effective (Absorption) = 1.02678 +/- 0.00178\n", + " Combined k-effective = 1.02710 +/- 0.00176\n", " Leakage Fraction = 0.00000 +/- 0.00000\n", "\n" ] @@ -1294,8 +1305,8 @@ "output_type": "stream", "text": [ "Continuous-Energy keff = 1.024295\n", - "Multi-Group keff = 1.026013\n", - "bias [pcm]: -171.8\n" + "Multi-Group keff = 1.027098\n", + "bias [pcm]: -280.3\n" ] } ], @@ -1392,7 +1403,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 40, @@ -1401,9 +1412,9 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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\nrkJggg==\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1433,7 +1444,7 @@ "collapsed": true }, "source": [ - "We also see very good agreement between the fission rate distributions, though these should converge closer together with an increasing number of particle histories in both the continuous-energy run to generate the multi-group cross sections, and in the multi-group calculation itself." + "We also see good agreement between the fission rate distributions, though these should converge closer together with an increasing number of particle histories in both the continuous-energy run to generate the multi-group cross sections, and in the multi-group calculation itself." ] }, { diff --git a/docs/source/usersguide/input.rst b/docs/source/usersguide/input.rst index 847dc66fff..6327d4106a 100644 --- a/docs/source/usersguide/input.rst +++ b/docs/source/usersguide/input.rst @@ -121,10 +121,13 @@ multi-group mode. ```` Element -------------------- -The ```` element indicates the weight cutoff used below which particles -undergo Russian roulette. Surviving particles are assigned a user-determined -weight. Note that weight cutoffs and Russian rouletting are not turned on by -default. This element has the following attributes/sub-elements: +The ```` element indicates two kinds of cutoffs. The first is the weight +cutoff used below which particles undergo Russian roulette. Surviving particles +are assigned a user-determined weight. Note that weight cutoffs and Russian +rouletting are not turned on by default. The second is the energy cutoff which +is used to kill particles under certain energy. The energy cutoff should not be +used unless you know particles under the energy are of no importance to results +you care. This element has the following attributes/sub-elements: :weight: The weight below which particles undergo Russian roulette. @@ -137,6 +140,11 @@ default. This element has the following attributes/sub-elements: *Default*: 1.0 + :energy: + The energy under which particles will be killed. + + *Default*: 0.0 + .. _eigenvalue: ```` Element @@ -709,6 +717,36 @@ survival biasing, otherwise known as implicit capture or absorption. *Default*: false +.. _tabular_legendre: + +```` Element +--------------------------------- + +The optional ```` element specifies how the multi-group +Legendre scattering kernel is represented if encountered in a multi-group +problem. Specifically, the options are to either convert the Legendre +expansion to a tabular representation or leave it as a set of Legendre +coefficients. Converting to a tabular representation will cost memory but can +allow for a decrease in runtime compared to leaving as a set of Legendre +coefficients. This element has the following attributes/sub-elements: + + :enable: + This attribute/sub-element denotes whether or not the conversion of a + Legendre scattering expansion to the tabular format should be performed or + not. A value of “true” means the conversion should be performed, “false” + means it will not. + + *Default*: true + + :num_points: + If the conversion is to take place the number of tabular points is + required. This attribute/sub-element allows the user to set the desired + number of points. + + *Default*: 33 + + .. note:: This element is only used in the multi-group :ref:`energy_mode`. + .. _temperature_default: ```` Element @@ -872,6 +910,19 @@ displayed. This element takes the following attributes: *Default*: 5 +```` Element +------------------------------------- + +The ```` element indicates whether fission neutrons +should be created or not. If this element is set to "true", fission neutrons +will be created; otherwise the fission is treated as capture and no fission +neutron will be created. Note that this option is only applied to fixed source +calculation. For eigenvalue calculation, fission will always be treated as real +fission. + + *Default*: true + + ```` Element ------------------------- diff --git a/examples/python/pincell_multigroup/build-xml.py b/examples/python/pincell_multigroup/build-xml.py index de76e59f05..216c565397 100644 --- a/examples/python/pincell_multigroup/build-xml.py +++ b/examples/python/pincell_multigroup/build-xml.py @@ -21,44 +21,47 @@ groups = openmc.mgxs.EnergyGroups(group_edges=[1E-11, 0.0635E-6, 10.0E-6, # Instantiate the 7-group (C5G7) cross section data uo2_xsdata = openmc.XSdata('UO2', groups) uo2_xsdata.order = 0 -uo2_xsdata.total = [0.1779492, 0.3298048, 0.4803882, 0.5543674, - 0.3118013, 0.3951678, 0.5644058] -uo2_xsdata.absorption = [8.0248E-03, 3.7174E-03, 2.6769E-02, 9.6236E-02, - 3.0020E-02, 1.1126E-01, 2.8278E-01] -uo2_xsdata.scatter = [[[0.1275370, 0.0423780, 0.0000094, 0.0000000, 0.0000000, 0.0000000, 0.0000000], - [0.0000000, 0.3244560, 0.0016314, 0.0000000, 0.0000000, 0.0000000, 0.0000000], - [0.0000000, 0.0000000, 0.4509400, 0.0026792, 0.0000000, 0.0000000, 0.0000000], - [0.0000000, 0.0000000, 0.0000000, 0.4525650, 0.0055664, 0.0000000, 0.0000000], - [0.0000000, 0.0000000, 0.0000000, 0.0001253, 0.2714010, 0.0102550, 0.0000000], - [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0012968, 0.2658020, 0.0168090], - [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0085458, 0.2730800]]] -uo2_xsdata.fission = [7.21206E-03, 8.19301E-04, 6.45320E-03, - 1.85648E-02, 1.78084E-02, 8.30348E-02, - 2.16004E-01] -uo2_xsdata.nu_fission = [2.005998E-02, 2.027303E-03, 1.570599E-02, - 4.518301E-02, 4.334208E-02, 2.020901E-01, - 5.257105E-01] -uo2_xsdata.chi = [5.8791E-01, 4.1176E-01, 3.3906E-04, 1.1761E-07, - 0.0000E+00, 0.0000E+00, 0.0000E+00] +uo2_xsdata.set_total( + [0.1779492, 0.3298048, 0.4803882, 0.5543674, 0.3118013, 0.3951678, + 0.5644058]) +uo2_xsdata.set_absorption([8.0248E-03, 3.7174E-03, 2.6769E-02, 9.6236E-02, + 3.0020E-02, 1.1126E-01, 2.8278E-01]) +uo2_xsdata.set_scatter_matrix( + [[[0.1275370, 0.0423780, 0.0000094, 0.0000000, 0.0000000, 0.0000000, 0.0000000], + [0.0000000, 0.3244560, 0.0016314, 0.0000000, 0.0000000, 0.0000000, 0.0000000], + [0.0000000, 0.0000000, 0.4509400, 0.0026792, 0.0000000, 0.0000000, 0.0000000], + [0.0000000, 0.0000000, 0.0000000, 0.4525650, 0.0055664, 0.0000000, 0.0000000], + [0.0000000, 0.0000000, 0.0000000, 0.0001253, 0.2714010, 0.0102550, 0.0000000], + [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0012968, 0.2658020, 0.0168090], + [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0085458, 0.2730800]]]) +uo2_xsdata.set_fission([7.21206E-03, 8.19301E-04, 6.45320E-03, + 1.85648E-02, 1.78084E-02, 8.30348E-02, + 2.16004E-01]) +uo2_xsdata.set_nu_fission([2.005998E-02, 2.027303E-03, 1.570599E-02, + 4.518301E-02, 4.334208E-02, 2.020901E-01, + 5.257105E-01]) +uo2_xsdata.set_chi([5.8791E-01, 4.1176E-01, 3.3906E-04, 1.1761E-07, 0.0000E+00, + 0.0000E+00, 0.0000E+00]) h2o_xsdata = openmc.XSdata('LWTR', groups) h2o_xsdata.order = 0 -h2o_xsdata.total = [0.15920605, 0.412969593, 0.59030986, 0.58435, - 0.718, 1.2544497, 2.650379] -h2o_xsdata.absorption = [6.0105E-04, 1.5793E-05, 3.3716E-04, - 1.9406E-03, 5.7416E-03, 1.5001E-02, - 3.7239E-02] -h2o_xsdata.scatter = [[[0.0444777, 0.1134000, 0.0007235, 0.0000037, 0.0000001, 0.0000000, 0.0000000], - [0.0000000, 0.2823340, 0.1299400, 0.0006234, 0.0000480, 0.0000074, 0.0000010], - [0.0000000, 0.0000000, 0.3452560, 0.2245700, 0.0169990, 0.0026443, 0.0005034], - [0.0000000, 0.0000000, 0.0000000, 0.0910284, 0.4155100, 0.0637320, 0.0121390], - [0.0000000, 0.0000000, 0.0000000, 0.0000714, 0.1391380, 0.5118200, 0.0612290], - [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0022157, 0.6999130, 0.5373200], - [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.1324400, 2.4807000]]] +h2o_xsdata.set_total([0.15920605, 0.412969593, 0.59030986, 0.58435, + 0.718, 1.2544497, 2.650379]) +h2o_xsdata.set_absorption([6.0105E-04, 1.5793E-05, 3.3716E-04, + 1.9406E-03, 5.7416E-03, 1.5001E-02, + 3.7239E-02]) +h2o_xsdata.set_scatter_matrix( + [[[0.0444777, 0.1134000, 0.0007235, 0.0000037, 0.0000001, 0.0000000, 0.0000000], + [0.0000000, 0.2823340, 0.1299400, 0.0006234, 0.0000480, 0.0000074, 0.0000010], + [0.0000000, 0.0000000, 0.3452560, 0.2245700, 0.0169990, 0.0026443, 0.0005034], + [0.0000000, 0.0000000, 0.0000000, 0.0910284, 0.4155100, 0.0637320, 0.0121390], + [0.0000000, 0.0000000, 0.0000000, 0.0000714, 0.1391380, 0.5118200, 0.0612290], + [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0022157, 0.6999130, 0.5373200], + [0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.1324400, 2.4807000]]]) mg_cross_sections_file = openmc.MGXSLibrary(groups) mg_cross_sections_file.add_xsdatas([uo2_xsdata, h2o_xsdata]) -mg_cross_sections_file.export_to_xml() +mg_cross_sections_file.export_to_hdf5() ############################################################################### @@ -129,7 +132,7 @@ geometry.export_to_xml() # Instantiate a Settings object, set all runtime parameters, and export to XML settings_file = openmc.Settings() settings_file.energy_mode = "multi-group" -settings_file.cross_sections = "./mgxs.xml" +settings_file.cross_sections = "./mgxs.h5" settings_file.batches = batches settings_file.inactive = inactive settings_file.particles = particles diff --git a/examples/xml/pincell_multigroup/mg_cross_sections.xml b/examples/xml/pincell_multigroup/mg_cross_sections.xml deleted file mode 100644 index 19d319f23e..0000000000 --- a/examples/xml/pincell_multigroup/mg_cross_sections.xml +++ /dev/null @@ -1,383 +0,0 @@ - - - - 7 - - 1E-11 0.0635E-6 10.0E-6 1.0E-4 1.0E-3 0.5 1.0 20.0 - - - - - - UO2 - UO2 - 2.53E-8 - 0 - true - - isotropic - - - - 8.0248E-03 3.7174E-03 2.6769E-02 9.6236E-02 3.0020E-02 1.1126E-01 2.8278E-01 - - - - 2.005998E-02 2.027303E-03 1.570599E-02 4.518301E-02 4.334208E-02 2.020901E-01 5.257105E-01 - - - - 5.8791E-01 4.1176E-01 3.3906E-04 1.1761E-07 0.0000E+00 0.0000E+00 0.0000E+00 - - - 7.21206E-03 8.19301E-04 6.45320E-03 1.85648E-02 1.78084E-02 8.30348E-02 2.16004E-01 - - - - - - 1.0 1.0 1.0 1.0 1.0 1.0 1.0 - - - - - - 0.1275370 0.0423780 0.0000094 0.0000000 0.0000000 0.0000000 0.0000000 - 0.0000000 0.3244560 0.0016314 0.0000000 0.0000000 0.0000000 0.0000000 - 0.0000000 0.0000000 0.4509400 0.0026792 0.0000000 0.0000000 0.0000000 - 0.0000000 0.0000000 0.0000000 0.4525650 0.0055664 0.0000000 0.0000000 - 0.0000000 0.0000000 0.0000000 0.0001253 0.2714010 0.0102550 0.0000000 - 0.0000000 0.0000000 0.0000000 0.0000000 0.0012968 0.2658020 0.0168090 - 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0085458 0.2730800 - - - - - 0.1779492 0.3298048 0.4803882 0.5543674000000001 0.3118013 0.39516779999999996 0.5644058 - - - - - - - MOX1 - MOX1 - 2.53E-8 - 0 - true - - - - 8.4339E-03 3.7577E-03 2.7970E-02 1.0421E-01 1.3994E-01 4.0918E-01 4.0935E-01 - - - - 1.27888062E-02 8.95701528E-03 7.37557218E-06 2.55837033E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 1.49041240E-03 1.04385401E-03 8.59552023E-07 2.98153464E-10 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 9.56411400E-03 6.69850756E-03 5.51582469E-06 1.91327830E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 3.84928781E-02 2.69596154E-02 2.21996483E-05 7.70040890E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 1.80629998E-02 1.26509513E-02 1.04173100E-05 3.61346022E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 3.91930789E-01 2.74500216E-01 2.26034688E-04 7.84048241E-08 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 4.19762096E-01 2.93992687E-01 2.42085585E-04 8.39724109E-08 0.00000000E+00 0.00000000E+00 0.00000000E+00 - - - - 7.62704E-03 8.76898E-04 5.69835E-03 2.28872E-02 1.07635E-02 2.32757E-01 2.48968E-01 - - - - - 1.0 1.0 1.0 1.0 1.0 1.0 1.0 - - - - - - 1.27537000E-01 4.23780000E-02 9.43740000E-06 5.51630000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 3.24456000E-01 1.63140000E-03 3.14270000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 4.50940000E-01 2.67920000E-03 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 4.52565000E-01 5.56640000E-03 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 1.25250000E-04 2.71401000E-01 1.02550000E-02 1.00210000E-08 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 1.29680000E-03 2.65802000E-01 1.68090000E-02 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 8.54580000E-03 2.73080000E-01 - - - - 0.1783583429163 0.3298451031427 0.4815892 0.5623414 0.421721260021 0.6930878 0.6909757999999999 - - - - - - - MOX2 - MOX2 - 2.53E-8 - 0 - true - - - - 0.0090657 0.0042967 0.032881 0.12203 0.18298 0.56846 0.58521 - - - - 1.40004593E-02 9.80563205E-03 8.07435789E-06 2.80075866E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 2.26856185E-03 1.58885378E-03 1.30832709E-06 4.53820413E-10 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 1.41886199E-02 9.93741584E-03 8.18287404E-06 2.83839974E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 5.54788444E-02 3.88562347E-02 3.19958106E-05 1.10984111E-08 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 2.69085702E-02 1.88462058E-02 1.55187355E-05 5.38299559E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 5.45687127E-01 3.82187973E-01 3.14709185E-04 1.09163414E-07 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 6.13307712E-01 4.29548032E-01 3.53707392E-04 1.22690752E-07 0.00000000E+00 0.00000000E+00 0.00000000E+00 - - - - 0.00825446 0.00132565 0.00842156 0.032873 0.0159636 0.323794 0.362803 - - - - - 1.0 1.0 1.0 1.0 1.0 1.0 1.0 - - - - - - 1.30457000E-01 4.17920000E-02 8.51050000E-06 5.13290000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 3.28428000E-01 1.64360000E-03 2.20170000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 4.58371000E-01 2.53310000E-03 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 4.63709000E-01 5.47660000E-03 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 1.76190000E-04 2.82313000E-01 8.72890000E-03 9.00160000E-09 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2.27600000E-03 2.49751000E-01 1.31140000E-02 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 8.86450000E-03 2.59529000E-01 - - - - 0.1813232156329 0.3343683022017 0.4937851 0.5912156 0.47419809900160004 0.833601 0.8536035 - - - - - - - MOX3 - MOX3 - 2.53E-8 - 0 - true - - - - 9.48620000E-03 4.65560000E-03 3.62400000E-02 1.32720000E-01 2.08400000E-01 6.58700000E-01 6.90170000E-01 - - - - 1.48071013E-02 1.03705874E-02 8.53956516E-06 2.96212546E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 2.78640474E-03 1.95154023E-03 1.60697792E-06 5.57413653E-10 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 1.73304404E-02 1.21378819E-02 9.99482763E-06 3.46691346E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 6.59928975E-02 4.62200600E-02 3.80594850E-05 1.32017225E-08 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 3.25131926E-02 2.27715674E-02 1.87510386E-05 6.50418701E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 6.32002662E-01 4.42641588E-01 3.64489161E-04 1.26430632E-07 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 7.28595687E-01 5.10293344E-01 4.20196380E-04 1.45753838E-07 0.00000000E+00 0.00000000E+00 0.00000000E+00 - - - - 8.67209000E-03 1.62426000E-03 1.02716000E-02 3.90447000E-02 1.92576000E-02 3.74888000E-01 4.30599000E-01 - - - - - 1.0 1.0 1.0 1.0 1.0 1.0 1.0 - - - - - - 1.31504000E-01 4.20460000E-02 8.69720000E-06 5.19380000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 3.30403000E-01 1.64630000E-03 2.60060000E-09 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 4.61792000E-01 2.47490000E-03 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 4.68021000E-01 5.43300000E-03 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 1.85970000E-04 2.85771000E-01 8.39730000E-03 8.92800000E-09 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2.39160000E-03 2.47614000E-01 1.23220000E-02 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 8.96810000E-03 2.56093000E-01 - - - - 1.83044902E-01 3.36704903E-01 5.00506900E-01 6.06174000E-01 5.02754279E-01 9.21027600E-01 9.55231100E-01 - - - - - - - FC - FC - 2.53E-8 - 0 - true - - - - 5.1132E-04 7.5813E-05 3.1643E-04 1.1675E-03 3.3977E-03 9.1886E-03 2.3244E-02 - - - - 1.323401E-08 1.434500E-08 1.128599E-06 1.276299E-05 3.538502E-07 1.740099E-06 5.063302E-06 - - - - 5.8791E-01 4.1176E-01 3.3906E-04 1.1761E-07 0.0000E+00 0.0000E+00 0.0000E+00 - - - - 4.79002E-09 5.82564E-09 4.63719E-07 5.24406E-06 1.45390E-07 7.14972E-07 2.08041E-06 - - - - - 1.0 1.0 1.0 1.0 1.0 1.0 1.0 - - - - - - 6.61659000E-02 5.90700000E-02 2.83340000E-04 1.46220000E-06 2.06420000E-08 0.00000000E00 0.00000000E00 - 0.00000000E00 2.40377000E-01 5.24350000E-02 2.49900000E-04 1.92390000E-05 2.98750000E-06 4.21400000E-07 - 0.00000000E00 0.00000000E00 1.83425000E-01 9.22880000E-02 6.93650000E-03 1.07900000E-03 2.05430000E-04 - 0.00000000E00 0.00000000E00 0.00000000E00 7.90769000E-02 1.69990000E-01 2.58600000E-02 4.92560000E-03 - 0.00000000E00 0.00000000E00 0.00000000E00 3.73400000E-05 9.97570000E-02 2.06790000E-01 2.44780000E-02 - 0.00000000E00 0.00000000E00 0.00000000E00 0.00000000E00 9.17420000E-04 3.16774000E-01 2.38760000E-01 - 0.00000000E00 0.00000000E00 0.00000000E00 0.00000000E00 0.00000000E00 4.97930000E-02 1.09910000E00 - - - - 1.26032048E-01 2.93160367E-01 2.84250824E-01 2.81025244E-01 3.34460185E-01 5.65640735E-01 1.17213908E00 - - - - - - - GT - GT - 2.53E-8 - 0 - false - - - - 5.11320000E-04 7.58010000E-05 3.15720000E-04 1.15820000E-03 3.39750000E-03 9.18780000E-03 2.32420000E-02 - - - - - - 6.61659000E-02 5.90700000E-02 2.83340000E-04 1.46220000E-06 2.06420000E-08 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 2.40377000E-01 5.24350000E-02 2.49900000E-04 1.92390000E-05 2.98750000E-06 4.21400000E-07 - 0.00000000E+00 0.00000000E+00 1.83297000E-01 9.23970000E-02 6.94460000E-03 1.08030000E-03 2.05670000E-04 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 7.88511000E-02 1.70140000E-01 2.58810000E-02 4.92970000E-03 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 3.73330000E-05 9.97372000E-02 2.06790000E-01 2.44780000E-02 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 9.17260000E-04 3.16765000E-01 2.38770000E-01 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4.97920000E-02 1.09912000E+00 - - - - 1.26032043E-01 2.93160349E-01 2.84240290E-01 2.80960000E-01 3.34440033E-01 5.65640060E-01 1.17215400E+00 - - - - - - LWTR - LWTR - 2.53E-8 - 0 - false - - - - 6.0105E-04 1.5793E-05 3.3716E-04 1.9406E-03 5.7416E-03 1.5001E-02 3.7239E-02 - - - - - - 0.0444777 0.1134000 0.0007235 0.0000037 0.0000001 0.0000000 0.0000000 - 0.0000000 0.2823340 0.1299400 0.0006234 0.0000480 0.0000074 0.0000010 - 0.0000000 0.0000000 0.3452560 0.2245700 0.0169990 0.0026443 0.0005034 - 0.0000000 0.0000000 0.0000000 0.0910284 0.4155100 0.0637320 0.0121390 - 0.0000000 0.0000000 0.0000000 0.0000714 0.1391380 0.5118200 0.0612290 - 0.0000000 0.0000000 0.0000000 0.0000000 0.0022157 0.6999130 0.5373200 - 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.1324400 2.4807000 - - - - 0.15920605 0.41296959299999997 0.59030986 0.5843499999999999 0.7180000000000001 1.2544497000000001 2.650379 - - - - - - - CR - CR - 2.53E-8 - 0 - false - - - - 1.70490000E-03 8.36224000E-03 8.37901000E-02 3.97797000E-01 6.98763000E-01 9.29508000E-01 1.17836000E+00 - - - - - - 1.70563000E-01 4.44012000E-02 9.83670000E-05 1.27786000E-07 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 4.71050000E-01 6.85480000E-04 3.91395000E-10 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 8.01859000E-01 7.20132000E-04 0.00000000E+00 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 5.70752000E-01 1.46015000E-03 0.00000000E+00 0.00000000E+00 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 6.55562000E-05 2.07838000E-01 3.81486000E-03 3.69760000E-09 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 1.02427000E-03 2.02465000E-01 4.75290000E-03 - 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 3.53043000E-03 6.58597000E-01 - - - - 2.16767595E-01 4.80097720E-01 8.86369232E-01 9.70009150E-01 9.10481420E-01 1.13775017E+00 1.84048743E+00 - - - diff --git a/examples/xml/pincell_multigroup/mgxs.h5 b/examples/xml/pincell_multigroup/mgxs.h5 new file mode 100644 index 0000000000..fe93c44bfa Binary files /dev/null and b/examples/xml/pincell_multigroup/mgxs.h5 differ diff --git a/examples/xml/pincell_multigroup/settings.xml b/examples/xml/pincell_multigroup/settings.xml index dfd2fac813..ab716d9e47 100644 --- a/examples/xml/pincell_multigroup/settings.xml +++ b/examples/xml/pincell_multigroup/settings.xml @@ -28,13 +28,12 @@ - true true true false - ./mg_cross_sections.xml + ./mgxs.h5 diff --git a/openmc/mesh.py b/openmc/mesh.py index 730e54547e..d626d728a2 100644 --- a/openmc/mesh.py +++ b/openmc/mesh.py @@ -284,10 +284,8 @@ class Mesh(object): openmc.XPlane(x0=self.upper_right[0], boundary_type=bc[1])] if len(self.dimension) == 1: - yplanes = [openmc.YPlane(y0=np.finfo(np.float).min, - boundary_type='reflective'), - openmc.YPlane(y0=np.finfo(np.float).max, - boundary_type='reflective')] + yplanes = [openmc.YPlane(y0=-1e10, boundary_type='reflective'), + openmc.YPlane(y0=1e10, boundary_type='reflective')] else: yplanes = [openmc.YPlane(y0=self.lower_left[1], boundary_type=bc[2]), @@ -295,10 +293,15 @@ class Mesh(object): boundary_type=bc[3])] if len(self.dimension) <= 2: - zplanes = [openmc.ZPlane(z0=np.finfo(np.float).min, - boundary_type='reflective'), - openmc.ZPlane(z0=np.finfo(np.float).max, - boundary_type='reflective')] + # 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 +/-1e10 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=-1e10, boundary_type='reflective'), + openmc.ZPlane(z0=1e10, boundary_type='reflective')] else: zplanes = [openmc.ZPlane(z0=self.lower_left[2], boundary_type=bc[4]), diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index ca1bd1b3ee..a8f54d16c0 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -819,11 +819,13 @@ class Library(object): return pickle.load(open(full_filename, 'rb')) def get_xsdata(self, domain, xsdata_name, nuclide='total', xs_type='macro', - order=None, tabular_legendre=None, tabular_points=33, - subdomain=None): + order=None, subdomain=None): """Generates an openmc.XSdata object describing a multi-group cross section - data set for eventual combination in to an openmc.MGXSLibrary object - (i.e., the library). + dataset for writing to an openmc.MGXSLibrary object. + + Note that this method does not build an XSdata + object with nested temperature tables. The temperature of each + XSdata object will be left at the default value of 300K. Parameters ---------- @@ -842,18 +844,6 @@ class Library(object): Scattering order for this data entry. Default is None, which will set the XSdata object to use the order of the Library. - tabular_legendre : None or bool - Flag to denote whether or not the Legendre expansion of the - scattering angular distribution is to be converted to a tabular - representation by OpenMC. A value of `True` means that it is to be - converted while a value of `False` means that it will not be. - Defaults to `None` which leaves the default behavior of OpenMC in - place (the distribution is converted to a tabular representation). - tabular_points : int - This parameter is not used unless the ``tabular_legendre`` - parameter is set to `True`. In this case, this parameter sets the - number of equally-spaced points in the domain of [-1,1] to be used - in building the tabular distribution. Default is `33`. subdomain : iterable of int This parameter is not used unless using a mesh domain. In that case, the subdomain is an [i,j,k] index (1-based indexing) of the @@ -864,7 +854,7 @@ class Library(object): Returns ------- xsdata : openmc.XSdata - Multi-Group Cross Section data set object. + Multi-Group Cross Section dataset object. Raises ------ @@ -887,10 +877,6 @@ class Library(object): if order is not None: cv.check_greater_than('order', order, 0, equality=True) cv.check_less_than('order', order, 10, equality=True) - cv.check_type('tabular_legendre', tabular_legendre, - (type(None), bool)) - if tabular_points is not None: - cv.check_greater_than('tabular_points', tabular_points, 1) if subdomain is not None: cv.check_iterable_type('subdomain', subdomain, Integral, max_depth=3) @@ -907,7 +893,7 @@ class Library(object): # Build & add metadata to XSdata object name = xsdata_name - if nuclide is not 'total': + if nuclide != 'total': name += '_' + nuclide xsdata = openmc.XSdata(name, self.energy_groups) @@ -919,14 +905,12 @@ class Library(object): # the provided order or the Library's order. xsdata.order = min(order, self.legendre_order) - # Set the tabular_legendre option if needed - if tabular_legendre is not None: - xsdata.tabular_legendre = {'enable': tabular_legendre, - 'num_points': tabular_points} + # Right now only 'legendre' data and isotropic weighting is supported + self.scatter_format = 'legendre' + self.representation = 'isotropic' - if nuclide is not 'total': - xsdata.zaid = self._nuclides[nuclide][0] - xsdata.awr = self._nuclides[nuclide][1] + if nuclide != 'total': + xsdata.atomic_weight_ratio = self._nuclides[nuclide][1] if subdomain is None: subdomain = 'all' @@ -937,7 +921,7 @@ class Library(object): if 'nu-transport' in self.mgxs_types and self.correction == 'P0': mymgxs = self.get_mgxs(domain, 'nu-transport') xsdata.set_total_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], - subdomains=subdomain) + subdomain=subdomain) elif 'total' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'total') xsdata.set_total_mgxs(mymgxs, xs_type=xs_type, nuclide=[nuclide], @@ -976,49 +960,55 @@ class Library(object): # If multiplicity matrix is available, prefer that if 'multiplicity matrix' in self.mgxs_types: mymgxs = self.get_mgxs(domain, 'multiplicity matrix') - xsdata.set_multiplicity_mgxs(mymgxs, xs_type=xs_type, - nuclide=[nuclide], - subdomain=subdomain) + xsdata.set_multiplicity_matrix_mgxs(mymgxs, xs_type=xs_type, + nuclide=[nuclide], + subdomain=subdomain) using_multiplicity = True # multiplicity will fall back to using scatter and nu-scatter elif ((('scatter matrix' in self.mgxs_types) and ('nu-scatter matrix' in self.mgxs_types))): scatt_mgxs = self.get_mgxs(domain, 'scatter matrix') nuscatt_mgxs = self.get_mgxs(domain, 'nu-scatter matrix') - xsdata.set_multiplicity_mgxs(nuscatt_mgxs, scatt_mgxs, - xs_type=xs_type, nuclide=[nuclide], - subdomain=subdomain) + xsdata.set_multiplicity_matrix_mgxs(nuscatt_mgxs, scatt_mgxs, + xs_type=xs_type, + nuclide=[nuclide], + subdomain=subdomain) using_multiplicity = True else: using_multiplicity = False if using_multiplicity: nuscatt_mgxs = self.get_mgxs(domain, 'nu-scatter matrix') - xsdata.set_scatter_mgxs(nuscatt_mgxs, xs_type=xs_type, - nuclide=[nuclide], subdomain=subdomain) + xsdata.set_scatter_matrix_mgxs(nuscatt_mgxs, xs_type=xs_type, + nuclide=[nuclide], + subdomain=subdomain) else: if 'nu-scatter matrix' in self.mgxs_types: nuscatt_mgxs = self.get_mgxs(domain, 'nu-scatter matrix') - xsdata.set_scatter_mgxs(nuscatt_mgxs, xs_type=xs_type, - nuclide=[nuclide], - subdomain=subdomain) + xsdata.set_scatter_matrix_mgxs(nuscatt_mgxs, xs_type=xs_type, + nuclide=[nuclide], + subdomain=subdomain) # Since we are not using multiplicity, then # scattering multiplication (nu-scatter) must be # accounted for approximately by using an adjusted # absorption cross section. - if 'total' in self.mgxs_types: - xsdata.absorption = \ - np.subtract(xsdata.total, - np.sum(xsdata.scatter[0, :, :], axis=1)) + if 'total' in self.mgxs_types or 'transport' in self.mgxs_types: + for i in range(len(xsdata.temperatures)): + xsdata._absorption[i] = \ + np.subtract(xsdata._total[i], np.sum( + xsdata._scatter_matrix[i][0, :, :], axis=1)) return xsdata - def create_mg_library(self, xs_type='macro', xsdata_names=None, - tabular_legendre=None, tabular_points=33): + def create_mg_library(self, xs_type='macro', xsdata_names=None): """Creates an openmc.MGXSLibrary object to contain the MGXS data for the Multi-Group mode of OpenMC. + Note that this library will not make use of nested temperature tables. + Every dataset in the library will be treated as if it was at the same + default temperature. + Parameters ---------- xs_type: {'macro', 'micro'} @@ -1028,18 +1018,6 @@ class Library(object): xsdata_names : Iterable of str List of names to apply to the "xsdata" entries in the resultant mgxs data file. Defaults to 'set1', 'set2', ... - tabular_legendre : None or bool - Flag to denote whether or not the Legendre expansion of the - scattering angular distribution is to be converted to a tabular - representation by OpenMC. A value of `True` means that it is to be - converted while a value of `False` means that it will not be. - Defaults to `None` which leaves the default behavior of OpenMC in - place (the distribution is converted to a tabular representation). - tabular_points : int - This parameter is not used unless the ``tabular_legendre`` - parameter is set to `True`. In this case, this parameter sets the - number of equally-spaced points in the domain of [-1,1] to be used - in building the tabular distribution. Default is `33`. Returns ------- @@ -1091,8 +1069,6 @@ class Library(object): # Create XSdata and Macroscopic for this domain xsdata = self.get_xsdata(domain, xsdata_name, - tabular_legendre=tabular_legendre, - tabular_points=tabular_points, subdomain=subdomain) mgxs_file.add_xsdata(xsdata) i += 1 @@ -1110,45 +1086,34 @@ class Library(object): xsdata_name = 'set' + str(i + 1) else: xsdata_name = xsdata_names[i] - if nuclide is not 'total': + if nuclide != 'total': xsdata_name += '_' + nuclide xsdata = self.get_xsdata(domain, xsdata_name, - nuclide=nuclide, xs_type=xs_type, - tabular_legendre=tabular_legendre, - tabular_points=tabular_points) + nuclide=nuclide, xs_type=xs_type) mgxs_file.add_xsdata(xsdata) return mgxs_file - def create_mg_mode(self, xsdata_names=None, tabular_legendre=None, - tabular_points=33, bc=['reflective'] * 6): + def create_mg_mode(self, xsdata_names=None, bc=['reflective'] * 6): """Creates an openmc.MGXSLibrary object to contain the MGXS data for the Multi-Group mode of OpenMC as well as the associated openmc.Materials - and openmc.Geometry objects. The created Geometry is the same as that - used to generate the MGXS data, with the only differences being - modifications to point to newly-created Materials which point to the - multi-group data. This method only creates a macroscopic - MGXS Library even if nuclidic tallies are specified in the Library. + and openmc.Geometry objects. + + The created Geometry is the same as that used to generate the MGXS + data, with the only differences being modifications to point to + newly-created Materials which point to the multi-group data. This + method only creates a macroscopic MGXS Library even if nuclidic tallies + are specified in the Library. Note that this library will not make + use of nested temperature tables. Every dataset in the library will + be treated as if it was at the same default temperature. Parameters ---------- xsdata_names : Iterable of str List of names to apply to the "xsdata" entries in the resultant mgxs data file. Defaults to 'set1', 'set2', ... - tabular_legendre : None or bool - Flag to denote whether or not the Legendre expansion of the - scattering angular distribution is to be converted to a tabular - representation by OpenMC. A value of `True` means that it is to be - converted while a value of `False` means that it will not be. - Defaults to `None` which leaves the default behavior of OpenMC in - place (the distribution is converted to a tabular representation). - tabular_points : int - This parameter is not used unless the ``tabular_legendre`` - parameter is set to `True`. In this case, this parameter sets the - number of equally-spaced points in the domain of [-1,1] to be used - in building the tabular distribution. Default is `33`. bc : iterable of {'reflective', 'periodic', 'transmission', or 'vacuum'} Boundary conditions for each of the four faces of a rectangle (if applying to a 2D mesh) or six faces of a parallelepiped @@ -1195,8 +1160,7 @@ class Library(object): cv.check_length("domains", self.domains, 1, 1) # Get the MGXS File Data - mgxs_file = self.create_mg_library('macro', xsdata_names, - tabular_legendre, tabular_points) + mgxs_file = self.create_mg_library('macro', xsdata_names) # Now move on the creating the geometry and assigning materials if self.domain_type == 'mesh': diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index 8394d9cc0b..2a8b0f6b76 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -1,81 +1,21 @@ from collections import Iterable from numbers import Real, Integral -from xml.etree import ElementTree as ET import sys from six import string_types import numpy as np +import h5py import openmc import openmc.mgxs from openmc.checkvalue import check_type, check_value, check_greater_than, \ check_iterable_type -from openmc.clean_xml import sort_xml_elements, clean_xml_indentation # Supported incoming particle MGXS angular treatment representations _REPRESENTATIONS = ['isotropic', 'angle'] - - -def ndarray_to_string(arr): - """Converts a numpy ndarray in to a join with spaces between entries - similar to ' '.join(map(str,arr)) but applied to all sub-dimensions. - - Parameters - ---------- - arr : numpy.ndarray - Array to combine in to a string - - Returns - ------- - text : str - String representation of array in arr - - """ - - shape = arr.shape - ndim = arr.ndim - tab = ' ' - indent = '\n' + tab + tab - text = indent - - if ndim == 1: - text += tab - for i in range(shape[0]): - text += '{:.7E} '.format(arr[i]) - text += indent - elif ndim == 2: - for i in range(shape[0]): - text += tab - for j in range(shape[1]): - text += '{:.7E} '.format(arr[i, j]) - text += indent - elif ndim == 3: - for i in range(shape[0]): - for j in range(shape[1]): - text += tab - for k in range(shape[2]): - text += '{:.7E} '.format(arr[i, j, k]) - text += indent - elif ndim == 4: - for i in range(shape[0]): - for j in range(shape[1]): - for k in range(shape[2]): - text += tab - for l in range(shape[3]): - text += '{:.7E} '.format(arr[i, j, k, l]) - text += indent - elif ndim == 5: - for i in range(shape[0]): - for j in range(shape[1]): - for k in range(shape[2]): - for l in range(shape[3]): - text += tab - for m in range(shape[4]): - text += '{:.7E} '.format(arr[i, j, k, l, m]) - text += indent - - return text +_SCATTER_TYPES = ['tabular', 'legendre', 'histogram'] +_SCATTER_SHAPES = ["[Order][G][G']"] class XSdata(object): @@ -84,162 +24,140 @@ class XSdata(object): Parameters ---------- - name : str, optional + name : str Name of the mgxs data set. energy_groups : openmc.mgxs.EnergyGroups - Energygroup structure + Energy group structure representation : {'isotropic', 'angle'}, optional Method used in generating the MGXS (isotropic or angle-dependent flux weighting). Defaults to 'isotropic' + temperatures : Iterable of float + Temperatures (in units of Kelvin) of the provided datasets. Defaults + to a single temperature at 294K. Attributes ---------- name : str Unique identifier for the xsdata object - alias : str - Separate unique identifier for the xsdata object - awr : float + aromic_weight_ratio : float Atomic weight ratio of an isotope. That is, the ratio of the mass of the isotope to the mass of a single neutron. - kT : float - Temperature (in units of MeV). + temperatures : numpy.ndarray + Temperatures (in units of Kelvin) of the provided datasets. Defaults + to a single temperature at 294K. energy_groups : openmc.mgxs.EnergyGroups Energy group structure fissionable : bool Whether or not this is a fissionable data set. - scatt_type : {'legendre', 'histogram', or 'tabular'} + scatter_format : {'legendre', 'histogram', or 'tabular'} Angular distribution representation (legendre, histogram, or tabular) + scatter_shapes : {"[Order][G][G']"} + Dimensionality of the scattering and multiplicity matrices order : int Either the Legendre order, number of bins, or number of points used to describe the angular distribution associated with each group-to-group transfer probability. - tabular_legendre : dict - Set how to treat the Legendre scattering kernel (tabular or leave in - Legendre polynomial form). Dict contains two keys: 'enable' and - 'num_points'. 'enable' is a boolean and 'num_points' is the - number of points to use, if 'enable' is True. representation : {'isotropic', 'angle'} Method used in generating the MGXS (isotropic or angle-dependent flux weighting). num_azimuthal : int Number of equal width angular bins that the azimuthal angular domain is - subdivided into. This only applies when ``representation`` is "angle". + subdivided into. This only applies when :attr:`XSdata.representation` + is "angle". num_polar : int Number of equal width angular bins that the polar angular domain is - subdivided into. This only applies when ``representation`` is "angle". + subdivided into. This only applies when :attr:`XSdata.representation` + is "angle". use_chi : bool Whether or not a chi vector or nu-fission matrix was used. vector_shape : iterable of int Dimensionality of vector multi-group cross sections (e.g., the total cross section). The return result depends on the value of - ``representation``. + :attr:`XSdata.representation`. matrix_shape : iterable of int Dimensionality of matrix multi-group cross sections (e.g., the fission matrix cross section). The return result depends on the - value of ``representation``. + value of :attr:`XSdata.representation`. pn_matrix_shape : iterable of int Dimensionality of scattering matrix data (e.g., the scattering matrix cross section). The return result depends on the - value of ``representation``. - total : numpy.ndarray - Group-wise total cross section ordered by increasing group index (i.e., - fast to thermal). If ``representation`` is "isotropic", then the length - of this list should equal the number of groups described in the - ``groups`` element. If ``representation`` is "angle", then the length - of this list should equal the number of groups times the number of - azimuthal angles times the number of polar angles, with the - inner-dimension being groups, intermediate-dimension being azimuthal - angles and outer-dimension being the polar angles. - absorption : numpy.ndarray - Group-wise absorption cross section ordered by increasing group index - (i.e., fast to thermal). If ``representation`` is "isotropic", then the - length of this list should equal the number of groups described in the - ``groups`` attribute. If ``representation`` is "angle", then the length - of this list should equal the number of groups times the number of - azimuthal angles times the number of polar angles, with the - inner-dimension being groups, intermediate-dimension being azimuthal - angles and outer-dimension being the polar angles. - scatter : numpy.ndarray + value of :attr:`XSdata.representation`. + total : dict of numpy.ndarray + Group-wise total cross section. + absorption : dict of numpy.ndarray + Group-wise absorption cross section. + scatter_matrix : dict of numpy.ndarray Scattering moment matrices presented with the columns representing incoming group and rows representing the outgoing group. That is, - down-scatter will be above the diagonal of the resultant matrix. This - matrix is repeated for every Legendre order (in order of increasing - orders) if ``scatt_type`` is "legendre"; otherwise, this matrix is - repeated for every bin of the histogram or tabular representation. - Finally, if ``representation`` is "angle", the above is repeated for - every azimuthal angle and every polar angle, in that order. - multiplicity : numpy.ndarray + down-scatter will be above the diagonal of the resultant matrix. + multiplicity_matrix : dict of numpy.ndarray Ratio of neutrons produced in scattering collisions to the neutrons which undergo scattering collisions; that is, the multiplicity provides the code with a scaling factor to account for neutrons produced in - (n,xn) reactions. This information is assumed isotropic and therefore - does not need to be repeated for every Legendre moment or - histogram/tabular bin. This matrix follows the same arrangement as - described for the ``scatter`` attribute, with the exception of the data - needed to provide the scattering type information. - fission : numpy.ndarray - Group-wise fission cross section ordered by increasing group index - (i.e., fast to thermal). If ``representation`` is "isotropic", then the - length of this list should equal the number of groups described in the - ``groups`` attribute. If ``representation`` is "angle", then the length - of this list should equal the number of groups times the number of - azimuthal angles times the number of polar angles, with the - inner-dimension being groups, intermediate-dimension being azimuthal - angles and outer-dimension being the polar angles. - kappa_fission : numpy.ndarray - Group-wise kappa-fission cross section ordered by increasing group - index (i.e., fast to thermal). If ``representation`` is "isotropic", - then the length of this list should equal the number of groups in the - ``groups`` attribute. If ``representation`` is "angle", then the length - of this list should equal the number of groups times the number of - azimuthal angles times the number of polar angles, with the - inner-dimension being groups, intermediate-dimension being azimuthal - angles and outer-dimension being the polar angles. - chi : numpy.ndarray + (n,xn) reactions. + fission : dict of numpy.ndarray + Group-wise fission cross section. + kappa_fission : dict of numpy.ndarray + Group-wise kappa-fission cross section. + chi : dict of numpy.ndarray Group-wise fission spectra ordered by increasing group index (i.e., - fast to thermal). This attribute should be used if making the common + fast to thermal). This attribute should be used if making the common approximation that the fission spectra does not depend on incoming - energy. If the user does not wish to make this approximation, then + energy. If the user does not wish to make this approximation, then this should not be provided and this information included in the - ``nu_fission`` element instead. If ``representation`` is "isotropic", - then the length of this list should equal the number of groups - in the ``groups`` element. If ``representation`` is "angle", then the - length of this list should equal the number of groups times the number - of azimuthal angles times the number of polar angles, with the - inner-dimension being groups, intermediate-dimension being azimuthal - angles and outer-dimension being the polar angles. - nu_fission : numpy.ndarray - Group-wise fission production cross section vector (i.e., if ``chi`` is - provided), or is the group-wise fission production matrix. If providing - the vector, it should be ordered the same as the ``fission`` data. If - providing the matrix, it should be ordered the same as the - ``multiplicity`` matrix. + :attr:`XSdata.nu_fission` attribute instead. + nu_fission : dict of numpy.ndarray + Group-wise fission production cross section vector (i.e., if + :attr:`XSdata.chi` is provided), or is the group-wise fission + production matrix. + inverse_velocities : dict of numpy.ndarray + Inverse of velocities, in units of sec/cm. + + Notes + ----- + The parameters containing cross section data have dimensionalities which + depend upon the value of :attr:`XSdata.representation` as well as the + number of Legendre or other angular dimensions as described by + :attr:`XSdata.order`. The :attr:`XSdata.vector_shape`, + :attr:`XSdata.matrix_shape`, and :attr:`XSdata.pn_matrix_shape` properties + are provided to obtain the dimensionality of the data for each temperature. + + The following are cross sections which should use each of these properties: + + vector_shape : + total, absorption, fission, kappa_fission, chi, nu_fission (if chi is + provided), inverse_velocities + matrix_shape : + multiplicity_matrix, nu_fission (if chi is not provided) + pn_matrix_shape : + scatter_matrix """ - def __init__(self, name, energy_groups, representation='isotropic'): + def __init__(self, name, energy_groups, temperatures=[294.], + representation='isotropic'): # Initialize class attributes - self._name = name - self._energy_groups = energy_groups - self._representation = representation - self._alias = None - self._awr = None - self._kT = None + self.name = name + self.energy_groups = energy_groups + self.temperatures = temperatures + self.representation = representation + self._atomic_weight_ratio = None self._fissionable = False - self._scatt_type = 'legendre' + self._scatter_format = 'legendre' + self._scatter_shape = "[Order][G][G']" self._order = None - self._tabular_legendre = None self._num_polar = None self._num_azimuthal = None - self._total = None - self._absorption = None - self._scatter = None - self._multiplicity = None - self._fission = None - self._nu_fission = None - self._kappa_fission = None - self._chi = None self._use_chi = None + self._total = len(temperatures) * [None] + self._absorption = len(temperatures) * [None] + self._scatter_matrix = len(temperatures) * [None] + self._multiplicity_matrix = len(temperatures) * [None] + self._fission = len(temperatures) * [None] + self._nu_fission = len(temperatures) * [None] + self._kappa_fission = len(temperatures) * [None] + self._chi = len(temperatures) * [None] + self._inverse_velocities = len(temperatures) * [None] @property def name(self): @@ -254,29 +172,29 @@ class XSdata(object): return self._representation @property - def alias(self): - return self._alias + def atomic_weight_ratio(self): + return self._atomic_weight_ratio @property - def awr(self): - return self._awr + def fissionable(self): + return self._fissionable @property - def kT(self): - return self._kT + def temperatures(self): + return self._temperatures @property - def scatt_type(self): - return self._scatt_type + def scatter_format(self): + return self._scatter_format + + @property + def scatter_shape(self): + return self._scatter_shape @property def order(self): return self._order - @property - def tabular_legendre(self): - return self._tabular_legendre - @property def num_polar(self): return self._num_polar @@ -298,12 +216,12 @@ class XSdata(object): return self._absorption @property - def scatter(self): - return self._scatter + def scatter_matrix(self): + return self._scatter_matrix @property - def multiplicity(self): - return self._multiplicity + def multiplicity_matrix(self): + return self._multiplicity_matrix @property def fission(self): @@ -323,36 +241,36 @@ class XSdata(object): @property def num_orders(self): - if (self._order is not None) and (self._scatt_type is not None): - if self._scatt_type is 'legendre': + if self._order is not None: + if self._scatter_format in (None, 'legendre'): return self._order + 1 else: return self._order @property def vector_shape(self): - if self.representation is 'isotropic': + if self.representation == 'isotropic': return (self.energy_groups.num_groups,) - elif self.representation is 'angle': + elif self.representation == 'angle': return (self.num_polar, self.num_azimuthal, self.energy_groups.num_groups) @property def matrix_shape(self): - if self.representation is 'isotropic': + if self.representation == 'isotropic': return (self.energy_groups.num_groups, self.energy_groups.num_groups) - elif self.representation is 'angle': + elif self.representation == 'angle': return (self.num_polar, self.num_azimuthal, self.energy_groups.num_groups, self.energy_groups.num_groups) @property def pn_matrix_shape(self): - if self.representation is 'isotropic': + if self.representation == 'isotropic': return (self.num_orders, self.energy_groups.num_groups, self.energy_groups.num_groups) - elif self.representation is 'angle': + elif self.representation == 'angle': return (self.num_polar, self.num_azimuthal, self.num_orders, self.energy_groups.num_groups, self.energy_groups.num_groups) @@ -379,34 +297,30 @@ class XSdata(object): check_value('representation', representation, _REPRESENTATIONS) self._representation = representation - @alias.setter - def alias(self, alias): - if alias is not None: - check_type('alias', alias, string_types) - self._alias = alias - else: - self._alias = self._name + @atomic_weight_ratio.setter + def atomic_weight_ratio(self, atomic_weight_ratio): + # Check validity of type and that the atomic_weight_ratio value is > 0 + check_type('atomic_weight_ratio', atomic_weight_ratio, Real) + check_greater_than('atomic_weight_ratio', atomic_weight_ratio, 0.0) + self._atomic_weight_ratio = atomic_weight_ratio - @awr.setter - def awr(self, awr): - # Check validity of type and that the awr value is > 0 - check_type('awr', awr, Real) - check_greater_than('awr', awr, 0.0) - self._awr = awr + @temperatures.setter + def temperatures(self, temperatures): + check_iterable_type('temperatures', temperatures, Real) - @kT.setter - def kT(self, kT): - # Check validity of type and that the kT value is >= 0 - check_type('kT', kT, Real) - check_greater_than('kT', kT, 0.0, equality=True) - self._kT = kT + self._temperatures = np.array(temperatures) - @scatt_type.setter - def scatt_type(self, scatt_type): + @scatter_format.setter + def scatter_format(self, scatter_format): # check to see it is of a valid type and value - check_value('scatt_type', scatt_type, ['legendre', 'histogram', - 'tabular']) - self._scatt_type = scatt_type + check_value('scatter_format', scatter_format, _SCATTER_TYPES) + self._scatter_format = scatter_format + + @scatter_shape.setter + def scatter_shape(self, scatter_shape): + # check to see it is of a valid type and value + check_value('scatter_shape', scatter_shape, _SCATTER_SHAPES) + self._scatter_shape = scatter_shape @order.setter def order(self, order): @@ -415,39 +329,16 @@ class XSdata(object): check_greater_than('order', order, 0, equality=True) self._order = order - @tabular_legendre.setter - def tabular_legendre(self, tabular_legendre): - # Check to make sure this is a dict and it has our keys with the - # right values. - check_type('tabular_legendre', tabular_legendre, dict) - if 'enable' in tabular_legendre: - enable = tabular_legendre['enable'] - check_type('enable', enable, bool) - else: - msg = 'The tabular_legendre dict must include a value keyed by ' \ - '"enable"' - raise ValueError(msg) - if 'num_points' in tabular_legendre: - num_points = tabular_legendre['num_points'] - check_type('num_points', num_points, Integral) - check_greater_than('num_points', num_points, 0) - else: - if not enable: - num_points = 1 - else: - num_points = 33 - self._tabular_legendre = {'enable': enable, 'num_points': num_points} - @num_polar.setter def num_polar(self, num_polar): # Make sure we have positive ints - check_value('num_polar', num_polar, Integral) + check_type('num_polar', num_polar, Integral) check_greater_than('num_polar', num_polar, 0) self._num_polar = num_polar @num_azimuthal.setter def num_azimuthal(self, num_azimuthal): - check_value('num_azimuthal', num_azimuthal, Integral) + check_type('num_azimuthal', num_azimuthal, Integral) check_greater_than('num_azimuthal', num_azimuthal, 0) self._num_azimuthal = num_azimuthal @@ -456,102 +347,261 @@ class XSdata(object): check_type('use_chi', use_chi, bool) self._use_chi = use_chi - @total.setter - def total(self, total): + def add_temperature(self, temperature): + """This method re-sizes the attributes of this XSdata object so that it + can accomodate an additional temperature. Note that the set_* methods + will still need to be executed. + + Parameters + ---------- + temperature : float + Temperature (in units of Kelvin) of the provided dataset. + + """ + check_type('temperature', temperature, Real) + + temp_store = self.temperatures.tolist().append(temperature) + self.temperatures = temp_store + + self._total.append(None) + self._absorption.append(None) + self._scatter_matrix.append(None) + self._multiplicity_matrix.append(None) + self._fission.append(None) + self._nu_fission.append(None) + self._kappa_fission.append(None) + self._chi.append(None) + self._inverse_velocities.append(None) + + def set_total(self, total, temperature=294.): + """This method sets the cross section for this XSdata object at the + provided temperature. + + Parameters + ---------- + total: np.ndarray + Total Cross Section + temperature : float + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). + + See also + -------- + openmc.mgxs_library.set_total_mgxs() + + """ check_type('total', total, Iterable, expected_iter_type=Real) - # Convert to a numpy array so we can easily get the shape for - # checking - nptotal = np.asarray(total) - check_value('total shape', nptotal.shape, [self.vector_shape]) + # Convert to a numpy array so we can easily get the shape for checking + total = np.asarray(total) + check_value('total shape', total.shape, [self.vector_shape]) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) - self._total = nptotal + i = np.where(self.temperatures == temperature)[0][0] + self._total[i] = total - @absorption.setter - def absorption(self, absorption): + def set_absorption(self, absorption, temperature=294.): + """This method sets the cross section for this XSdata object at the + provided temperature. + + Parameters + ---------- + absorption: np.ndarray + Absorption Cross Section + temperature : float + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). + + See also + -------- + openmc.mgxs_library.set_absorption_mgxs() + + """ check_type('absorption', absorption, Iterable, expected_iter_type=Real) - # Convert to a numpy array so we can easily get the shape for - # checking - npabsorption = np.asarray(absorption) - check_value('absorption shape', npabsorption.shape, - [self.vector_shape]) + # Convert to a numpy array so we can easily get the shape for checking + absorption = np.asarray(absorption) + check_value('absorption shape', absorption.shape, [self.vector_shape]) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) - self._absorption = npabsorption + i = np.where(self.temperatures == temperature)[0][0] + self._absorption[i] = absorption - @fission.setter - def fission(self, fission): + def set_fission(self, fission, temperature=294.): + """This method sets the cross section for this XSdata object at the + provided temperature. + + Parameters + ---------- + fission: np.ndarray + Fission Cross Section + temperature : float + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). + + See also + -------- + openmc.mgxs_library.set_fission_mgxs() + + """ check_type('fission', fission, Iterable, expected_iter_type=Real) - # Convert to a numpy array so we can easily get the shape for - # checking - npfission = np.asarray(fission) - check_value('fission shape', npfission.shape, [self.vector_shape]) + # Convert to a numpy array so we can easily get the shape for checking + fission = np.asarray(fission) + check_value('fission shape', fission.shape, [self.vector_shape]) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) - self._fission = npfission + i = np.where(self.temperatures == temperature)[0][0] + self._fission[i] = fission - if np.sum(self._fission) > 0.0: + if np.sum(fission) > 0.0: self._fissionable = True - @kappa_fission.setter - def kappa_fission(self, kappa_fission): + def set_kappa_fission(self, kappa_fission, temperature=294.): + """This method sets the cross section for this XSdata object at the + provided temperature. + + Parameters + ---------- + kappa_fission: np.ndarray + Kappa-Fission Cross Section + temperature : float + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). + + See also + -------- + openmc.mgxs_library.set_kappa_fission_mgxs() + + """ check_type('kappa_fission', kappa_fission, Iterable, expected_iter_type=Real) - # Convert to a numpy array so we can easily get the shape for - # checking - npkappa_fission = np.asarray(kappa_fission) - check_value('kappa fission shape', npkappa_fission.shape, + # Convert to a numpy array so we can easily get the shape for checking + kappa_fission = np.asarray(kappa_fission) + check_value('kappa fission shape', kappa_fission.shape, [self.vector_shape]) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) - self._kappa_fission = npkappa_fission + i = np.where(self.temperatures == temperature)[0][0] + self._kappa_fission[i] = kappa_fission - if np.sum(self._kappa_fission) > 0.0: + if np.sum(kappa_fission) > 0.0: self._fissionable = True - @chi.setter - def chi(self, chi): + def set_chi(self, chi, temperature=294.): + """This method sets the cross section for this XSdata object at the + provided temperature. + + Parameters + ---------- + chi: np.ndarray + Fission Spectrum + temperature : float + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). + + See also + -------- + openmc.mgxs_library.set_chi_mgxs() + + """ if self.use_chi is not None: if not self.use_chi: - msg = 'Providing "chi" when "nu-fission" already provided as a' \ - 'matrix' + msg = 'Providing "chi" when "nu-fission" already provided ' \ + 'as a matrix' raise ValueError(msg) check_type('chi', chi, Iterable, expected_iter_type=Real) - # Convert to a numpy array so we can easily get the shape for - # checking - npchi = np.asarray(chi) + # Convert to a numpy array so we can easily get the shape for checking + chi = np.asarray(chi) # Check the shape - if npchi.shape != self.vector_shape: + if chi.shape != self.vector_shape: msg = 'Provided chi iterable does not have the expected shape.' raise ValueError(msg) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) - self._chi = npchi + i = np.where(self.temperatures == temperature)[0][0] + self._chi[i] = chi if self.use_chi is not None: self.use_chi = True - @scatter.setter - def scatter(self, scatter): - # Convert to a numpy array so we can easily get the shape for - # checking - npscatter = np.asarray(scatter) - check_iterable_type('scatter', npscatter, Real, - max_depth=len(npscatter.shape)) - check_value('scatter shape', npscatter.shape, [self.pn_matrix_shape]) + def set_scatter_matrix(self, scatter, temperature=294.): + """This method sets the cross section for this XSdata object at the + provided temperature. - self._scatter = npscatter + Parameters + ---------- + scatter: np.ndarray + Scattering Matrix Cross Section + temperature : float + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). - @multiplicity.setter - def multiplicity(self, multiplicity): - # Convert to a numpy array so we can easily get the shape for - # checking - npmultiplicity = np.asarray(multiplicity) - check_iterable_type('multiplicity', npmultiplicity, Real, - max_depth=len(npmultiplicity.shape)) - check_value('multiplicity shape', npmultiplicity.shape, + See also + -------- + openmc.mgxs_library.set_scatter_matrix_mgxs() + + """ + # Convert to a numpy array so we can easily get the shape for checking + scatter = np.asarray(scatter) + check_iterable_type('scatter', scatter, Real, + max_depth=len(scatter.shape)) + check_value('scatter shape', scatter.shape, [self.pn_matrix_shape]) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) + + i = np.where(self.temperatures == temperature)[0][0] + self._scatter_matrix[i] = scatter + + def set_multiplicity_matrix(self, multiplicity, temperature=294.): + """This method sets the cross section for this XSdata object at the + provided temperature. + + Parameters + ---------- + multiplicity: np.ndarray + Multiplicity Matrix Cross Section + temperature : float + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). + + See also + -------- + openmc.mgxs_library.set_multiplicity_matrix_mgxs() + + """ + # Convert to a numpy array so we can easily get the shape for checking + multiplicity = np.asarray(multiplicity) + check_iterable_type('multiplicity', multiplicity, Real, + max_depth=len(multiplicity.shape)) + check_value('multiplicity shape', multiplicity.shape, [self.matrix_shape]) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) - self._multiplicity = npmultiplicity + i = np.where(self.temperatures == temperature)[0][0] + self._multiplicity_matrix[i] = multiplicity - @nu_fission.setter - def nu_fission(self, nu_fission): + def set_nu_fission(self, nu_fission, temperature=294.): + """This method sets the cross section for this XSdata object at the + provided temperature. + + Parameters + ---------- + nu_fission: np.ndarray + Nu-fission Cross Section + temperature : float + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). + + See also + -------- + openmc.mgxs_library.set_nu_fission_mgxs() + + """ # The NuFissionXS class does not have the capability to produce # a fission matrix and therefore if this path is pursued, we know # chi must be used. @@ -562,33 +612,63 @@ class XSdata(object): # chi already has been set. If not, we just check that this is OK # and set the use_chi flag accordingly - # Convert to a numpy array so we can easily get the shape for - # checking - npnu_fission = np.asarray(nu_fission) + # Convert to a numpy array so we can easily get the shape for checking + nu_fission = np.asarray(nu_fission) - check_iterable_type('nu_fission', npnu_fission, Real, - max_depth=len(npnu_fission.shape)) + check_iterable_type('nu_fission', nu_fission, Real, + max_depth=len(nu_fission.shape)) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) if self.use_chi is not None: if self.use_chi: - check_value('nu_fission shape', npnu_fission.shape, + check_value('nu_fission shape', nu_fission.shape, [self.vector_shape]) else: - check_value('nu_fission shape', npnu_fission.shape, + check_value('nu_fission shape', nu_fission.shape, [self.matrix_shape]) else: - check_value('nu_fission shape', npnu_fission.shape, + check_value('nu_fission shape', nu_fission.shape, [self.vector_shape, self.matrix_shape]) # Find out if we have a nu-fission matrix or vector # and set a flag to allow other methods to check this later. - self.use_chi = (npnu_fission.shape == self.vector_shape) + if nu_fission.shape == self.vector_shape: + self.use_chi = True + else: + self.use_chi = False - self._nu_fission = npnu_fission - if np.sum(self._nu_fission) > 0.0: + i = np.where(self.temperatures == temperature)[0][0] + self._nu_fission[i] = nu_fission + if np.sum(nu_fission) > 0.0: self._fissionable = True - def set_total_mgxs(self, total, nuclide='total', xs_type='macro', - subdomain='all'): + def set_inverse_velocities(self, inv_vel, temperature=294.): + """This method sets the inverse velocities for this XSdata object at the + provided temperature. + + Parameters + ---------- + inv_vel: np.ndarray + Inverse velocities in units of sec/cm. + temperature : float + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). + + """ + check_type('inverse velocities', inv_vel, Iterable, + expected_iter_type=Real) + # Convert to a numpy array so we can easily get the shape for checking + inv_vel = np.asarray(inv_vel) + check_value('inverse velocities shape', inv_vel.shape, + [self.vector_shape]) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) + + i = np.where(self.temperatures == temperature)[0][0] + self._inverse_velocities[i] = inv_vel + + def set_total_mgxs(self, total, temperature=294., nuclide='total', + xs_type='macro', subdomain=None): """This method allows for an openmc.mgxs.TotalXS or openmc.mgxs.TransportXS to be used to set the total cross section for this XSdata object. @@ -598,6 +678,9 @@ class XSdata(object): total: openmc.mgxs.TotalXS or openmc.mgxs.TransportXS MGXS Object containing the total or transport cross section for the domain of interest. + temperature : float + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -620,16 +703,19 @@ class XSdata(object): check_value('energy_groups', total.energy_groups, [self.energy_groups]) check_value('domain_type', total.domain_type, ['universe', 'cell', 'material', 'mesh']) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) - if self.representation is 'isotropic': - self._total = total.get_xs(nuclides=nuclide, xs_type=xs_type, - subdomains=subdomain) - elif self.representation is 'angle': + i = np.where(self.temperatures == temperature)[0][0] + if self.representation == 'isotropic': + self._total[i] = total.get_xs(nuclides=nuclide, xs_type=xs_type, + subdomains=subdomain) + elif self.representation == 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) - def set_absorption_mgxs(self, absorption, nuclide='total', - xs_type='macro', subdomain=None): + def set_absorption_mgxs(self, absorption, temperature=294., + nuclide='total', xs_type='macro', subdomain=None): """This method allows for an openmc.mgxs.AbsorptionXS to be used to set the absorption cross section for this XSdata object. @@ -638,6 +724,9 @@ class XSdata(object): absorption: openmc.mgxs.AbsorptionXS MGXS Object containing the absorption cross section for the domain of interest. + temperature : float + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -660,17 +749,20 @@ class XSdata(object): [self.energy_groups]) check_value('domain_type', absorption.domain_type, ['universe', 'cell', 'material', 'mesh']) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) - if self.representation is 'isotropic': - self._absorption = absorption.get_xs(nuclides=nuclide, - xs_type=xs_type, - subdomains=subdomain) - elif self.representation is 'angle': + i = np.where(self.temperatures == temperature)[0][0] + if self.representation == 'isotropic': + self._absorption[i] = absorption.get_xs(nuclides=nuclide, + xs_type=xs_type, + subdomains=subdomain) + elif self.representation == 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) - def set_fission_mgxs(self, fission, nuclide='total', xs_type='macro', - subdomain=None): + def set_fission_mgxs(self, fission, temperature=294., nuclide='total', + xs_type='macro', subdomain=None): """This method allows for an openmc.mgxs.FissionXS to be used to set the fission cross section for this XSdata object. @@ -679,6 +771,9 @@ class XSdata(object): fission: openmc.mgxs.FissionXS MGXS Object containing the fission cross section for the domain of interest. + temperature : float + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -701,17 +796,20 @@ class XSdata(object): [self.energy_groups]) check_value('domain_type', fission.domain_type, ['universe', 'cell', 'material', 'mesh']) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) - if self.representation is 'isotropic': - self._fission = fission.get_xs(nuclides=nuclide, - xs_type=xs_type, - subdomains=subdomain) - elif self.representation is 'angle': + i = np.where(self.temperatures == temperature)[0][0] + if self.representation == 'isotropic': + self._fission[i] = fission.get_xs(nuclides=nuclide, + xs_type=xs_type, + subdomains=subdomain) + elif self.representation == 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) - def set_nu_fission_mgxs(self, nu_fission, nuclide='total', - xs_type='macro', subdomain=None): + def set_nu_fission_mgxs(self, nu_fission, temperature=294., + nuclide='total', xs_type='macro', subdomain=None): """This method allows for an openmc.mgxs.NuFissionXS to be used to set the nu-fission cross section for this XSdata object. @@ -720,6 +818,9 @@ class XSdata(object): nu_fission: openmc.mgxs.NuFissionXS MGXS Object containing the nu-fission cross section for the domain of interest. + temperature : float + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -743,12 +844,15 @@ class XSdata(object): [self.energy_groups]) check_value('domain_type', nu_fission.domain_type, ['universe', 'cell', 'material', 'mesh']) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) - if self.representation is 'isotropic': - self._nu_fission = nu_fission.get_xs(nuclides=nuclide, - xs_type=xs_type, - subdomains=subdomain) - elif self.representation is 'angle': + i = np.where(self.temperatures == temperature)[0][0] + if self.representation == 'isotropic': + self._nu_fission[i] = nu_fission.get_xs(nuclides=nuclide, + xs_type=xs_type, + subdomains=subdomain) + elif self.representation == 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) @@ -760,8 +864,9 @@ class XSdata(object): if np.sum(self._nu_fission) > 0.0: self._fissionable = True - def set_kappa_fission_mgxs(self, k_fission, nuclide='total', - xs_type='macro', subdomain=None): + def set_kappa_fission_mgxs(self, k_fission, temperature=294., + nuclide='total', xs_type='macro', + subdomain=None): """This method allows for an openmc.mgxs.KappaFissionXS to be used to set the kappa-fission cross section for this XSdata object. @@ -771,6 +876,9 @@ class XSdata(object): kappa_fission: openmc.mgxs.KappaFissionXS MGXS Object containing the kappa-fission cross section for the domain of interest. + temperature : float + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -793,17 +901,20 @@ class XSdata(object): [self.energy_groups]) check_value('domain_type', k_fission.domain_type, ['universe', 'cell', 'material', 'mesh']) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) - if self.representation is 'isotropic': - self._kappa_fission = k_fission.get_xs(nuclides=nuclide, - xs_type=xs_type, - subdomains=subdomain) - elif self.representation is 'angle': + i = np.where(self.temperatures == temperature)[0][0] + if self.representation == 'isotropic': + self._kappa_fission[i] = k_fission.get_xs(nuclides=nuclide, + xs_type=xs_type, + subdomains=subdomain) + elif self.representation == 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) - def set_chi_mgxs(self, chi, nuclide='total', xs_type='macro', - subdomain=None): + def set_chi_mgxs(self, chi, temperature=294., nuclide='total', + xs_type='macro', subdomain=None): """This method allows for an openmc.mgxs.Chi to be used to set chi for this XSdata object. @@ -811,6 +922,9 @@ class XSdata(object): ---------- chi: openmc.mgxs.Chi MGXS Object containing chi for the domain of interest. + temperature : float + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -838,19 +952,23 @@ class XSdata(object): check_value('energy_groups', chi.energy_groups, [self.energy_groups]) check_value('domain_type', chi.domain_type, ['universe', 'cell', 'material', 'mesh']) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) - if self.representation is 'isotropic': - self._chi = chi.get_xs(nuclides=nuclide, - xs_type=xs_type, subdomains=subdomain) - elif self.representation is 'angle': + i = np.where(self.temperatures == temperature)[0][0] + if self.representation == 'isotropic': + self._chi[i] = chi.get_xs(nuclides=nuclide, + xs_type=xs_type, subdomains=subdomain) + elif self.representation == 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) if self.use_chi is not None: self.use_chi = True - def set_scatter_mgxs(self, scatter, nuclide='total', xs_type='macro', - subdomain=None): + def set_scatter_matrix_mgxs(self, scatter, temperature=294., + nuclide='total', xs_type='macro', + subdomain=None): """This method allows for an openmc.mgxs.ScatterMatrixXS to be used to set the scatter matrix cross section for this XSdata object. If the XSdata.order attribute has not yet been set, then @@ -861,6 +979,9 @@ class XSdata(object): scatter: openmc.mgxs.ScatterMatrixXS MGXS Object containing the scatter matrix cross section for the domain of interest. + temperature : float + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -883,8 +1004,10 @@ class XSdata(object): [self.energy_groups]) check_value('domain_type', scatter.domain_type, ['universe', 'cell', 'material', 'mesh']) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) - if self.scatt_type != 'legendre': + if self.scatter_format != 'legendre': msg = 'Anisotropic scattering representations other than ' \ 'Legendre expansions have not yet been implemented in ' \ 'openmc.mgxs.' @@ -900,24 +1023,27 @@ class XSdata(object): check_value('legendre_order', scatter.legendre_order, [self.order]) - if self.representation is 'isotropic': + i = np.where(self.temperatures == temperature)[0][0] + if self.representation == 'isotropic': # Get the scattering orders in the outermost dimension - self._scatter = np.zeros((self.num_orders, - self.energy_groups.num_groups, - self.energy_groups.num_groups)) + self._scatter_matrix[i] = np.zeros((self.num_orders, + self.energy_groups.num_groups, + self.energy_groups.num_groups)) for moment in range(self.num_orders): - self._scatter[moment, :, :] = \ + self._scatter_matrix[i][moment, :, :] = \ scatter.get_xs(nuclides=nuclide, xs_type=xs_type, moment=moment, subdomains=subdomain) - elif self.representation is 'angle': + elif self.representation == 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) - def set_multiplicity_mgxs(self, nuscatter, scatter=None, nuclide='total', - xs_type='macro', subdomain=None): + def set_multiplicity_matrix_mgxs(self, nuscatter, scatter=None, + temperature=294., nuclide='total', + xs_type='macro', subdomain=None): """This method allows for either the direct use of only an - openmc.mgxs.MultiplicityMatrixXS OR an openmc.mgxs.NuScatterMatrixXS and + openmc.mgxs.MultiplicityMatrixXS OR + an openmc.mgxs.NuScatterMatrixXS and openmc.mgxs.ScatterMatrixXS to be used to set the scattering multiplicity for this XSdata object. Multiplicity, in OpenMC parlance, is a factor used to account for the production @@ -934,6 +1060,9 @@ class XSdata(object): scatter: openmc.mgxs.ScatterMatrixXS MGXS Object containing the scattering matrix cross section for the domain of interest. + temperature : float + Temperature (in Kelvin) of the data. Defaults to room temperature + (294K). nuclide : str Individual nuclide (or 'total' if obtaining material-wise data) to gather data for. Defaults to 'total'. @@ -957,6 +1086,9 @@ class XSdata(object): [self.energy_groups]) check_value('domain_type', nuscatter.domain_type, ['universe', 'cell', 'material', 'mesh']) + check_type('temperature', temperature, Real) + check_value('temperature', temperature, self.temperatures) + if scatter is not None: check_type('scatter', scatter, openmc.mgxs.ScatterMatrixXS) if isinstance(nuscatter, openmc.mgxs.MultiplicityMatrixXS): @@ -969,102 +1101,174 @@ class XSdata(object): check_value('domain_type', scatter.domain_type, ['universe', 'cell', 'material', 'mesh']) - if self.representation is 'isotropic': + i = np.where(self.temperatures == temperature)[0][0] + if self.representation == 'isotropic': nuscatt = nuscatter.get_xs(nuclides=nuclide, xs_type=xs_type, moment=0, subdomains=subdomain) if isinstance(nuscatter, openmc.mgxs.MultiplicityMatrixXS): - self._multiplicity = nuscatt + self._multiplicity_matrix[i] = nuscatt else: scatt = scatter.get_xs(nuclides=nuclide, xs_type=xs_type, moment=0, subdomains=subdomain) - self._multiplicity = np.divide(nuscatt, scatt) - elif self.representation is 'angle': + self._multiplicity_matrix[i] = np.divide(nuscatt, scatt) + elif self.representation == 'angle': msg = 'Angular-Dependent MGXS have not yet been implemented' raise ValueError(msg) - self._multiplicity = np.nan_to_num(self._multiplicity) + self._multiplicity_matrix[i] = \ + np.nan_to_num(self._multiplicity_matrix[i]) - def _get_xsdata_xml(self): - element = ET.Element('xsdata') - element.set('name', self._name) + def to_hdf5(self, file): + """Write XSdata to an HDF5 file - if self._alias is not None: - subelement = ET.SubElement(element, 'alias') - subelement.text = self.alias + Parameters + ---------- + file : h5py.File + HDF5 File (a root Group) to write to - if self._kT is not None: - subelement = ET.SubElement(element, 'kT') - subelement.text = str(self._kT) + """ + grp = file.create_group(self.name) + if self.atomic_weight_ratio is not None: + grp.attrs['atomic_weight_ratio'] = self.atomic_weight_ratio + if self.fissionable is not None: + grp.attrs['fissionable'] = self.fissionable + if self.representation is not None: + grp.attrs['representation'] = np.string_(self.representation) + if self.representation == 'angle': + if self.num_azimuthal is not None: + grp.attrs['num_azimuthal'] = self.num_azimuthal + if self.num_polar is not None: + grp.attrs['num_polar'] = self.num_polar + if self.scatter_format is not None: + grp.attrs['scatter_format'] = np.string_(self.scatter_format) + if self.scatter_shape is not None: + grp.attrs['scatter_shape'] = np.string_(self.scatter_shape) + if self.order is not None: + grp.attrs['order'] = self.order - if self._awr is not None: - subelement = ET.SubElement(element, 'awr') - subelement.text = str(self._awr) + ktg = grp.create_group('kTs') + for temperature in self.temperatures: + temp_label = str(int(np.round(temperature))) + "K" + kT = temperature * openmc.data.K_BOLTZMANN + ktg.create_dataset(temp_label, data=kT) - if self._fissionable is not None: - subelement = ET.SubElement(element, 'fissionable') - subelement.text = str(self._fissionable) + # Create the temperature datasets + for i, temperature in enumerate(self.temperatures): + xs_grp = grp.create_group(str(int(np.round(temperature))) + "K") + if self._total[i] is None: + raise ValueError('total data must be provided when writing ' + 'the HDF5 library') + xs_grp.create_dataset("total", data=self._total[i]) + if self._absorption[i] is None: + raise ValueError('absorption data must be provided when ' + 'writing the HDF5 library') + xs_grp.create_dataset("absorption", data=self._absorption[i]) + if self.fissionable: + if self._fission[i] is not None: + xs_grp.create_dataset("fission", data=self._fission[i]) + if self._kappa_fission[i] is not None: + xs_grp.create_dataset("kappa-fission", + data=self._kappa_fission[i]) + if self._chi[i] is not None: + xs_grp.create_dataset("chi", data=self._chi[i]) + if self._nu_fission[i] is None: + raise ValueError('nu-fission data must be provided when ' + 'writing the HDF5 library') + xs_grp.create_dataset("nu-fission", data=self._nu_fission[i]) - if self._representation is not None: - subelement = ET.SubElement(element, 'representation') - subelement.text = self._representation + if self._scatter_matrix[i] is None: + raise ValueError('Scatter matrix must be provided when ' + 'writing the HDF5 library') - if self._representation == 'angle': - if self._num_azimuthal is not None: - subelement = ET.SubElement(element, 'num_azimuthal') - subelement.text = str(self._num_azimuthal) - if self._num_polar is not None: - subelement = ET.SubElement(element, 'num_polar') - subelement.text = str(self._num_polar) + # Get the sparse scattering data to print to the library + G = self.energy_groups.num_groups + if self.representation == 'isotropic': + g_out_bounds = np.zeros((G, 2), dtype=np.int) + for g_in in range(G): + nz = np.nonzero(self._scatter_matrix[i][0, g_in, :]) + g_out_bounds[g_in, 0] = nz[0][0] + g_out_bounds[g_in, 1] = nz[0][-1] + # Now create the flattened scatter matrix array + matrix = self._scatter_matrix[i] + flat_scatt = [] + for g_in in range(G): + for g_out in range(g_out_bounds[g_in, 0], + g_out_bounds[g_in, 1] + 1): + for l in range(len(matrix[:, g_in, g_out])): + flat_scatt.append(matrix[l, g_in, g_out]) + # And write it. + scatt_grp = xs_grp.create_group('scatter_data') + scatt_grp.create_dataset("scatter_matrix", + data=np.array(flat_scatt)) + # Repeat for multiplicity + if self._multiplicity_matrix[i] is not None: + # Now create the flattened scatter matrix array + matrix = self._multiplicity_matrix[i][:, :] + flat_mult = [] + for g_in in range(G): + for g_out in range(g_out_bounds[g_in, 0], + g_out_bounds[g_in, 1] + 1): + flat_mult.append(matrix[g_in, g_out]) + scatt_grp.create_dataset("multiplicity_matrix", + data=np.array(flat_mult)) - if self._scatt_type is not None: - subelement = ET.SubElement(element, 'scatt_type') - subelement.text = self._scatt_type + # And finally, adjust g_out_bounds for 1-based group counting + # and write it. + g_out_bounds[:, :] += 1 + scatt_grp.create_dataset("g_min", data=g_out_bounds[:, 0]) + scatt_grp.create_dataset("g_max", data=g_out_bounds[:, 1]) - if self._order is not None: - subelement = ET.SubElement(element, 'order') - subelement.text = str(self._order) + elif self.representation == 'angle': + Np = self.num_polar + Na = self.num_azimuthal + g_out_bounds = np.zeros((Np, Na, G, 2), dtype=np.int) + for p in range(Np): + for a in range(Na): + for g_in in range(G): + matrix = self._scatter_matrix[i][p, a, 0, g_in, :] + nz = np.nonzero(matrix) + g_out_bounds[p, a, g_in, 0] = nz[0][0] + g_out_bounds[p, a, g_in, 1] = nz[0][-1] + # Now create the flattened scatter matrix array + flat_scatt = [] + for p in range(Np): + for a in range(Na): + matrix = self._scatter_matrix[i][p, a, :, :, :] + for g_in in range(G): + for g_out in range(g_out_bounds[p, a, g_in, 0], + g_out_bounds[p, a, g_in, 1] + 1): + for l in range(len(matrix[:, g_in, g_out])): + flat_scatt.append(matrix[l, g_in, g_out]) + # And write it. + scatt_grp = xs_grp.create_group('scatter_data') + scatt_grp.create_dataset("scatter_matrix", + data=np.array(flat_scatt)) + # Repeat for multiplicity + if self._multiplicity_matrix[i] is not None: + # Now create the flattened scatter matrix array + flat_mult = [] + for p in range(Np): + for a in range(Na): + matrix = self._multiplicity_matrix[i][p, a, :, :] + for g_in in range(G): + for g_out in range(g_out_bounds[p, a, g_in, 0], + g_out_bounds[p, a, g_in, 1] + 1): + flat_mult.append(matrix[g_in, g_out]) + # And write it. + scatt_grp.create_dataset("multiplicity_matrix", + data=np.array(flat_mult)) - if self._tabular_legendre is not None: - subelement = ET.SubElement(element, 'tabular_legendre') - subelement.set('enable', str(self._tabular_legendre['enable'])) - subelement.set('num_points', - str(self._tabular_legendre['num_points'])) + # And finally, adjust g_out_bounds for 1-based group counting + # and write it. + g_out_bounds[:, :, :, :] += 1 + scatt_grp.create_dataset("g_min", data=g_out_bounds[:, :, :, 0]) + scatt_grp.create_dataset("g_max", data=g_out_bounds[:, :, :, 1]) - if self._total is not None: - subelement = ET.SubElement(element, 'total') - subelement.text = ndarray_to_string(self._total) - - if self._absorption is not None: - subelement = ET.SubElement(element, 'absorption') - subelement.text = ndarray_to_string(self._absorption) - - if self._scatter is not None: - subelement = ET.SubElement(element, 'scatter') - subelement.text = ndarray_to_string(self._scatter) - - if self._multiplicity is not None: - subelement = ET.SubElement(element, 'multiplicity') - subelement.text = ndarray_to_string(self._multiplicity) - - if self._fissionable: - if self._fission is not None: - subelement = ET.SubElement(element, 'fission') - subelement.text = ndarray_to_string(self._fission) - - if self._kappa_fission is not None: - subelement = ET.SubElement(element, 'k_fission') - subelement.text = ndarray_to_string(self._kappa_fission) - - if self._nu_fission is not None: - subelement = ET.SubElement(element, 'nu_fission') - subelement.text = ndarray_to_string(self._nu_fission) - - if self._chi is not None: - subelement = ET.SubElement(element, 'chi') - subelement.text = ndarray_to_string(self._chi) - - return element + # Add the kinetics data + if self._inverse_velocities[i] is not None: + xs_grp.create_dataset("inverse_velocities", + data=self._inverse_velocities[i]) class MGXSLibrary(object): @@ -1072,41 +1276,35 @@ class MGXSLibrary(object): Corresponds directly to the MG version of the cross_sections.xml input file. + Parameters + ---------- + energy_groups : openmc.mgxs.EnergyGroups + Energy group structure + Attributes ---------- energy_groups : openmc.mgxs.EnergyGroups Energy group structure. - inverse_velocities : Iterable of Real - Inverse of velocities, units of sec/cm xsdatas : Iterable of openmc.XSdata Iterable of multi-Group cross section data objects """ def __init__(self, energy_groups): + self.energy_groups = energy_groups self._xsdatas = [] - self._energy_groups = energy_groups - self._inverse_velocities = None - self._cross_sections_file = ET.Element('cross_sections') - - @property - def inverse_velocities(self): - return self._inverse_velocities @property def energy_groups(self): return self._energy_groups + @property + def temperatures(self): + return self._temperatures + @property def xsdatas(self): return self._xsdatas - @inverse_velocities.setter - def inverse_velocities(self, inverse_velocities): - check_type('inverse_velocities', inverse_velocities, Iterable, Real) - check_greater_than('number of inverse_velocities', - len(inverse_velocities), 0.0) - self._inverse_velocities = np.array(inverse_velocities) - @energy_groups.setter def energy_groups(self, energy_groups): check_type('energy groups', energy_groups, openmc.mgxs.EnergyGroups) @@ -1162,52 +1360,24 @@ class MGXSLibrary(object): self._xsdatas.remove(xsdata) - def _create_groups_subelement(self): - if self._energy_groups is not None: - element = ET.SubElement(self._cross_sections_file, 'groups') - element.text = str(self._energy_groups.num_groups) - - def _create_group_structure_subelement(self): - if self._energy_groups is not None: - element = ET.SubElement(self._cross_sections_file, - 'group_structure') - element.text = ' '.join(map(str, self._energy_groups.group_edges)) - - def _create_inverse_velocities_subelement(self): - if self._inverse_velocities is not None: - element = ET.SubElement(self._cross_sections_file, - 'inverse_velocities') - element.text = ' '.join(map(str, self._inverse_velocities)) - - def _create_xsdata_subelements(self): - for xsdata in self._xsdatas: - xml_element = xsdata._get_xsdata_xml() - self._cross_sections_file.append(xml_element) - - def export_to_xml(self, filename='mgxs.xml'): - """Create an mgxs.xml file that can be used for a - simulation. + def export_to_hdf5(self, filename='mgxs.h5'): + """Create an hdf5 file that can be used for a simulation. Parameters ---------- - filename : str, optional - filename of file, default is mgxs.xml + filename : str + Filename of file, default is mgxs.h5. """ - # Reset xml element tree - self._cross_sections_file.clear() + check_type('filename', filename, string_types) - self._create_groups_subelement() - self._create_group_structure_subelement() - self._create_inverse_velocities_subelement() - self._create_xsdata_subelements() + # Create and write to the HDF5 file + file = h5py.File(filename, "w") + file.attrs['groups'] = self.energy_groups.num_groups + file.attrs['group structure'] = self.energy_groups.group_edges - # Clean the indentation in the file to be user-readable - sort_xml_elements(self._cross_sections_file) - clean_xml_indentation(self._cross_sections_file) + for xsdata in self._xsdatas: + xsdata.to_hdf5(file) - # Write the XML Tree to the xsdatas.xml file - tree = ET.ElementTree(self._cross_sections_file) - tree.write(filename, xml_declaration=True, - encoding='utf-8', method='xml') + file.close() diff --git a/openmc/settings.py b/openmc/settings.py index 1a7c7792fb..a214b02f3a 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -87,10 +87,14 @@ class Settings(object): Seed for the linear congruential pseudorandom number generator survival_biasing : bool Indicate whether survival biasing is to be used - weight : float - Weight cutoff below which particle undergo Russian roulette - weight_avg : float - Weight assigned to particles that are not killed after Russian roulette + cutoff : dict + Dictionary defining weight cutoff and energy cutoff. The dictionary may + have three keys, 'weight', 'weight_avg' and 'energy'. Value for 'weight' + should be a float indicating weight cutoff below which particle undergo + Russian roulette. Value for 'weight_avg' should be a float indicating + weight assigned to particles that are not killed after Russian + roulette. Value of energy should be a float indicating energy in MeV + below which particle will be killed. entropy_dimension : tuple or list Number of Shannon entropy mesh cells in the x, y, and z directions, respectively @@ -98,6 +102,13 @@ class Settings(object): Coordinates of the lower-left point of the Shannon entropy mesh entropy_upper_right : tuple or list Coordinates of the upper-right point of the Shannon entropy mesh + tabular_legendre : dict + Determines if a multi-group scattering moment kernel expanded via + Legendre polynomials is to be converted to a tabular distribution or + not. Accepted keys are 'enable' and 'num_points'. The value for + 'enable' is a bool stating whether the conversion to tabular is + performed; the value for 'num_points' sets the number of points to use + in the tabular distribution, should 'enable' be True. temperature : dict Defines a default temperature and method for treating intermediate temperatures at which nuclear data doesn't exist. Accepted keys are @@ -139,6 +150,8 @@ class Settings(object): The elastic scattering model to use for resonant isotopes volume_calculations : VolumeCalculation or iterable of VolumeCalculation Stochastic volume calculation specifications + create_fission_neutrons : bool + Indicate whether fission neutrons should be created or not. """ @@ -198,11 +211,12 @@ class Settings(object): self._trace = None self._track = None + self._tabular_legendre = {} + self._temperature = {} # Cutoff subelement - self._weight = None - self._weight_avg = None + self._cutoff = None # Uniform fission source subelement self._ufs_dimension = 1 @@ -225,6 +239,8 @@ class Settings(object): self._volume_calculations = cv.CheckedList( VolumeCalculation, 'volume calculations') + self._create_fission_neutrons = None + @property def run_mode(self): return self._run_mode @@ -361,6 +377,10 @@ class Settings(object): def verbosity(self): return self._verbosity + @property + def tabular_legendre(self): + return self._tabular_legendre + @property def temperature(self): return self._temperature @@ -374,12 +394,8 @@ class Settings(object): return self._track @property - def weight(self): - return self._weight - - @property - def weight_avg(self): - return self._weight_avg + def cutoff(self): + return self._cutoff @property def ufs_dimension(self): @@ -425,6 +441,10 @@ class Settings(object): def volume_calculations(self): return self._volume_calculations + @property + def create_fission_neutrons(self): + return self._create_fission_neutrons + @run_mode.setter def run_mode(self, run_mode): if run_mode not in ['eigenvalue', 'fixed source']: @@ -612,17 +632,29 @@ class Settings(object): cv.check_type('survival biasing', survival_biasing, bool) self._survival_biasing = survival_biasing - @weight.setter - def weight(self, weight): - cv.check_type('weight cutoff', weight, Real) - cv.check_greater_than('weight cutoff', weight, 0.0) - self._weight = weight + @cutoff.setter + def cutoff(self, cutoff): + if not isinstance(cutoff, Mapping): + msg = 'Unable to set cutoff from "{0}" which is not a '\ + ' Python dictionary'.format(cutoff) + raise ValueError(msg) + for key in cutoff: + if key == 'weight': + cv.check_type('weight cutoff', cutoff['weight'], Real) + cv.check_greater_than('weight cutoff', cutoff['weight'], 0.0) + elif key == 'weight_avg': + cv.check_type('average survival weight', cutoff['weight_avg'], + Real) + cv.check_greater_than('average survival weight', + cutoff['weight_avg'], 0.0) + elif key == 'energy': + cv.check_type('energy cutoff', cutoff['energy'], Real) + cv.check_greater_than('energy cutoff', cutoff['energy'], 0.0) + else: + msg = 'Unable to set cutoff to "{0}" which is unsupported by '\ + 'OpenMC'.format(key) - @weight_avg.setter - def weight_avg(self, weight_avg): - cv.check_type('average survival weight', weight_avg, Real) - cv.check_greater_than('average survival weight', weight_avg, 0.0) - self._weight_avg = weight_avg + self._cutoff = cutoff @entropy_dimension.setter def entropy_dimension(self, dimension): @@ -666,6 +698,19 @@ class Settings(object): cv.check_type('no reduction option', no_reduce, bool) self._no_reduce = no_reduce + @tabular_legendre.setter + def tabular_legendre(self, tabular_legendre): + cv.check_type('tabular_legendre settings', tabular_legendre, Mapping) + for key, value in tabular_legendre.items(): + cv.check_value('tabular_legendre key', key, + ['enable', 'num_points']) + if key == 'enable': + cv.check_type('enable tabular_legendre', value, bool) + elif key == 'num_points': + cv.check_type('num_points tabular_legendre', value, Integral) + cv.check_greater_than('num_points tabular_legendre', value, 0) + self._tabular_legendre = tabular_legendre + @temperature.setter def temperature(self, temperature): cv.check_type('temperature settings', temperature, Mapping) @@ -824,6 +869,12 @@ class Settings(object): self._volume_calculations = cv.CheckedList( VolumeCalculation, 'stochastic volume calculations', vol_calcs) + @create_fission_neutrons.setter + def create_fission_neutrons(self, create_fission_neutrons): + cv.check_type('Whether create fission neutrons', + create_fission_neutrons, bool) + self._create_fission_neutrons = create_fission_neutrons + def _create_run_mode_subelement(self): if self.run_mode == 'eigenvalue': @@ -988,14 +1039,19 @@ class Settings(object): element.text = str(self._survival_biasing).lower() def _create_cutoff_subelement(self): - if self._weight is not None: + if self._cutoff is not None: element = ET.SubElement(self._settings_file, "cutoff") + if 'weight' in self._cutoff: + subelement = ET.SubElement(element, "weight") + subelement.text = str(self._cutoff['weight']) - subelement = ET.SubElement(element, "weight") - subelement.text = str(self._weight) + if 'weight_avg' in self._cutoff: + subelement = ET.SubElement(element, "weight_avg") + subelement.text = str(self._cutoff['weight_avg']) - subelement = ET.SubElement(element, "weight_avg") - subelement.text = str(self._weight_avg) + if 'energy' in self._cutoff: + subelement = ET.SubElement(element, "energy") + subelement.text = str(self._cutoff['energy']) def _create_entropy_subelement(self): if self._entropy_lower_left is not None and \ @@ -1049,6 +1105,15 @@ class Settings(object): element = ET.SubElement(self._settings_file, "no_reduce") element.text = str(self._no_reduce).lower() + def _create_tabular_legendre_subelements(self): + if self.tabular_legendre: + element = ET.SubElement(self._settings_file, "tabular_legendre") + subelement = ET.SubElement(element, "enable") + subelement.text = str(self._tabular_legendre['enable']).lower() + if 'num_points' in self._tabular_legendre: + subelement = ET.SubElement(element, "num_points") + subelement.text = str(self._tabular_legendre['num_points']) + def _create_temperature_subelements(self): if self.temperature: for key, value in sorted(self.temperature.items()): @@ -1119,6 +1184,11 @@ class Settings(object): for r in self.resonance_scattering: elem.append(r.to_xml_element()) + def _create_create_fission_neutrons_subelement(self): + if self._create_fission_neutrons is not None: + elem = ET.SubElement(self._settings_file, "create_fission_neutrons") + elem.text = str(self._create_fission_neutrons).lower() + def export_to_xml(self, path='settings.xml'): """Export simulation settings to an XML file. @@ -1155,6 +1225,7 @@ class Settings(object): self._create_no_reduce_subelement() self._create_threads_subelement() self._create_verbosity_subelement() + self._create_tabular_legendre_subelements() self._create_temperature_subelements() self._create_trace_subelement() self._create_track_subelement() @@ -1162,6 +1233,7 @@ class Settings(object): self._create_dd_subelement() self._create_resonance_scattering_subelement() self._create_volume_calcs_subelement() + self._create_create_fission_neutrons_subelement() # Clean the indentation in the file to be user-readable clean_xml_indentation(self._settings_file) diff --git a/scripts/openmc-ace-to-hdf5 b/scripts/openmc-ace-to-hdf5 index dd115d175c..bfc1c1a54d 100755 --- a/scripts/openmc-ace-to-hdf5 +++ b/scripts/openmc-ace-to-hdf5 @@ -108,7 +108,7 @@ elif args.xsdata is not None: for line in xsdata: words = line.split() if len(words) >= 9: - path = os.path.join(os.path.dirname(args.xsdata, words[8])) + path = os.path.join(os.path.dirname(args.xsdata), words[8]) if path not in ace_libraries: ace_libraries.append(path) diff --git a/scripts/openmc-update-mgxs b/scripts/openmc-update-mgxs new file mode 100755 index 0000000000..658be9fef7 --- /dev/null +++ b/scripts/openmc-update-mgxs @@ -0,0 +1,229 @@ +#!/usr/bin/env python +"""Update OpenMC's deprecated multi-group cross section XML files to the latest +HDF5-based format. + +Usage information can be obtained by running 'openmc-update-mgxs --help': + +usage: openmc-update-mgxs [-h] in out + +Update mgxs.xml files to the latest format. This will remove 'outside' +attributes/elements from lattices and replace them with 'outer' attributes. For +'cell' elements, any 'surfaces' attributes/elements will be renamed +'region'. Note that this script will not delete the given files; it will append +'.original' to the given files and write new ones. + +positional arguments: + in Input mgxs xml file + out Output mgxs hdf5 file + +optional arguments: + -h, --help show this help message and exit + +""" + +from __future__ import print_function +import os +from shutil import move +import warnings +import xml.etree.ElementTree as ET + +import argparse +import h5py +import numpy as np + +import openmc.mgxs_library + +description = """\ +Update OpenMC's deprecated multi-group cross section XML files to the latest +HDF5-based format.""" + + +def parse_args(): + """Read the input files from the commandline.""" + # Create argument parser + parser = argparse.ArgumentParser(description=description, + formatter_class=argparse.RawTextHelpFormatter) + parser.add_argument('-i', '--input', type=argparse.FileType('r'), + help='input XML file') + parser.add_argument('-o', '--output', nargs='?', default='', + help='output file, in HDF5 format') + args = vars(parser.parse_args()) + + if args['output'] == '': + filename = args['input'].name + extension = filenameos.path.splitext() + if extension == '.xml': + filename = filename[:filename.rfind('.')] + '.h5' + args['output'] = filename + + # Parse and return commandline arguments. + return args + + +def get_data(element, entry): + value = element.find(entry) + if value is not None: + value = value.text.strip() + else: + if entry in element.attrib: + value = element.attrib[entry].strip() + else: + value = None + + return value + + +if __name__ == '__main__': + args = parse_args() + + # Parse the XML data. + tree = ET.parse(args['input']) + root = tree.getroot() + + # Get old metadata + temp = tree.find('group_structure').text.strip() + temp = np.array(temp.split()) + group_structure = temp.astype(np.float) + energy_groups = openmc.mgxs.EnergyGroups(group_structure) + temp = tree.find('inverse_velocities') + if temp is not None: + temp = temp.text.strip() + temp = np.array(temp.split()) + inverse_velocities = temp.astype(np.float) + else: + inverse_velocities = None + + xsd = [] + names = [] + + # Now move on to the cross section data itself + for xsdata_elem in root.iter('xsdata'): + name = get_data(xsdata_elem, 'name') + + temperature = get_data(xsdata_elem, 'kT') + if temperature is not None: + temperature = \ + float(temperature) / openmc.data.K_BOLTZMANN + else: + temperature = 294. + temperatures = [temperature] + + awr = get_data(xsdata_elem, 'awr') + if awr is not None: + awr = float(awr) + + representation = get_data(xsdata_elem, 'representation') + if representation is None: + representation = 'isotropic' + if representation == 'angle': + n_azi = int(get_data(xsdata_elem, 'num_azimuthal')) + n_pol = int(get_data(xsdata_elem, 'num_polar')) + + scatter_format = get_data(xsdata_elem, 'scatt_type') + if scatter_format is None: + scatter_format = 'legendre' + + order = int(get_data(xsdata_elem, 'order')) + + tab_leg = get_data(xsdata_elem, 'tabular_legendre') + if tab_leg is not None: + warnings.Warning('The tabular_legendre option has moved to the ' + 'settings.xml file and must be added manually') + + # Either add the data to a previously existing xsdata (if it is + # for the same 'name' but a different temperature), or create a + # new one. + try: + # It is in our list, so store that entry + i = names.index(name) + except ValueError: + # It is not in our list, so add it + i = -1 + xsd.append(openmc.XSdata(name, energy_groups, + temperatures=temperatures, + representation=representation)) + if awr is not None: + xsd[-1].atomic_weight_ratio = awr + if representation == 'angle': + xsd[-1].num_azimuthal = n_azi + xsd[-1].num_polar = n_pol + xsd[-1].scatter_format = scatter_format + xsd[-1].order = order + names.append(name) + + if scatter_format == 'legendre': + order_dim = order + 1 + else: + order_dim = order + + if i != -1: + xsd[i].add_temperature(temperature) + + temp = get_data(xsdata_elem, 'total') + if temp is not None: + temp = np.array(temp.split(), dtype=float) + total = temp.astype(np.float) + total.shape = xsd[i].vector_shape + xsd[i].set_total(total, temperature) + + if inverse_velocities is not None: + xsd[i].set_inverse_velocities(inverse_velocities, temperature) + + temp = get_data(xsdata_elem, 'absorption') + temp = np.array(temp.split()) + absorption = temp.astype(np.float) + absorption.shape = xsd[i].vector_shape + xsd[i].set_absorption(absorption, temperature) + + temp = get_data(xsdata_elem, 'scatter') + temp = np.array(temp.split()) + scatter = temp.astype(np.float) + scatter.shape = xsd[i].pn_matrix_shape + xsd[i].set_scatter_matrix(scatter, temperature) + + temp = get_data(xsdata_elem, 'multiplicity') + if temp is not None: + temp = np.array(temp.split()) + multiplicity = temp.astype(np.float) + multiplicity.shape = xsd[i].matrix_shape + xsd[i].set_multiplicity_matrix(multiplicity, temperature) + + temp = get_data(xsdata_elem, 'fission') + if temp is not None: + temp = np.array(temp.split()) + fission = temp.astype(np.float) + fission.shape = xsd[i].vector_shape + xsd[i].set_fission(fission, temperature) + + temp = get_data(xsdata_elem, 'kappa_fission') + if temp is not None: + temp = np.array(temp.split()) + kappa_fission = temp.astype(np.float) + kappa_fission.shape = xsd[i].vector_shape + xsd[i].set_kappa_fission(kappa_fission, temperature) + + temp = get_data(xsdata_elem, 'chi') + if temp is not None: + temp = np.array(temp.split()) + chi = temp.astype(np.float) + chi.shape = xsd[i].vector_shape + xsd[i].set_chi(chi, temperature) + else: + chi = None + + temp = get_data(xsdata_elem, 'nu_fission') + if temp is not None: + temp = np.array(temp.split()) + nu_fission = temp.astype(np.float) + if chi is not None: + nu_fission.shape = xsd[i].vector_shape + else: + nu_fission.shape = xsd[i].matrix_shape + xsd[i].set_nu_fission(nu_fission, temperature) + + # Build library as we go, but first we have enough to initialize it + lib = openmc.MGXSLibrary(energy_groups) + + lib.add_xsdatas(xsd) + + lib.export_to_hdf5(args['output']) diff --git a/setup.py b/setup.py old mode 100644 new mode 100755 index 83098a9d5c..0885c28a86 --- a/setup.py +++ b/setup.py @@ -1,6 +1,7 @@ #!/usr/bin/env python import glob +import numpy as np try: from setuptools import setup have_setuptools = True @@ -57,7 +58,8 @@ if have_setuptools: # If Cython is present, add resonance reconstruction capability if have_cython: kwargs.update({ - 'ext_modules': cythonize('openmc/data/reconstruct.pyx') + 'ext_modules': cythonize('openmc/data/reconstruct.pyx'), + 'include_dirs': [np.get_include()] }) setup(**kwargs) diff --git a/src/geometry_header.F90 b/src/geometry_header.F90 index 1d1826fbfb..9f4be90b9b 100644 --- a/src/geometry_header.F90 +++ b/src/geometry_header.F90 @@ -1,6 +1,12 @@ module geometry_header - use constants, only: HALF, TWO, THREE, INFINITY + use algorithm, only: find + use constants, only: HALF, TWO, THREE, INFINITY, K_BOLTZMANN, & + MATERIAL_VOID, NONE + use dict_header, only: DictCharInt, DictIntInt + use material_header, only: Material + use stl_vector, only: VectorReal + use string, only: to_lower implicit none @@ -319,4 +325,74 @@ contains end if end function get_local_hex +!=============================================================================== +! GET_TEMPERATURES returns a list of temperatures that each nuclide/S(a,b) table +! appears at in the model. Later, this list is used to determine the actual +! temperatures to read (which may be different if interpolation is used) +!=============================================================================== + + subroutine get_temperatures(cells, materials, material_dict, nuclide_dict, & + n_nucs, nuc_temps, sab_dict, n_sabs, sab_temps) + type(Cell), allocatable, intent(in) :: cells(:) + type(Material), allocatable, intent(in) :: materials(:) + type(DictIntInt), intent(in) :: material_dict + type(DictCharInt), intent(in) :: nuclide_dict + integer, intent(in) :: n_nucs + type(VectorReal), allocatable, intent(out) :: nuc_temps(:) + type(DictCharInt), optional, intent(in) :: sab_dict + integer, optional, intent(in) :: n_sabs + type(VectorReal), optional, allocatable, intent(out) :: sab_temps(:) + + integer :: i, j, k + integer :: i_nuclide ! index in nuclides array + integer :: i_sab ! index in S(a,b) array + integer :: i_material + real(8) :: temperature ! temperature in Kelvin + + allocate(nuc_temps(n_nucs)) + if (present(n_sabs) .and. present(sab_temps)) allocate(sab_temps(n_sabs)) + + do i = 1, size(cells) + do j = 1, size(cells(i) % material) + ! Skip any non-material cells and void materials + if (cells(i) % material(j) == NONE .or. & + cells(i) % material(j) == MATERIAL_VOID) cycle + + ! Get temperature of cell (rounding to nearest integer) + if (size(cells(i) % sqrtkT) > 1) then + temperature = cells(i) % sqrtkT(j)**2 / K_BOLTZMANN + else + temperature = cells(i) % sqrtkT(1)**2 / K_BOLTZMANN + end if + + i_material = material_dict % get_key(cells(i) % material(j)) + associate (mat => materials(i_material)) + NUC_NAMES_LOOP: do k = 1, size(mat % names) + ! Get index in nuc_temps array + i_nuclide = nuclide_dict % get_key(to_lower(mat % names(k))) + + ! Add temperature if it hasn't already been added + if (find(nuc_temps(i_nuclide), temperature) == -1) then + call nuc_temps(i_nuclide) % push_back(temperature) + end if + end do NUC_NAMES_LOOP + + if (present(sab_temps) .and. present(sab_dict) .and. & + mat % n_sab > 0) then + SAB_NAMES_LOOP: do k = 1, size(mat % sab_names) + ! Get index in nuc_temps array + i_sab = sab_dict % get_key(to_lower(mat % sab_names(k))) + + ! Add temperature if it hasn't already been added + if (find(sab_temps(i_sab), temperature) == -1) then + call sab_temps(i_sab) % push_back(temperature) + end if + end do SAB_NAMES_LOOP + end if + end associate + end do + end do + + end subroutine get_temperatures + end module geometry_header diff --git a/src/global.F90 b/src/global.F90 index f00a1d368f..8049db6ef7 100644 --- a/src/global.F90 +++ b/src/global.F90 @@ -123,12 +123,15 @@ module global ! Midpoint of the energy group structure real(8), allocatable :: energy_bin_avg(:) - ! Inverse velocities of the energy groups (provided or estimated) - real(8), allocatable :: inverse_velocities(:) - ! Maximum Data Order integer :: max_order + ! Whether or not to convert Legendres to tabulars + logical :: legendre_to_tabular = .True. + + ! Number of points to use in the Legendre to tabular conversion + integer :: legendre_to_tabular_points = 33 + ! ============================================================================ ! TALLY-RELATED VARIABLES @@ -304,6 +307,7 @@ module global logical :: survival_biasing = .false. real(8) :: weight_cutoff = 0.25_8 + real(8) :: energy_cutoff = ZERO real(8) :: weight_survive = ONE ! ============================================================================ @@ -352,6 +356,9 @@ module global ! Write out initial source logical :: write_initial_source = .false. + ! Whether create fission neutrons or not. Only applied for MODE_FIXEDSOURCE + logical :: create_fission_neutrons = .true. + ! ============================================================================ ! CMFD VARIABLES diff --git a/src/hdf5_interface.F90 b/src/hdf5_interface.F90 index 136628162c..ce689afa3b 100644 --- a/src/hdf5_interface.F90 +++ b/src/hdf5_interface.F90 @@ -74,6 +74,7 @@ module hdf5_interface module procedure read_attribute_integer_2D module procedure read_attribute_string module procedure read_attribute_string_1D + module procedure read_attribute_logical end interface read_attribute interface write_attribute @@ -84,12 +85,14 @@ module hdf5_interface public :: write_dataset public :: read_dataset + public :: attribute_exists public :: write_attribute public :: read_attribute public :: file_create public :: file_open public :: file_close public :: create_group + public :: object_exists public :: open_group public :: close_group public :: open_dataset @@ -98,6 +101,7 @@ module hdf5_interface public :: write_attribute_string public :: get_groups public :: get_datasets + public :: get_name contains @@ -213,12 +217,11 @@ contains subroutine get_groups(object_id, names) integer(HID_T), intent(in) :: object_id - character(len=255), allocatable, intent(out) :: names(:) + character(len=150), allocatable, intent(out) :: names(:) integer :: n_members, i, group_count, type integer :: hdf5_err - character(len=255) :: name - + character(len=150) :: name ! Get number of members in this location call h5gn_members_f(object_id, './', n_members, hdf5_err) @@ -245,17 +248,49 @@ contains end subroutine get_groups +!=============================================================================== +! CHECK_ATTRIBUTE Checks to see if an attribute exists in the object +!=============================================================================== + + function attribute_exists(object_id, name) result(exists) + integer(HID_T), intent(in) :: object_id + character(*), intent(in) :: name ! name of group + logical :: exists + + integer :: hdf5_err ! HDF5 error code + + ! Check if attribute exists + call h5aexists_by_name_f(object_id, '.', trim(name), exists, hdf5_err) + + end function attribute_exists + +!=============================================================================== +! CHECK_GROUP Checks to see if a group exists in the object +!=============================================================================== + + function object_exists(object_id, name) result(exists) + integer(HID_T), intent(in) :: object_id + character(*), intent(in) :: name ! name of group + logical :: exists + + integer :: hdf5_err ! HDF5 error code + + ! Check if group exists + call h5ltpath_valid_f(object_id, trim(name), .true., exists, hdf5_err) + + end function object_exists + !=============================================================================== ! GET_DATASETS Gets a list of all the datasets in a given location. !=============================================================================== subroutine get_datasets(object_id, names) integer(HID_T), intent(in) :: object_id - character(len=255), allocatable, intent(out) :: names(:) + character(len=150), allocatable, intent(out) :: names(:) integer :: n_members, i, dset_count, type integer :: hdf5_err - character(len=255) :: name + character(len=150) :: name ! Get number of members in this location @@ -283,6 +318,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=150) :: 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 = 150 + 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 !=============================================================================== @@ -296,7 +352,7 @@ contains integer :: hdf5_err ! HDF5 error code ! Check if group exists - call h5ltpath_valid_f(group_id, trim(name), .true., exists, hdf5_err) + exists = object_exists(group_id, name) ! open group if it exists if (exists) then @@ -319,7 +375,7 @@ contains logical :: exists ! does the group exist ! Check if group exists - call h5ltpath_valid_f(group_id, trim(name), .true., exists, hdf5_err) + exists = object_exists(group_id, name) ! create group if (exists) then @@ -357,7 +413,7 @@ contains integer :: hdf5_err ! HDF5 error code ! Check if group exists - call h5ltpath_valid_f(group_id, trim(name), .true., exists, hdf5_err) + exists = object_exists(group_id, name) ! open group if it exists if (exists) then @@ -2486,6 +2542,29 @@ contains call h5tclose_f(memtype, hdf5_err) end subroutine read_attribute_string_1D_explicit + subroutine read_attribute_logical(buffer, obj_id, name) + logical, intent(inout), target :: buffer + integer(HID_T), intent(in) :: obj_id + character(*), intent(in) :: name + + integer, target :: int_buffer + integer :: hdf5_err + integer(HID_T) :: attr_id + type(c_ptr) :: f_ptr + + call h5aopen_f(obj_id, trim(name), attr_id, hdf5_err) + f_ptr = c_loc(int_buffer) + call h5aread_f(attr_id, H5T_NATIVE_INTEGER, f_ptr, hdf5_err) + call h5aclose_f(attr_id, hdf5_err) + + ! Convert to Fortran logical + if (int_buffer == 0) then + buffer = .false. + else + buffer = .true. + end if + end subroutine read_attribute_logical + subroutine get_shape(obj_id, dims) integer(HID_T), intent(in) :: obj_id integer(HSIZE_T), intent(out) :: dims(:) diff --git a/src/initialize.F90 b/src/initialize.F90 index 2bcf2e01f2..4fe6f8769c 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -113,12 +113,6 @@ contains if (run_CE) then ! Construct log energy grid for cross-sections call logarithmic_grid() - else - ! Create material macroscopic data for MGXS - call time_read_xs%start() - call read_mgxs() - call create_macro_xs() - call time_read_xs%stop() end if ! Allocate and setup tally stride, matching_bins, and tally maps diff --git a/src/input_xml.F90 b/src/input_xml.F90 index db08eedaab..e8b950d917 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -1,21 +1,20 @@ module input_xml - use hdf5 - - use algorithm, only: find use cmfd_input, only: configure_cmfd use constants - use dict_header, only: DictIntInt, ElemKeyValueCI + use dict_header, only: DictIntInt, DictCharInt, ElemKeyValueCI use distribution_multivariate use distribution_univariate use endf, only: reaction_name use energy_grid, only: grid_method, n_log_bins use error, only: fatal_error, warning - use geometry_header, only: Cell, Lattice, RectLattice, HexLattice + use geometry_header, only: Cell, Lattice, RectLattice, HexLattice, & + get_temperatures use global use hdf5_interface use list_header, only: ListChar, ListInt, ListReal use mesh_header, only: RegularMesh + use mgxs_data, only: create_macro_xs, read_mgxs use multipole, only: multipole_read use output, only: write_message use plot_header @@ -52,6 +51,17 @@ contains call read_tallies_xml() if (cmfd_run) call configure_cmfd() + if (.not. run_CE) then + ! Create material macroscopic data for MGXS + call time_read_xs % start() + call read_mgxs() + call create_macro_xs() + call time_read_xs % stop() + end if + + ! Normalize atom/weight percents + if (run_mode /= MODE_PLOTTING) call normalize_ao() + end subroutine read_input_xml !=============================================================================== @@ -91,6 +101,7 @@ contains type(Node), pointer :: node_trigger => null() type(Node), pointer :: node_keff_trigger => null() type(Node), pointer :: node_vol => null() + type(Node), pointer :: node_tab_leg => null() type(NodeList), pointer :: node_scat_list => null() type(NodeList), pointer :: node_source_list => null() type(NodeList), pointer :: node_vol_list => null() @@ -659,8 +670,15 @@ contains ! Cutoffs if (check_for_node(doc, "cutoff")) then call get_node_ptr(doc, "cutoff", node_cutoff) - call get_node_value(node_cutoff, "weight", weight_cutoff) - call get_node_value(node_cutoff, "weight_avg", weight_survive) + if (check_for_node(node_cutoff, "weight")) then + call get_node_value(node_cutoff, "weight", weight_cutoff) + end if + if (check_for_node(node_cutoff, "weight_avg")) then + call get_node_value(node_cutoff, "weight_avg", weight_survive) + end if + if (check_for_node(node_cutoff, "energy")) then + call get_node_value(node_cutoff, "energy", energy_cutoff) + end if end if ! Particle trace @@ -1102,6 +1120,44 @@ contains end select end if + ! Check whether create fission sites + if (run_mode == MODE_FIXEDSOURCE) then + if (check_for_node(doc, "create_fission_neutrons")) then + call get_node_value(doc, "create_fission_neutrons", temp_str) + temp_str = to_lower(temp_str) + if (trim(temp_str) == 'true' .or. trim(temp_str) == '1') then + create_fission_neutrons = .true. + else if (trim(temp_str) == 'false' .or. trim(temp_str) == '0') then + create_fission_neutrons = .false. + end if + end if + end if + + ! Check for tabular_legendre options + if (check_for_node(doc, "tabular_legendre")) then + + ! Get pointer to tabular_legendre node + call get_node_ptr(doc, "tabular_legendre", node_tab_leg) + + ! Check for enable option + if (check_for_node(node_tab_leg, "enable")) then + call get_node_value(node_tab_leg, "enable", temp_str) + temp_str = to_lower(temp_str) + if (trim(temp_str) == 'false' .or. & + trim(temp_str) == '0') legendre_to_tabular = .false. + end if + + ! Check for the number of points + if (check_for_node(node_tab_leg, "num_points")) then + call get_node_value(node_tab_leg, "num_points", & + legendre_to_tabular_points) + if (legendre_to_tabular_points <= 1 .and. (.not. run_CE)) then + call fatal_error("The 'num_points' subelement/attribute of the & + &'tabular_legendre' element must contain a value greater than 1") + end if + end if + end if + ! Close settings XML file call close_xmldoc(doc) @@ -1366,11 +1422,7 @@ contains ! Read cell temperatures. If the temperature is not specified, set it to ! ERROR_REAL for now. During initialization we'll replace ERROR_REAL with ! the temperature from the material data. - if (.not. run_CE) then - ! Cell temperatures are not used for MG mode. - allocate(c % sqrtkT(1)) - c % sqrtkT(1) = ZERO - else if (check_for_node(node_cell, "temperature")) then + if (check_for_node(node_cell, "temperature")) then n = get_arraysize_double(node_cell, "temperature") if (n > 0) then ! Make sure this is a "normal" cell. @@ -2048,7 +2100,7 @@ contains if (run_CE) then call read_ce_cross_sections_xml(libraries) else - call read_mg_cross_sections_xml(libraries) + call read_mg_cross_sections_header(libraries) end if ! Creating dictionary that maps the name of the material to the entry @@ -2076,18 +2128,17 @@ contains call assign_temperatures(material_temps) ! Determine desired temperatures for each nuclide and S(a,b) table - call get_temperatures(nuc_temps, sab_temps) + call get_temperatures(cells, materials, material_dict, nuclide_dict, & + n_nuclides_total, nuc_temps, sab_dict, & + n_sab_tables, sab_temps) ! Read continuous-energy cross sections if (run_CE .and. run_mode /= MODE_PLOTTING) then - call time_read_xs%start() + call time_read_xs % start() call read_ce_cross_sections(libraries, library_dict, nuc_temps, sab_temps) - call time_read_xs%stop() + call time_read_xs % stop() end if - ! Normalize atom/weight percents - if (run_mode /= MODE_PLOTTING) call normalize_ao() - ! Clear dictionary call library_dict % clear() end subroutine read_materials @@ -3250,7 +3301,7 @@ contains ! Search through nuclides pair_list => nuclide_dict % keys() do while (associated(pair_list)) - if (starts_with(pair_list % key, word)) then + if (trim(pair_list % key) == trim(word)) then word = pair_list % key(1:150) exit end if @@ -4587,44 +4638,43 @@ contains end subroutine read_ce_cross_sections_xml - subroutine read_mg_cross_sections_xml(libraries) + subroutine read_mg_cross_sections_header(libraries) type(Library), allocatable, intent(out) :: libraries(:) integer :: i ! loop index integer :: n_libraries - logical :: file_exists ! does cross_sections.xml exist? - type(Node), pointer :: doc => null() - type(Node), pointer :: node_xsdata => null() - type(NodeList), pointer :: node_xsdata_list => null() + logical :: file_exists ! does mgxs.h5 exist? + integer(HID_T) :: file_id real(8), allocatable :: rev_energy_bins(:) + character(len=MAX_WORD_LEN), allocatable :: names(:) - ! Check if mgxs.xml exists + ! Check if MGXS Library exists inquire(FILE=path_cross_sections, EXIST=file_exists) if (.not. file_exists) then - ! Could not find mgxs.xml file - call fatal_error("Cross sections XML file '" & + ! Could not find MGXS Library file + call fatal_error("Cross sections HDF5 file '" & // trim(path_cross_sections) // "' does not exist!") end if - call write_message("Reading cross sections XML file...", 5) + call write_message("Reading cross sections HDF5 file...", 5) - ! Parse mgxs.xml file - call open_xmldoc(doc, path_cross_sections) + ! Open file for reading + file_id = file_open(path_cross_sections, 'r', parallel=.true.) - if (check_for_node(doc, "groups")) then + if (attribute_exists(file_id, "groups")) then ! Get neutron group count - call get_node_value(doc, "groups", energy_groups) + call read_attribute(energy_groups, file_id, "groups") else - call fatal_error("groups element must exist!") + call fatal_error("'groups' attribute must exist!") end if allocate(rev_energy_bins(energy_groups + 1)) allocate(energy_bins(energy_groups + 1)) - if (check_for_node(doc, "group_structure")) then + if (attribute_exists(file_id, "group structure")) then ! Get neutron group structure - call get_node_array(doc, "group_structure", energy_bins) + call read_attribute(energy_bins, file_id, "group structure") else - call fatal_error("group_structures element must exist!") + call fatal_error("'group structure' attribute must exist!") end if ! First reverse the order of energy_groups @@ -4635,45 +4685,28 @@ contains energy_bin_avg(i) = HALF * (energy_bins(i) + energy_bins(i + 1)) end do - allocate(inverse_velocities(energy_groups)) - if (check_for_node(doc, "inverse_velocities")) then - ! Get inverse velocities - call get_node_array(doc, "inverse_velocities", inverse_velocities) - else - ! If not given, estimate them by using average energy in group which is - ! assumed to be the midpoint - do i = 1, energy_groups - inverse_velocities(i) = ONE / & - (sqrt(TWO * energy_bin_avg(i) / (MASS_NEUTRON_MEV)) * & - C_LIGHT * 100.0_8) - end do - end if + ! Get the datasets present in the library + call get_groups(file_id, names) + n_libraries = size(names) - ! Get node list of all - call get_node_list(doc, "xsdata", node_xsdata_list) - n_libraries = get_list_size(node_xsdata_list) - - ! Allocate xs_listings array + ! Allocate libraries array if (n_libraries == 0) then - call fatal_error("At least one element must be present in & - &mgxs.xml file!") + call fatal_error("At least one MGXS data set must be present in & + &mgxs library file!") else allocate(libraries(n_libraries)) end if do i = 1, n_libraries - ! Get pointer to xsdata table XML node - call get_list_item(node_xsdata_list, i, node_xsdata) - ! Get name of material allocate(libraries(i) % materials(1)) - call get_node_value(node_xsdata, "name", libraries(i) % materials(1)) + libraries(i) % materials(1) = names(i) end do - ! Close cross sections XML file - call close_xmldoc(doc) + ! Close MGXS HDF5 file + call file_close(file_id) - end subroutine read_mg_cross_sections_xml + end subroutine read_mg_cross_sections_header !=============================================================================== ! EXPAND_NATURAL_ELEMENT converts natural elements specified using an @@ -5618,7 +5651,7 @@ contains if (run_CE) then awr = nuclides(mat % nuclide(j)) % awr else - awr = ONE + awr = nuclides_MG(mat % nuclide(j)) % obj % awr end if ! if given weight percent, convert all values so that they are divided @@ -5643,7 +5676,7 @@ contains if (run_CE) then awr = nuclides(mat % nuclide(j)) % awr else - awr = ONE + awr = nuclides_MG(mat % nuclide(j)) % obj % awr end if x = mat % atom_density(j) sum_percent = sum_percent + x*awr @@ -5906,67 +5939,6 @@ contains end do end subroutine assign_temperatures -!=============================================================================== -! GET_TEMPERATURES returns a list of temperatures that each nuclide/S(a,b) table -! appears at in the model. Later, this list is used to determine the actual -! temperatures to read (which may be different if interpolation is used) -!=============================================================================== - - subroutine get_temperatures(nuc_temps, sab_temps) - type(VectorReal), allocatable, intent(out) :: nuc_temps(:) - type(VectorReal), allocatable, intent(out) :: sab_temps(:) - - integer :: i, j, k - integer :: i_nuclide ! index in nuclides array - integer :: i_sab ! index in S(a,b) array - integer :: i_material - real(8) :: temperature ! temperature in Kelvin - - allocate(nuc_temps(n_nuclides_total)) - allocate(sab_temps(n_sab_tables)) - - do i = 1, size(cells) - do j = 1, size(cells(i) % material) - ! Skip any non-material cells and void materials - if (cells(i) % material(j) == NONE .or. & - cells(i) % material(j) == MATERIAL_VOID) cycle - - ! Get temperature of cell (rounding to nearest integer) - if (size(cells(i) % sqrtkT) > 1) then - temperature = cells(i) % sqrtkT(j)**2 / K_BOLTZMANN - else - temperature = cells(i) % sqrtkT(1)**2 / K_BOLTZMANN - end if - - i_material = material_dict % get_key(cells(i) % material(j)) - associate (mat => materials(i_material)) - NUC_NAMES_LOOP: do k = 1, size(mat % names) - ! Get index in nuc_temps array - i_nuclide = nuclide_dict % get_key(to_lower(mat % names(k))) - - ! Add temperature if it hasn't already been added - if (find(nuc_temps(i_nuclide), temperature) == -1) then - call nuc_temps(i_nuclide) % push_back(temperature) - end if - end do NUC_NAMES_LOOP - - if (mat % n_sab > 0) then - SAB_NAMES_LOOP: do k = 1, size(mat % sab_names) - ! Get index in nuc_temps array - i_sab = sab_dict % get_key(to_lower(mat % sab_names(k))) - - ! Add temperature if it hasn't already been added - if (find(sab_temps(i_sab), temperature) == -1) then - call sab_temps(i_sab) % push_back(temperature) - end if - end do SAB_NAMES_LOOP - end if - end associate - end do - end do - - end subroutine get_temperatures - !=============================================================================== ! READ_0K_ELASTIC_SCATTERING !=============================================================================== diff --git a/src/mgxs_data.F90 b/src/mgxs_data.F90 index 05d6eb5ec6..857b2ded05 100644 --- a/src/mgxs_data.F90 +++ b/src/mgxs_data.F90 @@ -1,15 +1,17 @@ module mgxs_data -use constants + use constants + use algorithm, only: find use error, only: fatal_error + use geometry_header, only: get_temperatures use global + use hdf5_interface use material_header, only: Material use mgxs_header use output, only: write_message use set_header, only: SetChar + use stl_vector, only: VectorReal use string, only: to_lower - use xml_interface - implicit none contains @@ -20,52 +22,41 @@ contains !=============================================================================== subroutine read_mgxs() - integer :: i ! index in materials array integer :: j ! index over nuclides in material - integer :: i_xsdata ! index in list - integer :: i_nuclide ! index in nuclides - character(20) :: name ! name of isotope, e.g. 92235.03c + integer :: i_xsdata ! index in xsdata_dict + integer :: i_nuclide ! index in nuclides array + character(20) :: name ! name of library to load integer :: representation ! Data representation - type(Material), pointer :: mat - type(SetChar) :: already_read - type(Node), pointer :: doc => null() - type(Node), pointer :: node_xsdata - type(NodeList), pointer :: node_xsdata_list => null() - logical :: file_exists character(MAX_LINE_LEN) :: temp_str + type(Material), pointer :: mat + type(SetChar) :: already_read + integer(HID_T) :: file_id + integer(HID_T) :: xsdata_group + logical :: file_exists logical :: get_kfiss, get_fiss integer :: l type(DictCharInt) :: xsdata_dict + type(VectorReal), allocatable :: temps(:) - ! Check if cross_sections.xml exists + ! Check if MGXS Library exists inquire(FILE=path_cross_sections, EXIST=file_exists) if (.not. file_exists) then - ! Could not find cross_sections.xml file - call fatal_error("Cross sections XML file '" & + ! Could not find MGXS Library file + call fatal_error("Cross sections HDF5 file '" & &// trim(path_cross_sections) // "' does not exist!") end if call write_message("Loading Cross Section Data...", 5) - ! Parse cross_sections.xml file - call open_xmldoc(doc, path_cross_sections) + ! Get temperatures + call get_temperatures(cells, materials, material_dict, nuclide_dict, & + n_nuclides_total, temps) - ! Get node list of all - call get_node_list(doc, "xsdata", node_xsdata_list) + ! Open file for reading + file_id = file_open(path_cross_sections, 'r', parallel=.true.) - ! Build dictionary mapping nuclide names to an index in the node - ! list - do i = 1, get_list_size(node_xsdata_list) - ! Get pointer to xsdata table XML node - call get_list_item(node_xsdata_list, i, node_xsdata) - - ! Get name and create pair (name, i) - call get_node_value(node_xsdata, "name", name) - call xsdata_dict % add_key(to_lower(name), i) - end do - - ! allocate arrays for ACE table storage and cross section cache + ! allocate arrays for MGXS storage and cross section cache allocate(nuclides_MG(n_nuclides_total)) !$omp parallel allocate(micro_xs(n_nuclides_total)) @@ -102,18 +93,22 @@ contains i_xsdata = xsdata_dict % get_key(to_lower(name)) i_nuclide = mat % nuclide(j) - ! Get pointer to xsdata table XML node - call get_list_item(node_xsdata_list, i_xsdata, node_xsdata) - call write_message("Loading " // trim(name) // " Data...", 5) + ! Check to make sure cross section set exists in the library + if (object_exists(file_id, trim(name))) then + xsdata_group = open_group(file_id, trim(name)) + else + call fatal_error("Data for '" // trim(name) // "' does not exist in "& + &// trim(path_cross_sections)) + end if + ! First find out the data representation - if (check_for_node(node_xsdata, "representation")) then - call get_node_value(node_xsdata, "representation", temp_str) - temp_str = trim(to_lower(temp_str)) - if (temp_str == 'isotropic' .or. temp_str == 'iso') then + if (attribute_exists(xsdata_group, "representation")) then + call read_attribute(temp_str, xsdata_group, "representation") + if (trim(temp_str) == 'isotropic') then representation = MGXS_ISOTROPIC - else if (temp_str == 'angle') then + else if (trim(temp_str) == 'angle') then representation = MGXS_ANGLE else call fatal_error("Invalid Data Representation!") @@ -132,8 +127,10 @@ contains end select ! Now read in the data specific to the type we just declared - call nuclides_MG(i_nuclide) % obj % init_file(node_xsdata, & - energy_groups, get_kfiss, get_fiss, max_order) + call nuclides_MG(i_nuclide) % obj % from_hdf5(xsdata_group, & + energy_groups, temps(i_nuclide), temperature_method, & + temperature_tolerance, get_kfiss, get_fiss, max_order, & + legendre_to_tabular, legendre_to_tabular_points) ! Add name to dictionary call already_read % add(name) @@ -172,28 +169,74 @@ contains subroutine create_macro_xs() integer :: i_mat ! index in materials array type(Material), pointer :: mat ! current material - integer :: scatt_type + type(VectorReal), allocatable :: kTs(:) allocate(macro_xs(n_materials)) + ! Get temperatures to read for each material + call get_mat_kTs(kTs) + do i_mat = 1, n_materials mat => materials(i_mat) ! Check to see how our nuclides are represented ! Force all to be the same type ! Therefore type(nuclides(mat % nuclide(1)) % obj) dictates type(macroxs) - ! At the same time, we will find the scattering type, as that will dictate - ! how we allocate the scatter object within macroxs - scatt_type = nuclides_MG(mat % nuclide(1)) % obj % scatt_type select type(nuc => nuclides_MG(mat % nuclide(1)) % obj) type is (MgxsIso) allocate(MgxsIso :: macro_xs(i_mat) % obj) type is (MgxsAngle) allocate(MgxsAngle :: macro_xs(i_mat) % obj) end select - call macro_xs(i_mat) % obj % combine(mat, nuclides_MG, energy_groups, & - max_order, scatt_type) + ! Do not read materials which we do not actually use in the problem to + ! save space + if (allocated(kTs(i_mat) % data)) then + call macro_xs(i_mat) % obj % combine(kTs(i_mat), mat, nuclides_MG, & + energy_groups, max_order, & + temperature_tolerance, & + temperature_method) + end if end do end subroutine create_macro_xs +!=============================================================================== +! GET_MAT_kTs returns a list of temperatures (in MeV) that each +! material appears at in the model. +!=============================================================================== + + subroutine get_mat_kTs(kTs) + type(VectorReal), allocatable, intent(out) :: kTs(:) + + integer :: i, j + integer :: i_material ! Index in materials array + real(8) :: kT ! temperature in MeV + + allocate(kTs(size(materials))) + + do i = 1, size(cells) + do j = 1, size(cells(i) % material) + ! Skip any non-material cells and void materials + if (cells(i) % material(j) == NONE .or. & + cells(i) % material(j) == MATERIAL_VOID) cycle + + ! Get temperature of cell (rounding to nearest integer) + if (size(cells(i) % sqrtkT) > 1) then + kT = cells(i) % sqrtkT(j)**2 + else + kT = cells(i) % sqrtkT(1)**2 + end if + + i_material = material_dict % get_key(cells(i) % material(j)) + + ! Add temperature if it hasn't already been added + if (find(kTs(i_material), kT) == -1) then + call kTs(i_material) % push_back(kT) + end if + + end do + end do + + end subroutine get_mat_kTs + + end module mgxs_data diff --git a/src/mgxs_header.F90 b/src/mgxs_header.F90 index 9409398b3e..feb4d46a89 100644 --- a/src/mgxs_header.F90 +++ b/src/mgxs_header.F90 @@ -1,41 +1,78 @@ module mgxs_header - use constants, only: MAX_FILE_LEN, ZERO, ONE, TWO, PI + use, intrinsic :: ISO_FORTRAN_ENV + use, intrinsic :: ISO_C_BINDING + + use hdf5, only: HID_T, HSIZE_T, SIZE_T + + use algorithm, only: find, sort + use constants, only: MAX_WORD_LEN, ZERO, ONE, TWO, PI use error, only: fatal_error - use, intrinsic :: ISO_FORTRAN_ENV, only: OUTPUT_UNIT - use list_header, only: ListInt + use hdf5_interface use material_header, only: material - use math, only: calc_pn, calc_rn, expand_harmonic, & - evaluate_legendre + use math, only: evaluate_legendre use nuclide_header, only: MaterialMacroXS use random_lcg, only: prn use scattdata_header use string - use xml_interface + use stl_vector, only: VectorInt, VectorReal + +!=============================================================================== +! XS* contains the temperature-dependent cross section data for an MGXS +!=============================================================================== + + type :: XsDataIso + ! Microscopic cross sections + real(8), allocatable :: total(:) ! total cross section + real(8), allocatable :: absorption(:) ! absorption cross section + class(ScattData), allocatable :: scatter ! scattering info + real(8), allocatable :: nu_fission(:) ! fission production + real(8), allocatable :: k_fission(:) ! kappa-fission + real(8), allocatable :: fission(:) ! fission + real(8), allocatable :: chi(:, :) ! Fission Spectra + real(8), allocatable :: inv_vel(:) ! Inverse velocities + end type XsDataIso + + type :: XsDataAngle + ! Microscopic cross sections + ! In all cases, right-most indices are theta, phi + real(8), allocatable :: total(:, :, :) ! total cross section + real(8), allocatable :: absorption(:, :, :) ! absorption cross section + type(ScattDataContainer), allocatable :: scatter(:, :) ! scattering info + real(8), allocatable :: nu_fission(:, :, :) ! fission production + real(8), allocatable :: k_fission(:, :, :) ! kappa-fission + real(8), allocatable :: fission(:, :, :) ! fission + real(8), allocatable :: chi(:, :, :, :) ! Fission Spectra + real(8), allocatable :: inv_vel(:, :, :) ! Inverse velocities + end type XsDataAngle !=============================================================================== ! MGXS contains the base mgxs data for a nuclide/material !=============================================================================== type, abstract :: Mgxs - character(len=104) :: name ! name of dataset, e.g. 92235.03c - real(8) :: awr ! Atomic Weight Ratio - real(8) :: kT ! temperature in MeV (k*T) + character(len=MAX_WORD_LEN) :: name ! name of dataset, e.g. UO2 + real(8) :: awr ! Atomic Weight Ratio + real(8), allocatable :: kTs(:) ! temperature in MeV (k*T) ! Fission information - logical :: fissionable ! mgxs object is fissionable? - integer :: scatt_type ! either legendre, histogram, or tabular. + logical :: fissionable ! mgxs object is fissionable? + integer :: scatter_format ! either legendre, histogram, or tabular. + + ! Caching information + integer :: index_temp ! temperature index for nuclide contains - procedure(mgxs_init_file_), deferred :: init_file ! Initialize the data - procedure(mgxs_get_xs_), deferred :: get_xs ! Get the requested xs + procedure(mgxs_from_hdf5_), deferred :: from_hdf5 ! Load the data procedure(mgxs_combine_), deferred :: combine ! initializes object + procedure(mgxs_get_xs_), deferred :: get_xs ! Get the requested xs ! Sample the outgoing energy from a fission event procedure(mgxs_sample_fission_), deferred :: sample_fission_energy ! Sample the outgoing energy and angle from a scatter event procedure(mgxs_sample_scatter_), deferred :: sample_scatter ! Calculate the material specific MGXS data from the nuclides procedure(mgxs_calculate_xs_), deferred :: calculate_xs + procedure :: find_temperature => mgxs_find_temperature end type Mgxs !=============================================================================== @@ -51,18 +88,38 @@ module mgxs_header !=============================================================================== abstract interface - subroutine mgxs_init_file_(this, node_xsdata, groups, get_kfiss, get_fiss, & - max_order) - import Mgxs, Node - class(Mgxs), intent(inout) :: this ! Working Object - type(Node), pointer, intent(in) :: node_xsdata ! Data from MGXS xml - integer, intent(in) :: groups ! Number of Energy groups - logical, intent(in) :: get_kfiss ! Need Kappa-Fission? - logical, intent(in) :: get_fiss ! Should we get fiss data? - integer, intent(in) :: max_order ! Maximum requested order - end subroutine mgxs_init_file_ + subroutine mgxs_from_hdf5_(this, xs_id, groups, temperature, method, & + tolerance, get_kfiss, get_fiss, max_order, & + legendre_to_tabular, legendre_to_tabular_points) + import Mgxs, HID_T, VectorReal + class(Mgxs), intent(inout) :: this ! Working Object + integer(HID_T), intent(in) :: xs_id ! Library data + integer, intent(in) :: groups ! Number of Energy groups + type(VectorReal), intent(in) :: temperature ! list of desired temperatures + integer, intent(inout) :: method ! Type of temperature access + real(8), intent(in) :: tolerance ! Tolerance on method + logical, intent(in) :: get_kfiss ! Need Kappa-Fission? + logical, intent(in) :: get_fiss ! Should we get fiss data? + integer, intent(in) :: max_order ! Maximum requested order + logical, intent(in) :: legendre_to_tabular ! Convert Legendres to Tabular? + integer, intent(in) :: legendre_to_tabular_points ! Number of points to use + ! in that conversion + end subroutine mgxs_from_hdf5_ - pure function mgxs_get_xs_(this,xstype,gin,gout,uvw,mu) result(xs) + subroutine mgxs_combine_(this, temps, mat, nuclides, groups, max_order, & + tolerance, method) + import Mgxs, Material, MgxsContainer, VectorReal + class(Mgxs), intent(inout) :: this ! The Mgxs to initialize + type(VectorReal), intent(in) :: temps ! Temperatures to obtain + type(Material), pointer, intent(in) :: mat ! base material + type(MgxsContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from + integer, intent(in) :: groups ! Number of E groups + integer, intent(in) :: max_order ! Maximum requested order + real(8), intent(in) :: tolerance ! Tolerance on method + integer, intent(in) :: method ! Type of temperature access + end subroutine mgxs_combine_ + + pure function mgxs_get_xs_(this, xstype, gin, gout, uvw, mu) result(xs_val) import Mgxs class(Mgxs), intent(in) :: this character(*), intent(in) :: xstype ! Cross Section Type @@ -70,35 +127,12 @@ module mgxs_header integer, optional, intent(in) :: gout ! Outgoing Group real(8), optional, intent(in) :: uvw(3) ! Requested Angle real(8), optional, intent(in) :: mu ! Change in angle - real(8) :: xs ! Resultant xs + real(8) :: xs_val ! Resultant xs end function mgxs_get_xs_ - pure function mgxs_calc_f_(this,gin,gout,mu,uvw,iazi,ipol) result(f) - import Mgxs - class(Mgxs), intent(in) :: this - integer, intent(in) :: gin ! Incoming Energy Group - integer, intent(in) :: gout ! Outgoing Energy Group - real(8), intent(in) :: mu ! Angle of interest - real(8), intent(in), optional :: uvw(3) ! Direction vector - integer, intent(in), optional :: iazi ! Incoming Energy Group - integer, intent(in), optional :: ipol ! Outgoing Energy Group - real(8) :: f ! Return value of f(mu) - - end function mgxs_calc_f_ - - subroutine mgxs_combine_(this, mat, nuclides, groups, max_order, scatt_type) - import Mgxs, Material, MgxsContainer - class(Mgxs), intent(inout) :: this ! The Mgxs to initialize - type(Material), pointer, intent(in) :: mat ! base material - type(MgxsContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from - integer, intent(in) :: groups ! Number of E groups - integer, intent(in) :: max_order ! Maximum requested order - integer, intent(in) :: scatt_type ! Legendre or Tabular Scatt? - end subroutine mgxs_combine_ - function mgxs_sample_fission_(this, gin, uvw) result(gout) import Mgxs - class(Mgxs), intent(in) :: this ! Data to work with + class(Mgxs), intent(in) :: this integer, intent(in) :: gin ! Incoming energy group real(8), intent(in) :: uvw(3) ! Particle Direction integer :: gout ! Sampled outgoing group @@ -107,7 +141,7 @@ module mgxs_header subroutine mgxs_sample_scatter_(this, uvw, gin, gout, mu, wgt) import Mgxs - class(Mgxs), intent(in) :: this + class(Mgxs), intent(in) :: this real(8), intent(in) :: uvw(3) ! Incoming neutron direction integer, intent(in) :: gin ! Incoming neutron group integer, intent(out) :: gout ! Sampled outgoin group @@ -130,18 +164,9 @@ module mgxs_header !=============================================================================== type, extends(Mgxs) :: MgxsIso - - ! Microscopic cross sections - real(8), allocatable :: total(:) ! total cross section - real(8), allocatable :: absorption(:) ! absorption cross section - class(ScattData), allocatable :: scatter ! scattering information - real(8), allocatable :: nu_fission(:) ! fission matrix (Gout x Gin) - real(8), allocatable :: k_fission(:) ! kappa-fission - real(8), allocatable :: fission(:) ! neutron production - real(8), allocatable :: chi(:, :) ! Fission Spectra - + type(XsDataIso), allocatable :: xs(:) ! One for every temperature contains - procedure :: init_file => mgxsiso_init_file ! Initialize Nuclidic MGXS Data + procedure :: from_hdf5 => mgxsiso_from_hdf5 ! Initialize Nuclidic MGXS Data procedure :: get_xs => mgxsiso_get_xs ! Gets Size of Data w/in Object procedure :: combine => mgxsiso_combine ! inits object procedure :: sample_fission_energy => mgxsiso_sample_fission_energy @@ -155,23 +180,14 @@ module mgxs_header !=============================================================================== type, extends(Mgxs) :: MgxsAngle - - ! Microscopic cross sections - real(8), allocatable :: total(:, :, :) ! total cross section - real(8), allocatable :: absorption(:, :, :) ! absorption cross section - type(ScattDataContainer), allocatable :: scatter(:, :) ! scattering information - real(8), allocatable :: nu_fission(:, :, :) ! fission matrix (Gout x Gin) - real(8), allocatable :: k_fission(:, :, :) ! kappa-fission - real(8), allocatable :: fission(:, :, :) ! neutron production - real(8), allocatable :: chi(:, :, :, :) ! Fission Spectra - ! In all cases, right-most indices are theta, phi - integer :: n_pol ! Number of polar angles - integer :: n_azi ! Number of azimuthal angles - real(8), allocatable :: polar(:) ! polar angles - real(8), allocatable :: azimuthal(:) ! azimuthal angles + type(XsDataAngle), allocatable :: xs(:) ! One for every temperature + integer :: n_pol ! Number of polar angles + integer :: n_azi ! Number of azimuthal angles + real(8), allocatable :: polar(:) ! polar angles + real(8), allocatable :: azimuthal(:) ! azimuthal angles contains - procedure :: init_file => mgxsang_init_file ! Initialize Nuclidic MGXS Data + procedure :: from_hdf5 => mgxsang_from_hdf5 ! Initialize Nuclidic MGXS Data procedure :: get_xs => mgxsang_get_xs ! Gets Size of Data w/in Object procedure :: combine => mgxsang_combine ! inits object procedure :: sample_fission_energy => mgxsang_sample_fission_energy @@ -182,1046 +198,1032 @@ module mgxs_header contains !=============================================================================== -! MGXS*_INIT reads in the data from the XML file. At the point of entry -! the file would have been opened and metadata read. This routine begins with -! the xsdata object node itself. +! MGXS*_FROM_HDF5 reads in the data from the HDF5 Library. At the point of entry +! the file would have been opened and metadata read. !=============================================================================== - subroutine mgxs_init_file(this, node_xsdata) - class(Mgxs), intent(inout) :: this ! Working Object - type(Node), pointer, intent(in) :: node_xsdata ! Data from MGXS xml + subroutine mgxs_from_hdf5(this, xs_id, temperature, method, tolerance, & + temps_to_read, order_dim) + class(Mgxs), intent(inout) :: this ! Working Object + integer(HID_T), intent(in) :: xs_id ! Group in H5 file + type(VectorReal), intent(in) :: temperature ! list of desired temperatures + integer, intent(inout) :: method ! Type of temperature access + real(8), intent(in) :: tolerance ! Tolerance on method + type(VectorInt), intent(out) :: temps_to_read ! Temperatures to read + integer, intent(out) :: order_dim ! Scattering data order size - character(MAX_LINE_LEN) :: temp_str + integer(SIZE_T) :: name_len + integer(HID_T) :: kT_group + character(MAX_WORD_LEN), allocatable :: dset_names(:) + real(8), allocatable :: temps_available(:) ! temperatures available + real(8) :: temp_desired + real(8) :: temp_actual + character(MAX_WORD_LEN) :: temp_str + real(8) :: dangle + integer :: ipol, iazi - ! Load the nuclide metadata - call get_node_value(node_xsdata, "name", this % name) - this % name = to_lower(this % name) - if (check_for_node(node_xsdata, "kT")) then - call get_node_value(node_xsdata, "kT", this % kT) - else - this % kT = ZERO - end if - if (check_for_node(node_xsdata, "awr")) then - call get_node_value(node_xsdata, "awr", this % awr) + ! Get name of dataset from group + name_len = len(this % name) + this % name = get_name(xs_id, name_len) + + ! Get rid of leading '/' + this % name = trim(this % name(2:)) + + if (attribute_exists(xs_id, "atomic_weight_ratio")) then + call read_attribute(this % awr, xs_id, "atomic_weight_ratio") else this % awr = -ONE end if - if (check_for_node(node_xsdata, "scatt_type")) then - call get_node_value(node_xsdata, "scatt_type", temp_str) - temp_str = trim(to_lower(temp_str)) - if (temp_str == 'legendre') then - this % scatt_type = ANGLE_LEGENDRE - else if (temp_str == 'histogram') then - this % scatt_type = ANGLE_HISTOGRAM - else if (temp_str == 'tabular') then - this % scatt_type = ANGLE_TABULAR - else - call fatal_error("Invalid scatt_type option!") - end if - else - this % scatt_type = ANGLE_LEGENDRE + + ! Determine temperatures available + kT_group = open_group(xs_id, 'kTs') + call get_datasets(kT_group, dset_names) + allocate(temps_available(size(dset_names))) + do i = 1, size(dset_names) + ! Read temperature value + call read_dataset(temps_available(i), kT_group, trim(dset_names(i))) + ! Convert MeV to Kelvin + temps_available(i) = temps_available(i) / K_BOLTZMANN + end do + call sort(temps_available) + + ! If only one temperature is available, revert to nearest temperature + if (size(temps_available) == 1 .and. & + method == TEMPERATURE_INTERPOLATION) then + call warning("Cross sections for " // trim(this % name) // " are only & + &available at one temperature. Reverting to nearest temperature & + &method.") + method = TEMPERATURE_NEAREST end if - if (check_for_node(node_xsdata, "fissionable")) then - call get_node_value(node_xsdata, "fissionable", temp_str) - temp_str = to_lower(temp_str) - if (trim(temp_str) == 'true' .or. trim(temp_str) == '1') then - this % fissionable = .true. + select case (method) + case (TEMPERATURE_NEAREST) + ! Determine actual temperatures to read + TEMP_LOOP: do i = 1, temperature % size() + temp_desired = temperature % data(i) + i_closest = minloc(abs(temps_available - temp_desired), dim=1) + temp_actual = temps_available(i_closest) + if (abs(temp_actual - temp_desired) < tolerance) then + if (find(temps_to_read, nint(temp_actual)) == -1) then + call temps_to_read % push_back(nint(temp_actual)) + end if + else + call fatal_error("MGXS library does not contain cross sections & + &for " // trim(this % name) // " at or near " // & + trim(to_str(nint(temp_desired))) // " K.") + end if + end do TEMP_LOOP + + case (TEMPERATURE_INTERPOLATION) + ! If temperature interpolation or multipole is selected, get a list of + ! bounding temperatures for each actual temperature present in the model + TEMPS_LOOP: do i = 1, temperature % size() + temp_desired = temperature % data(i) + + do j = 1, size(temps_available) - 1 + if (temps_available(j) <= temp_desired .and. & + temp_desired < temps_available(j + 1)) then + if (find(temps_to_read, nint(temps_available(j))) == -1) then + call temps_to_read % push_back(nint(temps_available(j))) + end if + if (find(temps_to_read, nint(temps_available(j + 1))) == -1) then + call temps_to_read % push_back(nint(temps_available(j + 1))) + end if + cycle TEMPS_LOOP + end if + end do + + call fatal_error("MGXS library does not contain cross sections & + &for " // trim(this % name) // " at temperatures that bound " // & + trim(to_str(nint(temp_desired))) // " K.") + end do TEMPS_LOOP + end select + + ! Sort temperatures to read + call sort(temps_to_read) + + ! Get temperatures + n_temperature = temps_to_read % size() + allocate(this % kTs(n_temperature)) + do i = 1, n_temperature + ! Get temperature as a string + temp_str = trim(to_str(temps_to_read % data(i))) // "K" + + ! Read exact temperature value + call read_dataset(this % kTs(i), kT_group, trim(temp_str)) + end do + call close_group(kT_group) + + ! Allocate the XS object for the number of temperatures + select type(this) + type is (MgxsIso) + allocate(this % xs(n_temperature)) + type is (MgxsAngle) + allocate(this % xs(n_temperature)) + end select + + ! Load the remaining metadata + if (attribute_exists(xs_id, "scatter_format")) then + call read_attribute(temp_str, xs_id, "scatter_format") + temp_str = trim(temp_str) + if (to_lower(temp_str) == 'legendre') then + this % scatter_format = ANGLE_LEGENDRE + else if (to_lower(temp_str) == 'histogram') then + this % scatter_format = ANGLE_HISTOGRAM + else if (to_lower(temp_str) == 'tabular') then + this % scatter_format = ANGLE_TABULAR else - this % fissionable = .false. + call fatal_error("Invalid scatter_format option!") end if + else + this % scatter_format = ANGLE_LEGENDRE + end if + if (attribute_exists(xs_id, "scatter_shape")) then + call read_attribute(temp_str, xs_id, "scatter_shape") + temp_str = trim(temp_str) + if (to_lower(temp_str) /= "[order][g][g']") then + call fatal_error("Invalid scatter_shape option!") + end if + end if + if (attribute_exists(xs_id, "fissionable")) then + call read_attribute(this % fissionable, xs_id, "fissionable") else call fatal_error("Fissionable element must be set!") end if - end subroutine mgxs_init_file - - subroutine mgxsiso_init_file(this, node_xsdata, groups, get_kfiss, get_fiss, & - max_order) - class(MgxsIso), intent(inout) :: this ! Working Object - type(Node), pointer, intent(in) :: node_xsdata ! Data from MGXS xml - integer, intent(in) :: groups ! Number of Energy groups - logical, intent(in) :: get_kfiss ! Need Kappa-Fission? - logical, intent(in) :: get_fiss ! Need fiss data? - integer, intent(in) :: max_order ! Maximum requested order - - type(Node), pointer :: node_legendre_mu - character(MAX_LINE_LEN) :: temp_str - logical :: enable_leg_mu - real(8), allocatable :: temp_arr(:), temp_2d(:, :) - real(8), allocatable :: temp_mult(:, :) - real(8), allocatable :: scatt_coeffs(:, :, :) - real(8), allocatable :: input_scatt(:, :, :) - real(8), allocatable :: temp_scatt(:, :, :) - real(8) :: dmu, mu, norm - integer :: order, order_dim, gin, gout, l, arr_len - integer :: legendre_mu_points, imu - - ! Call generic data gathering routine (will populate the metadata) - call mgxs_init_file(this, node_xsdata) - - ! Load the more specific data - allocate(this % nu_fission(groups)) - allocate(this % chi(groups,groups)) - if (this % fissionable) then - if (check_for_node(node_xsdata, "chi")) then - ! Chi was provided, that means they are giving chi and nu-fission - ! vectors - ! Get chi - allocate(temp_arr(groups)) - call get_node_array(node_xsdata, "chi", temp_arr) - do gin = 1, groups - do gout = 1, groups - this % chi(gout, gin) = temp_arr(gout) - end do - ! Normalize chi so its CDF goes to 1 - this % chi(:, gin) = this % chi(:, gin) / sum(this % chi(:, gin)) - end do - deallocate(temp_arr) - - ! Get nu_fission (as a vector) - if (check_for_node(node_xsdata, "nu_fission")) then - call get_node_array(node_xsdata, "nu_fission", this % nu_fission) - else - call fatal_error("If fissionable, must provide nu_fission!") - end if - - else - ! chi isnt provided but is within nu_fission, existing as a matrix - ! So, get nu_fission (as a matrix) - if (check_for_node(node_xsdata, "nu_fission")) then - allocate(temp_arr(groups*groups)) - call get_node_array(node_xsdata, "nu_fission", temp_arr) - allocate(temp_2d(groups, groups)) - temp_2d = reshape(temp_arr, (/groups, groups/)) - deallocate(temp_arr) - else - call fatal_error("If fissionable, must provide nu_fission!") - end if - - ! Set the vector nu-fission from the matrix nu-fission - do gin = 1, groups - this % nu_fission(gin) = sum(temp_2d(:, gin)) - end do - - ! Now pull out information needed for chi - this % chi(:, :) = temp_2d - ! Normalize chi so its CDF goes to 1 - do gin = 1, groups - this % chi(:, gin) = this % chi(:, gin) / sum(this % chi(:, gin)) - end do - deallocate(temp_2d) - end if - ! If we have a need* for the fission and kappa-fission x/s, get them - ! (*Need is defined as will be using it to tally) - if (get_fiss) then - allocate(this % fission(groups)) - if (check_for_node(node_xsdata, "fission")) then - call get_node_array(node_xsdata, "fission", this % fission) - else - call fatal_error("Fission data missing, required due to fission& - & tallies in tallies.xml file!") - end if - end if - if (get_kfiss) then - allocate(this % k_fission(groups)) - if (check_for_node(node_xsdata, "kappa_fission")) then - call get_node_array(node_xsdata, "kappa_fission", this % k_fission) - else - call fatal_error("kappa_fission data missing, required due to & - &kappa-fission tallies in tallies.xml file!") - end if - end if - else - this % nu_fission = ZERO - this % chi = ZERO - end if - - allocate(this % absorption(groups)) - if (check_for_node(node_xsdata, "absorption")) then - call get_node_array(node_xsdata, "absorption", this % absorption) - else - call fatal_error("Must provide absorption!") - end if - - ! Get multiplication data if present - allocate(temp_mult(groups, groups)) - if (check_for_node(node_xsdata, "multiplicity")) then - arr_len = get_arraysize_double(node_xsdata, "multiplicity") - if (arr_len == groups * groups) then - allocate(temp_arr(arr_len)) - call get_node_array(node_xsdata, "multiplicity", temp_arr) - temp_mult(:, :) = reshape(temp_arr, (/groups, groups/)) - deallocate(temp_arr) - else - call fatal_error("Multiplicity length not same as number of groups& - & squared!") - end if - else - temp_mult(:, :) = ONE - end if - - ! Get scattering treatment information - ! Tabular_legendre tells us if we are to treat the provided - ! Legendre polynomials as tabular data (if enable is true, default) - ! or leaving them as Legendres (if enable is false) - - ! Set the default (Convert to tabular format w/ 33 points) - enable_leg_mu = .true. - legendre_mu_points = 33 - ! Get the user-provided values - if (check_for_node(node_xsdata, "tabular_legendre")) then - call get_node_ptr(node_xsdata, "tabular_legendre", node_legendre_mu) - if (check_for_node(node_legendre_mu, "enable")) then - call get_node_value(node_legendre_mu, "enable", temp_str) - temp_str = trim(to_lower(temp_str)) - if (temp_str == 'true' .or. temp_str == '1') then - enable_leg_mu = .true. - elseif (temp_str == 'false' .or. temp_str == '0') then - enable_leg_mu = .false. - else - call fatal_error("Unrecognized tabular_legendre/enable: " & - // temp_str) - end if - end if - ! Ok, so if we need to convert to a tabular form, get the user provided - ! number of points - if (enable_leg_mu) then - if (check_for_node(node_legendre_mu, "num_points")) then - call get_node_value(node_legendre_mu, "num_points", & - legendre_mu_points) - if (legendre_mu_points <= 0) & - call fatal_error("num_points element must be positive& - & and non-zero!") - else - ! Set the default number of points (0.0625 spacing) - legendre_mu_points = 33 - end if - end if - end if - ! Get the library's value for the order - if (check_for_node(node_xsdata, "order")) then - call get_node_value(node_xsdata, "order", order) + if (attribute_exists(xs_id, "order")) then + call read_attribute(order_dim, xs_id, "order") else call fatal_error("Order must be provided!") end if - ! Before retrieving the data, store the dimensionality of the data in - ! order_dim. For Legendre data, we usually refer to it as Pn where - ! n is the order. However Pn has n+1 sets of points (since you need to + ! Store the dimensionality of the data in order_dim. + ! For Legendre data, we usually refer to it as Pn where n is the order. + ! However Pn has n+1 sets of points (since you need to ! the count the P0 moment). Adjust for that. Histogram and Tabular ! formats dont need this adjustment. - if (this % scatt_type == ANGLE_LEGENDRE) then - order_dim = order + 1 + if (this % scatter_format == ANGLE_LEGENDRE) then + order_dim = order_dim + 1 else - order_dim = order + order_dim = order_dim end if - ! The input is gathered in the more user-friendly facing format of - ! Gout x Gin x Order. We will get it in that format in input_scatt, - ! but then need to convert it to a more useful ordering for processing - ! (Order x Gout x Gin). - allocate(input_scatt(groups, groups, order_dim)) - if (check_for_node(node_xsdata, "scatter")) then - allocate(temp_arr(groups * groups * order_dim)) - call get_node_array(node_xsdata, "scatter", temp_arr) - input_scatt = reshape(temp_arr, (/groups, groups, order_dim/)) - deallocate(temp_arr) - - ! Compare the number of orders given with the maximum order of the - ! problem. Strip off the supefluous orders if needed. - if (this % scatt_type == ANGLE_LEGENDRE) then - order = min(order_dim - 1, max_order) - order_dim = order + 1 - end if - allocate(temp_scatt(groups, groups, order_dim)) - temp_scatt(:, :, :) = input_scatt(:, :, 1:order_dim) - - ! Take input format (groups, groups, order) and convert to - ! the more useful format needed for scattdata: (order, groups, groups) - ! However, if scatt_type was ANGLE_LEGENDRE (i.e., the data was - ! provided as Legendre coefficients), and the user requested that - ! these legendres be converted to tabular form (note this is also - ! the default behavior), convert that now. - if (this % scatt_type == ANGLE_LEGENDRE .and. enable_leg_mu) then - ! Convert input parameters to what we need for the rest. - this % scatt_type = ANGLE_TABULAR - order_dim = legendre_mu_points - order = order_dim - dmu = TWO / real(order - 1, 8) - - allocate(scatt_coeffs(order_dim, groups, groups)) - do gin = 1, groups - do gout = 1, groups - norm = ZERO - do imu = 1, order_dim - if (imu == 1) then - mu = -ONE - else if (imu == order_dim) then - mu = ONE - else - mu = -ONE + real(imu - 1, 8) * dmu - end if - scatt_coeffs(imu, gout, gin) = & - evaluate_legendre(temp_scatt(gout, gin, :),mu) - ! Ensure positivity of distribution - if (scatt_coeffs(imu, gout, gin) < ZERO) & - scatt_coeffs(imu, gout, gin) = ZERO - ! And accrue the integral - if (imu > 1) then - norm = norm + HALF * dmu * & - (scatt_coeffs(imu - 1, gout, gin) + & - scatt_coeffs(imu, gout, gin)) - end if - end do - ! Now that we have the integral, lets ensure that the distribution - ! is normalized such that it preserves the original scattering xs - if (norm > ZERO) then - scatt_coeffs(:, gout, gin) = scatt_coeffs(:, gout, gin) * & - temp_scatt(gout, gin, 1) / norm - end if - end do - end do + ! Get angular meta-data and allocate as needed based off of the + ! information therein + select type(this) + type is (MgxsAngle) + if (attribute_exists(xs_id, "num_polar")) then + call read_attribute(this % n_pol, xs_id, "num_polar") else - ! Sticking with current representation, carry forward but change - ! the array ordering - allocate(scatt_coeffs(order_dim, groups, groups)) - do gin = 1, groups - do gout = 1, groups - do l = 1, order_dim - scatt_coeffs(l, gout, gin) = temp_scatt(gout, gin, l) - end do - end do - end do + call fatal_error("num_polar must be provided!") end if - deallocate(temp_scatt) - else - call fatal_error("Must provide scatter!") - end if - ! Allocate and initialize our ScattData Object. - if (this % scatt_type == ANGLE_HISTOGRAM) then - allocate(ScattDataHistogram :: this % scatter) - else if (this % scatt_type == ANGLE_TABULAR) then - allocate(ScattDataTabular :: this % scatter) - else if (this % scatt_type == ANGLE_LEGENDRE) then - allocate(ScattDataLegendre :: this % scatter) - end if + if (attribute_exists(xs_id, "num_azimuthal")) then + call read_attribute(this % n_azi, xs_id, "num_azimuthal") + else + call fatal_error("num_azimuthal must be provided!") + end if - ! Initialize the ScattData Object - call this % scatter % init(temp_mult, scatt_coeffs) - - ! Check sigA to ensure it is not 0 since it is - ! often divided by in the tally routines - ! (This may happen with Helium data) - do gin = 1, groups - if (this % absorption(gin) == ZERO) this % absorption(gin) = 1E-10_8 - end do - - ! Get, or infer, total xs data. - allocate(this % total(groups)) - if (check_for_node(node_xsdata, "total")) then - call get_node_array(node_xsdata, "total", this % total) - else - this % total(:) = this % absorption(:) + this % scatter % scattxs(:) - end if - - ! Deallocate temporaries for the next material - deallocate(input_scatt, scatt_coeffs, temp_mult) - - ! Finally, check sigT to ensure it is not 0 since it is - ! often divided by in the tally routines - do gin = 1, groups - if (this % total(gin) == ZERO) this % total(gin) = 1E-10_8 - end do - - - end subroutine mgxsiso_init_file - - subroutine mgxsang_init_file(this, node_xsdata, groups, get_kfiss, get_fiss, & - max_order) - class(MgxsAngle), intent(inout) :: this ! Working Object - type(Node), pointer, intent(in) :: node_xsdata ! Data from MGXS xml - integer, intent(in) :: groups ! Number of Energy groups - logical, intent(in) :: get_kfiss ! Need Kappa-Fission? - logical, intent(in) :: get_fiss ! Should we get fiss data? - integer, intent(in) :: max_order ! Maximum requested order - - type(Node), pointer :: node_legendre_mu - character(MAX_LINE_LEN) :: temp_str - logical :: enable_leg_mu - real(8), allocatable :: temp_arr(:), temp_4d(:, :, :, :) - real(8), allocatable :: temp_mult(:, :, :, :) - real(8), allocatable :: scatt_coeffs(:, :, :, :, :) - real(8), allocatable :: input_scatt(:, :, :, :, :) - real(8), allocatable :: temp_scatt(:, :, :, :, :) - real(8) :: dmu, mu, norm, dangle - integer :: order, order_dim, gin, gout, l, arr_len - integer :: legendre_mu_points, imu, ipol, iazi - - ! Call generic data gathering routine (will populate the metadata) - call mgxs_init_file(this, node_xsdata) - - if (check_for_node(node_xsdata, "num_polar")) then - call get_node_value(node_xsdata, "num_polar", this % n_pol) - else - call fatal_error("num_polar must be provided!") - end if - - if (check_for_node(node_xsdata, "num_azimuthal")) then - call get_node_value(node_xsdata, "num_azimuthal", this % n_azi) - else - call fatal_error("num_azimuthal must be provided!") - end if - - ! Load angle data, if present (else equally spaced) - allocate(this % polar(this % n_pol)) - allocate(this % azimuthal(this % n_azi)) - if (check_for_node(node_xsdata, "polar")) then - call fatal_error("User-Specified polar angle bins not yet supported!") - ! When this feature is supported, this line will be activated - call get_node_array(node_xsdata, "polar", this % polar) - else + ! Set angle data to use equally-spaced bins + allocate(this % polar(this % n_pol)) dangle = PI / real(this % n_pol, 8) do ipol = 1, this % n_pol this % polar(ipol) = (real(ipol, 8) - HALF) * dangle end do - end if - if (check_for_node(node_xsdata, "azimuthal")) then - call fatal_error("User-Specified azimuthal angle bins not yet supported!") - ! When this feature is supported, this line will be activated - call get_node_array(node_xsdata, "azimuthal", this % azimuthal) - else + allocate(this % azimuthal(this % n_azi)) dangle = TWO * PI / real(this % n_azi, 8) do iazi = 1, this % n_azi this % azimuthal(iazi) = -PI + (real(iazi, 8) - HALF) * dangle end do - end if - - ! Load the more specific data - allocate(this % nu_fission(groups, this % n_azi, this % n_pol)) - allocate(this % chi(groups, groups, this % n_azi, this % n_pol)) - if (this % fissionable) then - if (check_for_node(node_xsdata, "chi")) then - ! Chi was provided, that means they are giving chi and nu-fission - ! vectors - ! Get chi - allocate(temp_arr(1 * groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "chi", temp_arr) - ! Initialize counter for temp_arr - l = 0 - gin = 1 - do ipol = 1, this % n_pol - do iazi = 1, this % n_azi - do gout = 1, groups - l = l + 1 - this % chi(gout, gin, iazi, ipol) = temp_arr(l) - end do - ! Normalize chi so its CDF goes to 1 - this % chi(:, gin, iazi, ipol) = & - this % chi(:, gin, iazi, ipol) / & - sum(this % chi(:, gin, iazi, ipol)) - end do - end do - - ! Now set all the other gin values - do ipol = 1, this % n_pol - do iazi = 1, this % n_azi - do gin = 2, groups - this % chi(:, gin, iazi, ipol) = & - this % chi(:, 1, iazi, ipol) - end do - end do - end do - deallocate(temp_arr) - - ! Get nu_fission (as a vector) - if (check_for_node(node_xsdata, "nu_fission")) then - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "nu_fission", temp_arr) - this % nu_fission(:, :, :) = reshape(temp_arr, (/groups, & - this % n_azi, this % n_pol/)) - deallocate(temp_arr) - else - call fatal_error("If fissionable, must provide nu_fission!") - end if - - else - ! chi isnt provided but is within nu_fission, existing as a matrix - ! So, get nu_fission (as a matrix) - if (check_for_node(node_xsdata, "nu_fission")) then - allocate(temp_arr(groups * groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "nu_fission", temp_arr) - allocate(temp_4d(groups, groups, this % n_azi,this % n_pol)) - temp_4d(:, :, :, :) = reshape(temp_arr, (/groups, groups, & - this % n_azi, this % n_pol/)) - deallocate(temp_arr) - else - call fatal_error("If fissionable, must provide nu_fission!") - end if - - ! Set the vector nu-fission from the matrix nu-fission - do ipol = 1, this % n_pol - do iazi = 1, this % n_azi - do gin = 1, groups - this % nu_fission(gin, iazi, ipol) = & - sum(temp_4d(:, gin, iazi, ipol)) - end do - end do - end do - - ! Now pull out information needed for chi - this % chi = temp_4d - ! Normalize chi so its CDF goes to 1 - do ipol = 1, this % n_pol - do iazi = 1, this % n_azi - do gin = 1, groups - this % chi(:, gin, iazi, ipol) = & - this % chi(:, gin, iazi, ipol) / & - sum(this % chi(:, gin, iazi, ipol)) - end do - end do - end do - deallocate(temp_4d) - end if - - ! If we have a need* for the fission and kappa-fission x/s, get them - ! (*Need is defined as will be using it to tally) - if (get_fiss) then - if (check_for_node(node_xsdata, "fission")) then - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "fission", temp_arr) - allocate(this % fission(groups, this % n_azi, this % n_pol)) - this % fission(:, :, :) = reshape(temp_arr, (/groups, this % n_azi, & - this % n_pol/)) - deallocate(temp_arr) - else - call fatal_error("Fission data missing, required due to fission& - & tallies in tallies.xml file!") - end if - end if - if (get_kfiss) then - if (check_for_node(node_xsdata, "kappa_fission")) then - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "kappa_fission", temp_arr) - allocate(this % k_fission(groups, this % n_azi, this % n_pol)) - this % k_fission(:, :, :) = reshape(temp_arr, (/groups, & - this % n_azi, this % n_pol/)) - deallocate(temp_arr) - else - call fatal_error("kappa_fission data missing, required due to & - &kappa-fission tallies in tallies.xml file!") - end if - end if - else - this % nu_fission(:, :, :) = ZERO - this % chi(:, :, :, :) = ZERO - end if - - if (check_for_node(node_xsdata, "absorption")) then - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "absorption", temp_arr) - allocate(this % absorption(groups, this % n_azi, this % n_pol)) - this % absorption(:, :, :) = reshape(temp_arr, (/groups, this % n_azi, & - this % n_pol/)) - deallocate(temp_arr) - else - call fatal_error("Must provide absorption!") - end if - - ! Get multiplication data if present - allocate(temp_mult(groups,groups, this % n_azi, this % n_pol)) - if (check_for_node(node_xsdata, "multiplicity")) then - arr_len = get_arraysize_double(node_xsdata, "multiplicity") - if (arr_len == groups * groups * this % n_azi * this % n_pol) then - allocate(temp_arr(arr_len)) - call get_node_array(node_xsdata, "multiplicity", temp_arr) - temp_mult(:, :, :, :) = reshape(temp_arr, (/groups, groups, & - this % n_azi, this % n_pol/)) - deallocate(temp_arr) - else - call fatal_error("Multiplicity length not same as number of groups& - & squared!") - end if - else - temp_mult(:, :, :, :) = ONE - end if - - ! Get scattering treatment information - ! Tabular_legendre tells us if we are to treat the provided - ! Legendre polynomials as tabular data (if enable is true) or leaving - ! them as Legendres (if enable is false, or the default) - - ! Set the default (leave as Legendre polynomials) - enable_leg_mu = .false. - if (check_for_node(node_xsdata, "tabular_legendre")) then - call get_node_ptr(node_xsdata, "tabular_legendre", node_legendre_mu) - if (check_for_node(node_legendre_mu, "enable")) then - call get_node_value(node_legendre_mu, "enable", temp_str) - temp_str = trim(to_lower(temp_str)) - if (temp_str == 'true' .or. temp_str == '1') then - enable_leg_mu = .true. - elseif (temp_str == 'false' .or. temp_str == '0') then - enable_leg_mu = .false. - else - call fatal_error("Unrecognized tabular_legendre/enable: " & - // temp_str) - end if - end if - ! Ok, so if we need to convert to a tabular form, get the user provided - ! number of points - if (enable_leg_mu) then - if (check_for_node(node_legendre_mu, "num_points")) then - call get_node_value(node_legendre_mu, "num_points", & - legendre_mu_points) - if (legendre_mu_points <= 0) & - call fatal_error("num_points element must be positive& - & and non-zero!") - else - ! Set the default number of points (0.0625 spacing) - legendre_mu_points = 33 - end if - end if - end if - - ! Get the library's value for the order - if (check_for_node(node_xsdata, "order")) then - call get_node_value(node_xsdata, "order", order) - else - call fatal_error("Order must be provided!") - end if - - ! Before retrieving the data, store the dimensionality of the data in - ! order_dim. For Legendre data, we usually refer to it as Pn where - ! n is the order. However Pn has n+1 sets of points (since you need to - ! the count the P0 moment). Adjust for that. Histogram and Tabular - ! formats dont need this adjustment. - if (this % scatt_type == ANGLE_LEGENDRE) then - order_dim = order + 1 - else - order_dim = order - end if - - ! The input is gathered in the more user-friendly facing format of - ! Gout x Gin x Order x Azi x Pol. We will get it in that format in - ! input_scatt, but then need to convert it to a more useful ordering - ! for processing (Order x Gout x Gin x Azi x Pol). - allocate(input_scatt(groups, groups, order_dim, this % n_azi, & - this % n_pol)) - if (check_for_node(node_xsdata, "scatter")) then - allocate(temp_arr(groups * groups * order_dim * this % n_azi * & - this % n_pol)) - call get_node_array(node_xsdata, "scatter", temp_arr) - input_scatt(:, :, :, :, :) = reshape(temp_arr, (/groups, groups, & - order_dim, this % n_azi, this % n_pol/)) - deallocate(temp_arr) - - ! Compare the number of orders given with the maximum order of the - ! problem. Strip off the supefluous orders if needed. - if (this % scatt_type == ANGLE_LEGENDRE) then - order = min(order_dim - 1, max_order) - order_dim = order + 1 - end if - - allocate(temp_scatt(groups, groups, order_dim, this % n_azi, & - this % n_pol)) - temp_scatt(:, :, :, :, :) = input_scatt(:, :, 1:order_dim, :, :) - - ! Take input format (groups, groups, order) and convert to - ! the more useful format needed for scattdata: (order, groups, groups) - ! However, if scatt_type was ANGLE_LEGENDRE (i.e., the data was - ! provided as Legendre coefficients), and the user requested that - ! these legendres be converted to tabular form (note this is also - ! the default behavior), convert that now. - if (this % scatt_type == ANGLE_LEGENDRE .and. enable_leg_mu) then - - ! Convert input parameters to what we need for the rest. - this % scatt_type = ANGLE_TABULAR - order_dim = legendre_mu_points - order = order_dim - dmu = TWO / real(order - 1, 8) - - allocate(scatt_coeffs(order_dim, groups, groups, this % n_azi, & - this % n_pol)) - do ipol = 1, this % n_pol - do iazi = 1, this % n_azi - do gin = 1, groups - do gout = 1, groups - norm = ZERO - do imu = 1, order_dim - if (imu == 1) then - mu = -ONE - else if (imu == order_dim) then - mu = ONE - else - mu = -ONE + real(imu - 1, 8) * dmu - end if - scatt_coeffs(imu, gout, gin, iazi, ipol) = & - evaluate_legendre(temp_scatt(gout, gin, :, iazi, ipol), mu) - ! Ensure positivity of distribution - if (scatt_coeffs(imu, gout, gin, iazi, ipol) < ZERO) & - scatt_coeffs(imu, gout, gin, iazi, ipol) = ZERO - ! And accrue the integral - if (imu > 1) then - norm = norm + HALF * dmu * & - (scatt_coeffs(imu - 1, gout, gin, iazi, ipol) + & - scatt_coeffs(imu, gout, gin, iazi, ipol)) - end if - end do - ! Now that we have the integral, lets ensure that the distribution - ! is normalized such that it preserves the original scattering xs - if (norm > ZERO) then - scatt_coeffs(:, gout, gin, iazi, ipol) = & - scatt_coeffs(:, gout, gin, iazi, ipol) * & - temp_scatt(gout, gin, 1, iazi, ipol) / norm - end if - end do - end do - end do - end do - else - ! Sticking with current representation, carry forward but change - ! the array ordering - allocate(scatt_coeffs(order_dim, groups, groups, this % n_azi, & - this % n_pol)) - do ipol = 1, this % n_pol - do iazi = 1, this % n_azi - do gin = 1, groups - do gout = 1, groups - do l = 1, order_dim - scatt_coeffs(l, gout, gin, iazi, ipol) = & - temp_scatt(gout, gin, l, iazi, ipol) - end do - end do - end do - end do - end do - end if - deallocate(temp_scatt) - else - call fatal_error("Must provide scatter!") - end if - - allocate(this % scatter(this % n_azi, this % n_pol)) - do ipol = 1, this % n_pol - do iazi = 1, this % n_azi - ! Allocate and initialize our ScattData Object. - if (this % scatt_type == ANGLE_HISTOGRAM) then - allocate(ScattDataHistogram :: this % scatter(iazi, ipol) % obj) - else if (this % scatt_type == ANGLE_TABULAR) then - allocate(ScattDataTabular :: this % scatter(iazi, ipol) % obj) - else if (this % scatt_type == ANGLE_LEGENDRE) then - allocate(ScattDataLegendre :: this % scatter(iazi, ipol) % obj) - end if - - ! Initialize the ScattData Object - call this % scatter(iazi, ipol) % obj % init(& - temp_mult(:, :, iazi, ipol), & - scatt_coeffs(:, :, :, iazi, ipol)) - end do - end do - ! Deallocate temporaries for the next material - deallocate(input_scatt, scatt_coeffs, temp_mult) - - allocate(this % total(groups, this % n_azi, this % n_pol)) - if (check_for_node(node_xsdata, "total")) then - allocate(temp_arr(groups * this % n_azi * this % n_pol)) - call get_node_array(node_xsdata, "total", temp_arr) - this % total(:, :, :) = reshape(temp_arr, (/groups, this % n_azi, & - this % n_pol/)) - deallocate(temp_arr) - else - do ipol = 1, this % n_pol - do iazi = 1, this % n_azi - this % total(:, iazi, ipol) = this % absorption(:, iazi, ipol) + & - this % scatter(iazi, ipol) % obj % scattxs(:) - end do - end do - end if - - end subroutine mgxsang_init_file - -!=============================================================================== -! MGXS*_GET_XS returns the requested data cross section data -!=============================================================================== - - pure function mgxsiso_get_xs(this, xstype, gin, gout, uvw, mu) result(xs) - class(MgxsIso), intent(in) :: this ! The Mgxs to initialize - character(*) , intent(in) :: xstype ! Type of xs requested - integer, intent(in) :: gin ! Incoming Energy group - integer, optional, intent(in) :: gout ! Outgoing Energy group - real(8), optional, intent(in) :: uvw(3) ! Requested Angle - real(8), optional, intent(in) :: mu ! Change in angle - real(8) :: xs ! Requested x/s - - select case(xstype) - case('total') - xs = this % total(gin) - case('absorption') - xs = this % absorption(gin) - case('fission') - if (allocated(this % fission)) then - xs = this % fission(gin) - else - xs = ZERO - end if - case('kappa_fission') - if (allocated(this % k_fission)) then - xs = this % k_fission(gin) - else - xs = ZERO - end if - case('nu_fission') - xs = this % nu_fission(gin) - case('chi') - if (present(gout)) then - xs = this % chi(gout,gin) - else - ! Not sure youd want a 1 or a 0, but here you go! - xs = sum(this % chi(:, gin)) - end if - case('scatter') - if (present(gout)) then - if (gout < this % scatter % gmin(gin) .or. & - gout > this % scatter % gmax(gin)) then - xs = ZERO - else - xs = this % scatter % scattxs(gin) * & - this % scatter % energy(gin) % data(gout) - end if - else - xs = this % scatter % scattxs(gin) - end if - case('scatter/mult') - if (present(gout)) then - if (gout < this % scatter % gmin(gin) .or. & - gout > this % scatter % gmax(gin)) then - xs = ZERO - else - xs = this % scatter % scattxs(gin) * & - this % scatter % energy(gin) % data(gout) / & - this % scatter % mult(gin) % data(gout) - end if - else - xs = this % scatter % scattxs(gin) / & - (dot_product(this % scatter % mult(gin) % data, & - this % scatter % energy(gin) % data)) - end if - case('scatter*f_mu/mult','scatter*f_mu') - if (present(gout)) then - if (gout < this % scatter % gmin(gin) .or. & - gout > this % scatter % gmax(gin)) then - xs = ZERO - else - xs = this % scatter % scattxs(gin) * & - this % scatter % energy(gin) % data(gout) * & - this % scatter % calc_f(gin, gout, mu) - if (xstype == 'scatter*f_mu/mult') then - xs = xs / this % scatter % mult(gin) % data(gout) - end if - end if - else - xs = ZERO - ! TODO (Not likely needed) - ! (asking for f_mu without asking for a group or mu would mean the - ! user of this code wants the complete 1-outgoing group distribution - ! which Im not sure what they would do with that. - end if - case default - xs = ZERO end select - end function mgxsiso_get_xs + end subroutine mgxs_from_hdf5 - pure function mgxsang_get_xs(this, xstype, gin, gout, uvw, mu) result(xs) - class(MgxsAngle), intent(in) :: this ! The Mgxs to initialize - character(*) , intent(in) :: xstype ! Type of xs requested - integer, intent(in) :: gin ! Incoming Energy group - integer, optional, intent(in) :: gout ! Outgoing Energy group - real(8), optional, intent(in) :: uvw(3) ! Requested Angle - real(8), optional, intent(in) :: mu ! Change in angle - real(8) :: xs ! Requested x/s + subroutine mgxsiso_from_hdf5(this, xs_id, groups, temperature, method, & + tolerance, get_kfiss, get_fiss, max_order, & + legendre_to_tabular, legendre_to_tabular_points) + class(MgxsIso), intent(inout) :: this ! Working Object + integer(HID_T), intent(in) :: xs_id ! Group in H5 file + integer, intent(in) :: groups ! Number of Energy groups + type(VectorReal), intent(in) :: temperature ! list of desired temperatures + integer, intent(inout) :: method ! Type of temperature access + real(8), intent(in) :: tolerance ! Tolerance on method + logical, intent(in) :: get_kfiss ! Need Kappa-Fission? + logical, intent(in) :: get_fiss ! Should we get fiss data? + integer, intent(in) :: max_order ! Maximum requested order + logical, intent(in) :: legendre_to_tabular ! Convert Legendres to Tabular? + integer, intent(in) :: legendre_to_tabular_points ! Number of points to use + ! in that conversion - integer :: iazi, ipol + character(MAX_LINE_LEN) :: temp_str + integer(HID_T) :: xsdata_grp, scatt_grp + real(8), allocatable :: temp_arr(:), temp_2d(:, :) + real(8) :: dmu, mu, norm + integer :: order, order_dim, gin, gout, l, imu, length + type(VectorInt) :: temps_to_read + integer :: t + type(Jagged2D), allocatable :: input_scatt(:), scatt_coeffs(:) + type(Jagged1D), allocatable :: temp_mult(:) + integer, allocatable :: gmin(:), gmax(:) + + ! Call generic data gathering routine (will populate the metadata) + call mgxs_from_hdf5(this, xs_id, temperature, method, tolerance, & + temps_to_read, order_dim) + + ! Load the more specific data + do t = 1, temps_to_read % size() + associate(xs => this % xs(t)) + ! Get temperature as a string + temp_str = trim(to_str(temps_to_read % data(t))) // "K" + xsdata_grp = open_group(xs_id, trim(temp_str)) + allocate(xs % nu_fission(groups)) + allocate(xs % chi(groups, groups)) + if (this % fissionable) then + if (object_exists(xsdata_grp, "chi")) then + ! Chi was provided, that means we need chi and nu-fission vectors + ! Get chi + allocate(temp_arr(groups)) + call read_dataset(temp_arr, xsdata_grp, "chi") + do gin = 1, groups + do gout = 1, groups + xs % chi(gout, gin) = temp_arr(gout) + end do + ! Normalize chi so its CDF goes to 1 + xs % chi(:, gin) = xs % chi(:, gin) / sum(xs % chi(:, gin)) + end do + deallocate(temp_arr) + + ! Get nu_fission (as a vector) + if (object_exists(xsdata_grp, "nu-fission")) then + call read_dataset(xs % nu_fission, xsdata_grp, "nu-fission") + else + call fatal_error("If fissionable, must provide nu-fission!") + end if - if (present(uvw)) then - call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) - select case(xstype) - case('total') - xs = this % total(gin, iazi, ipol) - case('absorption') - xs = this % absorption(gin, iazi, ipol) - case('fission') - if (allocated(this % fission)) then - xs = this % fission(gin, iazi, ipol) - else - xs = ZERO - end if - case('kappa_fission') - if (allocated(this % k_fission)) then - xs = this % k_fission(gin, iazi, ipol) - else - xs = ZERO - end if - case('nu_fission') - xs = this % nu_fission(gin, iazi, ipol) - case('chi') - if (present(gout)) then - xs = this % chi(gout, gin, iazi, ipol) - else - ! Not sure you would want a 1 or a 0, but here you go! - xs = sum(this % chi(:, gin, iazi, ipol)) - end if - case('scatter') - if (present(gout)) then - if (gout < this % scatter(iazi, ipol) % obj % gmin(gin) .or. & - gout > this % scatter(iazi, ipol) % obj % gmax(gin)) then - xs = ZERO else - xs = this % scatter(iazi, ipol) % obj % scattxs(gin) * & - this % scatter(iazi, ipol) % obj % energy(gin) % data(gout) + ! chi isnt provided but is within nu_fission, existing as a matrix + ! So, get nu_fission (as a matrix) + if (object_exists(xsdata_grp, "nu-fission")) then + allocate(temp_2d(groups, groups)) + call read_dataset(temp_2d, xsdata_grp, "nu-fission") + else + call fatal_error("If fissionable, must provide nu-fission!") + end if + + ! Set the vector nu-fission from the matrix nu-fission + do gin = 1, groups + xs % nu_fission(gin) = sum(temp_2d(:, gin)) + end do + + ! Now pull out information needed for chi + xs % chi(:, :) = temp_2d + ! Normalize chi so its CDF goes to 1 + do gin = 1, groups + xs % chi(:, gin) = xs % chi(:, gin) / sum(xs % chi(:, gin)) + end do + deallocate(temp_2d) end if - else - xs = this % scatter(iazi, ipol) % obj % scattxs(gin) - end if - case('scatter/mult') - if (present(gout)) then - if (gout < this % scatter(iazi, ipol) % obj % gmin(gin) .or. & - gout > this % scatter(iazi, ipol) % obj % gmax(gin)) then - xs = ZERO - else - xs = this % scatter(iazi, ipol) % obj % scattxs(gin) * & - this % scatter(iazi, ipol) % obj % energy(gin) % data(gout) / & - this % scatter(iazi, ipol) % obj % mult(gin) % data(gout) + + ! If we have a need* for the fission and kappa-fission x/s, get them + ! (*Need is defined as will be using it to tally) + if (get_fiss) then + if (object_exists(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& + & tallies in tallies.xml file!") + end if end if - else - xs = this % scatter(iazi, ipol) % obj % scattxs(gin) / & - (dot_product(this % scatter(iazi, ipol) % obj % mult(gin) % data, & - this % scatter(iazi, ipol) % obj % energy(gin) % data)) - end if - case('scatter*f_mu/mult','scatter*f_mu') - if (present(gout)) then - if (gout < this % scatter(iazi, ipol) % obj % gmin(gin) .or. & - gout > this % scatter(iazi, ipol) % obj % gmax(gin)) then - xs = ZERO - else - xs = this % scatter(iazi, ipol) % obj % scattxs(gin) * & - this % scatter(iazi, ipol) % obj % energy(gin) % data(gout) - xs = xs * this % scatter(iazi, ipol) % obj % calc_f(gin, gout, mu) - if (xstype == 'scatter*f_mu/mult') then - xs = xs / & - this % scatter(iazi, ipol) % obj % mult(gin) % data(gout) + if (get_kfiss) then + if (object_exists(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 & + &kappa-fission tallies in tallies.xml file!") end if end if else - xs = ZERO - ! TODO (Not likely needed) - ! (asking for f_mu without asking for a group or mu would mean the - ! user of this code wants the complete 1-outgoing group distribution - ! which Im not sure what they would do with that. + xs % nu_fission = ZERO + xs % chi = ZERO end if - case default - xs = ZERO - end select - else - xs = ZERO - end if - end function mgxsang_get_xs + if (object_exists(xsdata_grp, "absorption")) then + allocate(xs % absorption(groups)) + call read_dataset(xs % absorption, xsdata_grp, "absorption") + else + call fatal_error("Must provide absorption!") + end if + + ! Get scattering data + if (.not. object_exists(xsdata_grp, "scatter_data")) & + call fatal_error("Must provide 'scatter_data'") + scatt_grp = open_group(xsdata_grp, 'scatter_data') + ! First get the outgoing group boundary indices + if (object_exists(scatt_grp, "g_min")) then + allocate(gmin(groups)) + call read_dataset(gmin, scatt_grp, "g_min") + else + call fatal_error("'g_min' for the scatter_data must be provided") + end if + if (object_exists(scatt_grp, "g_max")) then + allocate(gmax(groups)) + call read_dataset(gmax, scatt_grp, "g_max") + else + call fatal_error("'g_max' for the scatter_data must be provided") + end if + + ! 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 + order_dim * (gmax(gin) - gmin(gin) + 1) + end do + ! Allocate flattened array + allocate(temp_arr(length)) + if (.not. object_exists(scatt_grp, 'scatter_matrix')) & + call fatal_error("'scatter_matrix' must be provided") + call read_dataset(temp_arr, scatt_grp, "scatter_matrix") + + ! Compare the number of orders given with the maximum order of the + ! problem. Strip off the supefluous orders if needed. + if (this % scatter_format == ANGLE_LEGENDRE) then + order = min(order_dim - 1, max_order) + order_dim = order + 1 + end if + + ! Convert temp_arr to a jagged array ((gin) % data(l, gout)) for passing + ! to ScattData + allocate(input_scatt(groups)) + index = 1 + do gin = 1, groups + allocate(input_scatt(gin) % data(order_dim, gmin(gin):gmax(gin))) + do gout = gmin(gin), gmax(gin) + do l = 1, order_dim + input_scatt(gin) % data(l, gout) = temp_arr(index) + index = index + 1 + end do + end do + end do + deallocate(temp_arr) + + ! Finally convert the legendre to tabular if needed + allocate(scatt_coeffs(groups)) + if (this % scatter_format == ANGLE_LEGENDRE .and. & + legendre_to_tabular) then + this % scatter_format = ANGLE_TABULAR + order_dim = legendre_to_tabular_points + order = order_dim + dmu = TWO / real(order - 1, 8) + do gin = 1, groups + allocate(scatt_coeffs(gin) % data(order_dim, gmin(gin):gmax(gin))) + do gout = gmin(gin), gmax(gin) + norm = ZERO + do imu = 1, order_dim + if (imu == 1) then + mu = -ONE + else if (imu == order_dim) then + mu = ONE + else + mu = -ONE + real(imu - 1, 8) * dmu + end if + scatt_coeffs(gin) % data(imu, gout) = & + evaluate_legendre(input_scatt(gin) % data(:, gout), mu) + ! Ensure positivity of distribution + if (scatt_coeffs(gin) % data(imu, gout) < ZERO) & + scatt_coeffs(gin) % data(imu, gout) = ZERO + ! And accrue the integral + if (imu > 1) then + norm = norm + HALF * dmu * & + (scatt_coeffs(gin) % data(imu - 1, gout) + & + scatt_coeffs(gin) % data(imu, gout)) + end if + end do ! mu + ! Now that we have the integral, lets ensure that the distribution + ! is normalized such that it preserves the original scattering xs + if (norm > ZERO) then + scatt_coeffs(gin) % data(:, gout) = & + scatt_coeffs(gin) % data(:, gout) * & + input_scatt(gin) % data(1, gout) / norm + end if + end do ! gout + end do ! gin + else + ! Sticking with current representation + do gin = 1, groups + allocate(scatt_coeffs(gin) % data(order_dim, gmin(gin):gmax(gin))) + scatt_coeffs(gin) % data(:, :) = & + input_scatt(gin) % data(1:order_dim, :) + end do + end if + deallocate(input_scatt) + + ! Now get the multiplication matrix + if (object_exists(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 + ! 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_format == ANGLE_HISTOGRAM) then + allocate(ScattDataHistogram :: xs % scatter) + else if (this % scatter_format == ANGLE_TABULAR) then + allocate(ScattDataTabular :: xs % scatter) + else if (this % scatter_format == ANGLE_LEGENDRE) then + allocate(ScattDataLegendre :: xs % scatter) + end if + + ! Initialize the ScattData Object + call xs % scatter % init(gmin, gmax, temp_mult, scatt_coeffs) + + ! Check sigA to ensure it is not 0 since it is + ! often divided by in the tally routines + ! (This may happen with Helium data) + do gin = 1, groups + if (xs % absorption(gin) == ZERO) xs % absorption(gin) = 1E-10_8 + end do + + ! Get, or infer, total xs data. + allocate(xs % total(groups)) + if (object_exists(xsdata_grp, "total")) then + call read_dataset(xs % total, xsdata_grp, "total") + else + xs % total(:) = xs % absorption(:) + xs % scatter % scattxs(:) + end if + + ! Check sigT to ensure it is not 0 since it is + ! often divided by in the tally routines + do gin = 1, groups + if (xs % total(gin) == ZERO) xs % total(gin) = 1E-10_8 + end do + + ! Get kinetics data + if (object_exists(xsdata_grp, "inverse_velocities")) then + allocate(xs % inv_vel(groups)) + call read_dataset(xs % inv_vel, xsdata_grp, "inverse_velocities") + end if + + ! 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 + end subroutine mgxsiso_from_hdf5 + + subroutine mgxsang_from_hdf5(this, xs_id, groups, temperature, method, & + tolerance, get_kfiss, get_fiss, max_order, & + legendre_to_tabular, legendre_to_tabular_points) + class(MgxsAngle), intent(inout) :: this ! Working Object + integer(HID_T), intent(in) :: xs_id ! Group in H5 file + integer, intent(in) :: groups ! Number of Energy groups + type(VectorReal), intent(in) :: temperature ! list of desired temperatures + integer, intent(inout) :: method ! Type of temperature access + real(8), intent(in) :: tolerance ! Tolerance on method + logical, intent(in) :: get_kfiss ! Need Kappa-Fission? + logical, intent(in) :: get_fiss ! Should we get fiss data? + integer, intent(in) :: max_order ! Maximum requested order + logical, intent(in) :: legendre_to_tabular ! Convert Legendres to Tabular? + integer, intent(in) :: legendre_to_tabular_points ! Number of points to use + ! in that conversion + + character(MAX_LINE_LEN) :: temp_str + integer(HID_T) :: xsdata_grp, scatt_grp + integer, allocatable :: int_arr(:) + real(8), allocatable :: temp_arr(:), temp_4d(:, :, :, :) + real(8) :: dmu, mu, norm + integer :: order, order_dim, gin, gout, l, imu + type(VectorInt) :: temps_to_read + integer :: t, length, ipol, iazi + type(Jagged2D), allocatable :: input_scatt(:, :, :), scatt_coeffs(:, :, :) + type(Jagged1D), allocatable :: temp_mult(:, :, :) + integer, allocatable :: gmin(:, :, :), gmax(:, :, :) + + ! Call generic data gathering routine (will populate the metadata) + call mgxs_from_hdf5(this, xs_id, temperature, method, tolerance, & + temps_to_read, order_dim) + + ! Load the more specific data + do t = 1, temps_to_read % size() + associate(xs => this % xs(t)) + ! Get temperature as a string + temp_str = trim(to_str(temps_to_read % data(t))) // "K" + xsdata_grp = open_group(xs_id, trim(temp_str)) + allocate(xs % nu_fission(groups, this % n_azi, this % n_pol)) + allocate(xs % chi(groups, groups, this % n_azi, this % n_pol)) + if (this % fissionable) then + if (object_exists(xsdata_grp, "chi")) then + ! Chi was provided, that means we need chi and nu-fission vectors + ! Get chi + 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 + gin = 1 + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gout = 1, groups + l = l + 1 + xs % chi(gout, gin, iazi, ipol) = temp_arr(l) + end do + ! Normalize chi so its CDF goes to 1 + xs % chi(:, gin, iazi, ipol) = & + xs % chi(:, gin, iazi, ipol) / & + sum(xs % chi(:, gin, iazi, ipol)) + end do + end do + + ! Now set all the other gin values + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 2, groups + xs % chi(:, gin, iazi, ipol) = & + xs % chi(:, 1, iazi, ipol) + end do + end do + end do + deallocate(temp_arr) + + ! Get nu_fission (as a vector) + if (object_exists(xsdata_grp, "nu-fission")) then + allocate(temp_arr(groups * this % n_azi * this % n_pol)) + call read_dataset(temp_arr, xsdata_grp, "nu-fission") + xs % nu_fission = reshape(temp_arr, (/groups, this % n_azi, & + this % n_pol/)) + deallocate(temp_arr) + else + call fatal_error("If fissionable, must provide nu-fission!") + end if + + else + ! chi isnt provided but is within nu_fission, existing as a matrix + ! So, get nu_fission (as a matrix) + if (object_exists(xsdata_grp, "nu-fission")) then + allocate(temp_arr(groups * groups * this % n_azi * this % n_pol)) + call read_dataset(temp_arr, xsdata_grp, "nu-fission") + allocate(temp_4d(groups, groups, this % n_azi, this % n_pol)) + temp_4d(:, :, :, :) = reshape(temp_arr, (/groups, groups, & + this % n_azi, this % n_pol/)) + deallocate(temp_arr) + else + call fatal_error("If fissionable, must provide nu-fission!") + end if + + ! Set the vector nu-fission from the matrix nu-fission + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, groups + xs % nu_fission(gin, iazi, ipol) = & + sum(temp_4d(:, gin, iazi, ipol)) + end do + end do + end do + + ! Now pull out information needed for chi + xs % chi = temp_4d + ! Normalize chi so its CDF goes to 1 + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, groups + xs % chi(:, gin, iazi, ipol) = & + xs % chi(:, gin, iazi, ipol) / & + sum(xs % chi(:, gin, iazi, ipol)) + end do + end do + end do + deallocate(temp_4d) + end if + + ! If we have a need* for the fission and kappa-fission x/s, get them + ! (*Need is defined as will be using it to tally) + if (get_fiss) then + if (object_exists(xsdata_grp, "fission")) then + allocate(temp_arr(groups * this % n_azi * this % n_pol)) + call read_dataset(temp_arr, xsdata_grp, "fission") + allocate(xs % fission(groups, this % n_azi, this % n_pol)) + xs % fission = reshape(temp_arr, (/groups, this % n_azi, & + this % n_pol/)) + deallocate(temp_arr) + else + call fatal_error("Fission data missing, required due to fission& + & tallies in tallies.xml file!") + end if + end if + if (get_kfiss) then + if (object_exists(xsdata_grp, "kappa-fission")) then + allocate(temp_arr(groups * this % n_azi * this % n_pol)) + call read_dataset(temp_arr, xsdata_grp, "kappa-fission") + allocate(xs % k_fission(groups, this % n_azi, this % n_pol)) + xs % k_fission = reshape(temp_arr, (/groups, this % n_azi, & + this % n_pol/)) + deallocate(temp_arr) + else + call fatal_error("kappa_fission data missing, required due to & + &kappa-fission tallies in tallies.xml file!") + end if + end if + else + xs % nu_fission = ZERO + xs % chi = ZERO + end if + + if (object_exists(xsdata_grp, "absorption")) then + allocate(temp_arr(groups * this % n_azi * this % n_pol)) + call read_dataset(temp_arr, xsdata_grp, "absorption") + allocate(xs % absorption(groups, this % n_azi, this % n_pol)) + xs % absorption = reshape(temp_arr, (/groups, this % n_azi, & + this % n_pol/)) + deallocate(temp_arr) + else + call fatal_error("Must provide absorption!") + end if + + ! Get scattering data + if (.not. object_exists(xsdata_grp, "scatter_data")) & + call fatal_error("Must provide 'scatter_data'") + scatt_grp = open_group(xsdata_grp, 'scatter_data') + ! First get the outgoing group boundary indices + if (object_exists(scatt_grp, "g_min")) then + allocate(int_arr(groups * this % n_azi * this % n_pol)) + call read_dataset(int_arr, scatt_grp, "g_min") + allocate(gmin(groups, this % n_azi, this % n_pol)) + gmin = reshape(int_arr, (/groups, this % n_azi, this % n_pol/)) + deallocate(int_arr) + else + call fatal_error("'g_min' for the scatter_data must be provided") + end if + if (object_exists(scatt_grp, "g_max")) then + allocate(int_arr(groups * this % n_azi * this % n_pol)) + call read_dataset(int_arr, scatt_grp, "g_max") + allocate(gmax(groups, this % n_azi, this % n_pol)) + gmax = reshape(int_arr, (/groups, this % n_azi, this % n_pol/)) + deallocate(int_arr) + else + call fatal_error("'g_max' for the scatter_data must be provided") + end if + + ! 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 + order_dim * (gmax(gin, iazi, ipol) - & + gmin(gin, iazi, ipol) + 1) + end do + end do + end do + ! Allocate flattened array + allocate(temp_arr(length)) + if (.not. object_exists(scatt_grp, 'scatter_matrix')) & + call fatal_error("'scatter_matrix' must be provided") + call read_dataset(temp_arr, scatt_grp, "scatter_matrix") + + ! Compare the number of orders given with the maximum order of the + ! problem. Strip off the superfluous orders if needed. + if (this % scatter_format == ANGLE_LEGENDRE) then + order = min(order_dim - 1, max_order) + order_dim = order + 1 + end if + + ! Convert temp_arr to a jagged array ((gin) % data(l, gout)) for passing + ! to ScattData + allocate(input_scatt(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(input_scatt(gin, iazi, ipol) % data(order_dim, & + gmin(gin, iazi, ipol):gmax(gin, iazi, ipol))) + do gout = gmin(gin, iazi, ipol), gmax(gin, iazi, ipol) + do l = 1, order_dim + input_scatt(gin, iazi, ipol) % data(l, gout) = & + temp_arr(index) + index = index + 1 + end do ! gout + end do ! order + end do ! gin + end do ! iazi + end do ! ipol + deallocate(temp_arr) + + ! Finally convert the legendre to tabular if needed + allocate(scatt_coeffs(groups, this % n_azi, this % n_pol)) + if (this % scatter_format == ANGLE_LEGENDRE .and. & + legendre_to_tabular) then + this % scatter_format = ANGLE_TABULAR + order_dim = legendre_to_tabular_points + order = order_dim + dmu = TWO / real(order - 1, 8) + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, groups + allocate(scatt_coeffs(gin, iazi, ipol) % data(& + order_dim, & + gmin(gin, iazi, ipol):gmax(gin, iazi, ipol))) + do gout = gmin(gin, iazi, ipol), gmax(gin, iazi, ipol) + norm = ZERO + do imu = 1, order_dim + if (imu == 1) then + mu = -ONE + else if (imu == order_dim) then + mu = ONE + else + mu = -ONE + real(imu - 1, 8) * dmu + end if + scatt_coeffs(gin, iazi, ipol) % data(imu, gout) = & + evaluate_legendre(& + input_scatt(gin, iazi, ipol) % data(:, gout), mu) + ! Ensure positivity of distribution + if (scatt_coeffs(gin, iazi, ipol) % data(imu, gout) < ZERO) & + scatt_coeffs(gin, iazi, ipol) % data(imu, gout) = ZERO + ! And accrue the integral + if (imu > 1) then + norm = norm + HALF * dmu * & + (scatt_coeffs(gin, iazi, ipol) % data(imu - 1, gout) + & + scatt_coeffs(gin, iazi, ipol) % data(imu, gout)) + end if + end do ! mu + ! Now that we have the integral, lets ensure that the distribution + ! is normalized such that it preserves the original scattering xs + if (norm > ZERO) then + scatt_coeffs(gin, iazi, ipol) % data(:, gout) = & + scatt_coeffs(gin, iazi, ipol) % data(:, gout) * & + input_scatt(gin, iazi, ipol) % data(1, gout) / & + norm + end if + end do ! gout + end do ! gin + end do ! iazi + end do ! ipol + else + ! Sticking with current representation, carry forward + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, groups + allocate(scatt_coeffs(gin, iazi, ipol) % data(order_dim, & + gmin(gin, iazi, ipol):gmax(gin, iazi, ipol))) + scatt_coeffs(gin, iazi, ipol) % data(:, :) = & + input_scatt(gin, iazi, ipol) % data(1:order_dim, :) + end do + end do + end do + end if + deallocate(input_scatt) + + ! Now get the multiplication matrix + if (object_exists(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 + ! 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)) + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + ! Allocate and initialize our ScattData Object. + if (this % scatter_format == ANGLE_HISTOGRAM) then + allocate(ScattDataHistogram :: xs % scatter(iazi, ipol) % obj) + else if (this % scatter_format == ANGLE_TABULAR) then + allocate(ScattDataTabular :: xs % scatter(iazi, ipol) % obj) + else if (this % scatter_format == ANGLE_LEGENDRE) then + allocate(ScattDataLegendre :: xs % scatter(iazi, ipol) % obj) + end if + + ! Initialize the ScattData Object + call xs % scatter(iazi, ipol) % obj % init(gmin(:, iazi, ipol), & + gmax(:, iazi, ipol), temp_mult(:, iazi, ipol), & + scatt_coeffs(:, iazi, ipol)) + end do + end do + + ! Check sigA to ensure it is not 0 since it is + ! often divided by in the tally routines + ! (This may happen with Helium data) + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, groups + if (xs % absorption(gin, iazi, ipol) == ZERO) then + xs % absorption(gin, iazi, ipol) = 1E-10_8 + end if + end do + end do + end do + + allocate(xs % total(groups, this % n_azi, this % n_pol)) + if (object_exists(xsdata_grp, "total")) then + allocate(temp_arr(groups * this % n_azi * this % n_pol)) + call read_dataset(temp_arr, xsdata_grp, "total") + xs % total = reshape(temp_arr, (/groups, this % n_azi, & + this % n_pol/)) + deallocate(temp_arr) + else + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + xs % total(:, iazi, ipol) = xs % absorption(:, iazi, ipol) + & + xs % scatter(iazi, ipol) % obj % scattxs(:) + end do + end do + end if + + ! Check sigT to ensure it is not 0 since it is often divided by in + ! the tally routines + do ipol = 1, this % n_pol + do iazi = 1, this % n_azi + do gin = 1, groups + if (xs % total(gin, iazi, ipol) == ZERO) then + xs % total(gin, iazi, ipol) = 1E-10_8 + end if + end do + end do + end do + + ! Get kinetics data + if (object_exists(xsdata_grp, "inverse_velocities")) then + allocate(xs % inv_vel(groups, this % n_azi, this % n_pol)) + allocate(temp_arr(groups * this % n_azi * this % n_pol)) + call read_dataset(temp_arr, xsdata_grp, "inverse_velocities") + xs % inv_vel = reshape(temp_arr, (/groups, this % n_azi, & + this % n_pol/)) + deallocate(temp_arr) + end if + + ! 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 + end subroutine mgxsang_from_hdf5 !=============================================================================== -! MACROXS*_COMBINE Builds a macroscopic Mgxs object from microscopic Mgxs -! objects +! MGXS*_COMBINE Builds a macroscopic Mgxs object from microscopic Mgxs objects !=============================================================================== - subroutine mgxs_combine(this, mat, scatt_type) + subroutine mgxs_combine(this, temps, mat, nuclides, max_order, & + scatter_format, order_dim) class(Mgxs), intent(inout) :: this ! The Mgxs to initialize + type(VectorReal), intent(in) :: temps ! Temperatures to obtain type(Material), pointer, intent(in) :: mat ! base material - integer, intent(in) :: scatt_type ! How is data presented + type(MgxsContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from + integer, intent(in) :: max_order ! Maximum requested order + integer, intent(out) :: scatter_format ! Type of scatter + integer, intent(out) :: order_dim ! Scattering data order size + + integer :: t, mat_max_order, order ! Fill in meta-data from material information if (mat % name == "") then - this % name = trim(to_str(mat % id)) + this % name = trim(to_str(mat % id)) else - this % name = mat % name + this % name = trim(mat % name) end if this % fissionable = mat % fissionable - this % scatt_type = scatt_type ! The following info we should initialize, but we dont need it nor ! does it have guaranteed meaning. this % awr = -ONE - this % kT = -ONE - end subroutine mgxs_combine + allocate(this % kTs(temps % size())) + do t = 1, temps % size() + this % kTs(t) = temps % data(t) + end do - subroutine mgxsiso_combine(this, mat, nuclides, groups, max_order, scatt_type) - class(MgxsIso), intent(inout) :: this ! The Mgxs to initialize - type(Material), pointer, intent(in) :: mat ! base material - type(MgxsContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from - integer, intent(in) :: groups ! Number of E groups - integer, intent(in) :: max_order ! Maximum requested order - integer, intent(in) :: scatt_type ! How is data presented - - integer :: i ! loop index over nuclides - integer :: gin, gout ! group indices - real(8) :: atom_density ! atom density of a nuclide - real(8) :: norm, nuscatt - integer :: mat_max_order, order, order_dim, nuc_order_dim - real(8), allocatable :: temp_mult(:, :), mult_num(:, :), mult_denom(:, :) - real(8), allocatable :: scatt_coeffs(:, :, :) - - ! Set the meta-data - call mgxs_combine(this, mat, scatt_type) + ! Allocate the XS object for the number of temperatures + select type(this) + type is (MgxsIso) + allocate(this % xs(temps % size())) + type is (MgxsAngle) + allocate(this % xs(temps % size())) + end select ! Determine the scattering type of our data and ensure all scattering orders ! are the same. + scatter_format = nuclides(mat % nuclide(1)) % obj % scatter_format select type(nuc => nuclides(mat % nuclide(1)) % obj) type is (MgxsIso) - order = size(nuc % scatter % dist(1) % data, dim=1) + order = size(nuc % xs(1) % scatter % dist(1) % data, dim=1) + type is (MgxsAngle) + order = size(nuc % xs(1) % scatter(1, 1) % obj % dist(1) % data, dim=1) end select ! If we have tabular only data, then make sure all datasets have same size - if (scatt_type == ANGLE_HISTOGRAM) then + if (scatter_format == ANGLE_HISTOGRAM) then ! Check all scattering data to ensure it is the same size do i = 2, mat % n_nuclides select type(nuc => nuclides(mat % nuclide(i)) % obj) type is (MgxsIso) - if (order /= size(nuc % scatter % dist(1) % data, dim=1)) & + if (order /= size(nuc % xs(1) % scatter % dist(1) % data, dim=1)) & + call fatal_error("All histogram scattering entries must be& + & same length!") + type is (MgxsAngle) + if (order /= size(nuc % xs(1) % scatter(1, 1) % obj % dist(1) % data, dim=1)) & call fatal_error("All histogram scattering entries must be& & same length!") end select end do ! Ok, got our order, store the dimensionality order_dim = order - - ! Set our Scatter Object Type - allocate(ScattDataHistogram :: this % scatter) - - else if (scatt_type == ANGLE_TABULAR) then + else if (scatter_format == ANGLE_TABULAR) then ! Check all scattering data to ensure it is the same size do i = 2, mat % n_nuclides select type(nuc => nuclides(mat % nuclide(i)) % obj) type is (MgxsIso) - if (order /= size(nuc % scatter % dist(1) % data, dim=1)) & + if (order /= size(nuc % xs(1) % scatter % dist(1) % data, dim=1)) & + call fatal_error("All tabular scattering entries must be& + & same length!") + type is (MgxsAngle) + if (order /= size(nuc % xs(1) % scatter(1, 1) % obj % dist(1) % data, dim=1)) & call fatal_error("All tabular scattering entries must be& & same length!") end select end do ! Ok, got our order, store the dimensionality order_dim = order - - ! Set our Scatter Object Type - allocate(ScattDataTabular :: this % scatter) - - else if (scatt_type == ANGLE_LEGENDRE) then + else if (scatter_format == ANGLE_LEGENDRE) then ! Need to determine the maximum scattering order of all data in this material mat_max_order = 0 do i = 1, mat % n_nuclides select type(nuc => nuclides(mat % nuclide(i)) % obj) type is (MgxsIso) - if (size(nuc % scatter % dist(1) % data, dim=1) > mat_max_order) & - mat_max_order = size(nuc % scatter % dist(1) % data, dim=1) + if (size(nuc % xs(1) % scatter % dist(1) % data, & + dim=1) > mat_max_order) & + mat_max_order = size(nuc % xs(1) % scatter % dist(1) % data, & + dim=1) + type is (MgxsAngle) + if (size(nuc % xs(1) % scatter(1, 1) % obj % dist(1) % data, & + dim=1) > mat_max_order) & + mat_max_order = & + size(nuc % xs(1) % scatter(1, 1) % obj % dist(1) % data, & + dim=1) end select end do @@ -1229,146 +1231,279 @@ module mgxs_header ! the problem wide max scatt order and use whichever is lower order = min(mat_max_order, max_order) ! Ok, got our order, store the dimensionality - order_dim = order + 1 - - ! Set our Scatter Object Type - allocate(ScattDataLegendre :: this % scatter) + order_dim = order end if - ! Allocate and initialize data needed for macro_xs(i_mat) object - allocate(this % total(groups)) - this % total(:) = ZERO - allocate(this % absorption(groups)) - this % absorption(:) = ZERO - allocate(this % fission(groups)) - this % fission(:) = ZERO - allocate(this % k_fission(groups)) - this % k_fission(:) = ZERO - allocate(this % nu_fission(groups)) - this % nu_fission(:) = ZERO - allocate(this % chi(groups,groups)) - this % chi(:, :) = ZERO - allocate(temp_mult(groups,groups)) - temp_mult(:, :) = ZERO - allocate(mult_num(groups,groups)) - mult_num(:, :) = ZERO - allocate(mult_denom(groups,groups)) - mult_denom(:, :) = ZERO - allocate(scatt_coeffs(order_dim,groups,groups)) - scatt_coeffs(:, :, :) = ZERO + end subroutine mgxs_combine - ! Add contribution from each nuclide in material - do i = 1, mat % n_nuclides - ! Copy atom density of nuclide in material - atom_density = mat % atom_density(i) - - ! Perform our operations which depend upon the type - select type(nuc => nuclides(mat % nuclide(i)) % obj) - type is (MgxsIso) - ! Add contributions to total, absorption, and fission data (if necessary) - this % total(:) = this % total(:) + atom_density * nuc % total(:) - this % absorption(:) = this % absorption(:) + & - atom_density * nuc % absorption(:) - if (nuc % fissionable) then - this % chi(:, :) = this % chi(:, :) + atom_density * nuc % chi(:, :) - this % nu_fission(:) = this % nu_fission(:)+ atom_density * & - nuc % nu_fission(:) - if (allocated(nuc % fission)) then - this % fission(:) = this % fission(:) + atom_density * nuc % fission(:) - end if - if (allocated(nuc % k_fission)) then - this % k_fission(:) = this % k_fission(:) + atom_density * & - nuc % k_fission(:) - end if - end if - - ! Get the multiplication matrix - ! To combine from nuclidic data we need to use the final relationship - ! mult_{gg'} = sum_i(N_i*nuscatt_{i,g,g'}) / - ! sum_i(N_i*(nuscatt_{i,g,g'} / mult_{i,g,g'})) - ! Developed as follows: - ! mult_{gg'} = nuScatt{g,g'} / Scatt{g,g'} - ! mult_{gg'} = sum_i(N_i*nuscatt_{i,g,g'}) / sum(N_i*scatt_{i,g,g'}) - ! mult_{gg'} = sum_i(N_i*nuscatt_{i,g,g'}) / - ! sum_i(N_i*(nuscatt_{i,g,g'} / mult_{i,g,g'})) - ! nuscatt_{i,g,g'} can be reconstructed from scatter % energy and - ! scatter % scattxs - do gin = 1, groups - do gout = nuc % scatter % gmin(gin), nuc % scatter % gmax(gin) - nuscatt = nuc % scatter % scattxs(gin) * & - nuc % scatter % energy(gin) % data(gout) - mult_num(gout, gin) = mult_num(gout, gin) + atom_density * & - nuscatt - if (nuc % scatter % mult(gin) % data(gout) > ZERO) then - mult_denom(gout, gin) = mult_denom(gout,gin) + atom_density * & - nuscatt / nuc % scatter % mult(gin) % data(gout) - else - ! Avoid division by zero - mult_denom(gout, gin) = mult_denom(gout,gin) + atom_density - end if - end do - end do - - ! Get the complete scattering matrix - nuc_order_dim = size(nuc % scatter % dist(1) % data, dim=1) - scatt_coeffs(1:min(nuc_order_dim, order_dim), :, :) = & - scatt_coeffs(1:min(nuc_order_dim, order_dim), :, :) + & - atom_density * & - nuc % scatter % get_matrix(min(nuc_order_dim, order_dim)) - - type is (MgxsAngle) - call fatal_error("Invalid passing of MgxsAngle to MgxsIso object") - end select - end do - - ! Obtain temp_mult - do gin = 1, groups - do gout = 1, groups - if (mult_denom(gout, gin) > ZERO) then - temp_mult(gout, gin) = mult_num(gout, gin) / mult_denom(gout, gin) - else - temp_mult(gout, gin) = ONE - end if - end do - end do - - ! Initialize the ScattData Object - call this % scatter % init(temp_mult, scatt_coeffs) - - ! Now normalize chi - if (mat % fissionable) then - do gin = 1, groups - norm = sum(this % chi(:, gin)) - if (norm > ZERO) then - this % chi(:, gin) = this % chi(:, gin) / norm - end if - end do - end if - - ! Deallocate temporaries - deallocate(scatt_coeffs, temp_mult, mult_num, mult_denom) - - end subroutine mgxsiso_combine - - subroutine mgxsang_combine(this, mat, nuclides, groups, max_order, scatt_type) - class(MgxsAngle), intent(inout) :: this ! The Mgxs to initialize + subroutine mgxsiso_combine(this, temps, mat, nuclides, groups, max_order, & + tolerance, method) + class(MgxsIso), intent(inout) :: this ! The Mgxs to initialize + type(VectorReal), intent(in) :: temps ! Temperatures to obtain [MeV] type(Material), pointer, intent(in) :: mat ! base material type(MgxsContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from integer, intent(in) :: groups ! Number of E groups integer, intent(in) :: max_order ! Maximum requested order - integer, intent(in) :: scatt_type ! Legendre or Tabular Scatt? + real(8), intent(in) :: tolerance ! Tolerance on method + integer, intent(in) :: method ! Type of temperature access + + integer :: i ! loop index over nuclides + integer :: t ! Index in to temps + integer :: gin, gout ! group indices + real(8) :: atom_density ! atom density of a nuclide + real(8) :: norm, nuscatt + integer :: order_dim, nuc_order_dim + real(8), allocatable :: temp_mult(:, :), mult_num(:, :), mult_denom(:, :) + real(8), allocatable :: scatt_coeffs(:, :, :) + integer :: nuc_t + integer, allocatable :: nuc_ts(:) + real(8) :: temp_actual, temp_desired, interp + integer :: scatter_format + type(Jagged2D), allocatable :: nuc_matrix(:) + integer, allocatable :: gmin(:), gmax(:) + type(Jagged2D), allocatable :: jagged_scatt(:) + type(Jagged1D), allocatable :: jagged_mult(:) + + ! Set the meta-data + call mgxs_combine(this, temps, mat, nuclides, max_order, scatter_format, & + order_dim) + + ! Create the Xs Data for each temperature + TEMP_LOOP: do t = 1, temps % size() + ! Allocate and initialize the data needed for macro_xs(i_mat) object + allocate(this % xs(t) % total(groups)) + this % xs(t) % total(:) = ZERO + allocate(this % xs(t) % absorption(groups)) + this % xs(t) % absorption(:) = ZERO + allocate(this % xs(t) % fission(groups)) + this % xs(t) % fission(:) = ZERO + allocate(this % xs(t) % k_fission(groups)) + this % xs(t) % k_fission(:) = ZERO + allocate(this % xs(t) % nu_fission(groups)) + this % xs(t) % nu_fission(:) = ZERO + allocate(this % xs(t) % chi(groups,groups)) + this % xs(t) % chi(:, :) = ZERO + allocate(this % xs(t) % inv_vel(groups)) + this % xs(t) % inv_vel(:) = ZERO + allocate(temp_mult(groups,groups)) + temp_mult(:, :) = ZERO + allocate(mult_num(groups,groups)) + mult_num(:, :) = ZERO + allocate(mult_denom(groups,groups)) + mult_denom(:, :) = ZERO + allocate(scatt_coeffs(order_dim,groups,groups)) + scatt_coeffs(:, :, :) = ZERO + + this % scatter_format = scatter_format + if (scatter_format == ANGLE_LEGENDRE) then + allocate(ScattDataLegendre :: this % xs(t) % scatter) + else if (scatter_format == ANGLE_TABULAR) then + allocate(ScattDataTabular :: this % xs(t) % scatter) + else if (scatter_format == ANGLE_HISTOGRAM) then + allocate(ScattDataHistogram :: this % xs(t) % scatter) + end if + + ! Add contribution from each nuclide in material + NUC_LOOP: do i = 1, mat % n_nuclides + associate(nuc => nuclides(mat % nuclide(i)) % obj) + ! Copy atom density of nuclide in material + atom_density = mat % atom_density(i) + + select case (method) + case (TEMPERATURE_NEAREST) + ! Determine actual temperatures to read + temp_desired = temps % data(i) + allocate(nuc_ts(1)) + nuc_ts(1) = minloc(abs(nuc % kTs - temp_desired), dim=1) + temp_actual = nuc % kTs(nuc_ts(1)) + if (abs(temp_actual - temp_desired) >= K_BOLTZMANN * tolerance) then + call fatal_error("MGXS library does not contain cross sections & + &for " // trim(this % name) // " at or near " // & + trim(to_str(nint(temp_desired / K_BOLTZMANN))) // " K.") + end if + + case (TEMPERATURE_INTERPOLATION) + ! If temperature interpolation or multipole is selected, get a + ! list of bounding temperatures for each actual temperature + ! present in the model + temp_desired = temps % data(i) + allocate(nuc_ts(2)) + do j = 1, size(nuc % kTs) - 1 + if (nuc % kTs(j) <= temp_desired .and. & + temp_desired < nuc % kTs(j + 1)) then + nuc_ts(1) = j + nuc_ts(2) = j + 1 + end if + end do + + call fatal_error("Nuclear data library does not contain cross sections & + &for " // trim(this % name) // " at temperatures that bound " // & + trim(to_str(nint(temp_desired / K_BOLTZMANN))) // " K.") + end select + + select type(nuc) + type is (MgxsIso) + do j = 1, size(nuc_ts) + nuc_t = nuc_ts(j) + if (size(nuc_ts) == 1) then + interp = ONE + else if (j == 1) then + interp = (ONE - (temp_desired - nuc % kTs(nuc_ts(1))) / & + (nuc % kTs(nuc_ts(2)) - nuc % kTs(nuc_ts(1)))) + else + interp = ONE - interp + end if + + ! 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 * interp + this % xs(t) % absorption = this % xs(t) % absorption + & + atom_density * nuc % xs(nuc_t) % absorption * interp + if (nuc % fissionable) then + this % xs(t) % chi = this % xs(t) % chi + & + atom_density * nuc % xs(nuc_t) % chi * interp + this % xs(t) % nu_fission = this % xs(t) % nu_fission + & + atom_density * nuc % xs(nuc_t) % nu_fission * interp + if (allocated(nuc % xs(nuc_t) % fission)) then + this % xs(t) % fission = this % xs(t) % fission + & + atom_density * nuc % xs(nuc_t) % fission * interp + 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 * interp + end if + end if + if (allocated(nuc % xs(nuc_t) % inv_vel)) then + this % xs(t) % inv_vel = this % xs(t) % inv_vel + & + atom_density * nuc % xs(nuc_t) % inv_vel * interp + end if + + ! We will next gather the multiplicity and scattering matrices. + ! To avoid multiple re-allocations as we resize the storage + ! matrix (and/or to avoidlots of duplicate code), we will use a + ! dense matrix for this storage, with a reduction to the sparse + ! format at the end. + + ! Get the multiplicity_matrix + ! To combine from nuclidic data we need to use the final relationship + ! mult_{gg'} = sum_i(N_i*nuscatt_{i,g,g'}) / + ! sum_i(N_i*(nuscatt_{i,g,g'} / mult_{i,g,g'})) + ! Developed as follows: + ! mult_{gg'} = nuScatt{g,g'} / Scatt{g,g'} + ! mult_{gg'} = sum_i(N_i*nuscatt_{i,g,g'}) / sum(N_i*scatt_{i,g,g'}) + ! mult_{gg'} = sum_i(N_i*nuscatt_{i,g,g'}) / + ! sum_i(N_i*(nuscatt_{i,g,g'} / mult_{i,g,g'})) + ! nuscatt_{i,g,g'} can be reconstructed from scatter % energy and + ! scatter % scattxs + do gin = 1, groups + do gout = nuc % xs(nuc_t) % scatter % gmin(gin), nuc % xs(nuc_t) % scatter % gmax(gin) + nuscatt = nuc % xs(nuc_t) % scatter % scattxs(gin) * & + nuc % xs(nuc_t) % scatter % energy(gin) % data(gout) + mult_num(gout, gin) = mult_num(gout, gin) + atom_density * & + nuscatt * interp + if (nuc % xs(nuc_t) % scatter % mult(gin) % data(gout) > ZERO) then + mult_denom(gout, gin) = mult_denom(gout,gin) + atom_density * & + nuscatt / nuc % xs(nuc_t) % scatter % mult(gin) % data(gout) * & + interp + else + ! Avoid division by zero + mult_denom(gout, gin) = mult_denom(gout,gin) + atom_density * & + interp + end if + end do + end do + + ! Get the complete scattering matrix + nuc_order_dim = size(nuc % xs(nuc_t) % scatter % dist(1) % data, dim=1) + nuc_order_dim = min(nuc_order_dim, order_dim) + call nuc % xs(nuc_t) % scatter % get_matrix(nuc_order_dim, & + nuc_matrix) + do gin = 1, groups + do gout = nuc % xs(nuc_t) % scatter % gmin(gin), & + nuc % xs(nuc_t) % scatter % gmax(gin) + scatt_coeffs(1:nuc_order_dim, gout, gin) = & + scatt_coeffs(1: nuc_order_dim, gout, gin) + & + atom_density * interp * & + nuc_matrix(gin) % data(1:nuc_order_dim, gout) + end do + end do + end do + + type is (MgxsAngle) + call fatal_error("Invalid passing of MgxsAngle to MgxsIso object") + end select + + ! Obtain temp_mult + do gin = 1, groups + do gout = 1, groups + if (mult_denom(gout, gin) > ZERO) then + temp_mult(gout, gin) = mult_num(gout, gin) / mult_denom(gout, gin) + else + temp_mult(gout, gin) = ONE + end if + end do + end do + + ! Now create our jagged data from the dense data + call jagged_from_dense_2D(scatt_coeffs, jagged_scatt, gmin, gmax) + call jagged_from_dense_1D(temp_mult, jagged_mult) + + ! Initialize the ScattData Object + call this % xs(t) % scatter % init(gmin, gmax, jagged_mult, & + jagged_scatt) + + ! Now normalize chi + if (mat % fissionable) then + do gin = 1, groups + norm = sum(this % xs(t) % chi(:, gin)) + if (norm > ZERO) then + this % xs(t) % chi(:, gin) = this % xs(t) % chi(:, gin) / norm + end if + end do + end if + + ! Deallocate temporaries + deallocate(jagged_mult, jagged_scatt, gmin, gmax, scatt_coeffs, & + temp_mult, mult_num, mult_denom) + end associate ! nuc + end do NUC_LOOP + end do TEMP_LOOP + + end subroutine mgxsiso_combine + + subroutine mgxsang_combine(this, temps, mat, nuclides, groups, max_order, & + tolerance, method) + class(MgxsAngle), intent(inout) :: this ! The Mgxs to initialize + type(VectorReal), intent(in) :: temps ! Temperatures to obtain + type(Material), pointer, intent(in) :: mat ! base material + type(MgxsContainer), intent(in) :: nuclides(:) ! List of nuclides to harvest from + integer, intent(in) :: groups ! Number of E groups + integer, intent(in) :: max_order ! Maximum requested order + real(8), intent(in) :: tolerance ! Tolerance on method + integer, intent(in) :: method ! Type of temperature access integer :: i ! loop index over nuclides + integer :: t ! temperature loop index integer :: gin, gout ! group indices real(8) :: atom_density ! atom density of a nuclide integer :: ipol, iazi, n_pol, n_azi real(8) :: norm, nuscatt - integer :: mat_max_order, order, order_dim, nuc_order_dim + integer :: order_dim, nuc_order_dim real(8), allocatable :: temp_mult(:, :, :, :), mult_num(:, :, :, :) real(8), allocatable :: mult_denom(:, :, :, :), scatt_coeffs(:, :, :, :, :) + integer :: nuc_t + integer, allocatable :: nuc_ts(:) + real(8) :: temp_actual, temp_desired, interp + integer :: scatter_format + type(Jagged2D), allocatable :: nuc_matrix(:) + integer, allocatable :: gmin(:), gmax(:) + type(Jagged2D), allocatable :: jagged_scatt(:) + type(Jagged1D), allocatable :: jagged_mult(:) ! Set the meta-data - call mgxs_combine(this, mat, scatt_type) + call mgxs_combine(this, temps, mat, nuclides, max_order, scatter_format, & + order_dim) ! Get the number of each polar and azi angles and make sure all the ! NuclideAngle types have the same number of these angles @@ -1392,266 +1527,479 @@ module mgxs_header end select end do - ! Determine the scattering type of our data and ensure all scattering orders - ! are the same. - select type(nuc => nuclides(mat % nuclide(1)) % obj) - type is (MgxsAngle) - order = size(nuc % scatter(1,1) % obj % dist(1) % data, dim=1) - end select - ! If we have tabular only data, then make sure all datasets have same size - if (scatt_type == ANGLE_HISTOGRAM) then - ! Check all scattering data to ensure it is the same size - ! order = size(nuclides(mat % nuclide(1)) % obj % scatter % data,dim=1) - do i = 2, mat % n_nuclides - select type(nuc => nuclides(mat % nuclide(i)) % obj) - type is (MgxsAngle) - if (order /= size(nuc % scatter(1,1) % obj % dist(1) % data, dim=1)) & - call fatal_error("All histogram scattering entries must be& - & same length!") - end select - end do - ! Ok, got our order, store the dimensionality - order_dim = order + ! Create the Xs Data for each temperature + TEMP_LOOP: do t = 1, temps % size() + ! Allocate and initialize the data needed for macro_xs(i_mat) object + allocate(this % xs(t) % total(groups, n_azi, n_pol)) + this % xs(t) % total = ZERO + allocate(this % xs(t) % absorption(groups, n_azi, n_pol)) + this % xs(t) % absorption = ZERO + allocate(this % xs(t) % fission(groups, n_azi, n_pol)) + this % xs(t) % fission = ZERO + allocate(this % xs(t) % k_fission(groups, n_azi, n_pol)) + this % xs(t) % k_fission = ZERO + allocate(this % xs(t) % nu_fission(groups, n_azi, n_pol)) + this % xs(t) % nu_fission = ZERO + allocate(this % xs(t) % chi(groups, groups, n_azi, n_pol)) + this % xs(t) % chi = ZERO + allocate(this % xs(t) % inv_vel(groups, n_azi, n_pol)) + this % xs(t) % inv_vel = ZERO + allocate(temp_mult(groups, groups, n_azi, n_pol)) + temp_mult = ZERO + allocate(mult_num(groups, groups, n_azi, n_pol)) + mult_num = ZERO + allocate(mult_denom(groups, groups, n_azi, n_pol)) + mult_denom = ZERO + allocate(scatt_coeffs(order_dim, groups, groups, n_azi, n_pol)) + scatt_coeffs = ZERO - ! Set our Scatter Object Type - allocate(this % scatter(n_azi, n_pol)) + allocate(this % xs(t) % scatter(n_azi, n_pol)) do ipol = 1, n_pol do iazi = 1, n_azi - allocate(ScattDataHistogram :: this % scatter(iazi, ipol) % obj) - end do - end do - - else if (scatt_type == ANGLE_TABULAR) then - ! Check all scattering data to ensure it is the same size - do i = 2, mat % n_nuclides - select type(nuc => nuclides(mat % nuclide(i)) % obj) - type is (MgxsAngle) - if (order /= size(nuc % scatter(1, 1) % obj % dist(1) % data, dim=1)) & - call fatal_error("All tabular scattering entries must be& - & same length!") - end select - end do - ! Ok, got our order, store the dimensionality - order_dim = order - - ! Set our Scatter Object Type - allocate(this % scatter(n_azi, n_pol)) - do ipol = 1, n_pol - do iazi = 1, n_azi - allocate(ScattDataTabular :: this % scatter(iazi, ipol) % obj) - end do - end do - - else if (scatt_type == ANGLE_LEGENDRE) then - ! Need to determine the maximum scattering order of all data in this material - mat_max_order = 0 - do i = 1, mat % n_nuclides - select type(nuc => nuclides(mat % nuclide(i)) % obj) - type is (MgxsAngle) - if (size(nuc % scatter(1,1) % obj % dist(1) % data, dim=1) > mat_max_order) & - mat_max_order = size(nuc % scatter(1,1) % obj% dist(1) % data, dim=1) - end select - end do - - ! Now need to compare this material maximum scattering order with - ! the problem wide max scatt order and use whichever is lower - order = min(mat_max_order, max_order) - ! Ok, got our order, store the dimensionality - order_dim = order + 1 - - ! Set our Scatter Object Type - allocate(this % scatter(n_azi, n_pol)) - do ipol = 1, n_pol - do iazi = 1, n_azi - allocate(ScattDataLegendre :: this % scatter(iazi, ipol) % obj) - end do - end do - end if - - ! Allocate and initialize data within macro_xs(i_mat) object - allocate(this % total(groups, n_azi, n_pol)) - this % total(:, :, :) = ZERO - allocate(this % absorption(groups, n_azi, n_pol)) - this % absorption(:, :, :) = ZERO - allocate(this % fission(groups, n_azi, n_pol)) - this % fission(:, :, :) = ZERO - allocate(this % k_fission(groups, n_azi, n_pol)) - this % k_fission(:, :, :) = ZERO - allocate(this % nu_fission(groups, n_azi, n_pol)) - this % nu_fission(:, :, :) = ZERO - allocate(this % chi(groups, groups, n_azi, n_pol)) - this % chi(:, :, :, :) = ZERO - allocate(temp_mult(groups, groups, n_azi, n_pol)) - temp_mult(:, :, :, :) = ZERO - allocate(mult_num(groups, groups, n_azi, n_pol)) - mult_num(:, :, :, :) = ZERO - allocate(mult_denom(groups, groups, n_azi, n_pol)) - mult_denom(:, :, :, :) = ZERO - allocate(scatt_coeffs(order_dim, groups, groups, n_azi, n_pol)) - scatt_coeffs(:, :, :, :, :) = ZERO - - ! Add contribution from each nuclide in material - do i = 1, mat % n_nuclides - ! Copy atom density of nuclide in material - atom_density = mat % atom_density(i) - - ! Perform our operations which depend upon the type - select type(nuc => nuclides(mat % nuclide(i)) % obj) - type is (MgxsIso) - call fatal_error("Invalid passing of MgxsIso to MgxsAngle object") - type is (MgxsAngle) - ! Add contributions to total, absorption, and fission data (if necessary) - this % total(:, :, :) = this % total(:, :, :) + & - atom_density * nuc % total(:, :, :) - this % absorption(:, :, :) = this % absorption(:, :, :) + & - atom_density * nuc % absorption(:, :, :) - if (nuc % fissionable) then - this % chi = this % chi + atom_density * nuc % chi - this % nu_fission(:, :, :) = this % nu_fission(:, :, :) + & - atom_density * nuc % nu_fission(:, :, :) - if (allocated(nuc % fission)) then - this % fission(:, :, :) = this % fission(:, :, :) + & - atom_density * nuc % fission(:, :, :) + if (scatter_format == ANGLE_LEGENDRE) then + allocate(ScattDataLegendre :: & + this % xs(t) % scatter(iazi, ipol) % obj) + else if (scatter_format == ANGLE_TABULAR) then + allocate(ScattDataTabular :: & + this % xs(t) % scatter(iazi, ipol) % obj) + else if (scatter_format == ANGLE_HISTOGRAM) then + allocate(ScattDataHistogram :: & + this % xs(t) % scatter(iazi, ipol) % obj) end if - if (allocated(nuc % k_fission)) then - this % k_fission(:, :, :) = this % k_fission(:, :, :) + & - atom_density * nuc % k_fission(:, :, :) - end if - end if + end do + end do - ! Get the multiplication matrix - ! To combine from nuclidic data we need to use the final relationship - ! mult_{gg'} = sum_i(N_i*nuscatt_{i,g,g'}) / - ! sum_i(N_i*(nuscatt_{i,g,g'} / mult_{i,g,g'})) - ! Developed as follows: - ! mult_{gg'} = nuScatt{g,g'} / Scatt{g,g'} - ! mult_{gg'} = sum_i(N_i*nuscatt_{i,g,g'}) / sum(N_i*scatt_{i,g,g'}) - ! mult_{gg'} = sum_i(N_i*nuscatt_{i,g,g'}) / - ! sum_i(N_i*(nuscatt_{i,g,g'} / mult_{i,g,g'})) - ! nuscatt_{i,g,g'} can be reconstructed from scatter % energy and - ! scatter % scattxs - do ipol = 1, n_pol - do iazi = 1, n_azi - do gin = 1, groups - do gout = nuc % scatter(iazi, ipol) % obj % gmin(gin), & - nuc % scatter(iazi, ipol) % obj % gmax(gin) - nuscatt = nuc % scatter(iazi, ipol) % obj % scattxs(gin) * & - nuc % scatter(iazi, ipol) % obj % energy(gin) % data(gout) - mult_num(gout, gin, iazi, ipol) = mult_num(gout, gin, iazi, ipol) + & - atom_density * nuscatt - if (nuc % scatter(iazi, ipol) % obj % mult(gin) % data(gout) > ZERO) then - mult_denom(gout, gin, iazi, ipol) = & - mult_denom(gout, gin, iazi, ipol) + & - atom_density * nuscatt / & - nuc % scatter(iazi, ipol) % obj % mult(gin) % data(gout) - else - ! Avoid division by zero - mult_denom(gout, gin, iazi, ipol) = & - mult_denom(gout,gin, iazi, ipol) + atom_density + ! Add contribution from each nuclide in material + NUC_LOOP: do i = 1, mat % n_nuclides + associate(nuc => nuclides(mat % nuclide(i)) % obj) + + select case (method) + case (TEMPERATURE_NEAREST) + ! Determine actual temperatures to read + temp_desired = temps % data(i) + allocate(nuc_ts(1)) + nuc_ts(1) = minloc(abs(nuc % kTs - temp_desired), dim=1) + temp_actual = nuc % kTs(nuc_ts(1)) + if (abs(temp_actual - temp_desired) >= K_BOLTZMANN * tolerance) then + call fatal_error("MGXS library does not contain cross sections & + &for " // trim(this % name) // " at or near " // & + trim(to_str(nint(temp_desired / K_BOLTZMANN))) // " K.") + end if + + case (TEMPERATURE_INTERPOLATION) + ! If temperature interpolation or multipole is selected, get a + ! list of bounding temperatures for each actual temperature + ! present in the model + temp_desired = temps % data(i) + allocate(nuc_ts(2)) + do j = 1, size(nuc % kTs) - 1 + if (nuc % kTs(j) <= temp_desired .and. & + temp_desired < nuc % kTs(j + 1)) then + nuc_ts(1) = j + nuc_ts(2) = j + 1 + end if + end do + + call fatal_error("Nuclear data library does not contain cross sections & + &for " // trim(this % name) // " at temperatures that bound " // & + trim(to_str(nint(temp_desired / K_BOLTZMANN))) // " K.") + end select + + ! Copy atom density of nuclide in material + atom_density = mat % atom_density(i) + + select type(nuc) + type is (MgxsAngle) + do j = 1, size(nuc_ts) + nuc_t = nuc_ts(j) + if (size(nuc_ts) == 1) then + interp = ONE + else if (j == 1) then + interp = (ONE - (temp_desired - nuc % kTs(nuc_ts(1))) / & + (nuc % kTs(nuc_ts(2)) - nuc % kTs(nuc_ts(1)))) + else + interp = ONE - interp + end if + ! 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 * interp + this % xs(t) % absorption = this % xs(t) % absorption + & + atom_density * nuc % xs(nuc_t) % absorption * interp + if (allocated(nuc % xs(nuc_t) % inv_vel)) then + this % xs(t) % inv_vel = this % xs(t) % inv_vel + & + atom_density * nuc % xs(nuc_t) % inv_vel * interp + end if + if (nuc % fissionable) then + this % xs(t) % chi = this % xs(t) % chi + & + atom_density * nuc % xs(nuc_t) % chi * interp + this % xs(t) % nu_fission = this % xs(t) % nu_fission + & + atom_density * nuc % xs(nuc_t) % nu_fission * interp + if (allocated(nuc % xs(nuc_t) % fission)) then + this % xs(t) % fission = this % xs(t) % fission + & + atom_density * nuc % xs(nuc_t) % fission * interp 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 * interp + end if + end if + + ! We will next gather the multiplicity and scattering matrices. + ! To avoid multiple re-allocations as we resize the storage + ! matrix (and/or to avoidlots of duplicate code), we will use a + ! dense matrix for this storage, with a reduction to the sparse + ! format at the end. + + ! Get the multiplicity_matrix + ! To combine from nuclidic data we need to use the final relationship + ! mult_{gg'} = sum_i(N_i*nuscatt_{i,g,g'}) / + ! sum_i(N_i*(nuscatt_{i,g,g'} / mult_{i,g,g'})) + ! Developed as follows: + ! mult_{gg'} = nuScatt{g,g'} / Scatt{g,g'} + ! mult_{gg'} = sum_i(N_i*nuscatt_{i,g,g'}) / sum(N_i*scatt_{i,g,g'}) + ! mult_{gg'} = sum_i(N_i*nuscatt_{i,g,g'}) / + ! sum_i(N_i*(nuscatt_{i,g,g'} / mult_{i,g,g'})) + ! nuscatt_{i,g,g'} can be reconstructed from scatter % energy and + ! scatter % scattxs + do ipol = 1, n_pol + do iazi = 1, n_azi + do gin = 1, groups + do gout = nuc % xs(nuc_t) % scatter(iazi, ipol) %obj % gmin(gin), & + nuc % xs(nuc_t) % scatter(iazi, ipol) % obj % gmax(gin) + nuscatt = nuc % xs(nuc_t) % scatter(iazi, ipol) % obj % scattxs(gin) * & + nuc % xs(nuc_t) % scatter(iazi, ipol) % obj % energy(gin) % data(gout) + mult_num(gout, gin, iazi, ipol) = & + mult_num(gout, gin, iazi, ipol) + atom_density * & + nuscatt * interp + if (nuc % xs(nuc_t) % scatter(iazi, ipol) % obj % mult(gin) % data(gout) > ZERO) then + mult_denom(gout, gin, iazi, ipol) = & + mult_denom(gout, gin, iazi, ipol) + atom_density * & + interp * nuscatt / & + nuc % xs(nuc_t) % scatter(iazi, ipol) % obj % mult(gin) % data(gout) + else + ! Avoid division by zero + mult_denom(gout, gin, iazi, ipol) = & + mult_denom(gout, gin, iazi, ipol) + atom_density * & + interp + end if + end do + end do + + ! Get the complete scattering matrix + nuc_order_dim = & + size(nuc % xs(nuc_t) % scatter(iazi, ipol) % obj % & + dist(1) % data, dim=1) + nuc_order_dim = min(nuc_order_dim, order_dim) + call nuc % xs(nuc_t) % scatter(iazi, ipol) % obj % & + get_matrix(nuc_order_dim, nuc_matrix) + do gin = 1, groups + do gout = & + nuc % xs(nuc_t) % scatter(iazi, ipol) % obj % gmin(gin), & + nuc % xs(nuc_t) % scatter(iazi, ipol) % obj % gmax(gin) + scatt_coeffs(1:nuc_order_dim, gout, gin, iazi, ipol) = & + scatt_coeffs(1: nuc_order_dim, gout, gin, iazi, ipol) + & + atom_density * interp * & + nuc_matrix(gin) % data(1:nuc_order_dim, gout) + end do ! gout + end do ! gin + end do ! iazi + end do ! ipol + end do + type is (MgxsIso) + call fatal_error("Invalid passing of MgxsIso to MgxsAngle object") + end select + + ! Obtain temp_mult, create jaged arrays and initialize the + ! ScattData object. + do ipol = 1, n_pol + do iazi = 1, n_azi + ! Obtain temp_mult + do gin = 1, groups + do gout = 1, groups + if (mult_denom(gout, gin, iazi, ipol) > ZERO) then + temp_mult(gout, gin, iazi, ipol) = & + mult_num(gout, gin, iazi, ipol) / & + mult_denom(gout, gin, iazi, ipol) + else + temp_mult(gout, gin, iazi, ipol) = ONE + end if + end do end do + + ! 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 + call this % xs(t) % scatter(iazi, ipol) % obj % init(gmin, & + gmax, jagged_mult, jagged_scatt) + deallocate(jagged_scatt, jagged_mult, gmin, gmax) end do end do - end do - ! Get the complete scattering matrix - nuc_order_dim = size(nuc % scatter(1, 1) % obj % dist(1) % data, dim=1) - do ipol = 1, n_pol - do iazi = 1, n_azi - scatt_coeffs(1:min(nuc_order_dim, order_dim), :, :, iazi, ipol) = & - scatt_coeffs(1:min(nuc_order_dim, order_dim), :, :, iazi, ipol) + & - atom_density * nuc % scatter(iazi, ipol) % obj % get_matrix(& - min(nuc_order_dim, order_dim)) - end do - end do - end select - end do + ! Now normalize chi + if (mat % fissionable) then + do ipol = 1, n_pol + do iazi = 1, n_azi + do gin = 1, groups + norm = sum(this % xs(t) % chi(:, gin, iazi, ipol)) + if (norm > ZERO) then + this % xs(t) % chi(:, gin, iazi, ipol) = & + this % xs(t) % chi(:, gin, iazi, ipol) / norm + end if + end do + end do + end do + end if - ! Obtain temp_mult - do ipol = 1, n_pol - do iazi = 1, n_azi - do gin = 1, groups - do gout = 1, groups - if (mult_denom(gout, gin, iazi, ipol) > ZERO) then - temp_mult(gout, gin, iazi, ipol) = & - mult_num(gout, gin, iazi, ipol) / & - mult_denom(gout, gin, iazi, ipol) - else - temp_mult(gout, gin, iazi, ipol) = ONE - end if - end do - end do - end do - end do - - ! Initialize the ScattData Object - do ipol = 1, n_pol - do iazi = 1, n_azi - call this % scatter(iazi, ipol) % obj % init( & - temp_mult(:, :, iazi, ipol), scatt_coeffs(:, :, :, iazi, ipol)) - end do - end do - - ! Now normalize chi - if (mat % fissionable) then - do ipol = 1, n_pol - do iazi = 1, n_azi - do gin = 1, groups - norm = sum(this % chi(:, gin, iazi, ipol)) - if (norm > ZERO) then - this % chi(:, gin, iazi, ipol) = this % chi(:, gin, iazi, ipol) / norm - end if - end do - end do - end do - end if - - ! Deallocate temporaries for the next material - deallocate(scatt_coeffs, temp_mult) + ! Deallocate temporaries + deallocate(scatt_coeffs, temp_mult, mult_num, mult_denom) + end associate ! nuc + end do NUC_LOOP + end do TEMP_LOOP end subroutine mgxsang_combine +!=============================================================================== +! MGXS*_GET_XS returns the requested data cross section data +!=============================================================================== + + pure function mgxsiso_get_xs(this, xstype, gin, gout, uvw, mu) result(xs) + class(MgxsIso), intent(in) :: this ! The Xs to get data from + character(*) , intent(in) :: xstype ! Type of xs requested + integer, intent(in) :: gin ! Incoming Energy group + integer, optional, intent(in) :: gout ! Outgoing Energy group + real(8), optional, intent(in) :: uvw(3) ! Requested Angle + real(8), optional, intent(in) :: mu ! Change in angle + real(8) :: xs ! Requested x/s + integer :: t ! temperature index + + t = this % index_temp + + select case(xstype) + case('total') + xs = this % xs(t) % total(gin) + case('absorption') + xs = this % xs(t) % absorption(gin) + case('fission') + if (allocated(this % xs(t) % fission)) then + xs = this % xs(t) % fission(gin) + else + xs = ZERO + end if + case('kappa_fission') + if (allocated(this % xs(t) % k_fission)) then + xs = this % xs(t) % k_fission(gin) + else + xs = ZERO + end if + case('nu_fission') + xs = this % xs(t) % nu_fission(gin) + case('chi') + if (present(gout)) then + xs = this % xs(t) % chi(gout,gin) + else + ! Not sure youd want a 1 or a 0, but here you go! + xs = sum(this % xs(t) % chi(:, gin)) + end if + case('scatter') + if (present(gout)) then + if (gout < this % xs(t) % scatter % gmin(gin) .or. & + gout > this % xs(t) % scatter % gmax(gin)) then + xs = ZERO + else + xs = this % xs(t) % scatter % scattxs(gin) * & + this % xs(t) % scatter % energy(gin) % data(gout) + end if + else + xs = this % xs(t) % scatter % scattxs(gin) + end if + case('scatter/mult') + if (present(gout)) then + if (gout < this % xs(t) % scatter % gmin(gin) .or. & + gout > this % xs(t) % scatter % gmax(gin)) then + xs = ZERO + else + xs = this % xs(t) % scatter % scattxs(gin) * & + this % xs(t) % scatter % energy(gin) % data(gout) / & + this % xs(t) % scatter % mult(gin) % data(gout) + end if + else + xs = this % xs(t) % scatter % scattxs(gin) / & + (dot_product(this % xs(t) % scatter % mult(gin) % data, & + this % xs(t) % scatter % energy(gin) % data)) + end if + case('scatter*f_mu/mult','scatter*f_mu') + if (present(gout)) then + if (gout < this % xs(t) % scatter % gmin(gin) .or. & + gout > this % xs(t) % scatter % gmax(gin)) then + xs = ZERO + else + xs = this % xs(t) % scatter % scattxs(gin) * & + this % xs(t) % scatter % energy(gin) % data(gout) * & + this % xs(t) % scatter % calc_f(gin, gout, mu) + if (xstype == 'scatter*f_mu/mult') then + xs = xs / this % xs(t) % scatter % mult(gin) % data(gout) + end if + end if + else + xs = ZERO + ! TODO (Not likely needed) + ! (asking for f_mu without asking for a group or mu would mean the + ! user of this code wants the complete 1-outgoing group distribution + ! which Im not sure what they would do with that. + end if + case('inv_vel') + xs = this % xs(t) % inv_vel(gin) + case default + xs = ZERO + end select + end function mgxsiso_get_xs + + pure function mgxsang_get_xs(this, xstype, gin, gout, uvw, mu) result(xs) + class(MgxsAngle), intent(in) :: this ! The Mgxs to initialize + character(*) , intent(in) :: xstype ! Type of xs requested + integer, intent(in) :: gin ! Incoming Energy group + integer, optional, intent(in) :: gout ! Outgoing Energy group + real(8), optional, intent(in) :: uvw(3) ! Requested Angle + real(8), optional, intent(in) :: mu ! Change in angle + real(8) :: xs ! Requested x/s + + integer :: iazi, ipol, t + + t = this % index_temp + + if (present(uvw)) then + call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) + select case(xstype) + case('total') + xs = this % xs(t) % total(gin, iazi, ipol) + case('absorption') + xs = this % xs(t) % absorption(gin, iazi, ipol) + case('fission') + if (allocated(this % xs(t) % fission)) then + xs = this % xs(t) % fission(gin, iazi, ipol) + else + xs = ZERO + end if + case('kappa_fission') + if (allocated(this % xs(t) % k_fission)) then + xs = this % xs(t) % k_fission(gin, iazi, ipol) + else + xs = ZERO + end if + case('nu_fission') + xs = this % xs(t) % nu_fission(gin, iazi, ipol) + case('chi') + if (present(gout)) then + xs = this % xs(t) % chi(gout, gin, iazi, ipol) + else + ! Not sure you would want a 1 or a 0, but here you go! + xs = sum(this % xs(t) % chi(:, gin, iazi, ipol)) + end if + case('scatter') + if (present(gout)) then + if (gout < this % xs(t) % scatter(iazi, ipol) % obj % gmin(gin) .or. & + gout > this % xs(t) % scatter(iazi, ipol) % obj % gmax(gin)) then + xs = ZERO + else + xs = this % xs(t) % scatter(iazi, ipol) % obj % scattxs(gin) * & + this % xs(t) % scatter(iazi, ipol) % obj % energy(gin) % data(gout) + end if + else + xs = this % xs(t) % scatter(iazi, ipol) % obj % scattxs(gin) + end if + case('scatter/mult') + if (present(gout)) then + if (gout < this % xs(t) % scatter(iazi, ipol) % obj % gmin(gin) .or. & + gout > this % xs(t) % scatter(iazi, ipol) % obj % gmax(gin)) then + xs = ZERO + else + xs = this % xs(t) % scatter(iazi, ipol) % obj % scattxs(gin) * & + this % xs(t) % scatter(iazi, ipol) % obj % energy(gin) % data(gout) / & + this % xs(t) % scatter(iazi, ipol) % obj % mult(gin) % data(gout) + end if + else + xs = this % xs(t) % scatter(iazi, ipol) % obj % scattxs(gin) / & + (dot_product(this % xs(t) % scatter(iazi, ipol) % obj % mult(gin) % data, & + this % xs(t) % scatter(iazi, ipol) % obj % energy(gin) % data)) + end if + case('scatter*f_mu/mult','scatter*f_mu') + if (present(gout)) then + if (gout < this % xs(t) % scatter(iazi, ipol) % obj % gmin(gin) .or. & + gout > this % xs(t) % scatter(iazi, ipol) % obj % gmax(gin)) then + xs = ZERO + else + xs = this % xs(t) % scatter(iazi, ipol) % obj % scattxs(gin) * & + this % xs(t) % scatter(iazi, ipol) % obj % energy(gin) % data(gout) + xs = xs * this % xs(t) % scatter(iazi, ipol) % obj % calc_f(gin, gout, mu) + if (xstype == 'scatter*f_mu/mult') then + xs = xs / & + this % xs(t) % scatter(iazi, ipol) % obj % mult(gin) % data(gout) + end if + end if + else + xs = ZERO + ! TODO (Not likely needed) + ! (asking for f_mu without asking for a group or mu would mean the + ! user of this code wants the complete 1-outgoing group distribution + ! which Im not sure what they would do with that. + end if + case('inv_vel') + xs = this % xs(t) % inv_vel(gin, iazi, ipol) + case default + xs = ZERO + end select + else + xs = ZERO + end if + end function mgxsang_get_xs + !=============================================================================== ! MGXS*_SAMPLE_FISSION_ENERGY samples the outgoing energy from a fission event !=============================================================================== function mgxsiso_sample_fission_energy(this, gin, uvw) result(gout) class(MgxsIso), intent(in) :: this ! Data to work with - integer, intent(in) :: gin ! Incoming energy group - real(8), intent(in) :: uvw(3) ! Particle Direction - integer :: gout ! Sampled outgoing group - real(8) :: xi ! Our random number - real(8) :: prob ! Running probability + integer, intent(in) :: gin ! Incoming energy group + real(8), intent(in) :: uvw(3) ! Particle Direction + integer :: gout ! Sampled outgoing group + real(8) :: xi ! Our random number + real(8) :: prob ! Running probability xi = prn() gout = 1 - prob = this % chi(gout,gin) + prob = this % xs(this % index_temp) % chi(gout,gin) do while (prob < xi) gout = gout + 1 - prob = prob + this % chi(gout,gin) + prob = prob + this % xs(this % index_temp) % chi(gout,gin) end do end function mgxsiso_sample_fission_energy function mgxsang_sample_fission_energy(this, gin, uvw) result(gout) class(MgxsAngle), intent(in) :: this ! Data to work with - integer, intent(in) :: gin ! Incoming energy group - real(8), intent(in) :: uvw(3) ! Particle Direction - integer :: gout ! Sampled outgoing group - real(8) :: xi ! Our random number - real(8) :: prob ! Running probability - integer :: iazi, ipol + integer, intent(in) :: gin ! Incoming energy group + real(8), intent(in) :: uvw(3) ! Particle Direction + integer :: gout ! Sampled outgoing group + real(8) :: xi ! Our random number + real(8) :: prob ! Running probability + integer :: iazi, ipol ! Angle indices call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) xi = prn() gout = 1 - prob = this % chi(gout, gin, iazi, ipol) + prob = this % xs(this % index_temp) % chi(gout, gin, iazi, ipol) do while (prob < xi) gout = gout + 1 - prob = prob + this % chi(gout, gin, iazi, ipol) + prob = prob + this % xs(this % index_temp) % chi(gout, gin, iazi, ipol) end do end function mgxsang_sample_fission_energy @@ -1662,28 +2010,29 @@ module mgxs_header subroutine mgxsiso_sample_scatter(this, uvw, gin, gout, mu, wgt) class(MgxsIso), intent(in) :: this - real(8), intent(in) :: uvw(3) ! Incoming neutron direction - integer, intent(in) :: gin ! Incoming neutron group - integer, intent(out) :: gout ! Sampled outgoin group - real(8), intent(out) :: mu ! Sampled change in angle - real(8), intent(inout) :: wgt ! Particle weight + real(8), intent(in) :: uvw(3) ! Incoming neutron direction + integer, intent(in) :: gin ! Incoming neutron group + integer, intent(out) :: gout ! Sampled outgoin group + real(8), intent(out) :: mu ! Sampled change in angle + real(8), intent(inout) :: wgt ! Particle weight - call this % scatter % sample(gin, gout, mu, wgt) + call this % xs(this % index_temp) % scatter % sample(gin, gout, mu, wgt) end subroutine mgxsiso_sample_scatter subroutine mgxsang_sample_scatter(this, uvw, gin, gout, mu, wgt) class(MgxsAngle), intent(in) :: this - real(8), intent(in) :: uvw(3) ! Incoming neutron direction - integer, intent(in) :: gin ! Incoming neutron group - integer, intent(out) :: gout ! Sampled outgoin group - real(8), intent(out) :: mu ! Sampled change in angle - real(8), intent(inout) :: wgt ! Particle weight + real(8), intent(in) :: uvw(3) ! Incoming neutron direction + integer, intent(in) :: gin ! Incoming neutron group + integer, intent(out) :: gout ! Sampled outgoin group + real(8), intent(out) :: mu ! Sampled change in angle + real(8), intent(inout) :: wgt ! Particle weight integer :: iazi, ipol ! Angular indices call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) - call this % scatter(iazi, ipol) % obj % sample(gin, gout, mu, wgt) + call this % xs(this % index_temp) % scatter(iazi, ipol) % obj % sample( & + gin, gout, mu, wgt) end subroutine mgxsang_sample_scatter @@ -1698,11 +2047,11 @@ module mgxs_header real(8), intent(in) :: uvw(3) ! Incoming neutron direction type(MaterialMacroXS), intent(inout) :: xs ! Resultant Mgxs Data - xs % total = this % total(gin) - xs % elastic = this % scatter % scattxs(gin) - xs % absorption = this % absorption(gin) - xs % fission = this % fission(gin) - xs % nu_fission = this % nu_fission(gin) + xs % total = this % xs(this % index_temp) % total(gin) + xs % elastic = this % xs(this % index_temp) % scatter % scattxs(gin) + xs % absorption = this % xs(this % index_temp) % absorption(gin) + xs % fission = this % xs(this % index_temp) % fission(gin) + xs % nu_fission = this % xs(this % index_temp) % nu_fission(gin) end subroutine mgxsiso_calculate_xs @@ -1715,16 +2064,34 @@ module mgxs_header integer :: iazi, ipol call find_angle(this % polar, this % azimuthal, uvw, iazi, ipol) - xs % total = this % total(gin, iazi, ipol) - xs % elastic = this % scatter(iazi, ipol) % obj % scattxs(gin) - xs % absorption = this % absorption(gin, iazi, ipol) - xs % fission = this % fission(gin, iazi, ipol) - xs % nu_fission = this % nu_fission(gin, iazi, ipol) + xs % total = this % xs(this % index_temp) % & + total(gin, iazi, ipol) + xs % elastic = this % xs(this % index_temp) % & + scatter(iazi, ipol) % obj % scattxs(gin) + xs % absorption = this % xs(this % index_temp) % & + absorption(gin, iazi, ipol) + xs % fission = this % xs(this % index_temp) % & + fission(gin, iazi, ipol) + xs % nu_fission = this % xs(this % index_temp) % & + nu_fission(gin, iazi, ipol) end subroutine mgxsang_calculate_xs !=============================================================================== -! find_angle finds the closest angle on the data grid and returns that index +! MGXS_FIND_TEMPERATURE sets the temperature index for the given +! sqrt(temperature), (with temperature in units of MeV) +!=============================================================================== + + subroutine mgxs_find_temperature(this, sqrtkT) + class(Mgxs), intent(inout) :: this + real(8), intent(in) :: sqrtkT ! Temperature (in units of of MeV) + + this % index_temp = minloc(abs(this % kTs - (sqrtkT * sqrtkT)), dim=1) + + end subroutine mgxs_find_temperature + +!=============================================================================== +! FIND_ANGLE finds the closest angle on the data grid and returns that index !=============================================================================== pure subroutine find_angle(polar, azimuthal, uvw, i_azi, i_pol) diff --git a/src/nuclide_header.F90 b/src/nuclide_header.F90 index 5085acb416..63bd4417bc 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, & + object_exists, get_name, get_groups use list_header, only: ListInt use math, only: evaluate_legendre use multipole_header, only: MultipoleArray @@ -196,10 +195,6 @@ module nuclide_header logical, intent(in) :: master ! if this is the master proc 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 @@ -210,21 +205,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_WORD_LEN), allocatable :: dset_names(:) + character(MAX_WORD_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:)) @@ -336,12 +331,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 @@ -357,8 +350,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 (object_exists(group_id, 'urr')) then this % urr_present = .true. allocate(this % urr_data(n_temperature)) @@ -399,8 +391,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 (object_exists(group_id, 'total_nu')) then nu_group = open_group(group_id, 'total_nu') ! Read total nu data @@ -419,9 +410,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 (object_exists(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/output.F90 b/src/output.F90 index 03496decbc..8127725a68 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -856,8 +856,13 @@ contains write(UNIT=unit_tally, FMT='(1X,2A,1X,A)') repeat(" ", indent), & "Total Material" else - write(UNIT=unit_tally, FMT='(1X,2A,1X,A)') repeat(" ", indent), & - trim(nuclides(i_nuclide) % name) + if (run_CE) then + write(UNIT=unit_tally, FMT='(1X,2A,1X,A)') repeat(" ", indent), & + trim(nuclides(i_nuclide) % name) + else + write(UNIT=unit_tally, FMT='(1X,2A,1X,A)') repeat(" ", indent), & + trim(nuclides_MG(i_nuclide) % obj % name) + end if end if indent = indent + 2 diff --git a/src/physics.F90 b/src/physics.F90 index 6a6a9787d5..842540d166 100644 --- a/src/physics.F90 +++ b/src/physics.F90 @@ -96,10 +96,11 @@ contains ! absorption (including fission) if (nuc % fissionable) then - call sample_fission(i_nuclide, i_reaction) if (run_mode == MODE_EIGENVALUE) then + call sample_fission(i_nuclide, i_reaction) call create_fission_sites(p, i_nuclide, i_reaction, fission_bank, n_bank) - elseif (run_mode == MODE_FIXEDSOURCE) then + elseif (run_mode == MODE_FIXEDSOURCE .and. create_fission_neutrons) then + call sample_fission(i_nuclide, i_reaction) call create_fission_sites(p, i_nuclide, i_reaction, & p % secondary_bank, p % n_secondary) end if @@ -126,6 +127,13 @@ contains if (.not. p % alive) return end if + ! Kill neutron under certain energy + if (p % E < energy_cutoff) then + p % alive = .false. + p % wgt = ZERO + p % last_wgt = ZERO + end if + end subroutine sample_reaction !=============================================================================== diff --git a/src/physics_mg.F90 b/src/physics_mg.F90 index 2e5e467c14..c60fc6e2e1 100644 --- a/src/physics_mg.F90 +++ b/src/physics_mg.F90 @@ -73,7 +73,7 @@ contains if (mat % fissionable) then if (run_mode == MODE_EIGENVALUE) then call create_fission_sites(p, fission_bank, n_bank) - elseif (run_mode == MODE_FIXEDSOURCE) then + elseif (run_mode == MODE_FIXEDSOURCE .and. create_fission_neutrons) then call create_fission_sites(p, p % secondary_bank, p % n_secondary) end if end if diff --git a/src/reaction_header.F90 b/src/reaction_header.F90 index a7896e9ff3..12b3888c4b 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 dcf5df979a..bf81a5d902 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, object_exists, & + get_name use secondary_correlated, only: CorrelatedAngleEnergy use stl_vector, only: VectorInt, VectorReal use string, only: to_str, str_to_int @@ -66,7 +66,7 @@ module sab_header end type SabData type SAlphaBeta - character(100) :: name ! name of table, e.g. lwtr.10t + character(150) :: name ! name of table, e.g. lwtr.10t real(8) :: awr ! weight of nucleus in neutron masses real(8), allocatable :: kTs(:) ! temperatures in MeV (k*T) character(10), allocatable :: nuclides(:) ! List of valid nuclides @@ -92,8 +92,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 @@ -103,11 +102,10 @@ 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 - character(MAX_FILE_LEN), allocatable :: dset_names(:) + character(MAX_WORD_LEN), allocatable :: dset_names(:) real(8), allocatable :: temps_available(:) ! temperatures available real(8) :: temp_desired real(8) :: temp_actual @@ -115,7 +113,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:)) @@ -207,8 +205,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 (object_exists(T_group, 'elastic')) then ! Read cross section data elastic_group = open_group(T_group, 'elastic') dset_id = open_dataset(elastic_group, 'xs') @@ -250,8 +247,7 @@ contains end if ! Inelastic data - call h5ltpath_valid_f(T_group, 'inelastic', .true., exists, hdf5_err) - if (exists) then + if (object_exists(T_group, 'inelastic')) then ! Read type of inelastic data inelastic_group = open_group(T_group, 'inelastic') diff --git a/src/scattdata_header.F90 b/src/scattdata_header.F90 index d4643a0721..6004cbd190 100644 --- a/src/scattdata_header.F90 +++ b/src/scattdata_header.F90 @@ -41,18 +41,20 @@ module scattdata_header real(8), allocatable :: scattxs(:) ! Isotropic Sigma_{s,g_{in}} contains - procedure(scattdata_init_), deferred :: init ! Initializes ScattData + procedure(scattdata_init_), deferred :: init ! Initializes ScattData procedure(scattdata_calc_f_), deferred :: calc_f ! Calculates f, given mu procedure(scattdata_sample_), deferred :: sample ! sample the scatter event procedure :: get_matrix => scattdata_get_matrix ! Rebuild scattering matrix end type ScattData abstract interface - subroutine scattdata_init_(this, mult, coeffs) - import ScattData - class(ScattData), intent(inout) :: this ! Object to work with - real(8), intent(in) :: mult(:, :) ! Scatter Prod'n Matrix - real(8), intent(in) :: coeffs(:, :, :) ! Coefficients to use + subroutine scattdata_init_(this, gmin, gmax, mult, coeffs) + import ScattData, Jagged1D, Jagged2D + class(ScattData), intent(inout) :: this ! Object to work with + integer, intent(in) :: gmin(:) ! Min Gout + integer, intent(in) :: gmax(:) ! Max Gout + type(Jagged1D), intent(in) :: mult(:) ! Scatter Prod'n Matrix + type(Jagged2D), intent(in) :: coeffs(:) ! Coefficients to use end subroutine scattdata_init_ pure function scattdata_calc_f_(this, gin, gout, mu) result(f) @@ -79,9 +81,9 @@ module scattdata_header ! Maximal value for rejection sampling from rectangle type(Jagged1D), allocatable :: max_val(:) ! (Gin % data(Gout)) contains - procedure :: init => scattdatalegendre_init - procedure :: calc_f => scattdatalegendre_calc_f - procedure :: sample => scattdatalegendre_sample + procedure :: init => scattdatalegendre_init + procedure :: calc_f => scattdatalegendre_calc_f + procedure :: sample => scattdatalegendre_sample end type ScattDataLegendre type, extends(ScattData) :: ScattDataHistogram @@ -90,10 +92,10 @@ module scattdata_header ! Histogram of f(mu) (dist has CDF) type(Jagged2D), allocatable :: fmu(:) ! (Gin % data(Order/Nmu x Gout) contains - procedure :: init => scattdatahistogram_init - procedure :: calc_f => scattdatahistogram_calc_f - procedure :: sample => scattdatahistogram_sample - procedure :: get_matrix => scattdatahistogram_get_matrix + procedure :: init => scattdatahistogram_init + procedure :: calc_f => scattdatahistogram_calc_f + procedure :: sample => scattdatahistogram_sample + procedure :: get_matrix => scattdatahistogram_get_matrix end type ScattDataHistogram type, extends(ScattData) :: ScattDataTabular @@ -102,10 +104,10 @@ module scattdata_header ! PDF of f(mu) (dist has CDF) type(Jagged2D), allocatable :: fmu(:) ! (Gin % data(Order/Nmu x Gout) contains - procedure :: init => scattdatatabular_init - procedure :: calc_f => scattdatatabular_calc_f - procedure :: sample => scattdatatabular_sample - procedure :: get_matrix => scattdatatabular_get_matrix + procedure :: init => scattdatatabular_init + procedure :: calc_f => scattdatatabular_calc_f + procedure :: sample => scattdatatabular_sample + procedure :: get_matrix => scattdatatabular_get_matrix end type ScattDataTabular !=============================================================================== @@ -122,13 +124,15 @@ contains ! SCATTDATA*_INIT builds the scattdata object !=============================================================================== - subroutine scattdata_init(this, order, energy, mult) - class(ScattData), intent(inout) :: this ! Object to work on - integer, intent(in) :: order ! Data Order - real(8), intent(inout) :: energy(:, :) ! Energy Transfer Matrix - real(8), intent(in) :: mult(:, :) ! Scatter Prod'n Matrix + subroutine scattdata_init(this, order, gmin, gmax, energy, mult) + class(ScattData), intent(inout) :: this ! Object to work on + integer, intent(in) :: order ! Data Order + integer, intent(in) :: gmin(:) ! Min Gout + integer, intent(in) :: gmax(:) ! Max Gout + type(Jagged1D), intent(inout) :: energy(:) ! Energy Transfer Matrix + type(Jagged1D), intent(in) :: mult(:) ! Scatter Prod'n Matrix - integer :: groups, gmin, gmax, gin + integer :: groups, gin real(8) :: norm groups = size(energy, dim=1) @@ -138,83 +142,80 @@ contains allocate(this % energy(groups)) allocate(this % mult(groups)) allocate(this % dist(groups)) - ! Use energy to find the gmin and gmax values - ! Also set energy values when doing it + + this % gmin = gmin + this % gmax = gmax + + ! Set the outgoing energy PDF values do gin = 1, groups ! Make sure energy is normalized (i.e., CDF is 1) - norm = sum(energy(:, gin)) - if (norm /= ZERO) energy(:, gin) = energy(:, gin) / norm - ! Find gmin by checking the P0 moment - do gmin = 1, groups - if (energy(gmin, gin) > ZERO) exit - end do - ! Find gmax by checking the P0 moment - do gmax = groups, 1, -1 - if (energy(gmax, gin) > ZERO) exit - end do - ! Treat the case of all zeros - if (gmin > gmax) then - gmin = gin - gmax = gin - ! By not changing energy(gin) here we are leaving it as zero - end if - allocate(this % energy(gin) % data(gmin:gmax)) - this % energy(gin) % data(gmin:gmax) = energy(gmin:gmax, gin) - allocate(this % mult(gin) % data(gmin:gmax)) - this % mult(gin) % data(gmin:gmax) = mult(gmin:gmax, gin) - allocate(this % dist(gin) % data(order, gmin:gmax)) + norm = sum(energy(gin) % data(:)) + if (norm /= ZERO) energy(gin) % data(:) = energy(gin) % data(:) / norm + ! Set the values + allocate(this % energy(gin) % data(gmin(gin):gmax(gin))) + this % energy(gin) % data(:) = energy(gin) % data(:) + allocate(this % mult(gin) % data(gmin(gin):gmax(gin))) + this % mult(gin) % data(gmin(gin):gmax(gin)) = & + mult(gin) % data(gmin(gin):gmax(gin)) + allocate(this % dist(gin) % data(order, gmin(gin):gmax(gin))) this % dist(gin) % data = ZERO - this % gmin(gin) = gmin - this % gmax(gin) = gmax end do end subroutine scattdata_init - subroutine scattdatalegendre_init(this, mult, coeffs) - class(ScattDataLegendre), intent(inout) :: this ! Object to work on - real(8), intent(in) :: mult(:, :) ! Scatter Prod'n Matrix - real(8), intent(in) :: coeffs(:, :, :) ! Coefficients to use + subroutine scattdatalegendre_init(this, gmin, gmax, mult, coeffs) + class(ScattDataLegendre), intent(inout) :: this ! Object to work on + integer, intent(in) :: gmin(:) ! Min Gout + integer, intent(in) :: gmax(:) ! Max Gout + type(Jagged1D), intent(in) :: mult(:) ! Scatter Prod'n Matrix + type(Jagged2D), intent(in) :: coeffs(:) ! Coefficients to use real(8) :: dmu, mu, f, norm integer :: imu, Nmu, gout, gin, groups, order - real(8), allocatable :: energy(:, :) - real(8), allocatable :: matrix(:, :, :) + type(Jagged1D), allocatable :: energy(:) + type(Jagged2D), allocatable :: matrix(:) - groups = size(coeffs, dim=3) - order = size(coeffs, dim=1) + groups = size(coeffs) + order = size(coeffs(1) % data, dim=1) ! make a copy of coeffs that we can use to extract data and normalize - allocate(matrix(order, groups, groups)) - matrix (:, :, :)= coeffs + allocate(matrix(groups)) + do gin = 1, groups + allocate(matrix(gin) % data(order, gmin(gin):gmax(gin))) + matrix(gin) % data = coeffs(gin) % data + end do ! Get scattxs value allocate(this % scattxs(groups)) ! Get this by summing the un-normalized P0 coefficient in matrix ! over all outgoing groups - this % scattxs(:) = sum(matrix(1, :, :), dim=1) + do gin = 1, groups + this % scattxs(gin) = sum(matrix(gin) % data(1, :), dim=1) + end do - allocate(energy(groups, groups)) - energy(:, :) = ZERO + allocate(energy(groups)) ! Build energy transfer probability matrix from data in matrix ! while also normalizing matrix itself (making CDF of f(mu=1)=1) do gin = 1, groups - do gout = 1, groups - norm = matrix(1, gout, gin) - energy(gout, gin) = norm + allocate(energy(gin) % data(gmin(gin):gmax(gin))) + energy(gin) % data = ZERO + do gout = gmin(gin), gmax(gin) + norm = matrix(gin) % data(1, gout) + energy(gin) % data(gout) = norm if (norm /= ZERO) then - matrix(:, gout, gin) = matrix(:, gout, gin) / norm + matrix(gin) % data(:, gout) = matrix(gin) % data(:, gout) / norm end if end do end do - call scattdata_init(this, order, energy, mult) + call scattdata_init(this, order, gmin, gmax, energy, mult) allocate(this % max_val(groups)) ! Set dist values from matrix and initialize max_val do gin = 1, groups - do gout = this % gmin(gin), this % gmax(gin) - this % dist(gin) % data(:, gout) = matrix(:, gout, gin) + do gout = gmin(gin), gmax(gin) + this % dist(gin) % data(:, gout) = matrix(gin) % data(:, gout) end do - allocate(this % max_val(gin) % data(this % gmin(gin):this % gmax(gin))) + allocate(this % max_val(gin) % data(gmin(gin):gmax(gin))) this % max_val(gin) % data(:) = ZERO end do @@ -223,7 +224,7 @@ contains Nmu = 1001 dmu = TWO / real(Nmu - 1, 8) do gin = 1, groups - do gout = this % gmin(gin), this % gmax(gin) + do gout = gmin(gin), gmax(gin) do imu = 1, Nmu ! Update mu. Do first and last seperate to avoid float errors if (imu == 1) then @@ -246,44 +247,51 @@ contains end do end subroutine scattdatalegendre_init - subroutine scattdatahistogram_init(this, mult, coeffs) - class(ScattDataHistogram), intent(inout) :: this ! Object to work on - real(8), intent(in) :: mult(:, :) ! Scatter Prod'n Matrix - real(8), intent(in) :: coeffs(:, :, :) ! Coefficients to use + subroutine scattdatahistogram_init(this, gmin, gmax, mult, coeffs) + class(ScattDataHistogram), intent(inout) :: this ! Object to work on + integer, intent(in) :: gmin(:) ! Min Gout + integer, intent(in) :: gmax(:) ! Max Gout + type(Jagged1D), intent(in) :: mult(:) ! Scatter Prod'n Matrix + type(Jagged2D), intent(in) :: coeffs(:) ! Coefficients to use integer :: imu, gin, gout, groups, order real(8) :: norm - real(8), allocatable :: energy(:, :) - real(8), allocatable :: matrix(:, :, :) + type(Jagged1D), allocatable :: energy(:) + type(Jagged2D), allocatable :: matrix(:) - groups = size(coeffs, dim=3) - order = size(coeffs, dim=1) + groups = size(coeffs) + order = size(coeffs(1) % data, dim=1) ! make a copy of coeffs that we can use to extract data and normalize - allocate(matrix(order, groups, groups)) - matrix(:, :, :) = coeffs + allocate(matrix(groups)) + do gin = 1, groups + allocate(matrix(gin) % data(order, gmin(gin):gmax(gin))) + matrix(gin) % data = coeffs(gin) % data + end do ! Get scattxs value allocate(this % scattxs(groups)) ! Get this by summing the un-normalized P0 coefficient in matrix ! over all outgoing groups - this % scattxs(:) = sum(sum(matrix(:, :, :), dim=1), dim=1) + do gin = 1, groups + this % scattxs(gin) = sum(matrix(gin) % data(1, :), dim=1) + end do - allocate(energy(groups, groups)) - energy(:, :) = ZERO + allocate(energy(groups)) ! Build energy transfer probability matrix from data in matrix ! while also normalizing matrix itself (making CDF of f(mu=1)=1) do gin = 1, groups + allocate(energy(gin) % data(gmin(gin):gmax(gin))) do gout = 1, groups - norm = sum(matrix(:, gout, gin)) - energy(gout, gin) = norm + norm = sum(matrix(gin) % data(:, gout)) + energy(gin) % data(gout) = norm if (norm /= ZERO) then - matrix(:, gout, gin) = matrix(:, gout, gin) / norm + matrix(gin) % data(:, gout) = matrix(gin) % data(:, gout) / norm end if end do end do - call scattdata_init(this, order, energy, mult) + call scattdata_init(this, order, gmin, gmax, energy, mult) allocate(this % mu(order)) this % dmu = TWO / real(order, 8) @@ -296,17 +304,16 @@ contains ! also saving the original histogram in fmu allocate(this % fmu(groups)) do gin = 1, groups - allocate(this % fmu(gin) % data(order, & - this % gmin(gin):this % gmax(gin))) - do gout = this % gmin(gin), this % gmax(gin) + allocate(this % fmu(gin) % data(order, gmin(gin):gmax(gin))) + do gout = gmin(gin), gmax(gin) ! Store the histogram - this % fmu(gin) % data(:, gout) = matrix(:, gout, gin) + this % fmu(gin) % data(:, gout) = matrix(gin) % data(:, gout) ! Integrate the histogram this % dist(gin) % data(1, gout) = & - this % dmu * matrix(1, gout, gin) + this % dmu * matrix(gin) % data(1, gout) do imu = 2, order this % dist(gin) % data(imu, gout) = & - this % dmu * matrix(imu, gout, gin) + & + this % dmu * matrix(gin) % data(imu, gout) + & this % dist(gin) % data(imu - 1, gout) end do @@ -323,22 +330,27 @@ contains end subroutine scattdatahistogram_init - subroutine scattdatatabular_init(this, mult, coeffs) - class(ScattDataTabular), intent(inout) :: this ! Object to work on - real(8), intent(in) :: mult(:, :) ! Scatter Prod'n Matrix - real(8), intent(in) :: coeffs(:, :, :) ! Coefficients to use + subroutine scattdatatabular_init(this, gmin, gmax, mult, coeffs) + class(ScattDataTabular), intent(inout) :: this ! Object to work on + integer, intent(in) :: gmin(:) ! Min Gout + integer, intent(in) :: gmax(:) ! Max Gout + type(Jagged1D), intent(in) :: mult(:) ! Scatter Prod'n Matrix + type(Jagged2D), intent(in) :: coeffs(:) ! Coefficients to use integer :: imu, gin, gout, groups, order real(8) :: norm - real(8), allocatable :: energy(:, :) - real(8), allocatable :: matrix(:, :, :) + type(Jagged1D), allocatable :: energy(:) + type(Jagged2D), allocatable :: matrix(:) - groups = size(coeffs, dim=3) - order = size(coeffs, dim=1) + groups = size(coeffs) + order = size(coeffs(1) % data, dim=1) ! make a copy of coeffs that we can use to extract data and normalize - allocate(matrix(order, groups, groups)) - matrix(:, :, :) = coeffs + allocate(matrix(groups)) + do gin = 1, groups + allocate(matrix(gin) % data(order, gmin(gin):gmax(gin))) + matrix(gin) % data = coeffs(gin) % data + end do ! Build the angular distribution mu values allocate(this % mu(order)) @@ -356,39 +368,40 @@ contains ! over all outgoing groups do gin = 1, groups norm = ZERO - do gout = 1, groups + do gout = gmin(gin), gmax(gin) do imu = 2, order - norm = norm + HALF * this % dmu * (matrix(imu - 1, gout, gin) + & - matrix(imu, gout, gin)) + norm = norm + HALF * this % dmu * & + (matrix(gin) % data(imu - 1, gout) + & + matrix(gin) % data(imu, gout)) end do end do this % scattxs(gin) = norm end do - allocate(energy(groups, groups)) - energy(:, :) = ZERO + allocate(energy(groups)) ! Build energy transfer probability matrix from data in matrix do gin = 1, groups - do gout = 1, groups + allocate(energy(gin) % data(gmin(gin):gmax(gin))) + do gout = gmin(gin), gmax(gin) norm = ZERO do imu = 2, order norm = norm + HALF * this % dmu * & - (matrix(imu - 1, gout, gin) + matrix(imu, gout, gin)) + (matrix(gin) % data(imu - 1, gout) + & + matrix(gin) % data(imu, gout)) end do - energy(gout, gin) = norm + energy(gin) % data(gout) = norm end do end do - call scattdata_init(this, order, energy, mult) + call scattdata_init(this, order, gmin, gmax, energy, mult) ! Calculate f(mu) and integrate it so we can avoid rejection sampling allocate(this % fmu(groups)) do gin = 1, groups - allocate(this % fmu(gin) % data(order, & - this % gmin(gin):this % gmax(gin))) - do gout = this % gmin(gin), this % gmax(gin) + allocate(this % fmu(gin) % data(order, gmin(gin):gmax(gin))) + do gout = gmin(gin), gmax(gin) ! Coeffs contain f(mu), put in f(mu) as that is where the ! PDF lives - this % fmu(gin) % data(:, gout) = matrix(:, gout, gin) + this % fmu(gin) % data(:, gout) = matrix(gin) % data(:, gout) ! Force positivity do imu = 1, order @@ -640,10 +653,10 @@ contains ! using ScattData's information of fmu/dist, energy, and scattxs !=============================================================================== - pure function scattdata_get_matrix(this, req_order) result(matrix) - class(ScattData), intent(in) :: this ! Scattering Object to work with - integer, intent(in) :: req_order ! Requested order of matrix - real(8), allocatable :: matrix(:, :, :) ! Resultant matrix just built + subroutine scattdata_get_matrix(this, req_order, matrix) + class(ScattData), intent(in) :: this ! Scattering Object to work with + integer, intent(in) :: req_order ! Requested order of matrix + type(Jagged2D), allocatable, intent(inout) :: matrix(:) ! Resultant matrix just built integer :: order, groups, gin, gout @@ -651,66 +664,189 @@ contains ! Set gin and gout for getting the order order = min(req_order, size(this % dist(1) % data, dim=1)) - allocate(matrix(order, groups, groups)) + if (allocated(matrix)) deallocate(matrix) + allocate(matrix(groups)) ! Initialize to 0; this way the zero entries in the dense matrix dont ! need to be explicitly set, requiring a significant increase in the ! lines of code. - matrix(:, :, :) = ZERO do gin = 1, groups + allocate(matrix(gin) % data(order, groups)) do gout = this % gmin(gin), this % gmax(gin) - matrix(:, gout, gin) = this % scattxs(gin) * & + matrix(gin) % data(:, gout) = this % scattxs(gin) * & this % energy(gin) % data(gout) * & this % dist(gin) % data(1:order, gout) end do end do - end function scattdata_get_matrix + end subroutine scattdata_get_matrix - pure function scattdatahistogram_get_matrix(this, req_order) result(matrix) - class(ScattDataHistogram), intent(in) :: this ! Scattering Object to work with - integer, intent(in) :: req_order ! Requested order of matrix - real(8), allocatable :: matrix(:, :, :) ! Resultant matrix just built + subroutine scattdatahistogram_get_matrix(this, req_order, matrix) + class(ScattDataHistogram), intent(in) :: this ! Scattering Object to work with + integer, intent(in) :: req_order ! Requested order of matrix + type(Jagged2D), allocatable, intent(inout) :: matrix(:) ! Resultant matrix just built integer :: order, groups, gin, gout groups = size(this % energy) order = min(req_order, size(this % dist(1) % data, dim=1)) - allocate(matrix(order, groups, groups)) + if (allocated(matrix)) deallocate(matrix) + allocate(matrix(groups)) ! Initialize to 0; this way the zero entries in the dense matrix dont ! need to be explicitly set, requiring a significant increase in the ! lines of code. - matrix(:, :, :) = ZERO do gin = 1, groups + allocate(matrix(gin) % data(order, groups)) do gout = this % gmin(gin), this % gmax(gin) - matrix(:, gout, gin) = this % scattxs(gin) * & + matrix(gin) % data(:, gout) = this % scattxs(gin) * & this % energy(gin) % data(gout) * & this % fmu(gin) % data(1:order, gout) end do end do - end function scattdatahistogram_get_matrix + end subroutine scattdatahistogram_get_matrix - pure function scattdatatabular_get_matrix(this, req_order) result(matrix) - class(ScattDataTabular), intent(in) :: this ! Scattering Object to work with - integer, intent(in) :: req_order ! Requested order of matrix - real(8), allocatable :: matrix(:, :, :) ! Resultant matrix just built + subroutine scattdatatabular_get_matrix(this, req_order, matrix) + class(ScattDataTabular), intent(in) :: this ! Scattering Object to work with + integer, intent(in) :: req_order ! Requested order of matrix + type(Jagged2D), allocatable, intent(inout) :: matrix(:) ! Resultant matrix just built integer :: order, groups, gin, gout groups = size(this % energy) order = min(req_order, size(this % dist(1) % data, dim=1)) - allocate(matrix(order, groups, groups)) + if (allocated(matrix)) deallocate(matrix) + allocate(matrix(groups)) ! Initialize to 0; this way the zero entries in the dense matrix dont ! need to be explicitly set, requiring a significant increase in the ! lines of code. - matrix(:, :, :) = ZERO do gin = 1, groups + allocate(matrix(gin) % data(order, groups)) do gout = this % gmin(gin), this % gmax(gin) - matrix(:, gout, gin) = this % scattxs(gin) * & + matrix(gin) % data(:, gout) = this % scattxs(gin) * & this % energy(gin) % data(gout) * & this % fmu(gin) % data(1:order, gout) end do end do - end function scattdatatabular_get_matrix + end subroutine scattdatatabular_get_matrix + +!=============================================================================== +! JAGGED_FROM_DENSE_*D Creates a jagged array from a sparse dense matrix. +! The user can supply a key which indicates the values to remove, but the +! default is ZERO +!=============================================================================== + + subroutine jagged_from_dense_1D(dense, jagged, lo_bounds_, hi_bounds_, key_) + real(8), intent(in) :: dense(:, :) + type(Jagged1D), allocatable, intent(inout) :: jagged(:) + real(8), intent(in), optional :: key_ + integer, intent(inout), allocatable, optional :: lo_bounds_(:) + integer, intent(inout), allocatable, optional :: hi_bounds_(:) + + real(8) :: key + integer :: i, jmin, jmax + integer, allocatable :: lo_bounds(:), hi_bounds(:) + + if (present(key_)) then + key = key_ + else + key = ZERO + end if + + allocate(lo_bounds(size(dense, dim=2))) + allocate(hi_bounds(size(dense, dim=2))) + + if (allocated(jagged)) deallocate(jagged) + allocate(jagged(size(dense, dim=2))) + do i = 1, size(dense, dim=2) + ! Find the min and max j values + do jmin = 1, size(dense, dim=1) + if (dense(jmin, i) /= key) exit + end do + do jmax = size(dense, dim=1), 1, -1 + if (dense(jmax, i) /= key) exit + end do + ! Treat the case of all values matching the key + if (jmin > jmax) then + jmin = i + jmax = i + end if + + ! Now store the jagged row + allocate(jagged(i) % data(jmin:jmax)) + jagged(i) % data(jmin:jmax) = dense(jmin:jmax, i) + + lo_bounds(i) = jmin + hi_bounds(i) = jmax + end do + + if (present(lo_bounds_)) then + if (allocated(lo_bounds_)) deallocate(lo_bounds_) + allocate(lo_bounds_(size(dense, dim=2))) + lo_bounds_ = lo_bounds + end if + if (present(hi_bounds_)) then + if (allocated(hi_bounds_)) deallocate(hi_bounds_) + allocate(hi_bounds_(size(dense, dim=2))) + hi_bounds_ = hi_bounds + end if + + end subroutine jagged_from_dense_1D + + subroutine jagged_from_dense_2D(dense, jagged, lo_bounds_, hi_bounds_, key_) + real(8), intent(in) :: dense(:, :, :) + type(Jagged2D), allocatable, intent(inout) :: jagged(:) + real(8), intent(in), optional :: key_ + integer, intent(inout), allocatable, optional :: lo_bounds_(:) + integer, intent(inout), allocatable, optional :: hi_bounds_(:) + + real(8) :: key + integer :: i, jmin, jmax + integer, allocatable :: lo_bounds(:), hi_bounds(:) + + if (present(key_)) then + key = key_ + else + key = ZERO + end if + + allocate(lo_bounds(size(dense, dim=3))) + allocate(hi_bounds(size(dense, dim=3))) + + if (allocated(jagged)) deallocate(jagged) + allocate(jagged(size(dense, dim=3))) + do i = 1, size(dense, dim=3) + ! Find the min and max j values + do jmin = 1, size(dense, dim=2) + if (any(dense(:, jmin, i) /= key)) exit + end do + do jmax = size(dense, dim=2), 1, -1 + if (any(dense(:, jmax, i) /= key)) exit + end do + ! Treat the case of all values matching the key + if (jmin > jmax) then + jmin = i + jmax = i + end if + + ! Now store the jagged row + allocate(jagged(i) % data(size(dense, dim=1), jmin:jmax)) + jagged(i) % data(:, jmin:jmax) = dense(:, jmin:jmax, i) + + lo_bounds(i) = jmin + hi_bounds(i) = jmax + end do + + if (present(lo_bounds_)) then + if (allocated(lo_bounds_)) deallocate(lo_bounds_) + allocate(lo_bounds_(size(dense, dim=3))) + lo_bounds_ = lo_bounds + end if + if (present(hi_bounds_)) then + if (allocated(hi_bounds_)) deallocate(hi_bounds_) + allocate(hi_bounds_(size(dense, dim=3))) + hi_bounds_ = hi_bounds + end if + + end subroutine jagged_from_dense_2D end module scattdata_header diff --git a/src/secondary_uncorrelated.F90 b/src/secondary_uncorrelated.F90 index fc215484a9..40aa827da6 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,8 @@ 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, & + object_exists use random_lcg, only: prn !=============================================================================== @@ -56,25 +56,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 (object_exists(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 (object_exists(group_id, 'energy')) then energy_group = open_group(group_id, 'energy') call read_attribute(type, energy_group, 'type') select case (type) diff --git a/src/state_point.F90 b/src/state_point.F90 index 39532652f1..6b7a467d4f 100644 --- a/src/state_point.F90 +++ b/src/state_point.F90 @@ -251,11 +251,20 @@ contains allocate(str_array(tally % n_nuclide_bins)) NUCLIDE_LOOP: do j = 1, tally % n_nuclide_bins if (tally % nuclide_bins(j) > 0) then - i_xs = index(nuclides(tally % nuclide_bins(j)) % name, '.') - if (i_xs > 0) then - str_array(j) = nuclides(tally % nuclide_bins(j)) % name(1 : i_xs-1) + if (run_CE) then + i_xs = index(nuclides(tally % nuclide_bins(j)) % name, '.') + if (i_xs > 0) then + str_array(j) = nuclides(tally % nuclide_bins(j)) % name(1 : i_xs-1) + else + str_array(j) = nuclides(tally % nuclide_bins(j)) % name + end if else - str_array(j) = nuclides(tally % nuclide_bins(j)) % name + i_xs = index(nuclides_MG(tally % nuclide_bins(j)) % obj % name, '.') + if (i_xs > 0) then + str_array(j) = nuclides_MG(tally % nuclide_bins(j)) % obj % name(1 : i_xs-1) + else + str_array(j) = nuclides_MG(tally % nuclide_bins(j)) % obj % name + end if end if else str_array(j) = 'total' diff --git a/src/tally.F90 b/src/tally.F90 index f7d8ab5a28..978f26d7ba 100644 --- a/src/tally.F90 +++ b/src/tally.F90 @@ -1149,6 +1149,8 @@ contains ! Do same for nucxs, point it to the microscopic nuclide data of interest if (i_nuclide > 0) then nucxs => nuclides_MG(i_nuclide) % obj + ! And since we haven't calculated this temperature index yet, do so now + call nucxs % find_temperature(p % sqrtkT) end if i = 0 @@ -1228,11 +1230,21 @@ contains else score = p % last_wgt end if - score = score * inverse_velocities(p_g) / material_xs % total * flux + if (i_nuclide > 0) then + score = score * nucxs % get_xs('inv_vel', p_g, UVW=p_uvw) / & + matxs % get_xs('total', p_g, UVW=p_uvw) * flux + else + score = matxs % get_xs('inv_vel', p_g, UVW=p_uvw) * flux + end if else ! For inverse velocity, we need no cross section - score = flux * inverse_velocities(p_g) + if (i_nuclide > 0) then + score = score * nucxs % get_xs('inv_vel', p_g, UVW=p_uvw) * & + atom_density * flux + else + score = flux * matxs % get_xs('inv_vel', p_g, UVW=p_uvw) + end if end if @@ -1853,17 +1865,24 @@ contains i_nuclide = t % nuclide_bins(k) - ! Check to see if this nuclide was in the material of our collision. - do m = 1, mat % n_nuclides - if (mat % nuclide(m) == i_nuclide) then - atom_density = mat % atom_density(m) - exit - end if - end do + if (i_nuclide > 0) then + atom_density = -ONE + ! Check to see if this nuclide was in the material of our collision + do m = 1, mat % n_nuclides + if (mat % nuclide(m) == i_nuclide) then + atom_density = mat % atom_density(m) + exit + end if + end do + else + atom_density = ZERO + end if - ! Determine score for each bin - call score_general(p, t, (k-1)*t % n_score_bins, filter_index, & - i_nuclide, atom_density, filter_weight) + ! If we found the nuclide, determine the score for each bin + if (atom_density >= ZERO) then + call score_general(p, t, (k-1)*t % n_score_bins, filter_index, & + i_nuclide, atom_density, filter_weight) + end if end do NUCLIDE_LOOP diff --git a/src/tracking.F90 b/src/tracking.F90 index f2613146e4..b62cfc85a0 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -92,6 +92,9 @@ contains ! Since the MGXS can be angle dependent, this needs to be done ! After every collision for the MGXS mode if (p % material /= MATERIAL_VOID) then + ! Update the temperature index + call macro_xs(p % material) % obj % find_temperature(p % sqrtkT) + ! Get the data call macro_xs(p % material) % obj % calculate_xs(p % g, & p % coord(p % n_coord) % uvw, material_xs) else diff --git a/tests/1d_mgxs.h5 b/tests/1d_mgxs.h5 new file mode 100644 index 0000000000..3befba1940 Binary files /dev/null and b/tests/1d_mgxs.h5 differ diff --git a/tests/1d_mgxs.xml b/tests/1d_mgxs.xml deleted file mode 100644 index 8704b49ad4..0000000000 --- a/tests/1d_mgxs.xml +++ /dev/null @@ -1,9859 +0,0 @@ - - - 1 - 0.0000000E+00 2.0000000E+01 - - - uo2_iso - uo2_iso - 2.5300000E-08 - 5 - true - isotropic - - 4.1022364E-01 - - - 3.4687432E-02 - - - 4.9631431E-02 - - - 1.0000000E+00 - - - 2.0019027E-02 - - - 3.7564339E-01 - - 4.4983802E-02 - - 2.2781624E-02 - - 1.1639469E-02 - - 7.1975833E-03 - - 3.5887673E-03 - - - 1.0002764E+00 - - - - - clad_iso - clad_iso - 2.5300000E-08 - 5 - false - isotropic - - 3.0736836E-01 - - - 1.7027907E-03 - - - 3.0566993E-01 - - 4.1625057E-02 - - 2.2287832E-02 - - 3.9580806E-03 - - 3.3420849E-03 - - 1.3963828E-03 - - - 1.0000372E+00 - - - - - lwtr_iso - lwtr_iso - 2.5300000E-08 - 5 - false - isotropic - - 9.6904862E-01 - - - 1.0230968E-02 - - - 9.5881780E-01 - - 3.9202760E-01 - - 1.2865356E-01 - - 9.5231115E-03 - - -1.9647208E-02 - - 5.9291968E-04 - - - 1.0000000E+00 - - - - - uo2_iso_mu - uo2_iso_mu - 2.5300000E-08 - 32 - true - isotropic - histogram - - 4.1022364E-01 - - - 3.4687432E-02 - - - 4.9631431E-02 - - - 1.0000000E+00 - - - 2.0019027E-02 - - - 9.7621928E-03 - - 9.6669975E-03 - - 9.6217012E-03 - - 9.6029285E-03 - - 9.6155223E-03 - - 9.6417022E-03 - - 9.6845888E-03 - - 9.7355785E-03 - - 9.7971852E-03 - - 9.8708684E-03 - - 9.9451996E-03 - - 1.0026273E-02 - - 1.0121536E-02 - - 1.0227606E-02 - - 1.0340467E-02 - - 1.0461281E-02 - - 1.0600371E-02 - - 1.0742182E-02 - - 1.0892295E-02 - - 1.1062409E-02 - - 1.1236639E-02 - - 1.1440302E-02 - - 1.1662283E-02 - - 1.1931512E-02 - - 1.2259589E-02 - - 1.2696194E-02 - - 1.3272953E-02 - - 1.4078939E-02 - - 1.5238289E-02 - - 1.6956791E-02 - - 1.9602217E-02 - - 2.3848802E-02 - - - 1.0002764E+00 - - - - - clad_iso_mu - clad_iso_mu - 2.5300000E-08 - 32 - false - isotropic - histogram - - 3.0736836E-01 - - - 1.7027907E-03 - - - 8.7275040E-03 - - 8.3252599E-03 - - 8.0120655E-03 - - 7.7711039E-03 - - 7.5947251E-03 - - 7.4705350E-03 - - 7.3804037E-03 - - 7.3241515E-03 - - 7.3010244E-03 - - 7.3107188E-03 - - 7.3487081E-03 - - 7.4144814E-03 - - 7.5104992E-03 - - 7.6438156E-03 - - 7.7974114E-03 - - 7.9812213E-03 - - 8.1816102E-03 - - 8.4284406E-03 - - 8.6892059E-03 - - 8.9675370E-03 - - 9.2626673E-03 - - 9.6121293E-03 - - 9.9669464E-03 - - 1.0354054E-02 - - 1.0794903E-02 - - 1.1296566E-02 - - 1.1883978E-02 - - 1.2592532E-02 - - 1.3494682E-02 - - 1.4666635E-02 - - 1.6229823E-02 - - 1.8334594E-02 - - - 1.0000372E+00 - - - - - lwtr_iso_mu - lwtr_iso_mu - 2.5300000E-08 - 32 - false - isotropic - histogram - - 9.6904862E-01 - - - 1.0230968E-02 - - - 5.8755233E-03 - - 1.0934725E-02 - - 1.1142414E-02 - - 1.0437139E-02 - - 1.0756915E-02 - - 1.0623054E-02 - - 1.1295335E-02 - - 1.1326212E-02 - - 1.1795885E-02 - - 1.2179916E-02 - - 1.2528003E-02 - - 1.3121696E-02 - - 1.3563685E-02 - - 1.4242846E-02 - - 1.4567732E-02 - - 1.5913317E-02 - - 1.6851680E-02 - - 2.0792196E-02 - - 2.4129531E-02 - - 2.8258248E-02 - - 3.2040957E-02 - - 3.6266761E-02 - - 4.0455247E-02 - - 4.4731350E-02 - - 4.8820583E-02 - - 5.3746086E-02 - - 5.7743648E-02 - - 6.3513540E-02 - - 6.7353451E-02 - - 7.2430683E-02 - - 8.0723820E-02 - - 8.0655621E-02 - - - 1.0000000E+00 - - - - - uo2_ang - uo2_ang - 2.5300000E-08 - 5 - true - 32 - 1 - angle - - 4.0734790E-01 - - 4.0709470E-01 - - 4.0665280E-01 - - 4.0605122E-01 - - 4.0509226E-01 - - 4.0399893E-01 - - 4.0264927E-01 - - 4.0112684E-01 - - 3.9937450E-01 - - 3.9743081E-01 - - 3.9533879E-01 - - 3.9307550E-01 - - 3.9084961E-01 - - 3.8878017E-01 - - 3.8751931E-01 - - 3.8693825E-01 - - 3.9039929E-01 - - 4.0037023E-01 - - 4.1057791E-01 - - 4.1924835E-01 - - 4.2629128E-01 - - 4.3202621E-01 - - 4.3673213E-01 - - 4.4062993E-01 - - 4.4385222E-01 - - 4.4647166E-01 - - 4.4861335E-01 - - 4.5026817E-01 - - 4.5165329E-01 - - 4.5255720E-01 - - 4.5310208E-01 - - 4.5337269E-01 - - - 3.1599020E-02 - - 3.1371085E-02 - - 3.1023091E-02 - - 3.0539250E-02 - - 2.9839460E-02 - - 2.9013479E-02 - - 2.8058288E-02 - - 2.7047229E-02 - - 2.5977776E-02 - - 2.4952391E-02 - - 2.4009896E-02 - - 2.3244570E-02 - - 2.2725200E-02 - - 2.2489873E-02 - - 2.2624168E-02 - - 2.3059735E-02 - - 2.4782557E-02 - - 2.8553081E-02 - - 3.3194318E-02 - - 3.8038660E-02 - - 4.2666012E-02 - - 4.6923885E-02 - - 5.0708283E-02 - - 5.3996846E-02 - - 5.6845491E-02 - - 5.9213445E-02 - - 6.1182604E-02 - - 6.2742563E-02 - - 6.3985293E-02 - - 6.4852148E-02 - - 6.5364227E-02 - - 6.5703785E-02 - - - 4.5146530E-02 - - 4.4766687E-02 - - 4.4155441E-02 - - 4.3323960E-02 - - 4.2141314E-02 - - 4.0739637E-02 - - 3.9143652E-02 - - 3.7465300E-02 - - 3.5735871E-02 - - 3.4113931E-02 - - 3.2678644E-02 - - 3.1591060E-02 - - 3.0966537E-02 - - 3.0821062E-02 - - 3.1238242E-02 - - 3.2075654E-02 - - 3.4603728E-02 - - 3.9898114E-02 - - 4.6725370E-02 - - 5.4142159E-02 - - 6.1436273E-02 - - 6.8238302E-02 - - 7.4365771E-02 - - 7.9727018E-02 - - 8.4398863E-02 - - 8.8315890E-02 - - 9.1574736E-02 - - 9.4183896E-02 - - 9.6266615E-02 - - 9.7706019E-02 - - 9.8564505E-02 - - 9.9171965E-02 - - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - - 1.8183034E-02 - - 1.8028751E-02 - - 1.7777081E-02 - - 1.7434939E-02 - - 1.6947918E-02 - - 1.6371445E-02 - - 1.5714505E-02 - - 1.5023310E-02 - - 1.4310527E-02 - - 1.3640363E-02 - - 1.3045308E-02 - - 1.2590537E-02 - - 1.2323486E-02 - - 1.2250235E-02 - - 1.2408325E-02 - - 1.2741816E-02 - - 1.3791905E-02 - - 1.6011218E-02 - - 1.8846275E-02 - - 2.1907807E-02 - - 2.4909120E-02 - - 2.7704245E-02 - - 3.0220623E-02 - - 3.2422114E-02 - - 3.4339614E-02 - - 3.5947934E-02 - - 3.7286018E-02 - - 3.8357139E-02 - - 3.9212858E-02 - - 3.9804080E-02 - - 4.0156625E-02 - - 4.0404918E-02 - - - 3.7585902E-01 - - 4.4872720E-02 - - 2.2814276E-02 - - 1.1556342E-02 - - 7.2018303E-03 - - 3.6175403E-03 - - - - 3.7582315E-01 - - 4.4995749E-02 - - 2.2725116E-02 - - 1.1466478E-02 - - 7.0875483E-03 - - 3.5308164E-03 - - - - 3.7572011E-01 - - 4.4992452E-02 - - 2.2759820E-02 - - 1.1516099E-02 - - 7.0323440E-03 - - 3.5020003E-03 - - - - 3.7562995E-01 - - 4.5132914E-02 - - 2.2777514E-02 - - 1.1548988E-02 - - 7.0831467E-03 - - 3.5299129E-03 - - - - 3.7536612E-01 - - 4.5293164E-02 - - 2.2890080E-02 - - 1.1675089E-02 - - 7.1438522E-03 - - 3.5771809E-03 - - - - 3.7510372E-01 - - 4.5594244E-02 - - 2.2986083E-02 - - 1.1616892E-02 - - 7.1593645E-03 - - 3.5827527E-03 - - - - 3.7471139E-01 - - 4.5893399E-02 - - 2.3129097E-02 - - 1.1710573E-02 - - 7.2294990E-03 - - 3.6035030E-03 - - - - 3.7417853E-01 - - 4.6212271E-02 - - 2.3407493E-02 - - 1.1803607E-02 - - 7.2768873E-03 - - 3.6185275E-03 - - - - 3.7350485E-01 - - 4.6653124E-02 - - 2.3603271E-02 - - 1.1928427E-02 - - 7.3368483E-03 - - 3.6311780E-03 - - - - 3.7257204E-01 - - 4.7127424E-02 - - 2.3927026E-02 - - 1.2138279E-02 - - 7.4376541E-03 - - 3.6855451E-03 - - - - 3.7144563E-01 - - 4.7675499E-02 - - 2.4252831E-02 - - 1.2320100E-02 - - 7.5749097E-03 - - 3.7669728E-03 - - - - 3.6996977E-01 - - 4.8300830E-02 - - 2.4647138E-02 - - 1.2560662E-02 - - 7.7886594E-03 - - 3.8654464E-03 - - - - 3.6821602E-01 - - 4.8824396E-02 - - 2.5017750E-02 - - 1.2840163E-02 - - 7.9274823E-03 - - 3.9779025E-03 - - - - 3.6638016E-01 - - 4.9306135E-02 - - 2.5474307E-02 - - 1.3192593E-02 - - 8.2112330E-03 - - 4.1160831E-03 - - - - 3.6503713E-01 - - 4.9560796E-02 - - 2.5756337E-02 - - 1.3455138E-02 - - 8.3858370E-03 - - 4.2114689E-03 - - - - 3.6400368E-01 - - 4.9633132E-02 - - 2.5987536E-02 - - 1.3659891E-02 - - 8.5714354E-03 - - 4.3181256E-03 - - - - 3.6576117E-01 - - 4.8863049E-02 - - 2.5525363E-02 - - 1.3370670E-02 - - 8.3567729E-03 - - 4.1905625E-03 - - - - 3.7192172E-01 - - 4.6844936E-02 - - 2.3959446E-02 - - 1.2270393E-02 - - 7.5751281E-03 - - 3.7309644E-03 - - - - 3.7748124E-01 - - 4.4748629E-02 - - 2.2514789E-02 - - 1.1348962E-02 - - 6.9297472E-03 - - 3.4104693E-03 - - - - 3.8128097E-01 - - 4.3075850E-02 - - 2.1398961E-02 - - 1.0675116E-02 - - 6.5306660E-03 - - 3.2210938E-03 - - - - 3.8373406E-01 - - 4.1672472E-02 - - 2.0547117E-02 - - 1.0330913E-02 - - 6.3048028E-03 - - 3.1386749E-03 - - - - 3.8520439E-01 - - 4.0681902E-02 - - 2.0057126E-02 - - 1.0056063E-02 - - 6.1829817E-03 - - 3.0802737E-03 - - - - 3.8614505E-01 - - 3.9879282E-02 - - 1.9626439E-02 - - 9.9375963E-03 - - 6.1229946E-03 - - 3.0426688E-03 - - - - 3.8675390E-01 - - 3.9278504E-02 - - 1.9339777E-02 - - 9.8184985E-03 - - 6.0956157E-03 - - 3.0580002E-03 - - - - 3.8705360E-01 - - 3.8883125E-02 - - 1.9159064E-02 - - 9.7301477E-03 - - 6.0595588E-03 - - 3.0225068E-03 - - - - 3.8731880E-01 - - 3.8576519E-02 - - 1.9045072E-02 - - 9.7127863E-03 - - 6.0463869E-03 - - 3.0519472E-03 - - - - 3.8756725E-01 - - 3.8382695E-02 - - 1.8916082E-02 - - 9.6925622E-03 - - 6.0590015E-03 - - 2.9913798E-03 - - - - 3.8761982E-01 - - 3.8249486E-02 - - 1.8841512E-02 - - 9.6699646E-03 - - 6.0488356E-03 - - 3.0212480E-03 - - - - 3.8779017E-01 - - 3.8052198E-02 - - 1.8815974E-02 - - 9.5833623E-03 - - 5.9965640E-03 - - 2.9751261E-03 - - - - 3.8780028E-01 - - 3.7931450E-02 - - 1.8735581E-02 - - 9.6072395E-03 - - 5.9416328E-03 - - 3.0080955E-03 - - - - 3.8782277E-01 - - 3.7963999E-02 - - 1.8776116E-02 - - 9.6491264E-03 - - 5.9087373E-03 - - 3.0066367E-03 - - - - 3.8767898E-01 - - 3.7876954E-02 - - 1.8837344E-02 - - 9.7088929E-03 - - 5.9136976E-03 - - 3.0171235E-03 - - - 1.0002763E+00 - - - 1.0002760E+00 - - - 1.0002658E+00 - - - 1.0002710E+00 - - - 1.0002776E+00 - - - 1.0002767E+00 - - - 1.0002833E+00 - - - 1.0002791E+00 - - - 1.0002788E+00 - - - 1.0002858E+00 - - - 1.0002884E+00 - - - 1.0002916E+00 - - - 1.0003039E+00 - - - 1.0003181E+00 - - - 1.0003365E+00 - - - 1.0003544E+00 - - - 1.0003372E+00 - - - 1.0002764E+00 - - - 1.0002508E+00 - - - 1.0002343E+00 - - - 1.0002360E+00 - - - 1.0002375E+00 - - - 1.0002331E+00 - - - 1.0002344E+00 - - - 1.0002385E+00 - - - 1.0002316E+00 - - - 1.0002360E+00 - - - 1.0002360E+00 - - - 1.0002354E+00 - - - 1.0002349E+00 - - - 1.0002325E+00 - - - 1.0002268E+00 - - - - - clad_ang - clad_ang - 2.5300000E-08 - 5 - false - 32 - 1 - angle - - 3.1005638E-01 - - 3.0999067E-01 - - 3.0994879E-01 - - 3.0987779E-01 - - 3.0961631E-01 - - 3.0948272E-01 - - 3.0913340E-01 - - 3.0868239E-01 - - 3.0799925E-01 - - 3.0712597E-01 - - 3.0590948E-01 - - 3.0432728E-01 - - 3.0235012E-01 - - 2.9996873E-01 - - 2.9743091E-01 - - 2.9739624E-01 - - 3.0835788E-01 - - 3.1305337E-01 - - 3.1379599E-01 - - 3.1314506E-01 - - 3.1216249E-01 - - 3.1129786E-01 - - 3.1059203E-01 - - 3.1009561E-01 - - 3.0977837E-01 - - 3.0951041E-01 - - 3.0930940E-01 - - 3.0929712E-01 - - 3.0925741E-01 - - 3.0917641E-01 - - 3.0919741E-01 - - 3.0912502E-01 - - - 1.3490691E-03 - - 1.3463259E-03 - - 1.3498512E-03 - - 1.3366347E-03 - - 1.3288899E-03 - - 1.3176269E-03 - - 1.3059971E-03 - - 1.2891508E-03 - - 1.2713136E-03 - - 1.2555332E-03 - - 1.2394055E-03 - - 1.2170158E-03 - - 1.1969201E-03 - - 1.1849620E-03 - - 1.1899173E-03 - - 1.2761137E-03 - - 1.6244505E-03 - - 1.9090551E-03 - - 2.0837409E-03 - - 2.1976011E-03 - - 2.2746911E-03 - - 2.3308251E-03 - - 2.3700744E-03 - - 2.3981231E-03 - - 2.4248079E-03 - - 2.4441792E-03 - - 2.4510541E-03 - - 2.4640212E-03 - - 2.4741885E-03 - - 2.4697219E-03 - - 2.4721421E-03 - - 2.4729172E-03 - - - 3.0860746E-01 - - 5.0621457E-02 - - 2.7347709E-02 - - 4.7204795E-03 - - 4.0838896E-03 - - 1.6974585E-03 - - - - 3.0865194E-01 - - 5.0806752E-02 - - 2.6916586E-02 - - 4.8439138E-03 - - 4.1728626E-03 - - 1.7130886E-03 - - - - 3.0861586E-01 - - 5.0757624E-02 - - 2.7196188E-02 - - 4.8679553E-03 - - 4.0626181E-03 - - 1.7815988E-03 - - - - 3.0850283E-01 - - 5.0925397E-02 - - 2.7204505E-02 - - 4.8109149E-03 - - 4.1177685E-03 - - 1.7500469E-03 - - - - 3.0831737E-01 - - 5.1138142E-02 - - 2.7308021E-02 - - 4.8683307E-03 - - 4.0620680E-03 - - 1.6728150E-03 - - - - 3.0815133E-01 - - 5.1220538E-02 - - 2.7286345E-02 - - 4.8715905E-03 - - 4.0963982E-03 - - 1.6783881E-03 - - - - 3.0777979E-01 - - 5.1536936E-02 - - 2.7522750E-02 - - 4.9751865E-03 - - 4.1461347E-03 - - 1.7481718E-03 - - - - 3.0740186E-01 - - 5.1745014E-02 - - 2.7548398E-02 - - 4.9705992E-03 - - 4.2128374E-03 - - 1.7852471E-03 - - - - 3.0674467E-01 - - 5.2102012E-02 - - 2.7721735E-02 - - 4.9326171E-03 - - 4.2065723E-03 - - 1.7520577E-03 - - - - 3.0588587E-01 - - 5.2410298E-02 - - 2.7935183E-02 - - 5.1068594E-03 - - 4.2771962E-03 - - 1.7875734E-03 - - - - 3.0465659E-01 - - 5.2543078E-02 - - 2.7962434E-02 - - 5.0839680E-03 - - 4.3050048E-03 - - 1.8499733E-03 - - - - 3.0312229E-01 - - 5.2483292E-02 - - 2.8137041E-02 - - 5.2734764E-03 - - 4.4574974E-03 - - 1.8578935E-03 - - - - 3.0117092E-01 - - 5.2332000E-02 - - 2.8003257E-02 - - 5.2432554E-03 - - 4.5485878E-03 - - 1.8980534E-03 - - - - 2.9880209E-01 - - 5.1679340E-02 - - 2.7750518E-02 - - 5.3056401E-03 - - 4.5878997E-03 - - 1.9401945E-03 - - - - 2.9627667E-01 - - 5.0169523E-02 - - 2.7059202E-02 - - 5.2026216E-03 - - 4.5921641E-03 - - 1.8856744E-03 - - - - 2.9609986E-01 - - 4.6032461E-02 - - 2.4630572E-02 - - 4.5841577E-03 - - 3.9297754E-03 - - 1.6420383E-03 - - - - 3.0675667E-01 - - 3.7400062E-02 - - 1.9426565E-02 - - 2.7294131E-03 - - 2.0654845E-03 - - 6.7157182E-04 - - - - 3.1112942E-01 - - 3.2514340E-02 - - 1.7042298E-02 - - 2.2975512E-03 - - 1.7171252E-03 - - 6.1586296E-04 - - - - 3.1168284E-01 - - 2.9994361E-02 - - 1.5982971E-02 - - 2.2082409E-03 - - 1.7621544E-03 - - 6.7848731E-04 - - - - 3.1094402E-01 - - 2.9043011E-02 - - 1.5559822E-02 - - 2.3867453E-03 - - 1.8805422E-03 - - 8.0257257E-04 - - - - 3.0988917E-01 - - 2.8642621E-02 - - 1.5527633E-02 - - 2.5363175E-03 - - 2.0667848E-03 - - 8.9512793E-04 - - - - 3.0900783E-01 - - 2.8683967E-02 - - 1.5531635E-02 - - 2.6907133E-03 - - 2.2374989E-03 - - 9.9838820E-04 - - - - 3.0823110E-01 - - 2.8772506E-02 - - 1.5617343E-02 - - 2.7855260E-03 - - 2.3324886E-03 - - 1.0334317E-03 - - - - 3.0768619E-01 - - 2.9118421E-02 - - 1.5860568E-02 - - 2.8469804E-03 - - 2.4600144E-03 - - 1.0754851E-03 - - - - 3.0729355E-01 - - 2.9429106E-02 - - 1.6138063E-02 - - 2.9901807E-03 - - 2.5154903E-03 - - 1.1139796E-03 - - - - 3.0707342E-01 - - 2.9773340E-02 - - 1.6110013E-02 - - 2.9606704E-03 - - 2.6433692E-03 - - 1.1310602E-03 - - - - 3.0685025E-01 - - 3.0055483E-02 - - 1.6246774E-02 - - 3.1035410E-03 - - 2.6316501E-03 - - 1.1158252E-03 - - - - 3.0681469E-01 - - 3.0238686E-02 - - 1.6524723E-02 - - 3.0402635E-03 - - 2.6108287E-03 - - 1.1691486E-03 - - - - 3.0690606E-01 - - 3.0618190E-02 - - 1.6493402E-02 - - 3.0268029E-03 - - 2.5956288E-03 - - 1.0751657E-03 - - - - 3.0676357E-01 - - 3.0613175E-02 - - 1.6679358E-02 - - 2.8764512E-03 - - 2.5398735E-03 - - 1.0482210E-03 - - - - 3.0676223E-01 - - 3.0798581E-02 - - 1.6764686E-02 - - 3.1471928E-03 - - 2.7160881E-03 - - 1.2265875E-03 - - - - 3.0687178E-01 - - 3.0702117E-02 - - 1.6628813E-02 - - 2.8692462E-03 - - 2.4997850E-03 - - 9.3974161E-04 - - - 1.0000416E+00 - - - 1.0000513E+00 - - - 1.0000397E+00 - - - 1.0000409E+00 - - - 1.0000455E+00 - - - 1.0000417E+00 - - - 1.0000452E+00 - - - 1.0000431E+00 - - - 1.0000455E+00 - - - 1.0000451E+00 - - - 1.0000445E+00 - - - 1.0000482E+00 - - - 1.0000507E+00 - - - 1.0000542E+00 - - - 1.0000545E+00 - - - 1.0000461E+00 - - - 1.0000114E+00 - - - 1.0000112E+00 - - - 1.0000195E+00 - - - 1.0000216E+00 - - - 1.0000279E+00 - - - 1.0000307E+00 - - - 1.0000302E+00 - - - 1.0000313E+00 - - - 1.0000334E+00 - - - 1.0000309E+00 - - - 1.0000325E+00 - - - 1.0000318E+00 - - - 1.0000346E+00 - - - 1.0000335E+00 - - - 1.0000285E+00 - - - 1.0000358E+00 - - - - - lwtr_ang - lwtr_ang - 2.5300000E-08 - 5 - false - 32 - 1 - angle - - 8.3129229E-01 - - 8.3203829E-01 - - 8.3332424E-01 - - 8.3539719E-01 - - 8.3799288E-01 - - 8.4156597E-01 - - 8.4594074E-01 - - 8.5122773E-01 - - 8.5788274E-01 - - 8.6633387E-01 - - 8.7719846E-01 - - 8.9195077E-01 - - 9.1326621E-01 - - 9.4469159E-01 - - 9.9368716E-01 - - 1.0616854E+00 - - 1.0982938E+00 - - 1.0997200E+00 - - 1.0855410E+00 - - 1.0676695E+00 - - 1.0508172E+00 - - 1.0369337E+00 - - 1.0255762E+00 - - 1.0162841E+00 - - 1.0086633E+00 - - 1.0025783E+00 - - 9.9737297E-01 - - 9.9326768E-01 - - 9.9030852E-01 - - 9.8792719E-01 - - 9.8610453E-01 - - 9.8540665E-01 - - - 7.7368065E-03 - - 7.7519393E-03 - - 7.7819449E-03 - - 7.8285240E-03 - - 7.8881877E-03 - - 7.9652685E-03 - - 8.0588251E-03 - - 8.1724303E-03 - - 8.3079937E-03 - - 8.4749946E-03 - - 8.6811506E-03 - - 8.9456784E-03 - - 9.3049336E-03 - - 9.8025199E-03 - - 1.0529992E-02 - - 1.1498571E-02 - - 1.2065971E-02 - - 1.2168395E-02 - - 1.2053690E-02 - - 1.1870414E-02 - - 1.1678759E-02 - - 1.1516371E-02 - - 1.1377145E-02 - - 1.1262809E-02 - - 1.1166687E-02 - - 1.1090107E-02 - - 1.1022668E-02 - - 1.0968772E-02 - - 1.0931381E-02 - - 1.0898236E-02 - - 1.0872094E-02 - - 1.0866295E-02 - - - 8.2371185E-01 - - 3.5234207E-01 - - 1.1927931E-01 - - 7.4555729E-03 - - -1.8093822E-02 - - 4.7584668E-04 - - - - 8.2420033E-01 - - 3.5255993E-01 - - 1.1937026E-01 - - 7.2853742E-03 - - -1.8313481E-02 - - 4.3042936E-04 - - - - 8.2554395E-01 - - 3.5269171E-01 - - 1.1923224E-01 - - 7.3701368E-03 - - -1.8272340E-02 - - 4.4800957E-04 - - - - 8.2759297E-01 - - 3.5316566E-01 - - 1.1927088E-01 - - 7.3660347E-03 - - -1.8328170E-02 - - 4.1130682E-04 - - - - 8.3010220E-01 - - 3.5369971E-01 - - 1.1938537E-01 - - 7.4104975E-03 - - -1.8303317E-02 - - 4.1953876E-04 - - - - 8.3343687E-01 - - 3.5441436E-01 - - 1.1949872E-01 - - 7.5322327E-03 - - -1.8306753E-02 - - 4.5747101E-04 - - - - 8.3787092E-01 - - 3.5551997E-01 - - 1.1969232E-01 - - 7.5811660E-03 - - -1.8329166E-02 - - 4.7852748E-04 - - - - 8.4310387E-01 - - 3.5672367E-01 - - 1.1987885E-01 - - 7.6564988E-03 - - -1.8365527E-02 - - 4.5067238E-04 - - - - 8.4958953E-01 - - 3.5843887E-01 - - 1.2018528E-01 - - 7.7892315E-03 - - -1.8386164E-02 - - 4.8596316E-04 - - - - 8.5783406E-01 - - 3.6063097E-01 - - 1.2066889E-01 - - 7.9351893E-03 - - -1.8471175E-02 - - 4.7399741E-04 - - - - 8.6863002E-01 - - 3.6377631E-01 - - 1.2139807E-01 - - 8.1733217E-03 - - -1.8540490E-02 - - 5.0406643E-04 - - - - 8.8306988E-01 - - 3.6819641E-01 - - 1.2250274E-01 - - 8.4479144E-03 - - -1.8664160E-02 - - 5.3786229E-04 - - - - 9.0387733E-01 - - 3.7488040E-01 - - 1.2420959E-01 - - 8.7500816E-03 - - -1.8976448E-02 - - 4.9664889E-04 - - - - 9.3478951E-01 - - 3.8530100E-01 - - 1.2704555E-01 - - 9.1818403E-03 - - -1.9402464E-02 - - 5.3777400E-04 - - - - 9.8306151E-01 - - 4.0212328E-01 - - 1.3182489E-01 - - 9.8420986E-03 - - -2.0147587E-02 - - 5.9236718E-04 - - - - 1.0501953E+00 - - 4.2587762E-01 - - 1.3867637E-01 - - 1.0689470E-02 - - -2.1155894E-02 - - 6.5005469E-04 - - - - 1.0862685E+00 - - 4.3797788E-01 - - 1.4197736E-01 - - 1.1172759E-02 - - -2.1737067E-02 - - 6.5599084E-04 - - - - 1.0874414E+00 - - 4.3717092E-01 - - 1.4142760E-01 - - 1.1235986E-02 - - -2.1646253E-02 - - 6.5585383E-04 - - - - 1.0736455E+00 - - 4.3084349E-01 - - 1.3933736E-01 - - 1.1186759E-02 - - -2.1309779E-02 - - 6.3989000E-04 - - - - 1.0558960E+00 - - 4.2321090E-01 - - 1.3684390E-01 - - 1.1034633E-02 - - -2.0842589E-02 - - 6.8339604E-04 - - - - 1.0391120E+00 - - 4.1635648E-01 - - 1.3463939E-01 - - 1.0869743E-02 - - -2.0503958E-02 - - 6.5877305E-04 - - - - 1.0254663E+00 - - 4.1079355E-01 - - 1.3288830E-01 - - 1.0692002E-02 - - -2.0222325E-02 - - 7.2411022E-04 - - - - 1.0142449E+00 - - 4.0621344E-01 - - 1.3145072E-01 - - 1.0526222E-02 - - -1.9995334E-02 - - 6.8891812E-04 - - - - 1.0049846E+00 - - 4.0236090E-01 - - 1.3022093E-01 - - 1.0429641E-02 - - -1.9811424E-02 - - 7.3287561E-04 - - - - 9.9758865E-01 - - 3.9933064E-01 - - 1.2934518E-01 - - 1.0285856E-02 - - -1.9735216E-02 - - 6.4095239E-04 - - - - 9.9137092E-01 - - 3.9669204E-01 - - 1.2850897E-01 - - 1.0180247E-02 - - -1.9595919E-02 - - 7.4239863E-04 - - - - 9.8633885E-01 - - 3.9464706E-01 - - 1.2782783E-01 - - 1.0115679E-02 - - -1.9489063E-02 - - 6.7732699E-04 - - - - 9.8241480E-01 - - 3.9293162E-01 - - 1.2725328E-01 - - 1.0076113E-02 - - -1.9411729E-02 - - 6.7080378E-04 - - - - 9.7912906E-01 - - 3.9164180E-01 - - 1.2687293E-01 - - 9.9947816E-03 - - -1.9390105E-02 - - 6.8484948E-04 - - - - 9.7702901E-01 - - 3.9079267E-01 - - 1.2678305E-01 - - 1.0006132E-02 - - -1.9296574E-02 - - 7.3827259E-04 - - - - 9.7553202E-01 - - 3.9010913E-01 - - 1.2644932E-01 - - 9.9292219E-03 - - -1.9314591E-02 - - 7.3482134E-04 - - - - 9.7483429E-01 - - 3.8985598E-01 - - 1.2640804E-01 - - 9.9206549E-03 - - -1.9266376E-02 - - 7.6472379E-04 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - - - uo2_ang_mu - uo2_ang_mu - 2.5300000E-08 - 32 - true - 32 - 1 - angle - histogram - - 4.0734790E-01 - - 4.0709470E-01 - - 4.0665280E-01 - - 4.0605122E-01 - - 4.0509226E-01 - - 4.0399893E-01 - - 4.0264927E-01 - - 4.0112684E-01 - - 3.9937450E-01 - - 3.9743081E-01 - - 3.9533879E-01 - - 3.9307550E-01 - - 3.9084961E-01 - - 3.8878017E-01 - - 3.8751931E-01 - - 3.8693825E-01 - - 3.9039929E-01 - - 4.0037023E-01 - - 4.1057791E-01 - - 4.1924835E-01 - - 4.2629128E-01 - - 4.3202621E-01 - - 4.3673213E-01 - - 4.4062993E-01 - - 4.4385222E-01 - - 4.4647166E-01 - - 4.4861335E-01 - - 4.5026817E-01 - - 4.5165329E-01 - - 4.5255720E-01 - - 4.5310208E-01 - - 4.5337269E-01 - - - 3.1599020E-02 - - 3.1371085E-02 - - 3.1023091E-02 - - 3.0539250E-02 - - 2.9839460E-02 - - 2.9013479E-02 - - 2.8058288E-02 - - 2.7047229E-02 - - 2.5977776E-02 - - 2.4952391E-02 - - 2.4009896E-02 - - 2.3244570E-02 - - 2.2725200E-02 - - 2.2489873E-02 - - 2.2624168E-02 - - 2.3059735E-02 - - 2.4782557E-02 - - 2.8553081E-02 - - 3.3194318E-02 - - 3.8038660E-02 - - 4.2666012E-02 - - 4.6923885E-02 - - 5.0708283E-02 - - 5.3996846E-02 - - 5.6845491E-02 - - 5.9213445E-02 - - 6.1182604E-02 - - 6.2742563E-02 - - 6.3985293E-02 - - 6.4852148E-02 - - 6.5364227E-02 - - 6.5703785E-02 - - - 4.5146530E-02 - - 4.4766687E-02 - - 4.4155441E-02 - - 4.3323960E-02 - - 4.2141314E-02 - - 4.0739637E-02 - - 3.9143652E-02 - - 3.7465300E-02 - - 3.5735871E-02 - - 3.4113931E-02 - - 3.2678644E-02 - - 3.1591060E-02 - - 3.0966537E-02 - - 3.0821062E-02 - - 3.1238242E-02 - - 3.2075654E-02 - - 3.4603728E-02 - - 3.9898114E-02 - - 4.6725370E-02 - - 5.4142159E-02 - - 6.1436273E-02 - - 6.8238302E-02 - - 7.4365771E-02 - - 7.9727018E-02 - - 8.4398863E-02 - - 8.8315890E-02 - - 9.1574736E-02 - - 9.4183896E-02 - - 9.6266615E-02 - - 9.7706019E-02 - - 9.8564505E-02 - - 9.9171965E-02 - - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - 1.0000000E+00 - - - 1.8183034E-02 - - 1.8028751E-02 - - 1.7777081E-02 - - 1.7434939E-02 - - 1.6947918E-02 - - 1.6371445E-02 - - 1.5714505E-02 - - 1.5023310E-02 - - 1.4310527E-02 - - 1.3640363E-02 - - 1.3045308E-02 - - 1.2590537E-02 - - 1.2323486E-02 - - 1.2250235E-02 - - 1.2408325E-02 - - 1.2741816E-02 - - 1.3791905E-02 - - 1.6011218E-02 - - 1.8846275E-02 - - 2.1907807E-02 - - 2.4909120E-02 - - 2.7704245E-02 - - 3.0220623E-02 - - 3.2422114E-02 - - 3.4339614E-02 - - 3.5947934E-02 - - 3.7286018E-02 - - 3.8357139E-02 - - 3.9212858E-02 - - 3.9804080E-02 - - 4.0156625E-02 - - 4.0404918E-02 - - - 9.8066123E-03 - - 9.6646401E-03 - - 9.6663597E-03 - - 9.6289590E-03 - - 9.6096138E-03 - - 9.6458323E-03 - - 9.7060173E-03 - - 9.7686742E-03 - - 9.7497590E-03 - - 9.8863575E-03 - - 9.9653503E-03 - - 1.0024461E-02 - - 1.0143433E-02 - - 1.0224038E-02 - - 1.0343441E-02 - - 1.0433289E-02 - - 1.0526146E-02 - - 1.0783759E-02 - - 1.0949268E-02 - - 1.1096291E-02 - - 1.1232675E-02 - - 1.1455467E-02 - - 1.1650746E-02 - - 1.1903201E-02 - - 1.2297735E-02 - - 1.2748370E-02 - - 1.3264457E-02 - - 1.4048689E-02 - - 1.5280440E-02 - - 1.6908123E-02 - - 1.9601832E-02 - - 2.3844984E-02 - - - - 9.7708240E-03 - - 9.6914019E-03 - - 9.6149267E-03 - - 9.5973173E-03 - - 9.6433893E-03 - - 9.6506128E-03 - - 9.7039801E-03 - - 9.6956785E-03 - - 9.7873194E-03 - - 9.8654118E-03 - - 9.9413480E-03 - - 1.0063248E-02 - - 1.0102923E-02 - - 1.0232802E-02 - - 1.0308882E-02 - - 1.0501651E-02 - - 1.0589986E-02 - - 1.0719182E-02 - - 1.0893048E-02 - - 1.1057750E-02 - - 1.1303383E-02 - - 1.1462120E-02 - - 1.1668725E-02 - - 1.1965138E-02 - - 1.2270967E-02 - - 1.2704483E-02 - - 1.3318045E-02 - - 1.4113776E-02 - - 1.5284443E-02 - - 1.6903540E-02 - - 1.9623766E-02 - - 2.3773086E-02 - - - - 9.7573912E-03 - - 9.6754767E-03 - - 9.6414920E-03 - - 9.5888776E-03 - - 9.6229707E-03 - - 9.6517720E-03 - - 9.7047117E-03 - - 9.7260741E-03 - - 9.8017859E-03 - - 9.8536413E-03 - - 9.9389825E-03 - - 1.0024606E-02 - - 1.0138509E-02 - - 1.0234629E-02 - - 1.0324330E-02 - - 1.0453936E-02 - - 1.0578467E-02 - - 1.0739823E-02 - - 1.0879319E-02 - - 1.1046986E-02 - - 1.1241981E-02 - - 1.1441204E-02 - - 1.1664457E-02 - - 1.1957610E-02 - - 1.2276940E-02 - - 1.2759947E-02 - - 1.3279607E-02 - - 1.4124886E-02 - - 1.5267698E-02 - - 1.6982394E-02 - - 1.9550155E-02 - - 2.3789453E-02 - - - - 9.7595941E-03 - - 9.6406785E-03 - - 9.6091241E-03 - - 9.6094212E-03 - - 9.6096714E-03 - - 9.6231813E-03 - - 9.6784094E-03 - - 9.7493834E-03 - - 9.7951671E-03 - - 9.8514115E-03 - - 9.9241369E-03 - - 1.0012170E-02 - - 1.0117529E-02 - - 1.0213412E-02 - - 1.0335767E-02 - - 1.0447944E-02 - - 1.0584231E-02 - - 1.0753231E-02 - - 1.0883138E-02 - - 1.1065663E-02 - - 1.1250080E-02 - - 1.1439297E-02 - - 1.1646700E-02 - - 1.1958053E-02 - - 1.2287514E-02 - - 1.2721568E-02 - - 1.3290189E-02 - - 1.4110041E-02 - - 1.5281715E-02 - - 1.6979118E-02 - - 1.9608566E-02 - - 2.3793845E-02 - - - - 9.7316881E-03 - - 9.6194631E-03 - - 9.6065192E-03 - - 9.5773341E-03 - - 9.6080573E-03 - - 9.6136679E-03 - - 9.6707217E-03 - - 9.7207622E-03 - - 9.7745677E-03 - - 9.8542855E-03 - - 9.9290325E-03 - - 1.0013807E-02 - - 1.0087705E-02 - - 1.0212493E-02 - - 1.0318553E-02 - - 1.0440413E-02 - - 1.0586043E-02 - - 1.0693482E-02 - - 1.0881032E-02 - - 1.1028668E-02 - - 1.1236016E-02 - - 1.1448039E-02 - - 1.1645248E-02 - - 1.1940864E-02 - - 1.2280554E-02 - - 1.2704859E-02 - - 1.3284908E-02 - - 1.4087561E-02 - - 1.5269781E-02 - - 1.6974160E-02 - - 1.9647654E-02 - - 2.3878185E-02 - - - - 9.7161201E-03 - - 9.6202380E-03 - - 9.5797790E-03 - - 9.5545189E-03 - - 9.5785124E-03 - - 9.5970413E-03 - - 9.6077970E-03 - - 9.7078158E-03 - - 9.7457417E-03 - - 9.8241572E-03 - - 9.9053715E-03 - - 9.9664533E-03 - - 1.0069700E-02 - - 1.0182303E-02 - - 1.0310258E-02 - - 1.0426742E-02 - - 1.0561490E-02 - - 1.0707708E-02 - - 1.0863937E-02 - - 1.1051125E-02 - - 1.1221704E-02 - - 1.1442069E-02 - - 1.1658848E-02 - - 1.1941489E-02 - - 1.2275743E-02 - - 1.2702110E-02 - - 1.3323051E-02 - - 1.4108176E-02 - - 1.5289516E-02 - - 1.6993392E-02 - - 1.9675117E-02 - - 2.3895695E-02 - - - - 9.6862964E-03 - - 9.6118860E-03 - - 9.5204994E-03 - - 9.5427943E-03 - - 9.5461966E-03 - - 9.5657839E-03 - - 9.5949449E-03 - - 9.6654696E-03 - - 9.7413833E-03 - - 9.7999604E-03 - - 9.8652718E-03 - - 9.9395415E-03 - - 1.0066252E-02 - - 1.0162957E-02 - - 1.0288525E-02 - - 1.0410136E-02 - - 1.0544012E-02 - - 1.0683294E-02 - - 1.0857487E-02 - - 1.1034643E-02 - - 1.1202400E-02 - - 1.1413244E-02 - - 1.1649707E-02 - - 1.1927823E-02 - - 1.2268032E-02 - - 1.2711207E-02 - - 1.3301163E-02 - - 1.4107114E-02 - - 1.5299888E-02 - - 1.7035047E-02 - - 1.9688248E-02 - - 2.3980184E-02 - - - - 9.6789320E-03 - - 9.5794368E-03 - - 9.5136834E-03 - - 9.4987637E-03 - - 9.5122403E-03 - - 9.5462846E-03 - - 9.5893599E-03 - - 9.6291844E-03 - - 9.6755880E-03 - - 9.7758823E-03 - - 9.8512097E-03 - - 9.9153183E-03 - - 1.0010492E-02 - - 1.0132751E-02 - - 1.0249082E-02 - - 1.0374304E-02 - - 1.0525789E-02 - - 1.0647590E-02 - - 1.0816183E-02 - - 1.1002705E-02 - - 1.1172733E-02 - - 1.1391942E-02 - - 1.1634015E-02 - - 1.1896152E-02 - - 1.2250313E-02 - - 1.2701494E-02 - - 1.3297953E-02 - - 1.4128277E-02 - - 1.5304878E-02 - - 1.7057822E-02 - - 1.9759949E-02 - - 2.4058227E-02 - - - - 9.6295658E-03 - - 9.5389047E-03 - - 9.4742925E-03 - - 9.4575039E-03 - - 9.4670086E-03 - - 9.5016333E-03 - - 9.5287576E-03 - - 9.5962610E-03 - - 9.6450345E-03 - - 9.7355000E-03 - - 9.8168240E-03 - - 9.8832939E-03 - - 9.9783337E-03 - - 1.0096077E-02 - - 1.0226691E-02 - - 1.0343925E-02 - - 1.0478576E-02 - - 1.0624400E-02 - - 1.0795052E-02 - - 1.0971506E-02 - - 1.1155210E-02 - - 1.1359948E-02 - - 1.1600072E-02 - - 1.1891155E-02 - - 1.2217464E-02 - - 1.2687949E-02 - - 1.3279851E-02 - - 1.4139232E-02 - - 1.5331088E-02 - - 1.7109049E-02 - - 1.9804341E-02 - - 2.4140346E-02 - - - - 9.5761863E-03 - - 9.4820918E-03 - - 9.4335419E-03 - - 9.4124923E-03 - - 9.4238881E-03 - - 9.4447526E-03 - - 9.4999957E-03 - - 9.5315541E-03 - - 9.6078277E-03 - - 9.7003335E-03 - - 9.7574525E-03 - - 9.8379436E-03 - - 9.9462733E-03 - - 1.0053971E-02 - - 1.0174903E-02 - - 1.0296178E-02 - - 1.0416178E-02 - - 1.0598338E-02 - - 1.0736969E-02 - - 1.0921999E-02 - - 1.1103049E-02 - - 1.1337535E-02 - - 1.1560952E-02 - - 1.1844754E-02 - - 1.2186109E-02 - - 1.2650980E-02 - - 1.3288356E-02 - - 1.4113781E-02 - - 1.5336174E-02 - - 1.7136757E-02 - - 1.9885917E-02 - - 2.4274812E-02 - - - - 9.5122168E-03 - - 9.4370370E-03 - - 9.3789842E-03 - - 9.3641793E-03 - - 9.3461446E-03 - - 9.3736151E-03 - - 9.4378621E-03 - - 9.4888307E-03 - - 9.5578870E-03 - - 9.6287585E-03 - - 9.7018579E-03 - - 9.7842398E-03 - - 9.8853931E-03 - - 9.9928939E-03 - - 1.0118830E-02 - - 1.0234335E-02 - - 1.0390558E-02 - - 1.0549529E-02 - - 1.0695492E-02 - - 1.0871300E-02 - - 1.1074656E-02 - - 1.1276285E-02 - - 1.1528116E-02 - - 1.1795259E-02 - - 1.2170410E-02 - - 1.2620687E-02 - - 1.3248447E-02 - - 1.4113310E-02 - - 1.5330992E-02 - - 1.7146317E-02 - - 1.9971083E-02 - - 2.4420125E-02 - - - - 9.4655965E-03 - - 9.3472543E-03 - - 9.3135845E-03 - - 9.2723897E-03 - - 9.2802062E-03 - - 9.3207904E-03 - - 9.3438769E-03 - - 9.4089282E-03 - - 9.4772470E-03 - - 9.5593066E-03 - - 9.6350349E-03 - - 9.7156422E-03 - - 9.8254749E-03 - - 9.9256153E-03 - - 1.0046422E-02 - - 1.0170127E-02 - - 1.0324109E-02 - - 1.0494779E-02 - - 1.0643991E-02 - - 1.0830850E-02 - - 1.1006031E-02 - - 1.1226896E-02 - - 1.1461160E-02 - - 1.1751421E-02 - - 1.2117075E-02 - - 1.2580807E-02 - - 1.3191655E-02 - - 1.4078045E-02 - - 1.5308284E-02 - - 1.7194422E-02 - - 2.0045307E-02 - - 2.4607445E-02 - - - - 9.3803794E-03 - - 9.2679518E-03 - - 9.2244314E-03 - - 9.2113545E-03 - - 9.2138570E-03 - - 9.2462589E-03 - - 9.2883856E-03 - - 9.3378797E-03 - - 9.4087558E-03 - - 9.4791189E-03 - - 9.5459849E-03 - - 9.6532937E-03 - - 9.7407231E-03 - - 9.8542750E-03 - - 9.9718785E-03 - - 1.0102253E-02 - - 1.0257191E-02 - - 1.0422947E-02 - - 1.0576154E-02 - - 1.0751370E-02 - - 1.0937694E-02 - - 1.1150504E-02 - - 1.1403363E-02 - - 1.1690271E-02 - - 1.2041631E-02 - - 1.2515941E-02 - - 1.3148002E-02 - - 1.4030663E-02 - - 1.5293666E-02 - - 1.7182409E-02 - - 2.0111404E-02 - - 2.4776028E-02 - - - - 9.3172617E-03 - - 9.2089569E-03 - - 9.1486659E-03 - - 9.1277777E-03 - - 9.1461098E-03 - - 9.1678665E-03 - - 9.2093270E-03 - - 9.2630599E-03 - - 9.3084731E-03 - - 9.4133582E-03 - - 9.4836368E-03 - - 9.5792942E-03 - - 9.6772510E-03 - - 9.7775420E-03 - - 9.9042034E-03 - - 1.0042269E-02 - - 1.0180349E-02 - - 1.0339342E-02 - - 1.0499500E-02 - - 1.0689206E-02 - - 1.0856780E-02 - - 1.1064872E-02 - - 1.1313606E-02 - - 1.1607748E-02 - - 1.1964604E-02 - - 1.2435691E-02 - - 1.3060461E-02 - - 1.3974178E-02 - - 1.5269813E-02 - - 1.7174181E-02 - - 2.0168154E-02 - - 2.5006625E-02 - - - - 9.2675186E-03 - - 9.1560947E-03 - - 9.1099682E-03 - - 9.0686023E-03 - - 9.0949282E-03 - - 9.1189359E-03 - - 9.1587135E-03 - - 9.2079644E-03 - - 9.2872523E-03 - - 9.3678425E-03 - - 9.4331971E-03 - - 9.5255074E-03 - - 9.6234797E-03 - - 9.7408756E-03 - - 9.8464228E-03 - - 9.9839770E-03 - - 1.0134229E-02 - - 1.0296950E-02 - - 1.0437157E-02 - - 1.0621205E-02 - - 1.0805038E-02 - - 1.1016214E-02 - - 1.1261528E-02 - - 1.1539985E-02 - - 1.1895722E-02 - - 1.2371092E-02 - - 1.3001136E-02 - - 1.3913205E-02 - - 1.5214879E-02 - - 1.7172526E-02 - - 2.0220324E-02 - - 2.5144658E-02 - - - - 9.2487420E-03 - - 9.1281258E-03 - - 9.0754703E-03 - - 9.0528962E-03 - - 9.0607826E-03 - - 9.0836186E-03 - - 9.1336267E-03 - - 9.1791302E-03 - - 9.2456080E-03 - - 9.3262261E-03 - - 9.3970635E-03 - - 9.4814471E-03 - - 9.5988170E-03 - - 9.7082444E-03 - - 9.8223867E-03 - - 9.9431245E-03 - - 1.0105918E-02 - - 1.0235908E-02 - - 1.0399441E-02 - - 1.0585520E-02 - - 1.0757015E-02 - - 1.0981562E-02 - - 1.1194196E-02 - - 1.1486474E-02 - - 1.1845432E-02 - - 1.2322129E-02 - - 1.2940763E-02 - - 1.3835543E-02 - - 1.5166292E-02 - - 1.7159569E-02 - - 2.0241404E-02 - - 2.5261208E-02 - - - - 9.3326963E-03 - - 9.2136145E-03 - - 9.1672115E-03 - - 9.1448034E-03 - - 9.1509378E-03 - - 9.1710414E-03 - - 9.2163629E-03 - - 9.2665486E-03 - - 9.3325121E-03 - - 9.4016396E-03 - - 9.5034088E-03 - - 9.5773816E-03 - - 9.6674816E-03 - - 9.7850853E-03 - - 9.9014422E-03 - - 1.0023693E-02 - - 1.0166562E-02 - - 1.0315995E-02 - - 1.0472398E-02 - - 1.0641203E-02 - - 1.0830711E-02 - - 1.1048828E-02 - - 1.1263336E-02 - - 1.1551095E-02 - - 1.1894787E-02 - - 1.2358496E-02 - - 1.2983340E-02 - - 1.3874895E-02 - - 1.5186930E-02 - - 1.7144384E-02 - - 2.0133533E-02 - - 2.5038814E-02 - - - - 9.5906528E-03 - - 9.4714149E-03 - - 9.4373276E-03 - - 9.4092245E-03 - - 9.4080878E-03 - - 9.4464166E-03 - - 9.4856267E-03 - - 9.5436808E-03 - - 9.6059463E-03 - - 9.6771305E-03 - - 9.7582049E-03 - - 9.8361595E-03 - - 9.9382461E-03 - - 1.0051079E-02 - - 1.0152805E-02 - - 1.0287101E-02 - - 1.0441087E-02 - - 1.0565078E-02 - - 1.0711502E-02 - - 1.0891178E-02 - - 1.1071184E-02 - - 1.1292859E-02 - - 1.1522246E-02 - - 1.1788324E-02 - - 1.2135266E-02 - - 1.2615017E-02 - - 1.3201487E-02 - - 1.4060330E-02 - - 1.5281894E-02 - - 1.7084038E-02 - - 1.9845860E-02 - - 2.4315267E-02 - - - - 9.8248104E-03 - - 9.7323237E-03 - - 9.6774360E-03 - - 9.6780777E-03 - - 9.6806071E-03 - - 9.7078157E-03 - - 9.7458638E-03 - - 9.8100671E-03 - - 9.8562275E-03 - - 9.9244575E-03 - - 1.0022233E-02 - - 1.0083426E-02 - - 1.0184960E-02 - - 1.0286955E-02 - - 1.0393298E-02 - - 1.0523934E-02 - - 1.0674383E-02 - - 1.0799950E-02 - - 1.0950769E-02 - - 1.1117330E-02 - - 1.1304368E-02 - - 1.1511486E-02 - - 1.1731876E-02 - - 1.2009368E-02 - - 1.2343059E-02 - - 1.2776813E-02 - - 1.3375541E-02 - - 1.4170942E-02 - - 1.5323633E-02 - - 1.7010159E-02 - - 1.9570530E-02 - - 2.3678539E-02 - - - - 1.0003922E-02 - - 9.9126090E-03 - - 9.8710015E-03 - - 9.8670066E-03 - - 9.8659781E-03 - - 9.8893674E-03 - - 9.9377144E-03 - - 9.9843851E-03 - - 1.0043716E-02 - - 1.0114248E-02 - - 1.0187530E-02 - - 1.0267347E-02 - - 1.0358552E-02 - - 1.0462167E-02 - - 1.0591882E-02 - - 1.0702606E-02 - - 1.0831901E-02 - - 1.0977238E-02 - - 1.1108339E-02 - - 1.1308120E-02 - - 1.1462407E-02 - - 1.1644185E-02 - - 1.1896695E-02 - - 1.2152261E-02 - - 1.2470909E-02 - - 1.2904242E-02 - - 1.3463705E-02 - - 1.4217800E-02 - - 1.5306830E-02 - - 1.6913123E-02 - - 1.9352840E-02 - - 2.3210338E-02 - - - - 1.0110150E-02 - - 1.0038689E-02 - - 1.0006487E-02 - - 9.9882512E-03 - - 1.0012465E-02 - - 1.0038003E-02 - - 1.0080385E-02 - - 1.0133099E-02 - - 1.0195776E-02 - - 1.0230495E-02 - - 1.0337794E-02 - - 1.0414378E-02 - - 1.0494026E-02 - - 1.0600307E-02 - - 1.0712290E-02 - - 1.0823942E-02 - - 1.0947285E-02 - - 1.1079870E-02 - - 1.1237336E-02 - - 1.1392659E-02 - - 1.1573008E-02 - - 1.1782567E-02 - - 1.1965944E-02 - - 1.2231191E-02 - - 1.2530296E-02 - - 1.2940908E-02 - - 1.3487030E-02 - - 1.4206747E-02 - - 1.5258559E-02 - - 1.6813287E-02 - - 1.9165344E-02 - - 2.2905494E-02 - - - - 1.0214736E-02 - - 1.0132229E-02 - - 1.0105238E-02 - - 1.0076016E-02 - - 1.0102342E-02 - - 1.0126079E-02 - - 1.0166649E-02 - - 1.0211271E-02 - - 1.0274414E-02 - - 1.0328594E-02 - - 1.0415141E-02 - - 1.0493084E-02 - - 1.0583179E-02 - - 1.0679080E-02 - - 1.0785554E-02 - - 1.0896861E-02 - - 1.1025180E-02 - - 1.1151734E-02 - - 1.1308616E-02 - - 1.1460250E-02 - - 1.1631030E-02 - - 1.1818829E-02 - - 1.2020589E-02 - - 1.2270878E-02 - - 1.2564608E-02 - - 1.2974969E-02 - - 1.3498179E-02 - - 1.4207601E-02 - - 1.5228538E-02 - - 1.6730509E-02 - - 1.9011440E-02 - - 2.2710972E-02 - - - - 1.0268267E-02 - - 1.0196885E-02 - - 1.0157361E-02 - - 1.0140649E-02 - - 1.0169437E-02 - - 1.0183304E-02 - - 1.0243979E-02 - - 1.0276945E-02 - - 1.0343732E-02 - - 1.0412311E-02 - - 1.0476453E-02 - - 1.0547309E-02 - - 1.0646659E-02 - - 1.0745962E-02 - - 1.0848409E-02 - - 1.0960759E-02 - - 1.1082990E-02 - - 1.1214082E-02 - - 1.1358598E-02 - - 1.1499661E-02 - - 1.1661477E-02 - - 1.1836025E-02 - - 1.2058652E-02 - - 1.2293116E-02 - - 1.2566338E-02 - - 1.2977505E-02 - - 1.3480636E-02 - - 1.4176526E-02 - - 1.5190195E-02 - - 1.6660100E-02 - - 1.8910243E-02 - - 2.2560488E-02 - - - - 1.0317792E-02 - - 1.0247350E-02 - - 1.0209518E-02 - - 1.0176974E-02 - - 1.0202003E-02 - - 1.0234569E-02 - - 1.0290041E-02 - - 1.0329819E-02 - - 1.0401460E-02 - - 1.0453530E-02 - - 1.0512745E-02 - - 1.0606160E-02 - - 1.0688319E-02 - - 1.0769020E-02 - - 1.0865579E-02 - - 1.0991642E-02 - - 1.1131957E-02 - - 1.1257621E-02 - - 1.1387433E-02 - - 1.1532542E-02 - - 1.1687029E-02 - - 1.1880598E-02 - - 1.2082924E-02 - - 1.2307513E-02 - - 1.2595319E-02 - - 1.2957554E-02 - - 1.3464867E-02 - - 1.4143088E-02 - - 1.5132042E-02 - - 1.6579665E-02 - - 1.8862731E-02 - - 2.2454495E-02 - - - - 1.0353436E-02 - - 1.0273106E-02 - - 1.0227967E-02 - - 1.0220784E-02 - - 1.0226684E-02 - - 1.0260876E-02 - - 1.0312588E-02 - - 1.0358157E-02 - - 1.0401938E-02 - - 1.0498406E-02 - - 1.0534029E-02 - - 1.0633113E-02 - - 1.0711786E-02 - - 1.0806930E-02 - - 1.0902341E-02 - - 1.1005862E-02 - - 1.1140903E-02 - - 1.1256190E-02 - - 1.1418216E-02 - - 1.1551704E-02 - - 1.1699315E-02 - - 1.1876316E-02 - - 1.2095791E-02 - - 1.2321059E-02 - - 1.2598778E-02 - - 1.2945785E-02 - - 1.3441410E-02 - - 1.4150310E-02 - - 1.5110707E-02 - - 1.6555004E-02 - - 1.8801362E-02 - - 2.2362745E-02 - - - - 1.0368488E-02 - - 1.0298130E-02 - - 1.0243651E-02 - - 1.0237480E-02 - - 1.0271825E-02 - - 1.0283702E-02 - - 1.0344999E-02 - - 1.0388950E-02 - - 1.0443402E-02 - - 1.0499057E-02 - - 1.0554275E-02 - - 1.0647638E-02 - - 1.0712690E-02 - - 1.0827382E-02 - - 1.0931601E-02 - - 1.1018556E-02 - - 1.1152881E-02 - - 1.1290059E-02 - - 1.1420028E-02 - - 1.1563732E-02 - - 1.1705467E-02 - - 1.1895794E-02 - - 1.2092710E-02 - - 1.2310135E-02 - - 1.2594991E-02 - - 1.2963713E-02 - - 1.3446042E-02 - - 1.4105472E-02 - - 1.5078624E-02 - - 1.6548015E-02 - - 1.8734322E-02 - - 2.2344993E-02 - - - - 1.0381081E-02 - - 1.0306858E-02 - - 1.0277150E-02 - - 1.0252664E-02 - - 1.0290401E-02 - - 1.0294657E-02 - - 1.0329546E-02 - - 1.0392619E-02 - - 1.0438626E-02 - - 1.0515024E-02 - - 1.0591864E-02 - - 1.0665572E-02 - - 1.0764627E-02 - - 1.0867664E-02 - - 1.0949159E-02 - - 1.1055591E-02 - - 1.1176115E-02 - - 1.1296618E-02 - - 1.1417920E-02 - - 1.1572450E-02 - - 1.1714864E-02 - - 1.1894815E-02 - - 1.2080388E-02 - - 1.2311306E-02 - - 1.2600200E-02 - - 1.2956245E-02 - - 1.3438289E-02 - - 1.4113577E-02 - - 1.5087407E-02 - - 1.6503410E-02 - - 1.8740374E-02 - - 2.2290166E-02 - - - - 1.0379499E-02 - - 1.0316828E-02 - - 1.0280998E-02 - - 1.0282758E-02 - - 1.0275605E-02 - - 1.0306117E-02 - - 1.0348208E-02 - - 1.0378745E-02 - - 1.0464787E-02 - - 1.0530463E-02 - - 1.0608232E-02 - - 1.0674147E-02 - - 1.0763998E-02 - - 1.0837280E-02 - - 1.0949195E-02 - - 1.1058508E-02 - - 1.1190589E-02 - - 1.1322242E-02 - - 1.1432422E-02 - - 1.1582770E-02 - - 1.1718207E-02 - - 1.1912632E-02 - - 1.2075287E-02 - - 1.2309263E-02 - - 1.2598203E-02 - - 1.2947275E-02 - - 1.3422204E-02 - - 1.4101792E-02 - - 1.5074531E-02 - - 1.6493963E-02 - - 1.8703917E-02 - - 2.2279156E-02 - - - - 1.0425160E-02 - - 1.0318223E-02 - - 1.0301788E-02 - - 1.0294047E-02 - - 1.0284686E-02 - - 1.0349566E-02 - - 1.0366017E-02 - - 1.0397170E-02 - - 1.0476721E-02 - - 1.0527169E-02 - - 1.0602826E-02 - - 1.0679945E-02 - - 1.0766188E-02 - - 1.0868516E-02 - - 1.0967919E-02 - - 1.1069388E-02 - - 1.1166089E-02 - - 1.1293657E-02 - - 1.1442396E-02 - - 1.1579055E-02 - - 1.1756181E-02 - - 1.1901153E-02 - - 1.2075228E-02 - - 1.2329489E-02 - - 1.2582177E-02 - - 1.2965246E-02 - - 1.3451596E-02 - - 1.4114325E-02 - - 1.5048259E-02 - - 1.6478843E-02 - - 1.8702139E-02 - - 2.2209013E-02 - - - - 1.0403120E-02 - - 1.0338330E-02 - - 1.0290627E-02 - - 1.0277361E-02 - - 1.0322671E-02 - - 1.0363565E-02 - - 1.0362094E-02 - - 1.0440786E-02 - - 1.0485173E-02 - - 1.0557958E-02 - - 1.0608779E-02 - - 1.0701287E-02 - - 1.0735526E-02 - - 1.0841760E-02 - - 1.0953485E-02 - - 1.1083460E-02 - - 1.1193252E-02 - - 1.1297597E-02 - - 1.1457508E-02 - - 1.1572681E-02 - - 1.1742409E-02 - - 1.1907920E-02 - - 1.2078022E-02 - - 1.2328222E-02 - - 1.2585186E-02 - - 1.2967887E-02 - - 1.3432333E-02 - - 1.4108413E-02 - - 1.5033330E-02 - - 1.6472418E-02 - - 1.8651936E-02 - - 2.2205180E-02 - - - - 1.0383972E-02 - - 1.0327340E-02 - - 1.0320447E-02 - - 1.0278943E-02 - - 1.0322805E-02 - - 1.0366993E-02 - - 1.0395218E-02 - - 1.0418111E-02 - - 1.0463460E-02 - - 1.0564171E-02 - - 1.0601357E-02 - - 1.0671268E-02 - - 1.0756633E-02 - - 1.0863620E-02 - - 1.0982943E-02 - - 1.1088262E-02 - - 1.1182298E-02 - - 1.1297412E-02 - - 1.1404871E-02 - - 1.1585288E-02 - - 1.1730768E-02 - - 1.1878353E-02 - - 1.2074551E-02 - - 1.2333404E-02 - - 1.2612428E-02 - - 1.2970577E-02 - - 1.3454326E-02 - - 1.4077858E-02 - - 1.5040384E-02 - - 1.6507810E-02 - - 1.8671362E-02 - - 2.2195534E-02 - - - - 1.0393621E-02 - - 1.0343827E-02 - - 1.0278122E-02 - - 1.0307024E-02 - - 1.0321853E-02 - - 1.0374136E-02 - - 1.0395136E-02 - - 1.0457919E-02 - - 1.0485306E-02 - - 1.0588898E-02 - - 1.0597124E-02 - - 1.0623537E-02 - - 1.0731134E-02 - - 1.0828231E-02 - - 1.0959209E-02 - - 1.1072327E-02 - - 1.1248877E-02 - - 1.1263490E-02 - - 1.1402046E-02 - - 1.1566689E-02 - - 1.1767919E-02 - - 1.1861445E-02 - - 1.2076314E-02 - - 1.2322575E-02 - - 1.2537228E-02 - - 1.2963070E-02 - - 1.3353083E-02 - - 1.4108968E-02 - - 1.5044977E-02 - - 1.6501651E-02 - - 1.8769742E-02 - - 2.2133504E-02 - - - 1.0002763E+00 - - - 1.0002760E+00 - - - 1.0002658E+00 - - - 1.0002710E+00 - - - 1.0002776E+00 - - - 1.0002767E+00 - - - 1.0002833E+00 - - - 1.0002791E+00 - - - 1.0002788E+00 - - - 1.0002858E+00 - - - 1.0002884E+00 - - - 1.0002916E+00 - - - 1.0003039E+00 - - - 1.0003181E+00 - - - 1.0003365E+00 - - - 1.0003544E+00 - - - 1.0003372E+00 - - - 1.0002764E+00 - - - 1.0002508E+00 - - - 1.0002343E+00 - - - 1.0002360E+00 - - - 1.0002375E+00 - - - 1.0002331E+00 - - - 1.0002344E+00 - - - 1.0002385E+00 - - - 1.0002316E+00 - - - 1.0002360E+00 - - - 1.0002360E+00 - - - 1.0002354E+00 - - - 1.0002349E+00 - - - 1.0002325E+00 - - - 1.0002268E+00 - - - - - clad_ang_mu - clad_ang_mu - 2.5300000E-08 - 32 - false - 32 - 1 - angle - histogram - - 3.1005638E-01 - - 3.0999067E-01 - - 3.0994879E-01 - - 3.0987779E-01 - - 3.0961631E-01 - - 3.0948272E-01 - - 3.0913340E-01 - - 3.0868239E-01 - - 3.0799925E-01 - - 3.0712597E-01 - - 3.0590948E-01 - - 3.0432728E-01 - - 3.0235012E-01 - - 2.9996873E-01 - - 2.9743091E-01 - - 2.9739624E-01 - - 3.0835788E-01 - - 3.1305337E-01 - - 3.1379599E-01 - - 3.1314506E-01 - - 3.1216249E-01 - - 3.1129786E-01 - - 3.1059203E-01 - - 3.1009561E-01 - - 3.0977837E-01 - - 3.0951041E-01 - - 3.0930940E-01 - - 3.0929712E-01 - - 3.0925741E-01 - - 3.0917641E-01 - - 3.0919741E-01 - - 3.0912502E-01 - - - 1.3490691E-03 - - 1.3463259E-03 - - 1.3498512E-03 - - 1.3366347E-03 - - 1.3288899E-03 - - 1.3176269E-03 - - 1.3059971E-03 - - 1.2891508E-03 - - 1.2713136E-03 - - 1.2555332E-03 - - 1.2394055E-03 - - 1.2170158E-03 - - 1.1969201E-03 - - 1.1849620E-03 - - 1.1899173E-03 - - 1.2761137E-03 - - 1.6244505E-03 - - 1.9090551E-03 - - 2.0837409E-03 - - 2.1976011E-03 - - 2.2746911E-03 - - 2.3308251E-03 - - 2.3700744E-03 - - 2.3981231E-03 - - 2.4248079E-03 - - 2.4441792E-03 - - 2.4510541E-03 - - 2.4640212E-03 - - 2.4741885E-03 - - 2.4697219E-03 - - 2.4721421E-03 - - 2.4729172E-03 - - - 8.6638893E-03 - - 8.2719674E-03 - - 7.8055649E-03 - - 7.4105610E-03 - - 7.2544086E-03 - - 7.0854147E-03 - - 6.9965517E-03 - - 7.0314805E-03 - - 6.8552954E-03 - - 6.9138525E-03 - - 6.9528906E-03 - - 7.0689776E-03 - - 7.0720596E-03 - - 7.2523539E-03 - - 7.5405167E-03 - - 7.7624175E-03 - - 7.9838046E-03 - - 8.1702629E-03 - - 8.4784584E-03 - - 8.8970906E-03 - - 9.3105862E-03 - - 9.7826390E-03 - - 1.0253151E-02 - - 1.0659455E-02 - - 1.1134076E-02 - - 1.1649276E-02 - - 1.2603655E-02 - - 1.3342297E-02 - - 1.4372697E-02 - - 1.5779610E-02 - - 1.7933383E-02 - - 2.0318816E-02 - - - - 8.6137649E-03 - - 8.0815773E-03 - - 7.7778880E-03 - - 7.4879636E-03 - - 7.2446680E-03 - - 7.0652074E-03 - - 6.9244607E-03 - - 6.9131046E-03 - - 6.9017486E-03 - - 6.9408066E-03 - - 6.9814132E-03 - - 7.0440438E-03 - - 7.1589812E-03 - - 7.3353447E-03 - - 7.5896522E-03 - - 7.7529390E-03 - - 8.0199791E-03 - - 8.3484454E-03 - - 8.5960425E-03 - - 8.9554799E-03 - - 9.2763754E-03 - - 9.7440398E-03 - - 1.0084034E-02 - - 1.0634976E-02 - - 1.1176800E-02 - - 1.1768004E-02 - - 1.2488944E-02 - - 1.3414293E-02 - - 1.4307639E-02 - - 1.5845012E-02 - - 1.7838866E-02 - - 2.0339442E-02 - - - - 8.6069286E-03 - - 8.1600584E-03 - - 7.7753343E-03 - - 7.5082514E-03 - - 7.2541589E-03 - - 7.1052368E-03 - - 7.0049508E-03 - - 6.9087178E-03 - - 6.8877253E-03 - - 6.9276318E-03 - - 6.9580813E-03 - - 7.0116019E-03 - - 7.1577180E-03 - - 7.3369857E-03 - - 7.5182280E-03 - - 7.7277374E-03 - - 7.9440018E-03 - - 8.2744779E-03 - - 8.6378977E-03 - - 8.8881451E-03 - - 9.2653867E-03 - - 9.6492794E-03 - - 1.0205685E-02 - - 1.0657959E-02 - - 1.1210208E-02 - - 1.1713716E-02 - - 1.2497402E-02 - - 1.3347079E-02 - - 1.4469243E-02 - - 1.5835834E-02 - - 1.7754882E-02 - - 2.0415319E-02 - - - - 8.6357058E-03 - - 8.1456937E-03 - - 7.7155413E-03 - - 7.4818571E-03 - - 7.2524325E-03 - - 7.0736756E-03 - - 7.0115740E-03 - - 6.8735456E-03 - - 6.8726489E-03 - - 6.9218219E-03 - - 6.9136015E-03 - - 7.0770385E-03 - - 7.1125358E-03 - - 7.2947303E-03 - - 7.5540473E-03 - - 7.7247333E-03 - - 7.9593143E-03 - - 8.2175104E-03 - - 8.5783123E-03 - - 8.9662416E-03 - - 9.2850446E-03 - - 9.7500218E-03 - - 1.0192206E-02 - - 1.0589252E-02 - - 1.1196518E-02 - - 1.1754610E-02 - - 1.2477858E-02 - - 1.3364244E-02 - - 1.4489097E-02 - - 1.5799582E-02 - - 1.7806262E-02 - - 2.0415575E-02 - - - - 8.6187094E-03 - - 8.1028888E-03 - - 7.7502930E-03 - - 7.4368288E-03 - - 7.2053294E-03 - - 7.0754195E-03 - - 6.9609624E-03 - - 6.9199506E-03 - - 6.8721819E-03 - - 6.9170716E-03 - - 6.9278240E-03 - - 7.0082024E-03 - - 7.1469258E-03 - - 7.2928174E-03 - - 7.4578635E-03 - - 7.7005853E-03 - - 7.9397817E-03 - - 8.2897923E-03 - - 8.5642424E-03 - - 8.9336425E-03 - - 9.2822429E-03 - - 9.6866617E-03 - - 1.0169638E-02 - - 1.0601319E-02 - - 1.1134062E-02 - - 1.1797713E-02 - - 1.2521413E-02 - - 1.3398584E-02 - - 1.4465948E-02 - - 1.5920693E-02 - - 1.7831503E-02 - - 2.0386280E-02 - - - - 8.5957828E-03 - - 8.0917421E-03 - - 7.7483058E-03 - - 7.4335661E-03 - - 7.2051598E-03 - - 7.0542832E-03 - - 6.9482999E-03 - - 6.8660522E-03 - - 6.8566650E-03 - - 6.8895446E-03 - - 6.9769966E-03 - - 7.0151292E-03 - - 7.1289919E-03 - - 7.2728159E-03 - - 7.4843447E-03 - - 7.6904746E-03 - - 7.9728210E-03 - - 8.2376090E-03 - - 8.5714149E-03 - - 8.9027889E-03 - - 9.2973443E-03 - - 9.6952072E-03 - - 1.0177798E-02 - - 1.0619290E-02 - - 1.1136220E-02 - - 1.1749356E-02 - - 1.2532485E-02 - - 1.3371645E-02 - - 1.4476030E-02 - - 1.5936887E-02 - - 1.7814576E-02 - - 2.0401706E-02 - - - - 8.5762717E-03 - - 8.0787798E-03 - - 7.6957274E-03 - - 7.4218081E-03 - - 7.1969403E-03 - - 7.0456914E-03 - - 6.9243998E-03 - - 6.8670339E-03 - - 6.8410876E-03 - - 6.8440959E-03 - - 6.9114894E-03 - - 6.9709444E-03 - - 7.1246584E-03 - - 7.2467020E-03 - - 7.4540634E-03 - - 7.6790984E-03 - - 7.9072251E-03 - - 8.2202101E-03 - - 8.5598098E-03 - - 8.9093117E-03 - - 9.2775317E-03 - - 9.6625479E-03 - - 1.0156279E-02 - - 1.0632045E-02 - - 1.1116292E-02 - - 1.1767916E-02 - - 1.2489983E-02 - - 1.3349302E-02 - - 1.4524155E-02 - - 1.5953415E-02 - - 1.7870641E-02 - - 2.0504336E-02 - - - - 8.5580155E-03 - - 8.0552826E-03 - - 7.6847006E-03 - - 7.3901486E-03 - - 7.1714794E-03 - - 6.9956094E-03 - - 6.8966894E-03 - - 6.8584904E-03 - - 6.8074847E-03 - - 6.8182305E-03 - - 6.8700458E-03 - - 6.9598760E-03 - - 7.0775275E-03 - - 7.2721659E-03 - - 7.4256244E-03 - - 7.6626570E-03 - - 7.8956048E-03 - - 8.2476025E-03 - - 8.5876768E-03 - - 8.8916497E-03 - - 9.2599869E-03 - - 9.6607086E-03 - - 1.0104818E-02 - - 1.0621057E-02 - - 1.1139577E-02 - - 1.1789513E-02 - - 1.2505652E-02 - - 1.3335138E-02 - - 1.4480446E-02 - - 1.5926378E-02 - - 1.7926012E-02 - - 2.0526011E-02 - - - - 8.5161659E-03 - - 8.0446298E-03 - - 7.6545410E-03 - - 7.3722009E-03 - - 7.1148071E-03 - - 6.9727284E-03 - - 6.8574133E-03 - - 6.7687628E-03 - - 6.7671107E-03 - - 6.8028617E-03 - - 6.8012426E-03 - - 6.9205557E-03 - - 7.0398688E-03 - - 7.2416867E-03 - - 7.3960899E-03 - - 7.6495518E-03 - - 7.9006016E-03 - - 8.1906074E-03 - - 8.4993478E-03 - - 8.8863636E-03 - - 9.2483009E-03 - - 9.6547452E-03 - - 1.0109959E-02 - - 1.0588004E-02 - - 1.1123575E-02 - - 1.1768480E-02 - - 1.2510924E-02 - - 1.3377043E-02 - - 1.4514862E-02 - - 1.5985046E-02 - - 1.7920853E-02 - - 2.0545741E-02 - - - - 8.4881904E-03 - - 8.0008968E-03 - - 7.5800933E-03 - - 7.3219921E-03 - - 7.0930406E-03 - - 6.9243759E-03 - - 6.8395166E-03 - - 6.7595356E-03 - - 6.7209304E-03 - - 6.7524289E-03 - - 6.7924495E-03 - - 6.8886916E-03 - - 7.0061035E-03 - - 7.1949742E-03 - - 7.3557793E-03 - - 7.6015942E-03 - - 7.8273839E-03 - - 8.1635087E-03 - - 8.4872268E-03 - - 8.8563257E-03 - - 9.1982925E-03 - - 9.6315629E-03 - - 1.0058991E-02 - - 1.0542942E-02 - - 1.1120245E-02 - - 1.1716127E-02 - - 1.2496242E-02 - - 1.3357995E-02 - - 1.4520670E-02 - - 1.5968277E-02 - - 1.7999571E-02 - - 2.0619911E-02 - - - - 8.4547550E-03 - - 7.9415583E-03 - - 7.5504996E-03 - - 7.2492760E-03 - - 7.0388623E-03 - - 6.9114334E-03 - - 6.7880701E-03 - - 6.7298137E-03 - - 6.6707776E-03 - - 6.6865113E-03 - - 6.7469676E-03 - - 6.8440431E-03 - - 6.9530093E-03 - - 7.1334872E-03 - - 7.3320937E-03 - - 7.5447909E-03 - - 7.7926035E-03 - - 8.1024597E-03 - - 8.4776176E-03 - - 8.7989469E-03 - - 9.1860513E-03 - - 9.6106103E-03 - - 1.0035921E-02 - - 1.0516926E-02 - - 1.1111883E-02 - - 1.1693054E-02 - - 1.2421315E-02 - - 1.3359879E-02 - - 1.4448956E-02 - - 1.5939312E-02 - - 1.7946680E-02 - - 2.0638422E-02 - - - - 8.4199682E-03 - - 7.9132357E-03 - - 7.5289024E-03 - - 7.2000914E-03 - - 6.9952420E-03 - - 6.8508371E-03 - - 6.7532303E-03 - - 6.6833325E-03 - - 6.6177839E-03 - - 6.6622382E-03 - - 6.7105208E-03 - - 6.7909136E-03 - - 6.9136513E-03 - - 7.0763901E-03 - - 7.2891302E-03 - - 7.5133811E-03 - - 7.7798727E-03 - - 8.0728234E-03 - - 8.3719982E-03 - - 8.7418259E-03 - - 9.0827206E-03 - - 9.5593221E-03 - - 9.9725625E-03 - - 1.0449294E-02 - - 1.0985324E-02 - - 1.1627712E-02 - - 1.2345830E-02 - - 1.3279892E-02 - - 1.4416720E-02 - - 1.5897541E-02 - - 1.7949472E-02 - - 2.0670535E-02 - - - - 8.3808798E-03 - - 7.8549469E-03 - - 7.4548947E-03 - - 7.1338816E-03 - - 6.9441484E-03 - - 6.7971643E-03 - - 6.6772004E-03 - - 6.6034372E-03 - - 6.5689962E-03 - - 6.6291014E-03 - - 6.6629260E-03 - - 6.7229080E-03 - - 6.8650107E-03 - - 7.0400011E-03 - - 7.2281319E-03 - - 7.4627838E-03 - - 7.7395439E-03 - - 8.0343750E-03 - - 8.3395359E-03 - - 8.6563579E-03 - - 9.0736921E-03 - - 9.4975103E-03 - - 9.9294641E-03 - - 1.0370071E-02 - - 1.0916688E-02 - - 1.1554450E-02 - - 1.2270239E-02 - - 1.3181629E-02 - - 1.4291357E-02 - - 1.5819158E-02 - - 1.7859062E-02 - - 2.0611377E-02 - - - - 8.3161285E-03 - - 7.8077760E-03 - - 7.3959293E-03 - - 7.1090603E-03 - - 6.8980291E-03 - - 6.7587447E-03 - - 6.6504860E-03 - - 6.5749792E-03 - - 6.5613818E-03 - - 6.5416597E-03 - - 6.6015118E-03 - - 6.7070747E-03 - - 6.8290963E-03 - - 7.0031900E-03 - - 7.1846853E-03 - - 7.4125063E-03 - - 7.6750420E-03 - - 7.9813021E-03 - - 8.2806571E-03 - - 8.6141119E-03 - - 8.9704813E-03 - - 9.3882871E-03 - - 9.8368112E-03 - - 1.0298412E-02 - - 1.0822136E-02 - - 1.1413491E-02 - - 1.2145337E-02 - - 1.3048321E-02 - - 1.4114237E-02 - - 1.5706737E-02 - - 1.7654188E-02 - - 2.0500295E-02 - - - - 8.3192873E-03 - - 7.7697531E-03 - - 7.3819594E-03 - - 7.0971817E-03 - - 6.8836908E-03 - - 6.7313952E-03 - - 6.6234836E-03 - - 6.5684539E-03 - - 6.5572540E-03 - - 6.5781759E-03 - - 6.6163018E-03 - - 6.6999200E-03 - - 6.8297696E-03 - - 6.9564324E-03 - - 7.1572917E-03 - - 7.4359960E-03 - - 7.6444528E-03 - - 7.9171531E-03 - - 8.2232683E-03 - - 8.5632604E-03 - - 8.9017284E-03 - - 9.3233527E-03 - - 9.7185361E-03 - - 1.0167756E-02 - - 1.0690318E-02 - - 1.1287654E-02 - - 1.1955699E-02 - - 1.2797701E-02 - - 1.3915636E-02 - - 1.5417831E-02 - - 1.7413631E-02 - - 2.0132344E-02 - - - - 8.3402366E-03 - - 7.8783074E-03 - - 7.5306252E-03 - - 7.2763123E-03 - - 7.0815582E-03 - - 6.9389151E-03 - - 6.8574149E-03 - - 6.7982581E-03 - - 6.7740232E-03 - - 6.7825822E-03 - - 6.8155653E-03 - - 6.8794036E-03 - - 7.0109342E-03 - - 7.1732489E-03 - - 7.3504593E-03 - - 7.5193707E-03 - - 7.7780813E-03 - - 8.0399365E-03 - - 8.3133536E-03 - - 8.6051891E-03 - - 8.9148994E-03 - - 9.3197524E-03 - - 9.7034206E-03 - - 1.0115863E-02 - - 1.0600845E-02 - - 1.1142903E-02 - - 1.1780624E-02 - - 1.2556047E-02 - - 1.3579729E-02 - - 1.4891180E-02 - - 1.6672103E-02 - - 1.9078712E-02 - - - - 8.8088395E-03 - - 8.4507679E-03 - - 8.1708811E-03 - - 7.9801672E-03 - - 7.8027326E-03 - - 7.7405325E-03 - - 7.6178992E-03 - - 7.5796349E-03 - - 7.5729815E-03 - - 7.5709385E-03 - - 7.6313441E-03 - - 7.6551420E-03 - - 7.7197992E-03 - - 7.8770525E-03 - - 7.9879526E-03 - - 8.1371998E-03 - - 8.3342910E-03 - - 8.5247565E-03 - - 8.7962504E-03 - - 9.0806648E-03 - - 9.3313150E-03 - - 9.6858805E-03 - - 1.0017311E-02 - - 1.0396502E-02 - - 1.0810783E-02 - - 1.1308495E-02 - - 1.1873348E-02 - - 1.2517849E-02 - - 1.3292300E-02 - - 1.4204872E-02 - - 1.5413040E-02 - - 1.6865149E-02 - - - - 9.0402122E-03 - - 8.7656934E-03 - - 8.5418137E-03 - - 8.3375574E-03 - - 8.2205328E-03 - - 8.0954859E-03 - - 8.0140696E-03 - - 7.9720195E-03 - - 7.9707073E-03 - - 7.9496524E-03 - - 7.9729738E-03 - - 8.0286530E-03 - - 8.0949490E-03 - - 8.2040408E-03 - - 8.3348436E-03 - - 8.4638271E-03 - - 8.5967473E-03 - - 8.8120082E-03 - - 9.0406595E-03 - - 9.2571730E-03 - - 9.4741636E-03 - - 9.7864082E-03 - - 1.0105154E-02 - - 1.0426882E-02 - - 1.0815324E-02 - - 1.1263114E-02 - - 1.1718090E-02 - - 1.2294266E-02 - - 1.2954841E-02 - - 1.3732023E-02 - - 1.4787929E-02 - - 1.6057604E-02 - - - - 9.1615425E-03 - - 8.8847745E-03 - - 8.6630839E-03 - - 8.4765570E-03 - - 8.3309009E-03 - - 8.2383585E-03 - - 8.1836800E-03 - - 8.1120640E-03 - - 8.1261785E-03 - - 8.0708249E-03 - - 8.1480561E-03 - - 8.1784637E-03 - - 8.2346151E-03 - - 8.3274337E-03 - - 8.4147598E-03 - - 8.5448285E-03 - - 8.7091710E-03 - - 8.8843142E-03 - - 9.0949279E-03 - - 9.2936363E-03 - - 9.5389840E-03 - - 9.7958383E-03 - - 1.0086138E-02 - - 1.0400309E-02 - - 1.0727798E-02 - - 1.1115580E-02 - - 1.1556966E-02 - - 1.2062390E-02 - - 1.2723933E-02 - - 1.3461879E-02 - - 1.4407800E-02 - - 1.5727050E-02 - - - - 9.1377654E-03 - - 8.8751018E-03 - - 8.6821226E-03 - - 8.4858221E-03 - - 8.3554460E-03 - - 8.2804350E-03 - - 8.2266991E-03 - - 8.1758459E-03 - - 8.1472390E-03 - - 8.1455783E-03 - - 8.1349878E-03 - - 8.1925776E-03 - - 8.2538648E-03 - - 8.3264317E-03 - - 8.4644531E-03 - - 8.6009391E-03 - - 8.7147401E-03 - - 8.9206598E-03 - - 9.1064325E-03 - - 9.2780740E-03 - - 9.4991589E-03 - - 9.7677443E-03 - - 1.0040842E-02 - - 1.0310399E-02 - - 1.0637483E-02 - - 1.1002699E-02 - - 1.1454957E-02 - - 1.1928711E-02 - - 1.2543618E-02 - - 1.3315003E-02 - - 1.4311921E-02 - - 1.5626273E-02 - - - - 9.1477964E-03 - - 8.8569131E-03 - - 8.6480911E-03 - - 8.4806682E-03 - - 8.3743826E-03 - - 8.2509863E-03 - - 8.2112855E-03 - - 8.1583830E-03 - - 8.1332616E-03 - - 8.1132990E-03 - - 8.1560439E-03 - - 8.1779291E-03 - - 8.2488074E-03 - - 8.3305803E-03 - - 8.4259072E-03 - - 8.5822114E-03 - - 8.7017305E-03 - - 8.8788944E-03 - - 9.0655429E-03 - - 9.2582475E-03 - - 9.4805275E-03 - - 9.7278007E-03 - - 9.9553998E-03 - - 1.0269546E-02 - - 1.0586672E-02 - - 1.0921006E-02 - - 1.1328973E-02 - - 1.1802691E-02 - - 1.2450626E-02 - - 1.3255698E-02 - - 1.4251456E-02 - - 1.5657809E-02 - - - - 9.0883340E-03 - - 8.8433984E-03 - - 8.6289182E-03 - - 8.4439323E-03 - - 8.3093188E-03 - - 8.2332632E-03 - - 8.1799745E-03 - - 8.1280446E-03 - - 8.0845653E-03 - - 8.1128997E-03 - - 8.1014997E-03 - - 8.1603558E-03 - - 8.2532133E-03 - - 8.3021938E-03 - - 8.4337253E-03 - - 8.5567067E-03 - - 8.6772027E-03 - - 8.8890649E-03 - - 9.0381936E-03 - - 9.2474046E-03 - - 9.4507499E-03 - - 9.7047326E-03 - - 9.9402566E-03 - - 1.0205441E-02 - - 1.0504990E-02 - - 1.0882385E-02 - - 1.1274627E-02 - - 1.1783289E-02 - - 1.2386232E-02 - - 1.3164784E-02 - - 1.4270026E-02 - - 1.5728107E-02 - - - - 9.0807708E-03 - - 8.8015024E-03 - - 8.5814276E-03 - - 8.4248165E-03 - - 8.2946254E-03 - - 8.2126919E-03 - - 8.1370075E-03 - - 8.0715301E-03 - - 8.0815288E-03 - - 8.0835771E-03 - - 8.1054492E-03 - - 8.1477700E-03 - - 8.2076231E-03 - - 8.2545960E-03 - - 8.4024583E-03 - - 8.5599026E-03 - - 8.6575633E-03 - - 8.8233051E-03 - - 9.0064404E-03 - - 9.2354725E-03 - - 9.4557209E-03 - - 9.6788857E-03 - - 9.8947250E-03 - - 1.0174410E-02 - - 1.0498117E-02 - - 1.0823664E-02 - - 1.1218924E-02 - - 1.1737640E-02 - - 1.2318916E-02 - - 1.3224386E-02 - - 1.4293237E-02 - - 1.5742419E-02 - - - - 9.0662532E-03 - - 8.7875937E-03 - - 8.5608939E-03 - - 8.3990606E-03 - - 8.2689578E-03 - - 8.1502455E-03 - - 8.0945876E-03 - - 8.0499873E-03 - - 8.0046473E-03 - - 8.0312744E-03 - - 8.0845285E-03 - - 8.0864516E-03 - - 8.1794243E-03 - - 8.2886692E-03 - - 8.3753921E-03 - - 8.5095259E-03 - - 8.6235784E-03 - - 8.8149234E-03 - - 9.0064533E-03 - - 9.1933604E-03 - - 9.4366281E-03 - - 9.6340012E-03 - - 9.8577424E-03 - - 1.0162178E-02 - - 1.0489950E-02 - - 1.0830480E-02 - - 1.1216758E-02 - - 1.1718234E-02 - - 1.2372964E-02 - - 1.3217004E-02 - - 1.4300060E-02 - - 1.5874384E-02 - - - - 9.0385593E-03 - - 8.7911739E-03 - - 8.5398942E-03 - - 8.3506015E-03 - - 8.2438909E-03 - - 8.1613890E-03 - - 8.0460870E-03 - - 8.0305903E-03 - - 8.0028889E-03 - - 8.0232434E-03 - - 8.0276194E-03 - - 8.1064278E-03 - - 8.1288298E-03 - - 8.2312446E-03 - - 8.3452218E-03 - - 8.4759402E-03 - - 8.6203085E-03 - - 8.7737100E-03 - - 8.9852040E-03 - - 9.1640184E-03 - - 9.3706145E-03 - - 9.6371098E-03 - - 9.8385671E-03 - - 1.0187163E-02 - - 1.0453859E-02 - - 1.0791575E-02 - - 1.1239213E-02 - - 1.1704998E-02 - - 1.2413952E-02 - - 1.3197580E-02 - - 1.4388298E-02 - - 1.5983777E-02 - - - - 9.0381972E-03 - - 8.7249421E-03 - - 8.5299403E-03 - - 8.3296610E-03 - - 8.1906552E-03 - - 8.0856852E-03 - - 8.0084895E-03 - - 7.9976213E-03 - - 7.9681027E-03 - - 7.9954298E-03 - - 8.0300023E-03 - - 8.0899341E-03 - - 8.1518784E-03 - - 8.2341280E-03 - - 8.3101161E-03 - - 8.4644180E-03 - - 8.6281121E-03 - - 8.7991411E-03 - - 8.9588100E-03 - - 9.1981791E-03 - - 9.3869641E-03 - - 9.6145258E-03 - - 9.9132005E-03 - - 1.0156461E-02 - - 1.0475933E-02 - - 1.0810611E-02 - - 1.1229999E-02 - - 1.1691965E-02 - - 1.2394061E-02 - - 1.3229214E-02 - - 1.4413895E-02 - - 1.6023151E-02 - - - - 8.9900779E-03 - - 8.7242101E-03 - - 8.4738461E-03 - - 8.3135886E-03 - - 8.1704723E-03 - - 8.0916227E-03 - - 8.0054050E-03 - - 7.9890825E-03 - - 7.9822260E-03 - - 7.9494275E-03 - - 8.0343148E-03 - - 8.0498187E-03 - - 8.1090198E-03 - - 8.2328458E-03 - - 8.3082672E-03 - - 8.4585469E-03 - - 8.6087756E-03 - - 8.8041342E-03 - - 8.9504229E-03 - - 9.1682953E-03 - - 9.3389911E-03 - - 9.6352014E-03 - - 9.8666333E-03 - - 1.0149489E-02 - - 1.0464017E-02 - - 1.0804437E-02 - - 1.1200629E-02 - - 1.1730829E-02 - - 1.2396625E-02 - - 1.3311556E-02 - - 1.4467897E-02 - - 1.6069551E-02 - - - - 9.0103050E-03 - - 8.7325667E-03 - - 8.5095225E-03 - - 8.3198922E-03 - - 8.1828827E-03 - - 8.0755069E-03 - - 7.9981914E-03 - - 7.9413633E-03 - - 7.9823990E-03 - - 7.9246563E-03 - - 7.9815454E-03 - - 8.0345931E-03 - - 8.0725191E-03 - - 8.2341012E-03 - - 8.3041608E-03 - - 8.3831836E-03 - - 8.6106789E-03 - - 8.7518346E-03 - - 8.9641474E-03 - - 9.0978032E-03 - - 9.3592003E-03 - - 9.5996223E-03 - - 9.9237621E-03 - - 1.0175830E-02 - - 1.0455459E-02 - - 1.0836548E-02 - - 1.1244650E-02 - - 1.1760188E-02 - - 1.2384627E-02 - - 1.3346254E-02 - - 1.4480133E-02 - - 1.6136563E-02 - - - - 9.0228604E-03 - - 8.6804828E-03 - - 8.4614534E-03 - - 8.2426545E-03 - - 8.1392111E-03 - - 8.0814949E-03 - - 7.9912702E-03 - - 7.9974952E-03 - - 7.9421615E-03 - - 7.9138029E-03 - - 7.9451587E-03 - - 8.0340001E-03 - - 8.0954821E-03 - - 8.1764077E-03 - - 8.3095930E-03 - - 8.4157262E-03 - - 8.6168490E-03 - - 8.7576427E-03 - - 8.9333274E-03 - - 9.1895534E-03 - - 9.3857577E-03 - - 9.6418300E-03 - - 9.8564788E-03 - - 1.0150132E-02 - - 1.0487898E-02 - - 1.0870470E-02 - - 1.1271947E-02 - - 1.1778020E-02 - - 1.2502739E-02 - - 1.3339816E-02 - - 1.4543555E-02 - - 1.6130789E-02 - - - - 9.0622003E-03 - - 8.7178702E-03 - - 8.4596226E-03 - - 8.2747360E-03 - - 8.1644825E-03 - - 8.0165944E-03 - - 7.9932716E-03 - - 7.9360246E-03 - - 7.9425974E-03 - - 7.9418553E-03 - - 7.9541528E-03 - - 8.0182907E-03 - - 8.0812624E-03 - - 8.0915456E-03 - - 8.2908500E-03 - - 8.4101146E-03 - - 8.5246086E-03 - - 8.7454336E-03 - - 8.9623361E-03 - - 9.1273983E-03 - - 9.3738784E-03 - - 9.6552369E-03 - - 9.8941901E-03 - - 1.0161555E-02 - - 1.0501008E-02 - - 1.0866011E-02 - - 1.1314128E-02 - - 1.1790338E-02 - - 1.2447300E-02 - - 1.3396964E-02 - - 1.4531939E-02 - - 1.6115773E-02 - - - - 8.9679455E-03 - - 8.7523346E-03 - - 8.4194831E-03 - - 8.2562897E-03 - - 8.2501744E-03 - - 8.0453964E-03 - - 7.9636250E-03 - - 7.9278064E-03 - - 7.9395130E-03 - - 7.8808053E-03 - - 7.8942591E-03 - - 7.9779525E-03 - - 8.1203535E-03 - - 8.1780129E-03 - - 8.2976996E-03 - - 8.3927501E-03 - - 8.5693973E-03 - - 8.7760972E-03 - - 8.9639268E-03 - - 9.1777904E-03 - - 9.3233365E-03 - - 9.6757573E-03 - - 9.8043550E-03 - - 1.0142972E-02 - - 1.0460099E-02 - - 1.0900581E-02 - - 1.1166513E-02 - - 1.1798843E-02 - - 1.2569032E-02 - - 1.3335377E-02 - - 1.4567713E-02 - - 1.6266042E-02 - - - - 9.0235493E-03 - - 8.7359753E-03 - - 8.4400355E-03 - - 8.2314136E-03 - - 8.1409585E-03 - - 8.0562549E-03 - - 8.0165174E-03 - - 7.9631855E-03 - - 7.9527283E-03 - - 7.9590026E-03 - - 7.9558654E-03 - - 7.9982172E-03 - - 7.9903743E-03 - - 8.1472328E-03 - - 8.3527175E-03 - - 8.3019999E-03 - - 8.5775481E-03 - - 8.8353190E-03 - - 8.9853803E-03 - - 9.0836784E-03 - - 9.4481131E-03 - - 9.5401367E-03 - - 9.8920227E-03 - - 1.0186917E-02 - - 1.0500634E-02 - - 1.0833697E-02 - - 1.1379042E-02 - - 1.1793671E-02 - - 1.2553389E-02 - - 1.3369577E-02 - - 1.4595165E-02 - - 1.6031466E-02 - - - 1.0000416E+00 - - - 1.0000513E+00 - - - 1.0000397E+00 - - - 1.0000409E+00 - - - 1.0000455E+00 - - - 1.0000417E+00 - - - 1.0000452E+00 - - - 1.0000431E+00 - - - 1.0000455E+00 - - - 1.0000451E+00 - - - 1.0000445E+00 - - - 1.0000482E+00 - - - 1.0000507E+00 - - - 1.0000542E+00 - - - 1.0000545E+00 - - - 1.0000461E+00 - - - 1.0000114E+00 - - - 1.0000112E+00 - - - 1.0000195E+00 - - - 1.0000216E+00 - - - 1.0000279E+00 - - - 1.0000307E+00 - - - 1.0000302E+00 - - - 1.0000313E+00 - - - 1.0000334E+00 - - - 1.0000309E+00 - - - 1.0000325E+00 - - - 1.0000318E+00 - - - 1.0000346E+00 - - - 1.0000335E+00 - - - 1.0000285E+00 - - - 1.0000358E+00 - - - - - lwtr_ang_mu - lwtr_ang_mu - 2.5300000E-08 - 32 - false - 32 - 1 - angle - histogram - - 8.3129229E-01 - - 8.3203829E-01 - - 8.3332424E-01 - - 8.3539719E-01 - - 8.3799288E-01 - - 8.4156597E-01 - - 8.4594074E-01 - - 8.5122773E-01 - - 8.5788274E-01 - - 8.6633387E-01 - - 8.7719846E-01 - - 8.9195077E-01 - - 9.1326621E-01 - - 9.4469159E-01 - - 9.9368716E-01 - - 1.0616854E+00 - - 1.0982938E+00 - - 1.0997200E+00 - - 1.0855410E+00 - - 1.0676695E+00 - - 1.0508172E+00 - - 1.0369337E+00 - - 1.0255762E+00 - - 1.0162841E+00 - - 1.0086633E+00 - - 1.0025783E+00 - - 9.9737297E-01 - - 9.9326768E-01 - - 9.9030852E-01 - - 9.8792719E-01 - - 9.8610453E-01 - - 9.8540665E-01 - - - 7.7368065E-03 - - 7.7519393E-03 - - 7.7819449E-03 - - 7.8285240E-03 - - 7.8881877E-03 - - 7.9652685E-03 - - 8.0588251E-03 - - 8.1724303E-03 - - 8.3079937E-03 - - 8.4749946E-03 - - 8.6811506E-03 - - 8.9456784E-03 - - 9.3049336E-03 - - 9.8025199E-03 - - 1.0529992E-02 - - 1.1498571E-02 - - 1.2065971E-02 - - 1.2168395E-02 - - 1.2053690E-02 - - 1.1870414E-02 - - 1.1678759E-02 - - 1.1516371E-02 - - 1.1377145E-02 - - 1.1262809E-02 - - 1.1166687E-02 - - 1.1090107E-02 - - 1.1022668E-02 - - 1.0968772E-02 - - 1.0931381E-02 - - 1.0898236E-02 - - 1.0872094E-02 - - 1.0866295E-02 - - - 5.0690953E-03 - - 8.8284325E-03 - - 9.0078067E-03 - - 8.3473577E-03 - - 8.6118779E-03 - - 8.5008333E-03 - - 9.0278160E-03 - - 9.0320024E-03 - - 9.3778370E-03 - - 9.6052477E-03 - - 9.9703821E-03 - - 1.0342612E-02 - - 1.0646441E-02 - - 1.1197549E-02 - - 1.1382812E-02 - - 1.2469275E-02 - - 1.3368771E-02 - - 1.7162734E-02 - - 2.0335842E-02 - - 2.4108518E-02 - - 2.7585384E-02 - - 3.1409361E-02 - - 3.5211839E-02 - - 3.9132244E-02 - - 4.2882641E-02 - - 4.7206070E-02 - - 5.1012876E-02 - - 5.6053305E-02 - - 5.9624825E-02 - - 6.4222850E-02 - - 7.1113785E-02 - - 7.1863425E-02 - - - - 5.0668773E-03 - - 8.8623444E-03 - - 8.9736897E-03 - - 8.4193826E-03 - - 8.6200366E-03 - - 8.5331711E-03 - - 9.0253536E-03 - - 9.0024868E-03 - - 9.3587966E-03 - - 9.6337679E-03 - - 9.9001048E-03 - - 1.0351369E-02 - - 1.0700823E-02 - - 1.1172796E-02 - - 1.1445656E-02 - - 1.2427412E-02 - - 1.3375674E-02 - - 1.7104580E-02 - - 2.0306601E-02 - - 2.4056263E-02 - - 2.7577305E-02 - - 3.1469932E-02 - - 3.5286392E-02 - - 3.9182103E-02 - - 4.2943152E-02 - - 4.7360483E-02 - - 5.1005109E-02 - - 5.6171187E-02 - - 5.9667108E-02 - - 6.4232789E-02 - - 7.1121280E-02 - - 7.1846306E-02 - - - - 5.0585819E-03 - - 8.8480548E-03 - - 9.0578095E-03 - - 8.4267843E-03 - - 8.6269032E-03 - - 8.5421136E-03 - - 9.0526837E-03 - - 9.0736449E-03 - - 9.4245294E-03 - - 9.6888060E-03 - - 9.9567766E-03 - - 1.0375670E-02 - - 1.0725481E-02 - - 1.1243110E-02 - - 1.1484936E-02 - - 1.2521826E-02 - - 1.3438046E-02 - - 1.7151864E-02 - - 2.0343472E-02 - - 2.4110251E-02 - - 2.7659343E-02 - - 3.1511614E-02 - - 3.5309076E-02 - - 3.9196826E-02 - - 4.3043312E-02 - - 4.7345488E-02 - - 5.1124137E-02 - - 5.6080519E-02 - - 5.9764341E-02 - - 6.4292466E-02 - - 7.1165161E-02 - - 7.1900319E-02 - - - - 5.0739533E-03 - - 8.8878014E-03 - - 9.0739746E-03 - - 8.4571184E-03 - - 8.6763187E-03 - - 8.5845734E-03 - - 9.0893274E-03 - - 9.1072493E-03 - - 9.4607350E-03 - - 9.7370233E-03 - - 1.0006337E-02 - - 1.0437546E-02 - - 1.0767301E-02 - - 1.1309766E-02 - - 1.1552543E-02 - - 1.2572863E-02 - - 1.3499221E-02 - - 1.7217227E-02 - - 2.0383163E-02 - - 2.4178222E-02 - - 2.7731888E-02 - - 3.1561770E-02 - - 3.5431417E-02 - - 3.9298803E-02 - - 4.3075219E-02 - - 4.7440921E-02 - - 5.1196928E-02 - - 5.6281715E-02 - - 5.9863517E-02 - - 6.4363763E-02 - - 7.1290039E-02 - - 7.1984722E-02 - - - - 5.0933569E-03 - - 8.9571748E-03 - - 9.1350789E-03 - - 8.5026806E-03 - - 8.7154122E-03 - - 8.6182850E-03 - - 9.1387403E-03 - - 9.1503576E-03 - - 9.5054271E-03 - - 9.8046510E-03 - - 1.0063015E-02 - - 1.0512898E-02 - - 1.0850976E-02 - - 1.1369711E-02 - - 1.1602210E-02 - - 1.2644534E-02 - - 1.3573331E-02 - - 1.7276147E-02 - - 2.0485160E-02 - - 2.4267827E-02 - - 2.7795345E-02 - - 3.1650606E-02 - - 3.5516413E-02 - - 3.9384282E-02 - - 4.3193261E-02 - - 4.7565933E-02 - - 5.1283045E-02 - - 5.6364736E-02 - - 5.9999740E-02 - - 6.4499325E-02 - - 7.1460960E-02 - - 7.2121578E-02 - - - - 5.1073627E-03 - - 9.0205393E-03 - - 9.1796662E-03 - - 8.5645656E-03 - - 8.7990379E-03 - - 8.7021912E-03 - - 9.2162069E-03 - - 9.2138958E-03 - - 9.5751521E-03 - - 9.8799162E-03 - - 1.0149817E-02 - - 1.0595940E-02 - - 1.0925157E-02 - - 1.1451227E-02 - - 1.1697295E-02 - - 1.2747125E-02 - - 1.3679064E-02 - - 1.7388258E-02 - - 2.0589616E-02 - - 2.4369432E-02 - - 2.7920510E-02 - - 3.1792267E-02 - - 3.5621878E-02 - - 3.9491661E-02 - - 4.3278532E-02 - - 4.7679951E-02 - - 5.1436615E-02 - - 5.6547886E-02 - - 6.0145268E-02 - - 6.4662138E-02 - - 7.1681806E-02 - - 7.2326892E-02 - - - - 5.1442091E-03 - - 9.0852521E-03 - - 9.2735609E-03 - - 8.6388628E-03 - - 8.8708740E-03 - - 8.7690933E-03 - - 9.2934119E-03 - - 9.3186161E-03 - - 9.6592707E-03 - - 9.9678700E-03 - - 1.0236163E-02 - - 1.0694734E-02 - - 1.1025890E-02 - - 1.1566030E-02 - - 1.1820104E-02 - - 1.2881706E-02 - - 1.3817409E-02 - - 1.7525018E-02 - - 2.0707299E-02 - - 2.4504049E-02 - - 2.8056398E-02 - - 3.1942086E-02 - - 3.5781215E-02 - - 3.9676732E-02 - - 4.3508487E-02 - - 4.7899374E-02 - - 5.1653601E-02 - - 5.6724194E-02 - - 6.0363176E-02 - - 6.4884496E-02 - - 7.1995314E-02 - - 7.2586420E-02 - - - - 5.1859947E-03 - - 9.1884111E-03 - - 9.3553722E-03 - - 8.7326674E-03 - - 8.9615831E-03 - - 8.8682756E-03 - - 9.3981872E-03 - - 9.4022342E-03 - - 9.7833217E-03 - - 1.0082626E-02 - - 1.0346345E-02 - - 1.0823172E-02 - - 1.1169852E-02 - - 1.1713674E-02 - - 1.1957780E-02 - - 1.3030310E-02 - - 1.3974055E-02 - - 1.7679518E-02 - - 2.0873339E-02 - - 2.4674002E-02 - - 2.8233633E-02 - - 3.2098518E-02 - - 3.5967409E-02 - - 3.9901149E-02 - - 4.3708564E-02 - - 4.8163155E-02 - - 5.1864987E-02 - - 5.6965609E-02 - - 6.0598955E-02 - - 6.5237827E-02 - - 7.2317026E-02 - - 7.2846315E-02 - - - - 5.2179276E-03 - - 9.2840460E-03 - - 9.4689692E-03 - - 8.8426310E-03 - - 9.0784020E-03 - - 8.9710561E-03 - - 9.5058449E-03 - - 9.5242525E-03 - - 9.8985438E-03 - - 1.0230104E-02 - - 1.0489612E-02 - - 1.0966586E-02 - - 1.1313882E-02 - - 1.1867051E-02 - - 1.2127596E-02 - - 1.3217267E-02 - - 1.4158489E-02 - - 1.7874095E-02 - - 2.1071639E-02 - - 2.4904630E-02 - - 2.8444961E-02 - - 3.2350782E-02 - - 3.6218293E-02 - - 4.0127228E-02 - - 4.3958446E-02 - - 4.8412743E-02 - - 5.2176893E-02 - - 5.7339635E-02 - - 6.0969984E-02 - - 6.5571180E-02 - - 7.2752295E-02 - - 7.3254466E-02 - - - - 5.2716442E-03 - - 9.4281164E-03 - - 9.6132026E-03 - - 8.9742401E-03 - - 9.2100433E-03 - - 9.1094424E-03 - - 9.6671272E-03 - - 9.6893875E-03 - - 1.0054424E-02 - - 1.0384782E-02 - - 1.0663088E-02 - - 1.1145331E-02 - - 1.1502660E-02 - - 1.2069220E-02 - - 1.2330654E-02 - - 1.3451168E-02 - - 1.4376732E-02 - - 1.8119744E-02 - - 2.1312268E-02 - - 2.5156150E-02 - - 2.8702855E-02 - - 3.2612605E-02 - - 3.6519082E-02 - - 4.0492357E-02 - - 4.4282144E-02 - - 4.8807320E-02 - - 5.2599863E-02 - - 5.7759050E-02 - - 6.1395630E-02 - - 6.6046712E-02 - - 7.3333461E-02 - - 7.3753560E-02 - - - - 5.3238344E-03 - - 9.5970913E-03 - - 9.7854600E-03 - - 9.1224140E-03 - - 9.3984166E-03 - - 9.2843910E-03 - - 9.8479041E-03 - - 9.8775712E-03 - - 1.0248815E-02 - - 1.0588076E-02 - - 1.0866467E-02 - - 1.1377201E-02 - - 1.1745016E-02 - - 1.2324752E-02 - - 1.2591933E-02 - - 1.3738942E-02 - - 1.4661945E-02 - - 1.8420789E-02 - - 2.1616210E-02 - - 2.5483933E-02 - - 2.9053296E-02 - - 3.3018657E-02 - - 3.6902567E-02 - - 4.0918920E-02 - - 4.4768920E-02 - - 4.9324206E-02 - - 5.3104469E-02 - - 5.8346792E-02 - - 6.2007342E-02 - - 6.6700912E-02 - - 7.4111114E-02 - - 7.4471661E-02 - - - - 5.4122500E-03 - - 9.8114809E-03 - - 9.9988824E-03 - - 9.3373137E-03 - - 9.6193550E-03 - - 9.5022652E-03 - - 1.0091629E-02 - - 1.0102292E-02 - - 1.0507181E-02 - - 1.0845994E-02 - - 1.1145961E-02 - - 1.1663724E-02 - - 1.2054675E-02 - - 1.2641320E-02 - - 1.2925378E-02 - - 1.4109631E-02 - - 1.5019788E-02 - - 1.8801255E-02 - - 2.2007215E-02 - - 2.5928762E-02 - - 2.9530128E-02 - - 3.3525210E-02 - - 3.7488914E-02 - - 4.1518826E-02 - - 4.5409731E-02 - - 5.0007891E-02 - - 5.3821041E-02 - - 5.9155539E-02 - - 6.2863258E-02 - - 6.7589912E-02 - - 7.5149452E-02 - - 7.5483624E-02 - - - - 5.5291381E-03 - - 1.0106920E-02 - - 1.0289680E-02 - - 9.6380580E-03 - - 9.9265277E-03 - - 9.8058620E-03 - - 1.0411771E-02 - - 1.0436031E-02 - - 1.0855919E-02 - - 1.1210324E-02 - - 1.1523264E-02 - - 1.2064653E-02 - - 1.2477020E-02 - - 1.3073068E-02 - - 1.3372106E-02 - - 1.4596687E-02 - - 1.5522669E-02 - - 1.9346144E-02 - - 2.2590235E-02 - - 2.6577078E-02 - - 3.0198519E-02 - - 3.4263702E-02 - - 3.8312940E-02 - - 4.2417033E-02 - - 4.6331184E-02 - - 5.1039786E-02 - - 5.4923952E-02 - - 6.0373272E-02 - - 6.4126997E-02 - - 6.8933518E-02 - - 7.6721947E-02 - - 7.6881324E-02 - - - - 5.7051926E-03 - - 1.0534340E-02 - - 1.0734999E-02 - - 1.0047973E-02 - - 1.0355258E-02 - - 1.0218464E-02 - - 1.0877782E-02 - - 1.0922582E-02 - - 1.1349348E-02 - - 1.1717445E-02 - - 1.2048634E-02 - - 1.2622834E-02 - - 1.3044209E-02 - - 1.3697572E-02 - - 1.4007429E-02 - - 1.5297796E-02 - - 1.6229092E-02 - - 2.0130646E-02 - - 2.3419720E-02 - - 2.7507372E-02 - - 3.1241243E-02 - - 3.5411821E-02 - - 3.9541855E-02 - - 4.3748213E-02 - - 4.7789294E-02 - - 5.2605069E-02 - - 5.6580575E-02 - - 6.2218120E-02 - - 6.6002923E-02 - - 7.0996802E-02 - - 7.9059610E-02 - - 7.9125302E-02 - - - - 5.9798621E-03 - - 1.1178770E-02 - - 1.1398960E-02 - - 1.0686315E-02 - - 1.1015007E-02 - - 1.0888426E-02 - - 1.1578312E-02 - - 1.1599595E-02 - - 1.2096215E-02 - - 1.2485774E-02 - - 1.2847301E-02 - - 1.3454293E-02 - - 1.3910042E-02 - - 1.4624946E-02 - - 1.4951480E-02 - - 1.6345303E-02 - - 1.7294576E-02 - - 2.1305917E-02 - - 2.4724135E-02 - - 2.8975117E-02 - - 3.2851405E-02 - - 3.7179235E-02 - - 4.1473071E-02 - - 4.5870569E-02 - - 5.0061541E-02 - - 5.5118747E-02 - - 5.9217709E-02 - - 6.5121185E-02 - - 6.9056004E-02 - - 7.4268036E-02 - - 8.2796332E-02 - - 8.2707329E-02 - - - - 6.3814382E-03 - - 1.2092503E-02 - - 1.2307256E-02 - - 1.1538828E-02 - - 1.1908080E-02 - - 1.1757836E-02 - - 1.2534374E-02 - - 1.2563508E-02 - - 1.3099926E-02 - - 1.3526120E-02 - - 1.3927022E-02 - - 1.4604411E-02 - - 1.5096848E-02 - - 1.5885767E-02 - - 1.6230507E-02 - - 1.7756050E-02 - - 1.8747181E-02 - - 2.2956423E-02 - - 2.6549953E-02 - - 3.1007445E-02 - - 3.5079178E-02 - - 3.9663485E-02 - - 4.4205438E-02 - - 4.8827182E-02 - - 5.3252335E-02 - - 5.8585422E-02 - - 6.2916830E-02 - - 6.9202743E-02 - - 7.3345048E-02 - - 7.8865458E-02 - - 8.8060504E-02 - - 8.7720181E-02 - - - - 6.5814203E-03 - - 1.2589556E-02 - - 1.2831098E-02 - - 1.2021990E-02 - - 1.2420962E-02 - - 1.2274328E-02 - - 1.3072229E-02 - - 1.3125790E-02 - - 1.3684984E-02 - - 1.4120320E-02 - - 1.4541810E-02 - - 1.5241834E-02 - - 1.5792664E-02 - - 1.6581300E-02 - - 1.6973815E-02 - - 1.8580511E-02 - - 1.9572617E-02 - - 2.3865583E-02 - - 2.7520381E-02 - - 3.2101383E-02 - - 3.6273771E-02 - - 4.0991031E-02 - - 4.5628107E-02 - - 5.0375712E-02 - - 5.4927552E-02 - - 6.0463390E-02 - - 6.4846891E-02 - - 7.1361573E-02 - - 7.5574981E-02 - - 8.1252683E-02 - - 9.0772914E-02 - - 9.0305344E-02 - - - - 6.5954047E-03 - - 1.2649872E-02 - - 1.2894758E-02 - - 1.2088299E-02 - - 1.2500706E-02 - - 1.2323868E-02 - - 1.3135140E-02 - - 1.3183877E-02 - - 1.3757540E-02 - - 1.4215358E-02 - - 1.4630076E-02 - - 1.5341576E-02 - - 1.5875377E-02 - - 1.6697400E-02 - - 1.7075964E-02 - - 1.8685615E-02 - - 1.9688554E-02 - - 2.3959638E-02 - - 2.7582865E-02 - - 3.2154359E-02 - - 3.6319478E-02 - - 4.0991674E-02 - - 4.5627244E-02 - - 5.0390376E-02 - - 5.4901681E-02 - - 6.0435636E-02 - - 6.4805706E-02 - - 7.1338882E-02 - - 7.5494665E-02 - - 8.1186566E-02 - - 9.0719563E-02 - - 9.0193680E-02 - - - - 6.5336047E-03 - - 1.2512090E-02 - - 1.2764479E-02 - - 1.1984145E-02 - - 1.2375802E-02 - - 1.2210337E-02 - - 1.3005945E-02 - - 1.3053548E-02 - - 1.3626485E-02 - - 1.4068961E-02 - - 1.4494598E-02 - - 1.5200428E-02 - - 1.5722617E-02 - - 1.6508783E-02 - - 1.6910525E-02 - - 1.8489314E-02 - - 1.9473998E-02 - - 2.3688731E-02 - - 2.7256893E-02 - - 3.1731269E-02 - - 3.5822276E-02 - - 4.0457390E-02 - - 4.5020879E-02 - - 4.9721896E-02 - - 5.4161674E-02 - - 5.9588663E-02 - - 6.3895979E-02 - - 7.0351683E-02 - - 7.4478980E-02 - - 8.0093110E-02 - - 8.9495166E-02 - - 8.8945256E-02 - - - - 6.4468824E-03 - - 1.2344191E-02 - - 1.2577769E-02 - - 1.1799198E-02 - - 1.2185250E-02 - - 1.2024671E-02 - - 1.2823561E-02 - - 1.2867050E-02 - - 1.3414223E-02 - - 1.3868383E-02 - - 1.4274902E-02 - - 1.4957665E-02 - - 1.5477639E-02 - - 1.6280478E-02 - - 1.6660201E-02 - - 1.8210099E-02 - - 1.9176459E-02 - - 2.3317865E-02 - - 2.6814611E-02 - - 3.1226187E-02 - - 3.5261695E-02 - - 3.9778054E-02 - - 4.4282066E-02 - - 4.8849080E-02 - - 5.3188035E-02 - - 5.8562223E-02 - - 6.2824222E-02 - - 6.9127893E-02 - - 7.3188187E-02 - - 7.8690046E-02 - - 8.7933862E-02 - - 8.7463314E-02 - - - - 6.3504172E-03 - - 1.2150642E-02 - - 1.2387727E-02 - - 1.1620660E-02 - - 1.2007755E-02 - - 1.1841239E-02 - - 1.2616226E-02 - - 1.2659354E-02 - - 1.3210608E-02 - - 1.3647237E-02 - - 1.4056090E-02 - - 1.4738601E-02 - - 1.5248667E-02 - - 1.6022604E-02 - - 1.6399027E-02 - - 1.7924821E-02 - - 1.8865800E-02 - - 2.2962104E-02 - - 2.6396869E-02 - - 3.0722714E-02 - - 3.4680261E-02 - - 3.9148700E-02 - - 4.3549586E-02 - - 4.8057389E-02 - - 5.2369847E-02 - - 5.7634643E-02 - - 6.1797568E-02 - - 6.8018235E-02 - - 7.1991375E-02 - - 7.7432633E-02 - - 8.6562066E-02 - - 8.6040544E-02 - - - - 6.2807225E-03 - - 1.2005102E-02 - - 1.2236833E-02 - - 1.1484849E-02 - - 1.1844265E-02 - - 1.1694745E-02 - - 1.2469442E-02 - - 1.2503258E-02 - - 1.3035750E-02 - - 1.3456731E-02 - - 1.3869786E-02 - - 1.4538788E-02 - - 1.5043345E-02 - - 1.5804904E-02 - - 1.6173155E-02 - - 1.7678967E-02 - - 1.8617817E-02 - - 2.2640680E-02 - - 2.6043512E-02 - - 3.0350793E-02 - - 3.4235767E-02 - - 3.8635112E-02 - - 4.3006209E-02 - - 4.7438737E-02 - - 5.1680206E-02 - - 5.6869882E-02 - - 6.0948428E-02 - - 6.7112720E-02 - - 7.1046470E-02 - - 7.6389984E-02 - - 8.5416908E-02 - - 8.4912400E-02 - - - - 6.2384011E-03 - - 1.1883626E-02 - - 1.2102819E-02 - - 1.1362792E-02 - - 1.1727085E-02 - - 1.1577991E-02 - - 1.2321572E-02 - - 1.2368887E-02 - - 1.2886627E-02 - - 1.3323476E-02 - - 1.3712662E-02 - - 1.4368905E-02 - - 1.4867001E-02 - - 1.5621404E-02 - - 1.6001770E-02 - - 1.7495457E-02 - - 1.8410484E-02 - - 2.2403739E-02 - - 2.5792442E-02 - - 3.0003874E-02 - - 3.3860219E-02 - - 3.8194472E-02 - - 4.2513447E-02 - - 4.6944801E-02 - - 5.1102508E-02 - - 5.6230364E-02 - - 6.0282905E-02 - - 6.6396185E-02 - - 7.0267237E-02 - - 7.5567209E-02 - - 8.4430462E-02 - - 8.3984117E-02 - - - - 6.1845926E-03 - - 1.1774745E-02 - - 1.2008907E-02 - - 1.1282463E-02 - - 1.1630642E-02 - - 1.1486008E-02 - - 1.2212483E-02 - - 1.2255192E-02 - - 1.2777462E-02 - - 1.3204562E-02 - - 1.3600398E-02 - - 1.4255316E-02 - - 1.4736561E-02 - - 1.5470029E-02 - - 1.5845176E-02 - - 1.7313807E-02 - - 1.8247178E-02 - - 2.2230316E-02 - - 2.5531152E-02 - - 2.9731972E-02 - - 3.3558284E-02 - - 3.7872884E-02 - - 4.2109048E-02 - - 4.6517240E-02 - - 5.0645413E-02 - - 5.5683251E-02 - - 5.9750465E-02 - - 6.5766931E-02 - - 6.9579667E-02 - - 7.4872290E-02 - - 8.3643239E-02 - - 8.3206968E-02 - - - - 6.1719734E-03 - - 1.1719545E-02 - - 1.1917909E-02 - - 1.1189341E-02 - - 1.1548606E-02 - - 1.1416064E-02 - - 1.2129643E-02 - - 1.2168083E-02 - - 1.2694983E-02 - - 1.3100793E-02 - - 1.3481593E-02 - - 1.4146417E-02 - - 1.4630389E-02 - - 1.5367839E-02 - - 1.5730917E-02 - - 1.7184516E-02 - - 1.8089440E-02 - - 2.2023196E-02 - - 2.5336832E-02 - - 2.9501303E-02 - - 3.3286048E-02 - - 3.7579302E-02 - - 4.1818920E-02 - - 4.6160226E-02 - - 5.0276169E-02 - - 5.5322377E-02 - - 5.9292479E-02 - - 6.5292838E-02 - - 6.9134443E-02 - - 7.4296625E-02 - - 8.3006295E-02 - - 8.2573545E-02 - - - - 6.1382782E-03 - - 1.1652027E-02 - - 1.1858603E-02 - - 1.1149474E-02 - - 1.1500153E-02 - - 1.1352538E-02 - - 1.2052433E-02 - - 1.2104328E-02 - - 1.2615826E-02 - - 1.3028027E-02 - - 1.3393814E-02 - - 1.4056119E-02 - - 1.4520800E-02 - - 1.5244525E-02 - - 1.5619872E-02 - - 1.7065448E-02 - - 1.7976677E-02 - - 2.1928655E-02 - - 2.5188600E-02 - - 2.9345474E-02 - - 3.3098490E-02 - - 3.7352890E-02 - - 4.1577882E-02 - - 4.5851588E-02 - - 4.9907550E-02 - - 5.5007580E-02 - - 5.8924848E-02 - - 6.4866195E-02 - - 6.8653679E-02 - - 7.3799695E-02 - - 8.2491620E-02 - - 8.2047228E-02 - - - - 6.1241006E-03 - - 1.1590726E-02 - - 1.1801215E-02 - - 1.1080585E-02 - - 1.1434054E-02 - - 1.1286311E-02 - - 1.2000496E-02 - - 1.2020032E-02 - - 1.2555074E-02 - - 1.2968561E-02 - - 1.3345040E-02 - - 1.3984260E-02 - - 1.4471501E-02 - - 1.5187071E-02 - - 1.5527587E-02 - - 1.6969733E-02 - - 1.7880430E-02 - - 2.1827072E-02 - - 2.5070882E-02 - - 2.9204178E-02 - - 3.2920367E-02 - - 3.7138445E-02 - - 4.1355200E-02 - - 4.5651496E-02 - - 4.9686415E-02 - - 5.4664866E-02 - - 5.8632525E-02 - - 6.4518086E-02 - - 6.8341097E-02 - - 7.3449748E-02 - - 8.2031901E-02 - - 8.1619798E-02 - - - - 6.1062727E-03 - - 1.1540200E-02 - - 1.1761046E-02 - - 1.1040109E-02 - - 1.1412932E-02 - - 1.1240736E-02 - - 1.1950046E-02 - - 1.1997678E-02 - - 1.2505989E-02 - - 1.2930265E-02 - - 1.3303213E-02 - - 1.3935054E-02 - - 1.4397122E-02 - - 1.5128867E-02 - - 1.5487202E-02 - - 1.6938379E-02 - - 1.7810772E-02 - - 2.1723430E-02 - - 2.4973244E-02 - - 2.9068452E-02 - - 3.2834028E-02 - - 3.7010997E-02 - - 4.1148015E-02 - - 4.5454526E-02 - - 4.9470264E-02 - - 5.4447102E-02 - - 5.8392796E-02 - - 6.4249338E-02 - - 6.8034422E-02 - - 7.3189468E-02 - - 8.1672467E-02 - - 8.1260364E-02 - - - - 6.0833777E-03 - - 1.1517436E-02 - - 1.1712978E-02 - - 1.1032819E-02 - - 1.1358893E-02 - - 1.1208870E-02 - - 1.1912352E-02 - - 1.1958737E-02 - - 1.2469851E-02 - - 1.2881147E-02 - - 1.3237414E-02 - - 1.3873203E-02 - - 1.4346868E-02 - - 1.5065060E-02 - - 1.5417558E-02 - - 1.6865782E-02 - - 1.7748238E-02 - - 2.1647065E-02 - - 2.4885779E-02 - - 2.8999390E-02 - - 3.2709869E-02 - - 3.6878634E-02 - - 4.1028900E-02 - - 4.5288735E-02 - - 4.9351482E-02 - - 5.4263443E-02 - - 5.8208019E-02 - - 6.4026596E-02 - - 6.7817431E-02 - - 7.2944166E-02 - - 8.1408951E-02 - - 8.0980011E-02 - - - - 6.0960595E-03 - - 1.1509277E-02 - - 1.1717750E-02 - - 1.1016084E-02 - - 1.1324287E-02 - - 1.1181299E-02 - - 1.1926512E-02 - - 1.1924795E-02 - - 1.2430825E-02 - - 1.2836520E-02 - - 1.3191644E-02 - - 1.3847845E-02 - - 1.4306693E-02 - - 1.5047376E-02 - - 1.5361189E-02 - - 1.6797970E-02 - - 1.7681035E-02 - - 2.1572902E-02 - - 2.4843981E-02 - - 2.8950004E-02 - - 3.2646669E-02 - - 3.6798605E-02 - - 4.0927881E-02 - - 4.5165770E-02 - - 4.9225435E-02 - - 5.4165928E-02 - - 5.8066998E-02 - - 6.3897046E-02 - - 6.7667188E-02 - - 7.2785603E-02 - - 8.1253392E-02 - - 8.0864443E-02 - - - - 6.0706294E-03 - - 1.1507691E-02 - - 1.1695334E-02 - - 1.0977998E-02 - - 1.1320263E-02 - - 1.1167309E-02 - - 1.1887145E-02 - - 1.1908635E-02 - - 1.2405259E-02 - - 1.2838152E-02 - - 1.3210507E-02 - - 1.3849960E-02 - - 1.4283591E-02 - - 1.5028182E-02 - - 1.5329706E-02 - - 1.6759635E-02 - - 1.7685388E-02 - - 2.1572849E-02 - - 2.4772494E-02 - - 2.8864133E-02 - - 3.2582677E-02 - - 3.6784719E-02 - - 4.0900801E-02 - - 4.5137865E-02 - - 4.9135372E-02 - - 5.4093178E-02 - - 5.8034149E-02 - - 6.3786244E-02 - - 6.7502120E-02 - - 7.2584553E-02 - - 8.1167082E-02 - - 8.0688398E-02 - - - - 6.0461907E-03 - - 1.1481547E-02 - - 1.1737058E-02 - - 1.0999643E-02 - - 1.1361089E-02 - - 1.1125441E-02 - - 1.1866202E-02 - - 1.1842566E-02 - - 1.2424994E-02 - - 1.2799184E-02 - - 1.3219862E-02 - - 1.3773742E-02 - - 1.4257782E-02 - - 1.4972557E-02 - - 1.5426839E-02 - - 1.6740630E-02 - - 1.7654390E-02 - - 2.1573482E-02 - - 2.4801577E-02 - - 2.8800263E-02 - - 3.2583876E-02 - - 3.6801622E-02 - - 4.0806074E-02 - - 4.5107401E-02 - - 4.9075545E-02 - - 5.3960225E-02 - - 5.7982974E-02 - - 6.3859228E-02 - - 6.7502946E-02 - - 7.2470281E-02 - - 8.1149466E-02 - - 8.0629616E-02 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - 1.0000000E+00 - - - - - \ No newline at end of file diff --git a/tests/input_set.py b/tests/input_set.py index f3f9e88bd4..0d5a78bab9 100644 --- a/tests/input_set.py +++ b/tests/input_set.py @@ -1,8 +1,9 @@ +import numpy as np + import openmc from openmc.source import Source from openmc.stats import Box -import numpy as np class InputSet(object): def __init__(self): @@ -728,60 +729,59 @@ class AssemblyInputSet(object): class MGInputSet(InputSet): - def build_default_materials_and_geometry(self): + def build_default_materials_and_geometry(self, reps=None, as_macro=True): # Define materials needed for 1D/1G slab problem - uo2_data = openmc.Macroscopic('uo2_iso') - uo2 = openmc.Material(name='UO2', material_id=1) - uo2.set_density('macro', 1.0) - uo2.add_macroscopic(uo2_data) + mat_names = ['uo2', 'clad', 'lwtr'] + mgxs_reps = ['ang', 'ang_mu', 'iso', 'iso_mu'] - clad_data = openmc.Macroscopic('clad_ang_mu') - clad = openmc.Material(name='Clad', material_id=2) - clad.set_density('macro', 1.0) - clad.add_macroscopic(clad_data) + if reps is None: + reps = mgxs_reps - water_data = openmc.Macroscopic('lwtr_iso_mu') - water = openmc.Material(name='LWTR', material_id=3) - water.set_density('macro', 1.0) - water.add_macroscopic(water_data) + xs = [] + mats = [] + i = 0 + for mat in mat_names: + for rep in reps: + i += 1 + if as_macro: + xs.append(openmc.Macroscopic(mat + '_' + rep)) + mats.append(openmc.Material(name=str(i))) + mats[-1].set_density('macro', 1.) + mats[-1].add_macroscopic(xs[-1]) + else: + xs.append(openmc.Nuclide(mat + '_' + rep)) + mats.append(openmc.Material(name=str(i))) + mats[-1].set_density('atom/b-cm', 1.) + mats[-1].add_nuclide(xs[-1].name, 1.0, 'ao') - # Define the materials file. - self.materials += (uo2, clad, water) + # Define the materials file + self.xs_data = xs + self.materials += mats # Define surfaces. - # Assembly/Problem Boundary - left = openmc.XPlane(x0=0.0, surface_id=200, - boundary_type='reflective') - right = openmc.XPlane(x0=10.0, surface_id=201, - boundary_type='reflective') - bottom = openmc.YPlane(y0=0.0, surface_id=300, - boundary_type='reflective') - top = openmc.YPlane(y0=10.0, surface_id=301, - boundary_type='reflective') + left = openmc.XPlane(x0=0.0, boundary_type='reflective') + right = openmc.XPlane(x0=10.0, boundary_type='reflective') + bottom = openmc.YPlane(y0=0.0, boundary_type='reflective') + top = openmc.YPlane(y0=10.0, boundary_type='reflective') + # for each material add a plane + planes = [openmc.ZPlane(z0=0.0, boundary_type='reflective')] + dz = round(5. / float(len(mats)), 4) + for i in range(len(mats) - 1): + planes.append(openmc.ZPlane(z0=dz * float(i + 1))) + planes.append(openmc.ZPlane(z0=5.0, boundary_type='reflective')) - down = openmc.ZPlane(z0=0.0, surface_id=0, - boundary_type='reflective') - fuel_clad_intfc = openmc.ZPlane(z0=2.0, surface_id=1) - clad_lwtr_intfc = openmc.ZPlane(z0=2.4, surface_id=2) - up = openmc.ZPlane(z0=5.0, surface_id=3, - boundary_type='reflective') - - # Define cells - c1 = openmc.Cell(cell_id=1) - c1.region = +left & -right & +bottom & -top & +down & -fuel_clad_intfc - c1.fill = uo2 - c2 = openmc.Cell(cell_id=2) - c2.region = +left & -right & +bottom & -top & +fuel_clad_intfc & -clad_lwtr_intfc - c2.fill = clad - c3 = openmc.Cell(cell_id=3) - c3.region = +left & -right & +bottom & -top & +clad_lwtr_intfc & -up - c3.fill = water + # Define cells for each material + cells = [] + xy = +left & -right & +bottom & -top + for i, mat in enumerate(mats): + cells.append(openmc.Cell()) + cells[-1].region = xy & +planes[i] & -planes[i + 1] + cells[-1].fill = mat # Define root universe. root = openmc.Universe(universe_id=0, name='root universe') - - root.add_cells((c1, c2, c3)) + root.add_cells(cells) # Assign root universe to geometry self.geometry.root_universe = root @@ -791,9 +791,9 @@ class MGInputSet(InputSet): self.settings.inactive = 5 self.settings.particles = 100 self.settings.source = Source(space=Box([0.0, 0.0, 0.0], - [10.0, 10.0, 2.0])) + [10.0, 10.0, 5.])) self.settings.energy_mode = "multi-group" - self.settings.cross_sections = "../1d_mgxs.xml" + self.settings.cross_sections = "../1d_mgxs.h5" def build_defualt_plots(self): plot = openmc.Plot() diff --git a/tests/run_tests.py b/tests/run_tests.py index 87282055c2..28bedab0dc 100755 --- a/tests/run_tests.py +++ b/tests/run_tests.py @@ -117,7 +117,7 @@ def cleanup(path): for dirpath, dirnames, filenames in os.walk(path): for fname in filenames: for ext in ['.h5', '.ppm', '.voxel']: - if fname.endswith(ext): + if fname.endswith(ext) and fname != '1d_mgxs.h5': os.remove(os.path.join(dirpath, fname)) diff --git a/tests/test_create_fission_neutrons/inputs_true.dat b/tests/test_create_fission_neutrons/inputs_true.dat new file mode 100644 index 0000000000..8a1a17b9e9 --- /dev/null +++ b/tests/test_create_fission_neutrons/inputs_true.dat @@ -0,0 +1 @@ +c3581501d1486293c255390251d20584431a198fbb7c07dc2879dc95dc96e26786d3913ce0db8007f542468fd137ff3267824844c03b4687fdad81ea568c92d7 \ No newline at end of file diff --git a/tests/test_create_fission_neutrons/results_true.dat b/tests/test_create_fission_neutrons/results_true.dat new file mode 100644 index 0000000000..be7c5c438d --- /dev/null +++ b/tests/test_create_fission_neutrons/results_true.dat @@ -0,0 +1,3 @@ +tally 1: +sum = 2.056839E+02 +sum_sq = 4.244628E+03 diff --git a/tests/test_create_fission_neutrons/test_create_fission_neutrons.py b/tests/test_create_fission_neutrons/test_create_fission_neutrons.py new file mode 100755 index 0000000000..80da831cc0 --- /dev/null +++ b/tests/test_create_fission_neutrons/test_create_fission_neutrons.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.pardir) +from testing_harness import PyAPITestHarness +import openmc + + +class CreateFissionNeutronsTestHarness(PyAPITestHarness): + def _build_inputs(self): + # Material is composed of H-1 and U-235 + mat = openmc.Material(material_id=1, name='mat') + mat.set_density('atom/b-cm', 0.069335) + mat.add_nuclide('H1', 40.0) + mat.add_nuclide('U235', 1.0) + materials_file = openmc.Materials([mat]) + materials_file.export_to_xml() + + # Cell is box with reflective boundary + x1 = openmc.XPlane(surface_id=1, x0=-1) + x2 = openmc.XPlane(surface_id=2, x0=1) + y1 = openmc.YPlane(surface_id=3, y0=-1) + y2 = openmc.YPlane(surface_id=4, y0=1) + z1 = openmc.ZPlane(surface_id=5, z0=-1) + z2 = openmc.ZPlane(surface_id=6, z0=1) + for surface in [x1, x2, y1, y2, z1, z2]: + surface.boundary_type = 'reflective' + box = openmc.Cell(cell_id=1, name='box') + box.region = +x1 & -x2 & +y1 & -y2 & +z1 & -z2 + box.fill = mat + root = openmc.Universe(universe_id=0, name='root universe') + root.add_cell(box) + geometry = openmc.Geometry(root) + geometry.export_to_xml() + + # Set the running parameters + settings_file = openmc.Settings() + settings_file.run_mode = 'fixed source' + settings_file.batches = 10 + settings_file.particles = 100 + settings_file.create_fission_neutrons = False + bounds = [-1, -1, -1, 1, 1, 1] + uniform_dist = openmc.stats.Box(bounds[:3], bounds[3:]) + watt_dist = openmc.stats.Watt() + settings_file.source = openmc.source.Source(space=uniform_dist, + energy=watt_dist) + settings_file.export_to_xml() + + # Create tallies + tallies = openmc.Tallies() + tally = openmc.Tally(1) + tally.scores = ['flux'] + tallies.append(tally) + tallies.export_to_xml() + + def _get_results(self): + """Digest info in the statepoint and return as a string.""" + # Read the statepoint file. + sp = openmc.StatePoint(self._sp_name) + + # Write out tally data. + outstr = '' + t = sp.get_tally() + outstr += 'tally {0}:\n'.format(t.id) + outstr += 'sum = {0:12.6E}\n'.format(t.sum[0, 0, 0]) + outstr += 'sum_sq = {0:12.6E}\n'.format(t.sum_sq[0, 0, 0]) + + return outstr + + def _cleanup(self): + super(CreateFissionNeutronsTestHarness, self)._cleanup() + f = os.path.join(os.getcwd(), 'tallies.xml') + if os.path.exists(f): + os.remove(f) + + +if __name__ == '__main__': + harness = CreateFissionNeutronsTestHarness('statepoint.10.h5', True) + harness.main() diff --git a/tests/test_energy_cutoff/inputs_true.dat b/tests/test_energy_cutoff/inputs_true.dat new file mode 100644 index 0000000000..0630d2acc2 --- /dev/null +++ b/tests/test_energy_cutoff/inputs_true.dat @@ -0,0 +1 @@ +4dc6a7b131f6757ecc9b06e93d425712f0813c546ed9eaa0aafa4990383b2f3a5b742a5a39ef5f27300d2c861b344e78de2d2c569b9439e7893dc06b03bf3b02 \ No newline at end of file diff --git a/tests/test_energy_cutoff/results_true.dat b/tests/test_energy_cutoff/results_true.dat new file mode 100644 index 0000000000..5ad463b774 --- /dev/null +++ b/tests/test_energy_cutoff/results_true.dat @@ -0,0 +1,3 @@ +tally 1: +sum = 0.000000E+00 +sum_sq = 0.000000E+00 diff --git a/tests/test_energy_cutoff/test_energy_cutoff.py b/tests/test_energy_cutoff/test_energy_cutoff.py new file mode 100755 index 0000000000..6467a59255 --- /dev/null +++ b/tests/test_energy_cutoff/test_energy_cutoff.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.pardir) +from testing_harness import PyAPITestHarness +import openmc + + +class EnergyCutoffTestHarness(PyAPITestHarness): + def _build_inputs(self): + # Set energy cutoff + energy_cutoff = 4e-6 + + # Material is composed of H-1 + mat = openmc.Material(material_id=1, name='mat') + mat.set_density('atom/b-cm', 0.069335) + mat.add_nuclide('H1', 40.0) + materials_file = openmc.Materials([mat]) + materials_file.export_to_xml() + + # Cell is box with reflective boundary + x1 = openmc.XPlane(surface_id=1, x0=-1) + x2 = openmc.XPlane(surface_id=2, x0=1) + y1 = openmc.YPlane(surface_id=3, y0=-1) + y2 = openmc.YPlane(surface_id=4, y0=1) + z1 = openmc.ZPlane(surface_id=5, z0=-1) + z2 = openmc.ZPlane(surface_id=6, z0=1) + for surface in [x1, x2, y1, y2, z1, z2]: + surface.boundary_type = 'reflective' + box = openmc.Cell(cell_id=1, name='box') + box.region = +x1 & -x2 & +y1 & -y2 & +z1 & -z2 + box.fill = mat + root = openmc.Universe(universe_id=0, name='root universe') + root.add_cell(box) + geometry = openmc.Geometry(root) + geometry.export_to_xml() + + # Set the running parameters + settings_file = openmc.Settings() + settings_file.run_mode = 'fixed source' + settings_file.batches = 10 + settings_file.particles = 100 + settings_file.cutoff = {'energy': energy_cutoff} + bounds = [-1, -1, -1, 1, 1, 1] + uniform_dist = openmc.stats.Box(bounds[:3], bounds[3:]) + watt_dist = openmc.stats.Watt() + settings_file.source = openmc.source.Source(space=uniform_dist, + energy=watt_dist) + settings_file.export_to_xml() + + # Tally flux under energy cutoff + tallies = openmc.Tallies() + tally = openmc.Tally(1) + tally.scores = ['flux'] + energy_filter = openmc.filter.EnergyFilter((0.0, energy_cutoff)) + tally.filters = [energy_filter] + tallies.append(tally) + tallies.export_to_xml() + + def _get_results(self): + """Digest info in the statepoint and return as a string.""" + # Read the statepoint file. + sp = openmc.StatePoint(self._sp_name) + + # Write out tally data. + outstr = '' + t = sp.get_tally() + outstr += 'tally {0}:\n'.format(t.id) + outstr += 'sum = {0:12.6E}\n'.format(t.sum[0, 0, 0]) + outstr += 'sum_sq = {0:12.6E}\n'.format(t.sum_sq[0, 0, 0]) + + return outstr + + def _cleanup(self): + super(EnergyCutoffTestHarness, self)._cleanup() + f = os.path.join(os.getcwd(), 'tallies.xml') + if os.path.exists(f): + os.remove(f) + + +if __name__ == '__main__': + harness = EnergyCutoffTestHarness('statepoint.10.h5', True) + harness.main() diff --git a/tests/test_mg_basic/inputs_true.dat b/tests/test_mg_basic/inputs_true.dat index fad74ca827..08917ab7db 100644 --- a/tests/test_mg_basic/inputs_true.dat +++ b/tests/test_mg_basic/inputs_true.dat @@ -1 +1 @@ -e843dbee8b989142d68e78f7a3e83309a9982c0127974ba4b6a58c823ce298e8fffc8828b48aa696f045818a2a80ef4003f5a191f33aacef7d7dd72c950855a6 \ No newline at end of file +115218221500e60ea43145875324a9a6800366fcc97357ef4cd8182f9253e114cbe1c7481dd3bdd8d7dce5983e2cb757ae0a2e05ede236d94cba7909703ba7f7 \ No newline at end of file diff --git a/tests/test_mg_basic/results_true.dat b/tests/test_mg_basic/results_true.dat index 7cdda73b5d..01b7925469 100644 --- a/tests/test_mg_basic/results_true.dat +++ b/tests/test_mg_basic/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.047136E+00 2.765964E-02 +1.160653E+00 6.227102E-02 diff --git a/tests/test_mg_max_order/inputs_true.dat b/tests/test_mg_max_order/inputs_true.dat index d827cfaa49..3056e8cbdf 100644 --- a/tests/test_mg_max_order/inputs_true.dat +++ b/tests/test_mg_max_order/inputs_true.dat @@ -1 +1 @@ -7d508b1f3a2661566b8e8cb76fee61aecb96e8b60d633b06f13c4600bd854ea3366cdebd033c0a71ffb8adb90a9aeb64fe5ac0ef3235260921f5689c93e54305 \ No newline at end of file +139d760cd83eab001ed3fd52d7146fb5f30b7021b26ada6a1e425f5446185ac6fa61ac2ac58aa9e895981e10540160b7ae7428c833024679ef1ca762715e2d51 \ No newline at end of file diff --git a/tests/test_mg_max_order/results_true.dat b/tests/test_mg_max_order/results_true.dat index 4db04e0897..0e470e2cdb 100644 --- a/tests/test_mg_max_order/results_true.dat +++ b/tests/test_mg_max_order/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.102093E+00 4.962190E-02 +1.098323E+00 1.979833E-02 diff --git a/tests/test_mg_max_order/test_mg_max_order.py b/tests/test_mg_max_order/test_mg_max_order.py index da699316ca..8c7948a323 100644 --- a/tests/test_mg_max_order/test_mg_max_order.py +++ b/tests/test_mg_max_order/test_mg_max_order.py @@ -2,83 +2,26 @@ import os import sys + sys.path.insert(0, os.pardir) -from testing_harness import TestHarness, PyAPITestHarness +from testing_harness import PyAPITestHarness from input_set import MGInputSet -import openmc -class MGNuclideInputSet(MGInputSet): - def build_default_materials_and_geometry(self): - # Define materials needed for 1D/1G slab problem - uo2_data = openmc.Macroscopic('uo2_iso') - uo2 = openmc.Material(name='UO2', material_id=1) - uo2.set_density('macro', 1.0) - uo2.add_macroscopic(uo2_data) - - clad_data = openmc.Macroscopic('clad_iso') - clad = openmc.Material(name='Clad', material_id=2) - clad.set_density('macro', 1.0) - clad.add_macroscopic(clad_data) - - water_data = openmc.Macroscopic('lwtr_iso') - water = openmc.Material(name='LWTR', material_id=3) - water.set_density('macro', 1.0) - water.add_macroscopic(water_data) - - # Define the materials file. - self.materials += (uo2, clad, water) - - # Define surfaces. - - # Assembly/Problem Boundary - left = openmc.XPlane(x0=0.0, surface_id=200, - boundary_type='reflective') - right = openmc.XPlane(x0=10.0, surface_id=201, - boundary_type='reflective') - bottom = openmc.YPlane(y0=0.0, surface_id=300, - boundary_type='reflective') - top = openmc.YPlane(y0=10.0, surface_id=301, - boundary_type='reflective') - - down = openmc.ZPlane(z0=0.0, surface_id=0, - boundary_type='reflective') - fuel_clad_intfc = openmc.ZPlane(z0=2.0, surface_id=1) - clad_lwtr_intfc = openmc.ZPlane(z0=2.4, surface_id=2) - up = openmc.ZPlane(z0=5.0, surface_id=3, - boundary_type='reflective') - - # Define cells - c1 = openmc.Cell(cell_id=1) - c1.region = +left & -right & +bottom & -top & +down & -fuel_clad_intfc - c1.fill = uo2 - c2 = openmc.Cell(cell_id=2) - c2.region = +left & -right & +bottom & -top & +fuel_clad_intfc & -clad_lwtr_intfc - c2.fill = clad - c3 = openmc.Cell(cell_id=3) - c3.region = +left & -right & +bottom & -top & +clad_lwtr_intfc & -up - c3.fill = water - - # Define root universe. - root = openmc.Universe(universe_id=0, name='root universe') - - root.add_cells((c1,c2,c3)) - - # Define the geometry file. - geometry = openmc.Geometry() - geometry.root_universe = root - - self.geometry = geometry class MGMaxOrderTestHarness(PyAPITestHarness): def __init__(self, statepoint_name, tallies_present, mg=False): PyAPITestHarness.__init__(self, statepoint_name, tallies_present) - self._input_set = MGNuclideInputSet() + self._input_set = MGInputSet() def _build_inputs(self): + """Write input XML files.""" + reps = ['iso'] + self._input_set.build_default_materials_and_geometry(reps=reps) + self._input_set.build_default_settings() # Set P1 scattering self._input_set.settings.max_order = 1 - # Call standard input build - super(MGMaxOrderTestHarness, self)._build_inputs() + self._input_set.export() + if __name__ == '__main__': harness = MGMaxOrderTestHarness('statepoint.10.*', False, mg=True) diff --git a/tests/test_mg_nuclide/inputs_true.dat b/tests/test_mg_nuclide/inputs_true.dat index 18811f2854..57aa5d33f0 100644 --- a/tests/test_mg_nuclide/inputs_true.dat +++ b/tests/test_mg_nuclide/inputs_true.dat @@ -1 +1 @@ -be296da93031694b2915e1a10e3e6fd663d612cdd29a84745e3ccb0065c088b4bcda45f6919962f6ee784efe52ebe178bf7d3ce019859637ae57c2da1e240a04 \ No newline at end of file +6d03b988671fe21dfe2a908685536edb3059e5bdda7974ddfa65c7f63cecb7f6b3fce49bc1533ef2787e284121779653cb14a66cfd709258e4b07d8bd7571843 \ No newline at end of file diff --git a/tests/test_mg_nuclide/results_true.dat b/tests/test_mg_nuclide/results_true.dat index 7cdda73b5d..01b7925469 100644 --- a/tests/test_mg_nuclide/results_true.dat +++ b/tests/test_mg_nuclide/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.047136E+00 2.765964E-02 +1.160653E+00 6.227102E-02 diff --git a/tests/test_mg_nuclide/test_mg_nuclide.py b/tests/test_mg_nuclide/test_mg_nuclide.py index 89694eea25..b94af258f2 100644 --- a/tests/test_mg_nuclide/test_mg_nuclide.py +++ b/tests/test_mg_nuclide/test_mg_nuclide.py @@ -2,81 +2,22 @@ import os import sys + sys.path.insert(0, os.pardir) -from testing_harness import TestHarness, PyAPITestHarness +from testing_harness import PyAPITestHarness from input_set import MGInputSet -import openmc -class MGNuclideInputSet(MGInputSet): - def build_default_materials_and_geometry(self): - # Define materials needed for 1D/1G slab problem - # This time do using nuclide, not macroscopic - uo2 = openmc.Material(name='UO2', material_id=1) - uo2.set_density('sum', 1.0) - uo2.add_nuclide("uo2_iso", 1.0) - - clad = openmc.Material(name='Clad', material_id=2) - clad.set_density('sum', 1.0) - clad.add_nuclide("clad_ang_mu", 1.0) - - # water_data = openmc.Nuclide('lwtr_iso_mu', '71c') - water = openmc.Material(name='LWTR', material_id=3) - water.set_density('sum', 1.0) - water.add_nuclide("lwtr_iso_mu", 1.0) - - # Define the materials file. - self.materials.default_xs = '71c' - self.materials += (uo2, clad, water) - - # Define surfaces. - - # Assembly/Problem Boundary - left = openmc.XPlane(x0=0.0, surface_id=200, - boundary_type='reflective') - right = openmc.XPlane(x0=10.0, surface_id=201, - boundary_type='reflective') - bottom = openmc.YPlane(y0=0.0, surface_id=300, - boundary_type='reflective') - top = openmc.YPlane(y0=10.0, surface_id=301, - boundary_type='reflective') - - down = openmc.ZPlane(z0=0.0, surface_id=0, - boundary_type='reflective') - fuel_clad_intfc = openmc.ZPlane(z0=2.0, surface_id=1) - clad_lwtr_intfc = openmc.ZPlane(z0=2.4, surface_id=2) - up = openmc.ZPlane(z0=5.0, surface_id=3, - boundary_type='reflective') - - # Define cells - c1 = openmc.Cell(cell_id=1) - c1.region = +left & -right & +bottom & -top & +down & -fuel_clad_intfc - c1.fill = uo2 - c2 = openmc.Cell(cell_id=2) - c2.region = +left & -right & +bottom & -top & +fuel_clad_intfc & -clad_lwtr_intfc - c2.fill = clad - c3 = openmc.Cell(cell_id=3) - c3.region = +left & -right & +bottom & -top & +clad_lwtr_intfc & -up - c3.fill = water - - # Define root universe. - root = openmc.Universe(universe_id=0, name='root universe') - - root.add_cells((c1,c2,c3)) - - # Define the geometry file. - geometry = openmc.Geometry() - geometry.root_universe = root - - self.geometry = geometry class MGNuclideTestHarness(PyAPITestHarness): def __init__(self, statepoint_name, tallies_present, mg=False): PyAPITestHarness.__init__(self, statepoint_name, tallies_present) - self._input_set = MGNuclideInputSet() + self._input_set = MGInputSet() def _build_inputs(self): - super(MGNuclideTestHarness, self)._build_inputs() - + """Write input XML files.""" + self._input_set.build_default_materials_and_geometry(as_macro=False) + self._input_set.build_default_settings() + self._input_set.export() if __name__ == '__main__': diff --git a/tests/test_mg_tallies/inputs_true.dat b/tests/test_mg_tallies/inputs_true.dat index e1f3385a43..6b0ff76b15 100644 --- a/tests/test_mg_tallies/inputs_true.dat +++ b/tests/test_mg_tallies/inputs_true.dat @@ -1 +1 @@ -b607875dcaecb7110e396a62100182818b8b2853ec9921194b7ab00d6156373b01394ad8bd729babf7d258e6d9c599f6944c6857cd9d2f65ea98e245ee3cf010 \ No newline at end of file +8c496e13f9456bedcc0789ffdca81913596cca3c7867717ced38c3063b6cdc8949bd204c98723b72c1b456e3fc85fc90e6710482b0c74e5e29283902a5d9ed50 \ No newline at end of file diff --git a/tests/test_mg_tallies/results_true.dat b/tests/test_mg_tallies/results_true.dat index cb0498e511..b540d9a492 100644 --- a/tests/test_mg_tallies/results_true.dat +++ b/tests/test_mg_tallies/results_true.dat @@ -1,2906 +1 @@ -k-combined: -1.047136E+00 2.765964E-02 -tally 1: -2.490837E+00 -1.335515E+00 -8.299408E-02 -1.628477E-03 -3.917892E+00 -3.395475E+00 -3.777816E-02 -3.574150E-04 -9.366009E-02 -2.196850E-03 -2.099094E+00 -8.919271E-01 -7.540489E-02 -1.194829E-03 -3.366752E+00 -2.321133E+00 -3.536709E-02 -2.711517E-04 -8.768256E-02 -1.666633E-03 -2.667561E+00 -1.528159E+00 -6.981409E-02 -1.036744E-03 -3.696781E+00 -2.912439E+00 -2.768232E-02 -1.628195E-04 -6.863038E-02 -1.000769E-03 -2.643152E+00 -1.461242E+00 -7.777503E-02 -1.277892E-03 -3.881716E+00 -3.158579E+00 -3.318888E-02 -2.353505E-04 -8.228231E-02 -1.446581E-03 -2.379478E+00 -1.220072E+00 -7.149541E-02 -1.036720E-03 -3.597267E+00 -2.694760E+00 -3.098378E-02 -1.953397E-04 -7.681538E-02 -1.200655E-03 -3.128432E+00 -2.123023E+00 -8.683081E-02 -1.593217E-03 -4.568791E+00 -4.439900E+00 -3.595477E-02 -2.733665E-04 -8.913952E-02 -1.680246E-03 -3.320603E+00 -2.324411E+00 -9.169756E-02 -1.769612E-03 -4.811447E+00 -4.885591E+00 -3.780490E-02 -3.050758E-04 -9.372640E-02 -1.875147E-03 -3.709821E+00 -2.847102E+00 -1.037249E-01 -2.264974E-03 -5.329369E+00 -5.878403E+00 -4.295875E-02 -3.964777E-04 -1.065039E-01 -2.436949E-03 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.410307E+00 -1.211320E+00 -7.104710E-02 -1.056830E-03 -3.619111E+00 -2.712466E+00 -3.046789E-02 -2.019483E-04 -7.553639E-02 -1.241275E-03 -2.413065E+00 -1.186499E+00 -7.505466E-02 -1.154624E-03 -3.609948E+00 -2.664048E+00 -3.294274E-02 -2.242161E-04 -8.167207E-02 -1.378144E-03 -2.579691E+00 -1.399684E+00 -7.252523E-02 -1.085979E-03 -3.762646E+00 -2.966415E+00 -3.021298E-02 -1.872587E-04 -7.490441E-02 -1.150985E-03 -2.707136E+00 -1.528526E+00 -7.153411E-02 -1.046460E-03 -3.793295E+00 -2.976791E+00 -2.857458E-02 -1.671752E-04 -7.084247E-02 -1.027542E-03 -3.155079E+00 -2.066218E+00 -9.171950E-02 -1.711836E-03 -4.700403E+00 -4.503318E+00 -3.904100E-02 -3.167906E-04 -9.679096E-02 -1.947152E-03 -2.955891E+00 -1.796192E+00 -8.526700E-02 -1.464085E-03 -4.355866E+00 -3.839684E+00 -3.605221E-02 -2.663621E-04 -8.938111E-02 -1.637194E-03 -3.157638E+00 -2.088634E+00 -8.917486E-02 -1.627414E-03 -4.530493E+00 -4.262890E+00 -3.711278E-02 -2.791427E-04 -9.201048E-02 -1.715750E-03 -3.237824E+00 -2.159909E+00 -9.708289E-02 -1.898400E-03 -4.765807E+00 -4.617662E+00 -4.179332E-02 -3.503645E-04 -1.036145E-01 -2.153514E-03 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.616860E+00 -1.407243E+00 -7.221083E-02 -1.059301E-03 -3.719840E+00 -2.827103E+00 -2.963219E-02 -1.775955E-04 -7.346451E-02 -1.091590E-03 -2.536174E+00 -1.301621E+00 -7.790327E-02 -1.242427E-03 -3.836384E+00 -2.980367E+00 -3.409705E-02 -2.443384E-04 -8.453386E-02 -1.501825E-03 -2.326398E+00 -1.111745E+00 -6.380790E-02 -8.422824E-04 -3.373074E+00 -2.338678E+00 -2.619114E-02 -1.463613E-04 -6.493342E-02 -8.996094E-04 -2.745209E+00 -1.561299E+00 -7.557988E-02 -1.164281E-03 -3.914803E+00 -3.154166E+00 -3.099509E-02 -1.948889E-04 -7.684344E-02 -1.197884E-03 -2.737388E+00 -1.515779E+00 -7.304714E-02 -1.077128E-03 -3.854064E+00 -2.996781E+00 -2.937470E-02 -1.746013E-04 -7.282614E-02 -1.073187E-03 -2.731962E+00 -1.617682E+00 -7.685258E-02 -1.239175E-03 -4.057901E+00 -3.505399E+00 -3.210546E-02 -2.150275E-04 -7.959627E-02 -1.321666E-03 -2.826797E+00 -1.654653E+00 -8.798649E-02 -1.562942E-03 -4.238099E+00 -3.671654E+00 -3.864939E-02 -3.007708E-04 -9.582007E-02 -1.848687E-03 -2.503072E+00 -1.321745E+00 -6.623202E-02 -9.120239E-04 -3.541728E+00 -2.623055E+00 -2.654018E-02 -1.469478E-04 -6.579875E-02 -9.032144E-04 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.383417E+00 -1.171863E+00 -6.968054E-02 -9.924374E-04 -3.486989E+00 -2.493855E+00 -2.962148E-02 -1.817051E-04 -7.343795E-02 -1.116850E-03 -2.666159E+00 -1.492268E+00 -7.417343E-02 -1.141120E-03 -3.912196E+00 -3.186439E+00 -3.075257E-02 -1.953163E-04 -7.624217E-02 -1.200511E-03 -2.689651E+00 -1.483190E+00 -8.007622E-02 -1.328579E-03 -4.015410E+00 -3.294872E+00 -3.443210E-02 -2.525628E-04 -8.536450E-02 -1.552377E-03 -3.141608E+00 -2.000672E+00 -8.238823E-02 -1.366316E-03 -4.442048E+00 -3.976219E+00 -3.282615E-02 -2.177028E-04 -8.138301E-02 -1.338110E-03 -3.294568E+00 -2.201280E+00 -8.370459E-02 -1.449531E-03 -4.567777E+00 -4.247816E+00 -3.258414E-02 -2.266289E-04 -8.078302E-02 -1.392974E-03 -3.058734E+00 -1.911285E+00 -8.780153E-02 -1.572171E-03 -4.531361E+00 -4.177302E+00 -3.703146E-02 -2.828466E-04 -9.180888E-02 -1.738516E-03 -2.639291E+00 -1.470166E+00 -8.380168E-02 -1.469150E-03 -3.995402E+00 -3.337545E+00 -3.720130E-02 -2.907469E-04 -9.222996E-02 -1.787075E-03 -2.360183E+00 -1.196310E+00 -7.336179E-02 -1.123869E-03 -3.552179E+00 -2.637131E+00 -3.222538E-02 -2.218615E-04 -7.989359E-02 -1.363671E-03 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.177844E+00 -9.998272E-01 -6.808817E-02 -9.543925E-04 -3.302614E+00 -2.268097E+00 -3.001326E-02 -1.847730E-04 -7.440926E-02 -1.135706E-03 -2.459342E+00 -1.286534E+00 -6.409323E-02 -8.519553E-04 -3.511461E+00 -2.568245E+00 -2.550853E-02 -1.387171E-04 -6.324108E-02 -8.526242E-04 -2.712538E+00 -1.496273E+00 -7.040893E-02 -1.033599E-03 -3.801423E+00 -2.967673E+00 -2.785218E-02 -1.687241E-04 -6.905150E-02 -1.037062E-03 -3.078971E+00 -1.928690E+00 -8.927133E-02 -1.655293E-03 -4.508330E+00 -4.154031E+00 -3.778191E-02 -3.038622E-04 -9.366939E-02 -1.867688E-03 -3.040055E+00 -1.908677E+00 -8.543146E-02 -1.469528E-03 -4.395363E+00 -3.943052E+00 -3.551022E-02 -2.539139E-04 -8.803740E-02 -1.560681E-03 -2.854688E+00 -1.652859E+00 -8.501906E-02 -1.459424E-03 -4.215336E+00 -3.600073E+00 -3.650039E-02 -2.691434E-04 -9.049224E-02 -1.654289E-03 -2.563883E+00 -1.375196E+00 -8.901196E-02 -1.610331E-03 -4.042903E+00 -3.361278E+00 -4.116155E-02 -3.428545E-04 -1.020482E-01 -2.107354E-03 -2.353136E+00 -1.260383E+00 -7.514099E-02 -1.159881E-03 -3.611322E+00 -2.808437E+00 -3.349306E-02 -2.280172E-04 -8.303643E-02 -1.401507E-03 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.585363E+00 -1.416531E+00 -7.208386E-02 -1.068367E-03 -3.721777E+00 -2.868016E+00 -2.981132E-02 -1.871051E-04 -7.390860E-02 -1.150041E-03 -3.227353E+00 -2.189454E+00 -8.161989E-02 -1.366996E-03 -4.465292E+00 -4.143037E+00 -3.169508E-02 -2.069605E-04 -7.857885E-02 -1.272082E-03 -3.101358E+00 -2.022582E+00 -8.316566E-02 -1.469875E-03 -4.433641E+00 -4.167950E+00 -3.363316E-02 -2.428472E-04 -8.338377E-02 -1.492660E-03 -3.342682E+00 -2.353374E+00 -9.542381E-02 -1.892530E-03 -4.916807E+00 -5.068483E+00 -4.010858E-02 -3.330650E-04 -9.943770E-02 -2.047183E-03 -2.733720E+00 -1.608810E+00 -7.575232E-02 -1.234497E-03 -3.955386E+00 -3.353987E+00 -3.126476E-02 -2.114507E-04 -7.751200E-02 -1.299681E-03 -2.532385E+00 -1.341692E+00 -7.908024E-02 -1.289149E-03 -3.816608E+00 -3.020090E+00 -3.480705E-02 -2.494950E-04 -8.629409E-02 -1.533520E-03 -2.651467E+00 -1.472579E+00 -7.547436E-02 -1.201468E-03 -3.877983E+00 -3.154531E+00 -3.166886E-02 -2.150564E-04 -7.851384E-02 -1.321843E-03 -2.404559E+00 -1.241962E+00 -6.952417E-02 -1.036673E-03 -3.551485E+00 -2.687553E+00 -2.947110E-02 -1.929942E-04 -7.306514E-02 -1.186238E-03 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.740199E+00 -1.663131E+00 -8.719535E-02 -1.596752E-03 -4.146740E+00 -3.682203E+00 -3.870935E-02 -3.136109E-04 -9.596871E-02 -1.927608E-03 -3.006650E+00 -1.972749E+00 -8.846181E-02 -1.643195E-03 -4.449165E+00 -4.222523E+00 -3.779771E-02 -2.999515E-04 -9.370858E-02 -1.843651E-03 -2.669269E+00 -1.482479E+00 -7.250461E-02 -1.097959E-03 -3.815372E+00 -3.039000E+00 -2.952621E-02 -1.837209E-04 -7.320176E-02 -1.129240E-03 -2.906350E+00 -1.760817E+00 -8.559496E-02 -1.527401E-03 -4.338708E+00 -3.888336E+00 -3.663301E-02 -2.834528E-04 -9.082102E-02 -1.742242E-03 -2.633801E+00 -1.566751E+00 -7.851898E-02 -1.276803E-03 -3.867974E+00 -3.237952E+00 -3.370851E-02 -2.331450E-04 -8.357057E-02 -1.433025E-03 -2.946914E+00 -1.857842E+00 -7.586572E-02 -1.217999E-03 -4.089763E+00 -3.522165E+00 -2.980738E-02 -1.901498E-04 -7.389883E-02 -1.168755E-03 -2.884789E+00 -1.801722E+00 -7.517555E-02 -1.168857E-03 -4.085136E+00 -3.522983E+00 -2.985774E-02 -1.859368E-04 -7.402368E-02 -1.142860E-03 -2.740499E+00 -1.588007E+00 -7.592011E-02 -1.232446E-03 -3.959573E+00 -3.327411E+00 -3.134446E-02 -2.121705E-04 -7.770960E-02 -1.304106E-03 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -2.212799E+00 -1.000035E+00 -7.449165E-02 -1.135538E-03 -3.466616E+00 -2.419923E+00 -3.399202E-02 -2.463541E-04 -8.427346E-02 -1.514215E-03 -2.591189E+00 -1.530310E+00 -7.305643E-02 -1.114250E-03 -3.732882E+00 -3.031120E+00 -3.039294E-02 -1.919600E-04 -7.535057E-02 -1.179882E-03 -2.719836E+00 -1.670890E+00 -8.176774E-02 -1.472662E-03 -4.030045E+00 -3.607044E+00 -3.530219E-02 -2.721266E-04 -8.752165E-02 -1.672625E-03 -2.201534E+00 -1.026489E+00 -7.361463E-02 -1.156634E-03 -3.444005E+00 -2.510736E+00 -3.352726E-02 -2.491193E-04 -8.312121E-02 -1.531211E-03 -2.649820E+00 -1.500516E+00 -6.849773E-02 -9.733415E-04 -3.744876E+00 -2.926356E+00 -2.706771E-02 -1.530408E-04 -6.710661E-02 -9.406650E-04 -2.788908E+00 -1.667764E+00 -7.477958E-02 -1.148212E-03 -4.029335E+00 -3.403340E+00 -3.033277E-02 -1.914118E-04 -7.520139E-02 -1.176512E-03 -2.810664E+00 -1.609682E+00 -6.917229E-02 -9.875658E-04 -3.854296E+00 -3.029615E+00 -2.634304E-02 -1.483398E-04 -6.531000E-02 -9.117703E-04 -2.647586E+00 -1.416013E+00 -7.421099E-02 -1.112815E-03 -3.826931E+00 -2.947306E+00 -3.083732E-02 -1.923794E-04 -7.645229E-02 -1.182459E-03 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -0.000000E+00 -tally 2: -3.995283E+01 -3.210141E+02 -3.996387E+01 -3.211916E+02 -6.783537E+00 -9.416330E+00 -6.783789E+00 -9.417032E+00 -1.239468E+02 -3.134204E+03 -1.239468E+02 -3.134204E+03 +6ab4a178b642f886eea9fddbdf67a8d6d3e0d1968f06ee52d7fd5ecdc1b4a796398e9b3a8c15ac72fb1a011d13a5fcc59a868781d38fb11787e060bb2e602a7b \ No newline at end of file diff --git a/tests/test_mg_tallies/test_mg_tallies.py b/tests/test_mg_tallies/test_mg_tallies.py index c9c5e95be2..b9bbcb5542 100644 --- a/tests/test_mg_tallies/test_mg_tallies.py +++ b/tests/test_mg_tallies/test_mg_tallies.py @@ -3,38 +3,84 @@ import os import sys sys.path.insert(0, os.pardir) -from testing_harness import TestHarness, PyAPITestHarness +from testing_harness import HashedPyAPITestHarness import openmc -class MGTalliesTestHarness(PyAPITestHarness): +class MGTalliesTestHarness(HashedPyAPITestHarness): def _build_inputs(self): + """Write input XML files.""" + self._input_set.build_default_materials_and_geometry(as_macro=False) + self._input_set.build_default_settings() + # Instantiate a tally mesh mesh = openmc.Mesh(mesh_id=1) mesh.type = 'regular' - mesh.dimension = [17, 17, 1] + mesh.dimension = [1, 1, 10] mesh.lower_left = [0.0, 0.0, 0.0] - mesh.upper_right = [21.42, 21.42, 100.0] + mesh.upper_right = [10, 10, 5] # Instantiate some tally filters energy_filter = openmc.EnergyFilter([0.0, 20.0]) energyout_filter = openmc.EnergyoutFilter([0.0, 20.0]) mesh_filter = openmc.MeshFilter(mesh) - mat_filter = openmc.MaterialFilter([1,2,3]) + mat_ids = [mat.id for mat in self._input_set.materials] + mat_filter = openmc.MaterialFilter(mat_ids) - tally1 = openmc.Tally(tally_id=1) - tally1.filters = [mesh_filter] - tally1.scores = ['total', 'absorption', 'flux', - 'fission', 'nu-fission'] + nuclides = [xs.name for xs in self._input_set.xs_data] - tally2 = openmc.Tally(tally_id=2) - tally2.filters = [mat_filter, energy_filter, energyout_filter] - tally2.scores = ['scatter', 'nu-scatter'] + scores= {False: ['total', 'absorption', 'flux', 'fission', 'nu-fission'], + True: ['total', 'absorption', 'fission', 'nu-fission']} - self._input_set.tallies = openmc.Tallies([tally1, tally2]) + tallies = [] + for do_nuclides in [False, True]: + tallies.append(openmc.Tally()) + tallies[-1].filters = [mesh_filter] + tallies[-1].estimator = 'analog' + tallies[-1].scores = scores[do_nuclides] + if do_nuclides: + tallies[-1].nuclides = nuclides - super(MGTalliesTestHarness, self)._build_inputs() + tallies.append(openmc.Tally()) + tallies[-1].filters = [mesh_filter] + tallies[-1].estimator = 'tracklength' + tallies[-1].scores = scores[do_nuclides] + if do_nuclides: + tallies[-1].nuclides = nuclides + + tallies.append(openmc.Tally()) + tallies[-1].filters = [mat_filter, energy_filter] + tallies[-1].estimator = 'analog' + tallies[-1].scores = scores[do_nuclides] + ['scatter', + 'nu-scatter'] + if do_nuclides: + tallies[-1].nuclides = nuclides + + tallies.append(openmc.Tally()) + tallies[-1].filters = [mat_filter, energy_filter] + tallies[-1].estimator = 'collision' + tallies[-1].scores = scores[do_nuclides] + if do_nuclides: + tallies[-1].nuclides = nuclides + + tallies.append(openmc.Tally()) + tallies[-1].filters = [mat_filter, energy_filter] + tallies[-1].estimator = 'tracklength' + tallies[-1].scores = scores[do_nuclides] + if do_nuclides: + tallies[-1].nuclides = nuclides + + tallies.append(openmc.Tally()) + tallies[-1].filters = [mat_filter, energy_filter, + energyout_filter] + tallies[-1].scores = ['scatter', 'nu-scatter', 'nu-fission'] + if do_nuclides: + tallies[-1].nuclides = nuclides + + self._input_set.tallies = openmc.Tallies(tallies) + + self._input_set.export() def _cleanup(self): super(MGTalliesTestHarness, self)._cleanup() diff --git a/tests/test_mgxs_library_ce_to_mg/results_true.dat b/tests/test_mgxs_library_ce_to_mg/results_true.dat index 6710c82be1..0b73724c9c 100644 --- a/tests/test_mgxs_library_ce_to_mg/results_true.dat +++ b/tests/test_mgxs_library_ce_to_mg/results_true.dat @@ -1,2 +1,2 @@ k-combined: -1.140804E+00 2.937150E-02 +1.140724E+00 2.952379E-02 diff --git a/tests/test_mgxs_library_ce_to_mg/test_mgxs_library_ce_to_mg.py b/tests/test_mgxs_library_ce_to_mg/test_mgxs_library_ce_to_mg.py index baa54b018b..eee528e88e 100644 --- a/tests/test_mgxs_library_ce_to_mg/test_mgxs_library_ce_to_mg.py +++ b/tests/test_mgxs_library_ce_to_mg/test_mgxs_library_ce_to_mg.py @@ -61,14 +61,14 @@ class MGXSTestHarness(PyAPITestHarness): self._input_set.geometry = self.mgxs_lib.create_mg_mode() # Modify settings so we can run in MG mode - self._input_set.settings.cross_sections = './mgxs.xml' + self._input_set.settings.cross_sections = './mgxs.h5' self._input_set.settings.energy_mode = 'multi-group' # Write modified input files self._input_set.settings.export_to_xml() self._input_set.geometry.export_to_xml() self._input_set.materials.export_to_xml() - self._input_set.mgxs_file.export_to_xml() + self._input_set.mgxs_file.export_to_hdf5() # Dont need tallies.xml, so remove the file if os.path.exists('./tallies.xml'): os.remove('./tallies.xml') @@ -83,9 +83,8 @@ class MGXSTestHarness(PyAPITestHarness): returncode = openmc.run(openmc_exec=self._opts.exe) def _cleanup(self): - return super(MGXSTestHarness, self)._cleanup() - f = os.path.join(os.getcwd(), 'mgxs.xml') + f = os.path.join(os.getcwd(), 'mgxs.h5') if os.path.exists(f): os.remove(f)